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