<div dir="ltr"><div>Please add a section to CommandGuide/FileCheck.rst like the other directives.<br><br></div>-- Sean Silva<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 25, 2015 at 8:53 PM, Duncan P. N. Exon Smith <span dir="ltr"><<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br>
Date: Wed Feb 25 22:53:00 2015<br>
New Revision: 230612<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=230612&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=230612&view=rev</a><br>
Log:<br>
FileCheck: Add CHECK-SAME<br>
<br>
Add `CHECK-SAME`, which requires that the pattern matches on the *same*<br>
line as the previous `CHECK`/`CHECK-NEXT` -- in other words, no newline<br>
is allowed in the skipped region. This is similar to `CHECK-NEXT`,<br>
which requires exactly 1 newline in the skipped region.<br>
<br>
My motivation is to simplify checking the long lines of LLVM assembly<br>
for the new debug info hierarchy. This allows CHECK sequences like the<br>
following:<br>
<br>
CHECK: ![[REF]] = !SomeMDNode(<br>
CHECK-SAME: file: ![[FILE:[0-9]+]]<br>
CHECK-SAME: otherField: 93{{[,)]}}<br>
<br>
which is equivalent to:<br>
<br>
CHECK: ![[REF]] = !SomeMDNode({{.*}}file: ![[FILE:[0-9]+]]{{.*}}otherField: 93{{[,)]}}<br>
<br>
While this example just has two fields, many nodes in debug info have<br>
more than that. `CHECK-SAME` will keep the logic easy to follow.<br>
<br>
Morever, it enables interleaving `CHECK-NOT`s without allowing newlines.<br>
Consider the following:<br>
<br>
CHECK: ![[REF]] = !SomeMDNode(<br>
CHECK-SAME: file: ![[FILE:[0-9]+]]<br>
CHECK-NOT: unexpectedField:<br>
CHECK-SAME: otherField: 93{{[,)]}}<br>
CHECK-NOT: otherUnexpectedField:<br>
CHECK-SAME: )<br>
<br>
which doesn't seem to have an equivalent `CHECK` line.<br>
<br>
Added:<br>
llvm/trunk/test/FileCheck/same.txt<br>
Modified:<br>
llvm/trunk/utils/FileCheck/FileCheck.cpp<br>
<br>
Added: llvm/trunk/test/FileCheck/same.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/same.txt?rev=230612&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/same.txt?rev=230612&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/FileCheck/same.txt (added)<br>
+++ llvm/trunk/test/FileCheck/same.txt Wed Feb 25 22:53:00 2015<br>
@@ -0,0 +1,23 @@<br>
+foo bat bar<br>
+baz<br>
+<br>
+RUN: FileCheck --input-file=%s --check-prefix=PASS1 %s<br>
+PASS1: foo<br>
+PASS1-SAME: bat<br>
+PASS1-SAME: bar<br>
+PASS1-NEXT: baz<br>
+<br>
+RUN: FileCheck --input-file=%s --check-prefix=PASS2 %s<br>
+PASS2: foo<br>
+PASS2-NOT: baz<br>
+PASS2-SAME: bar<br>
+PASS2-NEXT: baz<br>
+<br>
+RUN: not FileCheck --input-file=%s --check-prefix=FAIL1 %s<br>
+FAIL1: foo<br>
+FAIL1-SAME: baz<br>
+<br>
+RUN: not FileCheck --input-file=%s --check-prefix=FAIL2 %s<br>
+FAIL2: foo<br>
+FAIL2-NOT: bat<br>
+FAIL2-SAME: bar<br>
<br>
Modified: llvm/trunk/utils/FileCheck/FileCheck.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/FileCheck/FileCheck.cpp?rev=230612&r1=230611&r2=230612&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/FileCheck/FileCheck.cpp?rev=230612&r1=230611&r2=230612&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/utils/FileCheck/FileCheck.cpp (original)<br>
+++ llvm/trunk/utils/FileCheck/FileCheck.cpp Wed Feb 25 22:53:00 2015<br>
@@ -73,6 +73,7 @@ namespace Check {<br>
CheckNone = 0,<br>
CheckPlain,<br>
CheckNext,<br>
+ CheckSame,<br>
CheckNot,<br>
CheckDAG,<br>
CheckLabel,<br>
@@ -620,6 +621,9 @@ struct CheckString {<br>
/// CheckNext - Verify there is a single line in the given buffer.<br>
bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;<br>
<br>
+ /// CheckSame - Verify there is no newline in the given buffer.<br>
+ bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;<br>
+<br>
/// CheckNot - Verify there's no "not strings" in the given buffer.<br>
bool CheckNot(const SourceMgr &SM, StringRef Buffer,<br>
const std::vector<const Pattern *> &NotStrings,<br>
@@ -683,6 +687,9 @@ static size_t CheckTypeSize(Check::Check<br>
case Check::CheckNext:<br>
return sizeof("-NEXT:") - 1;<br>
<br>
+ case Check::CheckSame:<br>
+ return sizeof("-SAME:") - 1;<br>
+<br>
case Check::CheckNot:<br>
return sizeof("-NOT:") - 1;<br>
<br>
@@ -713,6 +720,9 @@ static Check::CheckType FindCheckType(St<br>
if (Rest.startswith("NEXT:"))<br>
return Check::CheckNext;<br>
<br>
+ if (Rest.startswith("SAME:"))<br>
+ return Check::CheckSame;<br>
+<br>
if (Rest.startswith("NOT:"))<br>
return Check::CheckNot;<br>
<br>
@@ -919,10 +929,12 @@ static bool ReadCheckFile(SourceMgr &SM,<br>
Buffer = Buffer.substr(EOL);<br>
<br>
// Verify that CHECK-NEXT lines have at least one CHECK line before them.<br>
- if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {<br>
+ if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&<br>
+ CheckStrings.empty()) {<br>
+ StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";<br>
SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),<br>
SourceMgr::DK_Error,<br>
- "found '" + UsedPrefix + "-NEXT:' without previous '"<br>
+ "found '" + UsedPrefix + "-" + Type + "' without previous '"<br>
+ UsedPrefix + ": line");<br>
return true;<br>
}<br>
@@ -1053,6 +1065,11 @@ size_t CheckString::Check(const SourceMg<br>
if (CheckNext(SM, SkippedRegion))<br>
return StringRef::npos;<br>
<br>
+ // If this check is a "CHECK-SAME", verify that the previous match was on<br>
+ // the same line (i.e. that there is no newline between them).<br>
+ if (CheckSame(SM, SkippedRegion))<br>
+ return StringRef::npos;<br>
+<br>
// If this match had "not strings", verify that they don't exist in the<br>
// skipped region.<br>
if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))<br>
@@ -1098,6 +1115,34 @@ bool CheckString::CheckNext(const Source<br>
return true;<br>
}<br>
<br>
+ return false;<br>
+}<br>
+<br>
+bool CheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {<br>
+ if (CheckTy != Check::CheckSame)<br>
+ return false;<br>
+<br>
+ // Count the number of newlines between the previous match and this one.<br>
+ assert(Buffer.data() !=<br>
+ SM.getMemoryBuffer(SM.FindBufferContainingLoc(<br>
+ SMLoc::getFromPointer(Buffer.data())))<br>
+ ->getBufferStart() &&<br>
+ "CHECK-SAME can't be the first check in a file");<br>
+<br>
+ const char *FirstNewLine = nullptr;<br>
+ unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);<br>
+<br>
+ if (NumNewLines != 0) {<br>
+ SM.PrintMessage(Loc, SourceMgr::DK_Error,<br>
+ Prefix +<br>
+ "-SAME: is not on the same line as the previous match");<br>
+ SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,<br>
+ "'next' match was here");<br>
+ SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,<br>
+ "previous match ended here");<br>
+ return true;<br>
+ }<br>
+<br>
return false;<br>
}<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>