diff options
| author | Thomas Preud'homme <thomasp@graphcore.ai> | 2019-05-14 11:58:30 +0000 |
|---|---|---|
| committer | Thomas Preud'homme <thomasp@graphcore.ai> | 2019-05-14 11:58:30 +0000 |
| commit | 7b4ecdd3c2c64b0656f4a45a74fd2decf7606d0c (patch) | |
| tree | e1809bf80568482321f3436be2c1174c2bc6bd1d /llvm/unittests/Support | |
| parent | 2747ee2c83e4ba0c159f98498bdf98b3773ffa53 (diff) | |
| download | bcm5719-llvm-7b4ecdd3c2c64b0656f4a45a74fd2decf7606d0c.tar.gz bcm5719-llvm-7b4ecdd3c2c64b0656f4a45a74fd2decf7606d0c.zip | |
Reinstate "FileCheck [5/12]: Introduce regular numeric variables"
This reinstates r360578 (git e47362c1ec1ea31b626336cc05822035601c3e57),
reverted in r360653 (git 004393681c25e34e921adccc69ae6378090dee54),
with a fix for the list added in FileCheck.rst to build without error.
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/D60385
llvm-svn: 360665
Diffstat (limited to 'llvm/unittests/Support')
| -rw-r--r-- | llvm/unittests/Support/FileCheckTest.cpp | 205 |
1 files changed, 186 insertions, 19 deletions
diff --git a/llvm/unittests/Support/FileCheckTest.cpp b/llvm/unittests/Support/FileCheckTest.cpp index 2e9caa2935f..80120baa837 100644 --- a/llvm/unittests/Support/FileCheckTest.cpp +++ b/llvm/unittests/Support/FileCheckTest.cpp @@ -14,6 +14,57 @@ namespace { class FileCheckTest : public ::testing::Test {}; +TEST_F(FileCheckTest, NumericVariable) { + FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42); + 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_TRUE(Value); + EXPECT_EQ(42U, *Value); + EXPECT_TRUE(FooVar.setValue(43)); + Value = FooVar.getValue(); + EXPECT_TRUE(Value); + EXPECT_EQ(42U, *Value); + + // Clearing variable: getValue fails, clearValue again fails. + EXPECT_FALSE(FooVar.clearValue()); + 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; } + +TEST_F(FileCheckTest, NumExpr) { + FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42); + FileCheckNumExpr NumExpr = FileCheckNumExpr(doAdd, &FooVar, 18); + + // Defined variable: eval returns right value, no undefined variable + // returned. + llvm::Optional<uint64_t> Value = NumExpr.eval(); + EXPECT_TRUE(Value); + EXPECT_EQ(60U, *Value); + StringRef UndefVar = NumExpr.getUndefVarName(); + EXPECT_EQ("", UndefVar); + + // Undefined variable: eval fails, undefined variable returned. We call + // getUndefVarName first to check that it can be called without calling + // eval() first. + FooVar.clearValue(); + UndefVar = NumExpr.getUndefVarName(); + EXPECT_EQ("FOO", UndefVar); + Value = NumExpr.eval(); + EXPECT_FALSE(Value); +} + TEST_F(FileCheckTest, ValidVarNameStart) { EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a')); EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G')); @@ -90,22 +141,38 @@ TEST_F(FileCheckTest, ParseVar) { EXPECT_EQ(TrailIdx, VarName.size() - 1); } +static StringRef bufferize(SourceMgr &SM, StringRef Str) { + std::unique_ptr<MemoryBuffer> Buffer = + MemoryBuffer::getMemBufferCopy(Str, "TestBuffer"); + StringRef StrBufferRef = Buffer->getBuffer(); + SM.AddNewSourceBuffer(std::move(Buffer), SMLoc()); + return StrBufferRef; +} + class ExprTester { private: SourceMgr SM; + FileCheckRequest Req; FileCheckPatternContext Context; FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context); public: + ExprTester() { + std::vector<std::string> GlobalDefines; + GlobalDefines.emplace_back(std::string("#FOO=42")); + Context.defineCmdlineVariables(GlobalDefines, SM); + // Call ParsePattern to have @LINE defined. + P.ParsePattern("N/A", "CHECK", SM, 1, Req); + } + bool parseExpect(std::string &VarName, std::string &Trailer) { + bool IsPseudo = VarName[0] == '@'; std::string NameTrailer = VarName + Trailer; - std::unique_ptr<MemoryBuffer> Buffer = - MemoryBuffer::getMemBufferCopy(NameTrailer, "TestBuffer"); - StringRef NameTrailerRef = Buffer->getBuffer(); - SM.AddNewSourceBuffer(std::move(Buffer), SMLoc()); + StringRef NameTrailerRef = bufferize(SM, NameTrailer); StringRef VarNameRef = NameTrailerRef.substr(0, VarName.size()); StringRef TrailerRef = NameTrailerRef.substr(VarName.size()); - return P.parseNumericExpression(VarNameRef, TrailerRef, SM) == nullptr; + return P.parseNumericExpression(VarNameRef, IsPseudo, TrailerRef, SM) == + nullptr; } }; @@ -121,6 +188,14 @@ TEST_F(FileCheckTest, ParseExpr) { Trailer = ""; EXPECT_FALSE(Tester.parseExpect(VarName, Trailer)); + // Defined variable. + VarName = "FOO"; + EXPECT_FALSE(Tester.parseExpect(VarName, Trailer)); + + // Undefined variable. + VarName = "UNDEF"; + EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); + // Wrong Pseudovar. VarName = "@FOO"; EXPECT_TRUE(Tester.parseExpect(VarName, Trailer)); @@ -153,19 +228,38 @@ TEST_F(FileCheckTest, Substitution) { GlobalDefines.emplace_back(std::string("FOO=BAR")); Context.defineCmdlineVariables(GlobalDefines, SM); - FileCheckPatternSubstitution Substitution = + // Substitution of undefined pattern variable fails. + FileCheckPatternSubstitution PatternSubstitution = FileCheckPatternSubstitution(&Context, "VAR404", 42); - EXPECT_FALSE(Substitution.getResult()); - - FileCheckNumExpr NumExpr = FileCheckNumExpr(42); - Substitution = FileCheckPatternSubstitution(&Context, "@LINE", &NumExpr, 12); - llvm::Optional<std::string> Value = Substitution.getResult(); + EXPECT_FALSE(PatternSubstitution.getResult()); + + // Substitutions of defined pseudo and non-pseudo numeric variables return + // the right value. + FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42); + FileCheckNumericVariable NVar = FileCheckNumericVariable("@N", 10); + FileCheckNumExpr NumExprLine = FileCheckNumExpr(doAdd, &LineVar, 0); + FileCheckNumExpr NumExprN = FileCheckNumExpr(doAdd, &NVar, 3); + FileCheckPatternSubstitution SubstitutionLine = + FileCheckPatternSubstitution(&Context, "@LINE", &NumExprLine, 12); + FileCheckPatternSubstitution SubstitutionN = + FileCheckPatternSubstitution(&Context, "N", &NumExprN, 30); + llvm::Optional<std::string> Value = SubstitutionLine.getResult(); EXPECT_TRUE(Value); EXPECT_EQ("42", *Value); + Value = SubstitutionN.getResult(); + EXPECT_TRUE(Value); + EXPECT_EQ("13", *Value); + + // Substitution of undefined numeric variable fails. + LineVar.clearValue(); + EXPECT_FALSE(SubstitutionLine.getResult()); + NVar.clearValue(); + EXPECT_FALSE(SubstitutionN.getResult()); + // Substitution of defined pattern variable returns the right value. FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context); - Substitution = FileCheckPatternSubstitution(&Context, "FOO", 42); - Value = Substitution.getResult(); + PatternSubstitution = FileCheckPatternSubstitution(&Context, "FOO", 42); + Value = PatternSubstitution.getResult(); EXPECT_TRUE(Value); EXPECT_EQ("BAR", *Value); } @@ -177,19 +271,32 @@ TEST_F(FileCheckTest, UndefVars) { GlobalDefines.emplace_back(std::string("FOO=BAR")); Context.defineCmdlineVariables(GlobalDefines, SM); + // getUndefVarName() on a pattern variable substitution with an undefined + // variable returns that variable. FileCheckPatternSubstitution Substitution = FileCheckPatternSubstitution(&Context, "VAR404", 42); StringRef UndefVar = Substitution.getUndefVarName(); EXPECT_EQ("VAR404", UndefVar); - FileCheckNumExpr NumExpr = FileCheckNumExpr(42); - Substitution = FileCheckPatternSubstitution(&Context, "@LINE", &NumExpr, 12); + // getUndefVarName() on a pattern variable substitution with a defined + // variable returns an empty string. + Substitution = FileCheckPatternSubstitution(&Context, "FOO", 42); UndefVar = Substitution.getUndefVarName(); EXPECT_EQ("", UndefVar); - Substitution = FileCheckPatternSubstitution(&Context, "FOO", 42); + // getUndefVarName() on a numeric expression substitution with a defined + // variable returns an empty string. + FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42); + FileCheckNumExpr NumExpr = FileCheckNumExpr(doAdd, &LineVar, 0); + Substitution = FileCheckPatternSubstitution(&Context, "@LINE", &NumExpr, 12); UndefVar = Substitution.getUndefVarName(); EXPECT_EQ("", UndefVar); + + // getUndefVarName() on a numeric expression substitution with an undefined + // variable returns that variable. + LineVar.clearValue(); + UndefVar = Substitution.getUndefVarName(); + EXPECT_EQ("@LINE", UndefVar); } TEST_F(FileCheckTest, FileCheckContext) { @@ -197,36 +304,71 @@ TEST_F(FileCheckTest, FileCheckContext) { std::vector<std::string> GlobalDefines; SourceMgr SM; - // Missing equal sign + // Missing equal sign. GlobalDefines.emplace_back(std::string("LocalVar")); EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); + GlobalDefines.clear(); + GlobalDefines.emplace_back(std::string("#LocalNumVar")); + EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); - // Empty variable + // Empty variable name. GlobalDefines.clear(); GlobalDefines.emplace_back(std::string("=18")); EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); + GlobalDefines.clear(); + GlobalDefines.emplace_back(std::string("#=18")); + EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); - // Invalid variable + // Invalid variable name. GlobalDefines.clear(); GlobalDefines.emplace_back(std::string("18LocalVar=18")); EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); + GlobalDefines.clear(); + GlobalDefines.emplace_back(std::string("#18LocalNumVar=18")); + EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); + + // Name conflict between pattern and numeric variable. + GlobalDefines.clear(); + GlobalDefines.emplace_back(std::string("LocalVar=18")); + GlobalDefines.emplace_back(std::string("#LocalVar=36")); + EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); + Cxt = FileCheckPatternContext(); + GlobalDefines.clear(); + GlobalDefines.emplace_back(std::string("#LocalNumVar=18")); + GlobalDefines.emplace_back(std::string("LocalNumVar=36")); + EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); + Cxt = FileCheckPatternContext(); + + // Invalid numeric value for numeric variable. + GlobalDefines.clear(); + GlobalDefines.emplace_back(std::string("#LocalNumVar=x")); + EXPECT_TRUE(Cxt.defineCmdlineVariables(GlobalDefines, SM)); // Define local variables from command-line. GlobalDefines.clear(); GlobalDefines.emplace_back(std::string("LocalVar=FOO")); GlobalDefines.emplace_back(std::string("EmptyVar=")); + GlobalDefines.emplace_back(std::string("#LocalNumVar=18")); bool GotError = Cxt.defineCmdlineVariables(GlobalDefines, SM); EXPECT_FALSE(GotError); // Check defined variables are present and undefined is absent. StringRef LocalVarStr = "LocalVar"; + StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar"); StringRef EmptyVarStr = "EmptyVar"; StringRef UnknownVarStr = "UnknownVar"; llvm::Optional<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr); + FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt); + FileCheckNumExpr *NumExpr = + P.parseNumericExpression(LocalNumVarRef, false /*IsPseudo*/, "", SM); llvm::Optional<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); llvm::Optional<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr); EXPECT_TRUE(LocalVar); EXPECT_EQ(*LocalVar, "FOO"); + EXPECT_TRUE(NumExpr); + llvm::Optional<uint64_t> NumExprVal = NumExpr->eval(); + EXPECT_TRUE(NumExprVal); + EXPECT_EQ(*NumExprVal, 18U); EXPECT_TRUE(EmptyVar); EXPECT_EQ(*EmptyVar, ""); EXPECT_FALSE(UnknownVar); @@ -235,21 +377,46 @@ TEST_F(FileCheckTest, FileCheckContext) { Cxt.clearLocalVars(); LocalVar = Cxt.getPatternVarValue(LocalVarStr); EXPECT_FALSE(LocalVar); + // Check a numeric expression's evaluation fails if called after clearing of + // local variables, if it was created before. This is important because local + // 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.parseNumericExpression(LocalNumVarRef, false /*IsPseudo*/, "", SM); + EXPECT_FALSE(NumExpr); EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); EXPECT_FALSE(EmptyVar); // Redefine global variables and check variables are defined again. GlobalDefines.emplace_back(std::string("$GlobalVar=BAR")); + GlobalDefines.emplace_back(std::string("#$GlobalNumVar=36")); GotError = Cxt.defineCmdlineVariables(GlobalDefines, SM); EXPECT_FALSE(GotError); StringRef GlobalVarStr = "$GlobalVar"; + StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar"); llvm::Optional<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr); EXPECT_TRUE(GlobalVar); EXPECT_EQ(*GlobalVar, "BAR"); + P = FileCheckPattern(Check::CheckPlain, &Cxt); + NumExpr = + P.parseNumericExpression(GlobalNumVarRef, false /*IsPseudo*/, "", SM); + EXPECT_TRUE(NumExpr); + NumExprVal = NumExpr->eval(); + EXPECT_TRUE(NumExprVal); + EXPECT_EQ(*NumExprVal, 36U); // Clear local variables and check global variables remain defined. Cxt.clearLocalVars(); GlobalVar = Cxt.getPatternVarValue(GlobalVarStr); EXPECT_TRUE(GlobalVar); + P = FileCheckPattern(Check::CheckPlain, &Cxt); + NumExpr = + P.parseNumericExpression(GlobalNumVarRef, false /*IsPseudo*/, "", SM); + EXPECT_TRUE(NumExpr); + NumExprVal = NumExpr->eval(); + EXPECT_TRUE(NumExprVal); + EXPECT_EQ(*NumExprVal, 36U); } } // namespace |

