+// Get the size of the prefix extension.
+static size_t CheckTypeSize(Check::CheckType Ty) {
+ switch (Ty) {
+ case Check::CheckNone:
+ return 0;
+
+ case Check::CheckPlain:
+ return sizeof(":") - 1;
+
+ case Check::CheckNext:
+ return sizeof("-NEXT:") - 1;
+
+ case Check::CheckNot:
+ return sizeof("-NOT:") - 1;
+
+ case Check::CheckDAG:
+ return sizeof("-DAG:") - 1;
+
+ case Check::CheckLabel:
+ return sizeof("-LABEL:") - 1;
+
+ case Check::CheckEOF:
+ llvm_unreachable("Should not be using EOF size");
+ }
+
+ llvm_unreachable("Bad check type");
+}
+
+static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) {
+ char NextChar = Buffer[Prefix.size()];
+
+ // Verify that the : is present after the prefix.
+ if (NextChar == ':')
+ return Check::CheckPlain;
+
+ if (NextChar != '-')
+ return Check::CheckNone;
+
+ StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
+ if (Rest.startswith("NEXT:"))
+ return Check::CheckNext;
+
+ if (Rest.startswith("NOT:"))
+ return Check::CheckNot;
+
+ if (Rest.startswith("DAG:"))
+ return Check::CheckDAG;
+
+ if (Rest.startswith("LABEL:"))
+ return Check::CheckLabel;
+
+ return Check::CheckNone;
+}
+
+// From the given position, find the next character after the word.
+static size_t SkipWord(StringRef Str, size_t Loc) {
+ while (Loc < Str.size() && IsPartOfWord(Str[Loc]))
+ ++Loc;
+ return Loc;
+}
+
+// Try to find the first match in buffer for any prefix. If a valid match is
+// found, return that prefix and set its type and location. If there are almost
+// matches (e.g. the actual prefix string is found, but is not an actual check
+// string), but no valid match, return an empty string and set the position to
+// resume searching from. If no partial matches are found, return an empty
+// string and the location will be StringRef::npos. If one prefix is a substring
+// of another, the maximal match should be found. e.g. if "A" and "AA" are
+// prefixes then AA-CHECK: should match the second one.
+static StringRef FindFirstCandidateMatch(StringRef &Buffer,
+ Check::CheckType &CheckTy,
+ size_t &CheckLoc) {
+ StringRef FirstPrefix;
+ size_t FirstLoc = StringRef::npos;
+ size_t SearchLoc = StringRef::npos;
+ Check::CheckType FirstTy = Check::CheckNone;
+
+ CheckTy = Check::CheckNone;
+ CheckLoc = StringRef::npos;
+
+ for (prefix_iterator I = CheckPrefixes.begin(), E = CheckPrefixes.end();
+ I != E; ++I) {
+ StringRef Prefix(*I);
+ size_t PrefixLoc = Buffer.find(Prefix);
+
+ if (PrefixLoc == StringRef::npos)
+ continue;
+
+ // Track where we are searching for invalid prefixes that look almost right.
+ // We need to only advance to the first partial match on the next attempt
+ // since a partial match could be a substring of a later, valid prefix.
+ // Need to skip to the end of the word, otherwise we could end up
+ // matching a prefix in a substring later.
+ if (PrefixLoc < SearchLoc)
+ SearchLoc = SkipWord(Buffer, PrefixLoc);
+
+ // We only want to find the first match to avoid skipping some.
+ if (PrefixLoc > FirstLoc)
+ continue;
+ // If one matching check-prefix is a prefix of another, choose the
+ // longer one.
+ if (PrefixLoc == FirstLoc && Prefix.size() < FirstPrefix.size())
+ continue;
+
+ StringRef Rest = Buffer.drop_front(PrefixLoc);
+ // Make sure we have actually found the prefix, and not a word containing
+ // it. This should also prevent matching the wrong prefix when one is a
+ // substring of another.
+ if (PrefixLoc != 0 && IsPartOfWord(Buffer[PrefixLoc - 1]))
+ FirstTy = Check::CheckNone;
+ else
+ FirstTy = FindCheckType(Rest, Prefix);
+
+ FirstLoc = PrefixLoc;
+ FirstPrefix = Prefix;
+ }
+
+ // If the first prefix is invalid, we should continue the search after it.
+ if (FirstTy == Check::CheckNone) {
+ CheckLoc = SearchLoc;
+ return "";
+ }
+
+ CheckTy = FirstTy;
+ CheckLoc = FirstLoc;
+ return FirstPrefix;
+}
+
+static StringRef FindFirstMatchingPrefix(StringRef &Buffer,
+ unsigned &LineNumber,
+ Check::CheckType &CheckTy,
+ size_t &CheckLoc) {
+ while (!Buffer.empty()) {
+ StringRef Prefix = FindFirstCandidateMatch(Buffer, CheckTy, CheckLoc);
+ // If we found a real match, we are done.
+ if (!Prefix.empty()) {
+ LineNumber += Buffer.substr(0, CheckLoc).count('\n');
+ return Prefix;
+ }
+
+ // We didn't find any almost matches either, we are also done.
+ if (CheckLoc == StringRef::npos)
+ return StringRef();
+
+ LineNumber += Buffer.substr(0, CheckLoc + 1).count('\n');
+
+ // Advance to the last possible match we found and try again.
+ Buffer = Buffer.drop_front(CheckLoc + 1);
+ }
+
+ return StringRef();
+}
+
+/// ReadCheckFile - Read the check file, which specifies the sequence of
+/// expected strings. The strings are added to the CheckStrings vector.
+/// Returns true in case of an error, false otherwise.
+static bool ReadCheckFile(SourceMgr &SM,
+ std::vector<CheckString> &CheckStrings) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFileOrSTDIN(CheckFilename);
+ if (std::error_code EC = FileOrErr.getError()) {
+ errs() << "Could not open check file '" << CheckFilename
+ << "': " << EC.message() << '\n';
+ return true;
+ }
+
+ // If we want to canonicalize whitespace, strip excess whitespace from the
+ // buffer containing the CHECK lines. Remove DOS style line endings.
+ std::unique_ptr<MemoryBuffer> F = CanonicalizeInputFile(
+ std::move(FileOrErr.get()), NoCanonicalizeWhiteSpace);
+
+ // Find all instances of CheckPrefix followed by : in the file.
+ StringRef Buffer = F->getBuffer();
+
+ SM.AddNewSourceBuffer(std::move(F), SMLoc());
+
+ std::vector<Pattern> ImplicitNegativeChecks;
+ for (const auto &PatternString : ImplicitCheckNot) {
+ // Create a buffer with fake command line content in order to display the
+ // command line option responsible for the specific implicit CHECK-NOT.
+ std::string Prefix = std::string("-") + ImplicitCheckNot.ArgStr + "='";
+ std::string Suffix = "'";
+ std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy(
+ Prefix + PatternString + Suffix, "command line");
+
+ StringRef PatternInBuffer =
+ CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
+ SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
+
+ ImplicitNegativeChecks.push_back(Pattern(Check::CheckNot));
+ ImplicitNegativeChecks.back().ParsePattern(PatternInBuffer,
+ "IMPLICIT-CHECK", SM, 0);
+ }
+
+
+ std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
+
+ // LineNumber keeps track of the line on which CheckPrefix instances are
+ // found.
+ unsigned LineNumber = 1;
+
+ while (1) {
+ Check::CheckType CheckTy;
+ size_t PrefixLoc;
+
+ // See if a prefix occurs in the memory buffer.
+ StringRef UsedPrefix = FindFirstMatchingPrefix(Buffer,
+ LineNumber,
+ CheckTy,
+ PrefixLoc);
+ if (UsedPrefix.empty())
+ break;
+
+ Buffer = Buffer.drop_front(PrefixLoc);
+
+ // Location to use for error messages.
+ const char *UsedPrefixStart = Buffer.data() + (PrefixLoc == 0 ? 0 : 1);
+
+ // PrefixLoc is to the start of the prefix. Skip to the end.
+ Buffer = Buffer.drop_front(UsedPrefix.size() + CheckTypeSize(CheckTy));
+
+ // Okay, we found the prefix, yay. Remember the rest of the line, but ignore
+ // leading and trailing whitespace.
+ Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
+
+ // Scan ahead to the end of line.
+ size_t EOL = Buffer.find_first_of("\n\r");
+
+ // Remember the location of the start of the pattern, for diagnostics.
+ SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
+
+ // Parse the pattern.
+ Pattern P(CheckTy);
+ if (P.ParsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, LineNumber))
+ return true;
+
+ // Verify that CHECK-LABEL lines do not define or use variables
+ if ((CheckTy == Check::CheckLabel) && P.hasVariable()) {
+ SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
+ SourceMgr::DK_Error,
+ "found '" + UsedPrefix + "-LABEL:'"
+ " with variable definition or use");
+ return true;
+ }
+
+ Buffer = Buffer.substr(EOL);
+
+ // Verify that CHECK-NEXT lines have at least one CHECK line before them.
+ if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
+ SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
+ SourceMgr::DK_Error,
+ "found '" + UsedPrefix + "-NEXT:' without previous '"
+ + UsedPrefix + ": line");
+ return true;
+ }
+
+ // Handle CHECK-DAG/-NOT.
+ if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) {
+ DagNotMatches.push_back(P);
+ continue;
+ }
+
+ // Okay, add the string we captured to the output vector and move on.
+ CheckStrings.push_back(CheckString(P,
+ UsedPrefix,
+ PatternLoc,
+ CheckTy));
+ std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
+ DagNotMatches = ImplicitNegativeChecks;
+ }
+
+ // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
+ // prefix as a filler for the error message.
+ if (!DagNotMatches.empty()) {
+ CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF),
+ CheckPrefixes[0],
+ SMLoc::getFromPointer(Buffer.data()),
+ Check::CheckEOF));
+ std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
+ }
+
+ if (CheckStrings.empty()) {
+ errs() << "error: no check strings found with prefix"
+ << (CheckPrefixes.size() > 1 ? "es " : " ");
+ for (size_t I = 0, N = CheckPrefixes.size(); I != N; ++I) {
+ StringRef Prefix(CheckPrefixes[I]);
+ errs() << '\'' << Prefix << ":'";
+ if (I != N - 1)
+ errs() << ", ";
+ }
+
+ errs() << '\n';
+ return true;
+ }
+
+ return false;
+}
+
+static void PrintCheckFailed(const SourceMgr &SM, const SMLoc &Loc,
+ const Pattern &Pat, StringRef Buffer,
+ StringMap<StringRef> &VariableTable) {