1 //==-- llvm/FileCheck/FileCheck.h --------------------------------*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file This file has some utilities to use FileCheck as an API 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_FILECHECK_FILECHECK_H 14 #define LLVM_FILECHECK_FILECHECK_H 15 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/Support/MemoryBuffer.h" 18 #include "llvm/Support/Regex.h" 19 #include "llvm/Support/SourceMgr.h" 20 #include <bitset> 21 #include <string> 22 #include <vector> 23 24 namespace llvm { 25 26 /// Contains info about various FileCheck options. 27 struct FileCheckRequest { 28 std::vector<StringRef> CheckPrefixes; 29 std::vector<StringRef> CommentPrefixes; 30 bool NoCanonicalizeWhiteSpace = false; 31 std::vector<StringRef> ImplicitCheckNot; 32 std::vector<StringRef> GlobalDefines; 33 bool AllowEmptyInput = false; 34 bool AllowUnusedPrefixes = false; 35 bool MatchFullLines = false; 36 bool IgnoreCase = false; 37 bool IsDefaultCheckPrefix = false; 38 bool EnableVarScope = false; 39 bool AllowDeprecatedDagOverlap = false; 40 bool Verbose = false; 41 bool VerboseVerbose = false; 42 }; 43 44 namespace Check { 45 46 enum FileCheckKind { 47 CheckNone = 0, 48 CheckPlain, 49 CheckNext, 50 CheckSame, 51 CheckNot, 52 CheckDAG, 53 CheckLabel, 54 CheckEmpty, 55 CheckComment, 56 57 /// Indicates the pattern only matches the end of file. This is used for 58 /// trailing CHECK-NOTs. 59 CheckEOF, 60 61 /// Marks when parsing found a -NOT check combined with another CHECK suffix. 62 CheckBadNot, 63 64 /// Marks when parsing found a -COUNT directive with invalid count value. 65 CheckBadCount 66 }; 67 68 enum FileCheckKindModifier { 69 /// Modifies directive to perform literal match. 70 ModifierLiteral = 0, 71 72 // The number of modifier. 73 Size 74 }; 75 76 class FileCheckType { 77 FileCheckKind Kind; 78 int Count; ///< optional Count for some checks 79 /// Modifers for the check directive. 80 std::bitset<FileCheckKindModifier::Size> Modifiers; 81 82 public: 83 FileCheckType(FileCheckKind Kind = CheckNone) 84 : Kind(Kind), Count(1), Modifiers() {} 85 FileCheckType(const FileCheckType &) = default; 86 FileCheckType &operator=(const FileCheckType &) = default; 87 88 operator FileCheckKind() const { return Kind; } 89 90 int getCount() const { return Count; } 91 FileCheckType &setCount(int C); 92 93 bool isLiteralMatch() const { 94 return Modifiers[FileCheckKindModifier::ModifierLiteral]; 95 } 96 FileCheckType &setLiteralMatch(bool Literal = true) { 97 Modifiers.set(FileCheckKindModifier::ModifierLiteral, Literal); 98 return *this; 99 } 100 101 // \returns a description of \p Prefix. 102 std::string getDescription(StringRef Prefix) const; 103 104 // \returns a description of \p Modifiers. 105 std::string getModifiersDescription() const; 106 }; 107 } // namespace Check 108 109 /// Summary of a FileCheck diagnostic. 110 struct FileCheckDiag { 111 /// What is the FileCheck directive for this diagnostic? 112 Check::FileCheckType CheckTy; 113 /// Where is the FileCheck directive for this diagnostic? 114 SMLoc CheckLoc; 115 /// What type of match result does this diagnostic describe? 116 /// 117 /// A directive's supplied pattern is said to be either expected or excluded 118 /// depending on whether the pattern must have or must not have a match in 119 /// order for the directive to succeed. For example, a CHECK directive's 120 /// pattern is expected, and a CHECK-NOT directive's pattern is excluded. 121 /// All match result types whose names end with "Excluded" are for excluded 122 /// patterns, and all others are for expected patterns. 123 /// 124 /// There might be more than one match result for a single pattern. For 125 /// example, there might be several discarded matches 126 /// (MatchFoundButDiscarded) before either a good match 127 /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected), 128 /// and there might be a fuzzy match (MatchFuzzy) after the latter. 129 enum MatchType { 130 /// Indicates a good match for an expected pattern. 131 MatchFoundAndExpected, 132 /// Indicates a match for an excluded pattern. 133 MatchFoundButExcluded, 134 /// Indicates a match for an expected pattern, but the match is on the 135 /// wrong line. 136 MatchFoundButWrongLine, 137 /// Indicates a discarded match for an expected pattern. 138 MatchFoundButDiscarded, 139 /// Indicates no match for an excluded pattern. 140 MatchNoneAndExcluded, 141 /// Indicates no match for an expected pattern, but this might follow good 142 /// matches when multiple matches are expected for the pattern, or it might 143 /// follow discarded matches for the pattern. 144 MatchNoneButExpected, 145 /// Indicates a fuzzy match that serves as a suggestion for the next 146 /// intended match for an expected pattern with too few or no good matches. 147 MatchFuzzy, 148 } MatchTy; 149 /// The search range if MatchTy is MatchNoneAndExcluded or 150 /// MatchNoneButExpected, or the match range otherwise. 151 unsigned InputStartLine; 152 unsigned InputStartCol; 153 unsigned InputEndLine; 154 unsigned InputEndCol; 155 /// A note to replace the one normally indicated by MatchTy, or the empty 156 /// string if none. 157 std::string Note; 158 FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy, 159 SMLoc CheckLoc, MatchType MatchTy, SMRange InputRange, 160 StringRef Note = ""); 161 }; 162 163 class FileCheckPatternContext; 164 struct FileCheckString; 165 166 /// FileCheck class takes the request and exposes various methods that 167 /// use information from the request. 168 class FileCheck { 169 FileCheckRequest Req; 170 std::unique_ptr<FileCheckPatternContext> PatternContext; 171 // C++17 TODO: make this a plain std::vector. 172 std::unique_ptr<std::vector<FileCheckString>> CheckStrings; 173 174 public: 175 explicit FileCheck(FileCheckRequest Req); 176 ~FileCheck(); 177 178 // Combines the check prefixes into a single regex so that we can efficiently 179 // scan for any of the set. 180 // 181 // The semantics are that the longest-match wins which matches our regex 182 // library. 183 Regex buildCheckPrefixRegex(); 184 185 /// Reads the check file from \p Buffer and records the expected strings it 186 /// contains. Errors are reported against \p SM. 187 /// 188 /// Only expected strings whose prefix is one of those listed in \p PrefixRE 189 /// are recorded. \returns true in case of an error, false otherwise. 190 /// 191 /// If \p ImpPatBufferIDRange, then the range (inclusive start, exclusive end) 192 /// of IDs for source buffers added to \p SM for implicit patterns are 193 /// recorded in it. The range is empty if there are none. 194 bool 195 readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE, 196 std::pair<unsigned, unsigned> *ImpPatBufferIDRange = nullptr); 197 198 bool ValidateCheckPrefixes(); 199 200 /// Canonicalizes whitespaces in the file. Line endings are replaced with 201 /// UNIX-style '\n'. 202 StringRef CanonicalizeFile(MemoryBuffer &MB, 203 SmallVectorImpl<char> &OutputBuffer); 204 205 /// Checks the input to FileCheck provided in the \p Buffer against the 206 /// expected strings read from the check file and record diagnostics emitted 207 /// in \p Diags. Errors are recorded against \p SM. 208 /// 209 /// \returns false if the input fails to satisfy the checks. 210 bool checkInput(SourceMgr &SM, StringRef Buffer, 211 std::vector<FileCheckDiag> *Diags = nullptr); 212 }; 213 214 } // namespace llvm 215 216 #endif 217