llvm.org GIT mirror llvm / 9379c31
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230612 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 4 years ago
2 changed file(s) with 70 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
0 foo bat bar
1 baz
2
3 RUN: FileCheck --input-file=%s --check-prefix=PASS1 %s
4 PASS1: foo
5 PASS1-SAME: bat
6 PASS1-SAME: bar
7 PASS1-NEXT: baz
8
9 RUN: FileCheck --input-file=%s --check-prefix=PASS2 %s
10 PASS2: foo
11 PASS2-NOT: baz
12 PASS2-SAME: bar
13 PASS2-NEXT: baz
14
15 RUN: not FileCheck --input-file=%s --check-prefix=FAIL1 %s
16 FAIL1: foo
17 FAIL1-SAME: baz
18
19 RUN: not FileCheck --input-file=%s --check-prefix=FAIL2 %s
20 FAIL2: foo
21 FAIL2-NOT: bat
22 FAIL2-SAME: bar
7272 CheckNone = 0,
7373 CheckPlain,
7474 CheckNext,
75 CheckSame,
7576 CheckNot,
7677 CheckDAG,
7778 CheckLabel,
619620 /// CheckNext - Verify there is a single line in the given buffer.
620621 bool CheckNext(const SourceMgr &SM, StringRef Buffer) const;
621622
623 /// CheckSame - Verify there is no newline in the given buffer.
624 bool CheckSame(const SourceMgr &SM, StringRef Buffer) const;
625
622626 /// CheckNot - Verify there's no "not strings" in the given buffer.
623627 bool CheckNot(const SourceMgr &SM, StringRef Buffer,
624628 const std::vector &NotStrings,
682686 case Check::CheckNext:
683687 return sizeof("-NEXT:") - 1;
684688
689 case Check::CheckSame:
690 return sizeof("-SAME:") - 1;
691
685692 case Check::CheckNot:
686693 return sizeof("-NOT:") - 1;
687694
711718 StringRef Rest = Buffer.drop_front(Prefix.size() + 1);
712719 if (Rest.startswith("NEXT:"))
713720 return Check::CheckNext;
721
722 if (Rest.startswith("SAME:"))
723 return Check::CheckSame;
714724
715725 if (Rest.startswith("NOT:"))
716726 return Check::CheckNot;
918928 Buffer = Buffer.substr(EOL);
919929
920930 // Verify that CHECK-NEXT lines have at least one CHECK line before them.
921 if ((CheckTy == Check::CheckNext) && CheckStrings.empty()) {
931 if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&
932 CheckStrings.empty()) {
933 StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";
922934 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
923935 SourceMgr::DK_Error,
924 "found '" + UsedPrefix + "-NEXT:' without previous '"
936 "found '" + UsedPrefix + "-" + Type + "' without previous '"
925937 + UsedPrefix + ": line");
926938 return true;
927939 }
10521064 if (CheckNext(SM, SkippedRegion))
10531065 return StringRef::npos;
10541066
1067 // If this check is a "CHECK-SAME", verify that the previous match was on
1068 // the same line (i.e. that there is no newline between them).
1069 if (CheckSame(SM, SkippedRegion))
1070 return StringRef::npos;
1071
10551072 // If this match had "not strings", verify that they don't exist in the
10561073 // skipped region.
10571074 if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable))
10941111 "previous match ended here");
10951112 SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note,
10961113 "non-matching line after previous match is here");
1114 return true;
1115 }
1116
1117 return false;
1118 }
1119
1120 bool CheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
1121 if (CheckTy != Check::CheckSame)
1122 return false;
1123
1124 // Count the number of newlines between the previous match and this one.
1125 assert(Buffer.data() !=
1126 SM.getMemoryBuffer(SM.FindBufferContainingLoc(
1127 SMLoc::getFromPointer(Buffer.data())))
1128 ->getBufferStart() &&
1129 "CHECK-SAME can't be the first check in a file");
1130
1131 const char *FirstNewLine = nullptr;
1132 unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
1133
1134 if (NumNewLines != 0) {
1135 SM.PrintMessage(Loc, SourceMgr::DK_Error,
1136 Prefix +
1137 "-SAME: is not on the same line as the previous match");
1138 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
1139 "'next' match was here");
1140 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
1141 "previous match ended here");
10971142 return true;
10981143 }
10991144