[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / unittests / Support / FileCheckTest.cpp
blob8df4603dbd11877102ca1ae68476fe6074f227c4
1 //===- llvm/unittest/Support/FileCheckTest.cpp - FileCheck tests --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/FileCheck.h"
10 #include "gtest/gtest.h"
11 #include <unordered_set>
13 using namespace llvm;
14 namespace {
16 class FileCheckTest : public ::testing::Test {};
18 TEST_F(FileCheckTest, Literal) {
19 // Eval returns the literal's value.
20 FileCheckExpressionLiteral Ten(10);
21 Expected<uint64_t> Value = Ten.eval();
22 EXPECT_TRUE(bool(Value));
23 EXPECT_EQ(10U, *Value);
25 // Max value can be correctly represented.
26 FileCheckExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
27 Value = Max.eval();
28 EXPECT_TRUE(bool(Value));
29 EXPECT_EQ(std::numeric_limits<uint64_t>::max(), *Value);
32 static std::string toString(const std::unordered_set<std::string> &Set) {
33 bool First = true;
34 std::string Str;
35 for (StringRef S : Set) {
36 Str += Twine(First ? "{" + S : ", " + S).str();
37 First = false;
39 Str += '}';
40 return Str;
43 static void
44 expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames,
45 Error Err) {
46 handleAllErrors(std::move(Err), [&](const FileCheckUndefVarError &E) {
47 ExpectedUndefVarNames.erase(E.getVarName());
48 });
49 EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
52 static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
53 expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
56 TEST_F(FileCheckTest, NumericVariable) {
57 // Undefined variable: getValue and eval fail, error returned by eval holds
58 // the name of the undefined variable and setValue does not trigger assert.
59 FileCheckNumericVariable FooVar = FileCheckNumericVariable(1, "FOO");
60 EXPECT_EQ("FOO", FooVar.getName());
61 FileCheckNumericVariableUse FooVarUse =
62 FileCheckNumericVariableUse("FOO", &FooVar);
63 EXPECT_FALSE(FooVar.getValue());
64 Expected<uint64_t> EvalResult = FooVarUse.eval();
65 EXPECT_FALSE(EvalResult);
66 expectUndefError("FOO", EvalResult.takeError());
67 FooVar.setValue(42);
69 // Defined variable: getValue and eval return value set.
70 Optional<uint64_t> Value = FooVar.getValue();
71 EXPECT_TRUE(bool(Value));
72 EXPECT_EQ(42U, *Value);
73 EvalResult = FooVarUse.eval();
74 EXPECT_TRUE(bool(EvalResult));
75 EXPECT_EQ(42U, *EvalResult);
77 // Clearing variable: getValue and eval fail. Error returned by eval holds
78 // the name of the cleared variable.
79 FooVar.clearValue();
80 Value = FooVar.getValue();
81 EXPECT_FALSE(Value);
82 EvalResult = FooVarUse.eval();
83 EXPECT_FALSE(EvalResult);
84 expectUndefError("FOO", EvalResult.takeError());
87 uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
89 TEST_F(FileCheckTest, Binop) {
90 FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42);
91 std::unique_ptr<FileCheckNumericVariableUse> FooVarUse =
92 llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
93 FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR", 18);
94 std::unique_ptr<FileCheckNumericVariableUse> BarVarUse =
95 llvm::make_unique<FileCheckNumericVariableUse>("BAR", &BarVar);
96 FileCheckASTBinop Binop =
97 FileCheckASTBinop(doAdd, std::move(FooVarUse), std::move(BarVarUse));
99 // Defined variable: eval returns right value.
100 Expected<uint64_t> Value = Binop.eval();
101 EXPECT_TRUE(bool(Value));
102 EXPECT_EQ(60U, *Value);
104 // 1 undefined variable: eval fails, error contains name of undefined
105 // variable.
106 FooVar.clearValue();
107 Value = Binop.eval();
108 EXPECT_FALSE(Value);
109 expectUndefError("FOO", Value.takeError());
111 // 2 undefined variables: eval fails, error contains names of all undefined
112 // variables.
113 BarVar.clearValue();
114 Value = Binop.eval();
115 EXPECT_FALSE(Value);
116 expectUndefErrors({"FOO", "BAR"}, Value.takeError());
119 TEST_F(FileCheckTest, ValidVarNameStart) {
120 EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a'));
121 EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G'));
122 EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('_'));
123 EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('2'));
124 EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('$'));
125 EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('@'));
126 EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('+'));
127 EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('-'));
128 EXPECT_FALSE(FileCheckPattern::isValidVarNameStart(':'));
131 static StringRef bufferize(SourceMgr &SM, StringRef Str) {
132 std::unique_ptr<MemoryBuffer> Buffer =
133 MemoryBuffer::getMemBufferCopy(Str, "TestBuffer");
134 StringRef StrBufferRef = Buffer->getBuffer();
135 SM.AddNewSourceBuffer(std::move(Buffer), SMLoc());
136 return StrBufferRef;
139 TEST_F(FileCheckTest, ParseVar) {
140 SourceMgr SM;
141 StringRef OrigVarName = bufferize(SM, "GoodVar42");
142 StringRef VarName = OrigVarName;
143 Expected<FileCheckPattern::VariableProperties> ParsedVarResult =
144 FileCheckPattern::parseVariable(VarName, SM);
145 EXPECT_TRUE(bool(ParsedVarResult));
146 EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
147 EXPECT_TRUE(VarName.empty());
148 EXPECT_FALSE(ParsedVarResult->IsPseudo);
150 VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar");
151 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
152 EXPECT_TRUE(bool(ParsedVarResult));
153 EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
154 EXPECT_TRUE(VarName.empty());
155 EXPECT_FALSE(ParsedVarResult->IsPseudo);
157 VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar");
158 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
159 EXPECT_TRUE(bool(ParsedVarResult));
160 EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
161 EXPECT_TRUE(VarName.empty());
162 EXPECT_TRUE(ParsedVarResult->IsPseudo);
164 VarName = bufferize(SM, "42BadVar");
165 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
166 EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
168 VarName = bufferize(SM, "$@");
169 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
170 EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
172 VarName = OrigVarName = bufferize(SM, "B@dVar");
173 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
174 EXPECT_TRUE(bool(ParsedVarResult));
175 EXPECT_EQ(VarName, OrigVarName.substr(1));
176 EXPECT_EQ(ParsedVarResult->Name, "B");
177 EXPECT_FALSE(ParsedVarResult->IsPseudo);
179 VarName = OrigVarName = bufferize(SM, "B$dVar");
180 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
181 EXPECT_TRUE(bool(ParsedVarResult));
182 EXPECT_EQ(VarName, OrigVarName.substr(1));
183 EXPECT_EQ(ParsedVarResult->Name, "B");
184 EXPECT_FALSE(ParsedVarResult->IsPseudo);
186 VarName = bufferize(SM, "BadVar+");
187 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
188 EXPECT_TRUE(bool(ParsedVarResult));
189 EXPECT_EQ(VarName, "+");
190 EXPECT_EQ(ParsedVarResult->Name, "BadVar");
191 EXPECT_FALSE(ParsedVarResult->IsPseudo);
193 VarName = bufferize(SM, "BadVar-");
194 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
195 EXPECT_TRUE(bool(ParsedVarResult));
196 EXPECT_EQ(VarName, "-");
197 EXPECT_EQ(ParsedVarResult->Name, "BadVar");
198 EXPECT_FALSE(ParsedVarResult->IsPseudo);
200 VarName = bufferize(SM, "BadVar:");
201 ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
202 EXPECT_TRUE(bool(ParsedVarResult));
203 EXPECT_EQ(VarName, ":");
204 EXPECT_EQ(ParsedVarResult->Name, "BadVar");
205 EXPECT_FALSE(ParsedVarResult->IsPseudo);
208 class PatternTester {
209 private:
210 size_t LineNumber = 1;
211 SourceMgr SM;
212 FileCheckRequest Req;
213 FileCheckPatternContext Context;
214 FileCheckPattern P =
215 FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
217 public:
218 PatternTester() {
219 std::vector<std::string> GlobalDefines;
220 GlobalDefines.emplace_back(std::string("#FOO=42"));
221 GlobalDefines.emplace_back(std::string("BAR=BAZ"));
222 EXPECT_FALSE(
223 errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
224 Context.createLineVariable();
225 // Call parsePattern to have @LINE defined.
226 P.parsePattern("N/A", "CHECK", SM, Req);
227 // parsePattern does not expect to be called twice for the same line and
228 // will set FixedStr and RegExStr incorrectly if it is. Therefore prepare
229 // a pattern for a different line.
230 initNextPattern();
233 void initNextPattern() {
234 P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
237 bool parseNumVarDefExpect(StringRef Expr) {
238 StringRef ExprBufferRef = bufferize(SM, Expr);
239 return errorToBool(FileCheckPattern::parseNumericVariableDefinition(
240 ExprBufferRef, &Context, LineNumber, SM)
241 .takeError());
244 bool parseSubstExpect(StringRef Expr) {
245 StringRef ExprBufferRef = bufferize(SM, Expr);
246 Optional<FileCheckNumericVariable *> DefinedNumericVariable;
247 return errorToBool(P.parseNumericSubstitutionBlock(
248 ExprBufferRef, DefinedNumericVariable, false, SM)
249 .takeError());
252 bool parsePatternExpect(StringRef Pattern) {
253 StringRef PatBufferRef = bufferize(SM, Pattern);
254 return P.parsePattern(PatBufferRef, "CHECK", SM, Req);
257 bool matchExpect(StringRef Buffer) {
258 StringRef BufferRef = bufferize(SM, Buffer);
259 size_t MatchLen;
260 return errorToBool(P.match(BufferRef, MatchLen, SM).takeError());
264 TEST_F(FileCheckTest, ParseNumericVariableDefinition) {
265 PatternTester Tester;
267 // Invalid definition of pseudo.
268 EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE"));
270 // Conflict with pattern variable.
271 EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR"));
273 // Defined variable.
274 EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO"));
277 TEST_F(FileCheckTest, ParseExpr) {
278 PatternTester Tester;
280 // Variable definition.
282 // Definition of invalid variable.
283 EXPECT_TRUE(Tester.parseSubstExpect("10VAR:"));
284 EXPECT_TRUE(Tester.parseSubstExpect("@FOO:"));
285 EXPECT_TRUE(Tester.parseSubstExpect("@LINE:"));
287 // Garbage after name of variable being defined.
288 EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:"));
290 // Variable defined to numeric expression.
291 EXPECT_TRUE(Tester.parseSubstExpect("VAR1: FOO"));
293 // Acceptable variable definition.
294 EXPECT_FALSE(Tester.parseSubstExpect("VAR1:"));
295 EXPECT_FALSE(Tester.parseSubstExpect(" VAR2:"));
296 EXPECT_FALSE(Tester.parseSubstExpect("VAR3 :"));
297 EXPECT_FALSE(Tester.parseSubstExpect("VAR3: "));
299 // Numeric expression.
301 // Unacceptable variable.
302 EXPECT_TRUE(Tester.parseSubstExpect("10VAR"));
303 EXPECT_TRUE(Tester.parseSubstExpect("@FOO"));
305 // Only valid variable.
306 EXPECT_FALSE(Tester.parseSubstExpect("@LINE"));
307 EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
308 EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
310 // Use variable defined on same line.
311 EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
312 EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR"));
314 // Unsupported operator.
315 EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2"));
317 // Missing offset operand.
318 EXPECT_TRUE(Tester.parseSubstExpect("@LINE+"));
320 // Valid expression.
321 EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5"));
322 EXPECT_FALSE(Tester.parseSubstExpect("FOO+4"));
323 Tester.initNextPattern();
324 EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+FOO]]"));
325 EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+3-FOO]]"));
328 TEST_F(FileCheckTest, ParsePattern) {
329 PatternTester Tester;
331 // Space in pattern variable expression.
332 EXPECT_TRUE(Tester.parsePatternExpect("[[ BAR]]"));
334 // Invalid variable name.
335 EXPECT_TRUE(Tester.parsePatternExpect("[[42INVALID]]"));
337 // Invalid pattern variable definition.
338 EXPECT_TRUE(Tester.parsePatternExpect("[[@PAT:]]"));
339 EXPECT_TRUE(Tester.parsePatternExpect("[[PAT+2:]]"));
341 // Collision with numeric variable.
342 EXPECT_TRUE(Tester.parsePatternExpect("[[FOO:]]"));
344 // Valid use of pattern variable.
345 EXPECT_FALSE(Tester.parsePatternExpect("[[BAR]]"));
347 // Valid pattern variable definition.
348 EXPECT_FALSE(Tester.parsePatternExpect("[[PAT:[0-9]+]]"));
350 // Invalid numeric expressions.
351 EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]"));
352 EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]"));
353 EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]"));
354 EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]"));
356 // Valid numeric expressions and numeric variable definition.
357 EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]"));
358 EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE+2]]"));
359 EXPECT_FALSE(Tester.parsePatternExpect("[[#NUMVAR:]]"));
362 TEST_F(FileCheckTest, Match) {
363 PatternTester Tester;
365 // Check matching a definition only matches a number.
366 Tester.parsePatternExpect("[[#NUMVAR:]]");
367 EXPECT_TRUE(Tester.matchExpect("FAIL"));
368 EXPECT_FALSE(Tester.matchExpect("18"));
370 // Check matching the variable defined matches the correct number only
371 Tester.initNextPattern();
372 Tester.parsePatternExpect("[[#NUMVAR]] [[#NUMVAR+2]]");
373 EXPECT_TRUE(Tester.matchExpect("19 21"));
374 EXPECT_TRUE(Tester.matchExpect("18 21"));
375 EXPECT_FALSE(Tester.matchExpect("18 20"));
377 // Check matching a numeric expression using @LINE after match failure uses
378 // the correct value for @LINE.
379 Tester.initNextPattern();
380 EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
381 // Ok, @LINE is 4 now.
382 EXPECT_FALSE(Tester.matchExpect("4"));
383 Tester.initNextPattern();
384 // @LINE is now 5, match with substitution failure.
385 EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]"));
386 EXPECT_TRUE(Tester.matchExpect("FOO"));
387 Tester.initNextPattern();
388 // Check that @LINE is 6 as expected.
389 EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
390 EXPECT_FALSE(Tester.matchExpect("6"));
393 TEST_F(FileCheckTest, Substitution) {
394 SourceMgr SM;
395 FileCheckPatternContext Context;
396 std::vector<std::string> GlobalDefines;
397 GlobalDefines.emplace_back(std::string("FOO=BAR"));
398 EXPECT_FALSE(errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
400 // Substitution of an undefined string variable fails and error holds that
401 // variable's name.
402 FileCheckStringSubstitution StringSubstitution =
403 FileCheckStringSubstitution(&Context, "VAR404", 42);
404 Expected<std::string> SubstValue = StringSubstitution.getResult();
405 EXPECT_FALSE(bool(SubstValue));
406 expectUndefError("VAR404", SubstValue.takeError());
408 // Substitutions of defined pseudo and non-pseudo numeric variables return
409 // the right value.
410 FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42);
411 FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 10);
412 auto LineVarUse =
413 llvm::make_unique<FileCheckNumericVariableUse>("@LINE", &LineVar);
414 auto NVarUse = llvm::make_unique<FileCheckNumericVariableUse>("N", &NVar);
415 FileCheckNumericSubstitution SubstitutionLine = FileCheckNumericSubstitution(
416 &Context, "@LINE", std::move(LineVarUse), 12);
417 FileCheckNumericSubstitution SubstitutionN =
418 FileCheckNumericSubstitution(&Context, "N", std::move(NVarUse), 30);
419 SubstValue = SubstitutionLine.getResult();
420 EXPECT_TRUE(bool(SubstValue));
421 EXPECT_EQ("42", *SubstValue);
422 SubstValue = SubstitutionN.getResult();
423 EXPECT_TRUE(bool(SubstValue));
424 EXPECT_EQ("10", *SubstValue);
426 // Substitution of an undefined numeric variable fails, error holds name of
427 // undefined variable.
428 LineVar.clearValue();
429 SubstValue = SubstitutionLine.getResult();
430 EXPECT_FALSE(bool(SubstValue));
431 expectUndefError("@LINE", SubstValue.takeError());
432 NVar.clearValue();
433 SubstValue = SubstitutionN.getResult();
434 EXPECT_FALSE(bool(SubstValue));
435 expectUndefError("N", SubstValue.takeError());
437 // Substitution of a defined string variable returns the right value.
438 FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context, 1);
439 StringSubstitution = FileCheckStringSubstitution(&Context, "FOO", 42);
440 SubstValue = StringSubstitution.getResult();
441 EXPECT_TRUE(bool(SubstValue));
442 EXPECT_EQ("BAR", *SubstValue);
445 TEST_F(FileCheckTest, FileCheckContext) {
446 FileCheckPatternContext Cxt = FileCheckPatternContext();
447 std::vector<std::string> GlobalDefines;
448 SourceMgr SM;
450 // Missing equal sign.
451 GlobalDefines.emplace_back(std::string("LocalVar"));
452 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
453 GlobalDefines.clear();
454 GlobalDefines.emplace_back(std::string("#LocalNumVar"));
455 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
457 // Empty variable name.
458 GlobalDefines.clear();
459 GlobalDefines.emplace_back(std::string("=18"));
460 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
461 GlobalDefines.clear();
462 GlobalDefines.emplace_back(std::string("#=18"));
463 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
465 // Invalid variable name.
466 GlobalDefines.clear();
467 GlobalDefines.emplace_back(std::string("18LocalVar=18"));
468 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
469 GlobalDefines.clear();
470 GlobalDefines.emplace_back(std::string("#18LocalNumVar=18"));
471 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
473 // Name conflict between pattern and numeric variable.
474 GlobalDefines.clear();
475 GlobalDefines.emplace_back(std::string("LocalVar=18"));
476 GlobalDefines.emplace_back(std::string("#LocalVar=36"));
477 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
478 Cxt = FileCheckPatternContext();
479 GlobalDefines.clear();
480 GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
481 GlobalDefines.emplace_back(std::string("LocalNumVar=36"));
482 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
483 Cxt = FileCheckPatternContext();
485 // Invalid numeric value for numeric variable.
486 GlobalDefines.clear();
487 GlobalDefines.emplace_back(std::string("#LocalNumVar=x"));
488 EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
490 // Define local variables from command-line.
491 GlobalDefines.clear();
492 GlobalDefines.emplace_back(std::string("LocalVar=FOO"));
493 GlobalDefines.emplace_back(std::string("EmptyVar="));
494 GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
495 EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
497 // Check defined variables are present and undefined is absent.
498 StringRef LocalVarStr = "LocalVar";
499 StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar");
500 StringRef EmptyVarStr = "EmptyVar";
501 StringRef UnknownVarStr = "UnknownVar";
502 Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
503 FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1);
504 Optional<FileCheckNumericVariable *> DefinedNumericVariable;
505 Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionAST =
506 P.parseNumericSubstitutionBlock(LocalNumVarRef, DefinedNumericVariable,
507 /*IsLegacyLineExpr=*/false, SM);
508 EXPECT_TRUE(bool(LocalVar));
509 EXPECT_EQ(*LocalVar, "FOO");
510 Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
511 Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
512 EXPECT_TRUE(bool(ExpressionAST));
513 Expected<uint64_t> ExpressionVal = (*ExpressionAST)->eval();
514 EXPECT_TRUE(bool(ExpressionVal));
515 EXPECT_EQ(*ExpressionVal, 18U);
516 EXPECT_TRUE(bool(EmptyVar));
517 EXPECT_EQ(*EmptyVar, "");
518 EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
520 // Clear local variables and check they become absent.
521 Cxt.clearLocalVars();
522 LocalVar = Cxt.getPatternVarValue(LocalVarStr);
523 EXPECT_TRUE(errorToBool(LocalVar.takeError()));
524 // Check a numeric expression's evaluation fails if called after clearing of
525 // local variables, if it was created before. This is important because local
526 // variable clearing due to --enable-var-scope happens after numeric
527 // expressions are linked to the numeric variables they use.
528 EXPECT_TRUE(errorToBool((*ExpressionAST)->eval().takeError()));
529 P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
530 ExpressionAST = P.parseNumericSubstitutionBlock(
531 LocalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
532 EXPECT_TRUE(bool(ExpressionAST));
533 ExpressionVal = (*ExpressionAST)->eval();
534 EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
535 EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
536 EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
537 // Clear again because parseNumericSubstitutionBlock would have created a
538 // dummy variable and stored it in GlobalNumericVariableTable.
539 Cxt.clearLocalVars();
541 // Redefine global variables and check variables are defined again.
542 GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
543 GlobalDefines.emplace_back(std::string("#$GlobalNumVar=36"));
544 EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
545 StringRef GlobalVarStr = "$GlobalVar";
546 StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar");
547 Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
548 EXPECT_TRUE(bool(GlobalVar));
549 EXPECT_EQ(*GlobalVar, "BAR");
550 P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
551 ExpressionAST = P.parseNumericSubstitutionBlock(
552 GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
553 EXPECT_TRUE(bool(ExpressionAST));
554 ExpressionVal = (*ExpressionAST)->eval();
555 EXPECT_TRUE(bool(ExpressionVal));
556 EXPECT_EQ(*ExpressionVal, 36U);
558 // Clear local variables and check global variables remain defined.
559 Cxt.clearLocalVars();
560 EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
561 P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
562 ExpressionAST = P.parseNumericSubstitutionBlock(
563 GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
564 EXPECT_TRUE(bool(ExpressionAST));
565 ExpressionVal = (*ExpressionAST)->eval();
566 EXPECT_TRUE(bool(ExpressionVal));
567 EXPECT_EQ(*ExpressionVal, 36U);
569 } // namespace