1ee3c74fbSChris Lattner //===- FileCheck.cpp - Check that File's Contents match what is expected --===//
2ee3c74fbSChris Lattner //
3ee3c74fbSChris Lattner //                     The LLVM Compiler Infrastructure
4ee3c74fbSChris Lattner //
5ee3c74fbSChris Lattner // This file is distributed under the University of Illinois Open Source
6ee3c74fbSChris Lattner // License. See LICENSE.TXT for details.
7ee3c74fbSChris Lattner //
8ee3c74fbSChris Lattner //===----------------------------------------------------------------------===//
9ee3c74fbSChris Lattner //
10ee3c74fbSChris Lattner // FileCheck does a line-by line check of a file that validates whether it
11ee3c74fbSChris Lattner // contains the expected content.  This is useful for regression tests etc.
12ee3c74fbSChris Lattner //
13ee3c74fbSChris Lattner // This program exits with an error status of 2 on error, exit status of 0 if
14ee3c74fbSChris Lattner // the file matched the expected contents, and exit status of 1 if it did not
15ee3c74fbSChris Lattner // contain the expected contents.
16ee3c74fbSChris Lattner //
17ee3c74fbSChris Lattner //===----------------------------------------------------------------------===//
18ee3c74fbSChris Lattner 
1991d19d8eSChandler Carruth #include "llvm/ADT/SmallString.h"
2091d19d8eSChandler Carruth #include "llvm/ADT/StringExtras.h"
2191d19d8eSChandler Carruth #include "llvm/ADT/StringMap.h"
2213df4626SMatt Arsenault #include "llvm/ADT/StringSet.h"
23ee3c74fbSChris Lattner #include "llvm/Support/CommandLine.h"
24ee3c74fbSChris Lattner #include "llvm/Support/MemoryBuffer.h"
25ee3c74fbSChris Lattner #include "llvm/Support/PrettyStackTrace.h"
26f08d2db9SChris Lattner #include "llvm/Support/Regex.h"
2791d19d8eSChandler Carruth #include "llvm/Support/Signals.h"
28ee3c74fbSChris Lattner #include "llvm/Support/SourceMgr.h"
29ee3c74fbSChris Lattner #include "llvm/Support/raw_ostream.h"
308879e06dSChris Lattner #include <algorithm>
31981af002SWill Dietz #include <cctype>
32e8b8f1bcSEli Bendersky #include <map>
33e8b8f1bcSEli Bendersky #include <string>
34a6e9c3e4SRafael Espindola #include <system_error>
35e8b8f1bcSEli Bendersky #include <vector>
36ee3c74fbSChris Lattner using namespace llvm;
37ee3c74fbSChris Lattner 
38ee3c74fbSChris Lattner static cl::opt<std::string>
39ee3c74fbSChris Lattner CheckFilename(cl::Positional, cl::desc("<check-file>"), cl::Required);
40ee3c74fbSChris Lattner 
41ee3c74fbSChris Lattner static cl::opt<std::string>
42ee3c74fbSChris Lattner InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
43ee3c74fbSChris Lattner               cl::init("-"), cl::value_desc("filename"));
44ee3c74fbSChris Lattner 
4513df4626SMatt Arsenault static cl::list<std::string>
4613df4626SMatt Arsenault CheckPrefixes("check-prefix",
47ee3c74fbSChris Lattner               cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
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 
542c3e5cdfSChris Lattner static cl::opt<bool>
552c3e5cdfSChris Lattner NoCanonicalizeWhiteSpace("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.
13713df4626SMatt Arsenault   bool ParsePattern(StringRef PatternStr,
13813df4626SMatt Arsenault                     StringRef Prefix,
13913df4626SMatt Arsenault                     SourceMgr &SM,
14013df4626SMatt Arsenault                     unsigned LineNumber);
1413b40b445SChris Lattner 
1423b40b445SChris Lattner   /// Match - Match the pattern string against the input buffer Buffer.  This
1433b40b445SChris Lattner   /// returns the position that is matched or npos if there is no match.  If
1443b40b445SChris Lattner   /// there is a match, the size of the matched string is returned in MatchLen.
1458879e06dSChris Lattner   ///
1468879e06dSChris Lattner   /// The VariableTable StringMap provides the current values of filecheck
1478879e06dSChris Lattner   /// variables and is updated if this match defines new values.
1488879e06dSChris Lattner   size_t Match(StringRef Buffer, size_t &MatchLen,
1498879e06dSChris Lattner                StringMap<StringRef> &VariableTable) const;
150b16ab0c4SChris Lattner 
151e0ef65abSDaniel Dunbar   /// PrintFailureInfo - Print additional information about a failure to match
152e0ef65abSDaniel Dunbar   /// involving this pattern.
153e0ef65abSDaniel Dunbar   void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
154e0ef65abSDaniel Dunbar                         const StringMap<StringRef> &VariableTable) const;
155e0ef65abSDaniel Dunbar 
156f8bd2e5bSStephen Lin   bool hasVariable() const { return !(VariableUses.empty() &&
157f8bd2e5bSStephen Lin                                       VariableDefs.empty()); }
158f8bd2e5bSStephen Lin 
15938820972SMatt Arsenault   Check::CheckType getCheckTy() const { return CheckTy; }
16091a1b2c9SMichael Liao 
161b16ab0c4SChris Lattner private:
162e8b8f1bcSEli Bendersky   bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM);
163e8b8f1bcSEli Bendersky   void AddBackrefToRegEx(unsigned BackrefNum);
164fd29d886SDaniel Dunbar 
165fd29d886SDaniel Dunbar   /// ComputeMatchDistance - Compute an arbitrary estimate for the quality of
166fd29d886SDaniel Dunbar   /// matching this pattern at the start of \arg Buffer; a distance of zero
167fd29d886SDaniel Dunbar   /// should correspond to a perfect match.
168fd29d886SDaniel Dunbar   unsigned 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 
1838879e06dSChris Lattner 
18413df4626SMatt Arsenault bool Pattern::ParsePattern(StringRef PatternStr,
18513df4626SMatt Arsenault                            StringRef Prefix,
18613df4626SMatt Arsenault                            SourceMgr &SM,
18792987fb3SAlexander Kornienko                            unsigned LineNumber) {
18885913ccaSJames Y Knight   bool MatchFullLinesHere = MatchFullLines && CheckTy != Check::CheckNot;
18985913ccaSJames Y Knight 
19092987fb3SAlexander Kornienko   this->LineNumber = LineNumber;
1910a4c44bdSChris Lattner   PatternLoc = SMLoc::getFromPointer(PatternStr.data());
1920a4c44bdSChris Lattner 
19374d50731SChris Lattner   // Ignore trailing whitespace.
19474d50731SChris Lattner   while (!PatternStr.empty() &&
19574d50731SChris Lattner          (PatternStr.back() == ' ' || PatternStr.back() == '\t'))
19674d50731SChris Lattner     PatternStr = PatternStr.substr(0, PatternStr.size()-1);
19774d50731SChris Lattner 
19874d50731SChris Lattner   // Check that there is something on the line.
19974d50731SChris Lattner   if (PatternStr.empty()) {
20003b80a40SChris Lattner     SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
20103b80a40SChris Lattner                     "found empty check string with prefix '" +
20213df4626SMatt Arsenault                     Prefix + ":'");
20374d50731SChris Lattner     return true;
20474d50731SChris Lattner   }
20574d50731SChris Lattner 
206221460e0SChris Lattner   // Check to see if this is a fixed string, or if it has regex pieces.
20785913ccaSJames Y Knight   if (!MatchFullLinesHere &&
20885913ccaSJames Y Knight       (PatternStr.size() < 2 || (PatternStr.find("{{") == StringRef::npos &&
20985913ccaSJames Y Knight                                  PatternStr.find("[[") == StringRef::npos))) {
210221460e0SChris Lattner     FixedStr = PatternStr;
211221460e0SChris Lattner     return false;
212221460e0SChris Lattner   }
213221460e0SChris Lattner 
21485913ccaSJames Y Knight   if (MatchFullLinesHere) {
21585913ccaSJames Y Knight     RegExStr += '^';
21685913ccaSJames Y Knight     if (!NoCanonicalizeWhiteSpace)
21785913ccaSJames Y Knight       RegExStr += " *";
21885913ccaSJames Y Knight   }
21985913ccaSJames Y Knight 
2208879e06dSChris Lattner   // Paren value #0 is for the fully matched string.  Any new parenthesized
22153e0679dSChris Lattner   // values add from there.
2228879e06dSChris Lattner   unsigned CurParen = 1;
2238879e06dSChris Lattner 
224b16ab0c4SChris Lattner   // Otherwise, there is at least one regex piece.  Build up the regex pattern
225b16ab0c4SChris Lattner   // by escaping scary characters in fixed strings, building up one big regex.
226f08d2db9SChris Lattner   while (!PatternStr.empty()) {
2278879e06dSChris Lattner     // RegEx matches.
22853e0679dSChris Lattner     if (PatternStr.startswith("{{")) {
22943d50d4aSEli Bendersky       // This is the start of a regex match.  Scan for the }}.
230f08d2db9SChris Lattner       size_t End = PatternStr.find("}}");
231f08d2db9SChris Lattner       if (End == StringRef::npos) {
232f08d2db9SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
23303b80a40SChris Lattner                         SourceMgr::DK_Error,
23403b80a40SChris Lattner                         "found start of regex string with no end '}}'");
235f08d2db9SChris Lattner         return true;
236f08d2db9SChris Lattner       }
237f08d2db9SChris Lattner 
238e53c95f1SChris Lattner       // Enclose {{}} patterns in parens just like [[]] even though we're not
239e53c95f1SChris Lattner       // capturing the result for any purpose.  This is required in case the
240e53c95f1SChris Lattner       // expression contains an alternation like: CHECK:  abc{{x|z}}def.  We
241e53c95f1SChris Lattner       // want this to turn into: "abc(x|z)def" not "abcx|zdef".
242e53c95f1SChris Lattner       RegExStr += '(';
243e53c95f1SChris Lattner       ++CurParen;
244e53c95f1SChris Lattner 
2458879e06dSChris Lattner       if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
2468879e06dSChris Lattner         return true;
247e53c95f1SChris Lattner       RegExStr += ')';
24853e0679dSChris Lattner 
2498879e06dSChris Lattner       PatternStr = PatternStr.substr(End+2);
2508879e06dSChris Lattner       continue;
2518879e06dSChris Lattner     }
2528879e06dSChris Lattner 
2538879e06dSChris Lattner     // Named RegEx matches.  These are of two forms: [[foo:.*]] which matches .*
2548879e06dSChris Lattner     // (or some other regex) and assigns it to the FileCheck variable 'foo'. The
2558879e06dSChris Lattner     // second form is [[foo]] which is a reference to foo.  The variable name
25657cb733bSDaniel Dunbar     // itself must be of the form "[a-zA-Z_][0-9a-zA-Z_]*", otherwise we reject
2578879e06dSChris Lattner     // it.  This is to catch some common errors.
25853e0679dSChris Lattner     if (PatternStr.startswith("[[")) {
259061d2baaSEli Bendersky       // Find the closing bracket pair ending the match.  End is going to be an
260061d2baaSEli Bendersky       // offset relative to the beginning of the match string.
26181e5cd9eSAdrian Prantl       size_t End = FindRegexVarEnd(PatternStr.substr(2), SM);
262061d2baaSEli Bendersky 
2638879e06dSChris Lattner       if (End == StringRef::npos) {
2648879e06dSChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
26503b80a40SChris Lattner                         SourceMgr::DK_Error,
26603b80a40SChris Lattner                         "invalid named regex reference, no ]] found");
267f08d2db9SChris Lattner         return true;
268f08d2db9SChris Lattner       }
269f08d2db9SChris Lattner 
270061d2baaSEli Bendersky       StringRef MatchStr = PatternStr.substr(2, End);
271061d2baaSEli Bendersky       PatternStr = PatternStr.substr(End+4);
2728879e06dSChris Lattner 
2738879e06dSChris Lattner       // Get the regex name (e.g. "foo").
2748879e06dSChris Lattner       size_t NameEnd = MatchStr.find(':');
2758879e06dSChris Lattner       StringRef Name = MatchStr.substr(0, NameEnd);
2768879e06dSChris Lattner 
2778879e06dSChris Lattner       if (Name.empty()) {
27803b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
27903b80a40SChris Lattner                         "invalid name in named regex: empty name");
2808879e06dSChris Lattner         return true;
2818879e06dSChris Lattner       }
2828879e06dSChris Lattner 
28392987fb3SAlexander Kornienko       // Verify that the name/expression is well formed. FileCheck currently
28492987fb3SAlexander Kornienko       // supports @LINE, @LINE+number, @LINE-number expressions. The check here
28592987fb3SAlexander Kornienko       // is relaxed, more strict check is performed in \c EvaluateExpression.
28692987fb3SAlexander Kornienko       bool IsExpression = false;
28792987fb3SAlexander Kornienko       for (unsigned i = 0, e = Name.size(); i != e; ++i) {
28892987fb3SAlexander Kornienko         if (i == 0 && Name[i] == '@') {
28992987fb3SAlexander Kornienko           if (NameEnd != StringRef::npos) {
29092987fb3SAlexander Kornienko             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
29192987fb3SAlexander Kornienko                             SourceMgr::DK_Error,
29292987fb3SAlexander Kornienko                             "invalid name in named regex definition");
29392987fb3SAlexander Kornienko             return true;
29492987fb3SAlexander Kornienko           }
29592987fb3SAlexander Kornienko           IsExpression = true;
29692987fb3SAlexander Kornienko           continue;
29792987fb3SAlexander Kornienko         }
29892987fb3SAlexander Kornienko         if (Name[i] != '_' && !isalnum(Name[i]) &&
29992987fb3SAlexander Kornienko             (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
3008879e06dSChris Lattner           SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
30103b80a40SChris Lattner                           SourceMgr::DK_Error, "invalid name in named regex");
3028879e06dSChris Lattner           return true;
3038879e06dSChris Lattner         }
30492987fb3SAlexander Kornienko       }
3058879e06dSChris Lattner 
3068879e06dSChris Lattner       // Name can't start with a digit.
30783c74e9fSGuy Benyei       if (isdigit(static_cast<unsigned char>(Name[0]))) {
30803b80a40SChris Lattner         SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
30903b80a40SChris Lattner                         "invalid name in named regex");
3108879e06dSChris Lattner         return true;
3118879e06dSChris Lattner       }
3128879e06dSChris Lattner 
3138879e06dSChris Lattner       // Handle [[foo]].
3148879e06dSChris Lattner       if (NameEnd == StringRef::npos) {
315e8b8f1bcSEli Bendersky         // Handle variables that were defined earlier on the same line by
316e8b8f1bcSEli Bendersky         // emitting a backreference.
317e8b8f1bcSEli Bendersky         if (VariableDefs.find(Name) != VariableDefs.end()) {
318e8b8f1bcSEli Bendersky           unsigned VarParenNum = VariableDefs[Name];
319e8b8f1bcSEli Bendersky           if (VarParenNum < 1 || VarParenNum > 9) {
320e8b8f1bcSEli Bendersky             SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
321e8b8f1bcSEli Bendersky                             SourceMgr::DK_Error,
322e8b8f1bcSEli Bendersky                             "Can't back-reference more than 9 variables");
323e8b8f1bcSEli Bendersky             return true;
324e8b8f1bcSEli Bendersky           }
325e8b8f1bcSEli Bendersky           AddBackrefToRegEx(VarParenNum);
326e8b8f1bcSEli Bendersky         } else {
3278879e06dSChris Lattner           VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
328e8b8f1bcSEli Bendersky         }
3298879e06dSChris Lattner         continue;
3308879e06dSChris Lattner       }
3318879e06dSChris Lattner 
3328879e06dSChris Lattner       // Handle [[foo:.*]].
333e8b8f1bcSEli Bendersky       VariableDefs[Name] = CurParen;
3348879e06dSChris Lattner       RegExStr += '(';
3358879e06dSChris Lattner       ++CurParen;
3368879e06dSChris Lattner 
3378879e06dSChris Lattner       if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
3388879e06dSChris Lattner         return true;
3398879e06dSChris Lattner 
3408879e06dSChris Lattner       RegExStr += ')';
3418879e06dSChris Lattner     }
3428879e06dSChris Lattner 
3438879e06dSChris Lattner     // Handle fixed string matches.
3448879e06dSChris Lattner     // Find the end, which is the start of the next regex.
3458879e06dSChris Lattner     size_t FixedMatchEnd = PatternStr.find("{{");
3468879e06dSChris Lattner     FixedMatchEnd = std::min(FixedMatchEnd, PatternStr.find("[["));
3476f4f77b7SHans Wennborg     RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd));
3488879e06dSChris Lattner     PatternStr = PatternStr.substr(FixedMatchEnd);
349f08d2db9SChris Lattner   }
350f08d2db9SChris Lattner 
35185913ccaSJames Y Knight   if (MatchFullLinesHere) {
35285913ccaSJames Y Knight     if (!NoCanonicalizeWhiteSpace)
35385913ccaSJames Y Knight       RegExStr += " *";
35485913ccaSJames Y Knight     RegExStr += '$';
35585913ccaSJames Y Knight   }
35685913ccaSJames Y Knight 
35774d50731SChris Lattner   return false;
35874d50731SChris Lattner }
35974d50731SChris Lattner 
360e8b8f1bcSEli Bendersky bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen,
3618879e06dSChris Lattner                               SourceMgr &SM) {
362e8b8f1bcSEli Bendersky   Regex R(RS);
3638879e06dSChris Lattner   std::string Error;
3648879e06dSChris Lattner   if (!R.isValid(Error)) {
365e8b8f1bcSEli Bendersky     SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error,
36603b80a40SChris Lattner                     "invalid regex: " + Error);
3678879e06dSChris Lattner     return true;
3688879e06dSChris Lattner   }
3698879e06dSChris Lattner 
370e8b8f1bcSEli Bendersky   RegExStr += RS.str();
3718879e06dSChris Lattner   CurParen += R.getNumMatches();
3728879e06dSChris Lattner   return false;
3738879e06dSChris Lattner }
374b16ab0c4SChris Lattner 
375e8b8f1bcSEli Bendersky void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
376e8b8f1bcSEli Bendersky   assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
377e8b8f1bcSEli Bendersky   std::string Backref = std::string("\\") +
378e8b8f1bcSEli Bendersky                         std::string(1, '0' + BackrefNum);
379e8b8f1bcSEli Bendersky   RegExStr += Backref;
380e8b8f1bcSEli Bendersky }
381e8b8f1bcSEli Bendersky 
38292987fb3SAlexander Kornienko bool Pattern::EvaluateExpression(StringRef Expr, std::string &Value) const {
38392987fb3SAlexander Kornienko   // The only supported expression is @LINE([\+-]\d+)?
38492987fb3SAlexander Kornienko   if (!Expr.startswith("@LINE"))
38592987fb3SAlexander Kornienko     return false;
38692987fb3SAlexander Kornienko   Expr = Expr.substr(StringRef("@LINE").size());
38792987fb3SAlexander Kornienko   int Offset = 0;
38892987fb3SAlexander Kornienko   if (!Expr.empty()) {
38992987fb3SAlexander Kornienko     if (Expr[0] == '+')
39092987fb3SAlexander Kornienko       Expr = Expr.substr(1);
39192987fb3SAlexander Kornienko     else if (Expr[0] != '-')
39292987fb3SAlexander Kornienko       return false;
39392987fb3SAlexander Kornienko     if (Expr.getAsInteger(10, Offset))
39492987fb3SAlexander Kornienko       return false;
39592987fb3SAlexander Kornienko   }
39692987fb3SAlexander Kornienko   Value = llvm::itostr(LineNumber + Offset);
39792987fb3SAlexander Kornienko   return true;
39892987fb3SAlexander Kornienko }
39992987fb3SAlexander Kornienko 
400f08d2db9SChris Lattner /// Match - Match the pattern string against the input buffer Buffer.  This
401f08d2db9SChris Lattner /// returns the position that is matched or npos if there is no match.  If
402f08d2db9SChris Lattner /// there is a match, the size of the matched string is returned in MatchLen.
4038879e06dSChris Lattner size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
4048879e06dSChris Lattner                       StringMap<StringRef> &VariableTable) const {
405eba55822SJakob Stoklund Olesen   // If this is the EOF pattern, match it immediately.
40638820972SMatt Arsenault   if (CheckTy == Check::CheckEOF) {
407eba55822SJakob Stoklund Olesen     MatchLen = 0;
408eba55822SJakob Stoklund Olesen     return Buffer.size();
409eba55822SJakob Stoklund Olesen   }
410eba55822SJakob Stoklund Olesen 
411221460e0SChris Lattner   // If this is a fixed string pattern, just match it now.
412221460e0SChris Lattner   if (!FixedStr.empty()) {
413221460e0SChris Lattner     MatchLen = FixedStr.size();
414221460e0SChris Lattner     return Buffer.find(FixedStr);
415221460e0SChris Lattner   }
416221460e0SChris Lattner 
417b16ab0c4SChris Lattner   // Regex match.
4188879e06dSChris Lattner 
4198879e06dSChris Lattner   // If there are variable uses, we need to create a temporary string with the
4208879e06dSChris Lattner   // actual value.
4218879e06dSChris Lattner   StringRef RegExToMatch = RegExStr;
4228879e06dSChris Lattner   std::string TmpStr;
4238879e06dSChris Lattner   if (!VariableUses.empty()) {
4248879e06dSChris Lattner     TmpStr = RegExStr;
4258879e06dSChris Lattner 
4268879e06dSChris Lattner     unsigned InsertOffset = 0;
4278f870499SBenjamin Kramer     for (const auto &VariableUse : VariableUses) {
42892987fb3SAlexander Kornienko       std::string Value;
42992987fb3SAlexander Kornienko 
4308f870499SBenjamin Kramer       if (VariableUse.first[0] == '@') {
4318f870499SBenjamin Kramer         if (!EvaluateExpression(VariableUse.first, Value))
43292987fb3SAlexander Kornienko           return StringRef::npos;
43392987fb3SAlexander Kornienko       } else {
434e0ef65abSDaniel Dunbar         StringMap<StringRef>::iterator it =
4358f870499SBenjamin Kramer             VariableTable.find(VariableUse.first);
436e0ef65abSDaniel Dunbar         // If the variable is undefined, return an error.
437e0ef65abSDaniel Dunbar         if (it == VariableTable.end())
438e0ef65abSDaniel Dunbar           return StringRef::npos;
439e0ef65abSDaniel Dunbar 
4406f4f77b7SHans Wennborg         // Look up the value and escape it so that we can put it into the regex.
4416f4f77b7SHans Wennborg         Value += Regex::escape(it->second);
44292987fb3SAlexander Kornienko       }
4438879e06dSChris Lattner 
4448879e06dSChris Lattner       // Plop it into the regex at the adjusted offset.
4458f870499SBenjamin Kramer       TmpStr.insert(TmpStr.begin() + VariableUse.second + InsertOffset,
4468879e06dSChris Lattner                     Value.begin(), Value.end());
4478879e06dSChris Lattner       InsertOffset += Value.size();
4488879e06dSChris Lattner     }
4498879e06dSChris Lattner 
4508879e06dSChris Lattner     // Match the newly constructed regex.
4518879e06dSChris Lattner     RegExToMatch = TmpStr;
4528879e06dSChris Lattner   }
4538879e06dSChris Lattner 
4548879e06dSChris Lattner 
455b16ab0c4SChris Lattner   SmallVector<StringRef, 4> MatchInfo;
4568879e06dSChris Lattner   if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
457f08d2db9SChris Lattner     return StringRef::npos;
458b16ab0c4SChris Lattner 
459b16ab0c4SChris Lattner   // Successful regex match.
460b16ab0c4SChris Lattner   assert(!MatchInfo.empty() && "Didn't get any match");
461b16ab0c4SChris Lattner   StringRef FullMatch = MatchInfo[0];
462b16ab0c4SChris Lattner 
4638879e06dSChris Lattner   // If this defines any variables, remember their values.
4648f870499SBenjamin Kramer   for (const auto &VariableDef : VariableDefs) {
4658f870499SBenjamin Kramer     assert(VariableDef.second < MatchInfo.size() && "Internal paren error");
4668f870499SBenjamin Kramer     VariableTable[VariableDef.first] = MatchInfo[VariableDef.second];
4670a4c44bdSChris Lattner   }
4680a4c44bdSChris Lattner 
469b16ab0c4SChris Lattner   MatchLen = FullMatch.size();
470b16ab0c4SChris Lattner   return FullMatch.data()-Buffer.data();
471f08d2db9SChris Lattner }
472f08d2db9SChris Lattner 
473fd29d886SDaniel Dunbar unsigned Pattern::ComputeMatchDistance(StringRef Buffer,
474fd29d886SDaniel Dunbar                               const StringMap<StringRef> &VariableTable) const {
475fd29d886SDaniel Dunbar   // Just compute the number of matching characters. For regular expressions, we
476fd29d886SDaniel Dunbar   // just compare against the regex itself and hope for the best.
477fd29d886SDaniel Dunbar   //
478fd29d886SDaniel Dunbar   // FIXME: One easy improvement here is have the regex lib generate a single
479fd29d886SDaniel Dunbar   // example regular expression which matches, and use that as the example
480fd29d886SDaniel Dunbar   // string.
481fd29d886SDaniel Dunbar   StringRef ExampleString(FixedStr);
482fd29d886SDaniel Dunbar   if (ExampleString.empty())
483fd29d886SDaniel Dunbar     ExampleString = RegExStr;
484fd29d886SDaniel Dunbar 
485e9aa36c8SDaniel Dunbar   // Only compare up to the first line in the buffer, or the string size.
486e9aa36c8SDaniel Dunbar   StringRef BufferPrefix = Buffer.substr(0, ExampleString.size());
487e9aa36c8SDaniel Dunbar   BufferPrefix = BufferPrefix.split('\n').first;
488e9aa36c8SDaniel Dunbar   return BufferPrefix.edit_distance(ExampleString);
489fd29d886SDaniel Dunbar }
490fd29d886SDaniel Dunbar 
491e0ef65abSDaniel Dunbar void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
492e0ef65abSDaniel Dunbar                                const StringMap<StringRef> &VariableTable) const{
493e0ef65abSDaniel Dunbar   // If this was a regular expression using variables, print the current
494e0ef65abSDaniel Dunbar   // variable values.
495e0ef65abSDaniel Dunbar   if (!VariableUses.empty()) {
4968f870499SBenjamin Kramer     for (const auto &VariableUse : VariableUses) {
497e69170a1SAlp Toker       SmallString<256> Msg;
498e69170a1SAlp Toker       raw_svector_ostream OS(Msg);
4998f870499SBenjamin Kramer       StringRef Var = VariableUse.first;
50092987fb3SAlexander Kornienko       if (Var[0] == '@') {
50192987fb3SAlexander Kornienko         std::string Value;
50292987fb3SAlexander Kornienko         if (EvaluateExpression(Var, Value)) {
50392987fb3SAlexander Kornienko           OS << "with expression \"";
50492987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\" equal to \"";
50592987fb3SAlexander Kornienko           OS.write_escaped(Value) << "\"";
50692987fb3SAlexander Kornienko         } else {
50792987fb3SAlexander Kornienko           OS << "uses incorrect expression \"";
50892987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
50992987fb3SAlexander Kornienko         }
51092987fb3SAlexander Kornienko       } else {
51192987fb3SAlexander Kornienko         StringMap<StringRef>::const_iterator it = VariableTable.find(Var);
512e0ef65abSDaniel Dunbar 
513e0ef65abSDaniel Dunbar         // Check for undefined variable references.
514e0ef65abSDaniel Dunbar         if (it == VariableTable.end()) {
515e0ef65abSDaniel Dunbar           OS << "uses undefined variable \"";
51692987fb3SAlexander Kornienko           OS.write_escaped(Var) << "\"";
517e0ef65abSDaniel Dunbar         } else {
518e0ef65abSDaniel Dunbar           OS << "with variable \"";
519e0ef65abSDaniel Dunbar           OS.write_escaped(Var) << "\" equal to \"";
520e0ef65abSDaniel Dunbar           OS.write_escaped(it->second) << "\"";
521e0ef65abSDaniel Dunbar         }
52292987fb3SAlexander Kornienko       }
523e0ef65abSDaniel Dunbar 
52403b80a40SChris Lattner       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
52503b80a40SChris Lattner                       OS.str());
526e0ef65abSDaniel Dunbar     }
527e0ef65abSDaniel Dunbar   }
528fd29d886SDaniel Dunbar 
529fd29d886SDaniel Dunbar   // Attempt to find the closest/best fuzzy match.  Usually an error happens
530fd29d886SDaniel Dunbar   // because some string in the output didn't exactly match. In these cases, we
531fd29d886SDaniel Dunbar   // would like to show the user a best guess at what "should have" matched, to
532fd29d886SDaniel Dunbar   // save them having to actually check the input manually.
533fd29d886SDaniel Dunbar   size_t NumLinesForward = 0;
534fd29d886SDaniel Dunbar   size_t Best = StringRef::npos;
535fd29d886SDaniel Dunbar   double BestQuality = 0;
536fd29d886SDaniel Dunbar 
537fd29d886SDaniel Dunbar   // Use an arbitrary 4k limit on how far we will search.
5382bf486ebSDan Gohman   for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) {
539fd29d886SDaniel Dunbar     if (Buffer[i] == '\n')
540fd29d886SDaniel Dunbar       ++NumLinesForward;
541fd29d886SDaniel Dunbar 
542df22bbf7SDan Gohman     // Patterns have leading whitespace stripped, so skip whitespace when
543df22bbf7SDan Gohman     // looking for something which looks like a pattern.
544df22bbf7SDan Gohman     if (Buffer[i] == ' ' || Buffer[i] == '\t')
545df22bbf7SDan Gohman       continue;
546df22bbf7SDan Gohman 
547fd29d886SDaniel Dunbar     // Compute the "quality" of this match as an arbitrary combination of the
548fd29d886SDaniel Dunbar     // match distance and the number of lines skipped to get to this match.
549fd29d886SDaniel Dunbar     unsigned Distance = ComputeMatchDistance(Buffer.substr(i), VariableTable);
550fd29d886SDaniel Dunbar     double Quality = Distance + (NumLinesForward / 100.);
551fd29d886SDaniel Dunbar 
552fd29d886SDaniel Dunbar     if (Quality < BestQuality || Best == StringRef::npos) {
553fd29d886SDaniel Dunbar       Best = i;
554fd29d886SDaniel Dunbar       BestQuality = Quality;
555fd29d886SDaniel Dunbar     }
556fd29d886SDaniel Dunbar   }
557fd29d886SDaniel Dunbar 
558fd29d886SDaniel Dunbar   // Print the "possible intended match here" line if we found something
559c069cc8eSDaniel Dunbar   // reasonable and not equal to what we showed in the "scanning from here"
560c069cc8eSDaniel Dunbar   // line.
561c069cc8eSDaniel Dunbar   if (Best && Best != StringRef::npos && BestQuality < 50) {
562fd29d886SDaniel Dunbar       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
56303b80a40SChris Lattner                       SourceMgr::DK_Note, "possible intended match here");
564fd29d886SDaniel Dunbar 
565fd29d886SDaniel Dunbar     // FIXME: If we wanted to be really friendly we would show why the match
566fd29d886SDaniel Dunbar     // failed, as it can be hard to spot simple one character differences.
567fd29d886SDaniel Dunbar   }
568e0ef65abSDaniel Dunbar }
56974d50731SChris Lattner 
57081e5cd9eSAdrian Prantl size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
571061d2baaSEli Bendersky   // Offset keeps track of the current offset within the input Str
572061d2baaSEli Bendersky   size_t Offset = 0;
573061d2baaSEli Bendersky   // [...] Nesting depth
574061d2baaSEli Bendersky   size_t BracketDepth = 0;
575061d2baaSEli Bendersky 
576061d2baaSEli Bendersky   while (!Str.empty()) {
577061d2baaSEli Bendersky     if (Str.startswith("]]") && BracketDepth == 0)
578061d2baaSEli Bendersky       return Offset;
579061d2baaSEli Bendersky     if (Str[0] == '\\') {
580061d2baaSEli Bendersky       // Backslash escapes the next char within regexes, so skip them both.
581061d2baaSEli Bendersky       Str = Str.substr(2);
582061d2baaSEli Bendersky       Offset += 2;
583061d2baaSEli Bendersky     } else {
584061d2baaSEli Bendersky       switch (Str[0]) {
585061d2baaSEli Bendersky         default:
586061d2baaSEli Bendersky           break;
587061d2baaSEli Bendersky         case '[':
588061d2baaSEli Bendersky           BracketDepth++;
589061d2baaSEli Bendersky           break;
590061d2baaSEli Bendersky         case ']':
59181e5cd9eSAdrian Prantl           if (BracketDepth == 0) {
59281e5cd9eSAdrian Prantl             SM.PrintMessage(SMLoc::getFromPointer(Str.data()),
59381e5cd9eSAdrian Prantl                             SourceMgr::DK_Error,
59481e5cd9eSAdrian Prantl                             "missing closing \"]\" for regex variable");
59581e5cd9eSAdrian Prantl             exit(1);
59681e5cd9eSAdrian Prantl           }
597061d2baaSEli Bendersky           BracketDepth--;
598061d2baaSEli Bendersky           break;
599061d2baaSEli Bendersky       }
600061d2baaSEli Bendersky       Str = Str.substr(1);
601061d2baaSEli Bendersky       Offset++;
602061d2baaSEli Bendersky     }
603061d2baaSEli Bendersky   }
604061d2baaSEli Bendersky 
605061d2baaSEli Bendersky   return StringRef::npos;
606061d2baaSEli Bendersky }
607061d2baaSEli Bendersky 
608061d2baaSEli Bendersky 
60974d50731SChris Lattner //===----------------------------------------------------------------------===//
61074d50731SChris Lattner // Check Strings.
61174d50731SChris Lattner //===----------------------------------------------------------------------===//
6123b40b445SChris Lattner 
6133b40b445SChris Lattner /// CheckString - This is a check that we found in the input file.
6143b40b445SChris Lattner struct CheckString {
6153b40b445SChris Lattner   /// Pat - The pattern to match.
6163b40b445SChris Lattner   Pattern Pat;
61726cccfe1SChris Lattner 
61813df4626SMatt Arsenault   /// Prefix - Which prefix name this check matched.
61913df4626SMatt Arsenault   StringRef Prefix;
62013df4626SMatt Arsenault 
62126cccfe1SChris Lattner   /// Loc - The location in the match file that the check string was specified.
62226cccfe1SChris Lattner   SMLoc Loc;
62326cccfe1SChris Lattner 
62438820972SMatt Arsenault   /// CheckTy - Specify what kind of check this is. e.g. CHECK-NEXT: directive,
62538820972SMatt Arsenault   /// as opposed to a CHECK: directive.
62685913ccaSJames Y Knight   //  Check::CheckType CheckTy;
627f8bd2e5bSStephen Lin 
62891a1b2c9SMichael Liao   /// DagNotStrings - These are all of the strings that are disallowed from
629236d2d5eSChris Lattner   /// occurring between this match string and the previous one (or start of
630236d2d5eSChris Lattner   /// file).
63191a1b2c9SMichael Liao   std::vector<Pattern> DagNotStrings;
632236d2d5eSChris Lattner 
63385913ccaSJames Y Knight   CheckString(const Pattern &P, StringRef S, SMLoc L)
63485913ccaSJames Y Knight       : Pat(P), Prefix(S), Loc(L) {}
635dcc7d48dSMichael Liao 
63691a1b2c9SMichael Liao   /// Check - Match check string and its "not strings" and/or "dag strings".
637e93a3a08SStephen Lin   size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
638f8bd2e5bSStephen Lin                size_t &MatchLen, StringMap<StringRef> &VariableTable) const;
639dcc7d48dSMichael Liao 
640dcc7d48dSMichael Liao   /// CheckNext - Verify there is a single line in the given buffer.
641dcc7d48dSMichael Liao   bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
642dcc7d48dSMichael Liao 
64301ac1707SDuncan P. N. Exon Smith   /// CheckSame - Verify there is no newline in the given buffer.
64401ac1707SDuncan P. N. Exon Smith   bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
64501ac1707SDuncan P. N. Exon Smith 
646dcc7d48dSMichael Liao   /// CheckNot - Verify there's no "not strings" in the given buffer.
647dcc7d48dSMichael Liao   bool CheckNot(const SourceMgr &SM, StringRef Buffer,
64891a1b2c9SMichael Liao                 const std::vector<const Pattern *> &NotStrings,
64991a1b2c9SMichael Liao                 StringMap<StringRef> &VariableTable) const;
65091a1b2c9SMichael Liao 
65191a1b2c9SMichael Liao   /// CheckDag - Match "dag strings" and their mixed "not strings".
65291a1b2c9SMichael Liao   size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
65391a1b2c9SMichael Liao                   std::vector<const Pattern *> &NotStrings,
654dcc7d48dSMichael Liao                   StringMap<StringRef> &VariableTable) const;
65526cccfe1SChris Lattner };
65626cccfe1SChris Lattner 
657*20247900SChandler Carruth /// Canonicalize whitespaces in the file. Line endings are replaced with
658*20247900SChandler Carruth /// UNIX-style '\n'.
6595ea04c38SGuy Benyei ///
6605ea04c38SGuy Benyei /// \param PreserveHorizontal Don't squash consecutive horizontal whitespace
6615ea04c38SGuy Benyei /// characters to a single space.
662*20247900SChandler Carruth static StringRef CanonicalizeFile(MemoryBuffer &MB, bool PreserveHorizontal,
663*20247900SChandler Carruth                                   SmallVectorImpl<char> &OutputBuffer) {
664*20247900SChandler Carruth   OutputBuffer.reserve(MB.getBufferSize());
665a2f8fc5aSChris Lattner 
666*20247900SChandler Carruth   for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd();
667a2f8fc5aSChris Lattner        Ptr != End; ++Ptr) {
668fd781bf0SNAKAMURA Takumi     // Eliminate trailing dosish \r.
669fd781bf0SNAKAMURA Takumi     if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
670fd781bf0SNAKAMURA Takumi       continue;
671fd781bf0SNAKAMURA Takumi     }
672fd781bf0SNAKAMURA Takumi 
6735ea04c38SGuy Benyei     // If current char is not a horizontal whitespace or if horizontal
6745ea04c38SGuy Benyei     // whitespace canonicalization is disabled, dump it to output as is.
6755ea04c38SGuy Benyei     if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) {
676*20247900SChandler Carruth       OutputBuffer.push_back(*Ptr);
677a2f8fc5aSChris Lattner       continue;
678a2f8fc5aSChris Lattner     }
679a2f8fc5aSChris Lattner 
680a2f8fc5aSChris Lattner     // Otherwise, add one space and advance over neighboring space.
681*20247900SChandler Carruth     OutputBuffer.push_back(' ');
682a2f8fc5aSChris Lattner     while (Ptr+1 != End &&
683a2f8fc5aSChris Lattner            (Ptr[1] == ' ' || Ptr[1] == '\t'))
684a2f8fc5aSChris Lattner       ++Ptr;
685a2f8fc5aSChris Lattner   }
686a2f8fc5aSChris Lattner 
687*20247900SChandler Carruth   // Add a null byte and then return all but that byte.
688*20247900SChandler Carruth   OutputBuffer.push_back('\0');
689*20247900SChandler Carruth   return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1);
690a2f8fc5aSChris Lattner }
691a2f8fc5aSChris Lattner 
69238820972SMatt Arsenault static bool IsPartOfWord(char c) {
69338820972SMatt Arsenault   return (isalnum(c) || c == '-' || c == '_');
69438820972SMatt Arsenault }
69538820972SMatt Arsenault 
69613df4626SMatt Arsenault // Get the size of the prefix extension.
69713df4626SMatt Arsenault static size_t CheckTypeSize(Check::CheckType Ty) {
69813df4626SMatt Arsenault   switch (Ty) {
69913df4626SMatt Arsenault   case Check::CheckNone:
700a908e7bdSPaul Robinson   case Check::CheckBadNot:
70113df4626SMatt Arsenault     return 0;
70213df4626SMatt Arsenault 
70313df4626SMatt Arsenault   case Check::CheckPlain:
70413df4626SMatt Arsenault     return sizeof(":") - 1;
70513df4626SMatt Arsenault 
70613df4626SMatt Arsenault   case Check::CheckNext:
70713df4626SMatt Arsenault     return sizeof("-NEXT:") - 1;
70813df4626SMatt Arsenault 
70901ac1707SDuncan P. N. Exon Smith   case Check::CheckSame:
71001ac1707SDuncan P. N. Exon Smith     return sizeof("-SAME:") - 1;
71101ac1707SDuncan P. N. Exon Smith 
71213df4626SMatt Arsenault   case Check::CheckNot:
71313df4626SMatt Arsenault     return sizeof("-NOT:") - 1;
71413df4626SMatt Arsenault 
71513df4626SMatt Arsenault   case Check::CheckDAG:
71613df4626SMatt Arsenault     return sizeof("-DAG:") - 1;
71713df4626SMatt Arsenault 
71813df4626SMatt Arsenault   case Check::CheckLabel:
71913df4626SMatt Arsenault     return sizeof("-LABEL:") - 1;
72013df4626SMatt Arsenault 
72113df4626SMatt Arsenault   case Check::CheckEOF:
72213df4626SMatt Arsenault     llvm_unreachable("Should not be using EOF size");
72313df4626SMatt Arsenault   }
72413df4626SMatt Arsenault 
72513df4626SMatt Arsenault   llvm_unreachable("Bad check type");
72613df4626SMatt Arsenault }
72713df4626SMatt Arsenault 
72813df4626SMatt Arsenault static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
729c4d2d471SMatt Arsenault   char NextChar = Buffer[Prefix.size()];
73038820972SMatt Arsenault 
73138820972SMatt Arsenault   // Verify that the : is present after the prefix.
73213df4626SMatt Arsenault   if (NextChar == ':')
73338820972SMatt Arsenault     return Check::CheckPlain;
73438820972SMatt Arsenault 
73513df4626SMatt Arsenault   if (NextChar != '-')
73638820972SMatt Arsenault     return Check::CheckNone;
73738820972SMatt Arsenault 
738c4d2d471SMatt Arsenault   StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
73913df4626SMatt Arsenault   if (Rest.startswith("NEXT:"))
74038820972SMatt Arsenault     return Check::CheckNext;
74138820972SMatt Arsenault 
74201ac1707SDuncan P. N. Exon Smith   if (Rest.startswith("SAME:"))
74301ac1707SDuncan P. N. Exon Smith     return Check::CheckSame;
74401ac1707SDuncan P. N. Exon Smith 
74513df4626SMatt Arsenault   if (Rest.startswith("NOT:"))
74638820972SMatt Arsenault     return Check::CheckNot;
74738820972SMatt Arsenault 
74813df4626SMatt Arsenault   if (Rest.startswith("DAG:"))
74938820972SMatt Arsenault     return Check::CheckDAG;
75038820972SMatt Arsenault 
75113df4626SMatt Arsenault   if (Rest.startswith("LABEL:"))
75238820972SMatt Arsenault     return Check::CheckLabel;
75313df4626SMatt Arsenault 
754a908e7bdSPaul Robinson   // You can't combine -NOT with another suffix.
755a908e7bdSPaul Robinson   if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
756a908e7bdSPaul Robinson       Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
757a908e7bdSPaul Robinson       Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:"))
758a908e7bdSPaul Robinson     return Check::CheckBadNot;
759a908e7bdSPaul Robinson 
76013df4626SMatt Arsenault   return Check::CheckNone;
76138820972SMatt Arsenault }
76238820972SMatt Arsenault 
76313df4626SMatt Arsenault // From the given position, find the next character after the word.
76413df4626SMatt Arsenault static size_t SkipWord(StringRef Str, size_t Loc) {
76513df4626SMatt Arsenault   while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
76613df4626SMatt Arsenault     ++Loc;
76713df4626SMatt Arsenault   return Loc;
76813df4626SMatt Arsenault }
76913df4626SMatt Arsenault 
77013df4626SMatt Arsenault // Try to find the first match in buffer for any prefix. If a valid match is
77113df4626SMatt Arsenault // found, return that prefix and set its type and location.  If there are almost
77213df4626SMatt Arsenault // matches (e.g. the actual prefix string is found, but is not an actual check
77313df4626SMatt Arsenault // string), but no valid match, return an empty string and set the position to
77413df4626SMatt Arsenault // resume searching from. If no partial matches are found, return an empty
77513df4626SMatt Arsenault // string and the location will be StringRef::npos. If one prefix is a substring
77613df4626SMatt Arsenault // of another, the maximal match should be found. e.g. if "A" and "AA" are
77713df4626SMatt Arsenault // prefixes then AA-CHECK: should match the second one.
77813df4626SMatt Arsenault static StringRef FindFirstCandidateMatch(StringRef &Buffer,
77913df4626SMatt Arsenault                                          Check::CheckType &CheckTy,
78013df4626SMatt Arsenault                                          size_t &CheckLoc) {
78113df4626SMatt Arsenault   StringRef FirstPrefix;
78213df4626SMatt Arsenault   size_t FirstLoc = StringRef::npos;
78313df4626SMatt Arsenault   size_t SearchLoc = StringRef::npos;
78413df4626SMatt Arsenault   Check::CheckType FirstTy = Check::CheckNone;
78513df4626SMatt Arsenault 
78613df4626SMatt Arsenault   CheckTy = Check::CheckNone;
78713df4626SMatt Arsenault   CheckLoc = StringRef::npos;
78813df4626SMatt Arsenault 
7898f870499SBenjamin Kramer   for (StringRef Prefix : CheckPrefixes) {
79013df4626SMatt Arsenault     size_t PrefixLoc = Buffer.find(Prefix);
79113df4626SMatt Arsenault 
79213df4626SMatt Arsenault     if (PrefixLoc == StringRef::npos)
79313df4626SMatt Arsenault       continue;
79413df4626SMatt Arsenault 
79513df4626SMatt Arsenault     // Track where we are searching for invalid prefixes that look almost right.
79613df4626SMatt Arsenault     // We need to only advance to the first partial match on the next attempt
79713df4626SMatt Arsenault     // since a partial match could be a substring of a later, valid prefix.
79813df4626SMatt Arsenault     // Need to skip to the end of the word, otherwise we could end up
79913df4626SMatt Arsenault     // matching a prefix in a substring later.
80013df4626SMatt Arsenault     if (PrefixLoc < SearchLoc)
80113df4626SMatt Arsenault       SearchLoc = SkipWord(Buffer, PrefixLoc);
80213df4626SMatt Arsenault 
80313df4626SMatt Arsenault     // We only want to find the first match to avoid skipping some.
80413df4626SMatt Arsenault     if (PrefixLoc > FirstLoc)
80513df4626SMatt Arsenault       continue;
806a7181a1bSAlexey Samsonov     // If one matching check-prefix is a prefix of another, choose the
807a7181a1bSAlexey Samsonov     // longer one.
808a7181a1bSAlexey Samsonov     if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size())
809a7181a1bSAlexey Samsonov       continue;
81013df4626SMatt Arsenault 
81113df4626SMatt Arsenault     StringRef Rest = Buffer.drop_front(PrefixLoc);
81213df4626SMatt Arsenault     // Make sure we have actually found the prefix, and not a word containing
81313df4626SMatt Arsenault     // it. This should also prevent matching the wrong prefix when one is a
81413df4626SMatt Arsenault     // substring of another.
81513df4626SMatt Arsenault     if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
81643b5f572SDaniel Sanders       FirstTy = Check::CheckNone;
81743b5f572SDaniel Sanders     else
81843b5f572SDaniel Sanders       FirstTy = FindCheckType(Rest, Prefix);
81913df4626SMatt Arsenault 
82013df4626SMatt Arsenault     FirstLoc = PrefixLoc;
821a7181a1bSAlexey Samsonov     FirstPrefix = Prefix;
82213df4626SMatt Arsenault   }
82313df4626SMatt Arsenault 
824a7181a1bSAlexey Samsonov   // If the first prefix is invalid, we should continue the search after it.
825a7181a1bSAlexey Samsonov   if (FirstTy == Check::CheckNone) {
82613df4626SMatt Arsenault     CheckLoc = SearchLoc;
827a7181a1bSAlexey Samsonov     return "";
828a7181a1bSAlexey Samsonov   }
829a7181a1bSAlexey Samsonov 
83013df4626SMatt Arsenault   CheckTy = FirstTy;
83113df4626SMatt Arsenault   CheckLoc = FirstLoc;
83213df4626SMatt Arsenault   return FirstPrefix;
83313df4626SMatt Arsenault }
83413df4626SMatt Arsenault 
83513df4626SMatt Arsenault static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
83613df4626SMatt Arsenault                                          unsigned &LineNumber,
83713df4626SMatt Arsenault                                          Check::CheckType &CheckTy,
83813df4626SMatt Arsenault                                          size_t &CheckLoc) {
83913df4626SMatt Arsenault   while (!Buffer.empty()) {
84013df4626SMatt Arsenault     StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc);
84113df4626SMatt Arsenault     // If we found a real match, we are done.
84213df4626SMatt Arsenault     if (!Prefix.empty()) {
84313df4626SMatt Arsenault       LineNumber += Buffer.substr(0, CheckLoc).count('\n');
84413df4626SMatt Arsenault       return Prefix;
84513df4626SMatt Arsenault     }
84613df4626SMatt Arsenault 
84713df4626SMatt Arsenault     // We didn't find any almost matches either, we are also done.
84813df4626SMatt Arsenault     if (CheckLoc == StringRef::npos)
84913df4626SMatt Arsenault       return StringRef();
85013df4626SMatt Arsenault 
85113df4626SMatt Arsenault     LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
85213df4626SMatt Arsenault 
85313df4626SMatt Arsenault     // Advance to the last possible match we found and try again.
85413df4626SMatt Arsenault     Buffer = Buffer.drop_front(CheckLoc + 1);
85513df4626SMatt Arsenault   }
85613df4626SMatt Arsenault 
85713df4626SMatt Arsenault   return StringRef();
85838820972SMatt Arsenault }
859ee3c74fbSChris Lattner 
860ee3c74fbSChris Lattner /// ReadCheckFile - Read the check file, which specifies the sequence of
861ee3c74fbSChris Lattner /// expected strings.  The strings are added to the CheckStrings vector.
86243d50d4aSEli Bendersky /// Returns true in case of an error, false otherwise.
863*20247900SChandler Carruth static bool ReadCheckFile(SourceMgr &SM, StringRef Buffer,
86426cccfe1SChris Lattner                           std::vector<CheckString> &CheckStrings) {
86556ccdbbdSAlexander Kornienko   std::vector<Pattern> ImplicitNegativeChecks;
86656ccdbbdSAlexander Kornienko   for (const auto &PatternString : ImplicitCheckNot) {
86756ccdbbdSAlexander Kornienko     // Create a buffer with fake command line content in order to display the
86856ccdbbdSAlexander Kornienko     // command line option responsible for the specific implicit CHECK-NOT.
869ff43d69dSDavid Blaikie     std::string Prefix = (Twine("-") + ImplicitCheckNot.ArgStr + "='").str();
87056ccdbbdSAlexander Kornienko     std::string Suffix = "'";
8713560ff2cSRafael Espindola     std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
8723560ff2cSRafael Espindola         Prefix + PatternString + Suffix, "command line");
8733560ff2cSRafael Espindola 
87456ccdbbdSAlexander Kornienko     StringRef PatternInBuffer =
87556ccdbbdSAlexander Kornienko         CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
8761961f14cSDavid Blaikie     SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
87756ccdbbdSAlexander Kornienko 
87856ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
87956ccdbbdSAlexander Kornienko     ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
88056ccdbbdSAlexander Kornienko                                                "IMPLICIT-CHECK", SM, 0);
88156ccdbbdSAlexander Kornienko   }
88256ccdbbdSAlexander Kornienko 
88356ccdbbdSAlexander Kornienko 
88456ccdbbdSAlexander Kornienko   std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
885236d2d5eSChris Lattner 
88643d50d4aSEli Bendersky   // LineNumber keeps track of the line on which CheckPrefix instances are
88743d50d4aSEli Bendersky   // found.
88892987fb3SAlexander Kornienko   unsigned LineNumber = 1;
88992987fb3SAlexander Kornienko 
890ee3c74fbSChris Lattner   while (1) {
89113df4626SMatt Arsenault     Check::CheckType CheckTy;
89213df4626SMatt Arsenault     size_t PrefixLoc;
89313df4626SMatt Arsenault 
89413df4626SMatt Arsenault     // See if a prefix occurs in the memory buffer.
89513df4626SMatt Arsenault     StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
89613df4626SMatt Arsenault                                                    LineNumber,
89713df4626SMatt Arsenault                                                    CheckTy,
89813df4626SMatt Arsenault                                                    PrefixLoc);
89913df4626SMatt Arsenault     if (UsedPrefix.empty())
900ee3c74fbSChris Lattner       break;
901ee3c74fbSChris Lattner 
90213df4626SMatt Arsenault     Buffer = Buffer.drop_front(PrefixLoc);
90392987fb3SAlexander Kornienko 
90413df4626SMatt Arsenault     // Location to use for error messages.
90513df4626SMatt Arsenault     const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
90692987fb3SAlexander Kornienko 
90713df4626SMatt Arsenault     // PrefixLoc is to the start of the prefix. Skip to the end.
90813df4626SMatt Arsenault     Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
90910f10cedSChris Lattner 
910a908e7bdSPaul Robinson     // Complain about useful-looking but unsupported suffixes.
911a908e7bdSPaul Robinson     if (CheckTy == Check::CheckBadNot) {
912a908e7bdSPaul Robinson       SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
913a908e7bdSPaul Robinson                       SourceMgr::DK_Error,
914a908e7bdSPaul Robinson                       "unsupported -NOT combo on prefix '" + UsedPrefix + "'");
915a908e7bdSPaul Robinson       return true;
916a908e7bdSPaul Robinson     }
917a908e7bdSPaul Robinson 
91838820972SMatt Arsenault     // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
91938820972SMatt Arsenault     // leading and trailing whitespace.
920236d2d5eSChris Lattner     Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
921ee3c74fbSChris Lattner 
922ee3c74fbSChris Lattner     // Scan ahead to the end of line.
923caa5fc0cSChris Lattner     size_t EOL = Buffer.find_first_of("\n\r");
924ee3c74fbSChris Lattner 
925838fb09aSDan Gohman     // Remember the location of the start of the pattern, for diagnostics.
926838fb09aSDan Gohman     SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
927838fb09aSDan Gohman 
92874d50731SChris Lattner     // Parse the pattern.
92938820972SMatt Arsenault     Pattern P(CheckTy);
93013df4626SMatt Arsenault     if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
931ee3c74fbSChris Lattner       return true;
932ee3c74fbSChris Lattner 
933f8bd2e5bSStephen Lin     // Verify that CHECK-LABEL lines do not define or use variables
93438820972SMatt Arsenault     if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
93513df4626SMatt Arsenault       SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
936f8bd2e5bSStephen Lin                       SourceMgr::DK_Error,
93713df4626SMatt Arsenault                       "found '" + UsedPrefix + "-LABEL:'"
93813df4626SMatt Arsenault                       " with variable definition or use");
939f8bd2e5bSStephen Lin       return true;
940f8bd2e5bSStephen Lin     }
941f8bd2e5bSStephen Lin 
942236d2d5eSChris Lattner     Buffer = Buffer.substr(EOL);
94374d50731SChris Lattner 
944da108b4eSChris Lattner     // Verify that CHECK-NEXT lines have at least one CHECK line before them.
94501ac1707SDuncan P. N. Exon Smith     if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&
94601ac1707SDuncan P. N. Exon Smith         CheckStrings.empty()) {
94701ac1707SDuncan P. N. Exon Smith       StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";
94813df4626SMatt Arsenault       SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
94903b80a40SChris Lattner                       SourceMgr::DK_Error,
95001ac1707SDuncan P. N. Exon Smith                       "found '" + UsedPrefix + "-" + Type + "' without previous '"
95113df4626SMatt Arsenault                       + UsedPrefix + ": line");
952da108b4eSChris Lattner       return true;
953da108b4eSChris Lattner     }
954da108b4eSChris Lattner 
95591a1b2c9SMichael Liao     // Handle CHECK-DAG/-NOT.
95638820972SMatt Arsenault     if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
95791a1b2c9SMichael Liao       DagNotMatches.push_back(P);
95874d50731SChris Lattner       continue;
95974d50731SChris Lattner     }
96074d50731SChris Lattner 
961ee3c74fbSChris Lattner     // Okay, add the string we captured to the output vector and move on.
96285913ccaSJames Y Knight     CheckStrings.emplace_back(P, UsedPrefix, PatternLoc);
96391a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
96456ccdbbdSAlexander Kornienko     DagNotMatches = ImplicitNegativeChecks;
965ee3c74fbSChris Lattner   }
966ee3c74fbSChris Lattner 
96713df4626SMatt Arsenault   // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
96813df4626SMatt Arsenault   // prefix as a filler for the error message.
96991a1b2c9SMichael Liao   if (!DagNotMatches.empty()) {
970f5e2fc47SBenjamin Kramer     CheckStrings.emplace_back(Pattern(Check::CheckEOF), *CheckPrefixes.begin(),
97185913ccaSJames Y Knight                               SMLoc::getFromPointer(Buffer.data()));
97291a1b2c9SMichael Liao     std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
973eba55822SJakob Stoklund Olesen   }
974eba55822SJakob Stoklund Olesen 
975ee3c74fbSChris Lattner   if (CheckStrings.empty()) {
97613df4626SMatt Arsenault     errs() << "error: no check strings found with prefix"
97713df4626SMatt Arsenault            << (CheckPrefixes.size() > 1 ? "es " : " ");
9783e3ef2f2SChris Bieneman     prefix_iterator I = CheckPrefixes.begin();
9793e3ef2f2SChris Bieneman     prefix_iterator E = CheckPrefixes.end();
9803e3ef2f2SChris Bieneman     if (I != E) {
9813e3ef2f2SChris Bieneman       errs() << "\'" << *I << ":'";
9823e3ef2f2SChris Bieneman       ++I;
98313df4626SMatt Arsenault     }
9843e3ef2f2SChris Bieneman     for (; I != E; ++I)
9853e3ef2f2SChris Bieneman       errs() << ", \'" << *I << ":'";
98613df4626SMatt Arsenault 
98713df4626SMatt Arsenault     errs() << '\n';
988ee3c74fbSChris Lattner     return true;
989ee3c74fbSChris Lattner   }
990ee3c74fbSChris Lattner 
991ee3c74fbSChris Lattner   return false;
992ee3c74fbSChris Lattner }
993ee3c74fbSChris Lattner 
9943c76c523SCraig Topper static void PrintCheckFailed(const SourceMgr &SM, SMLoc Loc,
99591a1b2c9SMichael Liao                              const Pattern &Pat, StringRef Buffer,
996e0ef65abSDaniel Dunbar                              StringMap<StringRef> &VariableTable) {
997da108b4eSChris Lattner   // Otherwise, we have an error, emit an error message.
99891a1b2c9SMichael Liao   SM.PrintMessage(Loc, SourceMgr::DK_Error,
99903b80a40SChris Lattner                   "expected string not found in input");
1000da108b4eSChris Lattner 
1001da108b4eSChris Lattner   // Print the "scanning from here" line.  If the current position is at the
1002da108b4eSChris Lattner   // end of a line, advance to the start of the next line.
1003caa5fc0cSChris Lattner   Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
1004da108b4eSChris Lattner 
100503b80a40SChris Lattner   SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
100603b80a40SChris Lattner                   "scanning from here");
1007e0ef65abSDaniel Dunbar 
1008e0ef65abSDaniel Dunbar   // Allow the pattern to print additional information if desired.
100991a1b2c9SMichael Liao   Pat.PrintFailureInfo(SM, Buffer, VariableTable);
101091a1b2c9SMichael Liao }
101191a1b2c9SMichael Liao 
101291a1b2c9SMichael Liao static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
101391a1b2c9SMichael Liao                              StringRef Buffer,
101491a1b2c9SMichael Liao                              StringMap<StringRef> &VariableTable) {
101591a1b2c9SMichael Liao   PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable);
1016da108b4eSChris Lattner }
1017da108b4eSChris Lattner 
101837183584SChris Lattner /// CountNumNewlinesBetween - Count the number of newlines in the specified
101937183584SChris Lattner /// range.
1020592fe880SRichard Smith static unsigned CountNumNewlinesBetween(StringRef Range,
1021592fe880SRichard Smith                                         const char *&FirstNewLine) {
1022da108b4eSChris Lattner   unsigned NumNewLines = 0;
102337183584SChris Lattner   while (1) {
1024da108b4eSChris Lattner     // Scan for newline.
102537183584SChris Lattner     Range = Range.substr(Range.find_first_of("\n\r"));
102637183584SChris Lattner     if (Range.empty()) return NumNewLines;
1027da108b4eSChris Lattner 
1028da108b4eSChris Lattner     ++NumNewLines;
1029da108b4eSChris Lattner 
1030da108b4eSChris Lattner     // Handle \n\r and \r\n as a single newline.
103137183584SChris Lattner     if (Range.size() > 1 &&
103237183584SChris Lattner         (Range[1] == '\n' || Range[1] == '\r') &&
103337183584SChris Lattner         (Range[0] != Range[1]))
103437183584SChris Lattner       Range = Range.substr(1);
103537183584SChris Lattner     Range = Range.substr(1);
1036592fe880SRichard Smith 
1037592fe880SRichard Smith     if (NumNewLines == 1)
1038592fe880SRichard Smith       FirstNewLine = Range.begin();
1039da108b4eSChris Lattner   }
1040da108b4eSChris Lattner }
1041da108b4eSChris Lattner 
1042dcc7d48dSMichael Liao size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer,
1043e93a3a08SStephen Lin                           bool IsLabelScanMode, size_t &MatchLen,
1044dcc7d48dSMichael Liao                           StringMap<StringRef> &VariableTable) const {
104591a1b2c9SMichael Liao   size_t LastPos = 0;
104691a1b2c9SMichael Liao   std::vector<const Pattern *> NotStrings;
104791a1b2c9SMichael Liao 
1048e93a3a08SStephen Lin   // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
1049e93a3a08SStephen Lin   // bounds; we have not processed variable definitions within the bounded block
1050e93a3a08SStephen Lin   // yet so cannot handle any final CHECK-DAG yet; this is handled when going
1051e93a3a08SStephen Lin   // over the block again (including the last CHECK-LABEL) in normal mode.
1052e93a3a08SStephen Lin   if (!IsLabelScanMode) {
105391a1b2c9SMichael Liao     // Match "dag strings" (with mixed "not strings" if any).
105491a1b2c9SMichael Liao     LastPos = CheckDag(SM, Buffer, NotStrings, VariableTable);
105591a1b2c9SMichael Liao     if (LastPos == StringRef::npos)
105691a1b2c9SMichael Liao       return StringRef::npos;
1057e93a3a08SStephen Lin   }
105891a1b2c9SMichael Liao 
105991a1b2c9SMichael Liao   // Match itself from the last position after matching CHECK-DAG.
106091a1b2c9SMichael Liao   StringRef MatchBuffer = Buffer.substr(LastPos);
106191a1b2c9SMichael Liao   size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
1062dcc7d48dSMichael Liao   if (MatchPos == StringRef::npos) {
106391a1b2c9SMichael Liao     PrintCheckFailed(SM, *this, MatchBuffer, VariableTable);
1064dcc7d48dSMichael Liao     return StringRef::npos;
1065dcc7d48dSMichael Liao   }
1066dcc7d48dSMichael Liao 
1067e93a3a08SStephen Lin   // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
1068e93a3a08SStephen Lin   // or CHECK-NOT
1069e93a3a08SStephen Lin   if (!IsLabelScanMode) {
107091a1b2c9SMichael Liao     StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1071dcc7d48dSMichael Liao 
1072dcc7d48dSMichael Liao     // If this check is a "CHECK-NEXT", verify that the previous match was on
1073dcc7d48dSMichael Liao     // the previous line (i.e. that there is one newline between them).
1074dcc7d48dSMichael Liao     if (CheckNext(SM, SkippedRegion))
1075dcc7d48dSMichael Liao       return StringRef::npos;
1076dcc7d48dSMichael Liao 
107701ac1707SDuncan P. N. Exon Smith     // If this check is a "CHECK-SAME", verify that the previous match was on
107801ac1707SDuncan P. N. Exon Smith     // the same line (i.e. that there is no newline between them).
107901ac1707SDuncan P. N. Exon Smith     if (CheckSame(SM, SkippedRegion))
108001ac1707SDuncan P. N. Exon Smith       return StringRef::npos;
108101ac1707SDuncan P. N. Exon Smith 
1082dcc7d48dSMichael Liao     // If this match had "not strings", verify that they don't exist in the
1083dcc7d48dSMichael Liao     // skipped region.
108491a1b2c9SMichael Liao     if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
1085dcc7d48dSMichael Liao       return StringRef::npos;
1086f8bd2e5bSStephen Lin   }
1087dcc7d48dSMichael Liao 
10887dfb92b9SMehdi Amini   return LastPos + MatchPos;
1089dcc7d48dSMichael Liao }
1090dcc7d48dSMichael Liao 
1091dcc7d48dSMichael Liao bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
109285913ccaSJames Y Knight   if (Pat.getCheckTy() != Check::CheckNext)
1093dcc7d48dSMichael Liao     return false;
1094dcc7d48dSMichael Liao 
1095dcc7d48dSMichael Liao   // Count the number of newlines between the previous match and this one.
1096dcc7d48dSMichael Liao   assert(Buffer.data() !=
1097dcc7d48dSMichael Liao          SM.getMemoryBuffer(
1098dcc7d48dSMichael Liao            SM.FindBufferContainingLoc(
1099dcc7d48dSMichael Liao              SMLoc::getFromPointer(Buffer.data())))->getBufferStart() &&
1100dcc7d48dSMichael Liao          "CHECK-NEXT can't be the first check in a file");
1101dcc7d48dSMichael Liao 
110266f09ad0SCraig Topper   const char *FirstNewLine = nullptr;
1103592fe880SRichard Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
1104dcc7d48dSMichael Liao 
1105dcc7d48dSMichael Liao   if (NumNewLines == 0) {
110613df4626SMatt Arsenault     SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
1107dcc7d48dSMichael Liao                     "-NEXT: is on the same line as previous match");
1108dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1109dcc7d48dSMichael Liao                     SourceMgr::DK_Note, "'next' match was here");
1110dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1111dcc7d48dSMichael Liao                     "previous match ended here");
1112dcc7d48dSMichael Liao     return true;
1113dcc7d48dSMichael Liao   }
1114dcc7d48dSMichael Liao 
1115dcc7d48dSMichael Liao   if (NumNewLines != 1) {
111613df4626SMatt Arsenault     SM.PrintMessage(Loc, SourceMgr::DK_Error, Prefix +
1117dcc7d48dSMichael Liao                     "-NEXT: is not on the line after the previous match");
1118dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()),
1119dcc7d48dSMichael Liao                     SourceMgr::DK_Note, "'next' match was here");
1120dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1121dcc7d48dSMichael Liao                     "previous match ended here");
1122592fe880SRichard Smith     SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
1123592fe880SRichard Smith                     "non-matching line after previous match is here");
1124dcc7d48dSMichael Liao     return true;
1125dcc7d48dSMichael Liao   }
1126dcc7d48dSMichael Liao 
1127dcc7d48dSMichael Liao   return false;
1128dcc7d48dSMichael Liao }
1129dcc7d48dSMichael Liao 
113001ac1707SDuncan P. N. Exon Smith bool CheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
113185913ccaSJames Y Knight   if (Pat.getCheckTy() != Check::CheckSame)
113201ac1707SDuncan P. N. Exon Smith     return false;
113301ac1707SDuncan P. N. Exon Smith 
113401ac1707SDuncan P. N. Exon Smith   // Count the number of newlines between the previous match and this one.
113501ac1707SDuncan P. N. Exon Smith   assert(Buffer.data() !=
113601ac1707SDuncan P. N. Exon Smith              SM.getMemoryBuffer(SM.FindBufferContainingLoc(
113701ac1707SDuncan P. N. Exon Smith                                     SMLoc::getFromPointer(Buffer.data())))
113801ac1707SDuncan P. N. Exon Smith                  ->getBufferStart() &&
113901ac1707SDuncan P. N. Exon Smith          "CHECK-SAME can't be the first check in a file");
114001ac1707SDuncan P. N. Exon Smith 
114101ac1707SDuncan P. N. Exon Smith   const char *FirstNewLine = nullptr;
114201ac1707SDuncan P. N. Exon Smith   unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
114301ac1707SDuncan P. N. Exon Smith 
114401ac1707SDuncan P. N. Exon Smith   if (NumNewLines != 0) {
114501ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(Loc, SourceMgr::DK_Error,
114601ac1707SDuncan P. N. Exon Smith                     Prefix +
114701ac1707SDuncan P. N. Exon Smith                         "-SAME: is not on the same line as the previous match");
114801ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
114901ac1707SDuncan P. N. Exon Smith                     "'next' match was here");
115001ac1707SDuncan P. N. Exon Smith     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
115101ac1707SDuncan P. N. Exon Smith                     "previous match ended here");
115201ac1707SDuncan P. N. Exon Smith     return true;
115301ac1707SDuncan P. N. Exon Smith   }
115401ac1707SDuncan P. N. Exon Smith 
115501ac1707SDuncan P. N. Exon Smith   return false;
115601ac1707SDuncan P. N. Exon Smith }
115701ac1707SDuncan P. N. Exon Smith 
1158dcc7d48dSMichael Liao bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
115991a1b2c9SMichael Liao                            const std::vector<const Pattern *> &NotStrings,
1160dcc7d48dSMichael Liao                            StringMap<StringRef> &VariableTable) const {
11618f870499SBenjamin Kramer   for (const Pattern *Pat : NotStrings) {
116238820972SMatt Arsenault     assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
116391a1b2c9SMichael Liao 
1164dcc7d48dSMichael Liao     size_t MatchLen = 0;
116591a1b2c9SMichael Liao     size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable);
1166dcc7d48dSMichael Liao 
1167dcc7d48dSMichael Liao     if (Pos == StringRef::npos) continue;
1168dcc7d48dSMichael Liao 
1169dcc7d48dSMichael Liao     SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()+Pos),
1170dcc7d48dSMichael Liao                     SourceMgr::DK_Error,
117113df4626SMatt Arsenault                     Prefix + "-NOT: string occurred!");
117291a1b2c9SMichael Liao     SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note,
117313df4626SMatt Arsenault                     Prefix + "-NOT: pattern specified here");
1174dcc7d48dSMichael Liao     return true;
1175dcc7d48dSMichael Liao   }
1176dcc7d48dSMichael Liao 
1177dcc7d48dSMichael Liao   return false;
1178dcc7d48dSMichael Liao }
1179dcc7d48dSMichael Liao 
118091a1b2c9SMichael Liao size_t CheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
118191a1b2c9SMichael Liao                              std::vector<const Pattern *> &NotStrings,
118291a1b2c9SMichael Liao                              StringMap<StringRef> &VariableTable) const {
118391a1b2c9SMichael Liao   if (DagNotStrings.empty())
118491a1b2c9SMichael Liao     return 0;
118591a1b2c9SMichael Liao 
118691a1b2c9SMichael Liao   size_t LastPos = 0;
118791a1b2c9SMichael Liao   size_t StartPos = LastPos;
118891a1b2c9SMichael Liao 
11898f870499SBenjamin Kramer   for (const Pattern &Pat : DagNotStrings) {
119038820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG ||
119138820972SMatt Arsenault             Pat.getCheckTy() == Check::CheckNot) &&
119291a1b2c9SMichael Liao            "Invalid CHECK-DAG or CHECK-NOT!");
119391a1b2c9SMichael Liao 
119438820972SMatt Arsenault     if (Pat.getCheckTy() == Check::CheckNot) {
119591a1b2c9SMichael Liao       NotStrings.push_back(&Pat);
119691a1b2c9SMichael Liao       continue;
119791a1b2c9SMichael Liao     }
119891a1b2c9SMichael Liao 
119938820972SMatt Arsenault     assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!");
120091a1b2c9SMichael Liao 
120191a1b2c9SMichael Liao     size_t MatchLen = 0, MatchPos;
120291a1b2c9SMichael Liao 
120391a1b2c9SMichael Liao     // CHECK-DAG always matches from the start.
120491a1b2c9SMichael Liao     StringRef MatchBuffer = Buffer.substr(StartPos);
120591a1b2c9SMichael Liao     MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable);
120691a1b2c9SMichael Liao     // With a group of CHECK-DAGs, a single mismatching means the match on
120791a1b2c9SMichael Liao     // that group of CHECK-DAGs fails immediately.
120891a1b2c9SMichael Liao     if (MatchPos == StringRef::npos) {
120991a1b2c9SMichael Liao       PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable);
121091a1b2c9SMichael Liao       return StringRef::npos;
121191a1b2c9SMichael Liao     }
121291a1b2c9SMichael Liao     // Re-calc it as the offset relative to the start of the original string.
121391a1b2c9SMichael Liao     MatchPos += StartPos;
121491a1b2c9SMichael Liao 
121591a1b2c9SMichael Liao     if (!NotStrings.empty()) {
121691a1b2c9SMichael Liao       if (MatchPos < LastPos) {
121791a1b2c9SMichael Liao         // Reordered?
121891a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos),
121991a1b2c9SMichael Liao                         SourceMgr::DK_Error,
122013df4626SMatt Arsenault                         Prefix + "-DAG: found a match of CHECK-DAG"
122191a1b2c9SMichael Liao                         " reordering across a CHECK-NOT");
122291a1b2c9SMichael Liao         SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos),
122391a1b2c9SMichael Liao                         SourceMgr::DK_Note,
122413df4626SMatt Arsenault                         Prefix + "-DAG: the farthest match of CHECK-DAG"
122591a1b2c9SMichael Liao                         " is found here");
122691a1b2c9SMichael Liao         SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note,
122713df4626SMatt Arsenault                         Prefix + "-NOT: the crossed pattern specified"
122891a1b2c9SMichael Liao                         " here");
122991a1b2c9SMichael Liao         SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note,
123013df4626SMatt Arsenault                         Prefix + "-DAG: the reordered pattern specified"
123191a1b2c9SMichael Liao                         " here");
123291a1b2c9SMichael Liao         return StringRef::npos;
123391a1b2c9SMichael Liao       }
123491a1b2c9SMichael Liao       // All subsequent CHECK-DAGs should be matched from the farthest
123591a1b2c9SMichael Liao       // position of all precedent CHECK-DAGs (including this one.)
123691a1b2c9SMichael Liao       StartPos = LastPos;
123791a1b2c9SMichael Liao       // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to
123891a1b2c9SMichael Liao       // CHECK-DAG, verify that there's no 'not' strings occurred in that
123991a1b2c9SMichael Liao       // region.
124091a1b2c9SMichael Liao       StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
1241cf708c32STim Northover       if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
124291a1b2c9SMichael Liao         return StringRef::npos;
124391a1b2c9SMichael Liao       // Clear "not strings".
124491a1b2c9SMichael Liao       NotStrings.clear();
124591a1b2c9SMichael Liao     }
124691a1b2c9SMichael Liao 
124791a1b2c9SMichael Liao     // Update the last position with CHECK-DAG matches.
124891a1b2c9SMichael Liao     LastPos = std::max(MatchPos + MatchLen, LastPos);
124991a1b2c9SMichael Liao   }
125091a1b2c9SMichael Liao 
125191a1b2c9SMichael Liao   return LastPos;
125291a1b2c9SMichael Liao }
125391a1b2c9SMichael Liao 
125413df4626SMatt Arsenault // A check prefix must contain only alphanumeric, hyphens and underscores.
125513df4626SMatt Arsenault static bool ValidateCheckPrefix(StringRef CheckPrefix) {
125613df4626SMatt Arsenault   Regex Validator("^[a-zA-Z0-9_-]*$");
125713df4626SMatt Arsenault   return Validator.match(CheckPrefix);
125813df4626SMatt Arsenault }
125913df4626SMatt Arsenault 
126013df4626SMatt Arsenault static bool ValidateCheckPrefixes() {
126113df4626SMatt Arsenault   StringSet<> PrefixSet;
126213df4626SMatt Arsenault 
12638f870499SBenjamin Kramer   for (StringRef Prefix : CheckPrefixes) {
126424412b14SEli Bendersky     // Reject empty prefixes.
126524412b14SEli Bendersky     if (Prefix == "")
126624412b14SEli Bendersky       return false;
126724412b14SEli Bendersky 
12680356975cSDavid Blaikie     if (!PrefixSet.insert(Prefix).second)
126913df4626SMatt Arsenault       return false;
127013df4626SMatt Arsenault 
127113df4626SMatt Arsenault     if (!ValidateCheckPrefix(Prefix))
127213df4626SMatt Arsenault       return false;
127313df4626SMatt Arsenault   }
127413df4626SMatt Arsenault 
127513df4626SMatt Arsenault   return true;
127613df4626SMatt Arsenault }
127713df4626SMatt Arsenault 
127813df4626SMatt Arsenault // I don't think there's a way to specify an initial value for cl::list,
127913df4626SMatt Arsenault // so if nothing was specified, add the default
128013df4626SMatt Arsenault static void AddCheckPrefixIfNeeded() {
128113df4626SMatt Arsenault   if (CheckPrefixes.empty())
128213df4626SMatt Arsenault     CheckPrefixes.push_back("CHECK");
1283c2735158SRui Ueyama }
1284c2735158SRui Ueyama 
12852bd4f8b6SXinliang David Li static void DumpCommandLine(int argc, char **argv) {
12862bd4f8b6SXinliang David Li   errs() << "FileCheck command line: ";
12872bd4f8b6SXinliang David Li   for (int I = 0; I < argc; I++)
12882bd4f8b6SXinliang David Li     errs() << " " << argv[I];
12892bd4f8b6SXinliang David Li   errs() << "\n";
12902bd4f8b6SXinliang David Li }
12912bd4f8b6SXinliang David Li 
1292*20247900SChandler Carruth /// Check the input to FileCheck provided in the \p Buffer against the \p
1293*20247900SChandler Carruth /// CheckStrings read from the check file.
1294*20247900SChandler Carruth ///
1295*20247900SChandler Carruth /// Returns false if the input fails to satisfy the checks.
1296*20247900SChandler Carruth bool CheckInput(SourceMgr &SM, StringRef Buffer,
1297*20247900SChandler Carruth                 ArrayRef<CheckString> CheckStrings) {
1298*20247900SChandler Carruth   bool ChecksFailed = false;
1299*20247900SChandler Carruth 
1300*20247900SChandler Carruth   /// VariableTable - This holds all the current filecheck variables.
1301*20247900SChandler Carruth   StringMap<StringRef> VariableTable;
1302*20247900SChandler Carruth 
1303*20247900SChandler Carruth   unsigned i = 0, j = 0, e = CheckStrings.size();
1304*20247900SChandler Carruth   while (true) {
1305*20247900SChandler Carruth     StringRef CheckRegion;
1306*20247900SChandler Carruth     if (j == e) {
1307*20247900SChandler Carruth       CheckRegion = Buffer;
1308*20247900SChandler Carruth     } else {
1309*20247900SChandler Carruth       const CheckString &CheckLabelStr = CheckStrings[j];
1310*20247900SChandler Carruth       if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
1311*20247900SChandler Carruth         ++j;
1312*20247900SChandler Carruth         continue;
1313*20247900SChandler Carruth       }
1314*20247900SChandler Carruth 
1315*20247900SChandler Carruth       // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
1316*20247900SChandler Carruth       size_t MatchLabelLen = 0;
1317*20247900SChandler Carruth       size_t MatchLabelPos = CheckLabelStr.Check(SM, Buffer, true,
1318*20247900SChandler Carruth                                                  MatchLabelLen, VariableTable);
1319*20247900SChandler Carruth       if (MatchLabelPos == StringRef::npos)
1320*20247900SChandler Carruth         // Immediately bail of CHECK-LABEL fails, nothing else we can do.
1321*20247900SChandler Carruth         return false;
1322*20247900SChandler Carruth 
1323*20247900SChandler Carruth       CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen);
1324*20247900SChandler Carruth       Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen);
1325*20247900SChandler Carruth       ++j;
1326*20247900SChandler Carruth     }
1327*20247900SChandler Carruth 
1328*20247900SChandler Carruth     for ( ; i != j; ++i) {
1329*20247900SChandler Carruth       const CheckString &CheckStr = CheckStrings[i];
1330*20247900SChandler Carruth 
1331*20247900SChandler Carruth       // Check each string within the scanned region, including a second check
1332*20247900SChandler Carruth       // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
1333*20247900SChandler Carruth       size_t MatchLen = 0;
1334*20247900SChandler Carruth       size_t MatchPos = CheckStr.Check(SM, CheckRegion, false, MatchLen,
1335*20247900SChandler Carruth                                        VariableTable);
1336*20247900SChandler Carruth 
1337*20247900SChandler Carruth       if (MatchPos == StringRef::npos) {
1338*20247900SChandler Carruth         ChecksFailed = true;
1339*20247900SChandler Carruth         i = j;
1340*20247900SChandler Carruth         break;
1341*20247900SChandler Carruth       }
1342*20247900SChandler Carruth 
1343*20247900SChandler Carruth       CheckRegion = CheckRegion.substr(MatchPos + MatchLen);
1344*20247900SChandler Carruth     }
1345*20247900SChandler Carruth 
1346*20247900SChandler Carruth     if (j == e)
1347*20247900SChandler Carruth       break;
1348*20247900SChandler Carruth   }
1349*20247900SChandler Carruth 
1350*20247900SChandler Carruth   // Success if no checks failed.
1351*20247900SChandler Carruth   return !ChecksFailed;
1352*20247900SChandler Carruth }
1353*20247900SChandler Carruth 
1354ee3c74fbSChris Lattner int main(int argc, char **argv) {
13552ad6d48bSRichard Smith   sys::PrintStackTraceOnErrorSignal(argv[0]);
1356ee3c74fbSChris Lattner   PrettyStackTraceProgram X(argc, argv);
1357ee3c74fbSChris Lattner   cl::ParseCommandLineOptions(argc, argv);
1358ee3c74fbSChris Lattner 
135913df4626SMatt Arsenault   if (!ValidateCheckPrefixes()) {
136013df4626SMatt Arsenault     errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
136113df4626SMatt Arsenault               "start with a letter and contain only alphanumeric characters, "
136213df4626SMatt Arsenault               "hyphens and underscores\n";
1363c2735158SRui Ueyama     return 2;
1364c2735158SRui Ueyama   }
1365c2735158SRui Ueyama 
136613df4626SMatt Arsenault   AddCheckPrefixIfNeeded();
136713df4626SMatt Arsenault 
1368ee3c74fbSChris Lattner   SourceMgr SM;
1369ee3c74fbSChris Lattner 
1370ee3c74fbSChris Lattner   // Read the expected strings from the check file.
1371*20247900SChandler Carruth   ErrorOr<std::unique_ptr<MemoryBuffer>> CheckFileOrErr =
1372*20247900SChandler Carruth       MemoryBuffer::getFileOrSTDIN(CheckFilename);
1373*20247900SChandler Carruth   if (std::error_code EC = CheckFileOrErr.getError()) {
1374*20247900SChandler Carruth     errs() << "Could not open check file '" << CheckFilename
1375*20247900SChandler Carruth            << "': " << EC.message() << '\n';
1376*20247900SChandler Carruth     return 2;
1377*20247900SChandler Carruth   }
1378*20247900SChandler Carruth   MemoryBuffer &CheckFile = *CheckFileOrErr.get();
1379*20247900SChandler Carruth 
1380*20247900SChandler Carruth   SmallString<4096> CheckFileBuffer;
1381*20247900SChandler Carruth   StringRef CheckFileText =
1382*20247900SChandler Carruth       CanonicalizeFile(CheckFile, NoCanonicalizeWhiteSpace, CheckFileBuffer);
1383*20247900SChandler Carruth 
1384*20247900SChandler Carruth   SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
1385*20247900SChandler Carruth                             CheckFileText, CheckFile.getBufferIdentifier()),
1386*20247900SChandler Carruth                         SMLoc());
1387*20247900SChandler Carruth 
138826cccfe1SChris Lattner   std::vector<CheckString> CheckStrings;
1389*20247900SChandler Carruth   if (ReadCheckFile(SM, CheckFileText, CheckStrings))
1390ee3c74fbSChris Lattner     return 2;
1391ee3c74fbSChris Lattner 
1392*20247900SChandler Carruth 
1393ee3c74fbSChris Lattner   // Open the file to check and add it to SourceMgr.
1394*20247900SChandler Carruth   ErrorOr<std::unique_ptr<MemoryBuffer>> InputFileOrErr =
1395adf21f2aSRafael Espindola       MemoryBuffer::getFileOrSTDIN(InputFilename);
1396*20247900SChandler Carruth   if (std::error_code EC = InputFileOrErr.getError()) {
1397adf21f2aSRafael Espindola     errs() << "Could not open input file '" << InputFilename
1398adf21f2aSRafael Espindola            << "': " << EC.message() << '\n';
13998e1c6477SEli Bendersky     return 2;
1400ee3c74fbSChris Lattner   }
1401*20247900SChandler Carruth   MemoryBuffer &InputFile = *InputFileOrErr.get();
14022c3e5cdfSChris Lattner 
1403*20247900SChandler Carruth   if (InputFile.getBufferSize() == 0 && !AllowEmptyInput) {
1404b692bed7SChris Lattner     errs() << "FileCheck error: '" << InputFilename << "' is empty.\n";
14052bd4f8b6SXinliang David Li     DumpCommandLine(argc, argv);
14068e1c6477SEli Bendersky     return 2;
1407b692bed7SChris Lattner   }
1408b692bed7SChris Lattner 
1409*20247900SChandler Carruth   SmallString<4096> InputFileBuffer;
1410*20247900SChandler Carruth   StringRef InputFileText =
1411*20247900SChandler Carruth       CanonicalizeFile(InputFile, NoCanonicalizeWhiteSpace, InputFileBuffer);
14122c3e5cdfSChris Lattner 
1413*20247900SChandler Carruth   SM.AddNewSourceBuffer(
1414*20247900SChandler Carruth       MemoryBuffer::getMemBuffer(InputFileText, InputFile.getBufferIdentifier()), SMLoc());
1415ee3c74fbSChris Lattner 
1416*20247900SChandler Carruth   return CheckInput(SM, InputFileText, CheckStrings) ? EXIT_SUCCESS : 1;
1417ee3c74fbSChris Lattner }
1418