1ee3c74fbSChris Lattner //===- FileCheck.cpp - Check that File's Contents match what is expected --===//
2ee3c74fbSChris Lattner //
3ee3c74fbSChris Lattner //                     The LLVM Compiler Infrastructure
4ee3c74fbSChris Lattner //
5ee3c74fbSChris Lattner // This file is distributed under the University of Illinois Open Source
6ee3c74fbSChris Lattner // License. See LICENSE.TXT for details.
7ee3c74fbSChris Lattner //
8ee3c74fbSChris Lattner //===----------------------------------------------------------------------===//
9ee3c74fbSChris Lattner //
10ee3c74fbSChris Lattner // FileCheck does a line-by line check of a file that validates whether it
11ee3c74fbSChris Lattner // contains the expected content.  This is useful for regression tests etc.
12ee3c74fbSChris Lattner //
13ee3c74fbSChris Lattner // This program exits with an error status of 2 on error, exit status of 0 if
14ee3c74fbSChris Lattner // the file matched the expected contents, and exit status of 1 if it did not
15ee3c74fbSChris Lattner // contain the expected contents.
16ee3c74fbSChris Lattner //
17ee3c74fbSChris Lattner //===----------------------------------------------------------------------===//
18ee3c74fbSChris Lattner 
1991d19d8eSChandler Carruth #include "llvm/ADT/SmallString.h"
2091d19d8eSChandler Carruth #include "llvm/ADT/StringExtras.h"
2191d19d8eSChandler Carruth #include "llvm/ADT/StringMap.h"
2213df4626SMatt Arsenault #include "llvm/ADT/StringSet.h"
23ee3c74fbSChris Lattner #include "llvm/Support/CommandLine.h"
24ee3c74fbSChris Lattner #include "llvm/Support/MemoryBuffer.h"
25ee3c74fbSChris Lattner #include "llvm/Support/PrettyStackTrace.h"
26f08d2db9SChris Lattner #include "llvm/Support/Regex.h"
2791d19d8eSChandler Carruth #include "llvm/Support/Signals.h"
28ee3c74fbSChris Lattner #include "llvm/Support/SourceMgr.h"
29ee3c74fbSChris Lattner #include "llvm/Support/raw_ostream.h"
308879e06dSChris Lattner #include <algorithm>
31981af002SWill Dietz #include <cctype>
32e8b8f1bcSEli Bendersky #include <map>
33e8b8f1bcSEli Bendersky #include <string>
34a6e9c3e4SRafael Espindola #include <system_error>
35e8b8f1bcSEli Bendersky #include <vector>
36ee3c74fbSChris Lattner using namespace llvm;
37ee3c74fbSChris Lattner 
38ee3c74fbSChris Lattner static cl::opt<std::string>
39ee3c74fbSChris Lattner CheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);
40ee3c74fbSChris Lattner 
41ee3c74fbSChris Lattner static cl::opt<std::string>
42ee3c74fbSChris Lattner InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
43ee3c74fbSChris Lattner               cl::init("-"), cl::value_desc("filename"));
44ee3c74fbSChris Lattner 
4513df4626SMatt Arsenault static cl::list<std::string>
4613df4626SMatt Arsenault CheckPrefixes("check-prefix",
47ee3c74fbSChris Lattner               cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
48ee3c74fbSChris Lattner 
492c3e5cdfSChris Lattner static cl::opt<bool>
502c3e5cdfSChris Lattner NoCanonicalizeWhiteSpace("strict-whitespace",
512c3e5cdfSChris Lattner               cl::desc("Do not treat all horizontal whitespace as equivalent"));
522c3e5cdfSChris Lattner 
5356ccdbbdSAlexander Kornienko static cl::list<std::string> ImplicitCheckNot(
5456ccdbbdSAlexander Kornienko     "implicit-check-not",
5556ccdbbdSAlexander Kornienko     cl::desc("Add an implicit negative check with this pattern to every\n"
5656ccdbbdSAlexander Kornienko              "positive check. This can be used to ensure that no instances of\n"
5756ccdbbdSAlexander Kornienko              "this pattern occur which are not matched by a positive pattern"),
5856ccdbbdSAlexander Kornienko     cl::value_desc("pattern"));
5956ccdbbdSAlexander Kornienko 
601b9f936fSJustin Bogner static cl::opt<bool> AllowEmptyInput(
611b9f936fSJustin Bogner     "allow-empty", cl::init(false),
621b9f936fSJustin Bogner     cl::desc("Allow the input file to be empty. This is useful when making\n"
631b9f936fSJustin Bogner              "checks that some error message does not occur, for example."));
641b9f936fSJustin Bogner 
6513df4626SMatt Arsenault typedef cl::list<std::string>::const_iterator prefix_iterator;
6613df4626SMatt Arsenault 
6774d50731SChris Lattner //===----------------------------------------------------------------------===//
6874d50731SChris Lattner // Pattern Handling Code.
6974d50731SChris Lattner //===----------------------------------------------------------------------===//
7074d50731SChris Lattner 
7138820972SMatt Arsenault namespace Check {
7238820972SMatt Arsenault   enum CheckType {
7338820972SMatt Arsenault     CheckNone = 0,
7438820972SMatt Arsenault     CheckPlain,
7538820972SMatt Arsenault     CheckNext,
7601ac1707SDuncan P. N. Exon Smith     CheckSame,
7738820972SMatt Arsenault     CheckNot,
7838820972SMatt Arsenault     CheckDAG,
7938820972SMatt Arsenault     CheckLabel,
800a4c44bdSChris Lattner 
81eba55822SJakob Stoklund Olesen     /// MatchEOF - When set, this pattern only matches the end of file. This is
82eba55822SJakob Stoklund Olesen     /// used for trailing CHECK-NOTs.
8338820972SMatt Arsenault     CheckEOF
8438820972SMatt Arsenault   };
8538820972SMatt Arsenault }
86eba55822SJakob Stoklund Olesen 
8738820972SMatt Arsenault class Pattern {
8838820972SMatt Arsenault   SMLoc PatternLoc;
8991a1b2c9SMichael Liao 
9038820972SMatt Arsenault   Check::CheckType CheckTy;
9191a1b2c9SMichael Liao 
92b16ab0c4SChris Lattner   /// FixedStr - If non-empty, this pattern is a fixed string match with the
93b16ab0c4SChris Lattner   /// specified fixed string.
94221460e0SChris Lattner   StringRef FixedStr;
95b16ab0c4SChris Lattner 
96b16ab0c4SChris Lattner   /// RegEx - If non-empty, this is a regex pattern.
97b16ab0c4SChris Lattner   std::string RegExStr;
988879e06dSChris Lattner 
9992987fb3SAlexander Kornienko   /// \brief Contains the number of line this pattern is in.
10092987fb3SAlexander Kornienko   unsigned LineNumber;
10192987fb3SAlexander Kornienko 
1028879e06dSChris Lattner   /// VariableUses - Entries in this vector map to uses of a variable in the
1038879e06dSChris Lattner   /// pattern, e.g. "foo[[bar]]baz".  In this case, the RegExStr will contain
1048879e06dSChris Lattner   /// "foobaz" and we'll get an entry in this vector that tells us to insert the
1058879e06dSChris Lattner   /// value of bar at offset 3.
1068879e06dSChris Lattner   std::vector<std::pair<StringRef, unsigned> > VariableUses;
1078879e06dSChris Lattner 
108e8b8f1bcSEli Bendersky   /// VariableDefs - Maps definitions of variables to their parenthesized
109e8b8f1bcSEli Bendersky   /// capture numbers.
110e8b8f1bcSEli Bendersky   /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1.
111e8b8f1bcSEli Bendersky   std::map<StringRef, unsigned> VariableDefs;
1128879e06dSChris Lattner 
1133b40b445SChris Lattner public:
1143b40b445SChris Lattner 
11538820972SMatt Arsenault   Pattern(Check::CheckType Ty)
11638820972SMatt Arsenault     : CheckTy(Ty) { }
11774d50731SChris Lattner 
1180b707eb8SMichael Liao   /// getLoc - Return the location in source code.
1190b707eb8SMichael Liao   SMLoc getLoc() const { return PatternLoc; }
1200b707eb8SMichael Liao 
12113df4626SMatt Arsenault   /// ParsePattern - Parse the given string into the Pattern. Prefix provides
12213df4626SMatt Arsenault   /// which prefix is being matched, SM provides the SourceMgr used for error
12313df4626SMatt Arsenault   /// reports, and LineNumber is the line number in the input file from which
12413df4626SMatt Arsenault   /// the pattern string was read.  Returns true in case of an error, false
12513df4626SMatt Arsenault   /// otherwise.
12613df4626SMatt Arsenault   bool ParsePattern(StringRef PatternStr,
12713df4626SMatt Arsenault                     StringRef Prefix,
12813df4626SMatt Arsenault                     SourceMgr &SM,
12913df4626SMatt Arsenault                     unsigned LineNumber);
1303b40b445SChris Lattner 
1313b40b445SChris Lattner   /// Match - Match the pattern string against the input buffer Buffer.  This
1323b40b445SChris Lattner   /// returns the position that is matched or npos if there is no match.  If
1333b40b445SChris Lattner   /// there is a match, the size of the matched string is returned in MatchLen.
1348879e06dSChris Lattner   ///
1358879e06dSChris Lattner   /// The VariableTable StringMap provides the current values of filecheck
1368879e06dSChris Lattner   /// variables and is updated if this match defines new values.
1378879e06dSChris Lattner   size_t Match(StringRef Buffer, size_t &MatchLen,
1388879e06dSChris Lattner                StringMap<StringRef> &VariableTable) const;
139b16ab0c4SChris Lattner 
140e0ef65abSDaniel Dunbar   /// PrintFailureInfo - Print additional information about a failure to match
141e0ef65abSDaniel Dunbar   /// involving this pattern.
142e0ef65abSDaniel Dunbar   void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
143e0ef65abSDaniel Dunbar                         const StringMap<StringRef> &VariableTable) const;
144e0ef65abSDaniel Dunbar 
145f8bd2e5bSStephen Lin   bool hasVariable() const { return !(VariableUses.empty() &&
146f8bd2e5bSStephen Lin                                       VariableDefs.empty()); }
147f8bd2e5bSStephen Lin 
14838820972SMatt Arsenault   Check::CheckType getCheckTy() const { return CheckTy; }
14991a1b2c9SMichael Liao 
150b16ab0c4SChris Lattner private:
151e8b8f1bcSEli Bendersky   bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
152e8b8f1bcSEli Bendersky   void AddBackrefToRegEx(unsigned BackrefNum);
153fd29d886SDaniel Dunbar 
154fd29d886SDaniel Dunbar   /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
155fd29d886SDaniel Dunbar   /// matching this pattern at the start of \arg Buffer; a distance of zero
156fd29d886SDaniel Dunbar   /// should correspond to a perfect match.
157fd29d886SDaniel Dunbar   unsigned ComputeMatchDistance(StringRef Buffer,
158fd29d886SDaniel Dunbar                                const StringMap<StringRef> &VariableTable) const;
15992987fb3SAlexander Kornienko 
16092987fb3SAlexander Kornienko   /// \brief Evaluates expression and stores the result to \p Value.
16192987fb3SAlexander Kornienko   /// \return true on success. false when the expression has invalid syntax.
16292987fb3SAlexander Kornienko   bool EvaluateExpression(StringRef Expr, std::string &Value) const;
163061d2baaSEli Bendersky 
164061d2baaSEli Bendersky   /// \brief Finds the closing sequence of a regex variable usage or
165061d2baaSEli Bendersky   /// definition. Str has to point in the beginning of the definition
166061d2baaSEli Bendersky   /// (right after the opening sequence).
167061d2baaSEli Bendersky   /// \return offset of the closing sequence within Str, or npos if it was not
168061d2baaSEli Bendersky   /// found.
16981e5cd9eSAdrian Prantl   size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
1703b40b445SChris Lattner };
1713b40b445SChris Lattner 
1728879e06dSChris Lattner 
17313df4626SMatt Arsenault bool Pattern::ParsePattern(StringRef PatternStr,
17413df4626SMatt Arsenault                            StringRef Prefix,
17513df4626SMatt Arsenault                            SourceMgr &SM,
17692987fb3SAlexander Kornienko                            unsigned LineNumber) {
17792987fb3SAlexander Kornienko   this->LineNumber = LineNumber;
1780a4c44bdSChris Lattner   PatternLoc = SMLoc::getFromPointer(PatternStr.data());
1790a4c44bdSChris Lattner 
18074d50731SChris Lattner   // Ignore trailing whitespace.
18174d50731SChris Lattner   while (!PatternStr.empty() &&
18274d50731SChris Lattner          (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
18374d50731SChris Lattner     PatternStr = PatternStr.substr(0, PatternStr.size()-1);
18474d50731SChris Lattner 
18574d50731SChris Lattner   // Check that there is something on the line.
18674d50731SChris Lattner   if (PatternStr.empty()) {
18703b80a40SChris Lattner     SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
18803b80a40SChris Lattner                     "found empty check string with prefix '" +
18913df4626SMatt Arsenault                     Prefix + ":'");
19074d50731SChris Lattner     return true;
19174d50731SChris Lattner   }
19274d50731SChris Lattner 
193221460e0SChris Lattner   // Check to see if this is a fixed string, or if it has regex pieces.
194d9466967STed Kremenek   if (PatternStr.size() < 2 ||
1958879e06dSChris Lattner       (PatternStr.find("{{") == StringRef::npos &&
1968879e06dSChris Lattner        PatternStr.find("[[") == StringRef::npos)) {
197221460e0SChris Lattner     FixedStr = PatternStr;
198221460e0SChris Lattner     return false;
199221460e0SChris Lattner   }
200221460e0SChris Lattner 
2018879e06dSChris Lattner   // Paren value #0 is for the fully matched string.  Any new parenthesized
20253e0679dSChris Lattner   // values add from there.
2038879e06dSChris Lattner   unsigned CurParen = 1;
2048879e06dSChris Lattner 
205b16ab0c4SChris Lattner   // Otherwise, there is at least one regex piece.  Build up the regex pattern
206b16ab0c4SChris Lattner   // by escaping scary characters in fixed strings, building up one big regex.
207f08d2db9SChris Lattner   while (!PatternStr.empty()) {
2088879e06dSChris Lattner     // RegEx matches.
20953e0679dSChris Lattner     if (PatternStr.startswith("{{")) {
21043d50d4aSEli Bendersky       // This is the start of a regex match.  Scan for the }}.
211f08d2db9SChris Lattner       size_t End = PatternStr.find("}}");
212f08d2db9SChris Lattner       if (End == StringRef::npos) {
213f08d2db9SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
21403b80a40SChris Lattner                         SourceMgr::DK_Error,
21503b80a40SChris Lattner                         "found start of regex string with no end '}}'");
216f08d2db9SChris Lattner         return true;
217f08d2db9SChris Lattner       }
218f08d2db9SChris Lattner 
219e53c95f1SChris Lattner       // Enclose {{}} patterns in parens just like [[]] even though we're not
220e53c95f1SChris Lattner       // capturing the result for any purpose.  This is required in case the
221e53c95f1SChris Lattner       // expression contains an alternation like: CHECK:  abc{{x|z}}def.  We
222e53c95f1SChris Lattner       // want this to turn into: "abc(x|z)def" not "abcx|zdef".
223e53c95f1SChris Lattner       RegExStr += '(';
224e53c95f1SChris Lattner       ++CurParen;
225e53c95f1SChris Lattner 
2268879e06dSChris Lattner       if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
2278879e06dSChris Lattner         return true;
228e53c95f1SChris Lattner       RegExStr += ')';
22953e0679dSChris Lattner 
2308879e06dSChris Lattner       PatternStr = PatternStr.substr(End+2);
2318879e06dSChris Lattner       continue;
2328879e06dSChris Lattner     }
2338879e06dSChris Lattner 
2348879e06dSChris Lattner     // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
2358879e06dSChris Lattner     // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
2368879e06dSChris Lattner     // second form is [[foo]] which is a reference to foo.  The variable name
23757cb733bSDaniel Dunbar     // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
2388879e06dSChris Lattner     // it.  This is to catch some common errors.
23953e0679dSChris Lattner     if (PatternStr.startswith("[[")) {
240061d2baaSEli Bendersky       // Find the closing bracket pair ending the match.  End is going to be an
241061d2baaSEli Bendersky       // offset relative to the beginning of the match string.
24281e5cd9eSAdrian Prantl       size_t End = FindRegexVarEnd(PatternStr.substr(2), SM);
243061d2baaSEli Bendersky 
2448879e06dSChris Lattner       if (End == StringRef::npos) {
2458879e06dSChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
24603b80a40SChris Lattner                         SourceMgr::DK_Error,
24703b80a40SChris Lattner                         "invalid named regex reference, no ]] found");
248f08d2db9SChris Lattner         return true;
249f08d2db9SChris Lattner       }
250f08d2db9SChris Lattner 
251061d2baaSEli Bendersky       StringRef MatchStr = PatternStr.substr(2, End);
252061d2baaSEli Bendersky       PatternStr = PatternStr.substr(End+4);
2538879e06dSChris Lattner 
2548879e06dSChris Lattner       // Get the regex name (e.g. "foo").
2558879e06dSChris Lattner       size_t NameEnd = MatchStr.find(':');
2568879e06dSChris Lattner       StringRef Name = MatchStr.substr(0, NameEnd);
2578879e06dSChris Lattner 
2588879e06dSChris Lattner       if (Name.empty()) {
25903b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
26003b80a40SChris Lattner                         "invalid name in named regex: empty name");
2618879e06dSChris Lattner         return true;
2628879e06dSChris Lattner       }
2638879e06dSChris Lattner 
26492987fb3SAlexander Kornienko       // Verify that the name/expression is well formed. FileCheck currently
26592987fb3SAlexander Kornienko       // supports @LINE, @LINE+number, @LINE-number expressions. The check here
26692987fb3SAlexander Kornienko       // is relaxed, more strict check is performed in \c EvaluateExpression.
26792987fb3SAlexander Kornienko       bool IsExpression = false;
26892987fb3SAlexander Kornienko       for (unsigned i = 0, e = Name.size(); i != e; ++i) {
26992987fb3SAlexander Kornienko         if (i == 0 && Name[i] == '@') {
27092987fb3SAlexander Kornienko           if (NameEnd != StringRef::npos) {
27192987fb3SAlexander Kornienko             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
27292987fb3SAlexander Kornienko                             SourceMgr::DK_Error,
27392987fb3SAlexander Kornienko                             "invalid name in named regex definition");
27492987fb3SAlexander Kornienko             return true;
27592987fb3SAlexander Kornienko           }
27692987fb3SAlexander Kornienko           IsExpression = true;
27792987fb3SAlexander Kornienko           continue;
27892987fb3SAlexander Kornienko         }
27992987fb3SAlexander Kornienko         if (Name[i] != '_' && !isalnum(Name[i]) &&
28092987fb3SAlexander Kornienko             (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
2818879e06dSChris Lattner           SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
28203b80a40SChris Lattner                           SourceMgr::DK_Error, "invalid name in named regex");
2838879e06dSChris Lattner           return true;
2848879e06dSChris Lattner         }
28592987fb3SAlexander Kornienko       }
2868879e06dSChris Lattner 
2878879e06dSChris Lattner       // Name can't start with a digit.
28883c74e9fSGuy Benyei       if (isdigit(static_cast<unsigned char>(Name[0]))) {
28903b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
29003b80a40SChris Lattner                         "invalid name in named regex");
2918879e06dSChris Lattner         return true;
2928879e06dSChris Lattner       }
2938879e06dSChris Lattner 
2948879e06dSChris Lattner       // Handle [[foo]].
2958879e06dSChris Lattner       if (NameEnd == StringRef::npos) {
296e8b8f1bcSEli Bendersky         // Handle variables that were defined earlier on the same line by
297e8b8f1bcSEli Bendersky         // emitting a backreference.
298e8b8f1bcSEli Bendersky         if (VariableDefs.find(Name) != VariableDefs.end()) {
299e8b8f1bcSEli Bendersky           unsigned VarParenNum = VariableDefs[Name];
300e8b8f1bcSEli Bendersky           if (VarParenNum < 1 || VarParenNum > 9) {
301e8b8f1bcSEli Bendersky             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
302e8b8f1bcSEli Bendersky                             SourceMgr::DK_Error,
303e8b8f1bcSEli Bendersky                             "Can't back-reference more than 9 variables");
304e8b8f1bcSEli Bendersky             return true;
305e8b8f1bcSEli Bendersky           }
306e8b8f1bcSEli Bendersky           AddBackrefToRegEx(VarParenNum);
307e8b8f1bcSEli Bendersky         } else {
3088879e06dSChris Lattner           VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
309e8b8f1bcSEli Bendersky         }
3108879e06dSChris Lattner         continue;
3118879e06dSChris Lattner       }
3128879e06dSChris Lattner 
3138879e06dSChris Lattner       // Handle [[foo:.*]].
314e8b8f1bcSEli Bendersky       VariableDefs[Name] = CurParen;
3158879e06dSChris Lattner       RegExStr += '(';
3168879e06dSChris Lattner       ++CurParen;
3178879e06dSChris Lattner 
3188879e06dSChris Lattner       if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
3198879e06dSChris Lattner         return true;
3208879e06dSChris Lattner 
3218879e06dSChris Lattner       RegExStr += ')';
3228879e06dSChris Lattner     }
3238879e06dSChris Lattner 
3248879e06dSChris Lattner     // Handle fixed string matches.
3258879e06dSChris Lattner     // Find the end, which is the start of the next regex.
3268879e06dSChris Lattner     size_t FixedMatchEnd = PatternStr.find("{{");
3278879e06dSChris Lattner     FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
3286f4f77b7SHans Wennborg     RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
3298879e06dSChris Lattner     PatternStr = PatternStr.substr(FixedMatchEnd);
330f08d2db9SChris Lattner   }
331f08d2db9SChris Lattner 
33274d50731SChris Lattner   return false;
33374d50731SChris Lattner }
33474d50731SChris Lattner 
335e8b8f1bcSEli Bendersky bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen,
3368879e06dSChris Lattner                               SourceMgr &SM) {
337e8b8f1bcSEli Bendersky   Regex R(RS);
3388879e06dSChris Lattner   std::string Error;
3398879e06dSChris Lattner   if (!R.isValid(Error)) {
340e8b8f1bcSEli Bendersky     SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
34103b80a40SChris Lattner                     "invalid regex: " + Error);
3428879e06dSChris Lattner     return true;
3438879e06dSChris Lattner   }
3448879e06dSChris Lattner 
345e8b8f1bcSEli Bendersky   RegExStr += RS.str();
3468879e06dSChris Lattner   CurParen += R.getNumMatches();
3478879e06dSChris Lattner   return false;
3488879e06dSChris Lattner }
349b16ab0c4SChris Lattner 
350e8b8f1bcSEli Bendersky void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
351e8b8f1bcSEli Bendersky   assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
352e8b8f1bcSEli Bendersky   std::string Backref = std::string("\\") +
353e8b8f1bcSEli Bendersky                         std::string(1, '0' + BackrefNum);
354e8b8f1bcSEli Bendersky   RegExStr += Backref;
355e8b8f1bcSEli Bendersky }
356e8b8f1bcSEli Bendersky 
35792987fb3SAlexander Kornienko bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
35892987fb3SAlexander Kornienko   // The only supported expression is @LINE([\+-]\d+)?
35992987fb3SAlexander Kornienko   if (!Expr.startswith("@LINE"))
36092987fb3SAlexander Kornienko     return false;
36192987fb3SAlexander Kornienko   Expr = Expr.substr(StringRef("@LINE").size());
36292987fb3SAlexander Kornienko   int Offset = 0;
36392987fb3SAlexander Kornienko   if (!Expr.empty()) {
36492987fb3SAlexander Kornienko     if (Expr[0] == '+')
36592987fb3SAlexander Kornienko       Expr = Expr.substr(1);
36692987fb3SAlexander Kornienko     else if (Expr[0] != '-')
36792987fb3SAlexander Kornienko       return false;
36892987fb3SAlexander Kornienko     if (Expr.getAsInteger(10, Offset))
36992987fb3SAlexander Kornienko       return false;
37092987fb3SAlexander Kornienko   }
37192987fb3SAlexander Kornienko   Value = llvm::itostr(LineNumber + Offset);
37292987fb3SAlexander Kornienko   return true;
37392987fb3SAlexander Kornienko }
37492987fb3SAlexander Kornienko 
375f08d2db9SChris Lattner /// Match - Match the pattern string against the input buffer Buffer.  This
376f08d2db9SChris Lattner /// returns the position that is matched or npos if there is no match.  If
377f08d2db9SChris Lattner /// there is a match, the size of the matched string is returned in MatchLen.
3788879e06dSChris Lattner size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
3798879e06dSChris Lattner                       StringMap<StringRef> &VariableTable) const {
380eba55822SJakob Stoklund Olesen   // If this is the EOF pattern, match it immediately.
38138820972SMatt Arsenault   if (CheckTy == Check::CheckEOF) {
382eba55822SJakob Stoklund Olesen     MatchLen = 0;
383eba55822SJakob Stoklund Olesen     return Buffer.size();
384eba55822SJakob Stoklund Olesen   }
385eba55822SJakob Stoklund Olesen 
386221460e0SChris Lattner   // If this is a fixed string pattern, just match it now.
387221460e0SChris Lattner   if (!FixedStr.empty()) {
388221460e0SChris Lattner     MatchLen = FixedStr.size();
389221460e0SChris Lattner     return Buffer.find(FixedStr);
390221460e0SChris Lattner   }
391221460e0SChris Lattner 
392b16ab0c4SChris Lattner   // Regex match.
3938879e06dSChris Lattner 
3948879e06dSChris Lattner   // If there are variable uses, we need to create a temporary string with the
3958879e06dSChris Lattner   // actual value.
3968879e06dSChris Lattner   StringRef RegExToMatch = RegExStr;
3978879e06dSChris Lattner   std::string TmpStr;
3988879e06dSChris Lattner   if (!VariableUses.empty()) {
3998879e06dSChris Lattner     TmpStr = RegExStr;
4008879e06dSChris Lattner 
4018879e06dSChris Lattner     unsigned InsertOffset = 0;
4028879e06dSChris Lattner     for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
40392987fb3SAlexander Kornienko       std::string Value;
40492987fb3SAlexander Kornienko 
40592987fb3SAlexander Kornienko       if (VariableUses[i].first[0] == '@') {
40692987fb3SAlexander Kornienko         if (!EvaluateExpression(VariableUses[i].first, Value))
40792987fb3SAlexander Kornienko           return StringRef::npos;
40892987fb3SAlexander Kornienko       } else {
409e0ef65abSDaniel Dunbar         StringMap<StringRef>::iterator it =
410e0ef65abSDaniel Dunbar           VariableTable.find(VariableUses[i].first);
411e0ef65abSDaniel Dunbar         // If the variable is undefined, return an error.
412e0ef65abSDaniel Dunbar         if (it == VariableTable.end())
413e0ef65abSDaniel Dunbar           return StringRef::npos;
414e0ef65abSDaniel Dunbar 
4156f4f77b7SHans Wennborg         // Look up the value and escape it so that we can put it into the regex.
4166f4f77b7SHans Wennborg         Value += Regex::escape(it->second);
41792987fb3SAlexander Kornienko       }
4188879e06dSChris Lattner 
4198879e06dSChris Lattner       // Plop it into the regex at the adjusted offset.
4208879e06dSChris Lattner       TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset,
4218879e06dSChris Lattner                     Value.begin(), Value.end());
4228879e06dSChris Lattner       InsertOffset += Value.size();
4238879e06dSChris Lattner     }
4248879e06dSChris Lattner 
4258879e06dSChris Lattner     // Match the newly constructed regex.
4268879e06dSChris Lattner     RegExToMatch = TmpStr;
4278879e06dSChris Lattner   }
4288879e06dSChris Lattner 
4298879e06dSChris Lattner 
430b16ab0c4SChris Lattner   SmallVector<StringRef, 4> MatchInfo;
4318879e06dSChris Lattner   if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
432f08d2db9SChris Lattner     return StringRef::npos;
433b16ab0c4SChris Lattner 
434b16ab0c4SChris Lattner   // Successful regex match.
435b16ab0c4SChris Lattner   assert(!MatchInfo.empty() && "Didn't get any match");
436b16ab0c4SChris Lattner   StringRef FullMatch = MatchInfo[0];
437b16ab0c4SChris Lattner 
4388879e06dSChris Lattner   // If this defines any variables, remember their values.
439e8b8f1bcSEli Bendersky   for (std::map<StringRef, unsigned>::const_iterator I = VariableDefs.begin(),
440e8b8f1bcSEli Bendersky                                                      E = VariableDefs.end();
441e8b8f1bcSEli Bendersky        I != E; ++I) {
442e8b8f1bcSEli Bendersky     assert(I->second < MatchInfo.size() && "Internal paren error");
443e8b8f1bcSEli Bendersky     VariableTable[I->first] = MatchInfo[I->second];
4440a4c44bdSChris Lattner   }
4450a4c44bdSChris Lattner 
446b16ab0c4SChris Lattner   MatchLen = FullMatch.size();
447b16ab0c4SChris Lattner   return FullMatch.data()-Buffer.data();
448f08d2db9SChris Lattner }
449f08d2db9SChris Lattner 
450fd29d886SDaniel Dunbar unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
451fd29d886SDaniel Dunbar                               const StringMap<StringRef> &VariableTable) const {
452fd29d886SDaniel Dunbar   // Just compute the number of matching characters. For regular expressions, we
453fd29d886SDaniel Dunbar   // just compare against the regex itself and hope for the best.
454fd29d886SDaniel Dunbar   //
455fd29d886SDaniel Dunbar   // FIXME: One easy improvement here is have the regex lib generate a single
456fd29d886SDaniel Dunbar   // example regular expression which matches, and use that as the example
457fd29d886SDaniel Dunbar   // string.
458fd29d886SDaniel Dunbar   StringRef ExampleString(FixedStr);
459fd29d886SDaniel Dunbar   if (ExampleString.empty())
460fd29d886SDaniel Dunbar     ExampleString = RegExStr;
461fd29d886SDaniel Dunbar 
462e9aa36c8SDaniel Dunbar   // Only compare up to the first line in the buffer, or the string size.
463e9aa36c8SDaniel Dunbar   StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
464e9aa36c8SDaniel Dunbar   BufferPrefix = BufferPrefix.split('\n').first;
465e9aa36c8SDaniel Dunbar   return BufferPrefix.edit_distance(ExampleString);
466fd29d886SDaniel Dunbar }
467fd29d886SDaniel Dunbar 
468e0ef65abSDaniel Dunbar void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
469e0ef65abSDaniel Dunbar                                const StringMap<StringRef> &VariableTable) const{
470e0ef65abSDaniel Dunbar   // If this was a regular expression using variables, print the current
471e0ef65abSDaniel Dunbar   // variable values.
472e0ef65abSDaniel Dunbar   if (!VariableUses.empty()) {
473e0ef65abSDaniel Dunbar     for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
474e69170a1SAlp Toker       SmallString<256> Msg;
475e69170a1SAlp Toker       raw_svector_ostream OS(Msg);
47692987fb3SAlexander Kornienko       StringRef Var = VariableUses[i].first;
47792987fb3SAlexander Kornienko       if (Var[0] == '@') {
47892987fb3SAlexander Kornienko         std::string Value;
47992987fb3SAlexander Kornienko         if (EvaluateExpression(Var, Value)) {
48092987fb3SAlexander Kornienko           OS << "with expression \"";
48192987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\" equal to \"";
48292987fb3SAlexander Kornienko           OS.write_escaped(Value) << "\"";
48392987fb3SAlexander Kornienko         } else {
48492987fb3SAlexander Kornienko           OS << "uses incorrect expression \"";
48592987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
48692987fb3SAlexander Kornienko         }
48792987fb3SAlexander Kornienko       } else {
48892987fb3SAlexander Kornienko         StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
489e0ef65abSDaniel Dunbar 
490e0ef65abSDaniel Dunbar         // Check for undefined variable references.
491e0ef65abSDaniel Dunbar         if (it == VariableTable.end()) {
492e0ef65abSDaniel Dunbar           OS << "uses undefined variable \"";
49392987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
494e0ef65abSDaniel Dunbar         } else {
495e0ef65abSDaniel Dunbar           OS << "with variable \"";
496e0ef65abSDaniel Dunbar           OS.write_escaped(Var) << "\" equal to \"";
497e0ef65abSDaniel Dunbar           OS.write_escaped(it->second) << "\"";
498e0ef65abSDaniel Dunbar         }
49992987fb3SAlexander Kornienko       }
500e0ef65abSDaniel Dunbar 
50103b80a40SChris Lattner       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
50203b80a40SChris Lattner                       OS.str());
503e0ef65abSDaniel Dunbar     }
504e0ef65abSDaniel Dunbar   }
505fd29d886SDaniel Dunbar 
506fd29d886SDaniel Dunbar   // Attempt to find the closest/best fuzzy match.  Usually an error happens
507fd29d886SDaniel Dunbar   // because some string in the output didn't exactly match. In these cases, we
508fd29d886SDaniel Dunbar   // would like to show the user a best guess at what "should have" matched, to
509fd29d886SDaniel Dunbar   // save them having to actually check the input manually.
510fd29d886SDaniel Dunbar   size_t NumLinesForward = 0;
511fd29d886SDaniel Dunbar   size_t Best = StringRef::npos;
512fd29d886SDaniel Dunbar   double BestQuality = 0;
513fd29d886SDaniel Dunbar 
514fd29d886SDaniel Dunbar   // Use an arbitrary 4k limit on how far we will search.
5152bf486ebSDan Gohman   for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
516fd29d886SDaniel Dunbar     if (Buffer[i] == '\n')
517fd29d886SDaniel Dunbar       ++NumLinesForward;
518fd29d886SDaniel Dunbar 
519df22bbf7SDan Gohman     // Patterns have leading whitespace stripped, so skip whitespace when
520df22bbf7SDan Gohman     // looking for something which looks like a pattern.
521df22bbf7SDan Gohman     if (Buffer[i] == ' ' || Buffer[i] == '\t')
522df22bbf7SDan Gohman       continue;
523df22bbf7SDan Gohman 
524fd29d886SDaniel Dunbar     // Compute the "quality" of this match as an arbitrary combination of the
525fd29d886SDaniel Dunbar     // match distance and the number of lines skipped to get to this match.
526fd29d886SDaniel Dunbar     unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
527fd29d886SDaniel Dunbar     double Quality = Distance + (NumLinesForward / 100.);
528fd29d886SDaniel Dunbar 
529fd29d886SDaniel Dunbar     if (Quality < BestQuality || Best == StringRef::npos) {
530fd29d886SDaniel Dunbar       Best = i;
531fd29d886SDaniel Dunbar       BestQuality = Quality;
532fd29d886SDaniel Dunbar     }
533fd29d886SDaniel Dunbar   }
534fd29d886SDaniel Dunbar 
535fd29d886SDaniel Dunbar   // Print the "possible intended match here" line if we found something
536c069cc8eSDaniel Dunbar   // reasonable and not equal to what we showed in the "scanning from here"
537c069cc8eSDaniel Dunbar   // line.
538c069cc8eSDaniel Dunbar   if (Best && Best != StringRef::npos && BestQuality < 50) {
539fd29d886SDaniel Dunbar       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
54003b80a40SChris Lattner                       SourceMgr::DK_Note, "possible intended match here");
541fd29d886SDaniel Dunbar 
542fd29d886SDaniel Dunbar     // FIXME: If we wanted to be really friendly we would show why the match
543fd29d886SDaniel Dunbar     // failed, as it can be hard to spot simple one character differences.
544fd29d886SDaniel Dunbar   }
545e0ef65abSDaniel Dunbar }
54674d50731SChris Lattner 
54781e5cd9eSAdrian Prantl size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
548061d2baaSEli Bendersky   // Offset keeps track of the current offset within the input Str
549061d2baaSEli Bendersky   size_t Offset = 0;
550061d2baaSEli Bendersky   // [...] Nesting depth
551061d2baaSEli Bendersky   size_t BracketDepth = 0;
552061d2baaSEli Bendersky 
553061d2baaSEli Bendersky   while (!Str.empty()) {
554061d2baaSEli Bendersky     if (Str.startswith("]]") && BracketDepth == 0)
555061d2baaSEli Bendersky       return Offset;
556061d2baaSEli Bendersky     if (Str[0] == '\\') {
557061d2baaSEli Bendersky       // Backslash escapes the next char within regexes, so skip them both.
558061d2baaSEli Bendersky       Str = Str.substr(2);
559061d2baaSEli Bendersky       Offset += 2;
560061d2baaSEli Bendersky     } else {
561061d2baaSEli Bendersky       switch (Str[0]) {
562061d2baaSEli Bendersky         default:
563061d2baaSEli Bendersky           break;
564061d2baaSEli Bendersky         case '[':
565061d2baaSEli Bendersky           BracketDepth++;
566061d2baaSEli Bendersky           break;
567061d2baaSEli Bendersky         case ']':
56881e5cd9eSAdrian Prantl           if (BracketDepth == 0) {
56981e5cd9eSAdrian Prantl             SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
57081e5cd9eSAdrian Prantl                             SourceMgr::DK_Error,
57181e5cd9eSAdrian Prantl                             "missing closing \"]\" for regex variable");
57281e5cd9eSAdrian Prantl             exit(1);
57381e5cd9eSAdrian Prantl           }
574061d2baaSEli Bendersky           BracketDepth--;
575061d2baaSEli Bendersky           break;
576061d2baaSEli Bendersky       }
577061d2baaSEli Bendersky       Str = Str.substr(1);
578061d2baaSEli Bendersky       Offset++;
579061d2baaSEli Bendersky     }
580061d2baaSEli Bendersky   }
581061d2baaSEli Bendersky 
582061d2baaSEli Bendersky   return StringRef::npos;
583061d2baaSEli Bendersky }
584061d2baaSEli Bendersky 
585061d2baaSEli Bendersky 
58674d50731SChris Lattner //===----------------------------------------------------------------------===//
58774d50731SChris Lattner // Check Strings.
58874d50731SChris Lattner //===----------------------------------------------------------------------===//
5893b40b445SChris Lattner 
5903b40b445SChris Lattner /// CheckString - This is a check that we found in the input file.
5913b40b445SChris Lattner struct CheckString {
5923b40b445SChris Lattner   /// Pat - The pattern to match.
5933b40b445SChris Lattner   Pattern Pat;
59426cccfe1SChris Lattner 
59513df4626SMatt Arsenault   /// Prefix - Which prefix name this check matched.
59613df4626SMatt Arsenault   StringRef Prefix;
59713df4626SMatt Arsenault 
59826cccfe1SChris Lattner   /// Loc - The location in the match file that the check string was specified.
59926cccfe1SChris Lattner   SMLoc Loc;
60026cccfe1SChris Lattner 
60138820972SMatt Arsenault   /// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive,
60238820972SMatt Arsenault   /// as opposed to a CHECK: directive.
60338820972SMatt Arsenault   Check::CheckType CheckTy;
604f8bd2e5bSStephen Lin 
60591a1b2c9SMichael Liao   /// DagNotStrings - These are all of the strings that are disallowed from
606236d2d5eSChris Lattner   /// occurring between this match string and the previous one (or start of
607236d2d5eSChris Lattner   /// file).
60891a1b2c9SMichael Liao   std::vector<Pattern> DagNotStrings;
609236d2d5eSChris Lattner 
61013df4626SMatt Arsenault 
61113df4626SMatt Arsenault   CheckString(const Pattern &P,
61213df4626SMatt Arsenault               StringRef S,
61313df4626SMatt Arsenault               SMLoc L,
61413df4626SMatt Arsenault               Check::CheckType Ty)
61513df4626SMatt Arsenault     : Pat(P), Prefix(S), Loc(L), CheckTy(Ty) {}
616dcc7d48dSMichael Liao 
61791a1b2c9SMichael Liao   /// Check - Match check string and its "not strings" and/or "dag strings".
618e93a3a08SStephen Lin   size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
619f8bd2e5bSStephen Lin                size_t &MatchLen, StringMap<StringRef> &VariableTable) const;
620dcc7d48dSMichael Liao 
621dcc7d48dSMichael Liao   /// CheckNext - Verify there is a single line in the given buffer.
622dcc7d48dSMichael Liao   bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
623dcc7d48dSMichael Liao 
62401ac1707SDuncan P. N. Exon Smith   /// CheckSame - Verify there is no newline in the given buffer.
62501ac1707SDuncan P. N. Exon Smith   bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
62601ac1707SDuncan P. N. Exon Smith 
627dcc7d48dSMichael Liao   /// CheckNot - Verify there's no "not strings" in the given buffer.
628dcc7d48dSMichael Liao   bool CheckNot(const SourceMgr &SM, StringRef Buffer,
62991a1b2c9SMichael Liao                 const std::vector<const Pattern *> &NotStrings,
63091a1b2c9SMichael Liao                 StringMap<StringRef> &VariableTable) const;
63191a1b2c9SMichael Liao 
63291a1b2c9SMichael Liao   /// CheckDag - Match "dag strings" and their mixed "not strings".
63391a1b2c9SMichael Liao   size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
63491a1b2c9SMichael Liao                   std::vector<const Pattern *> &NotStrings,
635dcc7d48dSMichael Liao                   StringMap<StringRef> &VariableTable) const;
63626cccfe1SChris Lattner };
63726cccfe1SChris Lattner 
6385ea04c38SGuy Benyei /// Canonicalize whitespaces in the input file. Line endings are replaced
6395ea04c38SGuy Benyei /// with UNIX-style '\n'.
6405ea04c38SGuy Benyei ///
6415ea04c38SGuy Benyei /// \param PreserveHorizontal Don't squash consecutive horizontal whitespace
6425ea04c38SGuy Benyei /// characters to a single space.
6431961f14cSDavid Blaikie static std::unique_ptr<MemoryBuffer>
6441961f14cSDavid Blaikie CanonicalizeInputFile(std::unique_ptr<MemoryBuffer> MB,
6455ea04c38SGuy Benyei                       bool PreserveHorizontal) {
6460e45d24aSChris Lattner   SmallString<128> NewFile;
647a2f8fc5aSChris Lattner   NewFile.reserve(MB->getBufferSize());
648a2f8fc5aSChris Lattner 
649a2f8fc5aSChris Lattner   for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
650a2f8fc5aSChris Lattner        Ptr != End; ++Ptr) {
651fd781bf0SNAKAMURA Takumi     // Eliminate trailing dosish \r.
652fd781bf0SNAKAMURA Takumi     if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
653fd781bf0SNAKAMURA Takumi       continue;
654fd781bf0SNAKAMURA Takumi     }
655fd781bf0SNAKAMURA Takumi 
6565ea04c38SGuy Benyei     // If current char is not a horizontal whitespace or if horizontal
6575ea04c38SGuy Benyei     // whitespace canonicalization is disabled, dump it to output as is.
6585ea04c38SGuy Benyei     if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) {
659a2f8fc5aSChris Lattner       NewFile.push_back(*Ptr);
660a2f8fc5aSChris Lattner       continue;
661a2f8fc5aSChris Lattner     }
662a2f8fc5aSChris Lattner 
663a2f8fc5aSChris Lattner     // Otherwise, add one space and advance over neighboring space.
664a2f8fc5aSChris Lattner     NewFile.push_back(' ');
665a2f8fc5aSChris Lattner     while (Ptr+1 != End &&
666a2f8fc5aSChris Lattner            (Ptr[1] == ' ' || Ptr[1] == '\t'))
667a2f8fc5aSChris Lattner       ++Ptr;
668a2f8fc5aSChris Lattner   }
669a2f8fc5aSChris Lattner 
6701961f14cSDavid Blaikie   return std::unique_ptr<MemoryBuffer>(
6711961f14cSDavid Blaikie       MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier()));
672a2f8fc5aSChris Lattner }
673a2f8fc5aSChris Lattner 
67438820972SMatt Arsenault static bool IsPartOfWord(char c) {
67538820972SMatt Arsenault   return (isalnum(c) || c == '-' || c == '_');
67638820972SMatt Arsenault }
67738820972SMatt Arsenault 
67813df4626SMatt Arsenault // Get the size of the prefix extension.
67913df4626SMatt Arsenault static size_t CheckTypeSize(Check::CheckType Ty) {
68013df4626SMatt Arsenault   switch (Ty) {
68113df4626SMatt Arsenault   case Check::CheckNone:
68213df4626SMatt Arsenault     return 0;
68313df4626SMatt Arsenault 
68413df4626SMatt Arsenault   case Check::CheckPlain:
68513df4626SMatt Arsenault     return sizeof(":") - 1;
68613df4626SMatt Arsenault 
68713df4626SMatt Arsenault   case Check::CheckNext:
68813df4626SMatt Arsenault     return sizeof("-NEXT:") - 1;
68913df4626SMatt Arsenault 
69001ac1707SDuncan P. N. Exon Smith   case Check::CheckSame:
69101ac1707SDuncan P. N. Exon Smith     return sizeof("-SAME:") - 1;
69201ac1707SDuncan P. N. Exon Smith 
69313df4626SMatt Arsenault   case Check::CheckNot:
69413df4626SMatt Arsenault     return sizeof("-NOT:") - 1;
69513df4626SMatt Arsenault 
69613df4626SMatt Arsenault   case Check::CheckDAG:
69713df4626SMatt Arsenault     return sizeof("-DAG:") - 1;
69813df4626SMatt Arsenault 
69913df4626SMatt Arsenault   case Check::CheckLabel:
70013df4626SMatt Arsenault     return sizeof("-LABEL:") - 1;
70113df4626SMatt Arsenault 
70213df4626SMatt Arsenault   case Check::CheckEOF:
70313df4626SMatt Arsenault     llvm_unreachable("Should not be using EOF size");
70413df4626SMatt Arsenault   }
70513df4626SMatt Arsenault 
70613df4626SMatt Arsenault   llvm_unreachable("Bad check type");
70713df4626SMatt Arsenault }
70813df4626SMatt Arsenault 
70913df4626SMatt Arsenault static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
710c4d2d471SMatt Arsenault   char NextChar = Buffer[Prefix.size()];
71138820972SMatt Arsenault 
71238820972SMatt Arsenault   // Verify that the : is present after the prefix.
71313df4626SMatt Arsenault   if (NextChar == ':')
71438820972SMatt Arsenault     return Check::CheckPlain;
71538820972SMatt Arsenault 
71613df4626SMatt Arsenault   if (NextChar != '-')
71738820972SMatt Arsenault     return Check::CheckNone;
71838820972SMatt Arsenault 
719c4d2d471SMatt Arsenault   StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
72013df4626SMatt Arsenault   if (Rest.startswith("NEXT:"))
72138820972SMatt Arsenault     return Check::CheckNext;
72238820972SMatt Arsenault 
72301ac1707SDuncan P. N. Exon Smith   if (Rest.startswith("SAME:"))
72401ac1707SDuncan P. N. Exon Smith     return Check::CheckSame;
72501ac1707SDuncan P. N. Exon Smith 
72613df4626SMatt Arsenault   if (Rest.startswith("NOT:"))
72738820972SMatt Arsenault     return Check::CheckNot;
72838820972SMatt Arsenault 
72913df4626SMatt Arsenault   if (Rest.startswith("DAG:"))
73038820972SMatt Arsenault     return Check::CheckDAG;
73138820972SMatt Arsenault 
73213df4626SMatt Arsenault   if (Rest.startswith("LABEL:"))
73338820972SMatt Arsenault     return Check::CheckLabel;
73413df4626SMatt Arsenault 
73513df4626SMatt Arsenault   return Check::CheckNone;
73638820972SMatt Arsenault }
73738820972SMatt Arsenault 
73813df4626SMatt Arsenault // From the given position, find the next character after the word.
73913df4626SMatt Arsenault static size_t SkipWord(StringRef Str, size_t Loc) {
74013df4626SMatt Arsenault   while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
74113df4626SMatt Arsenault     ++Loc;
74213df4626SMatt Arsenault   return Loc;
74313df4626SMatt Arsenault }
74413df4626SMatt Arsenault 
74513df4626SMatt Arsenault // Try to find the first match in buffer for any prefix. If a valid match is
74613df4626SMatt Arsenault // found, return that prefix and set its type and location.  If there are almost
74713df4626SMatt Arsenault // matches (e.g. the actual prefix string is found, but is not an actual check
74813df4626SMatt Arsenault // string), but no valid match, return an empty string and set the position to
74913df4626SMatt Arsenault // resume searching from. If no partial matches are found, return an empty
75013df4626SMatt Arsenault // string and the location will be StringRef::npos. If one prefix is a substring
75113df4626SMatt Arsenault // of another, the maximal match should be found. e.g. if "A" and "AA" are
75213df4626SMatt Arsenault // prefixes then AA-CHECK: should match the second one.
75313df4626SMatt Arsenault static StringRef FindFirstCandidateMatch(StringRef &Buffer,
75413df4626SMatt Arsenault                                          Check::CheckType &CheckTy,
75513df4626SMatt Arsenault                                          size_t &CheckLoc) {
75613df4626SMatt Arsenault   StringRef FirstPrefix;
75713df4626SMatt Arsenault   size_t FirstLoc = StringRef::npos;
75813df4626SMatt Arsenault   size_t SearchLoc = StringRef::npos;
75913df4626SMatt Arsenault   Check::CheckType FirstTy = Check::CheckNone;
76013df4626SMatt Arsenault 
76113df4626SMatt Arsenault   CheckTy = Check::CheckNone;
76213df4626SMatt Arsenault   CheckLoc = StringRef::npos;
76313df4626SMatt Arsenault 
76413df4626SMatt Arsenault   for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
76513df4626SMatt Arsenault        I != E; ++I) {
76613df4626SMatt Arsenault     StringRef Prefix(*I);
76713df4626SMatt Arsenault     size_t PrefixLoc = Buffer.find(Prefix);
76813df4626SMatt Arsenault 
76913df4626SMatt Arsenault     if (PrefixLoc == StringRef::npos)
77013df4626SMatt Arsenault       continue;
77113df4626SMatt Arsenault 
77213df4626SMatt Arsenault     // Track where we are searching for invalid prefixes that look almost right.
77313df4626SMatt Arsenault     // We need to only advance to the first partial match on the next attempt
77413df4626SMatt Arsenault     // since a partial match could be a substring of a later, valid prefix.
77513df4626SMatt Arsenault     // Need to skip to the end of the word, otherwise we could end up
77613df4626SMatt Arsenault     // matching a prefix in a substring later.
77713df4626SMatt Arsenault     if (PrefixLoc < SearchLoc)
77813df4626SMatt Arsenault       SearchLoc = SkipWord(Buffer, PrefixLoc);
77913df4626SMatt Arsenault 
78013df4626SMatt Arsenault     // We only want to find the first match to avoid skipping some.
78113df4626SMatt Arsenault     if (PrefixLoc > FirstLoc)
78213df4626SMatt Arsenault       continue;
783a7181a1bSAlexey Samsonov     // If one matching check-prefix is a prefix of another, choose the
784a7181a1bSAlexey Samsonov     // longer one.
785a7181a1bSAlexey Samsonov     if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size())
786a7181a1bSAlexey Samsonov       continue;
78713df4626SMatt Arsenault 
78813df4626SMatt Arsenault     StringRef Rest = Buffer.drop_front(PrefixLoc);
78913df4626SMatt Arsenault     // Make sure we have actually found the prefix, and not a word containing
79013df4626SMatt Arsenault     // it. This should also prevent matching the wrong prefix when one is a
79113df4626SMatt Arsenault     // substring of another.
79213df4626SMatt Arsenault     if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
79343b5f572SDaniel Sanders       FirstTy = Check::CheckNone;
79443b5f572SDaniel Sanders     else
79543b5f572SDaniel Sanders       FirstTy = FindCheckType(Rest, Prefix);
79613df4626SMatt Arsenault 
79713df4626SMatt Arsenault     FirstLoc = PrefixLoc;
798a7181a1bSAlexey Samsonov     FirstPrefix = Prefix;
79913df4626SMatt Arsenault   }
80013df4626SMatt Arsenault 
801a7181a1bSAlexey Samsonov   // If the first prefix is invalid, we should continue the search after it.
802a7181a1bSAlexey Samsonov   if (FirstTy == Check::CheckNone) {
80313df4626SMatt Arsenault     CheckLoc = SearchLoc;
804a7181a1bSAlexey Samsonov     return "";
805a7181a1bSAlexey Samsonov   }
806a7181a1bSAlexey Samsonov 
80713df4626SMatt Arsenault   CheckTy = FirstTy;
80813df4626SMatt Arsenault   CheckLoc = FirstLoc;
80913df4626SMatt Arsenault   return FirstPrefix;
81013df4626SMatt Arsenault }
81113df4626SMatt Arsenault 
81213df4626SMatt Arsenault static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
81313df4626SMatt Arsenault                                          unsigned &LineNumber,
81413df4626SMatt Arsenault                                          Check::CheckType &CheckTy,
81513df4626SMatt Arsenault                                          size_t &CheckLoc) {
81613df4626SMatt Arsenault   while (!Buffer.empty()) {
81713df4626SMatt Arsenault     StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc);
81813df4626SMatt Arsenault     // If we found a real match, we are done.
81913df4626SMatt Arsenault     if (!Prefix.empty()) {
82013df4626SMatt Arsenault       LineNumber += Buffer.substr(0, CheckLoc).count('\n');
82113df4626SMatt Arsenault       return Prefix;
82213df4626SMatt Arsenault     }
82313df4626SMatt Arsenault 
82413df4626SMatt Arsenault     // We didn't find any almost matches either, we are also done.
82513df4626SMatt Arsenault     if (CheckLoc == StringRef::npos)
82613df4626SMatt Arsenault       return StringRef();
82713df4626SMatt Arsenault 
82813df4626SMatt Arsenault     LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
82913df4626SMatt Arsenault 
83013df4626SMatt Arsenault     // Advance to the last possible match we found and try again.
83113df4626SMatt Arsenault     Buffer = Buffer.drop_front(CheckLoc + 1);
83213df4626SMatt Arsenault   }
83313df4626SMatt Arsenault 
83413df4626SMatt Arsenault   return StringRef();
83538820972SMatt Arsenault }
836ee3c74fbSChris Lattner 
837ee3c74fbSChris Lattner /// ReadCheckFile - Read the check file, which specifies the sequence of
838ee3c74fbSChris Lattner /// expected strings.  The strings are added to the CheckStrings vector.
83943d50d4aSEli Bendersky /// Returns true in case of an error, false otherwise.
840ee3c74fbSChris Lattner static bool ReadCheckFile(SourceMgr &SM,
84126cccfe1SChris Lattner                           std::vector<CheckString> &CheckStrings) {
842adf21f2aSRafael Espindola   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
843adf21f2aSRafael Espindola       MemoryBuffer::getFileOrSTDIN(CheckFilename);
844adf21f2aSRafael Espindola   if (std::error_code EC = FileOrErr.getError()) {
845adf21f2aSRafael Espindola     errs() << "Could not open check file '" << CheckFilename
846adf21f2aSRafael Espindola            << "': " << EC.message() << '\n';
847ee3c74fbSChris Lattner     return true;
848ee3c74fbSChris Lattner   }
849a2f8fc5aSChris Lattner 
850a2f8fc5aSChris Lattner   // If we want to canonicalize whitespace, strip excess whitespace from the
8515ea04c38SGuy Benyei   // buffer containing the CHECK lines. Remove DOS style line endings.
8523560ff2cSRafael Espindola   std::unique_ptr<MemoryBuffer> F = CanonicalizeInputFile(
8533560ff2cSRafael Espindola       std::move(FileOrErr.get()), NoCanonicalizeWhiteSpace);
854ee3c74fbSChris Lattner 
85510f10cedSChris Lattner   // Find all instances of CheckPrefix followed by : in the file.
856caa5fc0cSChris Lattner   StringRef Buffer = F->getBuffer();
85756ccdbbdSAlexander Kornienko 
8581961f14cSDavid Blaikie   SM.AddNewSourceBuffer(std::move(F), SMLoc());
8591961f14cSDavid Blaikie 
86056ccdbbdSAlexander Kornienko   std::vector<Pattern> ImplicitNegativeChecks;
86156ccdbbdSAlexander Kornienko   for (const auto &PatternString : ImplicitCheckNot) {
86256ccdbbdSAlexander Kornienko     // Create a buffer with fake command line content in order to display the
86356ccdbbdSAlexander Kornienko     // command line option responsible for the specific implicit CHECK-NOT.
86456ccdbbdSAlexander Kornienko     std::string Prefix = std::string("-") + ImplicitCheckNot.ArgStr + "='";
86556ccdbbdSAlexander Kornienko     std::string Suffix = "'";
8663560ff2cSRafael Espindola     std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
8673560ff2cSRafael Espindola         Prefix + PatternString + Suffix, "command line");
8683560ff2cSRafael Espindola 
86956ccdbbdSAlexander Kornienko     StringRef PatternInBuffer =
87056ccdbbdSAlexander Kornienko         CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
8711961f14cSDavid Blaikie     SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
87256ccdbbdSAlexander Kornienko 
87356ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
87456ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
87556ccdbbdSAlexander Kornienko                                                "IMPLICIT-CHECK", SM, 0);
87656ccdbbdSAlexander Kornienko   }
87756ccdbbdSAlexander Kornienko 
87856ccdbbdSAlexander Kornienko 
87956ccdbbdSAlexander Kornienko   std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
880236d2d5eSChris Lattner 
88143d50d4aSEli Bendersky   // LineNumber keeps track of the line on which CheckPrefix instances are
88243d50d4aSEli Bendersky   // found.
88392987fb3SAlexander Kornienko   unsigned LineNumber = 1;
88492987fb3SAlexander Kornienko 
885ee3c74fbSChris Lattner   while (1) {
88613df4626SMatt Arsenault     Check::CheckType CheckTy;
88713df4626SMatt Arsenault     size_t PrefixLoc;
88813df4626SMatt Arsenault 
88913df4626SMatt Arsenault     // See if a prefix occurs in the memory buffer.
89013df4626SMatt Arsenault     StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
89113df4626SMatt Arsenault                                                    LineNumber,
89213df4626SMatt Arsenault                                                    CheckTy,
89313df4626SMatt Arsenault                                                    PrefixLoc);
89413df4626SMatt Arsenault     if (UsedPrefix.empty())
895ee3c74fbSChris Lattner       break;
896ee3c74fbSChris Lattner 
89713df4626SMatt Arsenault     Buffer = Buffer.drop_front(PrefixLoc);
89892987fb3SAlexander Kornienko 
89913df4626SMatt Arsenault     // Location to use for error messages.
90013df4626SMatt Arsenault     const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
90192987fb3SAlexander Kornienko 
90213df4626SMatt Arsenault     // PrefixLoc is to the start of the prefix. Skip to the end.
90313df4626SMatt Arsenault     Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
90410f10cedSChris Lattner 
90538820972SMatt Arsenault     // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
90638820972SMatt Arsenault     // leading and trailing whitespace.
907236d2d5eSChris Lattner     Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
908ee3c74fbSChris Lattner 
909ee3c74fbSChris Lattner     // Scan ahead to the end of line.
910caa5fc0cSChris Lattner     size_t EOL = Buffer.find_first_of("\n\r");
911ee3c74fbSChris Lattner 
912838fb09aSDan Gohman     // Remember the location of the start of the pattern, for diagnostics.
913838fb09aSDan Gohman     SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
914838fb09aSDan Gohman 
91574d50731SChris Lattner     // Parse the pattern.
91638820972SMatt Arsenault     Pattern P(CheckTy);
91713df4626SMatt Arsenault     if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
918ee3c74fbSChris Lattner       return true;
919ee3c74fbSChris Lattner 
920f8bd2e5bSStephen Lin     // Verify that CHECK-LABEL lines do not define or use variables
92138820972SMatt Arsenault     if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
92213df4626SMatt Arsenault       SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
923f8bd2e5bSStephen Lin                       SourceMgr::DK_Error,
92413df4626SMatt Arsenault                       "found '" + UsedPrefix + "-LABEL:'"
92513df4626SMatt Arsenault                       " with variable definition or use");
926f8bd2e5bSStephen Lin       return true;
927f8bd2e5bSStephen Lin     }
928f8bd2e5bSStephen Lin 
929236d2d5eSChris Lattner     Buffer = Buffer.substr(EOL);
93074d50731SChris Lattner 
931da108b4eSChris Lattner     // Verify that CHECK-NEXT lines have at least one CHECK line before them.
93201ac1707SDuncan P. N. Exon Smith     if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&
93301ac1707SDuncan P. N. Exon Smith         CheckStrings.empty()) {
93401ac1707SDuncan P. N. Exon Smith       StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";
93513df4626SMatt Arsenault       SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
93603b80a40SChris Lattner                       SourceMgr::DK_Error,
93701ac1707SDuncan P. N. Exon Smith                       "found '" + UsedPrefix + "-" + Type + "' without previous '"
93813df4626SMatt Arsenault                       + UsedPrefix + ": line");
939da108b4eSChris Lattner       return true;
940da108b4eSChris Lattner     }
941da108b4eSChris Lattner 
94291a1b2c9SMichael Liao     // Handle CHECK-DAG/-NOT.
94338820972SMatt Arsenault     if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
94491a1b2c9SMichael Liao       DagNotMatches.push_back(P);
94574d50731SChris Lattner       continue;
94674d50731SChris Lattner     }
94774d50731SChris Lattner 
948ee3c74fbSChris Lattner     // Okay, add the string we captured to the output vector and move on.
949*f5e2fc47SBenjamin Kramer     CheckStrings.emplace_back(P, UsedPrefix, PatternLoc, CheckTy);
95091a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
95156ccdbbdSAlexander Kornienko     DagNotMatches = ImplicitNegativeChecks;
952ee3c74fbSChris Lattner   }
953ee3c74fbSChris Lattner 
95413df4626SMatt Arsenault   // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
95513df4626SMatt Arsenault   // prefix as a filler for the error message.
95691a1b2c9SMichael Liao   if (!DagNotMatches.empty()) {
957*f5e2fc47SBenjamin Kramer     CheckStrings.emplace_back(Pattern(Check::CheckEOF), *CheckPrefixes.begin(),
958eba55822SJakob Stoklund Olesen                               SMLoc::getFromPointer(Buffer.data()),
959*f5e2fc47SBenjamin Kramer                               Check::CheckEOF);
96091a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
961eba55822SJakob Stoklund Olesen   }
962eba55822SJakob Stoklund Olesen 
963ee3c74fbSChris Lattner   if (CheckStrings.empty()) {
96413df4626SMatt Arsenault     errs() << "error: no check strings found with prefix"
96513df4626SMatt Arsenault            << (CheckPrefixes.size() > 1 ? "es " : " ");
9663e3ef2f2SChris Bieneman     prefix_iterator I = CheckPrefixes.begin();
9673e3ef2f2SChris Bieneman     prefix_iterator E = CheckPrefixes.end();
9683e3ef2f2SChris Bieneman     if (I != E) {
9693e3ef2f2SChris Bieneman       errs() << "\'" << *I << ":'";
9703e3ef2f2SChris Bieneman       ++I;
97113df4626SMatt Arsenault     }
9723e3ef2f2SChris Bieneman     for (; I != E; ++I)
9733e3ef2f2SChris Bieneman       errs() << ", \'" << *I << ":'";
97413df4626SMatt Arsenault 
97513df4626SMatt Arsenault     errs() << '\n';
976ee3c74fbSChris Lattner     return true;
977ee3c74fbSChris Lattner   }
978ee3c74fbSChris Lattner 
979ee3c74fbSChris Lattner   return false;
980ee3c74fbSChris Lattner }
981ee3c74fbSChris Lattner 
98291a1b2c9SMichael Liao static void PrintCheckFailed(const SourceMgr &SM, const SMLoc &Loc,
98391a1b2c9SMichael Liao                              const Pattern &Pat, StringRef Buffer,
984e0ef65abSDaniel Dunbar                              StringMap<StringRef> &VariableTable) {
985da108b4eSChris Lattner   // Otherwise, we have an error, emit an error message.
98691a1b2c9SMichael Liao   SM.PrintMessage(Loc, SourceMgr::DK_Error,
98703b80a40SChris Lattner                   "expected string not found in input");
988da108b4eSChris Lattner 
989da108b4eSChris Lattner   // Print the "scanning from here" line.  If the current position is at the
990da108b4eSChris Lattner   // end of a line, advance to the start of the next line.
991caa5fc0cSChris Lattner   Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
992da108b4eSChris Lattner 
99303b80a40SChris Lattner   SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
99403b80a40SChris Lattner                   "scanning from here");
995e0ef65abSDaniel Dunbar 
996e0ef65abSDaniel Dunbar   // Allow the pattern to print additional information if desired.
99791a1b2c9SMichael Liao   Pat.PrintFailureInfo(SM, Buffer, VariableTable);
99891a1b2c9SMichael Liao }
99991a1b2c9SMichael Liao 
100091a1b2c9SMichael Liao static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
100191a1b2c9SMichael Liao                              StringRef Buffer,
100291a1b2c9SMichael Liao                              StringMap<StringRef> &VariableTable) {
100391a1b2c9SMichael Liao   PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
1004da108b4eSChris Lattner }
1005da108b4eSChris Lattner 
100637183584SChris Lattner /// CountNumNewlinesBetween - Count the number of newlines in the specified
100737183584SChris Lattner /// range.
1008592fe880SRichard Smith static unsigned CountNumNewlinesBetween(StringRef Range,
1009592fe880SRichard Smith                                         const char *&FirstNewLine) {
1010da108b4eSChris Lattner   unsigned NumNewLines = 0;
101137183584SChris Lattner   while (1) {
1012da108b4eSChris Lattner     // Scan for newline.
101337183584SChris Lattner     Range = Range.substr(Range.find_first_of("\n\r"));
101437183584SChris Lattner     if (Range.empty()) return NumNewLines;
1015da108b4eSChris Lattner 
1016da108b4eSChris Lattner     ++NumNewLines;
1017da108b4eSChris Lattner 
1018da108b4eSChris Lattner     // Handle \n\r and \r\n as a single newline.
101937183584SChris Lattner     if (Range.size() > 1 &&
102037183584SChris Lattner         (Range[1] == '\n' || Range[1] == '\r') &&
102137183584SChris Lattner         (Range[0] != Range[1]))
102237183584SChris Lattner       Range = Range.substr(1);
102337183584SChris Lattner     Range = Range.substr(1);
1024592fe880SRichard Smith 
1025592fe880SRichard Smith     if (NumNewLines == 1)
1026592fe880SRichard Smith       FirstNewLine = Range.begin();
1027da108b4eSChris Lattner   }
1028da108b4eSChris Lattner }
1029da108b4eSChris Lattner 
1030dcc7d48dSMichael Liao size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
1031e93a3a08SStephen Lin                           bool IsLabelScanMode, size_t &MatchLen,
1032dcc7d48dSMichael Liao                           StringMap<StringRef> &VariableTable) const {
103391a1b2c9SMichael Liao   size_t LastPos = 0;
103491a1b2c9SMichael Liao   std::vector<const Pattern *> NotStrings;
103591a1b2c9SMichael Liao 
1036e93a3a08SStephen Lin   // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
1037e93a3a08SStephen Lin   // bounds; we have not processed variable definitions within the bounded block
1038e93a3a08SStephen Lin   // yet so cannot handle any final CHECK-DAG yet; this is handled when going
1039e93a3a08SStephen Lin   // over the block again (including the last CHECK-LABEL) in normal mode.
1040e93a3a08SStephen Lin   if (!IsLabelScanMode) {
104191a1b2c9SMichael Liao     // Match "dag strings" (with mixed "not strings" if any).
104291a1b2c9SMichael Liao     LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable);
104391a1b2c9SMichael Liao     if (LastPos == StringRef::npos)
104491a1b2c9SMichael Liao       return StringRef::npos;
1045e93a3a08SStephen Lin   }
104691a1b2c9SMichael Liao 
104791a1b2c9SMichael Liao   // Match itself from the last position after matching CHECK-DAG.
104891a1b2c9SMichael Liao   StringRef MatchBuffer = Buffer.substr(LastPos);
104991a1b2c9SMichael Liao   size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
1050dcc7d48dSMichael Liao   if (MatchPos == StringRef::npos) {
105191a1b2c9SMichael Liao     PrintCheckFailed(SM, *this, MatchBuffer, VariableTable);
1052dcc7d48dSMichael Liao     return StringRef::npos;
1053dcc7d48dSMichael Liao   }
1054dcc7d48dSMichael Liao 
1055e93a3a08SStephen Lin   // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
1056e93a3a08SStephen Lin   // or CHECK-NOT
1057e93a3a08SStephen Lin   if (!IsLabelScanMode) {
105891a1b2c9SMichael Liao     StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1059dcc7d48dSMichael Liao 
1060dcc7d48dSMichael Liao     // If this check is a "CHECK-NEXT", verify that the previous match was on
1061dcc7d48dSMichael Liao     // the previous line (i.e. that there is one newline between them).
1062dcc7d48dSMichael Liao     if (CheckNext(SM, SkippedRegion))
1063dcc7d48dSMichael Liao       return StringRef::npos;
1064dcc7d48dSMichael Liao 
106501ac1707SDuncan P. N. Exon Smith     // If this check is a "CHECK-SAME", verify that the previous match was on
106601ac1707SDuncan P. N. Exon Smith     // the same line (i.e. that there is no newline between them).
106701ac1707SDuncan P. N. Exon Smith     if (CheckSame(SM, SkippedRegion))
106801ac1707SDuncan P. N. Exon Smith       return StringRef::npos;
106901ac1707SDuncan P. N. Exon Smith 
1070dcc7d48dSMichael Liao     // If this match had "not strings", verify that they don't exist in the
1071dcc7d48dSMichael Liao     // skipped region.
107291a1b2c9SMichael Liao     if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
1073dcc7d48dSMichael Liao       return StringRef::npos;
1074f8bd2e5bSStephen Lin   }
1075dcc7d48dSMichael Liao 
10767dfb92b9SMehdi Amini   return LastPos + MatchPos;
1077dcc7d48dSMichael Liao }
1078dcc7d48dSMichael Liao 
1079dcc7d48dSMichael Liao bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
108038820972SMatt Arsenault   if (CheckTy != Check::CheckNext)
1081dcc7d48dSMichael Liao     return false;
1082dcc7d48dSMichael Liao 
1083dcc7d48dSMichael Liao   // Count the number of newlines between the previous match and this one.
1084dcc7d48dSMichael Liao   assert(Buffer.data() !=
1085dcc7d48dSMichael Liao          SM.getMemoryBuffer(
1086dcc7d48dSMichael Liao            SM.FindBufferContainingLoc(
1087dcc7d48dSMichael Liao              SMLoc::getFromPointer(Buffer.data())))->getBufferStart() &&
1088dcc7d48dSMichael Liao          "CHECK-NEXT can't be the first check in a file");
1089dcc7d48dSMichael Liao 
109066f09ad0SCraig Topper   const char *FirstNewLine = nullptr;
1091592fe880SRichard Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
1092dcc7d48dSMichael Liao 
1093dcc7d48dSMichael Liao   if (NumNewLines == 0) {
109413df4626SMatt Arsenault     SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
1095dcc7d48dSMichael Liao                     "-NEXT: is on the same line as previous match");
1096dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1097dcc7d48dSMichael Liao                     SourceMgr::DK_Note, "'next' match was here");
1098dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1099dcc7d48dSMichael Liao                     "previous match ended here");
1100dcc7d48dSMichael Liao     return true;
1101dcc7d48dSMichael Liao   }
1102dcc7d48dSMichael Liao 
1103dcc7d48dSMichael Liao   if (NumNewLines != 1) {
110413df4626SMatt Arsenault     SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
1105dcc7d48dSMichael Liao                     "-NEXT: is not on the line after the previous match");
1106dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1107dcc7d48dSMichael Liao                     SourceMgr::DK_Note, "'next' match was here");
1108dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1109dcc7d48dSMichael Liao                     "previous match ended here");
1110592fe880SRichard Smith     SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
1111592fe880SRichard Smith                     "non-matching line after previous match is here");
1112dcc7d48dSMichael Liao     return true;
1113dcc7d48dSMichael Liao   }
1114dcc7d48dSMichael Liao 
1115dcc7d48dSMichael Liao   return false;
1116dcc7d48dSMichael Liao }
1117dcc7d48dSMichael Liao 
111801ac1707SDuncan P. N. Exon Smith bool CheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
111901ac1707SDuncan P. N. Exon Smith   if (CheckTy != Check::CheckSame)
112001ac1707SDuncan P. N. Exon Smith     return false;
112101ac1707SDuncan P. N. Exon Smith 
112201ac1707SDuncan P. N. Exon Smith   // Count the number of newlines between the previous match and this one.
112301ac1707SDuncan P. N. Exon Smith   assert(Buffer.data() !=
112401ac1707SDuncan P. N. Exon Smith              SM.getMemoryBuffer(SM.FindBufferContainingLoc(
112501ac1707SDuncan P. N. Exon Smith                                     SMLoc::getFromPointer(Buffer.data())))
112601ac1707SDuncan P. N. Exon Smith                  ->getBufferStart() &&
112701ac1707SDuncan P. N. Exon Smith          "CHECK-SAME can't be the first check in a file");
112801ac1707SDuncan P. N. Exon Smith 
112901ac1707SDuncan P. N. Exon Smith   const char *FirstNewLine = nullptr;
113001ac1707SDuncan P. N. Exon Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
113101ac1707SDuncan P. N. Exon Smith 
113201ac1707SDuncan P. N. Exon Smith   if (NumNewLines != 0) {
113301ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(Loc, SourceMgr::DK_Error,
113401ac1707SDuncan P. N. Exon Smith                     Prefix +
113501ac1707SDuncan P. N. Exon Smith                         "-SAME: is not on the same line as the previous match");
113601ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
113701ac1707SDuncan P. N. Exon Smith                     "'next' match was here");
113801ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
113901ac1707SDuncan P. N. Exon Smith                     "previous match ended here");
114001ac1707SDuncan P. N. Exon Smith     return true;
114101ac1707SDuncan P. N. Exon Smith   }
114201ac1707SDuncan P. N. Exon Smith 
114301ac1707SDuncan P. N. Exon Smith   return false;
114401ac1707SDuncan P. N. Exon Smith }
114501ac1707SDuncan P. N. Exon Smith 
1146dcc7d48dSMichael Liao bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
114791a1b2c9SMichael Liao                            const std::vector<const Pattern *> &NotStrings,
1148dcc7d48dSMichael Liao                            StringMap<StringRef> &VariableTable) const {
1149dcc7d48dSMichael Liao   for (unsigned ChunkNo = 0, e = NotStrings.size();
1150dcc7d48dSMichael Liao        ChunkNo != e; ++ChunkNo) {
115191a1b2c9SMichael Liao     const Pattern *Pat = NotStrings[ChunkNo];
115238820972SMatt Arsenault     assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
115391a1b2c9SMichael Liao 
1154dcc7d48dSMichael Liao     size_t MatchLen = 0;
115591a1b2c9SMichael Liao     size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
1156dcc7d48dSMichael Liao 
1157dcc7d48dSMichael Liao     if (Pos == StringRef::npos) continue;
1158dcc7d48dSMichael Liao 
1159dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos),
1160dcc7d48dSMichael Liao                     SourceMgr::DK_Error,
116113df4626SMatt Arsenault                     Prefix + "-NOT: string occurred!");
116291a1b2c9SMichael Liao     SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note,
116313df4626SMatt Arsenault                     Prefix + "-NOT: pattern specified here");
1164dcc7d48dSMichael Liao     return true;
1165dcc7d48dSMichael Liao   }
1166dcc7d48dSMichael Liao 
1167dcc7d48dSMichael Liao   return false;
1168dcc7d48dSMichael Liao }
1169dcc7d48dSMichael Liao 
117091a1b2c9SMichael Liao size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
117191a1b2c9SMichael Liao                              std::vector<const Pattern *> &NotStrings,
117291a1b2c9SMichael Liao                              StringMap<StringRef> &VariableTable) const {
117391a1b2c9SMichael Liao   if (DagNotStrings.empty())
117491a1b2c9SMichael Liao     return 0;
117591a1b2c9SMichael Liao 
117691a1b2c9SMichael Liao   size_t LastPos = 0;
117791a1b2c9SMichael Liao   size_t StartPos = LastPos;
117891a1b2c9SMichael Liao 
117991a1b2c9SMichael Liao   for (unsigned ChunkNo = 0, e = DagNotStrings.size();
118091a1b2c9SMichael Liao        ChunkNo != e; ++ChunkNo) {
118191a1b2c9SMichael Liao     const Pattern &Pat = DagNotStrings[ChunkNo];
118291a1b2c9SMichael Liao 
118338820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG ||
118438820972SMatt Arsenault             Pat.getCheckTy() == Check::CheckNot) &&
118591a1b2c9SMichael Liao            "Invalid CHECK-DAG or CHECK-NOT!");
118691a1b2c9SMichael Liao 
118738820972SMatt Arsenault     if (Pat.getCheckTy() == Check::CheckNot) {
118891a1b2c9SMichael Liao       NotStrings.push_back(&Pat);
118991a1b2c9SMichael Liao       continue;
119091a1b2c9SMichael Liao     }
119191a1b2c9SMichael Liao 
119238820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
119391a1b2c9SMichael Liao 
119491a1b2c9SMichael Liao     size_t MatchLen = 0, MatchPos;
119591a1b2c9SMichael Liao 
119691a1b2c9SMichael Liao     // CHECK-DAG always matches from the start.
119791a1b2c9SMichael Liao     StringRef MatchBuffer = Buffer.substr(StartPos);
119891a1b2c9SMichael Liao     MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
119991a1b2c9SMichael Liao     // With a group of CHECK-DAGs, a single mismatching means the match on
120091a1b2c9SMichael Liao     // that group of CHECK-DAGs fails immediately.
120191a1b2c9SMichael Liao     if (MatchPos == StringRef::npos) {
120291a1b2c9SMichael Liao       PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
120391a1b2c9SMichael Liao       return StringRef::npos;
120491a1b2c9SMichael Liao     }
120591a1b2c9SMichael Liao     // Re-calc it as the offset relative to the start of the original string.
120691a1b2c9SMichael Liao     MatchPos += StartPos;
120791a1b2c9SMichael Liao 
120891a1b2c9SMichael Liao     if (!NotStrings.empty()) {
120991a1b2c9SMichael Liao       if (MatchPos < LastPos) {
121091a1b2c9SMichael Liao         // Reordered?
121191a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
121291a1b2c9SMichael Liao                         SourceMgr::DK_Error,
121313df4626SMatt Arsenault                         Prefix + "-DAG: found a match of CHECK-DAG"
121491a1b2c9SMichael Liao                         " reordering across a CHECK-NOT");
121591a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
121691a1b2c9SMichael Liao                         SourceMgr::DK_Note,
121713df4626SMatt Arsenault                         Prefix + "-DAG: the farthest match of CHECK-DAG"
121891a1b2c9SMichael Liao                         " is found here");
121991a1b2c9SMichael Liao         SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
122013df4626SMatt Arsenault                         Prefix + "-NOT: the crossed pattern specified"
122191a1b2c9SMichael Liao                         " here");
122291a1b2c9SMichael Liao         SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
122313df4626SMatt Arsenault                         Prefix + "-DAG: the reordered pattern specified"
122491a1b2c9SMichael Liao                         " here");
122591a1b2c9SMichael Liao         return StringRef::npos;
122691a1b2c9SMichael Liao       }
122791a1b2c9SMichael Liao       // All subsequent CHECK-DAGs should be matched from the farthest
122891a1b2c9SMichael Liao       // position of all precedent CHECK-DAGs (including this one.)
122991a1b2c9SMichael Liao       StartPos = LastPos;
123091a1b2c9SMichael Liao       // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
123191a1b2c9SMichael Liao       // CHECK-DAG, verify that there's no 'not' strings occurred in that
123291a1b2c9SMichael Liao       // region.
123391a1b2c9SMichael Liao       StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1234cf708c32STim Northover       if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
123591a1b2c9SMichael Liao         return StringRef::npos;
123691a1b2c9SMichael Liao       // Clear "not strings".
123791a1b2c9SMichael Liao       NotStrings.clear();
123891a1b2c9SMichael Liao     }
123991a1b2c9SMichael Liao 
124091a1b2c9SMichael Liao     // Update the last position with CHECK-DAG matches.
124191a1b2c9SMichael Liao     LastPos = std::max(MatchPos + MatchLen, LastPos);
124291a1b2c9SMichael Liao   }
124391a1b2c9SMichael Liao 
124491a1b2c9SMichael Liao   return LastPos;
124591a1b2c9SMichael Liao }
124691a1b2c9SMichael Liao 
124713df4626SMatt Arsenault // A check prefix must contain only alphanumeric, hyphens and underscores.
124813df4626SMatt Arsenault static bool ValidateCheckPrefix(StringRef CheckPrefix) {
124913df4626SMatt Arsenault   Regex Validator("^[a-zA-Z0-9_-]*$");
125013df4626SMatt Arsenault   return Validator.match(CheckPrefix);
125113df4626SMatt Arsenault }
125213df4626SMatt Arsenault 
125313df4626SMatt Arsenault static bool ValidateCheckPrefixes() {
125413df4626SMatt Arsenault   StringSet<> PrefixSet;
125513df4626SMatt Arsenault 
125613df4626SMatt Arsenault   for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
125713df4626SMatt Arsenault        I != E; ++I) {
125813df4626SMatt Arsenault     StringRef Prefix(*I);
125913df4626SMatt Arsenault 
126024412b14SEli Bendersky     // Reject empty prefixes.
126124412b14SEli Bendersky     if (Prefix == "")
126224412b14SEli Bendersky       return false;
126324412b14SEli Bendersky 
12640356975cSDavid Blaikie     if (!PrefixSet.insert(Prefix).second)
126513df4626SMatt Arsenault       return false;
126613df4626SMatt Arsenault 
126713df4626SMatt Arsenault     if (!ValidateCheckPrefix(Prefix))
126813df4626SMatt Arsenault       return false;
126913df4626SMatt Arsenault   }
127013df4626SMatt Arsenault 
127113df4626SMatt Arsenault   return true;
127213df4626SMatt Arsenault }
127313df4626SMatt Arsenault 
127413df4626SMatt Arsenault // I don't think there's a way to specify an initial value for cl::list,
127513df4626SMatt Arsenault // so if nothing was specified, add the default
127613df4626SMatt Arsenault static void AddCheckPrefixIfNeeded() {
127713df4626SMatt Arsenault   if (CheckPrefixes.empty())
127813df4626SMatt Arsenault     CheckPrefixes.push_back("CHECK");
1279c2735158SRui Ueyama }
1280c2735158SRui Ueyama 
1281ee3c74fbSChris Lattner int main(int argc, char **argv) {
1282ee3c74fbSChris Lattner   sys::PrintStackTraceOnErrorSignal();
1283ee3c74fbSChris Lattner   PrettyStackTraceProgram X(argc, argv);
1284ee3c74fbSChris Lattner   cl::ParseCommandLineOptions(argc, argv);
1285ee3c74fbSChris Lattner 
128613df4626SMatt Arsenault   if (!ValidateCheckPrefixes()) {
128713df4626SMatt Arsenault     errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
128813df4626SMatt Arsenault               "start with a letter and contain only alphanumeric characters, "
128913df4626SMatt Arsenault               "hyphens and underscores\n";
1290c2735158SRui Ueyama     return 2;
1291c2735158SRui Ueyama   }
1292c2735158SRui Ueyama 
129313df4626SMatt Arsenault   AddCheckPrefixIfNeeded();
129413df4626SMatt Arsenault 
1295ee3c74fbSChris Lattner   SourceMgr SM;
1296ee3c74fbSChris Lattner 
1297ee3c74fbSChris Lattner   // Read the expected strings from the check file.
129826cccfe1SChris Lattner   std::vector<CheckString> CheckStrings;
1299ee3c74fbSChris Lattner   if (ReadCheckFile(SM, CheckStrings))
1300ee3c74fbSChris Lattner     return 2;
1301ee3c74fbSChris Lattner 
1302ee3c74fbSChris Lattner   // Open the file to check and add it to SourceMgr.
1303adf21f2aSRafael Espindola   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
1304adf21f2aSRafael Espindola       MemoryBuffer::getFileOrSTDIN(InputFilename);
1305adf21f2aSRafael Espindola   if (std::error_code EC = FileOrErr.getError()) {
1306adf21f2aSRafael Espindola     errs() << "Could not open input file '" << InputFilename
1307adf21f2aSRafael Espindola            << "': " << EC.message() << '\n';
13088e1c6477SEli Bendersky     return 2;
1309ee3c74fbSChris Lattner   }
13103f6481d0SRafael Espindola   std::unique_ptr<MemoryBuffer> &File = FileOrErr.get();
13112c3e5cdfSChris Lattner 
13121b9f936fSJustin Bogner   if (File->getBufferSize() == 0 && !AllowEmptyInput) {
1313b692bed7SChris Lattner     errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
13148e1c6477SEli Bendersky     return 2;
1315b692bed7SChris Lattner   }
1316b692bed7SChris Lattner 
13172c3e5cdfSChris Lattner   // Remove duplicate spaces in the input file if requested.
13185ea04c38SGuy Benyei   // Remove DOS style line endings.
13191961f14cSDavid Blaikie   std::unique_ptr<MemoryBuffer> F =
1320ce5dd1acSRafael Espindola       CanonicalizeInputFile(std::move(File), NoCanonicalizeWhiteSpace);
13212c3e5cdfSChris Lattner 
1322ee3c74fbSChris Lattner   // Check that we have all of the expected strings, in order, in the input
1323ee3c74fbSChris Lattner   // file.
1324caa5fc0cSChris Lattner   StringRef Buffer = F->getBuffer();
1325ee3c74fbSChris Lattner 
13261961f14cSDavid Blaikie   SM.AddNewSourceBuffer(std::move(F), SMLoc());
13271961f14cSDavid Blaikie 
13281961f14cSDavid Blaikie   /// VariableTable - This holds all the current filecheck variables.
13291961f14cSDavid Blaikie   StringMap<StringRef> VariableTable;
13301961f14cSDavid Blaikie 
1331f8bd2e5bSStephen Lin   bool hasError = false;
1332ee3c74fbSChris Lattner 
1333f8bd2e5bSStephen Lin   unsigned i = 0, j = 0, e = CheckStrings.size();
1334ee3c74fbSChris Lattner 
1335f8bd2e5bSStephen Lin   while (true) {
1336f8bd2e5bSStephen Lin     StringRef CheckRegion;
1337f8bd2e5bSStephen Lin     if (j == e) {
1338f8bd2e5bSStephen Lin       CheckRegion = Buffer;
1339f8bd2e5bSStephen Lin     } else {
1340f8bd2e5bSStephen Lin       const CheckString &CheckLabelStr = CheckStrings[j];
134138820972SMatt Arsenault       if (CheckLabelStr.CheckTy != Check::CheckLabel) {
1342f8bd2e5bSStephen Lin         ++j;
1343f8bd2e5bSStephen Lin         continue;
1344da108b4eSChris Lattner       }
1345da108b4eSChris Lattner 
1346f8bd2e5bSStephen Lin       // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
1347f8bd2e5bSStephen Lin       size_t MatchLabelLen = 0;
1348e93a3a08SStephen Lin       size_t MatchLabelPos = CheckLabelStr.Check(SM, Buffer, true,
1349f8bd2e5bSStephen Lin                                                  MatchLabelLen, VariableTable);
1350f8bd2e5bSStephen Lin       if (MatchLabelPos == StringRef::npos) {
1351f8bd2e5bSStephen Lin         hasError = true;
1352f8bd2e5bSStephen Lin         break;
1353f8bd2e5bSStephen Lin       }
1354f8bd2e5bSStephen Lin 
1355f8bd2e5bSStephen Lin       CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
1356f8bd2e5bSStephen Lin       Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
1357f8bd2e5bSStephen Lin       ++j;
1358f8bd2e5bSStephen Lin     }
1359f8bd2e5bSStephen Lin 
1360f8bd2e5bSStephen Lin     for ( ; i != j; ++i) {
1361f8bd2e5bSStephen Lin       const CheckString &CheckStr = CheckStrings[i];
1362f8bd2e5bSStephen Lin 
1363f8bd2e5bSStephen Lin       // Check each string within the scanned region, including a second check
1364f8bd2e5bSStephen Lin       // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
1365f8bd2e5bSStephen Lin       size_t MatchLen = 0;
1366e93a3a08SStephen Lin       size_t MatchPos = CheckStr.Check(SM, CheckRegion, false, MatchLen,
1367f8bd2e5bSStephen Lin                                        VariableTable);
1368f8bd2e5bSStephen Lin 
1369f8bd2e5bSStephen Lin       if (MatchPos == StringRef::npos) {
1370f8bd2e5bSStephen Lin         hasError = true;
1371f8bd2e5bSStephen Lin         i = j;
1372f8bd2e5bSStephen Lin         break;
1373f8bd2e5bSStephen Lin       }
1374f8bd2e5bSStephen Lin 
1375f8bd2e5bSStephen Lin       CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
1376f8bd2e5bSStephen Lin     }
1377f8bd2e5bSStephen Lin 
1378f8bd2e5bSStephen Lin     if (j == e)
1379f8bd2e5bSStephen Lin       break;
1380f8bd2e5bSStephen Lin   }
1381f8bd2e5bSStephen Lin 
1382f8bd2e5bSStephen Lin   return hasError ? 1 : 0;
1383ee3c74fbSChris Lattner }
1384