llvm.org GIT mirror llvm / bb9779a
[FileCheck] Added --enable-var-scope option to enable scope for regex variables. If `--enable-var-scope` is in effect, variables with names that start with `$` are considered to be global. All other variables are local. All local variables get undefined at the beginning of each CHECK-LABEL block. Global variables are not affected by CHECK-LABEL. This makes it easier to ensure that individual tests are not affected by variables set in preceding tests. Differential Revision: https://reviews.llvm.org/D30749 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297396 91177308-0d34-0410-b5e6-96231b3b80d8 Artem Belevich 2 years ago
4 changed file(s) with 88 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
7575 diagnostic messages from tools that don't have an option similar to ``clang
7676 -verify``. With this option FileCheck will verify that input does not contain
7777 warnings not covered by any ``CHECK:`` patterns.
78
79 .. option:: --enable-var-scope
80
81 Enables scope for regex variables.
82
83 Variables with names that start with ``$`` are considered global and
84 remain set throughout the file.
85
86 All other variables get undefined after each encountered ``CHECK-LABEL``.
7887
7988 .. option:: -version
8089
343352 other unique identifiers. Conceptually, the presence of ``CHECK-LABEL`` divides
344353 the input stream into separate blocks, each of which is processed independently,
345354 preventing a ``CHECK:`` directive in one block matching a line in another block.
355 If ``--enable-var-scope`` is in effect, all local variables are cleared at the
356 beginning of the block.
357
346358 For example,
347359
348360 .. code-block:: llvm
435447 Can be useful if you want the operands of ``op`` to be the same register,
436448 and don't care exactly which register it is.
437449
450 If ``--enable-var-scope`` is in effect, variables with names that
451 start with ``$`` are considered to be global. All others variables are
452 local. All local variables get undefined at the beginning of each
453 CHECK-LABEL block. Global variables are not affected by CHECK-LABEL.
454 This makes it easier to ensure that individual tests are not affected
455 by variables set in preceding tests.
456
438457 FileCheck Expressions
439458 ~~~~~~~~~~~~~~~~~~~~~
440459
0 ; RUN: FileCheck -input-file %s %s
1 2
2 3 aaa
3 4 bbb
4 5 ccc
5 6 CHECK: [[@LINE-3]] {{a}}aa
6 7 CHECK: [[@LINE-3]] {{b}}bb
7 8 CHECK: [[@LINE-3]] {{c}}cc
8 9 foobar
9 10 CHECK: [[@LINE-1]] {{foo}}bar
10 11
11 12 arst CHECK: [[@LINE]] {{a}}rst
12 13
1 ; RUN: not FileCheck -check-prefix BAD -input-file %s %s
2 3
3 4 aaa
4 5 bbb
5 6 ccc
6 7 CHECK: [[@LINE-3]] {{a}}aa
7 8 CHECK: [[@LINE-3]] {{b}}bb
8 9 CHECK: [[@LINE-3]] {{c}}cc
9 10 foobar
10 11 CHECK: [[@LINE-1]] {{foo}}bar
11 12
12 13 arst CHECK: [[@LINE]] {{a}}rst
1313 14
14
14 15 BAD: [[@LINE:cant-have-regex]]
0 // RUN: FileCheck -check-prefix CHECK -input-file %s %s
1 // RUN: FileCheck -check-prefixes CHECK,GLOBAL -input-file %s %s
2 // RUN: FileCheck -check-prefixes CHECK,LOCAL -input-file %s %s
3 // RUN: FileCheck -check-prefixes CHECK,GLOBAL --enable-var-scope -input-file %s %s
4 // RUN: not FileCheck -check-prefixes CHECK,LOCAL --enable-var-scope -input-file %s %s
5
6 local
7 global
8 ; CHECK: [[LOCAL:loc.*]]
9 ; CHECK: [[$GLOBAL:glo.*]]
10
11 local2
12 global2
13 ; CHECK: [[LOCAL]]2
14 ; CHECK: [[$GLOBAL]]2
15
16 barrier:
17 ; CHECK-LABEL: barrier
18
19 local3
20 global3
21 ; LOCAL: [[LOCAL]]3
22 ; GLOBAL: [[$GLOBAL]]3
7272 "Allows leading and trailing whitespace if --strict-whitespace\n"
7373 "is not also passed."));
7474
75 static cl::opt EnableVarScope(
76 "enable-var-scope", cl::init(false),
77 cl::desc("Enables scope for regex variables. Variables with names that\n"
78 "do not start with '$' will be reset at the beginning of\n"
79 "each CHECK-LABEL block."));
80
7581 typedef cl::list::const_iterator prefix_iterator;
7682
7783 //===----------------------------------------------------------------------===//
262268 // is relaxed, more strict check is performed in \c EvaluateExpression.
263269 bool IsExpression = false;
264270 for (unsigned i = 0, e = Name.size(); i != e; ++i) {
265 if (i == 0 && Name[i] == '@') {
266 if (NameEnd != StringRef::npos) {
267 SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
268 SourceMgr::DK_Error,
269 "invalid name in named regex definition");
270 return true;
271 if (i == 0) {
272 if (Name[i] == '$') // Global vars start with '$'
273 continue;
274 if (Name[i] == '@') {
275 if (NameEnd != StringRef::npos) {
276 SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
277 SourceMgr::DK_Error,
278 "invalid name in named regex definition");
279 return true;
280 }
281 IsExpression = true;
282 continue;
271283 }
272 IsExpression = true;
273 continue;
274284 }
275285 if (Name[i] != '_' && !isalnum(Name[i]) &&
276286 (!IsExpression || (Name[i] != '+' && Name[i] != '-'))) {
12611271 errs() << "\n";
12621272 }
12631273
1274 // Remove local variables from \p VariableTable. Global variables
1275 // (start with '$') are preserved.
1276 static void ClearLocalVars(StringMap &VariableTable) {
1277 SmallVector LocalVars;
1278 for (const auto &Var : VariableTable)
1279 if (Var.first()[0] != '$')
1280 LocalVars.push_back(Var.first());
1281
1282 for (const auto &Var : LocalVars)
1283 VariableTable.erase(Var);
1284 }
1285
12641286 /// Check the input to FileCheck provided in the \p Buffer against the \p
12651287 /// CheckStrings read from the check file.
12661288 ///
12971319 ++j;
12981320 }
12991321
1322 if (EnableVarScope)
1323 ClearLocalVars(VariableTable);
1324
13001325 for (; i != j; ++i) {
13011326 const CheckString &CheckStr = CheckStrings[i];
13021327