blob: 9e6a6a2c8ab4df2fad392458945a3383d76275d9 [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.
634static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB,
635 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
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000660 // Free the old buffer and return a new one.
661 MemoryBuffer *MB2 =
Chris Lattner0e45d242010-04-05 22:42:30 +0000662 MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000663
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000664 delete MB;
665 return MB2;
666}
667
Matt Arsenault38820972013-09-17 22:30:02 +0000668static bool IsPartOfWord(char c) {
669 return (isalnum(c) || c == '-' || c == '_');
670}
671
Matt Arsenault13df4622013-11-10 02:04:09 +0000672// Get the size of the prefix extension.
673static size_t CheckTypeSize(Check::CheckType Ty) {
674 switch (Ty) {
675 case Check::CheckNone:
676 return 0;
677
678 case Check::CheckPlain:
679 return sizeof(":") - 1;
680
681 case Check::CheckNext:
682 return sizeof("-NEXT:") - 1;
683
684 case Check::CheckNot:
685 return sizeof("-NOT:") - 1;
686
687 case Check::CheckDAG:
688 return sizeof("-DAG:") - 1;
689
690 case Check::CheckLabel:
691 return sizeof("-LABEL:") - 1;
692
693 case Check::CheckEOF:
694 llvm_unreachable("Should not be using EOF size");
695 }
696
697 llvm_unreachable("Bad check type");
698}
699
700static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
Matt Arsenaultc4d2d472013-09-17 22:45:57 +0000701 char NextChar = Buffer[Prefix.size()];
Matt Arsenault38820972013-09-17 22:30:02 +0000702
703 // Verify that the : is present after the prefix.
Matt Arsenault13df4622013-11-10 02:04:09 +0000704 if (NextChar == ':')
Matt Arsenault38820972013-09-17 22:30:02 +0000705 return Check::CheckPlain;
Matt Arsenault38820972013-09-17 22:30:02 +0000706
Matt Arsenault13df4622013-11-10 02:04:09 +0000707 if (NextChar != '-')
Matt Arsenault38820972013-09-17 22:30:02 +0000708 return Check::CheckNone;
Matt Arsenault38820972013-09-17 22:30:02 +0000709
Matt Arsenaultc4d2d472013-09-17 22:45:57 +0000710 StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
Matt Arsenault13df4622013-11-10 02:04:09 +0000711 if (Rest.startswith("NEXT:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000712 return Check::CheckNext;
Matt Arsenault38820972013-09-17 22:30:02 +0000713
Matt Arsenault13df4622013-11-10 02:04:09 +0000714 if (Rest.startswith("NOT:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000715 return Check::CheckNot;
Matt Arsenault38820972013-09-17 22:30:02 +0000716
Matt Arsenault13df4622013-11-10 02:04:09 +0000717 if (Rest.startswith("DAG:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000718 return Check::CheckDAG;
Matt Arsenault38820972013-09-17 22:30:02 +0000719
Matt Arsenault13df4622013-11-10 02:04:09 +0000720 if (Rest.startswith("LABEL:"))
Matt Arsenault38820972013-09-17 22:30:02 +0000721 return Check::CheckLabel;
Matt Arsenault13df4622013-11-10 02:04:09 +0000722
723 return Check::CheckNone;
724}
725
726// From the given position, find the next character after the word.
727static size_t SkipWord(StringRef Str, size_t Loc) {
728 while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
729 ++Loc;
730 return Loc;
731}
732
733// Try to find the first match in buffer for any prefix. If a valid match is
734// found, return that prefix and set its type and location. If there are almost
735// matches (e.g. the actual prefix string is found, but is not an actual check
736// string), but no valid match, return an empty string and set the position to
737// resume searching from. If no partial matches are found, return an empty
738// string and the location will be StringRef::npos. If one prefix is a substring
739// of another, the maximal match should be found. e.g. if "A" and "AA" are
740// prefixes then AA-CHECK: should match the second one.
741static StringRef FindFirstCandidateMatch(StringRef &Buffer,
742 Check::CheckType &CheckTy,
743 size_t &CheckLoc) {
744 StringRef FirstPrefix;
745 size_t FirstLoc = StringRef::npos;
746 size_t SearchLoc = StringRef::npos;
747 Check::CheckType FirstTy = Check::CheckNone;
748
749 CheckTy = Check::CheckNone;
750 CheckLoc = StringRef::npos;
751
752 for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
753 I != E; ++I) {
754 StringRef Prefix(*I);
755 size_t PrefixLoc = Buffer.find(Prefix);
756
757 if (PrefixLoc == StringRef::npos)
758 continue;
759
760 // Track where we are searching for invalid prefixes that look almost right.
761 // We need to only advance to the first partial match on the next attempt
762 // since a partial match could be a substring of a later, valid prefix.
763 // Need to skip to the end of the word, otherwise we could end up
764 // matching a prefix in a substring later.
765 if (PrefixLoc < SearchLoc)
766 SearchLoc = SkipWord(Buffer, PrefixLoc);
767
768 // We only want to find the first match to avoid skipping some.
769 if (PrefixLoc > FirstLoc)
770 continue;
Alexey Samsonova7181a12013-11-13 14:12:52 +0000771 // If one matching check-prefix is a prefix of another, choose the
772 // longer one.
773 if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size())
774 continue;
Matt Arsenault13df4622013-11-10 02:04:09 +0000775
776 StringRef Rest = Buffer.drop_front(PrefixLoc);
777 // Make sure we have actually found the prefix, and not a word containing
778 // it. This should also prevent matching the wrong prefix when one is a
779 // substring of another.
780 if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
Daniel Sanders43b5f572013-11-20 13:25:05 +0000781 FirstTy = Check::CheckNone;
782 else
783 FirstTy = FindCheckType(Rest, Prefix);
Matt Arsenault13df4622013-11-10 02:04:09 +0000784
Matt Arsenault13df4622013-11-10 02:04:09 +0000785 FirstLoc = PrefixLoc;
Alexey Samsonova7181a12013-11-13 14:12:52 +0000786 FirstPrefix = Prefix;
Matt Arsenault38820972013-09-17 22:30:02 +0000787 }
788
Alexey Samsonova7181a12013-11-13 14:12:52 +0000789 // If the first prefix is invalid, we should continue the search after it.
790 if (FirstTy == Check::CheckNone) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000791 CheckLoc = SearchLoc;
Alexey Samsonova7181a12013-11-13 14:12:52 +0000792 return "";
Matt Arsenault13df4622013-11-10 02:04:09 +0000793 }
794
Alexey Samsonova7181a12013-11-13 14:12:52 +0000795 CheckTy = FirstTy;
796 CheckLoc = FirstLoc;
Matt Arsenault13df4622013-11-10 02:04:09 +0000797 return FirstPrefix;
798}
799
800static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
801 unsigned &LineNumber,
802 Check::CheckType &CheckTy,
803 size_t &CheckLoc) {
804 while (!Buffer.empty()) {
805 StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc);
806 // If we found a real match, we are done.
807 if (!Prefix.empty()) {
808 LineNumber += Buffer.substr(0, CheckLoc).count('\n');
809 return Prefix;
810 }
811
812 // We didn't find any almost matches either, we are also done.
813 if (CheckLoc == StringRef::npos)
814 return StringRef();
815
816 LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
817
818 // Advance to the last possible match we found and try again.
819 Buffer = Buffer.drop_front(CheckLoc + 1);
820 }
821
822 return StringRef();
Matt Arsenault38820972013-09-17 22:30:02 +0000823}
Chris Lattneree3c74f2009-07-08 18:44:05 +0000824
Chris Lattneree3c74f2009-07-08 18:44:05 +0000825/// ReadCheckFile - Read the check file, which specifies the sequence of
826/// expected strings. The strings are added to the CheckStrings vector.
Eli Bendersky43d50d42012-11-30 14:22:14 +0000827/// Returns true in case of an error, false otherwise.
Chris Lattneree3c74f2009-07-08 18:44:05 +0000828static bool ReadCheckFile(SourceMgr &SM,
Chris Lattner26cccfe2009-08-15 17:41:04 +0000829 std::vector<CheckString> &CheckStrings) {
Rafael Espindolaadf21f22014-07-06 17:43:13 +0000830 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
831 MemoryBuffer::getFileOrSTDIN(CheckFilename);
832 if (std::error_code EC = FileOrErr.getError()) {
833 errs() << "Could not open check file '" << CheckFilename
834 << "': " << EC.message() << '\n';
Chris Lattneree3c74f2009-07-08 18:44:05 +0000835 return true;
836 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000837
Chris Lattnera2f8fc52009-09-24 20:45:07 +0000838 // If we want to canonicalize whitespace, strip excess whitespace from the
Guy Benyei5ea04c32013-02-06 20:40:38 +0000839 // buffer containing the CHECK lines. Remove DOS style line endings.
Rafael Espindolaadf21f22014-07-06 17:43:13 +0000840 MemoryBuffer *F = CanonicalizeInputFile(FileOrErr.get().release(),
841 NoCanonicalizeWhiteSpace);
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000842
Chris Lattneree3c74f2009-07-08 18:44:05 +0000843 SM.AddNewSourceBuffer(F, SMLoc());
844
Chris Lattner10f10ce2009-08-15 18:00:42 +0000845 // Find all instances of CheckPrefix followed by : in the file.
Chris Lattnercaa5fc02009-09-20 22:11:44 +0000846 StringRef Buffer = F->getBuffer();
Alexander Kornienko56ccdbb2014-07-11 12:39:32 +0000847
848 std::vector<Pattern> ImplicitNegativeChecks;
849 for (const auto &PatternString : ImplicitCheckNot) {
850 // Create a buffer with fake command line content in order to display the
851 // command line option responsible for the specific implicit CHECK-NOT.
852 std::string Prefix = std::string("-") + ImplicitCheckNot.ArgStr + "='";
853 std::string Suffix = "'";
854 MemoryBuffer *CmdLine = MemoryBuffer::getMemBufferCopy(
855 Prefix + PatternString + Suffix, "command line");
856 StringRef PatternInBuffer =
857 CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
858 SM.AddNewSourceBuffer(CmdLine, SMLoc());
859
860 ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
861 ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
862 "IMPLICIT-CHECK", SM, 0);
863 }
864
865
866 std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000867
Eli Bendersky43d50d42012-11-30 14:22:14 +0000868 // LineNumber keeps track of the line on which CheckPrefix instances are
869 // found.
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000870 unsigned LineNumber = 1;
871
Chris Lattneree3c74f2009-07-08 18:44:05 +0000872 while (1) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000873 Check::CheckType CheckTy;
874 size_t PrefixLoc;
875
876 // See if a prefix occurs in the memory buffer.
877 StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
878 LineNumber,
879 CheckTy,
880 PrefixLoc);
881 if (UsedPrefix.empty())
Chris Lattneree3c74f2009-07-08 18:44:05 +0000882 break;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000883
Matt Arsenault13df4622013-11-10 02:04:09 +0000884 Buffer = Buffer.drop_front(PrefixLoc);
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000885
Matt Arsenault13df4622013-11-10 02:04:09 +0000886 // Location to use for error messages.
887 const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
Alexander Kornienko92987fb2012-11-14 21:07:37 +0000888
Matt Arsenault13df4622013-11-10 02:04:09 +0000889 // PrefixLoc is to the start of the prefix. Skip to the end.
890 Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000891
Matt Arsenault38820972013-09-17 22:30:02 +0000892 // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
893 // leading and trailing whitespace.
Chris Lattner236d2d52009-09-20 22:35:26 +0000894 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000895
Chris Lattneree3c74f2009-07-08 18:44:05 +0000896 // Scan ahead to the end of line.
Chris Lattnercaa5fc02009-09-20 22:11:44 +0000897 size_t EOL = Buffer.find_first_of("\n\r");
Chris Lattner74d50732009-09-24 20:39:13 +0000898
Dan Gohman838fb092010-01-29 21:53:18 +0000899 // Remember the location of the start of the pattern, for diagnostics.
900 SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
901
Chris Lattner74d50732009-09-24 20:39:13 +0000902 // Parse the pattern.
Matt Arsenault38820972013-09-17 22:30:02 +0000903 Pattern P(CheckTy);
Matt Arsenault13df4622013-11-10 02:04:09 +0000904 if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
Chris Lattneree3c74f2009-07-08 18:44:05 +0000905 return true;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000906
Stephen Linf8bd2e52013-07-12 14:51:05 +0000907 // Verify that CHECK-LABEL lines do not define or use variables
Matt Arsenault38820972013-09-17 22:30:02 +0000908 if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000909 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
Stephen Linf8bd2e52013-07-12 14:51:05 +0000910 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +0000911 "found '" + UsedPrefix + "-LABEL:'"
912 " with variable definition or use");
Stephen Linf8bd2e52013-07-12 14:51:05 +0000913 return true;
914 }
915
Chris Lattner74d50732009-09-24 20:39:13 +0000916 Buffer = Buffer.substr(EOL);
917
Chris Lattnerda108b42009-08-15 18:32:21 +0000918 // Verify that CHECK-NEXT lines have at least one CHECK line before them.
Matt Arsenault38820972013-09-17 22:30:02 +0000919 if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000920 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
Chris Lattner03b80a42011-10-16 05:43:57 +0000921 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +0000922 "found '" + UsedPrefix + "-NEXT:' without previous '"
923 + UsedPrefix + ": line");
Chris Lattnerda108b42009-08-15 18:32:21 +0000924 return true;
925 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000926
Michael Liao91a1b2c2013-05-14 20:34:12 +0000927 // Handle CHECK-DAG/-NOT.
Matt Arsenault38820972013-09-17 22:30:02 +0000928 if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
Michael Liao91a1b2c2013-05-14 20:34:12 +0000929 DagNotMatches.push_back(P);
Chris Lattner74d50732009-09-24 20:39:13 +0000930 continue;
931 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000932
Chris Lattneree3c74f2009-07-08 18:44:05 +0000933 // Okay, add the string we captured to the output vector and move on.
Chris Lattner3b40b442009-09-24 20:25:55 +0000934 CheckStrings.push_back(CheckString(P,
Matt Arsenault13df4622013-11-10 02:04:09 +0000935 UsedPrefix,
Dan Gohman838fb092010-01-29 21:53:18 +0000936 PatternLoc,
Matt Arsenault38820972013-09-17 22:30:02 +0000937 CheckTy));
Michael Liao91a1b2c2013-05-14 20:34:12 +0000938 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
Alexander Kornienko56ccdbb2014-07-11 12:39:32 +0000939 DagNotMatches = ImplicitNegativeChecks;
Chris Lattneree3c74f2009-07-08 18:44:05 +0000940 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000941
Matt Arsenault13df4622013-11-10 02:04:09 +0000942 // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
943 // prefix as a filler for the error message.
Michael Liao91a1b2c2013-05-14 20:34:12 +0000944 if (!DagNotMatches.empty()) {
Matt Arsenault38820972013-09-17 22:30:02 +0000945 CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF),
Matt Arsenault13df4622013-11-10 02:04:09 +0000946 CheckPrefixes[0],
Jakob Stoklund Oleseneba55822010-10-15 17:47:12 +0000947 SMLoc::getFromPointer(Buffer.data()),
Matt Arsenault38820972013-09-17 22:30:02 +0000948 Check::CheckEOF));
Michael Liao91a1b2c2013-05-14 20:34:12 +0000949 std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
Jakob Stoklund Oleseneba55822010-10-15 17:47:12 +0000950 }
951
Chris Lattneree3c74f2009-07-08 18:44:05 +0000952 if (CheckStrings.empty()) {
Matt Arsenault13df4622013-11-10 02:04:09 +0000953 errs() << "error: no check strings found with prefix"
954 << (CheckPrefixes.size() > 1 ? "es " : " ");
955 for (size_t I = 0, N = CheckPrefixes.size(); I != N; ++I) {
956 StringRef Prefix(CheckPrefixes[I]);
957 errs() << '\'' << Prefix << ":'";
958 if (I != N - 1)
959 errs() << ", ";
960 }
961
962 errs() << '\n';
Chris Lattneree3c74f2009-07-08 18:44:05 +0000963 return true;
964 }
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000965
Chris Lattneree3c74f2009-07-08 18:44:05 +0000966 return false;
967}
968
Michael Liao91a1b2c2013-05-14 20:34:12 +0000969static void PrintCheckFailed(const SourceMgr &SM, const SMLoc &Loc,
970 const Pattern &Pat, StringRef Buffer,
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000971 StringMap<StringRef> &VariableTable) {
Chris Lattnerda108b42009-08-15 18:32:21 +0000972 // Otherwise, we have an error, emit an error message.
Michael Liao91a1b2c2013-05-14 20:34:12 +0000973 SM.PrintMessage(Loc, SourceMgr::DK_Error,
Chris Lattner03b80a42011-10-16 05:43:57 +0000974 "expected string not found in input");
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000975
Chris Lattnerda108b42009-08-15 18:32:21 +0000976 // Print the "scanning from here" line. If the current position is at the
977 // end of a line, advance to the start of the next line.
Chris Lattnercaa5fc02009-09-20 22:11:44 +0000978 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +0000979
Chris Lattner03b80a42011-10-16 05:43:57 +0000980 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
981 "scanning from here");
Daniel Dunbare0ef65a2009-11-22 22:08:06 +0000982
983 // Allow the pattern to print additional information if desired.
Michael Liao91a1b2c2013-05-14 20:34:12 +0000984 Pat.PrintFailureInfo(SM, Buffer, VariableTable);
985}
986
987static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
988 StringRef Buffer,
989 StringMap<StringRef> &VariableTable) {
990 PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
Chris Lattnerda108b42009-08-15 18:32:21 +0000991}
992
Chris Lattner37183582009-09-20 22:42:44 +0000993/// CountNumNewlinesBetween - Count the number of newlines in the specified
994/// range.
Richard Smith592fe882014-04-07 17:09:53 +0000995static unsigned CountNumNewlinesBetween(StringRef Range,
996 const char *&FirstNewLine) {
Chris Lattnerda108b42009-08-15 18:32:21 +0000997 unsigned NumNewLines = 0;
Chris Lattner37183582009-09-20 22:42:44 +0000998 while (1) {
Chris Lattnerda108b42009-08-15 18:32:21 +0000999 // Scan for newline.
Chris Lattner37183582009-09-20 22:42:44 +00001000 Range = Range.substr(Range.find_first_of("\n\r"));
1001 if (Range.empty()) return NumNewLines;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001002
Chris Lattnerda108b42009-08-15 18:32:21 +00001003 ++NumNewLines;
Mikhail Glushenkovdefcda22010-08-20 17:38:38 +00001004
Chris Lattnerda108b42009-08-15 18:32:21 +00001005 // Handle \n\r and \r\n as a single newline.
Chris Lattner37183582009-09-20 22:42:44 +00001006 if (Range.size() > 1 &&
1007 (Range[1] == '\n' || Range[1] == '\r') &&
1008 (Range[0] != Range[1]))
1009 Range = Range.substr(1);
1010 Range = Range.substr(1);
Richard Smith592fe882014-04-07 17:09:53 +00001011
1012 if (NumNewLines == 1)
1013 FirstNewLine = Range.begin();
Chris Lattnerda108b42009-08-15 18:32:21 +00001014 }
Chris Lattnerda108b42009-08-15 18:32:21 +00001015}
1016
Michael Liaodcc7d482013-05-14 20:29:52 +00001017size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
Stephen Line93a3a02013-10-11 18:38:36 +00001018 bool IsLabelScanMode, size_t &MatchLen,
Michael Liaodcc7d482013-05-14 20:29:52 +00001019 StringMap<StringRef> &VariableTable) const {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001020 size_t LastPos = 0;
1021 std::vector<const Pattern *> NotStrings;
1022
Stephen Line93a3a02013-10-11 18:38:36 +00001023 // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
1024 // bounds; we have not processed variable definitions within the bounded block
1025 // yet so cannot handle any final CHECK-DAG yet; this is handled when going
1026 // over the block again (including the last CHECK-LABEL) in normal mode.
1027 if (!IsLabelScanMode) {
1028 // Match "dag strings" (with mixed "not strings" if any).
1029 LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable);
1030 if (LastPos == StringRef::npos)
1031 return StringRef::npos;
1032 }
Michael Liao91a1b2c2013-05-14 20:34:12 +00001033
1034 // Match itself from the last position after matching CHECK-DAG.
1035 StringRef MatchBuffer = Buffer.substr(LastPos);
1036 size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
Michael Liaodcc7d482013-05-14 20:29:52 +00001037 if (MatchPos == StringRef::npos) {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001038 PrintCheckFailed(SM, *this, MatchBuffer, VariableTable);
Michael Liaodcc7d482013-05-14 20:29:52 +00001039 return StringRef::npos;
1040 }
Michael Liao91a1b2c2013-05-14 20:34:12 +00001041 MatchPos += LastPos;
Michael Liaodcc7d482013-05-14 20:29:52 +00001042
Stephen Line93a3a02013-10-11 18:38:36 +00001043 // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
1044 // or CHECK-NOT
1045 if (!IsLabelScanMode) {
Stephen Linf8bd2e52013-07-12 14:51:05 +00001046 StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
Michael Liaodcc7d482013-05-14 20:29:52 +00001047
Stephen Linf8bd2e52013-07-12 14:51:05 +00001048 // If this check is a "CHECK-NEXT", verify that the previous match was on
1049 // the previous line (i.e. that there is one newline between them).
1050 if (CheckNext(SM, SkippedRegion))
1051 return StringRef::npos;
Michael Liaodcc7d482013-05-14 20:29:52 +00001052
Stephen Linf8bd2e52013-07-12 14:51:05 +00001053 // If this match had "not strings", verify that they don't exist in the
1054 // skipped region.
1055 if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
1056 return StringRef::npos;
1057 }
Michael Liaodcc7d482013-05-14 20:29:52 +00001058
1059 return MatchPos;
1060}
1061
1062bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
Matt Arsenault38820972013-09-17 22:30:02 +00001063 if (CheckTy != Check::CheckNext)
Michael Liaodcc7d482013-05-14 20:29:52 +00001064 return false;
1065
1066 // Count the number of newlines between the previous match and this one.
1067 assert(Buffer.data() !=
1068 SM.getMemoryBuffer(
1069 SM.FindBufferContainingLoc(
1070 SMLoc::getFromPointer(Buffer.data())))->getBufferStart() &&
1071 "CHECK-NEXT can't be the first check in a file");
1072
Craig Topper66f09ad2014-06-08 22:29:17 +00001073 const char *FirstNewLine = nullptr;
Richard Smith592fe882014-04-07 17:09:53 +00001074 unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
Michael Liaodcc7d482013-05-14 20:29:52 +00001075
1076 if (NumNewLines == 0) {
Matt Arsenault13df4622013-11-10 02:04:09 +00001077 SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
Michael Liaodcc7d482013-05-14 20:29:52 +00001078 "-NEXT: is on the same line as previous match");
1079 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1080 SourceMgr::DK_Note, "'next' match was here");
1081 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1082 "previous match ended here");
1083 return true;
1084 }
1085
1086 if (NumNewLines != 1) {
Matt Arsenault13df4622013-11-10 02:04:09 +00001087 SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
Michael Liaodcc7d482013-05-14 20:29:52 +00001088 "-NEXT: is not on the line after the previous match");
1089 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1090 SourceMgr::DK_Note, "'next' match was here");
1091 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1092 "previous match ended here");
Richard Smith592fe882014-04-07 17:09:53 +00001093 SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
1094 "non-matching line after previous match is here");
Michael Liaodcc7d482013-05-14 20:29:52 +00001095 return true;
1096 }
1097
1098 return false;
1099}
1100
1101bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
Michael Liao91a1b2c2013-05-14 20:34:12 +00001102 const std::vector<const Pattern *> &NotStrings,
Michael Liaodcc7d482013-05-14 20:29:52 +00001103 StringMap<StringRef> &VariableTable) const {
1104 for (unsigned ChunkNo = 0, e = NotStrings.size();
1105 ChunkNo != e; ++ChunkNo) {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001106 const Pattern *Pat = NotStrings[ChunkNo];
Matt Arsenault38820972013-09-17 22:30:02 +00001107 assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
Michael Liao91a1b2c2013-05-14 20:34:12 +00001108
Michael Liaodcc7d482013-05-14 20:29:52 +00001109 size_t MatchLen = 0;
Michael Liao91a1b2c2013-05-14 20:34:12 +00001110 size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
Michael Liaodcc7d482013-05-14 20:29:52 +00001111
1112 if (Pos == StringRef::npos) continue;
1113
1114 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos),
1115 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +00001116 Prefix + "-NOT: string occurred!");
Michael Liao91a1b2c2013-05-14 20:34:12 +00001117 SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001118 Prefix + "-NOT: pattern specified here");
Michael Liaodcc7d482013-05-14 20:29:52 +00001119 return true;
1120 }
1121
1122 return false;
1123}
1124
Michael Liao91a1b2c2013-05-14 20:34:12 +00001125size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
1126 std::vector<const Pattern *> &NotStrings,
1127 StringMap<StringRef> &VariableTable) const {
1128 if (DagNotStrings.empty())
1129 return 0;
1130
1131 size_t LastPos = 0;
1132 size_t StartPos = LastPos;
1133
1134 for (unsigned ChunkNo = 0, e = DagNotStrings.size();
1135 ChunkNo != e; ++ChunkNo) {
1136 const Pattern &Pat = DagNotStrings[ChunkNo];
1137
Matt Arsenault38820972013-09-17 22:30:02 +00001138 assert((Pat.getCheckTy() == Check::CheckDAG ||
1139 Pat.getCheckTy() == Check::CheckNot) &&
Michael Liao91a1b2c2013-05-14 20:34:12 +00001140 "Invalid CHECK-DAG or CHECK-NOT!");
1141
Matt Arsenault38820972013-09-17 22:30:02 +00001142 if (Pat.getCheckTy() == Check::CheckNot) {
Michael Liao91a1b2c2013-05-14 20:34:12 +00001143 NotStrings.push_back(&Pat);
1144 continue;
1145 }
1146
Matt Arsenault38820972013-09-17 22:30:02 +00001147 assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
Michael Liao91a1b2c2013-05-14 20:34:12 +00001148
1149 size_t MatchLen = 0, MatchPos;
1150
1151 // CHECK-DAG always matches from the start.
1152 StringRef MatchBuffer = Buffer.substr(StartPos);
1153 MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
1154 // With a group of CHECK-DAGs, a single mismatching means the match on
1155 // that group of CHECK-DAGs fails immediately.
1156 if (MatchPos == StringRef::npos) {
1157 PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
1158 return StringRef::npos;
1159 }
1160 // Re-calc it as the offset relative to the start of the original string.
1161 MatchPos += StartPos;
1162
1163 if (!NotStrings.empty()) {
1164 if (MatchPos < LastPos) {
1165 // Reordered?
1166 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
1167 SourceMgr::DK_Error,
Matt Arsenault13df4622013-11-10 02:04:09 +00001168 Prefix + "-DAG: found a match of CHECK-DAG"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001169 " reordering across a CHECK-NOT");
1170 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
1171 SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001172 Prefix + "-DAG: the farthest match of CHECK-DAG"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001173 " is found here");
1174 SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001175 Prefix + "-NOT: the crossed pattern specified"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001176 " here");
1177 SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
Matt Arsenault13df4622013-11-10 02:04:09 +00001178 Prefix + "-DAG: the reordered pattern specified"
Michael Liao91a1b2c2013-05-14 20:34:12 +00001179 " here");
1180 return StringRef::npos;
1181 }
1182 // All subsequent CHECK-DAGs should be matched from the farthest
1183 // position of all precedent CHECK-DAGs (including this one.)
1184 StartPos = LastPos;
1185 // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
1186 // CHECK-DAG, verify that there's no 'not' strings occurred in that
1187 // region.
1188 StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
Tim Northovercf708c32013-08-02 11:32:50 +00001189 if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
Michael Liao91a1b2c2013-05-14 20:34:12 +00001190 return StringRef::npos;
1191 // Clear "not strings".
1192 NotStrings.clear();
1193 }
1194
1195 // Update the last position with CHECK-DAG matches.
1196 LastPos = std::max(MatchPos + MatchLen, LastPos);
1197 }
1198
1199 return LastPos;
1200}
1201
Matt Arsenault13df4622013-11-10 02:04:09 +00001202// A check prefix must contain only alphanumeric, hyphens and underscores.
1203static bool ValidateCheckPrefix(StringRef CheckPrefix) {
1204 Regex Validator("^[a-zA-Z0-9_-]*$");
1205 return Validator.match(CheckPrefix);
1206}
1207
1208static bool ValidateCheckPrefixes() {
1209 StringSet<> PrefixSet;
1210
1211 for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
1212 I != E; ++I) {
1213 StringRef Prefix(*I);
1214
1215 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 =
Ahmed Charles96c9d952014-03-05 10:19:29 +00001271 CanonicalizeInputFile(File.release(), 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}