1 //==-- llvm/Support/FileCheck.h ---------------------------*- C++ -*-==//
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
7 //===----------------------------------------------------------------------===//
9 /// \file This file has some utilities to use FileCheck as an API
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_SUPPORT_FILECHECK_H
14 #define LLVM_SUPPORT_FILECHECK_H
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/Support/MemoryBuffer.h"
18 #include "llvm/Support/Regex.h"
19 #include "llvm/Support/SourceMgr.h"
25 /// Contains info about various FileCheck options.
26 struct 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 EnableVarScope
= false;
34 bool AllowDeprecatedDagOverlap
= false;
36 bool VerboseVerbose
= false;
40 //===----------------------------------------------------------------------===//
41 // Pattern Handling Code.
42 //===----------------------------------------------------------------------===//
56 /// Indicates the pattern only matches the end of file. This is used for
57 /// trailing CHECK-NOTs.
60 /// Marks when parsing found a -NOT check combined with another CHECK suffix.
63 /// Marks when parsing found a -COUNT directive with invalid count value.
69 int Count
; ///< optional Count for some checks
72 FileCheckType(FileCheckKind Kind
= CheckNone
) : Kind(Kind
), Count(1) {}
73 FileCheckType(const FileCheckType
&) = default;
75 operator FileCheckKind() const { return Kind
; }
77 int getCount() const { return Count
; }
78 FileCheckType
&setCount(int C
);
80 std::string
getDescription(StringRef Prefix
) const;
86 class FileCheckPattern
{
89 /// A fixed string to match as the pattern or empty if this pattern requires
93 /// A regex string to match as the pattern or empty if this pattern requires
94 /// a fixed string to match.
97 /// Entries in this vector map to uses of a variable in the pattern, e.g.
98 /// "foo[[bar]]baz". In this case, the RegExStr will contain "foobaz" and
99 /// we'll get an entry in this vector that tells us to insert the value of
101 std::vector
<std::pair
<StringRef
, unsigned>> VariableUses
;
103 /// Maps definitions of variables to their parenthesized capture numbers.
105 /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to
107 std::map
<StringRef
, unsigned> VariableDefs
;
109 Check::FileCheckType CheckTy
;
111 /// Contains the number of line this pattern is in.
115 explicit FileCheckPattern(Check::FileCheckType Ty
)
118 /// Returns the location in source code.
119 SMLoc
getLoc() const { return PatternLoc
; }
121 bool ParsePattern(StringRef PatternStr
, StringRef Prefix
, SourceMgr
&SM
,
122 unsigned LineNumber
, const FileCheckRequest
&Req
);
123 size_t Match(StringRef Buffer
, size_t &MatchLen
,
124 StringMap
<StringRef
> &VariableTable
) const;
125 void PrintVariableUses(const SourceMgr
&SM
, StringRef Buffer
,
126 const StringMap
<StringRef
> &VariableTable
,
127 SMRange MatchRange
= None
) const;
128 void PrintFuzzyMatch(const SourceMgr
&SM
, StringRef Buffer
,
129 const StringMap
<StringRef
> &VariableTable
,
130 std::vector
<FileCheckDiag
> *Diags
) const;
132 bool hasVariable() const {
133 return !(VariableUses
.empty() && VariableDefs
.empty());
136 Check::FileCheckType
getCheckTy() const { return CheckTy
; }
138 int getCount() const { return CheckTy
.getCount(); }
141 bool AddRegExToRegEx(StringRef RS
, unsigned &CurParen
, SourceMgr
&SM
);
142 void AddBackrefToRegEx(unsigned BackrefNum
);
144 ComputeMatchDistance(StringRef Buffer
,
145 const StringMap
<StringRef
> &VariableTable
) const;
146 bool EvaluateExpression(StringRef Expr
, std::string
&Value
) const;
147 size_t FindRegexVarEnd(StringRef Str
, SourceMgr
&SM
);
150 //===----------------------------------------------------------------------===//
151 /// Summary of a FileCheck diagnostic.
152 //===----------------------------------------------------------------------===//
154 struct FileCheckDiag
{
155 /// What is the FileCheck directive for this diagnostic?
156 Check::FileCheckType CheckTy
;
157 /// Where is the FileCheck directive for this diagnostic?
158 unsigned CheckLine
, CheckCol
;
159 /// What type of match result does this diagnostic describe?
161 /// A directive's supplied pattern is said to be either expected or excluded
162 /// depending on whether the pattern must have or must not have a match in
163 /// order for the directive to succeed. For example, a CHECK directive's
164 /// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
165 /// All match result types whose names end with "Excluded" are for excluded
166 /// patterns, and all others are for expected patterns.
168 /// There might be more than one match result for a single pattern. For
169 /// example, there might be several discarded matches
170 /// (MatchFoundButDiscarded) before either a good match
171 /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
172 /// and there might be a fuzzy match (MatchFuzzy) after the latter.
174 /// Indicates a good match for an expected pattern.
175 MatchFoundAndExpected
,
176 /// Indicates a match for an excluded pattern.
177 MatchFoundButExcluded
,
178 /// Indicates a match for an expected pattern, but the match is on the
180 MatchFoundButWrongLine
,
181 /// Indicates a discarded match for an expected pattern.
182 MatchFoundButDiscarded
,
183 /// Indicates no match for an excluded pattern.
184 MatchNoneAndExcluded
,
185 /// Indicates no match for an expected pattern, but this might follow good
186 /// matches when multiple matches are expected for the pattern, or it might
187 /// follow discarded matches for the pattern.
188 MatchNoneButExpected
,
189 /// Indicates a fuzzy match that serves as a suggestion for the next
190 /// intended match for an expected pattern with too few or no good matches.
193 /// The search range if MatchTy is MatchNoneAndExcluded or
194 /// MatchNoneButExpected, or the match range otherwise.
195 unsigned InputStartLine
;
196 unsigned InputStartCol
;
197 unsigned InputEndLine
;
198 unsigned InputEndCol
;
199 FileCheckDiag(const SourceMgr
&SM
, const Check::FileCheckType
&CheckTy
,
200 SMLoc CheckLoc
, MatchType MatchTy
, SMRange InputRange
);
203 //===----------------------------------------------------------------------===//
205 //===----------------------------------------------------------------------===//
207 /// A check that we found in the input file.
208 struct FileCheckString
{
209 /// The pattern to match.
210 FileCheckPattern Pat
;
212 /// Which prefix name this check matched.
215 /// The location in the match file that the check string was specified.
218 /// All of the strings that are disallowed from occurring between this match
219 /// string and the previous one (or start of file).
220 std::vector
<FileCheckPattern
> DagNotStrings
;
222 FileCheckString(const FileCheckPattern
&P
, StringRef S
, SMLoc L
)
223 : Pat(P
), Prefix(S
), Loc(L
) {}
225 size_t Check(const SourceMgr
&SM
, StringRef Buffer
, bool IsLabelScanMode
,
226 size_t &MatchLen
, StringMap
<StringRef
> &VariableTable
,
227 FileCheckRequest
&Req
, std::vector
<FileCheckDiag
> *Diags
) const;
229 bool CheckNext(const SourceMgr
&SM
, StringRef Buffer
) const;
230 bool CheckSame(const SourceMgr
&SM
, StringRef Buffer
) const;
231 bool CheckNot(const SourceMgr
&SM
, StringRef Buffer
,
232 const std::vector
<const FileCheckPattern
*> &NotStrings
,
233 StringMap
<StringRef
> &VariableTable
,
234 const FileCheckRequest
&Req
,
235 std::vector
<FileCheckDiag
> *Diags
) const;
236 size_t CheckDag(const SourceMgr
&SM
, StringRef Buffer
,
237 std::vector
<const FileCheckPattern
*> &NotStrings
,
238 StringMap
<StringRef
> &VariableTable
,
239 const FileCheckRequest
&Req
,
240 std::vector
<FileCheckDiag
> *Diags
) const;
243 /// FileCheck class takes the request and exposes various methods that
244 /// use information from the request.
246 FileCheckRequest Req
;
249 FileCheck(FileCheckRequest Req
) : Req(Req
) {}
251 // Combines the check prefixes into a single regex so that we can efficiently
252 // scan for any of the set.
254 // The semantics are that the longest-match wins which matches our regex
256 Regex
buildCheckPrefixRegex();
258 /// Read the check file, which specifies the sequence of expected strings.
260 /// The strings are added to the CheckStrings vector. Returns true in case of
261 /// an error, false otherwise.
262 bool ReadCheckFile(SourceMgr
&SM
, StringRef Buffer
, Regex
&PrefixRE
,
263 std::vector
<FileCheckString
> &CheckStrings
);
265 bool ValidateCheckPrefixes();
267 /// Canonicalize whitespaces in the file. Line endings are replaced with
269 StringRef
CanonicalizeFile(MemoryBuffer
&MB
,
270 SmallVectorImpl
<char> &OutputBuffer
);
272 /// Check the input to FileCheck provided in the \p Buffer against the \p
273 /// CheckStrings read from the check file.
275 /// Returns false if the input fails to satisfy the checks.
276 bool CheckInput(SourceMgr
&SM
, StringRef Buffer
,
277 ArrayRef
<FileCheckString
> CheckStrings
,
278 std::vector
<FileCheckDiag
> *Diags
= nullptr);