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