• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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