diff options
author | Thomas Preud'homme <thomasp@graphcore.ai> | 2019-06-06 13:21:06 +0000 |
---|---|---|
committer | Thomas Preud'homme <thomasp@graphcore.ai> | 2019-06-06 13:21:06 +0000 |
commit | 71d3f227a790d6cf39d8c6267940e0dc0c237e11 (patch) | |
tree | 581cedcd98bb3f08cf845dd37fc36a5f2cde0e61 /llvm/unittests/Support/FileCheckTest.cpp | |
parent | bf5bca5bea5b75faa1e66db458382929fbe4e475 (diff) | |
download | llvm-71d3f227a790d6cf39d8c6267940e0dc0c237e11.zip llvm-71d3f227a790d6cf39d8c6267940e0dc0c237e11.tar.gz llvm-71d3f227a790d6cf39d8c6267940e0dc0c237e11.tar.bz2 |
FileCheck [6/12]: Introduce numeric variable definition
Summary:
This patch is part of a patch series to add support for FileCheck
numeric expressions. This specific patch introduces support for defining
numeric variable in a CHECK directive.
This commit introduces support for defining numeric variable from a
litteral value in the input text. Numeric expressions can then use the
variable provided it is on a later line.
Copyright:
- Linaro (changes up to diff 183612 of revision D55940)
- GraphCore (changes in later versions of revision D55940 and
in new revision created off D55940)
Reviewers: jhenderson, chandlerc, jdenny, probinson, grimar, arichardson, rnk
Subscribers: hiraditya, llvm-commits, probinson, dblaikie, grimar, arichardson, tra, rnk, kristina, hfinkel, rogfer01, JonChesterfield
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60386
llvm-svn: 362705
Diffstat (limited to 'llvm/unittests/Support/FileCheckTest.cpp')
-rw-r--r-- | llvm/unittests/Support/FileCheckTest.cpp | 294 |
1 files changed, 197 insertions, 97 deletions
diff --git a/llvm/unittests/Support/FileCheckTest.cpp b/llvm/unittests/Support/FileCheckTest.cpp index dba6b59..2c8f485 100644 --- a/llvm/unittests/Support/FileCheckTest.cpp +++ b/llvm/unittests/Support/FileCheckTest.cpp @@ -15,12 +15,16 @@ namespace { class FileCheckTest : public ::testing::Test {}; TEST_F(FileCheckTest, NumericVariable) { - FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42); + // Undefined variable: getValue and clearValue fails, setValue works. + FileCheckNumericVariable FooVar = FileCheckNumericVariable(1, "FOO"); EXPECT_EQ("FOO", FooVar.getName()); - - // Defined variable: getValue returns a value, setValue fails and value - // remains unchanged. llvm::Optional<uint64_t> Value = FooVar.getValue(); + EXPECT_FALSE(Value); + EXPECT_TRUE(FooVar.clearValue()); + EXPECT_FALSE(FooVar.setValue(42)); + + // Defined variable: getValue returns value set, setValue fails. + Value = FooVar.getValue(); EXPECT_TRUE(Value); EXPECT_EQ(42U, *Value); EXPECT_TRUE(FooVar.setValue(43)); @@ -33,12 +37,6 @@ TEST_F(FileCheckTest, NumericVariable) { Value = FooVar.getValue(); EXPECT_FALSE(Value); EXPECT_TRUE(FooVar.clearValue()); - - // Undefined variable: setValue works, getValue returns value set. - EXPECT_FALSE(FooVar.setValue(43)); - Value = FooVar.getValue(); - EXPECT_TRUE(Value); - EXPECT_EQ(43U, *Value); } uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; } @@ -78,67 +76,69 @@ TEST_F(FileCheckTest, ValidVarNameStart) { } TEST_F(FileCheckTest, ParseVar) { - StringRef VarName = "GoodVar42"; + StringRef OrigVarName = "GoodVar42"; + StringRef VarName = OrigVarName; + StringRef ParsedName; bool IsPseudo = true; - unsigned TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(ParsedName, OrigVarName); + EXPECT_TRUE(VarName.empty()); EXPECT_FALSE(IsPseudo); - EXPECT_EQ(TrailIdx, VarName.size()); - VarName = "$GoodGlobalVar"; + VarName = OrigVarName = "$GoodGlobalVar"; IsPseudo = true; - TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(ParsedName, OrigVarName); + EXPECT_TRUE(VarName.empty()); EXPECT_FALSE(IsPseudo); - EXPECT_EQ(TrailIdx, VarName.size()); - VarName = "@GoodPseudoVar"; + VarName = OrigVarName = "@GoodPseudoVar"; IsPseudo = true; - TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(ParsedName, OrigVarName); + EXPECT_TRUE(VarName.empty()); EXPECT_TRUE(IsPseudo); - EXPECT_EQ(TrailIdx, VarName.size()); VarName = "42BadVar"; - EXPECT_TRUE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_TRUE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); VarName = "$@"; - EXPECT_TRUE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_TRUE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); - VarName = "B@dVar"; + VarName = OrigVarName = "B@dVar"; IsPseudo = true; - TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(VarName, OrigVarName.substr(1)); + EXPECT_EQ(ParsedName, "B"); EXPECT_FALSE(IsPseudo); - EXPECT_EQ(TrailIdx, 1U); - VarName = "B$dVar"; + VarName = OrigVarName = "B$dVar"; IsPseudo = true; - TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(VarName, OrigVarName.substr(1)); + EXPECT_EQ(ParsedName, "B"); EXPECT_FALSE(IsPseudo); - EXPECT_EQ(TrailIdx, 1U); VarName = "BadVar+"; IsPseudo = true; - TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(VarName, "+"); + EXPECT_EQ(ParsedName, "BadVar"); EXPECT_FALSE(IsPseudo); - EXPECT_EQ(TrailIdx, VarName.size() - 1); VarName = "BadVar-"; IsPseudo = true; - TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(VarName, "-"); + EXPECT_EQ(ParsedName, "BadVar"); EXPECT_FALSE(IsPseudo); - EXPECT_EQ(TrailIdx, VarName.size() - 1); VarName = "BadVar:"; IsPseudo = true; - TrailIdx = 0; - EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, IsPseudo, TrailIdx)); + EXPECT_FALSE(FileCheckPattern::parseVariable(VarName, ParsedName, IsPseudo)); + EXPECT_EQ(VarName, ":"); + EXPECT_EQ(ParsedName, "BadVar"); EXPECT_FALSE(IsPseudo); - EXPECT_EQ(TrailIdx, VarName.size() - 1); } static StringRef bufferize(SourceMgr &SM, StringRef Str) { @@ -149,76 +149,175 @@ static StringRef bufferize(SourceMgr &SM, StringRef Str) { return StrBufferRef; } -class ExprTester { +class PatternTester { private: + size_t LineNumber = 1; SourceMgr SM; FileCheckRequest Req; FileCheckPatternContext Context; - FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context); + FileCheckPattern P = + FileCheckPattern(Check::CheckPlain, &Context, LineNumber++); public: - ExprTester() { + PatternTester() { std::vector<std::string> GlobalDefines; GlobalDefines.emplace_back(std::string("#FOO=42")); + GlobalDefines.emplace_back(std::string("BAR=BAZ")); Context.defineCmdlineVariables(GlobalDefines, SM); - // Call ParsePattern to have @LINE defined. - P.ParsePattern("N/A", "CHECK", SM, 1, Req); + // Call parsePattern to have @LINE defined. + P.parsePattern("N/A", "CHECK", SM, Req); + // parsePattern does not expect to be called twice for the same line and + // will set FixedStr and RegExStr incorrectly if it is. Therefore prepare + // a pattern for a different line. + initNextPattern(); + } + + void initNextPattern() { + P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++); } - bool parseExpect(std::string &VarName, std::string &Trailer) { - bool IsPseudo = VarName[0] == '@'; - std::string NameTrailer = VarName + Trailer; - StringRef NameTrailerRef = bufferize(SM, NameTrailer); - StringRef VarNameRef = NameTrailerRef.substr(0, VarName.size()); - StringRef TrailerRef = NameTrailerRef.substr(VarName.size()); - return P.parseNumericSubstitution(VarNameRef, IsPseudo, TrailerRef, SM) == - nullptr; + bool parseNumVarDefExpect(StringRef Expr) { + StringRef ExprBufferRef = bufferize(SM, Expr); + StringRef Name; + return FileCheckPattern::parseNumericVariableDefinition(ExprBufferRef, Name, + &Context, SM); + } + + bool parseSubstExpect(StringRef Expr) { + StringRef ExprBufferRef = bufferize(SM, Expr); + FileCheckNumericVariable *DefinedNumericVariable; + return P.parseNumericSubstitutionBlock( + ExprBufferRef, DefinedNumericVariable, SM) == nullptr; + } + + bool parsePatternExpect(StringRef Pattern) { + StringRef PatBufferRef = bufferize(SM, Pattern); + return P.parsePattern(PatBufferRef, "CHECK", SM, Req); + } + + bool matchExpect(StringRef Buffer) { + StringRef BufferRef = bufferize(SM, Buffer); + size_t MatchLen; + return P.match(BufferRef, MatchLen, SM); } }; -TEST_F(FileCheckTest, ParseExpr) { - ExprTester Tester; +TEST_F(FileCheckTest, ParseNumericVariableDefinition) { + PatternTester Tester; - // @LINE with offset. - std::string VarName = "@LINE"; - std::string Trailer = "+3"; - EXPECT_FALSE(Tester.parseExpect(VarName, Trailer)); + // Invalid definition of pseudo. + EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE")); - // @LINE only. - Trailer = ""; - EXPECT_FALSE(Tester.parseExpect(VarName, Trailer)); + // Conflict with pattern variable. + EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR")); // Defined variable. - VarName = "FOO"; - EXPECT_FALSE(Tester.parseExpect(VarName, Trailer)); + EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO")); +} + +TEST_F(FileCheckTest, ParseExpr) { + PatternTester Tester; + + // Variable definition. - // Undefined variable. - VarName = "UNDEF"; - EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); + // Definition of invalid variable. + EXPECT_TRUE(Tester.parseSubstExpect("10VAR:")); + EXPECT_TRUE(Tester.parseSubstExpect("@FOO:")); + EXPECT_TRUE(Tester.parseSubstExpect("@LINE:")); - // Wrong Pseudovar. - VarName = "@FOO"; - EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); + // 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: ")); + + // Numeric expression. + + // Unacceptable variable. + EXPECT_TRUE(Tester.parseSubstExpect("10VAR")); + EXPECT_TRUE(Tester.parseSubstExpect("@FOO")); + EXPECT_TRUE(Tester.parseSubstExpect("UNDEF")); + + // Only valid variable. + EXPECT_FALSE(Tester.parseSubstExpect("@LINE")); + EXPECT_FALSE(Tester.parseSubstExpect("FOO")); + + // Use variable defined on same line. + EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]")); + EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR")); // Unsupported operator. - VarName = "@LINE"; - Trailer = "/2"; - EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); + EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2")); // Missing offset operand. - VarName = "@LINE"; - Trailer = "+"; - EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); + EXPECT_TRUE(Tester.parseSubstExpect("@LINE+")); // Cannot parse offset operand. - VarName = "@LINE"; - Trailer = "+x"; - EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); + EXPECT_TRUE(Tester.parseSubstExpect("@LINE+x")); // Unexpected string at end of numeric expression. - VarName = "@LINE"; - Trailer = "+5x"; - EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); + EXPECT_TRUE(Tester.parseSubstExpect("@LINE+5x")); + + // Valid expression. + EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5")); + EXPECT_FALSE(Tester.parseSubstExpect("FOO+4")); +} + +TEST_F(FileCheckTest, ParsePattern) { + PatternTester Tester; + + // Space in pattern variable expression. + EXPECT_TRUE(Tester.parsePatternExpect("[[ BAR]]")); + + // Invalid variable name. + EXPECT_TRUE(Tester.parsePatternExpect("[[42INVALID]]")); + + // Invalid pattern variable definition. + EXPECT_TRUE(Tester.parsePatternExpect("[[@PAT:]]")); + EXPECT_TRUE(Tester.parsePatternExpect("[[PAT+2:]]")); + + // Collision with numeric variable. + EXPECT_TRUE(Tester.parsePatternExpect("[[FOO:]]")); + + // Valid use of pattern variable. + EXPECT_FALSE(Tester.parsePatternExpect("[[BAR]]")); + + // Valid pattern variable definition. + EXPECT_FALSE(Tester.parsePatternExpect("[[PAT:[0-9]+]]")); + + // Invalid numeric expressions. + EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]")); + EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]")); + EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]")); + EXPECT_TRUE(Tester.parsePatternExpect("[[#2+@LINE]]")); + EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]")); + + // Valid numeric expressions and numeric variable definition. + EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]")); + EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE+2]]")); + EXPECT_FALSE(Tester.parsePatternExpect("[[#NUMVAR:]]")); +} + +TEST_F(FileCheckTest, Match) { + PatternTester Tester; + + // Check matching a definition only matches a number. + Tester.parsePatternExpect("[[#NUMVAR:]]"); + EXPECT_TRUE(Tester.matchExpect("FAIL")); + EXPECT_FALSE(Tester.matchExpect("18")); + + // Check matching the variable defined matches the correct number only + Tester.initNextPattern(); + Tester.parsePatternExpect("[[#NUMVAR]] [[#NUMVAR+2]]"); + EXPECT_TRUE(Tester.matchExpect("19 21")); + EXPECT_TRUE(Tester.matchExpect("18 21")); + EXPECT_FALSE(Tester.matchExpect("18 20")); } TEST_F(FileCheckTest, Substitution) { @@ -236,7 +335,7 @@ TEST_F(FileCheckTest, Substitution) { // Substitutions of defined pseudo and non-pseudo numeric variables return // the right value. FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42); - FileCheckNumericVariable NVar = FileCheckNumericVariable("@N", 10); + FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 10); FileCheckNumExpr NumExprLine = FileCheckNumExpr(doAdd, &LineVar, 0); FileCheckNumExpr NumExprN = FileCheckNumExpr(doAdd, &NVar, 3); FileCheckNumericSubstitution SubstitutionLine = @@ -257,7 +356,7 @@ TEST_F(FileCheckTest, Substitution) { EXPECT_FALSE(SubstitutionN.getResult()); // Substitution of a defined string variable returns the right value. - FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context); + FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context, 1); StringSubstitution = FileCheckStringSubstitution(&Context, "FOO", 42); Value = StringSubstitution.getResult(); EXPECT_TRUE(Value); @@ -359,9 +458,10 @@ TEST_F(FileCheckTest, FileCheckContext) { StringRef EmptyVarStr = "EmptyVar"; StringRef UnknownVarStr = "UnknownVar"; llvm::Optional<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr); - FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt); - FileCheckNumExpr *NumExpr = - P.parseNumericSubstitution(LocalNumVarRef, false /*IsPseudo*/, "", SM); + FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1); + FileCheckNumericVariable *DefinedNumericVariable; + FileCheckNumExpr *NumExpr = P.parseNumericSubstitutionBlock( + LocalNumVarRef, DefinedNumericVariable, SM); llvm::Optional<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); llvm::Optional<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr); EXPECT_TRUE(LocalVar); @@ -383,9 +483,9 @@ TEST_F(FileCheckTest, FileCheckContext) { // variable clearing due to --enable-var-scope happens after numeric // expressions are linked to the numeric variables they use. EXPECT_FALSE(NumExpr->eval()); - P = FileCheckPattern(Check::CheckPlain, &Cxt); - NumExpr = - P.parseNumericSubstitution(LocalNumVarRef, false /*IsPseudo*/, "", SM); + P = FileCheckPattern(Check::CheckPlain, &Cxt, 2); + NumExpr = P.parseNumericSubstitutionBlock(LocalNumVarRef, + DefinedNumericVariable, SM); EXPECT_FALSE(NumExpr); EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); EXPECT_FALSE(EmptyVar); @@ -400,9 +500,9 @@ TEST_F(FileCheckTest, FileCheckContext) { llvm::Optional<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr); EXPECT_TRUE(GlobalVar); EXPECT_EQ(*GlobalVar, "BAR"); - P = FileCheckPattern(Check::CheckPlain, &Cxt); - NumExpr = - P.parseNumericSubstitution(GlobalNumVarRef, false /*IsPseudo*/, "", SM); + P = FileCheckPattern(Check::CheckPlain, &Cxt, 3); + NumExpr = P.parseNumericSubstitutionBlock(GlobalNumVarRef, + DefinedNumericVariable, SM); EXPECT_TRUE(NumExpr); NumExprVal = NumExpr->eval(); EXPECT_TRUE(NumExprVal); @@ -412,9 +512,9 @@ TEST_F(FileCheckTest, FileCheckContext) { Cxt.clearLocalVars(); GlobalVar = Cxt.getPatternVarValue(GlobalVarStr); EXPECT_TRUE(GlobalVar); - P = FileCheckPattern(Check::CheckPlain, &Cxt); - NumExpr = - P.parseNumericSubstitution(GlobalNumVarRef, false /*IsPseudo*/, "", SM); + P = FileCheckPattern(Check::CheckPlain, &Cxt, 4); + NumExpr = P.parseNumericSubstitutionBlock(GlobalNumVarRef, + DefinedNumericVariable, SM); EXPECT_TRUE(NumExpr); NumExprVal = NumExpr->eval(); EXPECT_TRUE(NumExprVal); |