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