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 
45e8f2fb20SChandler Carruth static cl::list<std::string> CheckPrefixes(
46e8f2fb20SChandler Carruth     "check-prefix",
47ee3c74fbSChris Lattner     cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
48fd557cb0SDaniel Sanders static cl::alias CheckPrefixesAlias(
49fd557cb0SDaniel Sanders     "check-prefixes", cl::aliasopt(CheckPrefixes), cl::CommaSeparated,
50fd557cb0SDaniel Sanders     cl::NotHidden,
51fd557cb0SDaniel Sanders     cl::desc(
52fd557cb0SDaniel Sanders         "Alias for -check-prefix permitting multiple comma separated values"));
53ee3c74fbSChris Lattner 
54e8f2fb20SChandler Carruth static cl::opt<bool> NoCanonicalizeWhiteSpace(
55e8f2fb20SChandler Carruth     "strict-whitespace",
562c3e5cdfSChris Lattner     cl::desc("Do not treat all horizontal whitespace as equivalent"));
572c3e5cdfSChris Lattner 
5856ccdbbdSAlexander Kornienko static cl::list<std::string> ImplicitCheckNot(
5956ccdbbdSAlexander Kornienko     "implicit-check-not",
6056ccdbbdSAlexander Kornienko     cl::desc("Add an implicit negative check with this pattern to every\n"
6156ccdbbdSAlexander Kornienko              "positive check. This can be used to ensure that no instances of\n"
6256ccdbbdSAlexander Kornienko              "this pattern occur which are not matched by a positive pattern"),
6356ccdbbdSAlexander Kornienko     cl::value_desc("pattern"));
6456ccdbbdSAlexander Kornienko 
651b9f936fSJustin Bogner static cl::opt<bool> AllowEmptyInput(
661b9f936fSJustin Bogner     "allow-empty", cl::init(false),
671b9f936fSJustin Bogner     cl::desc("Allow the input file to be empty. This is useful when making\n"
681b9f936fSJustin Bogner              "checks that some error message does not occur, for example."));
691b9f936fSJustin Bogner 
7085913ccaSJames Y Knight static cl::opt<bool> MatchFullLines(
7185913ccaSJames Y Knight     "match-full-lines", cl::init(false),
7285913ccaSJames Y Knight     cl::desc("Require all positive matches to cover an entire input line.\n"
7385913ccaSJames Y Knight              "Allows leading and trailing whitespace if --strict-whitespace\n"
7485913ccaSJames Y Knight              "is not also passed."));
7585913ccaSJames Y Knight 
7613df4626SMatt Arsenault typedef cl::list<std::string>::const_iterator prefix_iterator;
7713df4626SMatt Arsenault 
7874d50731SChris Lattner //===----------------------------------------------------------------------===//
7974d50731SChris Lattner // Pattern Handling Code.
8074d50731SChris Lattner //===----------------------------------------------------------------------===//
8174d50731SChris Lattner 
8238820972SMatt Arsenault namespace Check {
8338820972SMatt Arsenault enum CheckType {
8438820972SMatt Arsenault   CheckNone = 0,
8538820972SMatt Arsenault   CheckPlain,
8638820972SMatt Arsenault   CheckNext,
8701ac1707SDuncan P. N. Exon Smith   CheckSame,
8838820972SMatt Arsenault   CheckNot,
8938820972SMatt Arsenault   CheckDAG,
9038820972SMatt Arsenault   CheckLabel,
910a4c44bdSChris Lattner 
924dabac20SChandler Carruth   /// Indicates the pattern only matches the end of file. This is used for
934dabac20SChandler Carruth   /// trailing CHECK-NOTs.
94a908e7bdSPaul Robinson   CheckEOF,
954dabac20SChandler Carruth 
964dabac20SChandler Carruth   /// Marks when parsing found a -NOT check combined with another CHECK suffix.
97a908e7bdSPaul Robinson   CheckBadNot
9838820972SMatt Arsenault };
9938820972SMatt Arsenault }
100eba55822SJakob Stoklund Olesen 
10138820972SMatt Arsenault class Pattern {
10238820972SMatt Arsenault   SMLoc PatternLoc;
10391a1b2c9SMichael Liao 
1044dabac20SChandler Carruth   /// A fixed string to match as the pattern or empty if this pattern requires
1054dabac20SChandler Carruth   /// a regex match.
106221460e0SChris Lattner   StringRef FixedStr;
107b16ab0c4SChris Lattner 
1084dabac20SChandler Carruth   /// A regex string to match as the pattern or empty if this pattern requires
1094dabac20SChandler Carruth   /// a fixed string to match.
110b16ab0c4SChris Lattner   std::string RegExStr;
1118879e06dSChris Lattner 
1124dabac20SChandler Carruth   /// Entries in this vector map to uses of a variable in the pattern, e.g.
1134dabac20SChandler Carruth   /// "foo[[bar]]baz".  In this case, the RegExStr will contain "foobaz" and
1144dabac20SChandler Carruth   /// we'll get an entry in this vector that tells us to insert the value of
1154dabac20SChandler Carruth   /// bar at offset 3.
1168879e06dSChris Lattner   std::vector<std::pair<StringRef, unsigned>> VariableUses;
1178879e06dSChris Lattner 
1184dabac20SChandler Carruth   /// Maps definitions of variables to their parenthesized capture numbers.
1194dabac20SChandler Carruth   ///
1204dabac20SChandler Carruth   /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to
1214dabac20SChandler Carruth   /// 1.
122e8b8f1bcSEli Bendersky   std::map<StringRef, unsigned> VariableDefs;
1238879e06dSChris Lattner 
124d1e020f7SSaleem Abdulrasool   Check::CheckType CheckTy;
1253b40b445SChris Lattner 
1264dabac20SChandler Carruth   /// Contains the number of line this pattern is in.
127d1e020f7SSaleem Abdulrasool   unsigned LineNumber;
128d1e020f7SSaleem Abdulrasool 
129d1e020f7SSaleem Abdulrasool public:
130d1e020f7SSaleem Abdulrasool   explicit Pattern(Check::CheckType Ty) : CheckTy(Ty) {}
13174d50731SChris Lattner 
1324dabac20SChandler Carruth   /// Returns the location in source code.
1330b707eb8SMichael Liao   SMLoc getLoc() const { return PatternLoc; }
1340b707eb8SMichael Liao 
135e8f2fb20SChandler Carruth   bool ParsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
13613df4626SMatt Arsenault                     unsigned LineNumber);
1378879e06dSChris Lattner   size_t Match(StringRef Buffer, size_t &MatchLen,
1388879e06dSChris Lattner                StringMap<StringRef> &VariableTable) const;
139e0ef65abSDaniel Dunbar   void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
140e0ef65abSDaniel Dunbar                         const StringMap<StringRef> &VariableTable) const;
141e0ef65abSDaniel Dunbar 
142e8f2fb20SChandler Carruth   bool hasVariable() const {
143e8f2fb20SChandler Carruth     return !(VariableUses.empty() && VariableDefs.empty());
144e8f2fb20SChandler Carruth   }
145f8bd2e5bSStephen Lin 
14638820972SMatt Arsenault   Check::CheckType getCheckTy() const { return CheckTy; }
14791a1b2c9SMichael Liao 
148b16ab0c4SChris Lattner private:
149e8b8f1bcSEli Bendersky   bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
150e8b8f1bcSEli Bendersky   void AddBackrefToRegEx(unsigned BackrefNum);
151e8f2fb20SChandler Carruth   unsigned
152e8f2fb20SChandler Carruth   ComputeMatchDistance(StringRef Buffer,
153fd29d886SDaniel Dunbar                        const StringMap<StringRef> &VariableTable) const;
15492987fb3SAlexander Kornienko   bool EvaluateExpression(StringRef Expr, std::string &Value) const;
15581e5cd9eSAdrian Prantl   size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
1563b40b445SChris Lattner };
1573b40b445SChris Lattner 
1584dabac20SChandler Carruth /// Parses the given string into the Pattern.
1594dabac20SChandler Carruth ///
1604dabac20SChandler Carruth /// \p Prefix provides which prefix is being matched, \p SM provides the
1614dabac20SChandler Carruth /// SourceMgr used for error reports, and \p LineNumber is the line number in
1624dabac20SChandler Carruth /// the input file from which the pattern string was read. Returns true in
1634dabac20SChandler Carruth /// case of an error, false otherwise.
164e8f2fb20SChandler Carruth bool Pattern::ParsePattern(StringRef PatternStr, StringRef Prefix,
165e8f2fb20SChandler Carruth                            SourceMgr &SM, unsigned LineNumber) {
16685913ccaSJames Y Knight   bool MatchFullLinesHere = MatchFullLines && CheckTy != Check::CheckNot;
16785913ccaSJames Y Knight 
16892987fb3SAlexander Kornienko   this->LineNumber = LineNumber;
1690a4c44bdSChris Lattner   PatternLoc = SMLoc::getFromPointer(PatternStr.data());
1700a4c44bdSChris Lattner 
171*1714676aSTom de Vries   if (!(NoCanonicalizeWhiteSpace && MatchFullLines))
17274d50731SChris Lattner     // Ignore trailing whitespace.
17374d50731SChris Lattner     while (!PatternStr.empty() &&
17474d50731SChris Lattner            (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
17574d50731SChris Lattner       PatternStr = PatternStr.substr(0, PatternStr.size() - 1);
17674d50731SChris Lattner 
17774d50731SChris Lattner   // Check that there is something on the line.
17874d50731SChris Lattner   if (PatternStr.empty()) {
17903b80a40SChris Lattner     SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
180e8f2fb20SChandler Carruth                     "found empty check string with prefix '" + Prefix + ":'");
18174d50731SChris Lattner     return true;
18274d50731SChris Lattner   }
18374d50731SChris Lattner 
184221460e0SChris Lattner   // Check to see if this is a fixed string, or if it has regex pieces.
18585913ccaSJames Y Knight   if (!MatchFullLinesHere &&
18685913ccaSJames Y Knight       (PatternStr.size() < 2 || (PatternStr.find("{{") == StringRef::npos &&
18785913ccaSJames Y Knight                                  PatternStr.find("[[") == StringRef::npos))) {
188221460e0SChris Lattner     FixedStr = PatternStr;
189221460e0SChris Lattner     return false;
190221460e0SChris Lattner   }
191221460e0SChris Lattner 
19285913ccaSJames Y Knight   if (MatchFullLinesHere) {
19385913ccaSJames Y Knight     RegExStr += '^';
19485913ccaSJames Y Knight     if (!NoCanonicalizeWhiteSpace)
19585913ccaSJames Y Knight       RegExStr += " *";
19685913ccaSJames Y Knight   }
19785913ccaSJames Y Knight 
1988879e06dSChris Lattner   // Paren value #0 is for the fully matched string.  Any new parenthesized
19953e0679dSChris Lattner   // values add from there.
2008879e06dSChris Lattner   unsigned CurParen = 1;
2018879e06dSChris Lattner 
202b16ab0c4SChris Lattner   // Otherwise, there is at least one regex piece.  Build up the regex pattern
203b16ab0c4SChris Lattner   // by escaping scary characters in fixed strings, building up one big regex.
204f08d2db9SChris Lattner   while (!PatternStr.empty()) {
2058879e06dSChris Lattner     // RegEx matches.
20653e0679dSChris Lattner     if (PatternStr.startswith("{{")) {
20743d50d4aSEli Bendersky       // This is the start of a regex match.  Scan for the }}.
208f08d2db9SChris Lattner       size_t End = PatternStr.find("}}");
209f08d2db9SChris Lattner       if (End == StringRef::npos) {
210f08d2db9SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
21103b80a40SChris Lattner                         SourceMgr::DK_Error,
21203b80a40SChris Lattner                         "found start of regex string with no end '}}'");
213f08d2db9SChris Lattner         return true;
214f08d2db9SChris Lattner       }
215f08d2db9SChris Lattner 
216e53c95f1SChris Lattner       // Enclose {{}} patterns in parens just like [[]] even though we're not
217e53c95f1SChris Lattner       // capturing the result for any purpose.  This is required in case the
218e53c95f1SChris Lattner       // expression contains an alternation like: CHECK:  abc{{x|z}}def.  We
219e53c95f1SChris Lattner       // want this to turn into: "abc(x|z)def" not "abcx|zdef".
220e53c95f1SChris Lattner       RegExStr += '(';
221e53c95f1SChris Lattner       ++CurParen;
222e53c95f1SChris Lattner 
2238879e06dSChris Lattner       if (AddRegExToRegEx(PatternStr.substr(2, End - 2), CurParen, SM))
2248879e06dSChris Lattner         return true;
225e53c95f1SChris Lattner       RegExStr += ')';
22653e0679dSChris Lattner 
2278879e06dSChris Lattner       PatternStr = PatternStr.substr(End + 2);
2288879e06dSChris Lattner       continue;
2298879e06dSChris Lattner     }
2308879e06dSChris Lattner 
2318879e06dSChris Lattner     // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
2328879e06dSChris Lattner     // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
2338879e06dSChris Lattner     // second form is [[foo]] which is a reference to foo.  The variable name
23457cb733bSDaniel Dunbar     // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
2358879e06dSChris Lattner     // it.  This is to catch some common errors.
23653e0679dSChris Lattner     if (PatternStr.startswith("[[")) {
237061d2baaSEli Bendersky       // Find the closing bracket pair ending the match.  End is going to be an
238061d2baaSEli Bendersky       // offset relative to the beginning of the match string.
23981e5cd9eSAdrian Prantl       size_t End = FindRegexVarEnd(PatternStr.substr(2), SM);
240061d2baaSEli Bendersky 
2418879e06dSChris Lattner       if (End == StringRef::npos) {
2428879e06dSChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
24303b80a40SChris Lattner                         SourceMgr::DK_Error,
24403b80a40SChris Lattner                         "invalid named regex reference, no ]] found");
245f08d2db9SChris Lattner         return true;
246f08d2db9SChris Lattner       }
247f08d2db9SChris Lattner 
248061d2baaSEli Bendersky       StringRef MatchStr = PatternStr.substr(2, End);
249061d2baaSEli Bendersky       PatternStr = PatternStr.substr(End + 4);
2508879e06dSChris Lattner 
2518879e06dSChris Lattner       // Get the regex name (e.g. "foo").
2528879e06dSChris Lattner       size_t NameEnd = MatchStr.find(':');
2538879e06dSChris Lattner       StringRef Name = MatchStr.substr(0, NameEnd);
2548879e06dSChris Lattner 
2558879e06dSChris Lattner       if (Name.empty()) {
25603b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
25703b80a40SChris Lattner                         "invalid name in named regex: empty name");
2588879e06dSChris Lattner         return true;
2598879e06dSChris Lattner       }
2608879e06dSChris Lattner 
26192987fb3SAlexander Kornienko       // Verify that the name/expression is well formed. FileCheck currently
26292987fb3SAlexander Kornienko       // supports @LINE, @LINE+number, @LINE-number expressions. The check here
26392987fb3SAlexander Kornienko       // is relaxed, more strict check is performed in \c EvaluateExpression.
26492987fb3SAlexander Kornienko       bool IsExpression = false;
26592987fb3SAlexander Kornienko       for (unsigned i = 0, e = Name.size(); i != e; ++i) {
26692987fb3SAlexander Kornienko         if (i == 0 && Name[i] == '@') {
26792987fb3SAlexander Kornienko           if (NameEnd != StringRef::npos) {
26892987fb3SAlexander Kornienko             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
26992987fb3SAlexander Kornienko                             SourceMgr::DK_Error,
27092987fb3SAlexander Kornienko                             "invalid name in named regex definition");
27192987fb3SAlexander Kornienko             return true;
27292987fb3SAlexander Kornienko           }
27392987fb3SAlexander Kornienko           IsExpression = true;
27492987fb3SAlexander Kornienko           continue;
27592987fb3SAlexander Kornienko         }
27692987fb3SAlexander Kornienko         if (Name[i] != '_' && !isalnum(Name[i]) &&
27792987fb3SAlexander Kornienko             (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
2788879e06dSChris Lattner           SM.PrintMessage(SMLoc::getFromPointer(Name.data() + i),
27903b80a40SChris Lattner                           SourceMgr::DK_Error, "invalid name in named regex");
2808879e06dSChris Lattner           return true;
2818879e06dSChris Lattner         }
28292987fb3SAlexander Kornienko       }
2838879e06dSChris Lattner 
2848879e06dSChris Lattner       // Name can't start with a digit.
28583c74e9fSGuy Benyei       if (isdigit(static_cast<unsigned char>(Name[0]))) {
28603b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
28703b80a40SChris Lattner                         "invalid name in named regex");
2888879e06dSChris Lattner         return true;
2898879e06dSChris Lattner       }
2908879e06dSChris Lattner 
2918879e06dSChris Lattner       // Handle [[foo]].
2928879e06dSChris Lattner       if (NameEnd == StringRef::npos) {
293e8b8f1bcSEli Bendersky         // Handle variables that were defined earlier on the same line by
294e8b8f1bcSEli Bendersky         // emitting a backreference.
295e8b8f1bcSEli Bendersky         if (VariableDefs.find(Name) != VariableDefs.end()) {
296e8b8f1bcSEli Bendersky           unsigned VarParenNum = VariableDefs[Name];
297e8b8f1bcSEli Bendersky           if (VarParenNum < 1 || VarParenNum > 9) {
298e8b8f1bcSEli Bendersky             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
299e8b8f1bcSEli Bendersky                             SourceMgr::DK_Error,
300e8b8f1bcSEli Bendersky                             "Can't back-reference more than 9 variables");
301e8b8f1bcSEli Bendersky             return true;
302e8b8f1bcSEli Bendersky           }
303e8b8f1bcSEli Bendersky           AddBackrefToRegEx(VarParenNum);
304e8b8f1bcSEli Bendersky         } else {
3058879e06dSChris Lattner           VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
306e8b8f1bcSEli Bendersky         }
3078879e06dSChris Lattner         continue;
3088879e06dSChris Lattner       }
3098879e06dSChris Lattner 
3108879e06dSChris Lattner       // Handle [[foo:.*]].
311e8b8f1bcSEli Bendersky       VariableDefs[Name] = CurParen;
3128879e06dSChris Lattner       RegExStr += '(';
3138879e06dSChris Lattner       ++CurParen;
3148879e06dSChris Lattner 
3158879e06dSChris Lattner       if (AddRegExToRegEx(MatchStr.substr(NameEnd + 1), CurParen, SM))
3168879e06dSChris Lattner         return true;
3178879e06dSChris Lattner 
3188879e06dSChris Lattner       RegExStr += ')';
3198879e06dSChris Lattner     }
3208879e06dSChris Lattner 
3218879e06dSChris Lattner     // Handle fixed string matches.
3228879e06dSChris Lattner     // Find the end, which is the start of the next regex.
3238879e06dSChris Lattner     size_t FixedMatchEnd = PatternStr.find("{{");
3248879e06dSChris Lattner     FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
3256f4f77b7SHans Wennborg     RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
3268879e06dSChris Lattner     PatternStr = PatternStr.substr(FixedMatchEnd);
327f08d2db9SChris Lattner   }
328f08d2db9SChris Lattner 
32985913ccaSJames Y Knight   if (MatchFullLinesHere) {
33085913ccaSJames Y Knight     if (!NoCanonicalizeWhiteSpace)
33185913ccaSJames Y Knight       RegExStr += " *";
33285913ccaSJames Y Knight     RegExStr += '$';
33385913ccaSJames Y Knight   }
33485913ccaSJames Y Knight 
33574d50731SChris Lattner   return false;
33674d50731SChris Lattner }
33774d50731SChris Lattner 
338e8f2fb20SChandler Carruth bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
339e8b8f1bcSEli Bendersky   Regex R(RS);
3408879e06dSChris Lattner   std::string Error;
3418879e06dSChris Lattner   if (!R.isValid(Error)) {
342e8b8f1bcSEli Bendersky     SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
34303b80a40SChris Lattner                     "invalid regex: " + Error);
3448879e06dSChris Lattner     return true;
3458879e06dSChris Lattner   }
3468879e06dSChris Lattner 
347e8b8f1bcSEli Bendersky   RegExStr += RS.str();
3488879e06dSChris Lattner   CurParen += R.getNumMatches();
3498879e06dSChris Lattner   return false;
3508879e06dSChris Lattner }
351b16ab0c4SChris Lattner 
352e8b8f1bcSEli Bendersky void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
353e8b8f1bcSEli Bendersky   assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
354e8f2fb20SChandler Carruth   std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum);
355e8b8f1bcSEli Bendersky   RegExStr += Backref;
356e8b8f1bcSEli Bendersky }
357e8b8f1bcSEli Bendersky 
3584dabac20SChandler Carruth /// Evaluates expression and stores the result to \p Value.
3594dabac20SChandler Carruth ///
3604dabac20SChandler Carruth /// Returns true on success and false when the expression has invalid syntax.
36192987fb3SAlexander Kornienko bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
36292987fb3SAlexander Kornienko   // The only supported expression is @LINE([\+-]\d+)?
36392987fb3SAlexander Kornienko   if (!Expr.startswith("@LINE"))
36492987fb3SAlexander Kornienko     return false;
36592987fb3SAlexander Kornienko   Expr = Expr.substr(StringRef("@LINE").size());
36692987fb3SAlexander Kornienko   int Offset = 0;
36792987fb3SAlexander Kornienko   if (!Expr.empty()) {
36892987fb3SAlexander Kornienko     if (Expr[0] == '+')
36992987fb3SAlexander Kornienko       Expr = Expr.substr(1);
37092987fb3SAlexander Kornienko     else if (Expr[0] != '-')
37192987fb3SAlexander Kornienko       return false;
37292987fb3SAlexander Kornienko     if (Expr.getAsInteger(10, Offset))
37392987fb3SAlexander Kornienko       return false;
37492987fb3SAlexander Kornienko   }
37592987fb3SAlexander Kornienko   Value = llvm::itostr(LineNumber + Offset);
37692987fb3SAlexander Kornienko   return true;
37792987fb3SAlexander Kornienko }
37892987fb3SAlexander Kornienko 
3794dabac20SChandler Carruth /// Matches the pattern string against the input buffer \p Buffer
3804dabac20SChandler Carruth ///
3814dabac20SChandler Carruth /// This returns the position that is matched or npos if there is no match. If
3824dabac20SChandler Carruth /// there is a match, the size of the matched string is returned in \p
3834dabac20SChandler Carruth /// MatchLen.
3844dabac20SChandler Carruth ///
3854dabac20SChandler Carruth /// The \p VariableTable StringMap provides the current values of filecheck
3864dabac20SChandler Carruth /// variables and is updated if this match defines new values.
3878879e06dSChris Lattner size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
3888879e06dSChris Lattner                       StringMap<StringRef> &VariableTable) const {
389eba55822SJakob Stoklund Olesen   // If this is the EOF pattern, match it immediately.
39038820972SMatt Arsenault   if (CheckTy == Check::CheckEOF) {
391eba55822SJakob Stoklund Olesen     MatchLen = 0;
392eba55822SJakob Stoklund Olesen     return Buffer.size();
393eba55822SJakob Stoklund Olesen   }
394eba55822SJakob Stoklund Olesen 
395221460e0SChris Lattner   // If this is a fixed string pattern, just match it now.
396221460e0SChris Lattner   if (!FixedStr.empty()) {
397221460e0SChris Lattner     MatchLen = FixedStr.size();
398221460e0SChris Lattner     return Buffer.find(FixedStr);
399221460e0SChris Lattner   }
400221460e0SChris Lattner 
401b16ab0c4SChris Lattner   // Regex match.
4028879e06dSChris Lattner 
4038879e06dSChris Lattner   // If there are variable uses, we need to create a temporary string with the
4048879e06dSChris Lattner   // actual value.
4058879e06dSChris Lattner   StringRef RegExToMatch = RegExStr;
4068879e06dSChris Lattner   std::string TmpStr;
4078879e06dSChris Lattner   if (!VariableUses.empty()) {
4088879e06dSChris Lattner     TmpStr = RegExStr;
4098879e06dSChris Lattner 
4108879e06dSChris Lattner     unsigned InsertOffset = 0;
4118f870499SBenjamin Kramer     for (const auto &VariableUse : VariableUses) {
41292987fb3SAlexander Kornienko       std::string Value;
41392987fb3SAlexander Kornienko 
4148f870499SBenjamin Kramer       if (VariableUse.first[0] == '@') {
4158f870499SBenjamin Kramer         if (!EvaluateExpression(VariableUse.first, Value))
41692987fb3SAlexander Kornienko           return StringRef::npos;
41792987fb3SAlexander Kornienko       } else {
418e0ef65abSDaniel Dunbar         StringMap<StringRef>::iterator it =
4198f870499SBenjamin Kramer             VariableTable.find(VariableUse.first);
420e0ef65abSDaniel Dunbar         // If the variable is undefined, return an error.
421e0ef65abSDaniel Dunbar         if (it == VariableTable.end())
422e0ef65abSDaniel Dunbar           return StringRef::npos;
423e0ef65abSDaniel Dunbar 
4246f4f77b7SHans Wennborg         // Look up the value and escape it so that we can put it into the regex.
4256f4f77b7SHans Wennborg         Value += Regex::escape(it->second);
42692987fb3SAlexander Kornienko       }
4278879e06dSChris Lattner 
4288879e06dSChris Lattner       // Plop it into the regex at the adjusted offset.
4298f870499SBenjamin Kramer       TmpStr.insert(TmpStr.begin() + VariableUse.second + InsertOffset,
4308879e06dSChris Lattner                     Value.begin(), Value.end());
4318879e06dSChris Lattner       InsertOffset += Value.size();
4328879e06dSChris Lattner     }
4338879e06dSChris Lattner 
4348879e06dSChris Lattner     // Match the newly constructed regex.
4358879e06dSChris Lattner     RegExToMatch = TmpStr;
4368879e06dSChris Lattner   }
4378879e06dSChris Lattner 
438b16ab0c4SChris Lattner   SmallVector<StringRef, 4> MatchInfo;
4398879e06dSChris Lattner   if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
440f08d2db9SChris Lattner     return StringRef::npos;
441b16ab0c4SChris Lattner 
442b16ab0c4SChris Lattner   // Successful regex match.
443b16ab0c4SChris Lattner   assert(!MatchInfo.empty() && "Didn't get any match");
444b16ab0c4SChris Lattner   StringRef FullMatch = MatchInfo[0];
445b16ab0c4SChris Lattner 
4468879e06dSChris Lattner   // If this defines any variables, remember their values.
4478f870499SBenjamin Kramer   for (const auto &VariableDef : VariableDefs) {
4488f870499SBenjamin Kramer     assert(VariableDef.second < MatchInfo.size() && "Internal paren error");
4498f870499SBenjamin Kramer     VariableTable[VariableDef.first] = MatchInfo[VariableDef.second];
4500a4c44bdSChris Lattner   }
4510a4c44bdSChris Lattner 
452b16ab0c4SChris Lattner   MatchLen = FullMatch.size();
453b16ab0c4SChris Lattner   return FullMatch.data() - Buffer.data();
454f08d2db9SChris Lattner }
455f08d2db9SChris Lattner 
4564dabac20SChandler Carruth 
4574dabac20SChandler Carruth /// Computes an arbitrary estimate for the quality of matching this pattern at
4584dabac20SChandler Carruth /// the start of \p Buffer; a distance of zero should correspond to a perfect
4594dabac20SChandler Carruth /// match.
460e8f2fb20SChandler Carruth unsigned
461e8f2fb20SChandler Carruth Pattern::ComputeMatchDistance(StringRef Buffer,
462fd29d886SDaniel Dunbar                               const StringMap<StringRef> &VariableTable) const {
463fd29d886SDaniel Dunbar   // Just compute the number of matching characters. For regular expressions, we
464fd29d886SDaniel Dunbar   // just compare against the regex itself and hope for the best.
465fd29d886SDaniel Dunbar   //
466fd29d886SDaniel Dunbar   // FIXME: One easy improvement here is have the regex lib generate a single
467fd29d886SDaniel Dunbar   // example regular expression which matches, and use that as the example
468fd29d886SDaniel Dunbar   // string.
469fd29d886SDaniel Dunbar   StringRef ExampleString(FixedStr);
470fd29d886SDaniel Dunbar   if (ExampleString.empty())
471fd29d886SDaniel Dunbar     ExampleString = RegExStr;
472fd29d886SDaniel Dunbar 
473e9aa36c8SDaniel Dunbar   // Only compare up to the first line in the buffer, or the string size.
474e9aa36c8SDaniel Dunbar   StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
475e9aa36c8SDaniel Dunbar   BufferPrefix = BufferPrefix.split('\n').first;
476e9aa36c8SDaniel Dunbar   return BufferPrefix.edit_distance(ExampleString);
477fd29d886SDaniel Dunbar }
478fd29d886SDaniel Dunbar 
4794dabac20SChandler Carruth /// Prints additional information about a failure to match involving this
4804dabac20SChandler Carruth /// pattern.
481e8f2fb20SChandler Carruth void Pattern::PrintFailureInfo(
482e8f2fb20SChandler Carruth     const SourceMgr &SM, StringRef Buffer,
483e0ef65abSDaniel Dunbar     const StringMap<StringRef> &VariableTable) const {
484e0ef65abSDaniel Dunbar   // If this was a regular expression using variables, print the current
485e0ef65abSDaniel Dunbar   // variable values.
486e0ef65abSDaniel Dunbar   if (!VariableUses.empty()) {
4878f870499SBenjamin Kramer     for (const auto &VariableUse : VariableUses) {
488e69170a1SAlp Toker       SmallString<256> Msg;
489e69170a1SAlp Toker       raw_svector_ostream OS(Msg);
4908f870499SBenjamin Kramer       StringRef Var = VariableUse.first;
49192987fb3SAlexander Kornienko       if (Var[0] == '@') {
49292987fb3SAlexander Kornienko         std::string Value;
49392987fb3SAlexander Kornienko         if (EvaluateExpression(Var, Value)) {
49492987fb3SAlexander Kornienko           OS << "with expression \"";
49592987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\" equal to \"";
49692987fb3SAlexander Kornienko           OS.write_escaped(Value) << "\"";
49792987fb3SAlexander Kornienko         } else {
49892987fb3SAlexander Kornienko           OS << "uses incorrect expression \"";
49992987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
50092987fb3SAlexander Kornienko         }
50192987fb3SAlexander Kornienko       } else {
50292987fb3SAlexander Kornienko         StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
503e0ef65abSDaniel Dunbar 
504e0ef65abSDaniel Dunbar         // Check for undefined variable references.
505e0ef65abSDaniel Dunbar         if (it == VariableTable.end()) {
506e0ef65abSDaniel Dunbar           OS << "uses undefined variable \"";
50792987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
508e0ef65abSDaniel Dunbar         } else {
509e0ef65abSDaniel Dunbar           OS << "with variable \"";
510e0ef65abSDaniel Dunbar           OS.write_escaped(Var) << "\" equal to \"";
511e0ef65abSDaniel Dunbar           OS.write_escaped(it->second) << "\"";
512e0ef65abSDaniel Dunbar         }
51392987fb3SAlexander Kornienko       }
514e0ef65abSDaniel Dunbar 
51503b80a40SChris Lattner       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
51603b80a40SChris Lattner                       OS.str());
517e0ef65abSDaniel Dunbar     }
518e0ef65abSDaniel Dunbar   }
519fd29d886SDaniel Dunbar 
520fd29d886SDaniel Dunbar   // Attempt to find the closest/best fuzzy match.  Usually an error happens
521fd29d886SDaniel Dunbar   // because some string in the output didn't exactly match. In these cases, we
522fd29d886SDaniel Dunbar   // would like to show the user a best guess at what "should have" matched, to
523fd29d886SDaniel Dunbar   // save them having to actually check the input manually.
524fd29d886SDaniel Dunbar   size_t NumLinesForward = 0;
525fd29d886SDaniel Dunbar   size_t Best = StringRef::npos;
526fd29d886SDaniel Dunbar   double BestQuality = 0;
527fd29d886SDaniel Dunbar 
528fd29d886SDaniel Dunbar   // Use an arbitrary 4k limit on how far we will search.
5292bf486ebSDan Gohman   for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
530fd29d886SDaniel Dunbar     if (Buffer[i] == '\n')
531fd29d886SDaniel Dunbar       ++NumLinesForward;
532fd29d886SDaniel Dunbar 
533df22bbf7SDan Gohman     // Patterns have leading whitespace stripped, so skip whitespace when
534df22bbf7SDan Gohman     // looking for something which looks like a pattern.
535df22bbf7SDan Gohman     if (Buffer[i] == ' ' || Buffer[i] == '\t')
536df22bbf7SDan Gohman       continue;
537df22bbf7SDan Gohman 
538fd29d886SDaniel Dunbar     // Compute the "quality" of this match as an arbitrary combination of the
539fd29d886SDaniel Dunbar     // match distance and the number of lines skipped to get to this match.
540fd29d886SDaniel Dunbar     unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
541fd29d886SDaniel Dunbar     double Quality = Distance + (NumLinesForward / 100.);
542fd29d886SDaniel Dunbar 
543fd29d886SDaniel Dunbar     if (Quality < BestQuality || Best == StringRef::npos) {
544fd29d886SDaniel Dunbar       Best = i;
545fd29d886SDaniel Dunbar       BestQuality = Quality;
546fd29d886SDaniel Dunbar     }
547fd29d886SDaniel Dunbar   }
548fd29d886SDaniel Dunbar 
549fd29d886SDaniel Dunbar   // Print the "possible intended match here" line if we found something
550c069cc8eSDaniel Dunbar   // reasonable and not equal to what we showed in the "scanning from here"
551c069cc8eSDaniel Dunbar   // line.
552c069cc8eSDaniel Dunbar   if (Best && Best != StringRef::npos && BestQuality < 50) {
553fd29d886SDaniel Dunbar     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
55403b80a40SChris Lattner                     SourceMgr::DK_Note, "possible intended match here");
555fd29d886SDaniel Dunbar 
556fd29d886SDaniel Dunbar     // FIXME: If we wanted to be really friendly we would show why the match
557fd29d886SDaniel Dunbar     // failed, as it can be hard to spot simple one character differences.
558fd29d886SDaniel Dunbar   }
559e0ef65abSDaniel Dunbar }
56074d50731SChris Lattner 
5614dabac20SChandler Carruth /// Finds the closing sequence of a regex variable usage or definition.
5624dabac20SChandler Carruth ///
5634dabac20SChandler Carruth /// \p Str has to point in the beginning of the definition (right after the
5644dabac20SChandler Carruth /// opening sequence). Returns the offset of the closing sequence within Str,
5654dabac20SChandler Carruth /// or npos if it was not found.
56681e5cd9eSAdrian Prantl size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
567061d2baaSEli Bendersky   // Offset keeps track of the current offset within the input Str
568061d2baaSEli Bendersky   size_t Offset = 0;
569061d2baaSEli Bendersky   // [...] Nesting depth
570061d2baaSEli Bendersky   size_t BracketDepth = 0;
571061d2baaSEli Bendersky 
572061d2baaSEli Bendersky   while (!Str.empty()) {
573061d2baaSEli Bendersky     if (Str.startswith("]]") && BracketDepth == 0)
574061d2baaSEli Bendersky       return Offset;
575061d2baaSEli Bendersky     if (Str[0] == '\\') {
576061d2baaSEli Bendersky       // Backslash escapes the next char within regexes, so skip them both.
577061d2baaSEli Bendersky       Str = Str.substr(2);
578061d2baaSEli Bendersky       Offset += 2;
579061d2baaSEli Bendersky     } else {
580061d2baaSEli Bendersky       switch (Str[0]) {
581061d2baaSEli Bendersky       default:
582061d2baaSEli Bendersky         break;
583061d2baaSEli Bendersky       case '[':
584061d2baaSEli Bendersky         BracketDepth++;
585061d2baaSEli Bendersky         break;
586061d2baaSEli Bendersky       case ']':
58781e5cd9eSAdrian Prantl         if (BracketDepth == 0) {
58881e5cd9eSAdrian Prantl           SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
58981e5cd9eSAdrian Prantl                           SourceMgr::DK_Error,
59081e5cd9eSAdrian Prantl                           "missing closing \"]\" for regex variable");
59181e5cd9eSAdrian Prantl           exit(1);
59281e5cd9eSAdrian Prantl         }
593061d2baaSEli Bendersky         BracketDepth--;
594061d2baaSEli Bendersky         break;
595061d2baaSEli Bendersky       }
596061d2baaSEli Bendersky       Str = Str.substr(1);
597061d2baaSEli Bendersky       Offset++;
598061d2baaSEli Bendersky     }
599061d2baaSEli Bendersky   }
600061d2baaSEli Bendersky 
601061d2baaSEli Bendersky   return StringRef::npos;
602061d2baaSEli Bendersky }
603061d2baaSEli Bendersky 
60474d50731SChris Lattner //===----------------------------------------------------------------------===//
60574d50731SChris Lattner // Check Strings.
60674d50731SChris Lattner //===----------------------------------------------------------------------===//
6073b40b445SChris Lattner 
6084dabac20SChandler Carruth /// A check that we found in the input file.
6093b40b445SChris Lattner struct CheckString {
6104dabac20SChandler Carruth   /// The pattern to match.
6113b40b445SChris Lattner   Pattern Pat;
61226cccfe1SChris Lattner 
6134dabac20SChandler Carruth   /// Which prefix name this check matched.
61413df4626SMatt Arsenault   StringRef Prefix;
61513df4626SMatt Arsenault 
6164dabac20SChandler Carruth   /// The location in the match file that the check string was specified.
61726cccfe1SChris Lattner   SMLoc Loc;
61826cccfe1SChris Lattner 
6194dabac20SChandler Carruth   /// All of the strings that are disallowed from occurring between this match
6204dabac20SChandler Carruth   /// string and the previous one (or start of file).
62191a1b2c9SMichael Liao   std::vector<Pattern> DagNotStrings;
622236d2d5eSChris Lattner 
62385913ccaSJames Y Knight   CheckString(const Pattern &P, StringRef S, SMLoc L)
62485913ccaSJames Y Knight       : Pat(P), Prefix(S), Loc(L) {}
625dcc7d48dSMichael Liao 
626e93a3a08SStephen Lin   size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
627f8bd2e5bSStephen Lin                size_t &MatchLen, StringMap<StringRef> &VariableTable) const;
628dcc7d48dSMichael Liao 
629dcc7d48dSMichael Liao   bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
63001ac1707SDuncan P. N. Exon Smith   bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
631dcc7d48dSMichael Liao   bool CheckNot(const SourceMgr &SM, StringRef Buffer,
63291a1b2c9SMichael Liao                 const std::vector<const Pattern *> &NotStrings,
63391a1b2c9SMichael Liao                 StringMap<StringRef> &VariableTable) const;
63491a1b2c9SMichael Liao   size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
63591a1b2c9SMichael Liao                   std::vector<const Pattern *> &NotStrings,
636dcc7d48dSMichael Liao                   StringMap<StringRef> &VariableTable) const;
63726cccfe1SChris Lattner };
63826cccfe1SChris Lattner 
63920247900SChandler Carruth /// Canonicalize whitespaces in the file. Line endings are replaced with
64020247900SChandler Carruth /// UNIX-style '\n'.
641b03c166aSChandler Carruth static StringRef CanonicalizeFile(MemoryBuffer &MB,
64220247900SChandler Carruth                                   SmallVectorImpl<char> &OutputBuffer) {
64320247900SChandler Carruth   OutputBuffer.reserve(MB.getBufferSize());
644a2f8fc5aSChris Lattner 
64520247900SChandler Carruth   for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd();
646a2f8fc5aSChris Lattner        Ptr != End; ++Ptr) {
647fd781bf0SNAKAMURA Takumi     // Eliminate trailing dosish \r.
648fd781bf0SNAKAMURA Takumi     if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
649fd781bf0SNAKAMURA Takumi       continue;
650fd781bf0SNAKAMURA Takumi     }
651fd781bf0SNAKAMURA Takumi 
6525ea04c38SGuy Benyei     // If current char is not a horizontal whitespace or if horizontal
6535ea04c38SGuy Benyei     // whitespace canonicalization is disabled, dump it to output as is.
654b03c166aSChandler Carruth     if (NoCanonicalizeWhiteSpace || (*Ptr != ' ' && *Ptr != '\t')) {
65520247900SChandler Carruth       OutputBuffer.push_back(*Ptr);
656a2f8fc5aSChris Lattner       continue;
657a2f8fc5aSChris Lattner     }
658a2f8fc5aSChris Lattner 
659a2f8fc5aSChris Lattner     // Otherwise, add one space and advance over neighboring space.
66020247900SChandler Carruth     OutputBuffer.push_back(' ');
661e8f2fb20SChandler Carruth     while (Ptr + 1 != End && (Ptr[1] == ' ' || Ptr[1] == '\t'))
662a2f8fc5aSChris Lattner       ++Ptr;
663a2f8fc5aSChris Lattner   }
664a2f8fc5aSChris Lattner 
66520247900SChandler Carruth   // Add a null byte and then return all but that byte.
66620247900SChandler Carruth   OutputBuffer.push_back('\0');
66720247900SChandler Carruth   return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
668a2f8fc5aSChris Lattner }
669a2f8fc5aSChris Lattner 
67038820972SMatt Arsenault static bool IsPartOfWord(char c) {
67138820972SMatt Arsenault   return (isalnum(c) || c == '-' || c == '_');
67238820972SMatt Arsenault }
67338820972SMatt Arsenault 
67413df4626SMatt Arsenault // Get the size of the prefix extension.
67513df4626SMatt Arsenault static size_t CheckTypeSize(Check::CheckType Ty) {
67613df4626SMatt Arsenault   switch (Ty) {
67713df4626SMatt Arsenault   case Check::CheckNone:
678a908e7bdSPaul Robinson   case Check::CheckBadNot:
67913df4626SMatt Arsenault     return 0;
68013df4626SMatt Arsenault 
68113df4626SMatt Arsenault   case Check::CheckPlain:
68213df4626SMatt Arsenault     return sizeof(":") - 1;
68313df4626SMatt Arsenault 
68413df4626SMatt Arsenault   case Check::CheckNext:
68513df4626SMatt Arsenault     return sizeof("-NEXT:") - 1;
68613df4626SMatt Arsenault 
68701ac1707SDuncan P. N. Exon Smith   case Check::CheckSame:
68801ac1707SDuncan P. N. Exon Smith     return sizeof("-SAME:") - 1;
68901ac1707SDuncan P. N. Exon Smith 
69013df4626SMatt Arsenault   case Check::CheckNot:
69113df4626SMatt Arsenault     return sizeof("-NOT:") - 1;
69213df4626SMatt Arsenault 
69313df4626SMatt Arsenault   case Check::CheckDAG:
69413df4626SMatt Arsenault     return sizeof("-DAG:") - 1;
69513df4626SMatt Arsenault 
69613df4626SMatt Arsenault   case Check::CheckLabel:
69713df4626SMatt Arsenault     return sizeof("-LABEL:") - 1;
69813df4626SMatt Arsenault 
69913df4626SMatt Arsenault   case Check::CheckEOF:
70013df4626SMatt Arsenault     llvm_unreachable("Should not be using EOF size");
70113df4626SMatt Arsenault   }
70213df4626SMatt Arsenault 
70313df4626SMatt Arsenault   llvm_unreachable("Bad check type");
70413df4626SMatt Arsenault }
70513df4626SMatt Arsenault 
70613df4626SMatt Arsenault static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
707c4d2d471SMatt Arsenault   char NextChar = Buffer[Prefix.size()];
70838820972SMatt Arsenault 
70938820972SMatt Arsenault   // Verify that the : is present after the prefix.
71013df4626SMatt Arsenault   if (NextChar == ':')
71138820972SMatt Arsenault     return Check::CheckPlain;
71238820972SMatt Arsenault 
71313df4626SMatt Arsenault   if (NextChar != '-')
71438820972SMatt Arsenault     return Check::CheckNone;
71538820972SMatt Arsenault 
716c4d2d471SMatt Arsenault   StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
71713df4626SMatt Arsenault   if (Rest.startswith("NEXT:"))
71838820972SMatt Arsenault     return Check::CheckNext;
71938820972SMatt Arsenault 
72001ac1707SDuncan P. N. Exon Smith   if (Rest.startswith("SAME:"))
72101ac1707SDuncan P. N. Exon Smith     return Check::CheckSame;
72201ac1707SDuncan P. N. Exon Smith 
72313df4626SMatt Arsenault   if (Rest.startswith("NOT:"))
72438820972SMatt Arsenault     return Check::CheckNot;
72538820972SMatt Arsenault 
72613df4626SMatt Arsenault   if (Rest.startswith("DAG:"))
72738820972SMatt Arsenault     return Check::CheckDAG;
72838820972SMatt Arsenault 
72913df4626SMatt Arsenault   if (Rest.startswith("LABEL:"))
73038820972SMatt Arsenault     return Check::CheckLabel;
73113df4626SMatt Arsenault 
732a908e7bdSPaul Robinson   // You can't combine -NOT with another suffix.
733a908e7bdSPaul Robinson   if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
734a908e7bdSPaul Robinson       Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
735a908e7bdSPaul Robinson       Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:"))
736a908e7bdSPaul Robinson     return Check::CheckBadNot;
737a908e7bdSPaul Robinson 
73813df4626SMatt Arsenault   return Check::CheckNone;
73938820972SMatt Arsenault }
74038820972SMatt Arsenault 
74113df4626SMatt Arsenault // From the given position, find the next character after the word.
74213df4626SMatt Arsenault static size_t SkipWord(StringRef Str, size_t Loc) {
74313df4626SMatt Arsenault   while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
74413df4626SMatt Arsenault     ++Loc;
74513df4626SMatt Arsenault   return Loc;
74613df4626SMatt Arsenault }
74713df4626SMatt Arsenault 
748726774cbSChandler Carruth /// Search the buffer for the first prefix in the prefix regular expression.
749726774cbSChandler Carruth ///
750726774cbSChandler Carruth /// This searches the buffer using the provided regular expression, however it
751726774cbSChandler Carruth /// enforces constraints beyond that:
752726774cbSChandler Carruth /// 1) The found prefix must not be a suffix of something that looks like
753726774cbSChandler Carruth ///    a valid prefix.
754726774cbSChandler Carruth /// 2) The found prefix must be followed by a valid check type suffix using \c
755726774cbSChandler Carruth ///    FindCheckType above.
756726774cbSChandler Carruth ///
757726774cbSChandler Carruth /// The first match of the regular expression to satisfy these two is returned,
758726774cbSChandler Carruth /// otherwise an empty StringRef is returned to indicate failure.
759726774cbSChandler Carruth ///
760726774cbSChandler Carruth /// If this routine returns a valid prefix, it will also shrink \p Buffer to
761726774cbSChandler Carruth /// start at the beginning of the returned prefix, increment \p LineNumber for
762726774cbSChandler Carruth /// each new line consumed from \p Buffer, and set \p CheckTy to the type of
763726774cbSChandler Carruth /// check found by examining the suffix.
764726774cbSChandler Carruth ///
765726774cbSChandler Carruth /// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy
766726774cbSChandler Carruth /// is unspecified.
767726774cbSChandler Carruth static StringRef FindFirstMatchingPrefix(Regex &PrefixRE, StringRef &Buffer,
76813df4626SMatt Arsenault                                          unsigned &LineNumber,
769726774cbSChandler Carruth                                          Check::CheckType &CheckTy) {
770726774cbSChandler Carruth   SmallVector<StringRef, 2> Matches;
771726774cbSChandler Carruth 
77213df4626SMatt Arsenault   while (!Buffer.empty()) {
773726774cbSChandler Carruth     // Find the first (longest) match using the RE.
774726774cbSChandler Carruth     if (!PrefixRE.match(Buffer, &Matches))
775726774cbSChandler Carruth       // No match at all, bail.
776726774cbSChandler Carruth       return StringRef();
777726774cbSChandler Carruth 
778726774cbSChandler Carruth     StringRef Prefix = Matches[0];
779726774cbSChandler Carruth     Matches.clear();
780726774cbSChandler Carruth 
781726774cbSChandler Carruth     assert(Prefix.data() >= Buffer.data() &&
782726774cbSChandler Carruth            Prefix.data() < Buffer.data() + Buffer.size() &&
783726774cbSChandler Carruth            "Prefix doesn't start inside of buffer!");
784726774cbSChandler Carruth     size_t Loc = Prefix.data() - Buffer.data();
785726774cbSChandler Carruth     StringRef Skipped = Buffer.substr(0, Loc);
786726774cbSChandler Carruth     Buffer = Buffer.drop_front(Loc);
787726774cbSChandler Carruth     LineNumber += Skipped.count('\n');
788726774cbSChandler Carruth 
789726774cbSChandler Carruth     // Check that the matched prefix isn't a suffix of some other check-like
790726774cbSChandler Carruth     // word.
791726774cbSChandler Carruth     // FIXME: This is a very ad-hoc check. it would be better handled in some
792726774cbSChandler Carruth     // other way. Among other things it seems hard to distinguish between
793726774cbSChandler Carruth     // intentional and unintentional uses of this feature.
794726774cbSChandler Carruth     if (Skipped.empty() || !IsPartOfWord(Skipped.back())) {
795726774cbSChandler Carruth       // Now extract the type.
796726774cbSChandler Carruth       CheckTy = FindCheckType(Buffer, Prefix);
797726774cbSChandler Carruth 
798726774cbSChandler Carruth       // If we've found a valid check type for this prefix, we're done.
799726774cbSChandler Carruth       if (CheckTy != Check::CheckNone)
80013df4626SMatt Arsenault         return Prefix;
80113df4626SMatt Arsenault     }
80213df4626SMatt Arsenault 
803726774cbSChandler Carruth     // If we didn't successfully find a prefix, we need to skip this invalid
804726774cbSChandler Carruth     // prefix and continue scanning. We directly skip the prefix that was
805726774cbSChandler Carruth     // matched and any additional parts of that check-like word.
806726774cbSChandler Carruth     Buffer = Buffer.drop_front(SkipWord(Buffer, Prefix.size()));
80713df4626SMatt Arsenault   }
80813df4626SMatt Arsenault 
809726774cbSChandler Carruth   // We ran out of buffer while skipping partial matches so give up.
81013df4626SMatt Arsenault   return StringRef();
81138820972SMatt Arsenault }
812ee3c74fbSChris Lattner 
8134dabac20SChandler Carruth /// Read the check file, which specifies the sequence of expected strings.
8144dabac20SChandler Carruth ///
8154dabac20SChandler Carruth /// The strings are added to the CheckStrings vector. Returns true in case of
8164dabac20SChandler Carruth /// an error, false otherwise.
817726774cbSChandler Carruth static bool ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
81826cccfe1SChris Lattner                           std::vector<CheckString> &CheckStrings) {
81956ccdbbdSAlexander Kornienko   std::vector<Pattern> ImplicitNegativeChecks;
82056ccdbbdSAlexander Kornienko   for (const auto &PatternString : ImplicitCheckNot) {
82156ccdbbdSAlexander Kornienko     // Create a buffer with fake command line content in order to display the
82256ccdbbdSAlexander Kornienko     // command line option responsible for the specific implicit CHECK-NOT.
823ff43d69dSDavid Blaikie     std::string Prefix = (Twine("-") + ImplicitCheckNot.ArgStr + "='").str();
82456ccdbbdSAlexander Kornienko     std::string Suffix = "'";
8253560ff2cSRafael Espindola     std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
8263560ff2cSRafael Espindola         Prefix + PatternString + Suffix, "command line");
8273560ff2cSRafael Espindola 
82856ccdbbdSAlexander Kornienko     StringRef PatternInBuffer =
82956ccdbbdSAlexander Kornienko         CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
8301961f14cSDavid Blaikie     SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
83156ccdbbdSAlexander Kornienko 
83256ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
83356ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
83456ccdbbdSAlexander Kornienko                                                "IMPLICIT-CHECK", SM, 0);
83556ccdbbdSAlexander Kornienko   }
83656ccdbbdSAlexander Kornienko 
83756ccdbbdSAlexander Kornienko   std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
838236d2d5eSChris Lattner 
83943d50d4aSEli Bendersky   // LineNumber keeps track of the line on which CheckPrefix instances are
84043d50d4aSEli Bendersky   // found.
84192987fb3SAlexander Kornienko   unsigned LineNumber = 1;
84292987fb3SAlexander Kornienko 
843ee3c74fbSChris Lattner   while (1) {
84413df4626SMatt Arsenault     Check::CheckType CheckTy;
84513df4626SMatt Arsenault 
84613df4626SMatt Arsenault     // See if a prefix occurs in the memory buffer.
847726774cbSChandler Carruth     StringRef UsedPrefix = FindFirstMatchingPrefix(PrefixRE, Buffer, LineNumber,
848726774cbSChandler Carruth                                                    CheckTy);
84913df4626SMatt Arsenault     if (UsedPrefix.empty())
850ee3c74fbSChris Lattner       break;
851726774cbSChandler Carruth     assert(UsedPrefix.data() == Buffer.data() &&
852726774cbSChandler Carruth            "Failed to move Buffer's start forward, or pointed prefix outside "
853726774cbSChandler Carruth            "of the buffer!");
85492987fb3SAlexander Kornienko 
85513df4626SMatt Arsenault     // Location to use for error messages.
856726774cbSChandler Carruth     const char *UsedPrefixStart = UsedPrefix.data();
85792987fb3SAlexander Kornienko 
858726774cbSChandler Carruth     // Skip the buffer to the end.
85913df4626SMatt Arsenault     Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
86010f10cedSChris Lattner 
861a908e7bdSPaul Robinson     // Complain about useful-looking but unsupported suffixes.
862a908e7bdSPaul Robinson     if (CheckTy == Check::CheckBadNot) {
863e8f2fb20SChandler Carruth       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Error,
864a908e7bdSPaul Robinson                       "unsupported -NOT combo on prefix '" + UsedPrefix + "'");
865a908e7bdSPaul Robinson       return true;
866a908e7bdSPaul Robinson     }
867a908e7bdSPaul Robinson 
86838820972SMatt Arsenault     // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
869a26bc914STom de Vries     // leading whitespace.
870*1714676aSTom de Vries     if (!(NoCanonicalizeWhiteSpace && MatchFullLines))
871236d2d5eSChris Lattner       Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
872ee3c74fbSChris Lattner 
873ee3c74fbSChris Lattner     // Scan ahead to the end of line.
874caa5fc0cSChris Lattner     size_t EOL = Buffer.find_first_of("\n\r");
875ee3c74fbSChris Lattner 
876838fb09aSDan Gohman     // Remember the location of the start of the pattern, for diagnostics.
877838fb09aSDan Gohman     SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
878838fb09aSDan Gohman 
87974d50731SChris Lattner     // Parse the pattern.
88038820972SMatt Arsenault     Pattern P(CheckTy);
88113df4626SMatt Arsenault     if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
882ee3c74fbSChris Lattner       return true;
883ee3c74fbSChris Lattner 
884f8bd2e5bSStephen Lin     // Verify that CHECK-LABEL lines do not define or use variables
88538820972SMatt Arsenault     if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
886e8f2fb20SChandler Carruth       SM.PrintMessage(
887e8f2fb20SChandler Carruth           SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error,
88813df4626SMatt Arsenault           "found '" + UsedPrefix + "-LABEL:'"
88913df4626SMatt Arsenault                                    " with variable definition or use");
890f8bd2e5bSStephen Lin       return true;
891f8bd2e5bSStephen Lin     }
892f8bd2e5bSStephen Lin 
893236d2d5eSChris Lattner     Buffer = Buffer.substr(EOL);
89474d50731SChris Lattner 
895da108b4eSChris Lattner     // Verify that CHECK-NEXT lines have at least one CHECK line before them.
89601ac1707SDuncan P. N. Exon Smith     if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&
89701ac1707SDuncan P. N. Exon Smith         CheckStrings.empty()) {
89801ac1707SDuncan P. N. Exon Smith       StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";
89913df4626SMatt Arsenault       SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
90003b80a40SChris Lattner                       SourceMgr::DK_Error,
901e8f2fb20SChandler Carruth                       "found '" + UsedPrefix + "-" + Type +
902e8f2fb20SChandler Carruth                           "' without previous '" + UsedPrefix + ": line");
903da108b4eSChris Lattner       return true;
904da108b4eSChris Lattner     }
905da108b4eSChris Lattner 
90691a1b2c9SMichael Liao     // Handle CHECK-DAG/-NOT.
90738820972SMatt Arsenault     if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
90891a1b2c9SMichael Liao       DagNotMatches.push_back(P);
90974d50731SChris Lattner       continue;
91074d50731SChris Lattner     }
91174d50731SChris Lattner 
912ee3c74fbSChris Lattner     // Okay, add the string we captured to the output vector and move on.
91385913ccaSJames Y Knight     CheckStrings.emplace_back(P, UsedPrefix, PatternLoc);
91491a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
91556ccdbbdSAlexander Kornienko     DagNotMatches = ImplicitNegativeChecks;
916ee3c74fbSChris Lattner   }
917ee3c74fbSChris Lattner 
91813df4626SMatt Arsenault   // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
91913df4626SMatt Arsenault   // prefix as a filler for the error message.
92091a1b2c9SMichael Liao   if (!DagNotMatches.empty()) {
921f5e2fc47SBenjamin Kramer     CheckStrings.emplace_back(Pattern(Check::CheckEOF), *CheckPrefixes.begin(),
92285913ccaSJames Y Knight                               SMLoc::getFromPointer(Buffer.data()));
92391a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
924eba55822SJakob Stoklund Olesen   }
925eba55822SJakob Stoklund Olesen 
926ee3c74fbSChris Lattner   if (CheckStrings.empty()) {
92713df4626SMatt Arsenault     errs() << "error: no check strings found with prefix"
92813df4626SMatt Arsenault            << (CheckPrefixes.size() > 1 ? "es " : " ");
9293e3ef2f2SChris Bieneman     prefix_iterator I = CheckPrefixes.begin();
9303e3ef2f2SChris Bieneman     prefix_iterator E = CheckPrefixes.end();
9313e3ef2f2SChris Bieneman     if (I != E) {
9323e3ef2f2SChris Bieneman       errs() << "\'" << *I << ":'";
9333e3ef2f2SChris Bieneman       ++I;
93413df4626SMatt Arsenault     }
9353e3ef2f2SChris Bieneman     for (; I != E; ++I)
9363e3ef2f2SChris Bieneman       errs() << ", \'" << *I << ":'";
93713df4626SMatt Arsenault 
93813df4626SMatt Arsenault     errs() << '\n';
939ee3c74fbSChris Lattner     return true;
940ee3c74fbSChris Lattner   }
941ee3c74fbSChris Lattner 
942ee3c74fbSChris Lattner   return false;
943ee3c74fbSChris Lattner }
944ee3c74fbSChris Lattner 
945e8f2fb20SChandler Carruth static void PrintCheckFailed(const SourceMgr &SM, SMLoc Loc, const Pattern &Pat,
946e8f2fb20SChandler Carruth                              StringRef Buffer,
947e0ef65abSDaniel Dunbar                              StringMap<StringRef> &VariableTable) {
948da108b4eSChris Lattner   // Otherwise, we have an error, emit an error message.
94991a1b2c9SMichael Liao   SM.PrintMessage(Loc, SourceMgr::DK_Error,
95003b80a40SChris Lattner                   "expected string not found in input");
951da108b4eSChris Lattner 
952da108b4eSChris Lattner   // Print the "scanning from here" line.  If the current position is at the
953da108b4eSChris Lattner   // end of a line, advance to the start of the next line.
954caa5fc0cSChris Lattner   Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
955da108b4eSChris Lattner 
95603b80a40SChris Lattner   SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
95703b80a40SChris Lattner                   "scanning from here");
958e0ef65abSDaniel Dunbar 
959e0ef65abSDaniel Dunbar   // Allow the pattern to print additional information if desired.
96091a1b2c9SMichael Liao   Pat.PrintFailureInfo(SM, Buffer, VariableTable);
96191a1b2c9SMichael Liao }
96291a1b2c9SMichael Liao 
96391a1b2c9SMichael Liao static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
96491a1b2c9SMichael Liao                              StringRef Buffer,
96591a1b2c9SMichael Liao                              StringMap<StringRef> &VariableTable) {
96691a1b2c9SMichael Liao   PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
967da108b4eSChris Lattner }
968da108b4eSChris Lattner 
9694dabac20SChandler Carruth /// Count the number of newlines in the specified range.
970592fe880SRichard Smith static unsigned CountNumNewlinesBetween(StringRef Range,
971592fe880SRichard Smith                                         const char *&FirstNewLine) {
972da108b4eSChris Lattner   unsigned NumNewLines = 0;
97337183584SChris Lattner   while (1) {
974da108b4eSChris Lattner     // Scan for newline.
97537183584SChris Lattner     Range = Range.substr(Range.find_first_of("\n\r"));
976e8f2fb20SChandler Carruth     if (Range.empty())
977e8f2fb20SChandler Carruth       return NumNewLines;
978da108b4eSChris Lattner 
979da108b4eSChris Lattner     ++NumNewLines;
980da108b4eSChris Lattner 
981da108b4eSChris Lattner     // Handle \n\r and \r\n as a single newline.
982e8f2fb20SChandler Carruth     if (Range.size() > 1 && (Range[1] == '\n' || Range[1] == '\r') &&
98337183584SChris Lattner         (Range[0] != Range[1]))
98437183584SChris Lattner       Range = Range.substr(1);
98537183584SChris Lattner     Range = Range.substr(1);
986592fe880SRichard Smith 
987592fe880SRichard Smith     if (NumNewLines == 1)
988592fe880SRichard Smith       FirstNewLine = Range.begin();
989da108b4eSChris Lattner   }
990da108b4eSChris Lattner }
991da108b4eSChris Lattner 
9924dabac20SChandler Carruth /// Match check string and its "not strings" and/or "dag strings".
993dcc7d48dSMichael Liao size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
994e93a3a08SStephen Lin                           bool IsLabelScanMode, size_t &MatchLen,
995dcc7d48dSMichael Liao                           StringMap<StringRef> &VariableTable) const {
99691a1b2c9SMichael Liao   size_t LastPos = 0;
99791a1b2c9SMichael Liao   std::vector<const Pattern *> NotStrings;
99891a1b2c9SMichael Liao 
999e93a3a08SStephen Lin   // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
1000e93a3a08SStephen Lin   // bounds; we have not processed variable definitions within the bounded block
1001e93a3a08SStephen Lin   // yet so cannot handle any final CHECK-DAG yet; this is handled when going
1002e93a3a08SStephen Lin   // over the block again (including the last CHECK-LABEL) in normal mode.
1003e93a3a08SStephen Lin   if (!IsLabelScanMode) {
100491a1b2c9SMichael Liao     // Match "dag strings" (with mixed "not strings" if any).
100591a1b2c9SMichael Liao     LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable);
100691a1b2c9SMichael Liao     if (LastPos == StringRef::npos)
100791a1b2c9SMichael Liao       return StringRef::npos;
1008e93a3a08SStephen Lin   }
100991a1b2c9SMichael Liao 
101091a1b2c9SMichael Liao   // Match itself from the last position after matching CHECK-DAG.
101191a1b2c9SMichael Liao   StringRef MatchBuffer = Buffer.substr(LastPos);
101291a1b2c9SMichael Liao   size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
1013dcc7d48dSMichael Liao   if (MatchPos == StringRef::npos) {
101491a1b2c9SMichael Liao     PrintCheckFailed(SM, *this, MatchBuffer, VariableTable);
1015dcc7d48dSMichael Liao     return StringRef::npos;
1016dcc7d48dSMichael Liao   }
1017dcc7d48dSMichael Liao 
1018e93a3a08SStephen Lin   // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
1019e93a3a08SStephen Lin   // or CHECK-NOT
1020e93a3a08SStephen Lin   if (!IsLabelScanMode) {
102191a1b2c9SMichael Liao     StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1022dcc7d48dSMichael Liao 
1023dcc7d48dSMichael Liao     // If this check is a "CHECK-NEXT", verify that the previous match was on
1024dcc7d48dSMichael Liao     // the previous line (i.e. that there is one newline between them).
1025dcc7d48dSMichael Liao     if (CheckNext(SM, SkippedRegion))
1026dcc7d48dSMichael Liao       return StringRef::npos;
1027dcc7d48dSMichael Liao 
102801ac1707SDuncan P. N. Exon Smith     // If this check is a "CHECK-SAME", verify that the previous match was on
102901ac1707SDuncan P. N. Exon Smith     // the same line (i.e. that there is no newline between them).
103001ac1707SDuncan P. N. Exon Smith     if (CheckSame(SM, SkippedRegion))
103101ac1707SDuncan P. N. Exon Smith       return StringRef::npos;
103201ac1707SDuncan P. N. Exon Smith 
1033dcc7d48dSMichael Liao     // If this match had "not strings", verify that they don't exist in the
1034dcc7d48dSMichael Liao     // skipped region.
103591a1b2c9SMichael Liao     if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
1036dcc7d48dSMichael Liao       return StringRef::npos;
1037f8bd2e5bSStephen Lin   }
1038dcc7d48dSMichael Liao 
10397dfb92b9SMehdi Amini   return LastPos + MatchPos;
1040dcc7d48dSMichael Liao }
1041dcc7d48dSMichael Liao 
10424dabac20SChandler Carruth /// Verify there is a single line in the given buffer.
1043dcc7d48dSMichael Liao bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
104485913ccaSJames Y Knight   if (Pat.getCheckTy() != Check::CheckNext)
1045dcc7d48dSMichael Liao     return false;
1046dcc7d48dSMichael Liao 
1047dcc7d48dSMichael Liao   // Count the number of newlines between the previous match and this one.
1048dcc7d48dSMichael Liao   assert(Buffer.data() !=
1049e8f2fb20SChandler Carruth              SM.getMemoryBuffer(SM.FindBufferContainingLoc(
1050e8f2fb20SChandler Carruth                                     SMLoc::getFromPointer(Buffer.data())))
1051e8f2fb20SChandler Carruth                  ->getBufferStart() &&
1052dcc7d48dSMichael Liao          "CHECK-NEXT can't be the first check in a file");
1053dcc7d48dSMichael Liao 
105466f09ad0SCraig Topper   const char *FirstNewLine = nullptr;
1055592fe880SRichard Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
1056dcc7d48dSMichael Liao 
1057dcc7d48dSMichael Liao   if (NumNewLines == 0) {
1058e8f2fb20SChandler Carruth     SM.PrintMessage(Loc, SourceMgr::DK_Error,
1059e8f2fb20SChandler Carruth                     Prefix + "-NEXT: is on the same line as previous match");
1060e8f2fb20SChandler Carruth     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
1061e8f2fb20SChandler Carruth                     "'next' match was here");
1062dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1063dcc7d48dSMichael Liao                     "previous match ended here");
1064dcc7d48dSMichael Liao     return true;
1065dcc7d48dSMichael Liao   }
1066dcc7d48dSMichael Liao 
1067dcc7d48dSMichael Liao   if (NumNewLines != 1) {
1068e8f2fb20SChandler Carruth     SM.PrintMessage(Loc, SourceMgr::DK_Error,
1069e8f2fb20SChandler Carruth                     Prefix +
1070dcc7d48dSMichael Liao                         "-NEXT: is not on the line after the previous match");
1071e8f2fb20SChandler Carruth     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
1072e8f2fb20SChandler Carruth                     "'next' match was here");
1073dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1074dcc7d48dSMichael Liao                     "previous match ended here");
1075592fe880SRichard Smith     SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
1076592fe880SRichard Smith                     "non-matching line after previous match is here");
1077dcc7d48dSMichael Liao     return true;
1078dcc7d48dSMichael Liao   }
1079dcc7d48dSMichael Liao 
1080dcc7d48dSMichael Liao   return false;
1081dcc7d48dSMichael Liao }
1082dcc7d48dSMichael Liao 
10834dabac20SChandler Carruth /// Verify there is no newline in the given buffer.
108401ac1707SDuncan P. N. Exon Smith bool CheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
108585913ccaSJames Y Knight   if (Pat.getCheckTy() != Check::CheckSame)
108601ac1707SDuncan P. N. Exon Smith     return false;
108701ac1707SDuncan P. N. Exon Smith 
108801ac1707SDuncan P. N. Exon Smith   // Count the number of newlines between the previous match and this one.
108901ac1707SDuncan P. N. Exon Smith   assert(Buffer.data() !=
109001ac1707SDuncan P. N. Exon Smith              SM.getMemoryBuffer(SM.FindBufferContainingLoc(
109101ac1707SDuncan P. N. Exon Smith                                     SMLoc::getFromPointer(Buffer.data())))
109201ac1707SDuncan P. N. Exon Smith                  ->getBufferStart() &&
109301ac1707SDuncan P. N. Exon Smith          "CHECK-SAME can't be the first check in a file");
109401ac1707SDuncan P. N. Exon Smith 
109501ac1707SDuncan P. N. Exon Smith   const char *FirstNewLine = nullptr;
109601ac1707SDuncan P. N. Exon Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
109701ac1707SDuncan P. N. Exon Smith 
109801ac1707SDuncan P. N. Exon Smith   if (NumNewLines != 0) {
109901ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(Loc, SourceMgr::DK_Error,
110001ac1707SDuncan P. N. Exon Smith                     Prefix +
110101ac1707SDuncan P. N. Exon Smith                         "-SAME: is not on the same line as the previous match");
110201ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
110301ac1707SDuncan P. N. Exon Smith                     "'next' match was here");
110401ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
110501ac1707SDuncan P. N. Exon Smith                     "previous match ended here");
110601ac1707SDuncan P. N. Exon Smith     return true;
110701ac1707SDuncan P. N. Exon Smith   }
110801ac1707SDuncan P. N. Exon Smith 
110901ac1707SDuncan P. N. Exon Smith   return false;
111001ac1707SDuncan P. N. Exon Smith }
111101ac1707SDuncan P. N. Exon Smith 
11124dabac20SChandler Carruth /// Verify there's no "not strings" in the given buffer.
1113dcc7d48dSMichael Liao bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
111491a1b2c9SMichael Liao                            const std::vector<const Pattern *> &NotStrings,
1115dcc7d48dSMichael Liao                            StringMap<StringRef> &VariableTable) const {
11168f870499SBenjamin Kramer   for (const Pattern *Pat : NotStrings) {
111738820972SMatt Arsenault     assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
111891a1b2c9SMichael Liao 
1119dcc7d48dSMichael Liao     size_t MatchLen = 0;
112091a1b2c9SMichael Liao     size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
1121dcc7d48dSMichael Liao 
1122e8f2fb20SChandler Carruth     if (Pos == StringRef::npos)
1123e8f2fb20SChandler Carruth       continue;
1124dcc7d48dSMichael Liao 
1125dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Pos),
1126e8f2fb20SChandler Carruth                     SourceMgr::DK_Error, Prefix + "-NOT: string occurred!");
112791a1b2c9SMichael Liao     SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note,
112813df4626SMatt Arsenault                     Prefix + "-NOT: pattern specified here");
1129dcc7d48dSMichael Liao     return true;
1130dcc7d48dSMichael Liao   }
1131dcc7d48dSMichael Liao 
1132dcc7d48dSMichael Liao   return false;
1133dcc7d48dSMichael Liao }
1134dcc7d48dSMichael Liao 
11354dabac20SChandler Carruth /// Match "dag strings" and their mixed "not strings".
113691a1b2c9SMichael Liao size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
113791a1b2c9SMichael Liao                              std::vector<const Pattern *> &NotStrings,
113891a1b2c9SMichael Liao                              StringMap<StringRef> &VariableTable) const {
113991a1b2c9SMichael Liao   if (DagNotStrings.empty())
114091a1b2c9SMichael Liao     return 0;
114191a1b2c9SMichael Liao 
114291a1b2c9SMichael Liao   size_t LastPos = 0;
114391a1b2c9SMichael Liao   size_t StartPos = LastPos;
114491a1b2c9SMichael Liao 
11458f870499SBenjamin Kramer   for (const Pattern &Pat : DagNotStrings) {
114638820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG ||
114738820972SMatt Arsenault             Pat.getCheckTy() == Check::CheckNot) &&
114891a1b2c9SMichael Liao            "Invalid CHECK-DAG or CHECK-NOT!");
114991a1b2c9SMichael Liao 
115038820972SMatt Arsenault     if (Pat.getCheckTy() == Check::CheckNot) {
115191a1b2c9SMichael Liao       NotStrings.push_back(&Pat);
115291a1b2c9SMichael Liao       continue;
115391a1b2c9SMichael Liao     }
115491a1b2c9SMichael Liao 
115538820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
115691a1b2c9SMichael Liao 
115791a1b2c9SMichael Liao     size_t MatchLen = 0, MatchPos;
115891a1b2c9SMichael Liao 
115991a1b2c9SMichael Liao     // CHECK-DAG always matches from the start.
116091a1b2c9SMichael Liao     StringRef MatchBuffer = Buffer.substr(StartPos);
116191a1b2c9SMichael Liao     MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
116291a1b2c9SMichael Liao     // With a group of CHECK-DAGs, a single mismatching means the match on
116391a1b2c9SMichael Liao     // that group of CHECK-DAGs fails immediately.
116491a1b2c9SMichael Liao     if (MatchPos == StringRef::npos) {
116591a1b2c9SMichael Liao       PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
116691a1b2c9SMichael Liao       return StringRef::npos;
116791a1b2c9SMichael Liao     }
116891a1b2c9SMichael Liao     // Re-calc it as the offset relative to the start of the original string.
116991a1b2c9SMichael Liao     MatchPos += StartPos;
117091a1b2c9SMichael Liao 
117191a1b2c9SMichael Liao     if (!NotStrings.empty()) {
117291a1b2c9SMichael Liao       if (MatchPos < LastPos) {
117391a1b2c9SMichael Liao         // Reordered?
117491a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
117591a1b2c9SMichael Liao                         SourceMgr::DK_Error,
117613df4626SMatt Arsenault                         Prefix + "-DAG: found a match of CHECK-DAG"
117791a1b2c9SMichael Liao                                  " reordering across a CHECK-NOT");
117891a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
117991a1b2c9SMichael Liao                         SourceMgr::DK_Note,
118013df4626SMatt Arsenault                         Prefix + "-DAG: the farthest match of CHECK-DAG"
118191a1b2c9SMichael Liao                                  " is found here");
118291a1b2c9SMichael Liao         SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
118313df4626SMatt Arsenault                         Prefix + "-NOT: the crossed pattern specified"
118491a1b2c9SMichael Liao                                  " here");
118591a1b2c9SMichael Liao         SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
118613df4626SMatt Arsenault                         Prefix + "-DAG: the reordered pattern specified"
118791a1b2c9SMichael Liao                                  " here");
118891a1b2c9SMichael Liao         return StringRef::npos;
118991a1b2c9SMichael Liao       }
119091a1b2c9SMichael Liao       // All subsequent CHECK-DAGs should be matched from the farthest
119191a1b2c9SMichael Liao       // position of all precedent CHECK-DAGs (including this one.)
119291a1b2c9SMichael Liao       StartPos = LastPos;
119391a1b2c9SMichael Liao       // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
119491a1b2c9SMichael Liao       // CHECK-DAG, verify that there's no 'not' strings occurred in that
119591a1b2c9SMichael Liao       // region.
119691a1b2c9SMichael Liao       StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1197cf708c32STim Northover       if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
119891a1b2c9SMichael Liao         return StringRef::npos;
119991a1b2c9SMichael Liao       // Clear "not strings".
120091a1b2c9SMichael Liao       NotStrings.clear();
120191a1b2c9SMichael Liao     }
120291a1b2c9SMichael Liao 
120391a1b2c9SMichael Liao     // Update the last position with CHECK-DAG matches.
120491a1b2c9SMichael Liao     LastPos = std::max(MatchPos + MatchLen, LastPos);
120591a1b2c9SMichael Liao   }
120691a1b2c9SMichael Liao 
120791a1b2c9SMichael Liao   return LastPos;
120891a1b2c9SMichael Liao }
120991a1b2c9SMichael Liao 
121013df4626SMatt Arsenault // A check prefix must contain only alphanumeric, hyphens and underscores.
121113df4626SMatt Arsenault static bool ValidateCheckPrefix(StringRef CheckPrefix) {
121213df4626SMatt Arsenault   Regex Validator("^[a-zA-Z0-9_-]*$");
121313df4626SMatt Arsenault   return Validator.match(CheckPrefix);
121413df4626SMatt Arsenault }
121513df4626SMatt Arsenault 
121613df4626SMatt Arsenault static bool ValidateCheckPrefixes() {
121713df4626SMatt Arsenault   StringSet<> PrefixSet;
121813df4626SMatt Arsenault 
12198f870499SBenjamin Kramer   for (StringRef Prefix : CheckPrefixes) {
122024412b14SEli Bendersky     // Reject empty prefixes.
122124412b14SEli Bendersky     if (Prefix == "")
122224412b14SEli Bendersky       return false;
122324412b14SEli Bendersky 
12240356975cSDavid Blaikie     if (!PrefixSet.insert(Prefix).second)
122513df4626SMatt Arsenault       return false;
122613df4626SMatt Arsenault 
122713df4626SMatt Arsenault     if (!ValidateCheckPrefix(Prefix))
122813df4626SMatt Arsenault       return false;
122913df4626SMatt Arsenault   }
123013df4626SMatt Arsenault 
123113df4626SMatt Arsenault   return true;
123213df4626SMatt Arsenault }
123313df4626SMatt Arsenault 
1234726774cbSChandler Carruth // Combines the check prefixes into a single regex so that we can efficiently
1235726774cbSChandler Carruth // scan for any of the set.
1236726774cbSChandler Carruth //
1237726774cbSChandler Carruth // The semantics are that the longest-match wins which matches our regex
1238726774cbSChandler Carruth // library.
1239726774cbSChandler Carruth static Regex buildCheckPrefixRegex() {
124013df4626SMatt Arsenault   // I don't think there's a way to specify an initial value for cl::list,
124113df4626SMatt Arsenault   // so if nothing was specified, add the default
124213df4626SMatt Arsenault   if (CheckPrefixes.empty())
124313df4626SMatt Arsenault     CheckPrefixes.push_back("CHECK");
1244726774cbSChandler Carruth 
1245726774cbSChandler Carruth   // We already validated the contents of CheckPrefixes so just concatenate
1246726774cbSChandler Carruth   // them as alternatives.
1247726774cbSChandler Carruth   SmallString<32> PrefixRegexStr;
1248726774cbSChandler Carruth   for (StringRef Prefix : CheckPrefixes) {
1249726774cbSChandler Carruth     if (Prefix != CheckPrefixes.front())
1250726774cbSChandler Carruth       PrefixRegexStr.push_back('|');
1251726774cbSChandler Carruth 
1252726774cbSChandler Carruth     PrefixRegexStr.append(Prefix);
1253726774cbSChandler Carruth   }
1254726774cbSChandler Carruth 
1255726774cbSChandler Carruth   return Regex(PrefixRegexStr);
1256c2735158SRui Ueyama }
1257c2735158SRui Ueyama 
12582bd4f8b6SXinliang David Li static void DumpCommandLine(int argc, char **argv) {
12592bd4f8b6SXinliang David Li   errs() << "FileCheck command line: ";
12602bd4f8b6SXinliang David Li   for (int I = 0; I < argc; I++)
12612bd4f8b6SXinliang David Li     errs() << " " << argv[I];
12622bd4f8b6SXinliang David Li   errs() << "\n";
12632bd4f8b6SXinliang David Li }
12642bd4f8b6SXinliang David Li 
126520247900SChandler Carruth /// Check the input to FileCheck provided in the \p Buffer against the \p
126620247900SChandler Carruth /// CheckStrings read from the check file.
126720247900SChandler Carruth ///
126820247900SChandler Carruth /// Returns false if the input fails to satisfy the checks.
126920247900SChandler Carruth bool CheckInput(SourceMgr &SM, StringRef Buffer,
127020247900SChandler Carruth                 ArrayRef<CheckString> CheckStrings) {
127120247900SChandler Carruth   bool ChecksFailed = false;
127220247900SChandler Carruth 
127320247900SChandler Carruth   /// VariableTable - This holds all the current filecheck variables.
127420247900SChandler Carruth   StringMap<StringRef> VariableTable;
127520247900SChandler Carruth 
127620247900SChandler Carruth   unsigned i = 0, j = 0, e = CheckStrings.size();
127720247900SChandler Carruth   while (true) {
127820247900SChandler Carruth     StringRef CheckRegion;
127920247900SChandler Carruth     if (j == e) {
128020247900SChandler Carruth       CheckRegion = Buffer;
128120247900SChandler Carruth     } else {
128220247900SChandler Carruth       const CheckString &CheckLabelStr = CheckStrings[j];
128320247900SChandler Carruth       if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
128420247900SChandler Carruth         ++j;
128520247900SChandler Carruth         continue;
128620247900SChandler Carruth       }
128720247900SChandler Carruth 
128820247900SChandler Carruth       // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
128920247900SChandler Carruth       size_t MatchLabelLen = 0;
1290e8f2fb20SChandler Carruth       size_t MatchLabelPos =
1291e8f2fb20SChandler Carruth           CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, VariableTable);
129220247900SChandler Carruth       if (MatchLabelPos == StringRef::npos)
129320247900SChandler Carruth         // Immediately bail of CHECK-LABEL fails, nothing else we can do.
129420247900SChandler Carruth         return false;
129520247900SChandler Carruth 
129620247900SChandler Carruth       CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
129720247900SChandler Carruth       Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
129820247900SChandler Carruth       ++j;
129920247900SChandler Carruth     }
130020247900SChandler Carruth 
130120247900SChandler Carruth     for (; i != j; ++i) {
130220247900SChandler Carruth       const CheckString &CheckStr = CheckStrings[i];
130320247900SChandler Carruth 
130420247900SChandler Carruth       // Check each string within the scanned region, including a second check
130520247900SChandler Carruth       // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
130620247900SChandler Carruth       size_t MatchLen = 0;
1307e8f2fb20SChandler Carruth       size_t MatchPos =
1308e8f2fb20SChandler Carruth           CheckStr.Check(SM, CheckRegion, false, MatchLen, VariableTable);
130920247900SChandler Carruth 
131020247900SChandler Carruth       if (MatchPos == StringRef::npos) {
131120247900SChandler Carruth         ChecksFailed = true;
131220247900SChandler Carruth         i = j;
131320247900SChandler Carruth         break;
131420247900SChandler Carruth       }
131520247900SChandler Carruth 
131620247900SChandler Carruth       CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
131720247900SChandler Carruth     }
131820247900SChandler Carruth 
131920247900SChandler Carruth     if (j == e)
132020247900SChandler Carruth       break;
132120247900SChandler Carruth   }
132220247900SChandler Carruth 
132320247900SChandler Carruth   // Success if no checks failed.
132420247900SChandler Carruth   return !ChecksFailed;
132520247900SChandler Carruth }
132620247900SChandler Carruth 
1327ee3c74fbSChris Lattner int main(int argc, char **argv) {
13282ad6d48bSRichard Smith   sys::PrintStackTraceOnErrorSignal(argv[0]);
1329ee3c74fbSChris Lattner   PrettyStackTraceProgram X(argc, argv);
1330ee3c74fbSChris Lattner   cl::ParseCommandLineOptions(argc, argv);
1331ee3c74fbSChris Lattner 
133213df4626SMatt Arsenault   if (!ValidateCheckPrefixes()) {
133313df4626SMatt Arsenault     errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
133413df4626SMatt Arsenault               "start with a letter and contain only alphanumeric characters, "
133513df4626SMatt Arsenault               "hyphens and underscores\n";
1336c2735158SRui Ueyama     return 2;
1337c2735158SRui Ueyama   }
1338c2735158SRui Ueyama 
1339726774cbSChandler Carruth   Regex PrefixRE = buildCheckPrefixRegex();
1340726774cbSChandler Carruth   std::string REError;
1341726774cbSChandler Carruth   if (!PrefixRE.isValid(REError)) {
1342726774cbSChandler Carruth     errs() << "Unable to combine check-prefix strings into a prefix regular "
1343726774cbSChandler Carruth               "expression! This is likely a bug in FileCheck's verification of "
1344726774cbSChandler Carruth               "the check-prefix strings. Regular expression parsing failed "
1345726774cbSChandler Carruth               "with the following error: "
1346726774cbSChandler Carruth            << REError << "\n";
1347726774cbSChandler Carruth     return 2;
1348726774cbSChandler Carruth   }
134913df4626SMatt Arsenault 
1350ee3c74fbSChris Lattner   SourceMgr SM;
1351ee3c74fbSChris Lattner 
1352ee3c74fbSChris Lattner   // Read the expected strings from the check file.
135320247900SChandler Carruth   ErrorOr<std::unique_ptr<MemoryBuffer>> CheckFileOrErr =
135420247900SChandler Carruth       MemoryBuffer::getFileOrSTDIN(CheckFilename);
135520247900SChandler Carruth   if (std::error_code EC = CheckFileOrErr.getError()) {
135620247900SChandler Carruth     errs() << "Could not open check file '" << CheckFilename
135720247900SChandler Carruth            << "': " << EC.message() << '\n';
135820247900SChandler Carruth     return 2;
135920247900SChandler Carruth   }
136020247900SChandler Carruth   MemoryBuffer &CheckFile = *CheckFileOrErr.get();
136120247900SChandler Carruth 
136220247900SChandler Carruth   SmallString<4096> CheckFileBuffer;
1363b03c166aSChandler Carruth   StringRef CheckFileText = CanonicalizeFile(CheckFile, CheckFileBuffer);
136420247900SChandler Carruth 
136520247900SChandler Carruth   SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
136620247900SChandler Carruth                             CheckFileText, CheckFile.getBufferIdentifier()),
136720247900SChandler Carruth                         SMLoc());
136820247900SChandler Carruth 
136926cccfe1SChris Lattner   std::vector<CheckString> CheckStrings;
1370726774cbSChandler Carruth   if (ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings))
1371ee3c74fbSChris Lattner     return 2;
1372ee3c74fbSChris Lattner 
1373ee3c74fbSChris Lattner   // Open the file to check and add it to SourceMgr.
137420247900SChandler Carruth   ErrorOr<std::unique_ptr<MemoryBuffer>> InputFileOrErr =
1375adf21f2aSRafael Espindola       MemoryBuffer::getFileOrSTDIN(InputFilename);
137620247900SChandler Carruth   if (std::error_code EC = InputFileOrErr.getError()) {
1377adf21f2aSRafael Espindola     errs() << "Could not open input file '" << InputFilename
1378adf21f2aSRafael Espindola            << "': " << EC.message() << '\n';
13798e1c6477SEli Bendersky     return 2;
1380ee3c74fbSChris Lattner   }
138120247900SChandler Carruth   MemoryBuffer &InputFile = *InputFileOrErr.get();
13822c3e5cdfSChris Lattner 
138320247900SChandler Carruth   if (InputFile.getBufferSize() == 0 && !AllowEmptyInput) {
1384b692bed7SChris Lattner     errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
13852bd4f8b6SXinliang David Li     DumpCommandLine(argc, argv);
13868e1c6477SEli Bendersky     return 2;
1387b692bed7SChris Lattner   }
1388b692bed7SChris Lattner 
138920247900SChandler Carruth   SmallString<4096> InputFileBuffer;
1390b03c166aSChandler Carruth   StringRef InputFileText = CanonicalizeFile(InputFile, InputFileBuffer);
13912c3e5cdfSChris Lattner 
1392e8f2fb20SChandler Carruth   SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
1393e8f2fb20SChandler Carruth                             InputFileText, InputFile.getBufferIdentifier()),
1394e8f2fb20SChandler Carruth                         SMLoc());
1395ee3c74fbSChris Lattner 
139620247900SChandler Carruth   return CheckInput(SM, InputFileText, CheckStrings) ? EXIT_SUCCESS : 1;
1397ee3c74fbSChris Lattner }
1398