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 
45*e8f2fb20SChandler Carruth static cl::list<std::string> CheckPrefixes(
46*e8f2fb20SChandler 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 
54*e8f2fb20SChandler Carruth static cl::opt<bool> NoCanonicalizeWhiteSpace(
55*e8f2fb20SChandler 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 
92eba55822SJakob Stoklund Olesen   /// MatchEOF - When set, this pattern only matches the end of file. This is
93eba55822SJakob Stoklund Olesen   /// used for trailing CHECK-NOTs.
94a908e7bdSPaul Robinson   CheckEOF,
95a908e7bdSPaul Robinson   /// CheckBadNot - Found -NOT combined with another CHECK suffix.
96a908e7bdSPaul Robinson   CheckBadNot
9738820972SMatt Arsenault };
9838820972SMatt Arsenault }
99eba55822SJakob Stoklund Olesen 
10038820972SMatt Arsenault class Pattern {
10138820972SMatt Arsenault   SMLoc PatternLoc;
10291a1b2c9SMichael Liao 
103b16ab0c4SChris Lattner   /// FixedStr - If non-empty, this pattern is a fixed string match with the
104b16ab0c4SChris Lattner   /// specified fixed string.
105221460e0SChris Lattner   StringRef FixedStr;
106b16ab0c4SChris Lattner 
107b16ab0c4SChris Lattner   /// RegEx - If non-empty, this is a regex pattern.
108b16ab0c4SChris Lattner   std::string RegExStr;
1098879e06dSChris Lattner 
1108879e06dSChris Lattner   /// VariableUses - Entries in this vector map to uses of a variable in the
1118879e06dSChris Lattner   /// pattern, e.g. "foo[[bar]]baz".  In this case, the RegExStr will contain
1128879e06dSChris Lattner   /// "foobaz" and we'll get an entry in this vector that tells us to insert the
1138879e06dSChris Lattner   /// value of bar at offset 3.
1148879e06dSChris Lattner   std::vector<std::pair<StringRef, unsigned>> VariableUses;
1158879e06dSChris Lattner 
116e8b8f1bcSEli Bendersky   /// VariableDefs - Maps definitions of variables to their parenthesized
117e8b8f1bcSEli Bendersky   /// capture numbers.
118e8b8f1bcSEli Bendersky   /// E.g. for the pattern "foo[[bar:.*]]baz", VariableDefs will map "bar" to 1.
119e8b8f1bcSEli Bendersky   std::map<StringRef, unsigned> VariableDefs;
1208879e06dSChris Lattner 
121d1e020f7SSaleem Abdulrasool   Check::CheckType CheckTy;
1223b40b445SChris Lattner 
123d1e020f7SSaleem Abdulrasool   /// \brief Contains the number of line this pattern is in.
124d1e020f7SSaleem Abdulrasool   unsigned LineNumber;
125d1e020f7SSaleem Abdulrasool 
126d1e020f7SSaleem Abdulrasool public:
127d1e020f7SSaleem Abdulrasool   explicit Pattern(Check::CheckType Ty) : CheckTy(Ty) {}
12874d50731SChris Lattner 
1290b707eb8SMichael Liao   /// getLoc - Return the location in source code.
1300b707eb8SMichael Liao   SMLoc getLoc() const { return PatternLoc; }
1310b707eb8SMichael Liao 
13213df4626SMatt Arsenault   /// ParsePattern - Parse the given string into the Pattern. Prefix provides
13313df4626SMatt Arsenault   /// which prefix is being matched, SM provides the SourceMgr used for error
13413df4626SMatt Arsenault   /// reports, and LineNumber is the line number in the input file from which
13513df4626SMatt Arsenault   /// the pattern string was read.  Returns true in case of an error, false
13613df4626SMatt Arsenault   /// otherwise.
137*e8f2fb20SChandler Carruth   bool ParsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
13813df4626SMatt Arsenault                     unsigned LineNumber);
1393b40b445SChris Lattner 
1403b40b445SChris Lattner   /// Match - Match the pattern string against the input buffer Buffer.  This
1413b40b445SChris Lattner   /// returns the position that is matched or npos if there is no match.  If
1423b40b445SChris Lattner   /// there is a match, the size of the matched string is returned in MatchLen.
1438879e06dSChris Lattner   ///
1448879e06dSChris Lattner   /// The VariableTable StringMap provides the current values of filecheck
1458879e06dSChris Lattner   /// variables and is updated if this match defines new values.
1468879e06dSChris Lattner   size_t Match(StringRef Buffer, size_t &MatchLen,
1478879e06dSChris Lattner                StringMap<StringRef> &VariableTable) const;
148b16ab0c4SChris Lattner 
149e0ef65abSDaniel Dunbar   /// PrintFailureInfo - Print additional information about a failure to match
150e0ef65abSDaniel Dunbar   /// involving this pattern.
151e0ef65abSDaniel Dunbar   void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
152e0ef65abSDaniel Dunbar                         const StringMap<StringRef> &VariableTable) const;
153e0ef65abSDaniel Dunbar 
154*e8f2fb20SChandler Carruth   bool hasVariable() const {
155*e8f2fb20SChandler Carruth     return !(VariableUses.empty() && VariableDefs.empty());
156*e8f2fb20SChandler Carruth   }
157f8bd2e5bSStephen Lin 
15838820972SMatt Arsenault   Check::CheckType getCheckTy() const { return CheckTy; }
15991a1b2c9SMichael Liao 
160b16ab0c4SChris Lattner private:
161e8b8f1bcSEli Bendersky   bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
162e8b8f1bcSEli Bendersky   void AddBackrefToRegEx(unsigned BackrefNum);
163fd29d886SDaniel Dunbar 
164fd29d886SDaniel Dunbar   /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
165fd29d886SDaniel Dunbar   /// matching this pattern at the start of \arg Buffer; a distance of zero
166fd29d886SDaniel Dunbar   /// should correspond to a perfect match.
167*e8f2fb20SChandler Carruth   unsigned
168*e8f2fb20SChandler Carruth   ComputeMatchDistance(StringRef Buffer,
169fd29d886SDaniel Dunbar                        const StringMap<StringRef> &VariableTable) const;
17092987fb3SAlexander Kornienko 
17192987fb3SAlexander Kornienko   /// \brief Evaluates expression and stores the result to \p Value.
17292987fb3SAlexander Kornienko   /// \return true on success. false when the expression has invalid syntax.
17392987fb3SAlexander Kornienko   bool EvaluateExpression(StringRef Expr, std::string &Value) const;
174061d2baaSEli Bendersky 
175061d2baaSEli Bendersky   /// \brief Finds the closing sequence of a regex variable usage or
176061d2baaSEli Bendersky   /// definition. Str has to point in the beginning of the definition
177061d2baaSEli Bendersky   /// (right after the opening sequence).
178061d2baaSEli Bendersky   /// \return offset of the closing sequence within Str, or npos if it was not
179061d2baaSEli Bendersky   /// found.
18081e5cd9eSAdrian Prantl   size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
1813b40b445SChris Lattner };
1823b40b445SChris Lattner 
183*e8f2fb20SChandler Carruth bool Pattern::ParsePattern(StringRef PatternStr, StringRef Prefix,
184*e8f2fb20SChandler Carruth                            SourceMgr &SM, unsigned LineNumber) {
18585913ccaSJames Y Knight   bool MatchFullLinesHere = MatchFullLines && CheckTy != Check::CheckNot;
18685913ccaSJames Y Knight 
18792987fb3SAlexander Kornienko   this->LineNumber = LineNumber;
1880a4c44bdSChris Lattner   PatternLoc = SMLoc::getFromPointer(PatternStr.data());
1890a4c44bdSChris Lattner 
19074d50731SChris Lattner   // Ignore trailing whitespace.
19174d50731SChris Lattner   while (!PatternStr.empty() &&
19274d50731SChris Lattner          (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
19374d50731SChris Lattner     PatternStr = PatternStr.substr(0, PatternStr.size() - 1);
19474d50731SChris Lattner 
19574d50731SChris Lattner   // Check that there is something on the line.
19674d50731SChris Lattner   if (PatternStr.empty()) {
19703b80a40SChris Lattner     SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
198*e8f2fb20SChandler Carruth                     "found empty check string with prefix '" + Prefix + ":'");
19974d50731SChris Lattner     return true;
20074d50731SChris Lattner   }
20174d50731SChris Lattner 
202221460e0SChris Lattner   // Check to see if this is a fixed string, or if it has regex pieces.
20385913ccaSJames Y Knight   if (!MatchFullLinesHere &&
20485913ccaSJames Y Knight       (PatternStr.size() < 2 || (PatternStr.find("{{") == StringRef::npos &&
20585913ccaSJames Y Knight                                  PatternStr.find("[[") == StringRef::npos))) {
206221460e0SChris Lattner     FixedStr = PatternStr;
207221460e0SChris Lattner     return false;
208221460e0SChris Lattner   }
209221460e0SChris Lattner 
21085913ccaSJames Y Knight   if (MatchFullLinesHere) {
21185913ccaSJames Y Knight     RegExStr += '^';
21285913ccaSJames Y Knight     if (!NoCanonicalizeWhiteSpace)
21385913ccaSJames Y Knight       RegExStr += " *";
21485913ccaSJames Y Knight   }
21585913ccaSJames Y Knight 
2168879e06dSChris Lattner   // Paren value #0 is for the fully matched string.  Any new parenthesized
21753e0679dSChris Lattner   // values add from there.
2188879e06dSChris Lattner   unsigned CurParen = 1;
2198879e06dSChris Lattner 
220b16ab0c4SChris Lattner   // Otherwise, there is at least one regex piece.  Build up the regex pattern
221b16ab0c4SChris Lattner   // by escaping scary characters in fixed strings, building up one big regex.
222f08d2db9SChris Lattner   while (!PatternStr.empty()) {
2238879e06dSChris Lattner     // RegEx matches.
22453e0679dSChris Lattner     if (PatternStr.startswith("{{")) {
22543d50d4aSEli Bendersky       // This is the start of a regex match.  Scan for the }}.
226f08d2db9SChris Lattner       size_t End = PatternStr.find("}}");
227f08d2db9SChris Lattner       if (End == StringRef::npos) {
228f08d2db9SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
22903b80a40SChris Lattner                         SourceMgr::DK_Error,
23003b80a40SChris Lattner                         "found start of regex string with no end '}}'");
231f08d2db9SChris Lattner         return true;
232f08d2db9SChris Lattner       }
233f08d2db9SChris Lattner 
234e53c95f1SChris Lattner       // Enclose {{}} patterns in parens just like [[]] even though we're not
235e53c95f1SChris Lattner       // capturing the result for any purpose.  This is required in case the
236e53c95f1SChris Lattner       // expression contains an alternation like: CHECK:  abc{{x|z}}def.  We
237e53c95f1SChris Lattner       // want this to turn into: "abc(x|z)def" not "abcx|zdef".
238e53c95f1SChris Lattner       RegExStr += '(';
239e53c95f1SChris Lattner       ++CurParen;
240e53c95f1SChris Lattner 
2418879e06dSChris Lattner       if (AddRegExToRegEx(PatternStr.substr(2, End - 2), CurParen, SM))
2428879e06dSChris Lattner         return true;
243e53c95f1SChris Lattner       RegExStr += ')';
24453e0679dSChris Lattner 
2458879e06dSChris Lattner       PatternStr = PatternStr.substr(End + 2);
2468879e06dSChris Lattner       continue;
2478879e06dSChris Lattner     }
2488879e06dSChris Lattner 
2498879e06dSChris Lattner     // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
2508879e06dSChris Lattner     // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
2518879e06dSChris Lattner     // second form is [[foo]] which is a reference to foo.  The variable name
25257cb733bSDaniel Dunbar     // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
2538879e06dSChris Lattner     // it.  This is to catch some common errors.
25453e0679dSChris Lattner     if (PatternStr.startswith("[[")) {
255061d2baaSEli Bendersky       // Find the closing bracket pair ending the match.  End is going to be an
256061d2baaSEli Bendersky       // offset relative to the beginning of the match string.
25781e5cd9eSAdrian Prantl       size_t End = FindRegexVarEnd(PatternStr.substr(2), SM);
258061d2baaSEli Bendersky 
2598879e06dSChris Lattner       if (End == StringRef::npos) {
2608879e06dSChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
26103b80a40SChris Lattner                         SourceMgr::DK_Error,
26203b80a40SChris Lattner                         "invalid named regex reference, no ]] found");
263f08d2db9SChris Lattner         return true;
264f08d2db9SChris Lattner       }
265f08d2db9SChris Lattner 
266061d2baaSEli Bendersky       StringRef MatchStr = PatternStr.substr(2, End);
267061d2baaSEli Bendersky       PatternStr = PatternStr.substr(End + 4);
2688879e06dSChris Lattner 
2698879e06dSChris Lattner       // Get the regex name (e.g. "foo").
2708879e06dSChris Lattner       size_t NameEnd = MatchStr.find(':');
2718879e06dSChris Lattner       StringRef Name = MatchStr.substr(0, NameEnd);
2728879e06dSChris Lattner 
2738879e06dSChris Lattner       if (Name.empty()) {
27403b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
27503b80a40SChris Lattner                         "invalid name in named regex: empty name");
2768879e06dSChris Lattner         return true;
2778879e06dSChris Lattner       }
2788879e06dSChris Lattner 
27992987fb3SAlexander Kornienko       // Verify that the name/expression is well formed. FileCheck currently
28092987fb3SAlexander Kornienko       // supports @LINE, @LINE+number, @LINE-number expressions. The check here
28192987fb3SAlexander Kornienko       // is relaxed, more strict check is performed in \c EvaluateExpression.
28292987fb3SAlexander Kornienko       bool IsExpression = false;
28392987fb3SAlexander Kornienko       for (unsigned i = 0, e = Name.size(); i != e; ++i) {
28492987fb3SAlexander Kornienko         if (i == 0 && Name[i] == '@') {
28592987fb3SAlexander Kornienko           if (NameEnd != StringRef::npos) {
28692987fb3SAlexander Kornienko             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
28792987fb3SAlexander Kornienko                             SourceMgr::DK_Error,
28892987fb3SAlexander Kornienko                             "invalid name in named regex definition");
28992987fb3SAlexander Kornienko             return true;
29092987fb3SAlexander Kornienko           }
29192987fb3SAlexander Kornienko           IsExpression = true;
29292987fb3SAlexander Kornienko           continue;
29392987fb3SAlexander Kornienko         }
29492987fb3SAlexander Kornienko         if (Name[i] != '_' && !isalnum(Name[i]) &&
29592987fb3SAlexander Kornienko             (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
2968879e06dSChris Lattner           SM.PrintMessage(SMLoc::getFromPointer(Name.data() + i),
29703b80a40SChris Lattner                           SourceMgr::DK_Error, "invalid name in named regex");
2988879e06dSChris Lattner           return true;
2998879e06dSChris Lattner         }
30092987fb3SAlexander Kornienko       }
3018879e06dSChris Lattner 
3028879e06dSChris Lattner       // Name can't start with a digit.
30383c74e9fSGuy Benyei       if (isdigit(static_cast<unsigned char>(Name[0]))) {
30403b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
30503b80a40SChris Lattner                         "invalid name in named regex");
3068879e06dSChris Lattner         return true;
3078879e06dSChris Lattner       }
3088879e06dSChris Lattner 
3098879e06dSChris Lattner       // Handle [[foo]].
3108879e06dSChris Lattner       if (NameEnd == StringRef::npos) {
311e8b8f1bcSEli Bendersky         // Handle variables that were defined earlier on the same line by
312e8b8f1bcSEli Bendersky         // emitting a backreference.
313e8b8f1bcSEli Bendersky         if (VariableDefs.find(Name) != VariableDefs.end()) {
314e8b8f1bcSEli Bendersky           unsigned VarParenNum = VariableDefs[Name];
315e8b8f1bcSEli Bendersky           if (VarParenNum < 1 || VarParenNum > 9) {
316e8b8f1bcSEli Bendersky             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
317e8b8f1bcSEli Bendersky                             SourceMgr::DK_Error,
318e8b8f1bcSEli Bendersky                             "Can't back-reference more than 9 variables");
319e8b8f1bcSEli Bendersky             return true;
320e8b8f1bcSEli Bendersky           }
321e8b8f1bcSEli Bendersky           AddBackrefToRegEx(VarParenNum);
322e8b8f1bcSEli Bendersky         } else {
3238879e06dSChris Lattner           VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
324e8b8f1bcSEli Bendersky         }
3258879e06dSChris Lattner         continue;
3268879e06dSChris Lattner       }
3278879e06dSChris Lattner 
3288879e06dSChris Lattner       // Handle [[foo:.*]].
329e8b8f1bcSEli Bendersky       VariableDefs[Name] = CurParen;
3308879e06dSChris Lattner       RegExStr += '(';
3318879e06dSChris Lattner       ++CurParen;
3328879e06dSChris Lattner 
3338879e06dSChris Lattner       if (AddRegExToRegEx(MatchStr.substr(NameEnd + 1), CurParen, SM))
3348879e06dSChris Lattner         return true;
3358879e06dSChris Lattner 
3368879e06dSChris Lattner       RegExStr += ')';
3378879e06dSChris Lattner     }
3388879e06dSChris Lattner 
3398879e06dSChris Lattner     // Handle fixed string matches.
3408879e06dSChris Lattner     // Find the end, which is the start of the next regex.
3418879e06dSChris Lattner     size_t FixedMatchEnd = PatternStr.find("{{");
3428879e06dSChris Lattner     FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
3436f4f77b7SHans Wennborg     RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
3448879e06dSChris Lattner     PatternStr = PatternStr.substr(FixedMatchEnd);
345f08d2db9SChris Lattner   }
346f08d2db9SChris Lattner 
34785913ccaSJames Y Knight   if (MatchFullLinesHere) {
34885913ccaSJames Y Knight     if (!NoCanonicalizeWhiteSpace)
34985913ccaSJames Y Knight       RegExStr += " *";
35085913ccaSJames Y Knight     RegExStr += '$';
35185913ccaSJames Y Knight   }
35285913ccaSJames Y Knight 
35374d50731SChris Lattner   return false;
35474d50731SChris Lattner }
35574d50731SChris Lattner 
356*e8f2fb20SChandler Carruth bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
357e8b8f1bcSEli Bendersky   Regex R(RS);
3588879e06dSChris Lattner   std::string Error;
3598879e06dSChris Lattner   if (!R.isValid(Error)) {
360e8b8f1bcSEli Bendersky     SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
36103b80a40SChris Lattner                     "invalid regex: " + Error);
3628879e06dSChris Lattner     return true;
3638879e06dSChris Lattner   }
3648879e06dSChris Lattner 
365e8b8f1bcSEli Bendersky   RegExStr += RS.str();
3668879e06dSChris Lattner   CurParen += R.getNumMatches();
3678879e06dSChris Lattner   return false;
3688879e06dSChris Lattner }
369b16ab0c4SChris Lattner 
370e8b8f1bcSEli Bendersky void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
371e8b8f1bcSEli Bendersky   assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
372*e8f2fb20SChandler Carruth   std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum);
373e8b8f1bcSEli Bendersky   RegExStr += Backref;
374e8b8f1bcSEli Bendersky }
375e8b8f1bcSEli Bendersky 
37692987fb3SAlexander Kornienko bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
37792987fb3SAlexander Kornienko   // The only supported expression is @LINE([\+-]\d+)?
37892987fb3SAlexander Kornienko   if (!Expr.startswith("@LINE"))
37992987fb3SAlexander Kornienko     return false;
38092987fb3SAlexander Kornienko   Expr = Expr.substr(StringRef("@LINE").size());
38192987fb3SAlexander Kornienko   int Offset = 0;
38292987fb3SAlexander Kornienko   if (!Expr.empty()) {
38392987fb3SAlexander Kornienko     if (Expr[0] == '+')
38492987fb3SAlexander Kornienko       Expr = Expr.substr(1);
38592987fb3SAlexander Kornienko     else if (Expr[0] != '-')
38692987fb3SAlexander Kornienko       return false;
38792987fb3SAlexander Kornienko     if (Expr.getAsInteger(10, Offset))
38892987fb3SAlexander Kornienko       return false;
38992987fb3SAlexander Kornienko   }
39092987fb3SAlexander Kornienko   Value = llvm::itostr(LineNumber + Offset);
39192987fb3SAlexander Kornienko   return true;
39292987fb3SAlexander Kornienko }
39392987fb3SAlexander Kornienko 
394f08d2db9SChris Lattner /// Match - Match the pattern string against the input buffer Buffer.  This
395f08d2db9SChris Lattner /// returns the position that is matched or npos if there is no match.  If
396f08d2db9SChris Lattner /// there is a match, the size of the matched string is returned in MatchLen.
3978879e06dSChris Lattner size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
3988879e06dSChris Lattner                       StringMap<StringRef> &VariableTable) const {
399eba55822SJakob Stoklund Olesen   // If this is the EOF pattern, match it immediately.
40038820972SMatt Arsenault   if (CheckTy == Check::CheckEOF) {
401eba55822SJakob Stoklund Olesen     MatchLen = 0;
402eba55822SJakob Stoklund Olesen     return Buffer.size();
403eba55822SJakob Stoklund Olesen   }
404eba55822SJakob Stoklund Olesen 
405221460e0SChris Lattner   // If this is a fixed string pattern, just match it now.
406221460e0SChris Lattner   if (!FixedStr.empty()) {
407221460e0SChris Lattner     MatchLen = FixedStr.size();
408221460e0SChris Lattner     return Buffer.find(FixedStr);
409221460e0SChris Lattner   }
410221460e0SChris Lattner 
411b16ab0c4SChris Lattner   // Regex match.
4128879e06dSChris Lattner 
4138879e06dSChris Lattner   // If there are variable uses, we need to create a temporary string with the
4148879e06dSChris Lattner   // actual value.
4158879e06dSChris Lattner   StringRef RegExToMatch = RegExStr;
4168879e06dSChris Lattner   std::string TmpStr;
4178879e06dSChris Lattner   if (!VariableUses.empty()) {
4188879e06dSChris Lattner     TmpStr = RegExStr;
4198879e06dSChris Lattner 
4208879e06dSChris Lattner     unsigned InsertOffset = 0;
4218f870499SBenjamin Kramer     for (const auto &VariableUse : VariableUses) {
42292987fb3SAlexander Kornienko       std::string Value;
42392987fb3SAlexander Kornienko 
4248f870499SBenjamin Kramer       if (VariableUse.first[0] == '@') {
4258f870499SBenjamin Kramer         if (!EvaluateExpression(VariableUse.first, Value))
42692987fb3SAlexander Kornienko           return StringRef::npos;
42792987fb3SAlexander Kornienko       } else {
428e0ef65abSDaniel Dunbar         StringMap<StringRef>::iterator it =
4298f870499SBenjamin Kramer             VariableTable.find(VariableUse.first);
430e0ef65abSDaniel Dunbar         // If the variable is undefined, return an error.
431e0ef65abSDaniel Dunbar         if (it == VariableTable.end())
432e0ef65abSDaniel Dunbar           return StringRef::npos;
433e0ef65abSDaniel Dunbar 
4346f4f77b7SHans Wennborg         // Look up the value and escape it so that we can put it into the regex.
4356f4f77b7SHans Wennborg         Value += Regex::escape(it->second);
43692987fb3SAlexander Kornienko       }
4378879e06dSChris Lattner 
4388879e06dSChris Lattner       // Plop it into the regex at the adjusted offset.
4398f870499SBenjamin Kramer       TmpStr.insert(TmpStr.begin() + VariableUse.second + InsertOffset,
4408879e06dSChris Lattner                     Value.begin(), Value.end());
4418879e06dSChris Lattner       InsertOffset += Value.size();
4428879e06dSChris Lattner     }
4438879e06dSChris Lattner 
4448879e06dSChris Lattner     // Match the newly constructed regex.
4458879e06dSChris Lattner     RegExToMatch = TmpStr;
4468879e06dSChris Lattner   }
4478879e06dSChris Lattner 
448b16ab0c4SChris Lattner   SmallVector<StringRef, 4> MatchInfo;
4498879e06dSChris Lattner   if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
450f08d2db9SChris Lattner     return StringRef::npos;
451b16ab0c4SChris Lattner 
452b16ab0c4SChris Lattner   // Successful regex match.
453b16ab0c4SChris Lattner   assert(!MatchInfo.empty() && "Didn't get any match");
454b16ab0c4SChris Lattner   StringRef FullMatch = MatchInfo[0];
455b16ab0c4SChris Lattner 
4568879e06dSChris Lattner   // If this defines any variables, remember their values.
4578f870499SBenjamin Kramer   for (const auto &VariableDef : VariableDefs) {
4588f870499SBenjamin Kramer     assert(VariableDef.second < MatchInfo.size() && "Internal paren error");
4598f870499SBenjamin Kramer     VariableTable[VariableDef.first] = MatchInfo[VariableDef.second];
4600a4c44bdSChris Lattner   }
4610a4c44bdSChris Lattner 
462b16ab0c4SChris Lattner   MatchLen = FullMatch.size();
463b16ab0c4SChris Lattner   return FullMatch.data() - Buffer.data();
464f08d2db9SChris Lattner }
465f08d2db9SChris Lattner 
466*e8f2fb20SChandler Carruth unsigned
467*e8f2fb20SChandler Carruth Pattern::ComputeMatchDistance(StringRef Buffer,
468fd29d886SDaniel Dunbar                               const StringMap<StringRef> &VariableTable) const {
469fd29d886SDaniel Dunbar   // Just compute the number of matching characters. For regular expressions, we
470fd29d886SDaniel Dunbar   // just compare against the regex itself and hope for the best.
471fd29d886SDaniel Dunbar   //
472fd29d886SDaniel Dunbar   // FIXME: One easy improvement here is have the regex lib generate a single
473fd29d886SDaniel Dunbar   // example regular expression which matches, and use that as the example
474fd29d886SDaniel Dunbar   // string.
475fd29d886SDaniel Dunbar   StringRef ExampleString(FixedStr);
476fd29d886SDaniel Dunbar   if (ExampleString.empty())
477fd29d886SDaniel Dunbar     ExampleString = RegExStr;
478fd29d886SDaniel Dunbar 
479e9aa36c8SDaniel Dunbar   // Only compare up to the first line in the buffer, or the string size.
480e9aa36c8SDaniel Dunbar   StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
481e9aa36c8SDaniel Dunbar   BufferPrefix = BufferPrefix.split('\n').first;
482e9aa36c8SDaniel Dunbar   return BufferPrefix.edit_distance(ExampleString);
483fd29d886SDaniel Dunbar }
484fd29d886SDaniel Dunbar 
485*e8f2fb20SChandler Carruth void Pattern::PrintFailureInfo(
486*e8f2fb20SChandler Carruth     const SourceMgr &SM, StringRef Buffer,
487e0ef65abSDaniel Dunbar     const StringMap<StringRef> &VariableTable) const {
488e0ef65abSDaniel Dunbar   // If this was a regular expression using variables, print the current
489e0ef65abSDaniel Dunbar   // variable values.
490e0ef65abSDaniel Dunbar   if (!VariableUses.empty()) {
4918f870499SBenjamin Kramer     for (const auto &VariableUse : VariableUses) {
492e69170a1SAlp Toker       SmallString<256> Msg;
493e69170a1SAlp Toker       raw_svector_ostream OS(Msg);
4948f870499SBenjamin Kramer       StringRef Var = VariableUse.first;
49592987fb3SAlexander Kornienko       if (Var[0] == '@') {
49692987fb3SAlexander Kornienko         std::string Value;
49792987fb3SAlexander Kornienko         if (EvaluateExpression(Var, Value)) {
49892987fb3SAlexander Kornienko           OS << "with expression \"";
49992987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\" equal to \"";
50092987fb3SAlexander Kornienko           OS.write_escaped(Value) << "\"";
50192987fb3SAlexander Kornienko         } else {
50292987fb3SAlexander Kornienko           OS << "uses incorrect expression \"";
50392987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
50492987fb3SAlexander Kornienko         }
50592987fb3SAlexander Kornienko       } else {
50692987fb3SAlexander Kornienko         StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
507e0ef65abSDaniel Dunbar 
508e0ef65abSDaniel Dunbar         // Check for undefined variable references.
509e0ef65abSDaniel Dunbar         if (it == VariableTable.end()) {
510e0ef65abSDaniel Dunbar           OS << "uses undefined variable \"";
51192987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
512e0ef65abSDaniel Dunbar         } else {
513e0ef65abSDaniel Dunbar           OS << "with variable \"";
514e0ef65abSDaniel Dunbar           OS.write_escaped(Var) << "\" equal to \"";
515e0ef65abSDaniel Dunbar           OS.write_escaped(it->second) << "\"";
516e0ef65abSDaniel Dunbar         }
51792987fb3SAlexander Kornienko       }
518e0ef65abSDaniel Dunbar 
51903b80a40SChris Lattner       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
52003b80a40SChris Lattner                       OS.str());
521e0ef65abSDaniel Dunbar     }
522e0ef65abSDaniel Dunbar   }
523fd29d886SDaniel Dunbar 
524fd29d886SDaniel Dunbar   // Attempt to find the closest/best fuzzy match.  Usually an error happens
525fd29d886SDaniel Dunbar   // because some string in the output didn't exactly match. In these cases, we
526fd29d886SDaniel Dunbar   // would like to show the user a best guess at what "should have" matched, to
527fd29d886SDaniel Dunbar   // save them having to actually check the input manually.
528fd29d886SDaniel Dunbar   size_t NumLinesForward = 0;
529fd29d886SDaniel Dunbar   size_t Best = StringRef::npos;
530fd29d886SDaniel Dunbar   double BestQuality = 0;
531fd29d886SDaniel Dunbar 
532fd29d886SDaniel Dunbar   // Use an arbitrary 4k limit on how far we will search.
5332bf486ebSDan Gohman   for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
534fd29d886SDaniel Dunbar     if (Buffer[i] == '\n')
535fd29d886SDaniel Dunbar       ++NumLinesForward;
536fd29d886SDaniel Dunbar 
537df22bbf7SDan Gohman     // Patterns have leading whitespace stripped, so skip whitespace when
538df22bbf7SDan Gohman     // looking for something which looks like a pattern.
539df22bbf7SDan Gohman     if (Buffer[i] == ' ' || Buffer[i] == '\t')
540df22bbf7SDan Gohman       continue;
541df22bbf7SDan Gohman 
542fd29d886SDaniel Dunbar     // Compute the "quality" of this match as an arbitrary combination of the
543fd29d886SDaniel Dunbar     // match distance and the number of lines skipped to get to this match.
544fd29d886SDaniel Dunbar     unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
545fd29d886SDaniel Dunbar     double Quality = Distance + (NumLinesForward / 100.);
546fd29d886SDaniel Dunbar 
547fd29d886SDaniel Dunbar     if (Quality < BestQuality || Best == StringRef::npos) {
548fd29d886SDaniel Dunbar       Best = i;
549fd29d886SDaniel Dunbar       BestQuality = Quality;
550fd29d886SDaniel Dunbar     }
551fd29d886SDaniel Dunbar   }
552fd29d886SDaniel Dunbar 
553fd29d886SDaniel Dunbar   // Print the "possible intended match here" line if we found something
554c069cc8eSDaniel Dunbar   // reasonable and not equal to what we showed in the "scanning from here"
555c069cc8eSDaniel Dunbar   // line.
556c069cc8eSDaniel Dunbar   if (Best && Best != StringRef::npos && BestQuality < 50) {
557fd29d886SDaniel Dunbar     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
55803b80a40SChris Lattner                     SourceMgr::DK_Note, "possible intended match here");
559fd29d886SDaniel Dunbar 
560fd29d886SDaniel Dunbar     // FIXME: If we wanted to be really friendly we would show why the match
561fd29d886SDaniel Dunbar     // failed, as it can be hard to spot simple one character differences.
562fd29d886SDaniel Dunbar   }
563e0ef65abSDaniel Dunbar }
56474d50731SChris Lattner 
56581e5cd9eSAdrian Prantl size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
566061d2baaSEli Bendersky   // Offset keeps track of the current offset within the input Str
567061d2baaSEli Bendersky   size_t Offset = 0;
568061d2baaSEli Bendersky   // [...] Nesting depth
569061d2baaSEli Bendersky   size_t BracketDepth = 0;
570061d2baaSEli Bendersky 
571061d2baaSEli Bendersky   while (!Str.empty()) {
572061d2baaSEli Bendersky     if (Str.startswith("]]") && BracketDepth == 0)
573061d2baaSEli Bendersky       return Offset;
574061d2baaSEli Bendersky     if (Str[0] == '\\') {
575061d2baaSEli Bendersky       // Backslash escapes the next char within regexes, so skip them both.
576061d2baaSEli Bendersky       Str = Str.substr(2);
577061d2baaSEli Bendersky       Offset += 2;
578061d2baaSEli Bendersky     } else {
579061d2baaSEli Bendersky       switch (Str[0]) {
580061d2baaSEli Bendersky       default:
581061d2baaSEli Bendersky         break;
582061d2baaSEli Bendersky       case '[':
583061d2baaSEli Bendersky         BracketDepth++;
584061d2baaSEli Bendersky         break;
585061d2baaSEli Bendersky       case ']':
58681e5cd9eSAdrian Prantl         if (BracketDepth == 0) {
58781e5cd9eSAdrian Prantl           SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
58881e5cd9eSAdrian Prantl                           SourceMgr::DK_Error,
58981e5cd9eSAdrian Prantl                           "missing closing \"]\" for regex variable");
59081e5cd9eSAdrian Prantl           exit(1);
59181e5cd9eSAdrian Prantl         }
592061d2baaSEli Bendersky         BracketDepth--;
593061d2baaSEli Bendersky         break;
594061d2baaSEli Bendersky       }
595061d2baaSEli Bendersky       Str = Str.substr(1);
596061d2baaSEli Bendersky       Offset++;
597061d2baaSEli Bendersky     }
598061d2baaSEli Bendersky   }
599061d2baaSEli Bendersky 
600061d2baaSEli Bendersky   return StringRef::npos;
601061d2baaSEli Bendersky }
602061d2baaSEli Bendersky 
60374d50731SChris Lattner //===----------------------------------------------------------------------===//
60474d50731SChris Lattner // Check Strings.
60574d50731SChris Lattner //===----------------------------------------------------------------------===//
6063b40b445SChris Lattner 
6073b40b445SChris Lattner /// CheckString - This is a check that we found in the input file.
6083b40b445SChris Lattner struct CheckString {
6093b40b445SChris Lattner   /// Pat - The pattern to match.
6103b40b445SChris Lattner   Pattern Pat;
61126cccfe1SChris Lattner 
61213df4626SMatt Arsenault   /// Prefix - Which prefix name this check matched.
61313df4626SMatt Arsenault   StringRef Prefix;
61413df4626SMatt Arsenault 
61526cccfe1SChris Lattner   /// Loc - The location in the match file that the check string was specified.
61626cccfe1SChris Lattner   SMLoc Loc;
61726cccfe1SChris Lattner 
61838820972SMatt Arsenault   /// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive,
61938820972SMatt Arsenault   /// as opposed to a CHECK: directive.
62085913ccaSJames Y Knight   //  Check::CheckType CheckTy;
621f8bd2e5bSStephen Lin 
62291a1b2c9SMichael Liao   /// DagNotStrings - These are all of the strings that are disallowed from
623236d2d5eSChris Lattner   /// occurring between this match string and the previous one (or start of
624236d2d5eSChris Lattner   /// file).
62591a1b2c9SMichael Liao   std::vector<Pattern> DagNotStrings;
626236d2d5eSChris Lattner 
62785913ccaSJames Y Knight   CheckString(const Pattern &P, StringRef S, SMLoc L)
62885913ccaSJames Y Knight       : Pat(P), Prefix(S), Loc(L) {}
629dcc7d48dSMichael Liao 
63091a1b2c9SMichael Liao   /// Check - Match check string and its "not strings" and/or "dag strings".
631e93a3a08SStephen Lin   size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
632f8bd2e5bSStephen Lin                size_t &MatchLen, StringMap<StringRef> &VariableTable) const;
633dcc7d48dSMichael Liao 
634dcc7d48dSMichael Liao   /// CheckNext - Verify there is a single line in the given buffer.
635dcc7d48dSMichael Liao   bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
636dcc7d48dSMichael Liao 
63701ac1707SDuncan P. N. Exon Smith   /// CheckSame - Verify there is no newline in the given buffer.
63801ac1707SDuncan P. N. Exon Smith   bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
63901ac1707SDuncan P. N. Exon Smith 
640dcc7d48dSMichael Liao   /// CheckNot - Verify there's no "not strings" in the given buffer.
641dcc7d48dSMichael Liao   bool CheckNot(const SourceMgr &SM, StringRef Buffer,
64291a1b2c9SMichael Liao                 const std::vector<const Pattern *> &NotStrings,
64391a1b2c9SMichael Liao                 StringMap<StringRef> &VariableTable) const;
64491a1b2c9SMichael Liao 
64591a1b2c9SMichael Liao   /// CheckDag - Match "dag strings" and their mixed "not strings".
64691a1b2c9SMichael Liao   size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
64791a1b2c9SMichael Liao                   std::vector<const Pattern *> &NotStrings,
648dcc7d48dSMichael Liao                   StringMap<StringRef> &VariableTable) const;
64926cccfe1SChris Lattner };
65026cccfe1SChris Lattner 
65120247900SChandler Carruth /// Canonicalize whitespaces in the file. Line endings are replaced with
65220247900SChandler Carruth /// UNIX-style '\n'.
6535ea04c38SGuy Benyei ///
6545ea04c38SGuy Benyei /// \param PreserveHorizontal Don't squash consecutive horizontal whitespace
6555ea04c38SGuy Benyei /// characters to a single space.
65620247900SChandler Carruth static StringRef CanonicalizeFile(MemoryBuffer &MB, bool PreserveHorizontal,
65720247900SChandler Carruth                                   SmallVectorImpl<char> &OutputBuffer) {
65820247900SChandler Carruth   OutputBuffer.reserve(MB.getBufferSize());
659a2f8fc5aSChris Lattner 
66020247900SChandler Carruth   for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd();
661a2f8fc5aSChris Lattner        Ptr != End; ++Ptr) {
662fd781bf0SNAKAMURA Takumi     // Eliminate trailing dosish \r.
663fd781bf0SNAKAMURA Takumi     if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
664fd781bf0SNAKAMURA Takumi       continue;
665fd781bf0SNAKAMURA Takumi     }
666fd781bf0SNAKAMURA Takumi 
6675ea04c38SGuy Benyei     // If current char is not a horizontal whitespace or if horizontal
6685ea04c38SGuy Benyei     // whitespace canonicalization is disabled, dump it to output as is.
6695ea04c38SGuy Benyei     if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) {
67020247900SChandler Carruth       OutputBuffer.push_back(*Ptr);
671a2f8fc5aSChris Lattner       continue;
672a2f8fc5aSChris Lattner     }
673a2f8fc5aSChris Lattner 
674a2f8fc5aSChris Lattner     // Otherwise, add one space and advance over neighboring space.
67520247900SChandler Carruth     OutputBuffer.push_back(' ');
676*e8f2fb20SChandler Carruth     while (Ptr + 1 != End && (Ptr[1] == ' ' || Ptr[1] == '\t'))
677a2f8fc5aSChris Lattner       ++Ptr;
678a2f8fc5aSChris Lattner   }
679a2f8fc5aSChris Lattner 
68020247900SChandler Carruth   // Add a null byte and then return all but that byte.
68120247900SChandler Carruth   OutputBuffer.push_back('\0');
68220247900SChandler Carruth   return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
683a2f8fc5aSChris Lattner }
684a2f8fc5aSChris Lattner 
68538820972SMatt Arsenault static bool IsPartOfWord(char c) {
68638820972SMatt Arsenault   return (isalnum(c) || c == '-' || c == '_');
68738820972SMatt Arsenault }
68838820972SMatt Arsenault 
68913df4626SMatt Arsenault // Get the size of the prefix extension.
69013df4626SMatt Arsenault static size_t CheckTypeSize(Check::CheckType Ty) {
69113df4626SMatt Arsenault   switch (Ty) {
69213df4626SMatt Arsenault   case Check::CheckNone:
693a908e7bdSPaul Robinson   case Check::CheckBadNot:
69413df4626SMatt Arsenault     return 0;
69513df4626SMatt Arsenault 
69613df4626SMatt Arsenault   case Check::CheckPlain:
69713df4626SMatt Arsenault     return sizeof(":") - 1;
69813df4626SMatt Arsenault 
69913df4626SMatt Arsenault   case Check::CheckNext:
70013df4626SMatt Arsenault     return sizeof("-NEXT:") - 1;
70113df4626SMatt Arsenault 
70201ac1707SDuncan P. N. Exon Smith   case Check::CheckSame:
70301ac1707SDuncan P. N. Exon Smith     return sizeof("-SAME:") - 1;
70401ac1707SDuncan P. N. Exon Smith 
70513df4626SMatt Arsenault   case Check::CheckNot:
70613df4626SMatt Arsenault     return sizeof("-NOT:") - 1;
70713df4626SMatt Arsenault 
70813df4626SMatt Arsenault   case Check::CheckDAG:
70913df4626SMatt Arsenault     return sizeof("-DAG:") - 1;
71013df4626SMatt Arsenault 
71113df4626SMatt Arsenault   case Check::CheckLabel:
71213df4626SMatt Arsenault     return sizeof("-LABEL:") - 1;
71313df4626SMatt Arsenault 
71413df4626SMatt Arsenault   case Check::CheckEOF:
71513df4626SMatt Arsenault     llvm_unreachable("Should not be using EOF size");
71613df4626SMatt Arsenault   }
71713df4626SMatt Arsenault 
71813df4626SMatt Arsenault   llvm_unreachable("Bad check type");
71913df4626SMatt Arsenault }
72013df4626SMatt Arsenault 
72113df4626SMatt Arsenault static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
722c4d2d471SMatt Arsenault   char NextChar = Buffer[Prefix.size()];
72338820972SMatt Arsenault 
72438820972SMatt Arsenault   // Verify that the : is present after the prefix.
72513df4626SMatt Arsenault   if (NextChar == ':')
72638820972SMatt Arsenault     return Check::CheckPlain;
72738820972SMatt Arsenault 
72813df4626SMatt Arsenault   if (NextChar != '-')
72938820972SMatt Arsenault     return Check::CheckNone;
73038820972SMatt Arsenault 
731c4d2d471SMatt Arsenault   StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
73213df4626SMatt Arsenault   if (Rest.startswith("NEXT:"))
73338820972SMatt Arsenault     return Check::CheckNext;
73438820972SMatt Arsenault 
73501ac1707SDuncan P. N. Exon Smith   if (Rest.startswith("SAME:"))
73601ac1707SDuncan P. N. Exon Smith     return Check::CheckSame;
73701ac1707SDuncan P. N. Exon Smith 
73813df4626SMatt Arsenault   if (Rest.startswith("NOT:"))
73938820972SMatt Arsenault     return Check::CheckNot;
74038820972SMatt Arsenault 
74113df4626SMatt Arsenault   if (Rest.startswith("DAG:"))
74238820972SMatt Arsenault     return Check::CheckDAG;
74338820972SMatt Arsenault 
74413df4626SMatt Arsenault   if (Rest.startswith("LABEL:"))
74538820972SMatt Arsenault     return Check::CheckLabel;
74613df4626SMatt Arsenault 
747a908e7bdSPaul Robinson   // You can't combine -NOT with another suffix.
748a908e7bdSPaul Robinson   if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
749a908e7bdSPaul Robinson       Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
750a908e7bdSPaul Robinson       Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:"))
751a908e7bdSPaul Robinson     return Check::CheckBadNot;
752a908e7bdSPaul Robinson 
75313df4626SMatt Arsenault   return Check::CheckNone;
75438820972SMatt Arsenault }
75538820972SMatt Arsenault 
75613df4626SMatt Arsenault // From the given position, find the next character after the word.
75713df4626SMatt Arsenault static size_t SkipWord(StringRef Str, size_t Loc) {
75813df4626SMatt Arsenault   while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
75913df4626SMatt Arsenault     ++Loc;
76013df4626SMatt Arsenault   return Loc;
76113df4626SMatt Arsenault }
76213df4626SMatt Arsenault 
76313df4626SMatt Arsenault // Try to find the first match in buffer for any prefix. If a valid match is
76413df4626SMatt Arsenault // found, return that prefix and set its type and location.  If there are almost
76513df4626SMatt Arsenault // matches (e.g. the actual prefix string is found, but is not an actual check
76613df4626SMatt Arsenault // string), but no valid match, return an empty string and set the position to
76713df4626SMatt Arsenault // resume searching from. If no partial matches are found, return an empty
76813df4626SMatt Arsenault // string and the location will be StringRef::npos. If one prefix is a substring
76913df4626SMatt Arsenault // of another, the maximal match should be found. e.g. if "A" and "AA" are
77013df4626SMatt Arsenault // prefixes then AA-CHECK: should match the second one.
77113df4626SMatt Arsenault static StringRef FindFirstCandidateMatch(StringRef &Buffer,
77213df4626SMatt Arsenault                                          Check::CheckType &CheckTy,
77313df4626SMatt Arsenault                                          size_t &CheckLoc) {
77413df4626SMatt Arsenault   StringRef FirstPrefix;
77513df4626SMatt Arsenault   size_t FirstLoc = StringRef::npos;
77613df4626SMatt Arsenault   size_t SearchLoc = StringRef::npos;
77713df4626SMatt Arsenault   Check::CheckType FirstTy = Check::CheckNone;
77813df4626SMatt Arsenault 
77913df4626SMatt Arsenault   CheckTy = Check::CheckNone;
78013df4626SMatt Arsenault   CheckLoc = StringRef::npos;
78113df4626SMatt Arsenault 
7828f870499SBenjamin Kramer   for (StringRef Prefix : CheckPrefixes) {
78313df4626SMatt Arsenault     size_t PrefixLoc = Buffer.find(Prefix);
78413df4626SMatt Arsenault 
78513df4626SMatt Arsenault     if (PrefixLoc == StringRef::npos)
78613df4626SMatt Arsenault       continue;
78713df4626SMatt Arsenault 
78813df4626SMatt Arsenault     // Track where we are searching for invalid prefixes that look almost right.
78913df4626SMatt Arsenault     // We need to only advance to the first partial match on the next attempt
79013df4626SMatt Arsenault     // since a partial match could be a substring of a later, valid prefix.
79113df4626SMatt Arsenault     // Need to skip to the end of the word, otherwise we could end up
79213df4626SMatt Arsenault     // matching a prefix in a substring later.
79313df4626SMatt Arsenault     if (PrefixLoc < SearchLoc)
79413df4626SMatt Arsenault       SearchLoc = SkipWord(Buffer, PrefixLoc);
79513df4626SMatt Arsenault 
79613df4626SMatt Arsenault     // We only want to find the first match to avoid skipping some.
79713df4626SMatt Arsenault     if (PrefixLoc > FirstLoc)
79813df4626SMatt Arsenault       continue;
799a7181a1bSAlexey Samsonov     // If one matching check-prefix is a prefix of another, choose the
800a7181a1bSAlexey Samsonov     // longer one.
801a7181a1bSAlexey Samsonov     if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size())
802a7181a1bSAlexey Samsonov       continue;
80313df4626SMatt Arsenault 
80413df4626SMatt Arsenault     StringRef Rest = Buffer.drop_front(PrefixLoc);
80513df4626SMatt Arsenault     // Make sure we have actually found the prefix, and not a word containing
80613df4626SMatt Arsenault     // it. This should also prevent matching the wrong prefix when one is a
80713df4626SMatt Arsenault     // substring of another.
80813df4626SMatt Arsenault     if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
80943b5f572SDaniel Sanders       FirstTy = Check::CheckNone;
81043b5f572SDaniel Sanders     else
81143b5f572SDaniel Sanders       FirstTy = FindCheckType(Rest, Prefix);
81213df4626SMatt Arsenault 
81313df4626SMatt Arsenault     FirstLoc = PrefixLoc;
814a7181a1bSAlexey Samsonov     FirstPrefix = Prefix;
81513df4626SMatt Arsenault   }
81613df4626SMatt Arsenault 
817a7181a1bSAlexey Samsonov   // If the first prefix is invalid, we should continue the search after it.
818a7181a1bSAlexey Samsonov   if (FirstTy == Check::CheckNone) {
81913df4626SMatt Arsenault     CheckLoc = SearchLoc;
820a7181a1bSAlexey Samsonov     return "";
821a7181a1bSAlexey Samsonov   }
822a7181a1bSAlexey Samsonov 
82313df4626SMatt Arsenault   CheckTy = FirstTy;
82413df4626SMatt Arsenault   CheckLoc = FirstLoc;
82513df4626SMatt Arsenault   return FirstPrefix;
82613df4626SMatt Arsenault }
82713df4626SMatt Arsenault 
82813df4626SMatt Arsenault static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
82913df4626SMatt Arsenault                                          unsigned &LineNumber,
83013df4626SMatt Arsenault                                          Check::CheckType &CheckTy,
83113df4626SMatt Arsenault                                          size_t &CheckLoc) {
83213df4626SMatt Arsenault   while (!Buffer.empty()) {
83313df4626SMatt Arsenault     StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc);
83413df4626SMatt Arsenault     // If we found a real match, we are done.
83513df4626SMatt Arsenault     if (!Prefix.empty()) {
83613df4626SMatt Arsenault       LineNumber += Buffer.substr(0, CheckLoc).count('\n');
83713df4626SMatt Arsenault       return Prefix;
83813df4626SMatt Arsenault     }
83913df4626SMatt Arsenault 
84013df4626SMatt Arsenault     // We didn't find any almost matches either, we are also done.
84113df4626SMatt Arsenault     if (CheckLoc == StringRef::npos)
84213df4626SMatt Arsenault       return StringRef();
84313df4626SMatt Arsenault 
84413df4626SMatt Arsenault     LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
84513df4626SMatt Arsenault 
84613df4626SMatt Arsenault     // Advance to the last possible match we found and try again.
84713df4626SMatt Arsenault     Buffer = Buffer.drop_front(CheckLoc + 1);
84813df4626SMatt Arsenault   }
84913df4626SMatt Arsenault 
85013df4626SMatt Arsenault   return StringRef();
85138820972SMatt Arsenault }
852ee3c74fbSChris Lattner 
853ee3c74fbSChris Lattner /// ReadCheckFile - Read the check file, which specifies the sequence of
854ee3c74fbSChris Lattner /// expected strings.  The strings are added to the CheckStrings vector.
85543d50d4aSEli Bendersky /// Returns true in case of an error, false otherwise.
85620247900SChandler Carruth static bool ReadCheckFile(SourceMgr &SM, StringRef Buffer,
85726cccfe1SChris Lattner                           std::vector<CheckString> &CheckStrings) {
85856ccdbbdSAlexander Kornienko   std::vector<Pattern> ImplicitNegativeChecks;
85956ccdbbdSAlexander Kornienko   for (const auto &PatternString : ImplicitCheckNot) {
86056ccdbbdSAlexander Kornienko     // Create a buffer with fake command line content in order to display the
86156ccdbbdSAlexander Kornienko     // command line option responsible for the specific implicit CHECK-NOT.
862ff43d69dSDavid Blaikie     std::string Prefix = (Twine("-") + ImplicitCheckNot.ArgStr + "='").str();
86356ccdbbdSAlexander Kornienko     std::string Suffix = "'";
8643560ff2cSRafael Espindola     std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
8653560ff2cSRafael Espindola         Prefix + PatternString + Suffix, "command line");
8663560ff2cSRafael Espindola 
86756ccdbbdSAlexander Kornienko     StringRef PatternInBuffer =
86856ccdbbdSAlexander Kornienko         CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
8691961f14cSDavid Blaikie     SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
87056ccdbbdSAlexander Kornienko 
87156ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
87256ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
87356ccdbbdSAlexander Kornienko                                                "IMPLICIT-CHECK", SM, 0);
87456ccdbbdSAlexander Kornienko   }
87556ccdbbdSAlexander Kornienko 
87656ccdbbdSAlexander Kornienko   std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
877236d2d5eSChris Lattner 
87843d50d4aSEli Bendersky   // LineNumber keeps track of the line on which CheckPrefix instances are
87943d50d4aSEli Bendersky   // found.
88092987fb3SAlexander Kornienko   unsigned LineNumber = 1;
88192987fb3SAlexander Kornienko 
882ee3c74fbSChris Lattner   while (1) {
88313df4626SMatt Arsenault     Check::CheckType CheckTy;
88413df4626SMatt Arsenault     size_t PrefixLoc;
88513df4626SMatt Arsenault 
88613df4626SMatt Arsenault     // See if a prefix occurs in the memory buffer.
887*e8f2fb20SChandler Carruth     StringRef UsedPrefix =
888*e8f2fb20SChandler Carruth         FindFirstMatchingPrefix(Buffer, LineNumber, CheckTy, PrefixLoc);
88913df4626SMatt Arsenault     if (UsedPrefix.empty())
890ee3c74fbSChris Lattner       break;
891ee3c74fbSChris Lattner 
89213df4626SMatt Arsenault     Buffer = Buffer.drop_front(PrefixLoc);
89392987fb3SAlexander Kornienko 
89413df4626SMatt Arsenault     // Location to use for error messages.
89513df4626SMatt Arsenault     const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
89692987fb3SAlexander Kornienko 
89713df4626SMatt Arsenault     // PrefixLoc is to the start of the prefix. Skip to the end.
89813df4626SMatt Arsenault     Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
89910f10cedSChris Lattner 
900a908e7bdSPaul Robinson     // Complain about useful-looking but unsupported suffixes.
901a908e7bdSPaul Robinson     if (CheckTy == Check::CheckBadNot) {
902*e8f2fb20SChandler Carruth       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Error,
903a908e7bdSPaul Robinson                       "unsupported -NOT combo on prefix '" + UsedPrefix + "'");
904a908e7bdSPaul Robinson       return true;
905a908e7bdSPaul Robinson     }
906a908e7bdSPaul Robinson 
90738820972SMatt Arsenault     // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
90838820972SMatt Arsenault     // leading and trailing whitespace.
909236d2d5eSChris Lattner     Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
910ee3c74fbSChris Lattner 
911ee3c74fbSChris Lattner     // Scan ahead to the end of line.
912caa5fc0cSChris Lattner     size_t EOL = Buffer.find_first_of("\n\r");
913ee3c74fbSChris Lattner 
914838fb09aSDan Gohman     // Remember the location of the start of the pattern, for diagnostics.
915838fb09aSDan Gohman     SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
916838fb09aSDan Gohman 
91774d50731SChris Lattner     // Parse the pattern.
91838820972SMatt Arsenault     Pattern P(CheckTy);
91913df4626SMatt Arsenault     if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
920ee3c74fbSChris Lattner       return true;
921ee3c74fbSChris Lattner 
922f8bd2e5bSStephen Lin     // Verify that CHECK-LABEL lines do not define or use variables
92338820972SMatt Arsenault     if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
924*e8f2fb20SChandler Carruth       SM.PrintMessage(
925*e8f2fb20SChandler Carruth           SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error,
92613df4626SMatt Arsenault           "found '" + UsedPrefix + "-LABEL:'"
92713df4626SMatt Arsenault                                    " with variable definition or use");
928f8bd2e5bSStephen Lin       return true;
929f8bd2e5bSStephen Lin     }
930f8bd2e5bSStephen Lin 
931236d2d5eSChris Lattner     Buffer = Buffer.substr(EOL);
93274d50731SChris Lattner 
933da108b4eSChris Lattner     // Verify that CHECK-NEXT lines have at least one CHECK line before them.
93401ac1707SDuncan P. N. Exon Smith     if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&
93501ac1707SDuncan P. N. Exon Smith         CheckStrings.empty()) {
93601ac1707SDuncan P. N. Exon Smith       StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";
93713df4626SMatt Arsenault       SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
93803b80a40SChris Lattner                       SourceMgr::DK_Error,
939*e8f2fb20SChandler Carruth                       "found '" + UsedPrefix + "-" + Type +
940*e8f2fb20SChandler Carruth                           "' without previous '" + UsedPrefix + ": line");
941da108b4eSChris Lattner       return true;
942da108b4eSChris Lattner     }
943da108b4eSChris Lattner 
94491a1b2c9SMichael Liao     // Handle CHECK-DAG/-NOT.
94538820972SMatt Arsenault     if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
94691a1b2c9SMichael Liao       DagNotMatches.push_back(P);
94774d50731SChris Lattner       continue;
94874d50731SChris Lattner     }
94974d50731SChris Lattner 
950ee3c74fbSChris Lattner     // Okay, add the string we captured to the output vector and move on.
95185913ccaSJames Y Knight     CheckStrings.emplace_back(P, UsedPrefix, PatternLoc);
95291a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
95356ccdbbdSAlexander Kornienko     DagNotMatches = ImplicitNegativeChecks;
954ee3c74fbSChris Lattner   }
955ee3c74fbSChris Lattner 
95613df4626SMatt Arsenault   // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
95713df4626SMatt Arsenault   // prefix as a filler for the error message.
95891a1b2c9SMichael Liao   if (!DagNotMatches.empty()) {
959f5e2fc47SBenjamin Kramer     CheckStrings.emplace_back(Pattern(Check::CheckEOF), *CheckPrefixes.begin(),
96085913ccaSJames Y Knight                               SMLoc::getFromPointer(Buffer.data()));
96191a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
962eba55822SJakob Stoklund Olesen   }
963eba55822SJakob Stoklund Olesen 
964ee3c74fbSChris Lattner   if (CheckStrings.empty()) {
96513df4626SMatt Arsenault     errs() << "error: no check strings found with prefix"
96613df4626SMatt Arsenault            << (CheckPrefixes.size() > 1 ? "es " : " ");
9673e3ef2f2SChris Bieneman     prefix_iterator I = CheckPrefixes.begin();
9683e3ef2f2SChris Bieneman     prefix_iterator E = CheckPrefixes.end();
9693e3ef2f2SChris Bieneman     if (I != E) {
9703e3ef2f2SChris Bieneman       errs() << "\'" << *I << ":'";
9713e3ef2f2SChris Bieneman       ++I;
97213df4626SMatt Arsenault     }
9733e3ef2f2SChris Bieneman     for (; I != E; ++I)
9743e3ef2f2SChris Bieneman       errs() << ", \'" << *I << ":'";
97513df4626SMatt Arsenault 
97613df4626SMatt Arsenault     errs() << '\n';
977ee3c74fbSChris Lattner     return true;
978ee3c74fbSChris Lattner   }
979ee3c74fbSChris Lattner 
980ee3c74fbSChris Lattner   return false;
981ee3c74fbSChris Lattner }
982ee3c74fbSChris Lattner 
983*e8f2fb20SChandler Carruth static void PrintCheckFailed(const SourceMgr &SM, SMLoc Loc, const Pattern &Pat,
984*e8f2fb20SChandler Carruth                              StringRef Buffer,
985e0ef65abSDaniel Dunbar                              StringMap<StringRef> &VariableTable) {
986da108b4eSChris Lattner   // Otherwise, we have an error, emit an error message.
98791a1b2c9SMichael Liao   SM.PrintMessage(Loc, SourceMgr::DK_Error,
98803b80a40SChris Lattner                   "expected string not found in input");
989da108b4eSChris Lattner 
990da108b4eSChris Lattner   // Print the "scanning from here" line.  If the current position is at the
991da108b4eSChris Lattner   // end of a line, advance to the start of the next line.
992caa5fc0cSChris Lattner   Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
993da108b4eSChris Lattner 
99403b80a40SChris Lattner   SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
99503b80a40SChris Lattner                   "scanning from here");
996e0ef65abSDaniel Dunbar 
997e0ef65abSDaniel Dunbar   // Allow the pattern to print additional information if desired.
99891a1b2c9SMichael Liao   Pat.PrintFailureInfo(SM, Buffer, VariableTable);
99991a1b2c9SMichael Liao }
100091a1b2c9SMichael Liao 
100191a1b2c9SMichael Liao static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
100291a1b2c9SMichael Liao                              StringRef Buffer,
100391a1b2c9SMichael Liao                              StringMap<StringRef> &VariableTable) {
100491a1b2c9SMichael Liao   PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
1005da108b4eSChris Lattner }
1006da108b4eSChris Lattner 
100737183584SChris Lattner /// CountNumNewlinesBetween - Count the number of newlines in the specified
100837183584SChris Lattner /// range.
1009592fe880SRichard Smith static unsigned CountNumNewlinesBetween(StringRef Range,
1010592fe880SRichard Smith                                         const char *&FirstNewLine) {
1011da108b4eSChris Lattner   unsigned NumNewLines = 0;
101237183584SChris Lattner   while (1) {
1013da108b4eSChris Lattner     // Scan for newline.
101437183584SChris Lattner     Range = Range.substr(Range.find_first_of("\n\r"));
1015*e8f2fb20SChandler Carruth     if (Range.empty())
1016*e8f2fb20SChandler Carruth       return NumNewLines;
1017da108b4eSChris Lattner 
1018da108b4eSChris Lattner     ++NumNewLines;
1019da108b4eSChris Lattner 
1020da108b4eSChris Lattner     // Handle \n\r and \r\n as a single newline.
1021*e8f2fb20SChandler Carruth     if (Range.size() > 1 && (Range[1] == '\n' || Range[1] == '\r') &&
102237183584SChris Lattner         (Range[0] != Range[1]))
102337183584SChris Lattner       Range = Range.substr(1);
102437183584SChris Lattner     Range = Range.substr(1);
1025592fe880SRichard Smith 
1026592fe880SRichard Smith     if (NumNewLines == 1)
1027592fe880SRichard Smith       FirstNewLine = Range.begin();
1028da108b4eSChris Lattner   }
1029da108b4eSChris Lattner }
1030da108b4eSChris Lattner 
1031dcc7d48dSMichael Liao size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
1032e93a3a08SStephen Lin                           bool IsLabelScanMode, size_t &MatchLen,
1033dcc7d48dSMichael Liao                           StringMap<StringRef> &VariableTable) const {
103491a1b2c9SMichael Liao   size_t LastPos = 0;
103591a1b2c9SMichael Liao   std::vector<const Pattern *> NotStrings;
103691a1b2c9SMichael Liao 
1037e93a3a08SStephen Lin   // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
1038e93a3a08SStephen Lin   // bounds; we have not processed variable definitions within the bounded block
1039e93a3a08SStephen Lin   // yet so cannot handle any final CHECK-DAG yet; this is handled when going
1040e93a3a08SStephen Lin   // over the block again (including the last CHECK-LABEL) in normal mode.
1041e93a3a08SStephen Lin   if (!IsLabelScanMode) {
104291a1b2c9SMichael Liao     // Match "dag strings" (with mixed "not strings" if any).
104391a1b2c9SMichael Liao     LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable);
104491a1b2c9SMichael Liao     if (LastPos == StringRef::npos)
104591a1b2c9SMichael Liao       return StringRef::npos;
1046e93a3a08SStephen Lin   }
104791a1b2c9SMichael Liao 
104891a1b2c9SMichael Liao   // Match itself from the last position after matching CHECK-DAG.
104991a1b2c9SMichael Liao   StringRef MatchBuffer = Buffer.substr(LastPos);
105091a1b2c9SMichael Liao   size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
1051dcc7d48dSMichael Liao   if (MatchPos == StringRef::npos) {
105291a1b2c9SMichael Liao     PrintCheckFailed(SM, *this, MatchBuffer, VariableTable);
1053dcc7d48dSMichael Liao     return StringRef::npos;
1054dcc7d48dSMichael Liao   }
1055dcc7d48dSMichael Liao 
1056e93a3a08SStephen Lin   // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
1057e93a3a08SStephen Lin   // or CHECK-NOT
1058e93a3a08SStephen Lin   if (!IsLabelScanMode) {
105991a1b2c9SMichael Liao     StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1060dcc7d48dSMichael Liao 
1061dcc7d48dSMichael Liao     // If this check is a "CHECK-NEXT", verify that the previous match was on
1062dcc7d48dSMichael Liao     // the previous line (i.e. that there is one newline between them).
1063dcc7d48dSMichael Liao     if (CheckNext(SM, SkippedRegion))
1064dcc7d48dSMichael Liao       return StringRef::npos;
1065dcc7d48dSMichael Liao 
106601ac1707SDuncan P. N. Exon Smith     // If this check is a "CHECK-SAME", verify that the previous match was on
106701ac1707SDuncan P. N. Exon Smith     // the same line (i.e. that there is no newline between them).
106801ac1707SDuncan P. N. Exon Smith     if (CheckSame(SM, SkippedRegion))
106901ac1707SDuncan P. N. Exon Smith       return StringRef::npos;
107001ac1707SDuncan P. N. Exon Smith 
1071dcc7d48dSMichael Liao     // If this match had "not strings", verify that they don't exist in the
1072dcc7d48dSMichael Liao     // skipped region.
107391a1b2c9SMichael Liao     if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
1074dcc7d48dSMichael Liao       return StringRef::npos;
1075f8bd2e5bSStephen Lin   }
1076dcc7d48dSMichael Liao 
10777dfb92b9SMehdi Amini   return LastPos + MatchPos;
1078dcc7d48dSMichael Liao }
1079dcc7d48dSMichael Liao 
1080dcc7d48dSMichael Liao bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
108185913ccaSJames Y Knight   if (Pat.getCheckTy() != Check::CheckNext)
1082dcc7d48dSMichael Liao     return false;
1083dcc7d48dSMichael Liao 
1084dcc7d48dSMichael Liao   // Count the number of newlines between the previous match and this one.
1085dcc7d48dSMichael Liao   assert(Buffer.data() !=
1086*e8f2fb20SChandler Carruth              SM.getMemoryBuffer(SM.FindBufferContainingLoc(
1087*e8f2fb20SChandler Carruth                                     SMLoc::getFromPointer(Buffer.data())))
1088*e8f2fb20SChandler Carruth                  ->getBufferStart() &&
1089dcc7d48dSMichael Liao          "CHECK-NEXT can't be the first check in a file");
1090dcc7d48dSMichael Liao 
109166f09ad0SCraig Topper   const char *FirstNewLine = nullptr;
1092592fe880SRichard Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
1093dcc7d48dSMichael Liao 
1094dcc7d48dSMichael Liao   if (NumNewLines == 0) {
1095*e8f2fb20SChandler Carruth     SM.PrintMessage(Loc, SourceMgr::DK_Error,
1096*e8f2fb20SChandler Carruth                     Prefix + "-NEXT: is on the same line as previous match");
1097*e8f2fb20SChandler Carruth     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
1098*e8f2fb20SChandler Carruth                     "'next' match was here");
1099dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1100dcc7d48dSMichael Liao                     "previous match ended here");
1101dcc7d48dSMichael Liao     return true;
1102dcc7d48dSMichael Liao   }
1103dcc7d48dSMichael Liao 
1104dcc7d48dSMichael Liao   if (NumNewLines != 1) {
1105*e8f2fb20SChandler Carruth     SM.PrintMessage(Loc, SourceMgr::DK_Error,
1106*e8f2fb20SChandler Carruth                     Prefix +
1107dcc7d48dSMichael Liao                         "-NEXT: is not on the line after the previous match");
1108*e8f2fb20SChandler Carruth     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
1109*e8f2fb20SChandler Carruth                     "'next' match was here");
1110dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1111dcc7d48dSMichael Liao                     "previous match ended here");
1112592fe880SRichard Smith     SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
1113592fe880SRichard Smith                     "non-matching line after previous match is here");
1114dcc7d48dSMichael Liao     return true;
1115dcc7d48dSMichael Liao   }
1116dcc7d48dSMichael Liao 
1117dcc7d48dSMichael Liao   return false;
1118dcc7d48dSMichael Liao }
1119dcc7d48dSMichael Liao 
112001ac1707SDuncan P. N. Exon Smith bool CheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
112185913ccaSJames Y Knight   if (Pat.getCheckTy() != Check::CheckSame)
112201ac1707SDuncan P. N. Exon Smith     return false;
112301ac1707SDuncan P. N. Exon Smith 
112401ac1707SDuncan P. N. Exon Smith   // Count the number of newlines between the previous match and this one.
112501ac1707SDuncan P. N. Exon Smith   assert(Buffer.data() !=
112601ac1707SDuncan P. N. Exon Smith              SM.getMemoryBuffer(SM.FindBufferContainingLoc(
112701ac1707SDuncan P. N. Exon Smith                                     SMLoc::getFromPointer(Buffer.data())))
112801ac1707SDuncan P. N. Exon Smith                  ->getBufferStart() &&
112901ac1707SDuncan P. N. Exon Smith          "CHECK-SAME can't be the first check in a file");
113001ac1707SDuncan P. N. Exon Smith 
113101ac1707SDuncan P. N. Exon Smith   const char *FirstNewLine = nullptr;
113201ac1707SDuncan P. N. Exon Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
113301ac1707SDuncan P. N. Exon Smith 
113401ac1707SDuncan P. N. Exon Smith   if (NumNewLines != 0) {
113501ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(Loc, SourceMgr::DK_Error,
113601ac1707SDuncan P. N. Exon Smith                     Prefix +
113701ac1707SDuncan P. N. Exon Smith                         "-SAME: is not on the same line as the previous match");
113801ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
113901ac1707SDuncan P. N. Exon Smith                     "'next' match was here");
114001ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
114101ac1707SDuncan P. N. Exon Smith                     "previous match ended here");
114201ac1707SDuncan P. N. Exon Smith     return true;
114301ac1707SDuncan P. N. Exon Smith   }
114401ac1707SDuncan P. N. Exon Smith 
114501ac1707SDuncan P. N. Exon Smith   return false;
114601ac1707SDuncan P. N. Exon Smith }
114701ac1707SDuncan P. N. Exon Smith 
1148dcc7d48dSMichael Liao bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
114991a1b2c9SMichael Liao                            const std::vector<const Pattern *> &NotStrings,
1150dcc7d48dSMichael Liao                            StringMap<StringRef> &VariableTable) const {
11518f870499SBenjamin Kramer   for (const Pattern *Pat : NotStrings) {
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 
1157*e8f2fb20SChandler Carruth     if (Pos == StringRef::npos)
1158*e8f2fb20SChandler Carruth       continue;
1159dcc7d48dSMichael Liao 
1160dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Pos),
1161*e8f2fb20SChandler Carruth                     SourceMgr::DK_Error, 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 
11798f870499SBenjamin Kramer   for (const Pattern &Pat : DagNotStrings) {
118038820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG ||
118138820972SMatt Arsenault             Pat.getCheckTy() == Check::CheckNot) &&
118291a1b2c9SMichael Liao            "Invalid CHECK-DAG or CHECK-NOT!");
118391a1b2c9SMichael Liao 
118438820972SMatt Arsenault     if (Pat.getCheckTy() == Check::CheckNot) {
118591a1b2c9SMichael Liao       NotStrings.push_back(&Pat);
118691a1b2c9SMichael Liao       continue;
118791a1b2c9SMichael Liao     }
118891a1b2c9SMichael Liao 
118938820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
119091a1b2c9SMichael Liao 
119191a1b2c9SMichael Liao     size_t MatchLen = 0, MatchPos;
119291a1b2c9SMichael Liao 
119391a1b2c9SMichael Liao     // CHECK-DAG always matches from the start.
119491a1b2c9SMichael Liao     StringRef MatchBuffer = Buffer.substr(StartPos);
119591a1b2c9SMichael Liao     MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
119691a1b2c9SMichael Liao     // With a group of CHECK-DAGs, a single mismatching means the match on
119791a1b2c9SMichael Liao     // that group of CHECK-DAGs fails immediately.
119891a1b2c9SMichael Liao     if (MatchPos == StringRef::npos) {
119991a1b2c9SMichael Liao       PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
120091a1b2c9SMichael Liao       return StringRef::npos;
120191a1b2c9SMichael Liao     }
120291a1b2c9SMichael Liao     // Re-calc it as the offset relative to the start of the original string.
120391a1b2c9SMichael Liao     MatchPos += StartPos;
120491a1b2c9SMichael Liao 
120591a1b2c9SMichael Liao     if (!NotStrings.empty()) {
120691a1b2c9SMichael Liao       if (MatchPos < LastPos) {
120791a1b2c9SMichael Liao         // Reordered?
120891a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
120991a1b2c9SMichael Liao                         SourceMgr::DK_Error,
121013df4626SMatt Arsenault                         Prefix + "-DAG: found a match of CHECK-DAG"
121191a1b2c9SMichael Liao                                  " reordering across a CHECK-NOT");
121291a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
121391a1b2c9SMichael Liao                         SourceMgr::DK_Note,
121413df4626SMatt Arsenault                         Prefix + "-DAG: the farthest match of CHECK-DAG"
121591a1b2c9SMichael Liao                                  " is found here");
121691a1b2c9SMichael Liao         SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
121713df4626SMatt Arsenault                         Prefix + "-NOT: the crossed pattern specified"
121891a1b2c9SMichael Liao                                  " here");
121991a1b2c9SMichael Liao         SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
122013df4626SMatt Arsenault                         Prefix + "-DAG: the reordered pattern specified"
122191a1b2c9SMichael Liao                                  " here");
122291a1b2c9SMichael Liao         return StringRef::npos;
122391a1b2c9SMichael Liao       }
122491a1b2c9SMichael Liao       // All subsequent CHECK-DAGs should be matched from the farthest
122591a1b2c9SMichael Liao       // position of all precedent CHECK-DAGs (including this one.)
122691a1b2c9SMichael Liao       StartPos = LastPos;
122791a1b2c9SMichael Liao       // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
122891a1b2c9SMichael Liao       // CHECK-DAG, verify that there's no 'not' strings occurred in that
122991a1b2c9SMichael Liao       // region.
123091a1b2c9SMichael Liao       StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1231cf708c32STim Northover       if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
123291a1b2c9SMichael Liao         return StringRef::npos;
123391a1b2c9SMichael Liao       // Clear "not strings".
123491a1b2c9SMichael Liao       NotStrings.clear();
123591a1b2c9SMichael Liao     }
123691a1b2c9SMichael Liao 
123791a1b2c9SMichael Liao     // Update the last position with CHECK-DAG matches.
123891a1b2c9SMichael Liao     LastPos = std::max(MatchPos + MatchLen, LastPos);
123991a1b2c9SMichael Liao   }
124091a1b2c9SMichael Liao 
124191a1b2c9SMichael Liao   return LastPos;
124291a1b2c9SMichael Liao }
124391a1b2c9SMichael Liao 
124413df4626SMatt Arsenault // A check prefix must contain only alphanumeric, hyphens and underscores.
124513df4626SMatt Arsenault static bool ValidateCheckPrefix(StringRef CheckPrefix) {
124613df4626SMatt Arsenault   Regex Validator("^[a-zA-Z0-9_-]*$");
124713df4626SMatt Arsenault   return Validator.match(CheckPrefix);
124813df4626SMatt Arsenault }
124913df4626SMatt Arsenault 
125013df4626SMatt Arsenault static bool ValidateCheckPrefixes() {
125113df4626SMatt Arsenault   StringSet<> PrefixSet;
125213df4626SMatt Arsenault 
12538f870499SBenjamin Kramer   for (StringRef Prefix : CheckPrefixes) {
125424412b14SEli Bendersky     // Reject empty prefixes.
125524412b14SEli Bendersky     if (Prefix == "")
125624412b14SEli Bendersky       return false;
125724412b14SEli Bendersky 
12580356975cSDavid Blaikie     if (!PrefixSet.insert(Prefix).second)
125913df4626SMatt Arsenault       return false;
126013df4626SMatt Arsenault 
126113df4626SMatt Arsenault     if (!ValidateCheckPrefix(Prefix))
126213df4626SMatt Arsenault       return false;
126313df4626SMatt Arsenault   }
126413df4626SMatt Arsenault 
126513df4626SMatt Arsenault   return true;
126613df4626SMatt Arsenault }
126713df4626SMatt Arsenault 
126813df4626SMatt Arsenault // I don't think there's a way to specify an initial value for cl::list,
126913df4626SMatt Arsenault // so if nothing was specified, add the default
127013df4626SMatt Arsenault static void AddCheckPrefixIfNeeded() {
127113df4626SMatt Arsenault   if (CheckPrefixes.empty())
127213df4626SMatt Arsenault     CheckPrefixes.push_back("CHECK");
1273c2735158SRui Ueyama }
1274c2735158SRui Ueyama 
12752bd4f8b6SXinliang David Li static void DumpCommandLine(int argc, char **argv) {
12762bd4f8b6SXinliang David Li   errs() << "FileCheck command line: ";
12772bd4f8b6SXinliang David Li   for (int I = 0; I < argc; I++)
12782bd4f8b6SXinliang David Li     errs() << " " << argv[I];
12792bd4f8b6SXinliang David Li   errs() << "\n";
12802bd4f8b6SXinliang David Li }
12812bd4f8b6SXinliang David Li 
128220247900SChandler Carruth /// Check the input to FileCheck provided in the \p Buffer against the \p
128320247900SChandler Carruth /// CheckStrings read from the check file.
128420247900SChandler Carruth ///
128520247900SChandler Carruth /// Returns false if the input fails to satisfy the checks.
128620247900SChandler Carruth bool CheckInput(SourceMgr &SM, StringRef Buffer,
128720247900SChandler Carruth                 ArrayRef<CheckString> CheckStrings) {
128820247900SChandler Carruth   bool ChecksFailed = false;
128920247900SChandler Carruth 
129020247900SChandler Carruth   /// VariableTable - This holds all the current filecheck variables.
129120247900SChandler Carruth   StringMap<StringRef> VariableTable;
129220247900SChandler Carruth 
129320247900SChandler Carruth   unsigned i = 0, j = 0, e = CheckStrings.size();
129420247900SChandler Carruth   while (true) {
129520247900SChandler Carruth     StringRef CheckRegion;
129620247900SChandler Carruth     if (j == e) {
129720247900SChandler Carruth       CheckRegion = Buffer;
129820247900SChandler Carruth     } else {
129920247900SChandler Carruth       const CheckString &CheckLabelStr = CheckStrings[j];
130020247900SChandler Carruth       if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
130120247900SChandler Carruth         ++j;
130220247900SChandler Carruth         continue;
130320247900SChandler Carruth       }
130420247900SChandler Carruth 
130520247900SChandler Carruth       // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
130620247900SChandler Carruth       size_t MatchLabelLen = 0;
1307*e8f2fb20SChandler Carruth       size_t MatchLabelPos =
1308*e8f2fb20SChandler Carruth           CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, VariableTable);
130920247900SChandler Carruth       if (MatchLabelPos == StringRef::npos)
131020247900SChandler Carruth         // Immediately bail of CHECK-LABEL fails, nothing else we can do.
131120247900SChandler Carruth         return false;
131220247900SChandler Carruth 
131320247900SChandler Carruth       CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
131420247900SChandler Carruth       Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
131520247900SChandler Carruth       ++j;
131620247900SChandler Carruth     }
131720247900SChandler Carruth 
131820247900SChandler Carruth     for (; i != j; ++i) {
131920247900SChandler Carruth       const CheckString &CheckStr = CheckStrings[i];
132020247900SChandler Carruth 
132120247900SChandler Carruth       // Check each string within the scanned region, including a second check
132220247900SChandler Carruth       // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
132320247900SChandler Carruth       size_t MatchLen = 0;
1324*e8f2fb20SChandler Carruth       size_t MatchPos =
1325*e8f2fb20SChandler Carruth           CheckStr.Check(SM, CheckRegion, false, MatchLen, VariableTable);
132620247900SChandler Carruth 
132720247900SChandler Carruth       if (MatchPos == StringRef::npos) {
132820247900SChandler Carruth         ChecksFailed = true;
132920247900SChandler Carruth         i = j;
133020247900SChandler Carruth         break;
133120247900SChandler Carruth       }
133220247900SChandler Carruth 
133320247900SChandler Carruth       CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
133420247900SChandler Carruth     }
133520247900SChandler Carruth 
133620247900SChandler Carruth     if (j == e)
133720247900SChandler Carruth       break;
133820247900SChandler Carruth   }
133920247900SChandler Carruth 
134020247900SChandler Carruth   // Success if no checks failed.
134120247900SChandler Carruth   return !ChecksFailed;
134220247900SChandler Carruth }
134320247900SChandler Carruth 
1344ee3c74fbSChris Lattner int main(int argc, char **argv) {
13452ad6d48bSRichard Smith   sys::PrintStackTraceOnErrorSignal(argv[0]);
1346ee3c74fbSChris Lattner   PrettyStackTraceProgram X(argc, argv);
1347ee3c74fbSChris Lattner   cl::ParseCommandLineOptions(argc, argv);
1348ee3c74fbSChris Lattner 
134913df4626SMatt Arsenault   if (!ValidateCheckPrefixes()) {
135013df4626SMatt Arsenault     errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
135113df4626SMatt Arsenault               "start with a letter and contain only alphanumeric characters, "
135213df4626SMatt Arsenault               "hyphens and underscores\n";
1353c2735158SRui Ueyama     return 2;
1354c2735158SRui Ueyama   }
1355c2735158SRui Ueyama 
135613df4626SMatt Arsenault   AddCheckPrefixIfNeeded();
135713df4626SMatt Arsenault 
1358ee3c74fbSChris Lattner   SourceMgr SM;
1359ee3c74fbSChris Lattner 
1360ee3c74fbSChris Lattner   // Read the expected strings from the check file.
136120247900SChandler Carruth   ErrorOr<std::unique_ptr<MemoryBuffer>> CheckFileOrErr =
136220247900SChandler Carruth       MemoryBuffer::getFileOrSTDIN(CheckFilename);
136320247900SChandler Carruth   if (std::error_code EC = CheckFileOrErr.getError()) {
136420247900SChandler Carruth     errs() << "Could not open check file '" << CheckFilename
136520247900SChandler Carruth            << "': " << EC.message() << '\n';
136620247900SChandler Carruth     return 2;
136720247900SChandler Carruth   }
136820247900SChandler Carruth   MemoryBuffer &CheckFile = *CheckFileOrErr.get();
136920247900SChandler Carruth 
137020247900SChandler Carruth   SmallString<4096> CheckFileBuffer;
137120247900SChandler Carruth   StringRef CheckFileText =
137220247900SChandler Carruth       CanonicalizeFile(CheckFile, NoCanonicalizeWhiteSpace, CheckFileBuffer);
137320247900SChandler Carruth 
137420247900SChandler Carruth   SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
137520247900SChandler Carruth                             CheckFileText, CheckFile.getBufferIdentifier()),
137620247900SChandler Carruth                         SMLoc());
137720247900SChandler Carruth 
137826cccfe1SChris Lattner   std::vector<CheckString> CheckStrings;
137920247900SChandler Carruth   if (ReadCheckFile(SM, CheckFileText, CheckStrings))
1380ee3c74fbSChris Lattner     return 2;
1381ee3c74fbSChris Lattner 
1382ee3c74fbSChris Lattner   // Open the file to check and add it to SourceMgr.
138320247900SChandler Carruth   ErrorOr<std::unique_ptr<MemoryBuffer>> InputFileOrErr =
1384adf21f2aSRafael Espindola       MemoryBuffer::getFileOrSTDIN(InputFilename);
138520247900SChandler Carruth   if (std::error_code EC = InputFileOrErr.getError()) {
1386adf21f2aSRafael Espindola     errs() << "Could not open input file '" << InputFilename
1387adf21f2aSRafael Espindola            << "': " << EC.message() << '\n';
13888e1c6477SEli Bendersky     return 2;
1389ee3c74fbSChris Lattner   }
139020247900SChandler Carruth   MemoryBuffer &InputFile = *InputFileOrErr.get();
13912c3e5cdfSChris Lattner 
139220247900SChandler Carruth   if (InputFile.getBufferSize() == 0 && !AllowEmptyInput) {
1393b692bed7SChris Lattner     errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
13942bd4f8b6SXinliang David Li     DumpCommandLine(argc, argv);
13958e1c6477SEli Bendersky     return 2;
1396b692bed7SChris Lattner   }
1397b692bed7SChris Lattner 
139820247900SChandler Carruth   SmallString<4096> InputFileBuffer;
139920247900SChandler Carruth   StringRef InputFileText =
140020247900SChandler Carruth       CanonicalizeFile(InputFile, NoCanonicalizeWhiteSpace, InputFileBuffer);
14012c3e5cdfSChris Lattner 
1402*e8f2fb20SChandler Carruth   SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
1403*e8f2fb20SChandler Carruth                             InputFileText, InputFile.getBufferIdentifier()),
1404*e8f2fb20SChandler Carruth                         SMLoc());
1405ee3c74fbSChris Lattner 
140620247900SChandler Carruth   return CheckInput(SM, InputFileText, CheckStrings) ? EXIT_SUCCESS : 1;
1407ee3c74fbSChris Lattner }
1408