Line data Source code
1 : //==-- llvm/Support/FileCheck.h ---------------------------*- C++ -*-==//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : /// \file This file has some utilities to use FileCheck as an API
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_SUPPORT_FILECHECK_H
15 : #define LLVM_SUPPORT_FILECHECK_H
16 :
17 : #include "llvm/ADT/StringMap.h"
18 : #include "llvm/Support/MemoryBuffer.h"
19 : #include "llvm/Support/Regex.h"
20 : #include "llvm/Support/SourceMgr.h"
21 : #include <vector>
22 : #include <map>
23 :
24 : namespace llvm {
25 :
26 : /// Contains info about various FileCheck options.
27 122310 : struct FileCheckRequest {
28 : std::vector<std::string> CheckPrefixes;
29 : bool NoCanonicalizeWhiteSpace = false;
30 : std::vector<std::string> ImplicitCheckNot;
31 : std::vector<std::string> GlobalDefines;
32 : bool AllowEmptyInput = false;
33 : bool MatchFullLines = false;
34 : bool EnableVarScope = false;
35 : bool AllowDeprecatedDagOverlap = false;
36 : bool Verbose = false;
37 : bool VerboseVerbose = false;
38 : };
39 :
40 :
41 : //===----------------------------------------------------------------------===//
42 : // Pattern Handling Code.
43 : //===----------------------------------------------------------------------===//
44 :
45 : namespace Check {
46 : enum FileCheckType {
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 : }
64 :
65 : class FileCheckPattern {
66 : SMLoc PatternLoc;
67 :
68 : /// A fixed string to match as the pattern or empty if this pattern requires
69 : /// a regex match.
70 : StringRef FixedStr;
71 :
72 : /// A regex string to match as the pattern or empty if this pattern requires
73 : /// a fixed string to match.
74 : std::string RegExStr;
75 :
76 : /// Entries in this vector map to uses of a variable in the pattern, e.g.
77 : /// "foo[[bar]]baz". In this case, the RegExStr will contain "foobaz" and
78 : /// we'll get an entry in this vector that tells us to insert the value of
79 : /// bar at offset 3.
80 : std::vector<std::pair<StringRef, unsigned>> VariableUses;
81 :
82 : /// Maps definitions of variables to their parenthesized capture numbers.
83 : ///
84 : /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to
85 : /// 1.
86 : std::map<StringRef, unsigned> VariableDefs;
87 :
88 : Check::FileCheckType CheckTy;
89 :
90 : /// Contains the number of line this pattern is in.
91 : unsigned LineNumber;
92 :
93 : public:
94 : explicit FileCheckPattern(Check::FileCheckType Ty)
95 5419754 : : CheckTy(Ty) {}
96 :
97 : /// Returns the location in source code.
98 0 : SMLoc getLoc() const { return PatternLoc; }
99 :
100 : bool ParsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
101 : unsigned LineNumber, const FileCheckRequest &Req);
102 : size_t Match(StringRef Buffer, size_t &MatchLen,
103 : StringMap<StringRef> &VariableTable) const;
104 : void PrintVariableUses(const SourceMgr &SM, StringRef Buffer,
105 : const StringMap<StringRef> &VariableTable,
106 : SMRange MatchRange = None) const;
107 : void PrintFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
108 : const StringMap<StringRef> &VariableTable) const;
109 :
110 : bool hasVariable() const {
111 234203 : return !(VariableUses.empty() && VariableDefs.empty());
112 : }
113 :
114 0 : Check::FileCheckType getCheckTy() const { return CheckTy; }
115 :
116 : private:
117 : bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
118 : void AddBackrefToRegEx(unsigned BackrefNum);
119 : unsigned
120 : ComputeMatchDistance(StringRef Buffer,
121 : const StringMap<StringRef> &VariableTable) const;
122 : bool EvaluateExpression(StringRef Expr, std::string &Value) const;
123 : size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
124 : };
125 :
126 : //===----------------------------------------------------------------------===//
127 : // Check Strings.
128 : //===----------------------------------------------------------------------===//
129 :
130 : /// A check that we found in the input file.
131 6253851 : struct FileCheckString {
132 : /// The pattern to match.
133 : FileCheckPattern Pat;
134 :
135 : /// Which prefix name this check matched.
136 : StringRef Prefix;
137 :
138 : /// The location in the match file that the check string was specified.
139 : SMLoc Loc;
140 :
141 : /// All of the strings that are disallowed from occurring between this match
142 : /// string and the previous one (or start of file).
143 : std::vector<FileCheckPattern> DagNotStrings;
144 :
145 : FileCheckString(const FileCheckPattern &P, StringRef S, SMLoc L)
146 2564481 : : Pat(P), Prefix(S), Loc(L) {}
147 :
148 : size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
149 : size_t &MatchLen, StringMap<StringRef> &VariableTable,
150 : FileCheckRequest &Req) const;
151 :
152 : bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
153 : bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
154 : bool CheckNot(const SourceMgr &SM, StringRef Buffer,
155 : const std::vector<const FileCheckPattern *> &NotStrings,
156 : StringMap<StringRef> &VariableTable,
157 : const FileCheckRequest &Req) const;
158 : size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
159 : std::vector<const FileCheckPattern *> &NotStrings,
160 : StringMap<StringRef> &VariableTable,
161 : const FileCheckRequest &Req) const;
162 : };
163 :
164 : /// FileCheck class takes the request and exposes various methods that
165 : /// use information from the request.
166 61155 : class FileCheck {
167 : FileCheckRequest Req;
168 :
169 : public:
170 61155 : FileCheck(FileCheckRequest Req) : Req(Req) {}
171 :
172 : // Combines the check prefixes into a single regex so that we can efficiently
173 : // scan for any of the set.
174 : //
175 : // The semantics are that the longest-match wins which matches our regex
176 : // library.
177 : Regex buildCheckPrefixRegex();
178 :
179 : /// Read the check file, which specifies the sequence of expected strings.
180 : ///
181 : /// The strings are added to the CheckStrings vector. Returns true in case of
182 : /// an error, false otherwise.
183 : bool ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
184 : std::vector<FileCheckString> &CheckStrings);
185 :
186 : bool ValidateCheckPrefixes();
187 :
188 : /// Canonicalize whitespaces in the file. Line endings are replaced with
189 : /// UNIX-style '\n'.
190 : StringRef CanonicalizeFile(MemoryBuffer &MB,
191 : SmallVectorImpl<char> &OutputBuffer);
192 :
193 : /// Check the input to FileCheck provided in the \p Buffer against the \p
194 : /// CheckStrings read from the check file.
195 : ///
196 : /// Returns false if the input fails to satisfy the checks.
197 : bool CheckInput(SourceMgr &SM, StringRef Buffer,
198 : ArrayRef<FileCheckString> CheckStrings);
199 : };
200 : } // namespace llvm
201 : #endif
|