llvm.org GIT mirror llvm / 583ccd4
[FileCheck] Add CHECK-EMPTY directive for checking for blank lines Prior to this change, there was no clean way of getting FileCheck to check that a line is completely empty. The expected way of using "CHECK: {{^$}}" does not work because the '^' matches the end of the previous match (this behaviour may be desirable in certain instances). For the same reason, "CHECK-NEXT: {{^$}}" will fail when the previous match was at the end of the line, as the pattern will match there. Using the recommended [[:space:]] to match an explicit new line could also match a space, and thus is not always desired. Literal '\n' matches also do not work. A workaround was suggested in the review, but it is a little clunky. This change adds a new directive that behaves the same as CHECK-NEXT, except that it only matches against empty lines (nothing, not even whitespace, is allowed). As with CHECK-NEXT, it will fail if more than one newline occurs before the next blank line. Example usage: ; test.txt foo bar ; CHECK: foo ; CHECK-EMPTY: ; CHECK-NEXT: bar Differential Revision: https://reviews.llvm.org/D28896 Reviewed by: probinson git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335613 91177308-0d34-0410-b5e6-96231b3b80d8 James Henderson 1 year, 4 months ago
3 changed file(s) with 108 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
238238
239239 "``CHECK-SAME:``" directives reject the input if there are any newlines between
240240 it and the previous directive. A "``CHECK-SAME:``" cannot be the first
241 directive in a file.
242
243 The "CHECK-EMPTY:" directive
244 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
245
246 If you need to check that the next line has nothing on it, not even whitespace,
247 you can use the "``CHECK-EMPTY:``" directive.
248
249 .. code-block:: llvm
250
251 foo
252
253 bar
254 ; CHECK: foo
255 ; CHECK-EMPTY:
256 ; CHECK-NEXT: bar
257
258 Just like "``CHECK-NEXT:``" the directive will fail if there is more than one
259 newline before it finds the next blank line, and it cannot be the first
241260 directive in a file.
242261
243262 The "CHECK-NOT:" directive
0 ; basic functionality
1 ; RUN: FileCheck %s --input-file %s --check-prefix=CHECK1
2 foo
3
4 bar
5 CHECK1: foo
6 CHECK1-EMPTY:
7 CHECK1-NEXT: bar
8
9 ; next line must be blank
10 ; RUN: not FileCheck %s --input-file %s --check-prefix=CHECK2A 2>&1 | FileCheck %s --check-prefix=CHECK2B
11 badger
12 CHECK2A: badger
13 CHECK2A-EMPTY:
14 CHECK2B: CHECK2A-EMPTY: is not on the line after the previous match
15
16 ; CHECK-EMPTY must have empty pattern
17 ; RUN: not FileCheck %s --input-file %s --check-prefix=CHECK3A 2>&1 | FileCheck %s --check-prefix=CHECK3B
18 CHECK3A: foo
19 CHECK3A-EMPTY: this is not empty
20 CHECK3B: found non-empty check string for empty check with prefix 'CHECK3A:'
21
22 ; CHECK-EMPTY cannot be the first check
23 ; RUN: not FileCheck %s --input-file %s --check-prefix=CHECK4A 2>&1 | FileCheck %s --check-prefix=CHECK4B
24 CHECK4A-EMPTY:
25 CHECK4B: found 'CHECK4A-EMPTY' without previous 'CHECK4A: line
26
27 ; CHECK-EMPTY-NOT and CHECK-NOT-EMPTY rejected
28 ; RUN: not FileCheck %s --input-file %s --check-prefixes=CHECK5A 2>&1 | FileCheck %s --check-prefix=CHECK5C
29 ; RUN: not FileCheck %s --input-file %s --check-prefixes=CHECK5B 2>&1 | FileCheck %s --check-prefix=CHECK5C
30 CHECK5A-EMPTY-NOT:
31 CHECK5B-NOT-EMPTY:
32 CHECK5C: unsupported -NOT combo on prefix 'CHECK5{{A|B}}'
33
34 ; whitespace does not count as empty
35 ; RUN: not FileCheck %s --input-file %s --check-prefix=CHECK6A --match-full-lines 2>&1 | FileCheck %s --check-prefix=CHECK6B
36 CHECK6A: the next line has spaces
37 CHECK6A-EMPTY:
38 CHECK6B: expected string not found in input
39
40 ; ***don't add any further blank lines after this point***
41 ; CHECK-EMPTY, like CHECK-NEXT, will report an error if the first matching
42 ; line is not the line immediately following the previous check.
43 the next line has spaces
44
9696 CheckNot,
9797 CheckDAG,
9898 CheckLabel,
99 CheckEmpty,
99100
100101 /// Indicates the pattern only matches the end of file. This is used for
101102 /// trailing CHECK-NOTs.
183184 PatternStr = PatternStr.substr(0, PatternStr.size() - 1);
184185
185186 // Check that there is something on the line.
186 if (PatternStr.empty()) {
187 if (PatternStr.empty() && CheckTy != Check::CheckEmpty) {
187188 SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
188189 "found empty check string with prefix '" + Prefix + ":'");
189190 return true;
191 }
192
193 if (!PatternStr.empty() && CheckTy == Check::CheckEmpty) {
194 SM.PrintMessage(
195 PatternLoc, SourceMgr::DK_Error,
196 "found non-empty check string for empty check with prefix '" + Prefix +
197 ":'");
198 return true;
199 }
200
201 if (CheckTy == Check::CheckEmpty) {
202 RegExStr = "(\n$)";
203 return false;
190204 }
191205
192206 // Check to see if this is a fixed string, or if it has regex pieces.
708722 case Check::CheckLabel:
709723 return sizeof("-LABEL:") - 1;
710724
725 case Check::CheckEmpty:
726 return sizeof("-EMPTY:") - 1;
727
711728 case Check::CheckEOF:
712729 llvm_unreachable("Should not be using EOF size");
713730 }
744761 if (Rest.startswith("LABEL:"))
745762 return Check::CheckLabel;
746763
764 if (Rest.startswith("EMPTY:"))
765 return Check::CheckEmpty;
766
747767 // You can't combine -NOT with another suffix.
748768 if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") ||
749769 Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") ||
750 Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:"))
770 Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") ||
771 Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:"))
751772 return Check::CheckBadNot;
752773
753774 return Check::CheckNone;
907928
908929 Buffer = Buffer.substr(EOL);
909930
910 // Verify that CHECK-NEXT lines have at least one CHECK line before them.
911 if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) &&
931 // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them.
932 if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame ||
933 CheckTy == Check::CheckEmpty) &&
912934 CheckStrings.empty()) {
913 StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME";
935 StringRef Type = CheckTy == Check::CheckNext
936 ? "NEXT"
937 : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME";
914938 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart),
915939 SourceMgr::DK_Error,
916940 "found '" + UsedPrefix + "-" + Type +
10561080
10571081 /// Verify there is a single line in the given buffer.
10581082 bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const {
1059 if (Pat.getCheckTy() != Check::CheckNext)
1083 if (Pat.getCheckTy() != Check::CheckNext &&
1084 Pat.getCheckTy() != Check::CheckEmpty)
10601085 return false;
1086
1087 Twine CheckName =
1088 Prefix +
1089 Twine(Pat.getCheckTy() == Check::CheckEmpty ? "-EMPTY" : "-NEXT");
10611090
10621091 // Count the number of newlines between the previous match and this one.
10631092 assert(Buffer.data() !=
10641093 SM.getMemoryBuffer(SM.FindBufferContainingLoc(
10651094 SMLoc::getFromPointer(Buffer.data())))
10661095 ->getBufferStart() &&
1067 "CHECK-NEXT can't be the first check in a file");
1096 "CHECK-NEXT and CHECK-EMPTY can't be the first check in a file");
10681097
10691098 const char *FirstNewLine = nullptr;
10701099 unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine);
10711100
1101 // For CHECK-EMPTY, the preceding new line is consumed by the pattern, so
1102 // this needs to be re-added.
1103 if (Pat.getCheckTy() == Check::CheckEmpty)
1104 ++NumNewLines;
1105
10721106 if (NumNewLines == 0) {
10731107 SM.PrintMessage(Loc, SourceMgr::DK_Error,
1074 Prefix + "-NEXT: is on the same line as previous match");
1108 CheckName + ": is on the same line as previous match");
10751109 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
10761110 "'next' match was here");
10771111 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
10811115
10821116 if (NumNewLines != 1) {
10831117 SM.PrintMessage(Loc, SourceMgr::DK_Error,
1084 Prefix +
1085 "-NEXT: is not on the line after the previous match");
1118 CheckName +
1119 ": is not on the line after the previous match");
10861120 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note,
10871121 "'next' match was here");
10881122 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,