summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Support/FileCheckTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/Support/FileCheckTest.cpp')
-rw-r--r--llvm/unittests/Support/FileCheckTest.cpp166
1 files changed, 113 insertions, 53 deletions
diff --git a/llvm/unittests/Support/FileCheckTest.cpp b/llvm/unittests/Support/FileCheckTest.cpp
index 2b7b2707be8..147ed68e223 100644
--- a/llvm/unittests/Support/FileCheckTest.cpp
+++ b/llvm/unittests/Support/FileCheckTest.cpp
@@ -49,15 +49,21 @@ expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames,
EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
}
+// Return whether Err contains any FileCheckUndefVarError whose associated name
+// is not ExpectedUndefVarName.
static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
}
+uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
+
TEST_F(FileCheckTest, NumericVariable) {
- // Undefined variable: getValue and eval fail, error returned by eval holds
- // the name of the undefined variable.
+ // Undefined variable: isValueKnownAtMatchTime returns false, getValue and
+ // eval fail, error returned by eval holds the name of the undefined
+ // variable.
FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1);
EXPECT_EQ("FOO", FooVar.getName());
+ EXPECT_FALSE(FooVar.isValueKnownAtMatchTime());
FileCheckNumericVariableUse FooVarUse =
FileCheckNumericVariableUse("FOO", &FooVar);
EXPECT_FALSE(FooVar.getValue());
@@ -67,7 +73,9 @@ TEST_F(FileCheckTest, NumericVariable) {
FooVar.setValue(42);
- // Defined variable: getValue and eval return value set.
+ // Defined variable: isValueKnownAtMatchTime returns true, getValue and eval
+ // return value set.
+ EXPECT_TRUE(FooVar.isValueKnownAtMatchTime());
Optional<uint64_t> Value = FooVar.getValue();
EXPECT_TRUE(bool(Value));
EXPECT_EQ(42U, *Value);
@@ -75,24 +83,51 @@ TEST_F(FileCheckTest, NumericVariable) {
EXPECT_TRUE(bool(EvalResult));
EXPECT_EQ(42U, *EvalResult);
+ // Variable defined by numeric expression: isValueKnownAtMatchTime
+ // returns true, getValue and eval return value of expression, setValue
+ // clears expression.
+ std::unique_ptr<FileCheckNumericVariableUse> FooVarUsePtr =
+ llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
+ std::unique_ptr<FileCheckExpressionLiteral> One =
+ llvm::make_unique<FileCheckExpressionLiteral>(1);
+ FileCheckASTBinop Binop =
+ FileCheckASTBinop(doAdd, std::move(FooVarUsePtr), std::move(One));
+ FileCheckNumericVariable FoobarExprVar =
+ FileCheckNumericVariable("FOOBAR", 2, &Binop);
+ EXPECT_TRUE(FoobarExprVar.isValueKnownAtMatchTime());
+ EXPECT_FALSE(FoobarExprVar.getValue());
+ FileCheckNumericVariableUse FoobarExprVarUse =
+ FileCheckNumericVariableUse("FOOBAR", &FoobarExprVar);
+ EvalResult = FoobarExprVarUse.eval();
+ EXPECT_TRUE(bool(EvalResult));
+ EXPECT_EQ(43U, *EvalResult);
+ EXPECT_TRUE(FoobarExprVar.getExpressionAST());
+ FoobarExprVar.setValue(43);
+ EXPECT_FALSE(FoobarExprVar.getExpressionAST());
+ FoobarExprVar = FileCheckNumericVariable("FOOBAR", 2, &Binop);
+ EXPECT_TRUE(FoobarExprVar.getExpressionAST());
+
// Clearing variable: getValue and eval fail. Error returned by eval holds
// the name of the cleared variable.
FooVar.clearValue();
- Value = FooVar.getValue();
- EXPECT_FALSE(Value);
+ FoobarExprVar.clearValue();
+ EXPECT_FALSE(FoobarExprVar.getExpressionAST());
+ EXPECT_FALSE(FooVar.getValue());
+ EXPECT_FALSE(FoobarExprVar.getValue());
EvalResult = FooVarUse.eval();
EXPECT_FALSE(EvalResult);
expectUndefError("FOO", EvalResult.takeError());
+ EvalResult = FoobarExprVarUse.eval();
+ EXPECT_FALSE(EvalResult);
+ expectUndefError("FOOBAR", EvalResult.takeError());
}
-uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
-
TEST_F(FileCheckTest, Binop) {
- FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO");
+ FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1);
FooVar.setValue(42);
std::unique_ptr<FileCheckNumericVariableUse> FooVarUse =
llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
- FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR");
+ FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR", 2);
BarVar.setValue(18);
std::unique_ptr<FileCheckNumericVariableUse> BarVarUse =
llvm::make_unique<FileCheckNumericVariableUse>("BAR", &BarVar);
@@ -237,19 +272,13 @@ public:
P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
}
- bool parseNumVarDefExpect(StringRef Expr) {
- StringRef ExprBufferRef = bufferize(SM, Expr);
- return errorToBool(FileCheckPattern::parseNumericVariableDefinition(
- ExprBufferRef, &Context, LineNumber, SM)
- .takeError());
- }
-
bool parseSubstExpect(StringRef Expr) {
StringRef ExprBufferRef = bufferize(SM, Expr);
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
- return errorToBool(P.parseNumericSubstitutionBlock(
- ExprBufferRef, DefinedNumericVariable, false, SM)
- .takeError());
+ return errorToBool(
+ P.parseNumericSubstitutionBlock(ExprBufferRef, DefinedNumericVariable,
+ false, LineNumber - 1, &Context, SM)
+ .takeError());
}
bool parsePatternExpect(StringRef Pattern) {
@@ -264,19 +293,6 @@ public:
}
};
-TEST_F(FileCheckTest, ParseNumericVariableDefinition) {
- PatternTester Tester;
-
- // Invalid definition of pseudo.
- EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE"));
-
- // Conflict with pattern variable.
- EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR"));
-
- // Defined variable.
- EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO"));
-}
-
TEST_F(FileCheckTest, ParseExpr) {
PatternTester Tester;
@@ -287,17 +303,18 @@ TEST_F(FileCheckTest, ParseExpr) {
EXPECT_TRUE(Tester.parseSubstExpect("@FOO:"));
EXPECT_TRUE(Tester.parseSubstExpect("@LINE:"));
+ // Conflict with pattern variable.
+ EXPECT_TRUE(Tester.parseSubstExpect("BAR:"));
+
// Garbage after name of variable being defined.
EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:"));
- // Variable defined to numeric expression.
- EXPECT_TRUE(Tester.parseSubstExpect("VAR1: FOO"));
-
// Acceptable variable definition.
EXPECT_FALSE(Tester.parseSubstExpect("VAR1:"));
EXPECT_FALSE(Tester.parseSubstExpect(" VAR2:"));
EXPECT_FALSE(Tester.parseSubstExpect("VAR3 :"));
EXPECT_FALSE(Tester.parseSubstExpect("VAR3: "));
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#FOOBAR: FOO+1]]"));
// Numeric expression.
@@ -310,9 +327,21 @@ TEST_F(FileCheckTest, ParseExpr) {
EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
- // Use variable defined on same line.
- EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
- EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR"));
+ // Valid empty expression.
+ EXPECT_FALSE(Tester.parseSubstExpect(""));
+
+ // Valid use of variable defined on the same line from expression. Note that
+ // the same pattern object is used for the parsePatternExpect and
+ // parseSubstExpect since no initNextPattern is called, thus appearing as
+ // being on the same line from the pattern's point of view.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:FOO+1]]"));
+ EXPECT_FALSE(Tester.parseSubstExpect("LINE1VAR"));
+
+ // Invalid use of variable defined on same line from input. As above, the
+ // absence of a call to initNextPattern makes it appear to be on the same
+ // line from the pattern's point of view.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE2VAR:]]"));
+ EXPECT_TRUE(Tester.parseSubstExpect("LINE2VAR"));
// Unsupported operator.
EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2"));
@@ -323,6 +352,7 @@ TEST_F(FileCheckTest, ParseExpr) {
// Valid expression.
EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5"));
EXPECT_FALSE(Tester.parseSubstExpect("FOO+4"));
+ EXPECT_FALSE(Tester.parseSubstExpect("FOOBAR"));
Tester.initNextPattern();
EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+FOO]]"));
EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+3-FOO]]"));
@@ -354,7 +384,6 @@ TEST_F(FileCheckTest, ParsePattern) {
EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]"));
EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]"));
EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]"));
- EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]"));
// Valid numeric expressions and numeric variable definition.
EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]"));
@@ -365,9 +394,16 @@ TEST_F(FileCheckTest, ParsePattern) {
TEST_F(FileCheckTest, Match) {
PatternTester Tester;
+ // Check matching an empty expression only matches a number.
+ Tester.parsePatternExpect("[[#]]");
+ EXPECT_TRUE(Tester.matchExpect("FAIL"));
+ EXPECT_FALSE(Tester.matchExpect("18"));
+
// Check matching a definition only matches a number.
+ Tester.initNextPattern();
Tester.parsePatternExpect("[[#NUMVAR:]]");
EXPECT_TRUE(Tester.matchExpect("FAIL"));
+ EXPECT_TRUE(Tester.matchExpect(""));
EXPECT_FALSE(Tester.matchExpect("18"));
// Check matching the variable defined matches the correct number only
@@ -381,16 +417,16 @@ TEST_F(FileCheckTest, Match) {
// the correct value for @LINE.
Tester.initNextPattern();
EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
- // Ok, @LINE is 4 now.
- EXPECT_FALSE(Tester.matchExpect("4"));
+ // Ok, @LINE is 5 now.
+ EXPECT_FALSE(Tester.matchExpect("5"));
Tester.initNextPattern();
- // @LINE is now 5, match with substitution failure.
+ // @LINE is now 6, match with substitution failure.
EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]"));
EXPECT_TRUE(Tester.matchExpect("FOO"));
Tester.initNextPattern();
- // Check that @LINE is 6 as expected.
+ // Check that @LINE is 7 as expected.
EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
- EXPECT_FALSE(Tester.matchExpect("6"));
+ EXPECT_FALSE(Tester.matchExpect("7"));
}
TEST_F(FileCheckTest, Substitution) {
@@ -410,9 +446,9 @@ TEST_F(FileCheckTest, Substitution) {
// Substitutions of defined pseudo and non-pseudo numeric variables return
// the right value.
- FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE");
+ FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 1);
+ FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 1);
LineVar.setValue(42);
- FileCheckNumericVariable NVar = FileCheckNumericVariable("N");
NVar.setValue(10);
auto LineVarUse =
llvm::make_unique<FileCheckNumericVariableUse>("@LINE", &LineVar);
@@ -494,22 +530,29 @@ TEST_F(FileCheckTest, FileCheckContext) {
// Define local variables from command-line.
GlobalDefines.clear();
+ // Clear local variables to remove dummy numeric variable x that
+ // parseNumericSubstitutionBlock would have created and stored in
+ // GlobalNumericVariableTable.
+ Cxt.clearLocalVars();
GlobalDefines.emplace_back(std::string("LocalVar=FOO"));
GlobalDefines.emplace_back(std::string("EmptyVar="));
- GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
+ GlobalDefines.emplace_back(std::string("#LocalNumVar1=18"));
+ GlobalDefines.emplace_back(std::string("#LocalNumVar2=LocalNumVar1+2"));
EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
// Check defined variables are present and undefined is absent.
StringRef LocalVarStr = "LocalVar";
- StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar");
+ StringRef LocalNumVar1Ref = bufferize(SM, "LocalNumVar1");
+ StringRef LocalNumVar2Ref = bufferize(SM, "LocalNumVar2");
StringRef EmptyVarStr = "EmptyVar";
StringRef UnknownVarStr = "UnknownVar";
Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1);
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionAST =
- P.parseNumericSubstitutionBlock(LocalNumVarRef, DefinedNumericVariable,
- /*IsLegacyLineExpr=*/false, SM);
+ P.parseNumericSubstitutionBlock(LocalNumVar1Ref, DefinedNumericVariable,
+ /*IsLegacyLineExpr=*/false,
+ /*LineNumber=*/1, &Cxt, SM);
EXPECT_TRUE(bool(LocalVar));
EXPECT_EQ(*LocalVar, "FOO");
Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
@@ -518,6 +561,14 @@ TEST_F(FileCheckTest, FileCheckContext) {
Expected<uint64_t> ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(bool(ExpressionVal));
EXPECT_EQ(*ExpressionVal, 18U);
+ ExpressionAST =
+ P.parseNumericSubstitutionBlock(LocalNumVar2Ref, DefinedNumericVariable,
+ /*IsLegacyLineExpr=*/false,
+ /*LineNumber=*/1, &Cxt, SM);
+ EXPECT_TRUE(bool(ExpressionAST));
+ ExpressionVal = (*ExpressionAST)->eval();
+ EXPECT_TRUE(bool(ExpressionVal));
+ EXPECT_EQ(*ExpressionVal, 20U);
EXPECT_TRUE(bool(EmptyVar));
EXPECT_EQ(*EmptyVar, "");
EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
@@ -533,7 +584,14 @@ TEST_F(FileCheckTest, FileCheckContext) {
EXPECT_TRUE(errorToBool((*ExpressionAST)->eval().takeError()));
P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
ExpressionAST = P.parseNumericSubstitutionBlock(
- LocalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+ LocalNumVar1Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+ /*LineNumber=*/2, &Cxt, SM);
+ EXPECT_TRUE(bool(ExpressionAST));
+ ExpressionVal = (*ExpressionAST)->eval();
+ EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
+ ExpressionAST = P.parseNumericSubstitutionBlock(
+ LocalNumVar2Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+ /*LineNumber=*/2, &Cxt, SM);
EXPECT_TRUE(bool(ExpressionAST));
ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
@@ -554,7 +612,8 @@ TEST_F(FileCheckTest, FileCheckContext) {
EXPECT_EQ(*GlobalVar, "BAR");
P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
ExpressionAST = P.parseNumericSubstitutionBlock(
- GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+ GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+ /*LineNumber=*/3, &Cxt, SM);
EXPECT_TRUE(bool(ExpressionAST));
ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(bool(ExpressionVal));
@@ -565,7 +624,8 @@ TEST_F(FileCheckTest, FileCheckContext) {
EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
ExpressionAST = P.parseNumericSubstitutionBlock(
- GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+ GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+ /*LineNumber=*/4, &Cxt, SM);
EXPECT_TRUE(bool(ExpressionAST));
ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(bool(ExpressionVal));
OpenPOWER on IntegriCloud