diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 |
commit | 5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch) | |
tree | a6140557876943cdd800ee997c9317283394b22c /utils/FileCheck | |
parent | f03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff) |
Diffstat (limited to 'utils/FileCheck')
-rw-r--r-- | utils/FileCheck/FileCheck.cpp | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp index 59affa1ada1b..8fe2f88a3e70 100644 --- a/utils/FileCheck/FileCheck.cpp +++ b/utils/FileCheck/FileCheck.cpp @@ -73,6 +73,7 @@ namespace Check { CheckNone = 0, CheckPlain, CheckNext, + CheckSame, CheckNot, CheckDAG, CheckLabel, @@ -620,6 +621,9 @@ struct CheckString { /// CheckNext - Verify there is a single line in the given buffer. bool CheckNext(const SourceMgr &SM, StringRef Buffer) const; + /// CheckSame - Verify there is no newline in the given buffer. + bool CheckSame(const SourceMgr &SM, StringRef Buffer) const; + /// CheckNot - Verify there's no "not strings" in the given buffer. bool CheckNot(const SourceMgr &SM, StringRef Buffer, const std::vector<const Pattern *> &NotStrings, @@ -683,6 +687,9 @@ static size_t CheckTypeSize(Check::CheckType Ty) { case Check::CheckNext: return sizeof("-NEXT:") - 1; + case Check::CheckSame: + return sizeof("-SAME:") - 1; + case Check::CheckNot: return sizeof("-NOT:") - 1; @@ -713,6 +720,9 @@ static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) { if (Rest.startswith("NEXT:")) return Check::CheckNext; + if (Rest.startswith("SAME:")) + return Check::CheckSame; + if (Rest.startswith("NOT:")) return Check::CheckNot; @@ -919,10 +929,12 @@ static bool ReadCheckFile(SourceMgr &SM, Buffer = Buffer.substr(EOL); // Verify that CHECK-NEXT lines have at least one CHECK line before them. - if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) { + if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) && + CheckStrings.empty()) { + StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME"; SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error, - "found '" + UsedPrefix + "-NEXT:' without previous '" + "found '" + UsedPrefix + "-" + Type + "' without previous '" + UsedPrefix + ": line"); return true; } @@ -946,7 +958,7 @@ static bool ReadCheckFile(SourceMgr &SM, // prefix as a filler for the error message. if (!DagNotMatches.empty()) { CheckStrings.push_back(CheckString(Pattern(Check::CheckEOF), - CheckPrefixes[0], + *CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data()), Check::CheckEOF)); std::swap(DagNotMatches, CheckStrings.back().DagNotStrings); @@ -955,12 +967,14 @@ static bool ReadCheckFile(SourceMgr &SM, 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() << ", "; + prefix_iterator I = CheckPrefixes.begin(); + prefix_iterator E = CheckPrefixes.end(); + if (I != E) { + errs() << "\'" << *I << ":'"; + ++I; } + for (; I != E; ++I) + errs() << ", \'" << *I << ":'"; errs() << '\n'; return true; @@ -1041,7 +1055,6 @@ size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer, PrintCheckFailed(SM, *this, MatchBuffer, VariableTable); return StringRef::npos; } - MatchPos += LastPos; // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT // or CHECK-NOT @@ -1053,13 +1066,18 @@ size_t CheckString::Check(const SourceMgr &SM, StringRef Buffer, if (CheckNext(SM, SkippedRegion)) return StringRef::npos; + // If this check is a "CHECK-SAME", verify that the previous match was on + // the same line (i.e. that there is no newline between them). + if (CheckSame(SM, SkippedRegion)) + return StringRef::npos; + // If this match had "not strings", verify that they don't exist in the // skipped region. if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable)) return StringRef::npos; } - return MatchPos; + return LastPos + MatchPos; } bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const { @@ -1101,6 +1119,34 @@ bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const { return false; } +bool CheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const { + if (CheckTy != Check::CheckSame) + return false; + + // Count the number of newlines between the previous match and this one. + assert(Buffer.data() != + SM.getMemoryBuffer(SM.FindBufferContainingLoc( + SMLoc::getFromPointer(Buffer.data()))) + ->getBufferStart() && + "CHECK-SAME can't be the first check in a file"); + + const char *FirstNewLine = nullptr; + unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine); + + if (NumNewLines != 0) { + SM.PrintMessage(Loc, SourceMgr::DK_Error, + Prefix + + "-SAME: is not on the same line as the previous match"); + SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note, + "'next' match was here"); + SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, + "previous match ended here"); + return true; + } + + return false; +} + bool CheckString::CheckNot(const SourceMgr &SM, StringRef Buffer, const std::vector<const Pattern *> &NotStrings, StringMap<StringRef> &VariableTable) const { |