xref: /freebsd/contrib/llvm-project/llvm/include/llvm/FileCheck/FileCheck.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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