[llvm] r230612 - FileCheck: Add CHECK-SAME
Duncan P. N. Exon Smith
dexonsmith at apple.com
Wed Feb 25 20:53:00 PST 2015
Author: dexonsmith
Date: Wed Feb 25 22:53:00 2015
New Revision: 230612
URL: http://llvm.org/viewvc/llvm-project?rev=230612&view=rev
Log:
FileCheck: Add CHECK-SAME
Add `CHECK-SAME`, which requires that the pattern matches on the *same*
line as the previous `CHECK`/`CHECK-NEXT` -- in other words, no newline
is allowed in the skipped region. This is similar to `CHECK-NEXT`,
which requires exactly 1 newline in the skipped region.
My motivation is to simplify checking the long lines of LLVM assembly
for the new debug info hierarchy. This allows CHECK sequences like the
following:
CHECK: ![[REF]] = !SomeMDNode(
CHECK-SAME: file: ![[FILE:[0-9]+]]
CHECK-SAME: otherField: 93{{[,)]}}
which is equivalent to:
CHECK: ![[REF]] = !SomeMDNode({{.*}}file: ![[FILE:[0-9]+]]{{.*}}otherField: 93{{[,)]}}
While this example just has two fields, many nodes in debug info have
more than that. `CHECK-SAME` will keep the logic easy to follow.
Morever, it enables interleaving `CHECK-NOT`s without allowing newlines.
Consider the following:
CHECK: ![[REF]] = !SomeMDNode(
CHECK-SAME: file: ![[FILE:[0-9]+]]
CHECK-NOT: unexpectedField:
CHECK-SAME: otherField: 93{{[,)]}}
CHECK-NOT: otherUnexpectedField:
CHECK-SAME: )
which doesn't seem to have an equivalent `CHECK` line.
Added:
llvm/trunk/test/FileCheck/same.txt
Modified:
llvm/trunk/utils/FileCheck/FileCheck.cpp
Added: llvm/trunk/test/FileCheck/same.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/same.txt?rev=230612&view=auto
==============================================================================
--- llvm/trunk/test/FileCheck/same.txt (added)
+++ llvm/trunk/test/FileCheck/same.txt Wed Feb 25 22:53:00 2015
@@ -0,0 +1,23 @@
+foo bat bar
+baz
+
+RUN: FileCheck --input-file=%s --check-prefix=PASS1 %s
+PASS1: foo
+PASS1-SAME: bat
+PASS1-SAME: bar
+PASS1-NEXT: baz
+
+RUN: FileCheck --input-file=%s --check-prefix=PASS2 %s
+PASS2: foo
+PASS2-NOT: baz
+PASS2-SAME: bar
+PASS2-NEXT: baz
+
+RUN: not FileCheck --input-file=%s --check-prefix=FAIL1 %s
+FAIL1: foo
+FAIL1-SAME: baz
+
+RUN: not FileCheck --input-file=%s --check-prefix=FAIL2 %s
+FAIL2: foo
+FAIL2-NOT: bat
+FAIL2-SAME: bar
Modified: llvm/trunk/utils/FileCheck/FileCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/FileCheck/FileCheck.cpp?rev=230612&r1=230611&r2=230612&view=diff
==============================================================================
--- llvm/trunk/utils/FileCheck/FileCheck.cpp (original)
+++ llvm/trunk/utils/FileCheck/FileCheck.cpp Wed Feb 25 22:53:00 2015
@@ -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::Check
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(St
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;
}
@@ -1053,6 +1065,11 @@ size_t CheckString::Check(const SourceMg
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))
@@ -1098,6 +1115,34 @@ bool CheckString::CheckNext(const Source
return true;
}
+ 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;
}
More information about the llvm-commits
mailing list