blob: de8d46bcb8f27b8d180ac895485367d40ae74f40 [file] [log] [blame]
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001//==-- 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
24namespace llvm {
25
26/// Contains info about various FileCheck options.
27struct 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
45namespace Check {
46enum 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
65class 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.
Andrew Scull0372a572018-11-16 15:47:06 +000083 ///
Andrew Scullcdfcccc2018-10-05 20:58:37 +010084 /// 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
93public:
94 explicit FileCheckPattern(Check::FileCheckType Ty)
95 : CheckTy(Ty) {}
96
97 /// Returns the location in source code.
98 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 return !(VariableUses.empty() && VariableDefs.empty());
112 }
113
114 Check::FileCheckType getCheckTy() const { return CheckTy; }
115
116private:
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.
131struct 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 : 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.
166class FileCheck {
167 FileCheckRequest Req;
168
169public:
170 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