blob: 9cd1fe75760b1f3deab6bfc1648fa9bd9672b457 [file] [log] [blame]
Chris Lattneree3c74f2009-07-08 18:44:05 +00001//===- FileCheck.cpp - Check that File's Contents match what is expected --===//
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// FileCheck does a line-by line check of a file that validates whether it
11// contains the expected content. This is useful for regression tests etc.
12//
13// This program exits with an error status of 2 on error, exit status of 0 if
14// the file matched the expected contents, and exit status of 1 if it did not
15// contain the expected contents.
16//
17//===----------------------------------------------------------------------===//
18
Chandler Carruth91d19d82012-12-04 10:37:14 +000019#include "llvm/ADT/SmallString.h"
20#include "llvm/ADT/StringExtras.h"
21#include "llvm/ADT/StringMap.h"
Matt Arsenault13df4622013-11-10 02:04:09 +000022#include "llvm/ADT/StringSet.h"
Chris Lattneree3c74f2009-07-08 18:44:05 +000023#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/MemoryBuffer.h"
25#include "llvm/Support/PrettyStackTrace.h"
Chris Lattnerf08d2db2009-09-24 21:47:32 +000026#include "llvm/Support/Regex.h"
Chandler Carruth91d19d82012-12-04 10:37:14 +000027#include "llvm/Support/Signals.h"
Chris Lattneree3c74f2009-07-08 18:44:05 +000028#include "llvm/Support/SourceMgr.h"
29#include "llvm/Support/raw_ostream.h"
Chris Lattner8879e062009-09-27 07:56:52 +000030#include <algorithm>
Will Dietz981af002013-10-12 00:55:57 +000031#include <cctype>
Eli Benderskye8b8f1b2012-12-01 21:54:48 +000032#include <map>
33#include <string>
Rafael Espindolaa6e9c3e2014-06-12 17:38:55 +000034#include <system_error>
Eli Benderskye8b8f1b2012-12-01 21:54:48 +000035#include <vector>
Chris Lattneree3c74f2009-07-08 18:44:05 +000036using namespace llvm;
37
38static cl::opt<std::string>
39CheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);
40
41static cl::opt<std::string>
42InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
43 cl::init("-"), cl::value_desc("filename"));
44
Matt Arsenault13df4622013-11-10 02:04:09 +000045static cl::list<std::string>
46CheckPrefixes("check-prefix",
47 cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
Chris Lattneree3c74f2009-07-08 18:44:05 +000048
Chris Lattner2c3e5cd2009-07-11 18:58:15 +000049static cl::opt<bool>
50NoCanonicalizeWhiteSpace("strict-whitespace",
51 cl::desc("Do not treat all horizontal whitespace as equivalent"));
52
Alexander Kornienko56ccdbb2014-07-11 12:39:32 +000053static cl::list<std::string> ImplicitCheckNot(
54 "implicit-check-not",
55 cl::desc("Add an implicit negative check with this pattern to every\n"
56 "positive check. This can be used to ensure that no instances of\n"
57 "this pattern occur which are not matched by a positive pattern"),
58 cl::value_desc("pattern"));
59
Matt Arsenault13df4622013-11-10 02:04:09 +000060typedef cl::list<std::string>::const_iterator prefix_iterator;
61
Chris Lattner74d50732009-09-24 20:39:13 +000062//===----------------------------------------------------------------------===//
63// Pattern Handling Code.
64//===----------------------------------------------------------------------===//
65
Matt Arsenault38820972013-09-17 22:30:02 +000066namespace Check {
67 enum CheckType {
68 CheckNone = 0,
69 CheckPlain,
70 CheckNext,
71 CheckNot,
72 CheckDAG,
73 CheckLabel,
74
75 /// MatchEOF - When set, this pattern only matches the end of file. This is
76 /// used for trailing CHECK-NOTs.
77 CheckEOF
78 };
79}
80
Chris Lattner3b40b442009-09-24 20:25:55 +000081class Pattern {
Chris Lattner0a4c44b2009-09-25 17:29:36 +000082 SMLoc PatternLoc;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +000083
Matt Arsenault38820972013-09-17 22:30:02 +000084 Check::CheckType CheckTy;
Michael Liao91a1b2c2013-05-14 20:34:12 +000085
Chris Lattnerb16ab0c2009-09-25 17:23:43 +000086 /// FixedStr - If non-empty, this pattern is a fixed string match with the
87 /// specified fixed string.
Chris Lattner221460e2009-09-25 17:09:12 +000088 StringRef FixedStr;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +000089
Chris Lattnerb16ab0c2009-09-25 17:23:43 +000090 /// RegEx - If non-empty, this is a regex pattern.
91 std::string RegExStr;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +000092
Alexander Kornienko92987fb2012-11-14 21:07:37 +000093 /// \brief Contains the number of line this pattern is in.
94 unsigned LineNumber;
95
Chris Lattner8879e062009-09-27 07:56:52 +000096 /// VariableUses - Entries in this vector map to uses of a variable in the
97 /// pattern, e.g. "foo[[bar]]baz". In this case, the RegExStr will contain
98 /// "foobaz" and we'll get an entry in this vector that tells us to insert the
99 /// value of bar at offset 3.
100 std::vector<std::pair<StringRef, unsigned> > VariableUses;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000101
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000102 /// VariableDefs - Maps definitions of variables to their parenthesized
103 /// capture numbers.
104 /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1.
105 std::map<StringRef, unsigned> VariableDefs;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000106
Chris Lattner3b40b442009-09-24 20:25:55 +0000107public:
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000108
Matt Arsenault38820972013-09-17 22:30:02 +0000109 Pattern(Check::CheckType Ty)
110 : CheckTy(Ty) { }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000111
Michael Liao0b707eb2013-04-25 21:31:34 +0000112 /// getLoc - Return the location in source code.
113 SMLoc getLoc() const { return PatternLoc; }
114
Matt Arsenault13df4622013-11-10 02:04:09 +0000115 /// ParsePattern - Parse the given string into the Pattern. Prefix provides
116 /// which prefix is being matched, SM provides the SourceMgr used for error
117 /// reports, and LineNumber is the line number in the input file from which
118 /// the pattern string was read. Returns true in case of an error, false
119 /// otherwise.
120 bool ParsePattern(StringRef PatternStr,
121 StringRef Prefix,
122 SourceMgr &SM,
123 unsigned LineNumber);
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000124
Chris Lattner3b40b442009-09-24 20:25:55 +0000125 /// Match - Match the pattern string against the input buffer Buffer. This
126 /// returns the position that is matched or npos if there is no match. If
127 /// there is a match, the size of the matched string is returned in MatchLen.
Chris Lattner8879e062009-09-27 07:56:52 +0000128 ///
129 /// The VariableTable StringMap provides the current values of filecheck
130 /// variables and is updated if this match defines new values.
131 size_t Match(StringRef Buffer, size_t &MatchLen,
132 StringMap<StringRef> &VariableTable) const;
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000133
134 /// PrintFailureInfo - Print additional information about a failure to match
135 /// involving this pattern.
136 void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
137 const StringMap<StringRef> &VariableTable) const;
138
Stephen Linf8bd2e52013-07-12 14:51:05 +0000139 bool hasVariable() const { return !(VariableUses.empty() &&
140 VariableDefs.empty()); }
141
Matt Arsenault38820972013-09-17 22:30:02 +0000142 Check::CheckType getCheckTy() const { return CheckTy; }
Michael Liao91a1b2c2013-05-14 20:34:12 +0000143
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000144private:
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000145 bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
146 void AddBackrefToRegEx(unsigned BackrefNum);
Daniel Dunbarfd29d882009-11-22 22:59:26 +0000147
148 /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
149 /// matching this pattern at the start of \arg Buffer; a distance of zero
150 /// should correspond to a perfect match.
151 unsigned ComputeMatchDistance(StringRef Buffer,
152 const StringMap<StringRef> &VariableTable) const;
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000153
154 /// \brief Evaluates expression and stores the result to \p Value.
155 /// \return true on success. false when the expression has invalid syntax.
156 bool EvaluateExpression(StringRef Expr, std::string &Value) const;
Eli Bendersky061d2ba2012-12-02 16:02:41 +0000157
158 /// \brief Finds the closing sequence of a regex variable usage or
159 /// definition. Str has to point in the beginning of the definition
160 /// (right after the opening sequence).
161 /// \return offset of the closing sequence within Str, or npos if it was not
162 /// found.
Adrian Prantl81e5cd92014-01-03 21:49:09 +0000163 size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
Chris Lattner3b40b442009-09-24 20:25:55 +0000164};
165
Chris Lattner8879e062009-09-27 07:56:52 +0000166
Matt Arsenault13df4622013-11-10 02:04:09 +0000167bool Pattern::ParsePattern(StringRef PatternStr,
168 StringRef Prefix,
169 SourceMgr &SM,
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000170 unsigned LineNumber) {
171 this->LineNumber = LineNumber;
Chris Lattner0a4c44b2009-09-25 17:29:36 +0000172 PatternLoc = SMLoc::getFromPointer(PatternStr.data());
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000173
Chris Lattner74d50732009-09-24 20:39:13 +0000174 // Ignore trailing whitespace.
175 while (!PatternStr.empty() &&
176 (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
177 PatternStr = PatternStr.substr(0, PatternStr.size()-1);
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000178
Chris Lattner74d50732009-09-24 20:39:13 +0000179 // Check that there is something on the line.
180 if (PatternStr.empty()) {
Chris Lattner03b80a42011-10-16 05:43:57 +0000181 SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
182 "found empty check string with prefix '" +
Matt Arsenault13df4622013-11-10 02:04:09 +0000183 Prefix + ":'");
Chris Lattner74d50732009-09-24 20:39:13 +0000184 return true;
185 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000186
Chris Lattner221460e2009-09-25 17:09:12 +0000187 // Check to see if this is a fixed string, or if it has regex pieces.
Ted Kremenekd9466962012-09-08 04:32:13 +0000188 if (PatternStr.size() < 2 ||
Chris Lattner8879e062009-09-27 07:56:52 +0000189 (PatternStr.find("{{") == StringRef::npos &&
190 PatternStr.find("[[") == StringRef::npos)) {
Chris Lattner221460e2009-09-25 17:09:12 +0000191 FixedStr = PatternStr;
192 return false;
193 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000194
Chris Lattner8879e062009-09-27 07:56:52 +0000195 // Paren value #0 is for the fully matched string. Any new parenthesized
Chris Lattner53e06792011-04-09 06:18:02 +0000196 // values add from there.
Chris Lattner8879e062009-09-27 07:56:52 +0000197 unsigned CurParen = 1;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000198
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000199 // Otherwise, there is at least one regex piece. Build up the regex pattern
200 // by escaping scary characters in fixed strings, building up one big regex.
Chris Lattnerf08d2db2009-09-24 21:47:32 +0000201 while (!PatternStr.empty()) {
Chris Lattner8879e062009-09-27 07:56:52 +0000202 // RegEx matches.
Chris Lattner53e06792011-04-09 06:18:02 +0000203 if (PatternStr.startswith("{{")) {
Eli Bendersky43d50d42012-11-30 14:22:14 +0000204 // This is the start of a regex match. Scan for the }}.
Chris Lattner8879e062009-09-27 07:56:52 +0000205 size_t End = PatternStr.find("}}");
206 if (End == StringRef::npos) {
207 SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
Chris Lattner03b80a42011-10-16 05:43:57 +0000208 SourceMgr::DK_Error,
209 "found start of regex string with no end '}}'");
Chris Lattner8879e062009-09-27 07:56:52 +0000210 return true;
211 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000212
Chris Lattnere53c95f2011-04-09 06:37:03 +0000213 // Enclose {{}} patterns in parens just like [[]] even though we're not
214 // capturing the result for any purpose. This is required in case the
215 // expression contains an alternation like: CHECK: abc{{x|z}}def. We
216 // want this to turn into: "abc(x|z)def" not "abcx|zdef".
217 RegExStr += '(';
218 ++CurParen;
219
Chris Lattner8879e062009-09-27 07:56:52 +0000220 if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
221 return true;
Chris Lattnere53c95f2011-04-09 06:37:03 +0000222 RegExStr += ')';
Chris Lattner53e06792011-04-09 06:18:02 +0000223
Chris Lattner8879e062009-09-27 07:56:52 +0000224 PatternStr = PatternStr.substr(End+2);
Chris Lattnerf08d2db2009-09-24 21:47:32 +0000225 continue;
226 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000227
Chris Lattner8879e062009-09-27 07:56:52 +0000228 // Named RegEx matches. These are of two forms: [[foo:.*]] which matches .*
229 // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
230 // second form is [[foo]] which is a reference to foo. The variable name
Daniel Dunbar57cb7332009-11-22 22:07:50 +0000231 // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
Chris Lattner8879e062009-09-27 07:56:52 +0000232 // it. This is to catch some common errors.
Chris Lattner53e06792011-04-09 06:18:02 +0000233 if (PatternStr.startswith("[[")) {
Eli Bendersky061d2ba2012-12-02 16:02:41 +0000234 // Find the closing bracket pair ending the match. End is going to be an
235 // offset relative to the beginning of the match string.
Adrian Prantl81e5cd92014-01-03 21:49:09 +0000236 size_t End = FindRegexVarEnd(PatternStr.substr(2), SM);
Eli Bendersky061d2ba2012-12-02 16:02:41 +0000237
Chris Lattner8879e062009-09-27 07:56:52 +0000238 if (End == StringRef::npos) {
239 SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
Chris Lattner03b80a42011-10-16 05:43:57 +0000240 SourceMgr::DK_Error,
241 "invalid named regex reference, no ]] found");
Chris Lattner8879e062009-09-27 07:56:52 +0000242 return true;
243 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000244
Eli Bendersky061d2ba2012-12-02 16:02:41 +0000245 StringRef MatchStr = PatternStr.substr(2, End);
246 PatternStr = PatternStr.substr(End+4);
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000247
Chris Lattner8879e062009-09-27 07:56:52 +0000248 // Get the regex name (e.g. "foo").
249 size_t NameEnd = MatchStr.find(':');
250 StringRef Name = MatchStr.substr(0, NameEnd);
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000251
Chris Lattner8879e062009-09-27 07:56:52 +0000252 if (Name.empty()) {
Chris Lattner03b80a42011-10-16 05:43:57 +0000253 SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
254 "invalid name in named regex: empty name");
Chris Lattner8879e062009-09-27 07:56:52 +0000255 return true;
256 }
257
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000258 // Verify that the name/expression is well formed. FileCheck currently
259 // supports @LINE, @LINE+number, @LINE-number expressions. The check here
260 // is relaxed, more strict check is performed in \c EvaluateExpression.
261 bool IsExpression = false;
262 for (unsigned i = 0, e = Name.size(); i != e; ++i) {
263 if (i == 0 && Name[i] == '@') {
264 if (NameEnd != StringRef::npos) {
265 SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
266 SourceMgr::DK_Error,
267 "invalid name in named regex definition");
268 return true;
269 }
270 IsExpression = true;
271 continue;
272 }
273 if (Name[i] != '_' && !isalnum(Name[i]) &&
274 (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
Chris Lattner8879e062009-09-27 07:56:52 +0000275 SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
Chris Lattner03b80a42011-10-16 05:43:57 +0000276 SourceMgr::DK_Error, "invalid name in named regex");
Chris Lattner8879e062009-09-27 07:56:52 +0000277 return true;
278 }
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000279 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000280
Chris Lattner8879e062009-09-27 07:56:52 +0000281 // Name can't start with a digit.
Guy Benyei83c74e92013-02-12 21:21:59 +0000282 if (isdigit(static_cast<unsigned char>(Name[0]))) {
Chris Lattner03b80a42011-10-16 05:43:57 +0000283 SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
284 "invalid name in named regex");
Chris Lattner8879e062009-09-27 07:56:52 +0000285 return true;
286 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000287
Chris Lattner8879e062009-09-27 07:56:52 +0000288 // Handle [[foo]].
289 if (NameEnd == StringRef::npos) {
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000290 // Handle variables that were defined earlier on the same line by
291 // emitting a backreference.
292 if (VariableDefs.find(Name) != VariableDefs.end()) {
293 unsigned VarParenNum = VariableDefs[Name];
294 if (VarParenNum < 1 || VarParenNum > 9) {
295 SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
296 SourceMgr::DK_Error,
297 "Can't back-reference more than 9 variables");
298 return true;
299 }
300 AddBackrefToRegEx(VarParenNum);
301 } else {
302 VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
303 }
Chris Lattner8879e062009-09-27 07:56:52 +0000304 continue;
305 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000306
Chris Lattner8879e062009-09-27 07:56:52 +0000307 // Handle [[foo:.*]].
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000308 VariableDefs[Name] = CurParen;
Chris Lattner8879e062009-09-27 07:56:52 +0000309 RegExStr += '(';
310 ++CurParen;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000311
Chris Lattner8879e062009-09-27 07:56:52 +0000312 if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
313 return true;
314
315 RegExStr += ')';
Chris Lattnerf08d2db2009-09-24 21:47:32 +0000316 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000317
Chris Lattner8879e062009-09-27 07:56:52 +0000318 // Handle fixed string matches.
319 // Find the end, which is the start of the next regex.
320 size_t FixedMatchEnd = PatternStr.find("{{");
321 FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
Hans Wennborg6f4f77b2013-12-12 00:06:41 +0000322 RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
Chris Lattner8879e062009-09-27 07:56:52 +0000323 PatternStr = PatternStr.substr(FixedMatchEnd);
Chris Lattnerf08d2db2009-09-24 21:47:32 +0000324 }
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000325
Chris Lattner74d50732009-09-24 20:39:13 +0000326 return false;
327}
328
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000329bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen,
Chris Lattner8879e062009-09-27 07:56:52 +0000330 SourceMgr &SM) {
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000331 Regex R(RS);
Chris Lattner8879e062009-09-27 07:56:52 +0000332 std::string Error;
333 if (!R.isValid(Error)) {
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000334 SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
Chris Lattner03b80a42011-10-16 05:43:57 +0000335 "invalid regex: " + Error);
Chris Lattner8879e062009-09-27 07:56:52 +0000336 return true;
337 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000338
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000339 RegExStr += RS.str();
Chris Lattner8879e062009-09-27 07:56:52 +0000340 CurParen += R.getNumMatches();
341 return false;
342}
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000343
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000344void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
345 assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
346 std::string Backref = std::string("\\") +
347 std::string(1, '0' + BackrefNum);
348 RegExStr += Backref;
349}
350
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000351bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
352 // The only supported expression is @LINE([\+-]\d+)?
353 if (!Expr.startswith("@LINE"))
354 return false;
355 Expr = Expr.substr(StringRef("@LINE").size());
356 int Offset = 0;
357 if (!Expr.empty()) {
358 if (Expr[0] == '+')
359 Expr = Expr.substr(1);
360 else if (Expr[0] != '-')
361 return false;
362 if (Expr.getAsInteger(10, Offset))
363 return false;
364 }
365 Value = llvm::itostr(LineNumber + Offset);
366 return true;
367}
368
Chris Lattnerf08d2db2009-09-24 21:47:32 +0000369/// Match - Match the pattern string against the input buffer Buffer. This
370/// returns the position that is matched or npos if there is no match. If
371/// there is a match, the size of the matched string is returned in MatchLen.
Chris Lattner8879e062009-09-27 07:56:52 +0000372size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
373 StringMap<StringRef> &VariableTable) const {
Jakob Stoklund Oleseneba55822010-10-15 17:47:12 +0000374 // If this is the EOF pattern, match it immediately.
Matt Arsenault38820972013-09-17 22:30:02 +0000375 if (CheckTy == Check::CheckEOF) {
Jakob Stoklund Oleseneba55822010-10-15 17:47:12 +0000376 MatchLen = 0;
377 return Buffer.size();
378 }
379
Chris Lattner221460e2009-09-25 17:09:12 +0000380 // If this is a fixed string pattern, just match it now.
381 if (!FixedStr.empty()) {
382 MatchLen = FixedStr.size();
383 return Buffer.find(FixedStr);
384 }
Chris Lattner8879e062009-09-27 07:56:52 +0000385
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000386 // Regex match.
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000387
Chris Lattner8879e062009-09-27 07:56:52 +0000388 // If there are variable uses, we need to create a temporary string with the
389 // actual value.
390 StringRef RegExToMatch = RegExStr;
391 std::string TmpStr;
392 if (!VariableUses.empty()) {
393 TmpStr = RegExStr;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000394
Chris Lattner8879e062009-09-27 07:56:52 +0000395 unsigned InsertOffset = 0;
396 for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
Chris Lattner8879e062009-09-27 07:56:52 +0000397 std::string Value;
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000398
399 if (VariableUses[i].first[0] == '@') {
400 if (!EvaluateExpression(VariableUses[i].first, Value))
401 return StringRef::npos;
402 } else {
403 StringMap<StringRef>::iterator it =
404 VariableTable.find(VariableUses[i].first);
405 // If the variable is undefined, return an error.
406 if (it == VariableTable.end())
407 return StringRef::npos;
408
Hans Wennborg6f4f77b2013-12-12 00:06:41 +0000409 // Look up the value and escape it so that we can put it into the regex.
410 Value += Regex::escape(it->second);
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000411 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000412
Chris Lattner8879e062009-09-27 07:56:52 +0000413 // Plop it into the regex at the adjusted offset.
414 TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset,
415 Value.begin(), Value.end());
416 InsertOffset += Value.size();
417 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000418
Chris Lattner8879e062009-09-27 07:56:52 +0000419 // Match the newly constructed regex.
420 RegExToMatch = TmpStr;
421 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000422
423
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000424 SmallVector<StringRef, 4> MatchInfo;
Chris Lattner8879e062009-09-27 07:56:52 +0000425 if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000426 return StringRef::npos;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000427
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000428 // Successful regex match.
429 assert(!MatchInfo.empty() && "Didn't get any match");
430 StringRef FullMatch = MatchInfo[0];
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000431
Chris Lattner8879e062009-09-27 07:56:52 +0000432 // If this defines any variables, remember their values.
Eli Benderskye8b8f1b2012-12-01 21:54:48 +0000433 for (std::map<StringRef, unsigned>::const_iterator I = VariableDefs.begin(),
434 E = VariableDefs.end();
435 I != E; ++I) {
436 assert(I->second < MatchInfo.size() && "Internal paren error");
437 VariableTable[I->first] = MatchInfo[I->second];
Chris Lattner0a4c44b2009-09-25 17:29:36 +0000438 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000439
Chris Lattnerb16ab0c2009-09-25 17:23:43 +0000440 MatchLen = FullMatch.size();
441 return FullMatch.data()-Buffer.data();
Chris Lattnerf08d2db2009-09-24 21:47:32 +0000442}
443
Daniel Dunbarfd29d882009-11-22 22:59:26 +0000444unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
445 const StringMap<StringRef> &VariableTable) const {
446 // Just compute the number of matching characters. For regular expressions, we
447 // just compare against the regex itself and hope for the best.
448 //
449 // FIXME: One easy improvement here is have the regex lib generate a single
450 // example regular expression which matches, and use that as the example
451 // string.
452 StringRef ExampleString(FixedStr);
453 if (ExampleString.empty())
454 ExampleString = RegExStr;
455
Daniel Dunbare9aa36c2010-01-30 00:24:06 +0000456 // Only compare up to the first line in the buffer, or the string size.
457 StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
458 BufferPrefix = BufferPrefix.split('\n').first;
459 return BufferPrefix.edit_distance(ExampleString);
Daniel Dunbarfd29d882009-11-22 22:59:26 +0000460}
461
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000462void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
463 const StringMap<StringRef> &VariableTable) const{
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000464 // If this was a regular expression using variables, print the current
465 // variable values.
466 if (!VariableUses.empty()) {
467 for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
Alp Tokere69170a2014-06-26 22:52:05 +0000468 SmallString<256> Msg;
469 raw_svector_ostream OS(Msg);
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000470 StringRef Var = VariableUses[i].first;
471 if (Var[0] == '@') {
472 std::string Value;
473 if (EvaluateExpression(Var, Value)) {
474 OS << "with expression \"";
475 OS.write_escaped(Var) << "\" equal to \"";
476 OS.write_escaped(Value) << "\"";
477 } else {
478 OS << "uses incorrect expression \"";
479 OS.write_escaped(Var) << "\"";
480 }
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000481 } else {
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000482 StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
483
484 // Check for undefined variable references.
485 if (it == VariableTable.end()) {
486 OS << "uses undefined variable \"";
487 OS.write_escaped(Var) << "\"";
488 } else {
489 OS << "with variable \"";
490 OS.write_escaped(Var) << "\" equal to \"";
491 OS.write_escaped(it->second) << "\"";
492 }
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000493 }
494
Chris Lattner03b80a42011-10-16 05:43:57 +0000495 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
496 OS.str());
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000497 }
498 }
Daniel Dunbarfd29d882009-11-22 22:59:26 +0000499
500 // Attempt to find the closest/best fuzzy match. Usually an error happens
501 // because some string in the output didn't exactly match. In these cases, we
502 // would like to show the user a best guess at what "should have" matched, to
503 // save them having to actually check the input manually.
504 size_t NumLinesForward = 0;
505 size_t Best = StringRef::npos;
506 double BestQuality = 0;
507
508 // Use an arbitrary 4k limit on how far we will search.
Dan Gohman2bf486e2010-01-29 21:57:46 +0000509 for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
Daniel Dunbarfd29d882009-11-22 22:59:26 +0000510 if (Buffer[i] == '\n')
511 ++NumLinesForward;
512
Dan Gohmandf22bbf2010-01-29 21:55:16 +0000513 // Patterns have leading whitespace stripped, so skip whitespace when
514 // looking for something which looks like a pattern.
515 if (Buffer[i] == ' ' || Buffer[i] == '\t')
516 continue;
517
Daniel Dunbarfd29d882009-11-22 22:59:26 +0000518 // Compute the "quality" of this match as an arbitrary combination of the
519 // match distance and the number of lines skipped to get to this match.
520 unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
521 double Quality = Distance + (NumLinesForward / 100.);
522
523 if (Quality < BestQuality || Best == StringRef::npos) {
524 Best = i;
525 BestQuality = Quality;
526 }
527 }
528
Daniel Dunbarc069cc82010-03-19 18:07:43 +0000529 // Print the "possible intended match here" line if we found something
530 // reasonable and not equal to what we showed in the "scanning from here"
531 // line.
532 if (Best && Best != StringRef::npos && BestQuality < 50) {
533 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
Chris Lattner03b80a42011-10-16 05:43:57 +0000534 SourceMgr::DK_Note, "possible intended match here");
Daniel Dunbarfd29d882009-11-22 22:59:26 +0000535
536 // FIXME: If we wanted to be really friendly we would show why the match
537 // failed, as it can be hard to spot simple one character differences.
538 }
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000539}
Chris Lattner74d50732009-09-24 20:39:13 +0000540
Adrian Prantl81e5cd92014-01-03 21:49:09 +0000541size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
Eli Bendersky061d2ba2012-12-02 16:02:41 +0000542 // Offset keeps track of the current offset within the input Str
543 size_t Offset = 0;
544 // [...] Nesting depth
545 size_t BracketDepth = 0;
546
547 while (!Str.empty()) {
548 if (Str.startswith("]]") && BracketDepth == 0)
549 return Offset;
550 if (Str[0] == '\\') {
551 // Backslash escapes the next char within regexes, so skip them both.
552 Str = Str.substr(2);
553 Offset += 2;
554 } else {
555 switch (Str[0]) {
556 default:
557 break;
558 case '[':
559 BracketDepth++;
560 break;
561 case ']':
Adrian Prantl81e5cd92014-01-03 21:49:09 +0000562 if (BracketDepth == 0) {
563 SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
564 SourceMgr::DK_Error,
565 "missing closing \"]\" for regex variable");
566 exit(1);
567 }
Eli Bendersky061d2ba2012-12-02 16:02:41 +0000568 BracketDepth--;
569 break;
570 }
571 Str = Str.substr(1);
572 Offset++;
573 }
574 }
575
576 return StringRef::npos;
577}
578
579
Chris Lattner74d50732009-09-24 20:39:13 +0000580//===----------------------------------------------------------------------===//
581// Check Strings.
582//===----------------------------------------------------------------------===//
Chris Lattner3b40b442009-09-24 20:25:55 +0000583
584/// CheckString - This is a check that we found in the input file.
585struct CheckString {
586 /// Pat - The pattern to match.
587 Pattern Pat;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000588
Matt Arsenault13df4622013-11-10 02:04:09 +0000589 /// Prefix - Which prefix name this check matched.
590 StringRef Prefix;
591
Chris Lattner26cccfe2009-08-15 17:41:04 +0000592 /// Loc - The location in the match file that the check string was specified.
593 SMLoc Loc;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000594
Matt Arsenault38820972013-09-17 22:30:02 +0000595 /// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive,
596 /// as opposed to a CHECK: directive.
597 Check::CheckType CheckTy;
Stephen Linf8bd2e52013-07-12 14:51:05 +0000598
Michael Liao91a1b2c2013-05-14 20:34:12 +0000599 /// DagNotStrings - These are all of the strings that are disallowed from
Chris Lattner236d2d52009-09-20 22:35:26 +0000600 /// occurring between this match string and the previous one (or start of
601 /// file).
Michael Liao91a1b2c2013-05-14 20:34:12 +0000602 std::vector<Pattern> DagNotStrings;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000603
Matt Arsenault13df4622013-11-10 02:04:09 +0000604
605 CheckString(const Pattern &P,
606 StringRef S,
607 SMLoc L,
608 Check::CheckType Ty)
609 : Pat(P), Prefix(S), Loc(L), CheckTy(Ty) {}
Michael Liaodcc7d482013-05-14 20:29:52 +0000610
Michael Liao91a1b2c2013-05-14 20:34:12 +0000611 /// Check - Match check string and its "not strings" and/or "dag strings".
Stephen Line93a3a02013-10-11 18:38:36 +0000612 size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
Stephen Linf8bd2e52013-07-12 14:51:05 +0000613 size_t &MatchLen, StringMap<StringRef> &VariableTable) const;
Michael Liaodcc7d482013-05-14 20:29:52 +0000614
615 /// CheckNext - Verify there is a single line in the given buffer.
616 bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
617
618 /// CheckNot - Verify there's no "not strings" in the given buffer.
619 bool CheckNot(const SourceMgr &SM, StringRef Buffer,
Michael Liao91a1b2c2013-05-14 20:34:12 +0000620 const std::vector<const Pattern *> &NotStrings,
Michael Liaodcc7d482013-05-14 20:29:52 +0000621 StringMap<StringRef> &VariableTable) const;
Michael Liao91a1b2c2013-05-14 20:34:12 +0000622
623 /// CheckDag - Match "dag strings" and their mixed "not strings".
624 size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
625 std::vector<const Pattern *> &NotStrings,
626 StringMap<StringRef> &VariableTable) const;
Chris Lattner26cccfe2009-08-15 17:41:04 +0000627};
628
Guy Benyei5ea04c32013-02-06 20:40:38 +0000629/// Canonicalize whitespaces in the input file. Line endings are replaced
630/// with UNIX-style '\n'.
631///
632/// \param PreserveHorizontal Don't squash consecutive horizontal whitespace
633/// characters to a single space.
Rafael Espindolace5dd1a2014-08-01 14:11:14 +0000634static MemoryBuffer *CanonicalizeInputFile(std::unique_ptr<MemoryBuffer> MB,
Guy Benyei5ea04c32013-02-06 20:40:38 +0000635 bool PreserveHorizontal) {
Chris Lattner0e45d242010-04-05 22:42:30 +0000636 SmallString<128> NewFile;
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000637 NewFile.reserve(MB->getBufferSize());
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000638
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000639 for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
640 Ptr != End; ++Ptr) {
NAKAMURA Takumifd781bf2010-11-14 03:28:22 +0000641 // Eliminate trailing dosish \r.
642 if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
643 continue;
644 }
645
Michael Liao61bed2f2013-04-25 18:54:02 +0000646 // If current char is not a horizontal whitespace or if horizontal
Guy Benyei5ea04c32013-02-06 20:40:38 +0000647 // whitespace canonicalization is disabled, dump it to output as is.
648 if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) {
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000649 NewFile.push_back(*Ptr);
650 continue;
651 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000652
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000653 // Otherwise, add one space and advance over neighboring space.
654 NewFile.push_back(' ');
655 while (Ptr+1 != End &&
656 (Ptr[1] == ' ' || Ptr[1] == '\t'))
657 ++Ptr;
658 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000659
Rafael Espindolace5dd1a2014-08-01 14:11:14 +0000660 return MemoryBuffer::getMemBufferCopy(NewFile.str(),
661 MB->getBufferIdentifier());
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000662}
663
Matt Arsenault38820972013-09-17 22:30:02 +0000664static bool IsPartOfWord(char c) {
665 return (isalnum(c) || c == '-' || c == '_');
666}
667
Matt Arsenault13df4622013-11-10 02:04:09 +0000668// Get the size of the prefix extension.
669static size_t CheckTypeSize(Check::CheckType Ty) {
670 switch (Ty) {
671 case Check::CheckNone:
672 return 0;
673
674 case Check::CheckPlain:
675 return sizeof(":") - 1;
676
677 case Check::CheckNext:
678 return sizeof("-NEXT:") - 1;
679
680 case Check::CheckNot:
681 return sizeof("-NOT:") - 1;
682
683 case Check::CheckDAG:
684 return sizeof("-DAG:") - 1;
685
686 case Check::CheckLabel:
687 return sizeof("-LABEL:") - 1;
688
689 case Check::CheckEOF:
690 llvm_unreachable("Should not be using EOF size");
691 }
692
693 llvm_unreachable("Bad check type");
694}
695
696static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
Matt Arsenaultc4d2d472013-09-17 22:45:57 +0000697 char NextChar = Buffer[Prefix.size()];
Matt Arsenault38820972013-09-17 22:30:02 +0000698
699 // Verify that the : is present after the prefix.
Matt Arsenault13df4622013-11-10 02:04:09 +0000700 if (NextChar == ':')
Matt Arsenault38820972013-09-17 22:30:02 +0000701 return Check::CheckPlain;
Matt Arsenault38820972013-09-17 22:30:02 +0000702
Matt Arsenault13df4622013-11-10 02:04:09 +0000703 if (NextChar != '-')
Matt Arsenault38820972013-09-17 22:30:02 +0000704 return Check::CheckNone;
Matt Arsenault38820972013-09-17 22:30:02 +0000705
Matt Arsenaultc4d2d472013-09-17 22:45:57 +0000706 StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
Matt Arsenault13df4622013-11-10 02:04:09 +0000707 if (Rest.startswith("NEXT:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000708 return Check::CheckNext;
Matt Arsenault38820972013-09-17 22:30:02 +0000709
Matt Arsenault13df4622013-11-10 02:04:09 +0000710 if (Rest.startswith("NOT:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000711 return Check::CheckNot;
Matt Arsenault38820972013-09-17 22:30:02 +0000712
Matt Arsenault13df4622013-11-10 02:04:09 +0000713 if (Rest.startswith("DAG:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000714 return Check::CheckDAG;
Matt Arsenault38820972013-09-17 22:30:02 +0000715
Matt Arsenault13df4622013-11-10 02:04:09 +0000716 if (Rest.startswith("LABEL:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000717 return Check::CheckLabel;
Matt Arsenault13df4622013-11-10 02:04:09 +0000718
719 return Check::CheckNone;
720}
721
722// From the given position, find the next character after the word.
723static size_t SkipWord(StringRef Str, size_t Loc) {
724 while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
725 ++Loc;
726 return Loc;
727}
728
729// Try to find the first match in buffer for any prefix. If a valid match is
730// found, return that prefix and set its type and location. If there are almost
731// matches (e.g. the actual prefix string is found, but is not an actual check
732// string), but no valid match, return an empty string and set the position to
733// resume searching from. If no partial matches are found, return an empty
734// string and the location will be StringRef::npos. If one prefix is a substring
735// of another, the maximal match should be found. e.g. if "A" and "AA" are
736// prefixes then AA-CHECK: should match the second one.
737static StringRef FindFirstCandidateMatch(StringRef &Buffer,
738 Check::CheckType &CheckTy,
739 size_t &CheckLoc) {
740 StringRef FirstPrefix;
741 size_t FirstLoc = StringRef::npos;
742 size_t SearchLoc = StringRef::npos;
743 Check::CheckType FirstTy = Check::CheckNone;
744
745 CheckTy = Check::CheckNone;
746 CheckLoc = StringRef::npos;
747
748 for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
749 I != E; ++I) {
750 StringRef Prefix(*I);
751 size_t PrefixLoc = Buffer.find(Prefix);
752
753 if (PrefixLoc == StringRef::npos)
754 continue;
755
756 // Track where we are searching for invalid prefixes that look almost right.
757 // We need to only advance to the first partial match on the next attempt
758 // since a partial match could be a substring of a later, valid prefix.
759 // Need to skip to the end of the word, otherwise we could end up
760 // matching a prefix in a substring later.
761 if (PrefixLoc < SearchLoc)
762 SearchLoc = SkipWord(Buffer, PrefixLoc);
763
764 // We only want to find the first match to avoid skipping some.
765 if (PrefixLoc > FirstLoc)
766 continue;
Alexey Samsonova7181a12013-11-13 14:12:52 +0000767 // If one matching check-prefix is a prefix of another, choose the
768 // longer one.
769 if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size())
770 continue;
Matt Arsenault13df4622013-11-10 02:04:09 +0000771
772 StringRef Rest = Buffer.drop_front(PrefixLoc);
773 // Make sure we have actually found the prefix, and not a word containing
774 // it. This should also prevent matching the wrong prefix when one is a
775 // substring of another.
776 if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
Daniel Sanders43b5f572013-11-20 13:25:05 +0000777 FirstTy = Check::CheckNone;
778 else
779 FirstTy = FindCheckType(Rest, Prefix);
Matt Arsenault13df4622013-11-10 02:04:09 +0000780
Matt Arsenault13df4622013-11-10 02:04:09 +0000781 FirstLoc = PrefixLoc;
Alexey Samsonova7181a12013-11-13 14:12:52 +0000782 FirstPrefix = Prefix;
Matt Arsenault38820972013-09-17 22:30:02 +0000783 }
784
Alexey Samsonova7181a12013-11-13 14:12:52 +0000785 // If the first prefix is invalid, we should continue the search after it.
786 if (FirstTy == Check::CheckNone) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000787 CheckLoc = SearchLoc;
Alexey Samsonova7181a12013-11-13 14:12:52 +0000788 return "";
Matt Arsenault13df4622013-11-10 02:04:09 +0000789 }
790
Alexey Samsonova7181a12013-11-13 14:12:52 +0000791 CheckTy = FirstTy;
792 CheckLoc = FirstLoc;
Matt Arsenault13df4622013-11-10 02:04:09 +0000793 return FirstPrefix;
794}
795
796static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
797 unsigned &LineNumber,
798 Check::CheckType &CheckTy,
799 size_t &CheckLoc) {
800 while (!Buffer.empty()) {
801 StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc);
802 // If we found a real match, we are done.
803 if (!Prefix.empty()) {
804 LineNumber += Buffer.substr(0, CheckLoc).count('\n');
805 return Prefix;
806 }
807
808 // We didn't find any almost matches either, we are also done.
809 if (CheckLoc == StringRef::npos)
810 return StringRef();
811
812 LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
813
814 // Advance to the last possible match we found and try again.
815 Buffer = Buffer.drop_front(CheckLoc + 1);
816 }
817
818 return StringRef();
Matt Arsenault38820972013-09-17 22:30:02 +0000819}
Chris Lattneree3c74f2009-07-08 18:44:05 +0000820
Chris Lattneree3c74f2009-07-08 18:44:05 +0000821/// ReadCheckFile - Read the check file, which specifies the sequence of
822/// expected strings. The strings are added to the CheckStrings vector.
Eli Bendersky43d50d42012-11-30 14:22:14 +0000823/// Returns true in case of an error, false otherwise.
Chris Lattneree3c74f2009-07-08 18:44:05 +0000824static bool ReadCheckFile(SourceMgr &SM,
Chris Lattner26cccfe2009-08-15 17:41:04 +0000825 std::vector<CheckString> &CheckStrings) {
Rafael Espindolaadf21f22014-07-06 17:43:13 +0000826 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
827 MemoryBuffer::getFileOrSTDIN(CheckFilename);
828 if (std::error_code EC = FileOrErr.getError()) {
829 errs() << "Could not open check file '" << CheckFilename
830 << "': " << EC.message() << '\n';
Chris Lattneree3c74f2009-07-08 18:44:05 +0000831 return true;
832 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000833
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000834 // If we want to canonicalize whitespace, strip excess whitespace from the
Guy Benyei5ea04c32013-02-06 20:40:38 +0000835 // buffer containing the CHECK lines. Remove DOS style line endings.
Rafael Espindolace5dd1a2014-08-01 14:11:14 +0000836 MemoryBuffer *F = CanonicalizeInputFile(std::move(FileOrErr.get()),
Rafael Espindolaadf21f22014-07-06 17:43:13 +0000837 NoCanonicalizeWhiteSpace);
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000838
Chris Lattneree3c74f2009-07-08 18:44:05 +0000839 SM.AddNewSourceBuffer(F, SMLoc());
840
Chris Lattner10f10ce2009-08-15 18:00:42 +0000841 // Find all instances of CheckPrefix followed by : in the file.
Chris Lattnercaa5fc02009-09-20 22:11:44 +0000842 StringRef Buffer = F->getBuffer();
Alexander Kornienko56ccdbb2014-07-11 12:39:32 +0000843
844 std::vector<Pattern> ImplicitNegativeChecks;
845 for (const auto &PatternString : ImplicitCheckNot) {
846 // Create a buffer with fake command line content in order to display the
847 // command line option responsible for the specific implicit CHECK-NOT.
848 std::string Prefix = std::string("-") + ImplicitCheckNot.ArgStr + "='";
849 std::string Suffix = "'";
850 MemoryBuffer *CmdLine = MemoryBuffer::getMemBufferCopy(
851 Prefix + PatternString + Suffix, "command line");
852 StringRef PatternInBuffer =
853 CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
854 SM.AddNewSourceBuffer(CmdLine, SMLoc());
855
856 ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
857 ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
858 "IMPLICIT-CHECK", SM, 0);
859 }
860
861
862 std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000863
Eli Bendersky43d50d42012-11-30 14:22:14 +0000864 // LineNumber keeps track of the line on which CheckPrefix instances are
865 // found.
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000866 unsigned LineNumber = 1;
867
Chris Lattneree3c74f2009-07-08 18:44:05 +0000868 while (1) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000869 Check::CheckType CheckTy;
870 size_t PrefixLoc;
871
872 // See if a prefix occurs in the memory buffer.
873 StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
874 LineNumber,
875 CheckTy,
876 PrefixLoc);
877 if (UsedPrefix.empty())
Chris Lattneree3c74f2009-07-08 18:44:05 +0000878 break;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000879
Matt Arsenault13df4622013-11-10 02:04:09 +0000880 Buffer = Buffer.drop_front(PrefixLoc);
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000881
Matt Arsenault13df4622013-11-10 02:04:09 +0000882 // Location to use for error messages.
883 const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000884
Matt Arsenault13df4622013-11-10 02:04:09 +0000885 // PrefixLoc is to the start of the prefix. Skip to the end.
886 Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000887
Matt Arsenault38820972013-09-17 22:30:02 +0000888 // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
889 // leading and trailing whitespace.
Chris Lattner236d2d52009-09-20 22:35:26 +0000890 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000891
Chris Lattneree3c74f2009-07-08 18:44:05 +0000892 // Scan ahead to the end of line.
Chris Lattnercaa5fc02009-09-20 22:11:44 +0000893 size_t EOL = Buffer.find_first_of("\n\r");
Chris Lattner74d50732009-09-24 20:39:13 +0000894
Dan Gohman838fb092010-01-29 21:53:18 +0000895 // Remember the location of the start of the pattern, for diagnostics.
896 SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
897
Chris Lattner74d50732009-09-24 20:39:13 +0000898 // Parse the pattern.
Matt Arsenault38820972013-09-17 22:30:02 +0000899 Pattern P(CheckTy);
Matt Arsenault13df4622013-11-10 02:04:09 +0000900 if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
Chris Lattneree3c74f2009-07-08 18:44:05 +0000901 return true;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000902
Stephen Linf8bd2e52013-07-12 14:51:05 +0000903 // Verify that CHECK-LABEL lines do not define or use variables
Matt Arsenault38820972013-09-17 22:30:02 +0000904 if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000905 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
Stephen Linf8bd2e52013-07-12 14:51:05 +0000906 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +0000907 "found '" + UsedPrefix + "-LABEL:'"
908 " with variable definition or use");
Stephen Linf8bd2e52013-07-12 14:51:05 +0000909 return true;
910 }
911
Chris Lattner74d50732009-09-24 20:39:13 +0000912 Buffer = Buffer.substr(EOL);
913
Chris Lattnerda108b42009-08-15 18:32:21 +0000914 // Verify that CHECK-NEXT lines have at least one CHECK line before them.
Matt Arsenault38820972013-09-17 22:30:02 +0000915 if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000916 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
Chris Lattner03b80a42011-10-16 05:43:57 +0000917 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +0000918 "found '" + UsedPrefix + "-NEXT:' without previous '"
919 + UsedPrefix + ": line");
Chris Lattnerda108b42009-08-15 18:32:21 +0000920 return true;
921 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000922
Michael Liao91a1b2c2013-05-14 20:34:12 +0000923 // Handle CHECK-DAG/-NOT.
Matt Arsenault38820972013-09-17 22:30:02 +0000924 if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
Michael Liao91a1b2c2013-05-14 20:34:12 +0000925 DagNotMatches.push_back(P);
Chris Lattner74d50732009-09-24 20:39:13 +0000926 continue;
927 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000928
Chris Lattneree3c74f2009-07-08 18:44:05 +0000929 // Okay, add the string we captured to the output vector and move on.
Chris Lattner3b40b442009-09-24 20:25:55 +0000930 CheckStrings.push_back(CheckString(P,
Matt Arsenault13df4622013-11-10 02:04:09 +0000931 UsedPrefix,
Dan Gohman838fb092010-01-29 21:53:18 +0000932 PatternLoc,
Matt Arsenault38820972013-09-17 22:30:02 +0000933 CheckTy));
Michael Liao91a1b2c2013-05-14 20:34:12 +0000934 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
Alexander Kornienko56ccdbb2014-07-11 12:39:32 +0000935 DagNotMatches = ImplicitNegativeChecks;
Chris Lattneree3c74f2009-07-08 18:44:05 +0000936 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000937
Matt Arsenault13df4622013-11-10 02:04:09 +0000938 // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
939 // prefix as a filler for the error message.
Michael Liao91a1b2c2013-05-14 20:34:12 +0000940 if (!DagNotMatches.empty()) {
Matt Arsenault38820972013-09-17 22:30:02 +0000941 CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF),
Matt Arsenault13df4622013-11-10 02:04:09 +0000942 CheckPrefixes[0],
Jakob Stoklund Oleseneba55822010-10-15 17:47:12 +0000943 SMLoc::getFromPointer(Buffer.data()),
Matt Arsenault38820972013-09-17 22:30:02 +0000944 Check::CheckEOF));
Michael Liao91a1b2c2013-05-14 20:34:12 +0000945 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
Jakob Stoklund Oleseneba55822010-10-15 17:47:12 +0000946 }
947
Chris Lattneree3c74f2009-07-08 18:44:05 +0000948 if (CheckStrings.empty()) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000949 errs() << "error: no check strings found with prefix"
950 << (CheckPrefixes.size() > 1 ? "es " : " ");
951 for (size_t I = 0, N = CheckPrefixes.size(); I != N; ++I) {
952 StringRef Prefix(CheckPrefixes[I]);
953 errs() << '\'' << Prefix << ":'";
954 if (I != N - 1)
955 errs() << ", ";
956 }
957
958 errs() << '\n';
Chris Lattneree3c74f2009-07-08 18:44:05 +0000959 return true;
960 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000961
Chris Lattneree3c74f2009-07-08 18:44:05 +0000962 return false;
963}
964
Michael Liao91a1b2c2013-05-14 20:34:12 +0000965static void PrintCheckFailed(const SourceMgr &SM, const SMLoc &Loc,
966 const Pattern &Pat, StringRef Buffer,
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000967 StringMap<StringRef> &VariableTable) {
Chris Lattnerda108b42009-08-15 18:32:21 +0000968 // Otherwise, we have an error, emit an error message.
Michael Liao91a1b2c2013-05-14 20:34:12 +0000969 SM.PrintMessage(Loc, SourceMgr::DK_Error,
Chris Lattner03b80a42011-10-16 05:43:57 +0000970 "expected string not found in input");
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000971
Chris Lattnerda108b42009-08-15 18:32:21 +0000972 // Print the "scanning from here" line. If the current position is at the
973 // end of a line, advance to the start of the next line.
Chris Lattnercaa5fc02009-09-20 22:11:44 +0000974 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000975
Chris Lattner03b80a42011-10-16 05:43:57 +0000976 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
977 "scanning from here");
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000978
979 // Allow the pattern to print additional information if desired.
Michael Liao91a1b2c2013-05-14 20:34:12 +0000980 Pat.PrintFailureInfo(SM, Buffer, VariableTable);
981}
982
983static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
984 StringRef Buffer,
985 StringMap<StringRef> &VariableTable) {
986 PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
Chris Lattnerda108b42009-08-15 18:32:21 +0000987}
988
Chris Lattner37183582009-09-20 22:42:44 +0000989/// CountNumNewlinesBetween - Count the number of newlines in the specified
990/// range.
Richard Smith592fe882014-04-07 17:09:53 +0000991static unsigned CountNumNewlinesBetween(StringRef Range,
992 const char *&FirstNewLine) {
Chris Lattnerda108b42009-08-15 18:32:21 +0000993 unsigned NumNewLines = 0;
Chris Lattner37183582009-09-20 22:42:44 +0000994 while (1) {
Chris Lattnerda108b42009-08-15 18:32:21 +0000995 // Scan for newline.
Chris Lattner37183582009-09-20 22:42:44 +0000996 Range = Range.substr(Range.find_first_of("\n\r"));
997 if (Range.empty()) return NumNewLines;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000998
Chris Lattnerda108b42009-08-15 18:32:21 +0000999 ++NumNewLines;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001000
Chris Lattnerda108b42009-08-15 18:32:21 +00001001 // Handle \n\r and \r\n as a single newline.
Chris Lattner37183582009-09-20 22:42:44 +00001002 if (Range.size() > 1 &&
1003 (Range[1] == '\n' || Range[1] == '\r') &&
1004 (Range[0] != Range[1]))
1005 Range = Range.substr(1);
1006 Range = Range.substr(1);
Richard Smith592fe882014-04-07 17:09:53 +00001007
1008 if (NumNewLines == 1)
1009 FirstNewLine = Range.begin();
Chris Lattnerda108b42009-08-15 18:32:21 +00001010 }
Chris Lattnerda108b42009-08-15 18:32:21 +00001011}
1012
Michael Liaodcc7d482013-05-14 20:29:52 +00001013size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
Stephen Line93a3a02013-10-11 18:38:36 +00001014 bool IsLabelScanMode, size_t &MatchLen,
Michael Liaodcc7d482013-05-14 20:29:52 +00001015 StringMap<StringRef> &VariableTable) const {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001016 size_t LastPos = 0;
1017 std::vector<const Pattern *> NotStrings;
1018
Stephen Line93a3a02013-10-11 18:38:36 +00001019 // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
1020 // bounds; we have not processed variable definitions within the bounded block
1021 // yet so cannot handle any final CHECK-DAG yet; this is handled when going
1022 // over the block again (including the last CHECK-LABEL) in normal mode.
1023 if (!IsLabelScanMode) {
1024 // Match "dag strings" (with mixed "not strings" if any).
1025 LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable);
1026 if (LastPos == StringRef::npos)
1027 return StringRef::npos;
1028 }
Michael Liao91a1b2c2013-05-14 20:34:12 +00001029
1030 // Match itself from the last position after matching CHECK-DAG.
1031 StringRef MatchBuffer = Buffer.substr(LastPos);
1032 size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
Michael Liaodcc7d482013-05-14 20:29:52 +00001033 if (MatchPos == StringRef::npos) {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001034 PrintCheckFailed(SM, *this, MatchBuffer, VariableTable);
Michael Liaodcc7d482013-05-14 20:29:52 +00001035 return StringRef::npos;
1036 }
Michael Liao91a1b2c2013-05-14 20:34:12 +00001037 MatchPos += LastPos;
Michael Liaodcc7d482013-05-14 20:29:52 +00001038
Stephen Line93a3a02013-10-11 18:38:36 +00001039 // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
1040 // or CHECK-NOT
1041 if (!IsLabelScanMode) {
Stephen Linf8bd2e52013-07-12 14:51:05 +00001042 StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
Michael Liaodcc7d482013-05-14 20:29:52 +00001043
Stephen Linf8bd2e52013-07-12 14:51:05 +00001044 // If this check is a "CHECK-NEXT", verify that the previous match was on
1045 // the previous line (i.e. that there is one newline between them).
1046 if (CheckNext(SM, SkippedRegion))
1047 return StringRef::npos;
Michael Liaodcc7d482013-05-14 20:29:52 +00001048
Stephen Linf8bd2e52013-07-12 14:51:05 +00001049 // If this match had "not strings", verify that they don't exist in the
1050 // skipped region.
1051 if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
1052 return StringRef::npos;
1053 }
Michael Liaodcc7d482013-05-14 20:29:52 +00001054
1055 return MatchPos;
1056}
1057
1058bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
Matt Arsenault38820972013-09-17 22:30:02 +00001059 if (CheckTy != Check::CheckNext)
Michael Liaodcc7d482013-05-14 20:29:52 +00001060 return false;
1061
1062 // Count the number of newlines between the previous match and this one.
1063 assert(Buffer.data() !=
1064 SM.getMemoryBuffer(
1065 SM.FindBufferContainingLoc(
1066 SMLoc::getFromPointer(Buffer.data())))->getBufferStart() &&
1067 "CHECK-NEXT can't be the first check in a file");
1068
Craig Topper66f09ad2014-06-08 22:29:17 +00001069 const char *FirstNewLine = nullptr;
Richard Smith592fe882014-04-07 17:09:53 +00001070 unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
Michael Liaodcc7d482013-05-14 20:29:52 +00001071
1072 if (NumNewLines == 0) {
Matt Arsenault13df4622013-11-10 02:04:09 +00001073 SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
Michael Liaodcc7d482013-05-14 20:29:52 +00001074 "-NEXT: is on the same line as previous match");
1075 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1076 SourceMgr::DK_Note, "'next' match was here");
1077 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1078 "previous match ended here");
1079 return true;
1080 }
1081
1082 if (NumNewLines != 1) {
Matt Arsenault13df4622013-11-10 02:04:09 +00001083 SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
Michael Liaodcc7d482013-05-14 20:29:52 +00001084 "-NEXT: is not on the line after the previous match");
1085 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1086 SourceMgr::DK_Note, "'next' match was here");
1087 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1088 "previous match ended here");
Richard Smith592fe882014-04-07 17:09:53 +00001089 SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
1090 "non-matching line after previous match is here");
Michael Liaodcc7d482013-05-14 20:29:52 +00001091 return true;
1092 }
1093
1094 return false;
1095}
1096
1097bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
Michael Liao91a1b2c2013-05-14 20:34:12 +00001098 const std::vector<const Pattern *> &NotStrings,
Michael Liaodcc7d482013-05-14 20:29:52 +00001099 StringMap<StringRef> &VariableTable) const {
1100 for (unsigned ChunkNo = 0, e = NotStrings.size();
1101 ChunkNo != e; ++ChunkNo) {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001102 const Pattern *Pat = NotStrings[ChunkNo];
Matt Arsenault38820972013-09-17 22:30:02 +00001103 assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
Michael Liao91a1b2c2013-05-14 20:34:12 +00001104
Michael Liaodcc7d482013-05-14 20:29:52 +00001105 size_t MatchLen = 0;
Michael Liao91a1b2c2013-05-14 20:34:12 +00001106 size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
Michael Liaodcc7d482013-05-14 20:29:52 +00001107
1108 if (Pos == StringRef::npos) continue;
1109
1110 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos),
1111 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +00001112 Prefix + "-NOT: string occurred!");
Michael Liao91a1b2c2013-05-14 20:34:12 +00001113 SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001114 Prefix + "-NOT: pattern specified here");
Michael Liaodcc7d482013-05-14 20:29:52 +00001115 return true;
1116 }
1117
1118 return false;
1119}
1120
Michael Liao91a1b2c2013-05-14 20:34:12 +00001121size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
1122 std::vector<const Pattern *> &NotStrings,
1123 StringMap<StringRef> &VariableTable) const {
1124 if (DagNotStrings.empty())
1125 return 0;
1126
1127 size_t LastPos = 0;
1128 size_t StartPos = LastPos;
1129
1130 for (unsigned ChunkNo = 0, e = DagNotStrings.size();
1131 ChunkNo != e; ++ChunkNo) {
1132 const Pattern &Pat = DagNotStrings[ChunkNo];
1133
Matt Arsenault38820972013-09-17 22:30:02 +00001134 assert((Pat.getCheckTy() == Check::CheckDAG ||
1135 Pat.getCheckTy() == Check::CheckNot) &&
Michael Liao91a1b2c2013-05-14 20:34:12 +00001136 "Invalid CHECK-DAG or CHECK-NOT!");
1137
Matt Arsenault38820972013-09-17 22:30:02 +00001138 if (Pat.getCheckTy() == Check::CheckNot) {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001139 NotStrings.push_back(&Pat);
1140 continue;
1141 }
1142
Matt Arsenault38820972013-09-17 22:30:02 +00001143 assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
Michael Liao91a1b2c2013-05-14 20:34:12 +00001144
1145 size_t MatchLen = 0, MatchPos;
1146
1147 // CHECK-DAG always matches from the start.
1148 StringRef MatchBuffer = Buffer.substr(StartPos);
1149 MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
1150 // With a group of CHECK-DAGs, a single mismatching means the match on
1151 // that group of CHECK-DAGs fails immediately.
1152 if (MatchPos == StringRef::npos) {
1153 PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
1154 return StringRef::npos;
1155 }
1156 // Re-calc it as the offset relative to the start of the original string.
1157 MatchPos += StartPos;
1158
1159 if (!NotStrings.empty()) {
1160 if (MatchPos < LastPos) {
1161 // Reordered?
1162 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
1163 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +00001164 Prefix + "-DAG: found a match of CHECK-DAG"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001165 " reordering across a CHECK-NOT");
1166 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
1167 SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001168 Prefix + "-DAG: the farthest match of CHECK-DAG"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001169 " is found here");
1170 SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001171 Prefix + "-NOT: the crossed pattern specified"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001172 " here");
1173 SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001174 Prefix + "-DAG: the reordered pattern specified"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001175 " here");
1176 return StringRef::npos;
1177 }
1178 // All subsequent CHECK-DAGs should be matched from the farthest
1179 // position of all precedent CHECK-DAGs (including this one.)
1180 StartPos = LastPos;
1181 // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
1182 // CHECK-DAG, verify that there's no 'not' strings occurred in that
1183 // region.
1184 StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
Tim Northovercf708c32013-08-02 11:32:50 +00001185 if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
Michael Liao91a1b2c2013-05-14 20:34:12 +00001186 return StringRef::npos;
1187 // Clear "not strings".
1188 NotStrings.clear();
1189 }
1190
1191 // Update the last position with CHECK-DAG matches.
1192 LastPos = std::max(MatchPos + MatchLen, LastPos);
1193 }
1194
1195 return LastPos;
1196}
1197
Matt Arsenault13df4622013-11-10 02:04:09 +00001198// A check prefix must contain only alphanumeric, hyphens and underscores.
1199static bool ValidateCheckPrefix(StringRef CheckPrefix) {
1200 Regex Validator("^[a-zA-Z0-9_-]*$");
1201 return Validator.match(CheckPrefix);
1202}
1203
1204static bool ValidateCheckPrefixes() {
1205 StringSet<> PrefixSet;
1206
1207 for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
1208 I != E; ++I) {
1209 StringRef Prefix(*I);
1210
Eli Bendersky24412b12014-07-29 20:30:53 +00001211 // Reject empty prefixes.
1212 if (Prefix == "")
1213 return false;
1214
Matt Arsenault13df4622013-11-10 02:04:09 +00001215 if (!PrefixSet.insert(Prefix))
1216 return false;
1217
1218 if (!ValidateCheckPrefix(Prefix))
1219 return false;
1220 }
1221
1222 return true;
1223}
1224
1225// I don't think there's a way to specify an initial value for cl::list,
1226// so if nothing was specified, add the default
1227static void AddCheckPrefixIfNeeded() {
1228 if (CheckPrefixes.empty())
1229 CheckPrefixes.push_back("CHECK");
Rui Ueyamac27351582013-08-12 23:05:59 +00001230}
1231
Chris Lattneree3c74f2009-07-08 18:44:05 +00001232int main(int argc, char **argv) {
1233 sys::PrintStackTraceOnErrorSignal();
1234 PrettyStackTraceProgram X(argc, argv);
1235 cl::ParseCommandLineOptions(argc, argv);
1236
Matt Arsenault13df4622013-11-10 02:04:09 +00001237 if (!ValidateCheckPrefixes()) {
1238 errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
1239 "start with a letter and contain only alphanumeric characters, "
1240 "hyphens and underscores\n";
Rui Ueyamac27351582013-08-12 23:05:59 +00001241 return 2;
1242 }
1243
Matt Arsenault13df4622013-11-10 02:04:09 +00001244 AddCheckPrefixIfNeeded();
1245
Chris Lattneree3c74f2009-07-08 18:44:05 +00001246 SourceMgr SM;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001247
Chris Lattneree3c74f2009-07-08 18:44:05 +00001248 // Read the expected strings from the check file.
Chris Lattner26cccfe2009-08-15 17:41:04 +00001249 std::vector<CheckString> CheckStrings;
Chris Lattneree3c74f2009-07-08 18:44:05 +00001250 if (ReadCheckFile(SM, CheckStrings))
1251 return 2;
1252
1253 // Open the file to check and add it to SourceMgr.
Rafael Espindolaadf21f22014-07-06 17:43:13 +00001254 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
1255 MemoryBuffer::getFileOrSTDIN(InputFilename);
1256 if (std::error_code EC = FileOrErr.getError()) {
1257 errs() << "Could not open input file '" << InputFilename
1258 << "': " << EC.message() << '\n';
Eli Bendersky8e1c6472012-11-30 13:51:33 +00001259 return 2;
Chris Lattneree3c74f2009-07-08 18:44:05 +00001260 }
Rafael Espindolaadf21f22014-07-06 17:43:13 +00001261 std::unique_ptr<MemoryBuffer> File = std::move(FileOrErr.get());
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001262
Benjamin Kramere963d662013-03-23 13:56:23 +00001263 if (File->getBufferSize() == 0) {
Chris Lattnerb692bed2011-02-09 16:46:02 +00001264 errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
Eli Bendersky8e1c6472012-11-30 13:51:33 +00001265 return 2;
Chris Lattnerb692bed2011-02-09 16:46:02 +00001266 }
Benjamin Kramere963d662013-03-23 13:56:23 +00001267
Chris Lattner2c3e5cd2009-07-11 18:58:15 +00001268 // Remove duplicate spaces in the input file if requested.
Guy Benyei5ea04c32013-02-06 20:40:38 +00001269 // Remove DOS style line endings.
Benjamin Kramere963d662013-03-23 13:56:23 +00001270 MemoryBuffer *F =
Rafael Espindolace5dd1a2014-08-01 14:11:14 +00001271 CanonicalizeInputFile(std::move(File), NoCanonicalizeWhiteSpace);
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001272
Chris Lattneree3c74f2009-07-08 18:44:05 +00001273 SM.AddNewSourceBuffer(F, SMLoc());
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001274
Chris Lattner8879e062009-09-27 07:56:52 +00001275 /// VariableTable - This holds all the current filecheck variables.
1276 StringMap<StringRef> VariableTable;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001277
Chris Lattneree3c74f2009-07-08 18:44:05 +00001278 // Check that we have all of the expected strings, in order, in the input
1279 // file.
Chris Lattnercaa5fc02009-09-20 22:11:44 +00001280 StringRef Buffer = F->getBuffer();
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001281
Stephen Linf8bd2e52013-07-12 14:51:05 +00001282 bool hasError = false;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001283
Stephen Linf8bd2e52013-07-12 14:51:05 +00001284 unsigned i = 0, j = 0, e = CheckStrings.size();
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001285
Stephen Linf8bd2e52013-07-12 14:51:05 +00001286 while (true) {
1287 StringRef CheckRegion;
1288 if (j == e) {
1289 CheckRegion = Buffer;
1290 } else {
1291 const CheckString &CheckLabelStr = CheckStrings[j];
Matt Arsenault38820972013-09-17 22:30:02 +00001292 if (CheckLabelStr.CheckTy != Check::CheckLabel) {
Stephen Linf8bd2e52013-07-12 14:51:05 +00001293 ++j;
1294 continue;
1295 }
Chris Lattner37183582009-09-20 22:42:44 +00001296
Stephen Linf8bd2e52013-07-12 14:51:05 +00001297 // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
1298 size_t MatchLabelLen = 0;
Stephen Line93a3a02013-10-11 18:38:36 +00001299 size_t MatchLabelPos = CheckLabelStr.Check(SM, Buffer, true,
Stephen Linf8bd2e52013-07-12 14:51:05 +00001300 MatchLabelLen, VariableTable);
1301 if (MatchLabelPos == StringRef::npos) {
1302 hasError = true;
1303 break;
1304 }
1305
1306 CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
1307 Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
1308 ++j;
1309 }
1310
1311 for ( ; i != j; ++i) {
1312 const CheckString &CheckStr = CheckStrings[i];
1313
1314 // Check each string within the scanned region, including a second check
1315 // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
1316 size_t MatchLen = 0;
Stephen Line93a3a02013-10-11 18:38:36 +00001317 size_t MatchPos = CheckStr.Check(SM, CheckRegion, false, MatchLen,
Stephen Linf8bd2e52013-07-12 14:51:05 +00001318 VariableTable);
1319
1320 if (MatchPos == StringRef::npos) {
1321 hasError = true;
1322 i = j;
1323 break;
1324 }
1325
1326 CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
1327 }
1328
1329 if (j == e)
1330 break;
Chris Lattneree3c74f2009-07-08 18:44:05 +00001331 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001332
Stephen Linf8bd2e52013-07-12 14:51:05 +00001333 return hasError ? 1 : 0;
Chris Lattneree3c74f2009-07-08 18:44:05 +00001334}