Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 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 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "llvm/Support/FileCheck.h" |
| 10 | #include "gtest/gtest.h" |
| 11 | |
| 12 | using namespace llvm; |
| 13 | namespace { |
| 14 | |
| 15 | class FileCheckTest : public ::testing::Test {}; |
| 16 | |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 17 | TEST_F(FileCheckTest, NumericVariable) { |
Thomas Preud'homme | 2bf04f2 | 2019-07-10 12:49:28 +0000 | [diff] [blame] | 18 | // Undefined variable: getValue fails, setValue does not trigger assert. |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 19 | FileCheckNumericVariable FooVar = FileCheckNumericVariable(1, "FOO"); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 20 | EXPECT_EQ("FOO", FooVar.getName()); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 21 | llvm::Optional<uint64_t> Value = FooVar.getValue(); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 22 | EXPECT_FALSE(Value); |
Thomas Preud'homme | 2bf04f2 | 2019-07-10 12:49:28 +0000 | [diff] [blame] | 23 | FooVar.clearValue(); |
| 24 | FooVar.setValue(42); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 25 | |
Thomas Preud'homme | 2bf04f2 | 2019-07-10 12:49:28 +0000 | [diff] [blame] | 26 | // Defined variable: getValue returns value set. |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 27 | Value = FooVar.getValue(); |
| 28 | EXPECT_TRUE(Value); |
| 29 | EXPECT_EQ(42U, *Value); |
| 30 | |
Thomas Preud'homme | 2bf04f2 | 2019-07-10 12:49:28 +0000 | [diff] [blame] | 31 | // Clearing variable: getValue fails. |
| 32 | FooVar.clearValue(); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 33 | Value = FooVar.getValue(); |
| 34 | EXPECT_FALSE(Value); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; } |
| 38 | |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 39 | static void expectUndefError(const Twine &ExpectedStr, Error Err) { |
| 40 | handleAllErrors(std::move(Err), [&](const FileCheckUndefVarError &E) { |
| 41 | EXPECT_EQ(ExpectedStr.str(), E.getVarName()); |
| 42 | }); |
| 43 | } |
| 44 | |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 45 | TEST_F(FileCheckTest, Expression) { |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 46 | FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 47 | FileCheckExpression Expression = FileCheckExpression(doAdd, &FooVar, 18); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 48 | |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 49 | // Defined variable: eval returns right value. |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 50 | Expected<uint64_t> Value = Expression.eval(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 51 | EXPECT_TRUE(bool(Value)); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 52 | EXPECT_EQ(60U, *Value); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 53 | |
| 54 | // Undefined variable: eval fails, undefined variable returned. We call |
| 55 | // getUndefVarName first to check that it can be called without calling |
| 56 | // eval() first. |
| 57 | FooVar.clearValue(); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 58 | Error EvalError = Expression.eval().takeError(); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 59 | EXPECT_TRUE(errorToBool(std::move(EvalError))); |
| 60 | expectUndefError("FOO", std::move(EvalError)); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 61 | } |
| 62 | |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 63 | TEST_F(FileCheckTest, ValidVarNameStart) { |
| 64 | EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a')); |
| 65 | EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G')); |
| 66 | EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('_')); |
| 67 | EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('2')); |
| 68 | EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('$')); |
| 69 | EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('@')); |
| 70 | EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('+')); |
| 71 | EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('-')); |
| 72 | EXPECT_FALSE(FileCheckPattern::isValidVarNameStart(':')); |
| 73 | } |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 74 | |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 75 | static StringRef bufferize(SourceMgr &SM, StringRef Str) { |
| 76 | std::unique_ptr<MemoryBuffer> Buffer = |
| 77 | MemoryBuffer::getMemBufferCopy(Str, "TestBuffer"); |
| 78 | StringRef StrBufferRef = Buffer->getBuffer(); |
| 79 | SM.AddNewSourceBuffer(std::move(Buffer), SMLoc()); |
| 80 | return StrBufferRef; |
| 81 | } |
| 82 | |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 83 | TEST_F(FileCheckTest, ParseVar) { |
| 84 | SourceMgr SM; |
| 85 | StringRef OrigVarName = bufferize(SM, "GoodVar42"); |
| 86 | StringRef VarName = OrigVarName; |
| 87 | bool IsPseudo = true; |
| 88 | Expected<StringRef> ParsedName = |
| 89 | FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 90 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 91 | EXPECT_EQ(*ParsedName, OrigVarName); |
| 92 | EXPECT_TRUE(VarName.empty()); |
| 93 | EXPECT_FALSE(IsPseudo); |
| 94 | |
| 95 | VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar"); |
| 96 | IsPseudo = true; |
| 97 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 98 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 99 | EXPECT_EQ(*ParsedName, OrigVarName); |
| 100 | EXPECT_TRUE(VarName.empty()); |
| 101 | EXPECT_FALSE(IsPseudo); |
| 102 | |
| 103 | VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar"); |
| 104 | IsPseudo = true; |
| 105 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 106 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 107 | EXPECT_EQ(*ParsedName, OrigVarName); |
| 108 | EXPECT_TRUE(VarName.empty()); |
| 109 | EXPECT_TRUE(IsPseudo); |
| 110 | |
| 111 | VarName = bufferize(SM, "42BadVar"); |
| 112 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
| 113 | EXPECT_TRUE(errorToBool(ParsedName.takeError())); |
| 114 | |
| 115 | VarName = bufferize(SM, "$@"); |
| 116 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
| 117 | EXPECT_TRUE(errorToBool(ParsedName.takeError())); |
| 118 | |
| 119 | VarName = OrigVarName = bufferize(SM, "B@dVar"); |
| 120 | IsPseudo = true; |
| 121 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 122 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 123 | EXPECT_EQ(VarName, OrigVarName.substr(1)); |
| 124 | EXPECT_EQ(*ParsedName, "B"); |
| 125 | EXPECT_FALSE(IsPseudo); |
| 126 | |
| 127 | VarName = OrigVarName = bufferize(SM, "B$dVar"); |
| 128 | IsPseudo = true; |
| 129 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 130 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 131 | EXPECT_EQ(VarName, OrigVarName.substr(1)); |
| 132 | EXPECT_EQ(*ParsedName, "B"); |
| 133 | EXPECT_FALSE(IsPseudo); |
| 134 | |
| 135 | VarName = bufferize(SM, "BadVar+"); |
| 136 | IsPseudo = true; |
| 137 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 138 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 139 | EXPECT_EQ(VarName, "+"); |
| 140 | EXPECT_EQ(*ParsedName, "BadVar"); |
| 141 | EXPECT_FALSE(IsPseudo); |
| 142 | |
| 143 | VarName = bufferize(SM, "BadVar-"); |
| 144 | IsPseudo = true; |
| 145 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 146 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 147 | EXPECT_EQ(VarName, "-"); |
| 148 | EXPECT_EQ(*ParsedName, "BadVar"); |
| 149 | EXPECT_FALSE(IsPseudo); |
| 150 | |
| 151 | VarName = bufferize(SM, "BadVar:"); |
| 152 | IsPseudo = true; |
| 153 | ParsedName = FileCheckPattern::parseVariable(VarName, IsPseudo, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 154 | EXPECT_TRUE(bool(ParsedName)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 155 | EXPECT_EQ(VarName, ":"); |
| 156 | EXPECT_EQ(*ParsedName, "BadVar"); |
| 157 | EXPECT_FALSE(IsPseudo); |
| 158 | } |
| 159 | |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 160 | class PatternTester { |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 161 | private: |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 162 | size_t LineNumber = 1; |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 163 | SourceMgr SM; |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 164 | FileCheckRequest Req; |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 165 | FileCheckPatternContext Context; |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 166 | FileCheckPattern P = |
| 167 | FileCheckPattern(Check::CheckPlain, &Context, LineNumber++); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 168 | |
| 169 | public: |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 170 | PatternTester() { |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 171 | std::vector<std::string> GlobalDefines; |
| 172 | GlobalDefines.emplace_back(std::string("#FOO=42")); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 173 | GlobalDefines.emplace_back(std::string("BAR=BAZ")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 174 | EXPECT_FALSE( |
| 175 | errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 56f6308 | 2019-07-05 16:25:46 +0000 | [diff] [blame] | 176 | Context.createLineVariable(); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 177 | // Call parsePattern to have @LINE defined. |
| 178 | P.parsePattern("N/A", "CHECK", SM, Req); |
| 179 | // parsePattern does not expect to be called twice for the same line and |
| 180 | // will set FixedStr and RegExStr incorrectly if it is. Therefore prepare |
| 181 | // a pattern for a different line. |
| 182 | initNextPattern(); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 183 | } |
| 184 | |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 185 | void initNextPattern() { |
| 186 | P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++); |
| 187 | } |
| 188 | |
| 189 | bool parseNumVarDefExpect(StringRef Expr) { |
| 190 | StringRef ExprBufferRef = bufferize(SM, Expr); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 191 | return errorToBool(FileCheckPattern::parseNumericVariableDefinition( |
Thomas Preud'homme | 56f6308 | 2019-07-05 16:25:46 +0000 | [diff] [blame] | 192 | ExprBufferRef, &Context, LineNumber, SM) |
| 193 | .takeError()); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | bool parseSubstExpect(StringRef Expr) { |
| 197 | StringRef ExprBufferRef = bufferize(SM, Expr); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 198 | Optional<FileCheckNumericVariable *> DefinedNumericVariable; |
| 199 | return errorToBool(P.parseNumericSubstitutionBlock( |
| 200 | ExprBufferRef, DefinedNumericVariable, SM) |
| 201 | .takeError()); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 202 | } |
| 203 | |
| 204 | bool parsePatternExpect(StringRef Pattern) { |
| 205 | StringRef PatBufferRef = bufferize(SM, Pattern); |
| 206 | return P.parsePattern(PatBufferRef, "CHECK", SM, Req); |
| 207 | } |
| 208 | |
| 209 | bool matchExpect(StringRef Buffer) { |
| 210 | StringRef BufferRef = bufferize(SM, Buffer); |
| 211 | size_t MatchLen; |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 212 | return errorToBool(P.match(BufferRef, MatchLen, SM).takeError()); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 213 | } |
| 214 | }; |
| 215 | |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 216 | TEST_F(FileCheckTest, ParseNumericVariableDefinition) { |
| 217 | PatternTester Tester; |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 218 | |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 219 | // Invalid definition of pseudo. |
| 220 | EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE")); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 221 | |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 222 | // Conflict with pattern variable. |
| 223 | EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR")); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 224 | |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 225 | // Defined variable. |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 226 | EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO")); |
| 227 | } |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 228 | |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 229 | TEST_F(FileCheckTest, ParseExpr) { |
| 230 | PatternTester Tester; |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 231 | |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 232 | // Variable definition. |
| 233 | |
| 234 | // Definition of invalid variable. |
| 235 | EXPECT_TRUE(Tester.parseSubstExpect("10VAR:")); |
| 236 | EXPECT_TRUE(Tester.parseSubstExpect("@FOO:")); |
| 237 | EXPECT_TRUE(Tester.parseSubstExpect("@LINE:")); |
| 238 | |
| 239 | // Garbage after name of variable being defined. |
| 240 | EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:")); |
| 241 | |
| 242 | // Variable defined to numeric expression. |
| 243 | EXPECT_TRUE(Tester.parseSubstExpect("VAR1: FOO")); |
| 244 | |
| 245 | // Acceptable variable definition. |
| 246 | EXPECT_FALSE(Tester.parseSubstExpect("VAR1:")); |
| 247 | EXPECT_FALSE(Tester.parseSubstExpect(" VAR2:")); |
| 248 | EXPECT_FALSE(Tester.parseSubstExpect("VAR3 :")); |
| 249 | EXPECT_FALSE(Tester.parseSubstExpect("VAR3: ")); |
| 250 | |
| 251 | // Numeric expression. |
| 252 | |
| 253 | // Unacceptable variable. |
| 254 | EXPECT_TRUE(Tester.parseSubstExpect("10VAR")); |
| 255 | EXPECT_TRUE(Tester.parseSubstExpect("@FOO")); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 256 | |
| 257 | // Only valid variable. |
| 258 | EXPECT_FALSE(Tester.parseSubstExpect("@LINE")); |
| 259 | EXPECT_FALSE(Tester.parseSubstExpect("FOO")); |
Thomas Preud'homme | fe7ac17 | 2019-07-05 16:25:33 +0000 | [diff] [blame] | 260 | EXPECT_FALSE(Tester.parseSubstExpect("UNDEF")); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 261 | |
| 262 | // Use variable defined on same line. |
| 263 | EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]")); |
| 264 | EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR")); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 265 | |
| 266 | // Unsupported operator. |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 267 | EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2")); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 268 | |
| 269 | // Missing offset operand. |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 270 | EXPECT_TRUE(Tester.parseSubstExpect("@LINE+")); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 271 | |
| 272 | // Cannot parse offset operand. |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 273 | EXPECT_TRUE(Tester.parseSubstExpect("@LINE+x")); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 274 | |
| 275 | // Unexpected string at end of numeric expression. |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 276 | EXPECT_TRUE(Tester.parseSubstExpect("@LINE+5x")); |
| 277 | |
| 278 | // Valid expression. |
| 279 | EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5")); |
| 280 | EXPECT_FALSE(Tester.parseSubstExpect("FOO+4")); |
| 281 | } |
| 282 | |
| 283 | TEST_F(FileCheckTest, ParsePattern) { |
| 284 | PatternTester Tester; |
| 285 | |
| 286 | // Space in pattern variable expression. |
| 287 | EXPECT_TRUE(Tester.parsePatternExpect("[[ BAR]]")); |
| 288 | |
| 289 | // Invalid variable name. |
| 290 | EXPECT_TRUE(Tester.parsePatternExpect("[[42INVALID]]")); |
| 291 | |
| 292 | // Invalid pattern variable definition. |
| 293 | EXPECT_TRUE(Tester.parsePatternExpect("[[@PAT:]]")); |
| 294 | EXPECT_TRUE(Tester.parsePatternExpect("[[PAT+2:]]")); |
| 295 | |
| 296 | // Collision with numeric variable. |
| 297 | EXPECT_TRUE(Tester.parsePatternExpect("[[FOO:]]")); |
| 298 | |
| 299 | // Valid use of pattern variable. |
| 300 | EXPECT_FALSE(Tester.parsePatternExpect("[[BAR]]")); |
| 301 | |
| 302 | // Valid pattern variable definition. |
| 303 | EXPECT_FALSE(Tester.parsePatternExpect("[[PAT:[0-9]+]]")); |
| 304 | |
| 305 | // Invalid numeric expressions. |
| 306 | EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]")); |
| 307 | EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]")); |
| 308 | EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]")); |
| 309 | EXPECT_TRUE(Tester.parsePatternExpect("[[#2+@LINE]]")); |
| 310 | EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]")); |
| 311 | |
| 312 | // Valid numeric expressions and numeric variable definition. |
| 313 | EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]")); |
| 314 | EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE+2]]")); |
| 315 | EXPECT_FALSE(Tester.parsePatternExpect("[[#NUMVAR:]]")); |
| 316 | } |
| 317 | |
| 318 | TEST_F(FileCheckTest, Match) { |
| 319 | PatternTester Tester; |
| 320 | |
| 321 | // Check matching a definition only matches a number. |
| 322 | Tester.parsePatternExpect("[[#NUMVAR:]]"); |
| 323 | EXPECT_TRUE(Tester.matchExpect("FAIL")); |
| 324 | EXPECT_FALSE(Tester.matchExpect("18")); |
| 325 | |
| 326 | // Check matching the variable defined matches the correct number only |
| 327 | Tester.initNextPattern(); |
| 328 | Tester.parsePatternExpect("[[#NUMVAR]] [[#NUMVAR+2]]"); |
| 329 | EXPECT_TRUE(Tester.matchExpect("19 21")); |
| 330 | EXPECT_TRUE(Tester.matchExpect("18 21")); |
| 331 | EXPECT_FALSE(Tester.matchExpect("18 20")); |
Thomas Preud'homme | f6ea43b | 2019-07-10 12:49:17 +0000 | [diff] [blame] | 332 | |
| 333 | // Check matching a numeric expression using @LINE after match failure uses |
| 334 | // the correct value for @LINE. |
| 335 | Tester.initNextPattern(); |
| 336 | EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]")); |
| 337 | // Ok, @LINE is 4 now. |
| 338 | EXPECT_FALSE(Tester.matchExpect("4")); |
| 339 | Tester.initNextPattern(); |
| 340 | // @LINE is now 5, match with substitution failure. |
| 341 | EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]")); |
| 342 | EXPECT_TRUE(Tester.matchExpect("FOO")); |
| 343 | Tester.initNextPattern(); |
| 344 | // Check that @LINE is 6 as expected. |
| 345 | EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]")); |
| 346 | EXPECT_FALSE(Tester.matchExpect("6")); |
Thomas Preud'homme | 15cb1f1 | 2019-04-29 17:46:26 +0000 | [diff] [blame] | 347 | } |
| 348 | |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 349 | TEST_F(FileCheckTest, Substitution) { |
| 350 | SourceMgr SM; |
| 351 | FileCheckPatternContext Context; |
| 352 | std::vector<std::string> GlobalDefines; |
| 353 | GlobalDefines.emplace_back(std::string("FOO=BAR")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 354 | EXPECT_FALSE(errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 355 | |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 356 | // Substitution of an undefined string variable fails and error holds that |
| 357 | // variable's name. |
Thomas Preud'homme | f3b9bb3 | 2019-05-23 00:10:29 +0000 | [diff] [blame] | 358 | FileCheckStringSubstitution StringSubstitution = |
| 359 | FileCheckStringSubstitution(&Context, "VAR404", 42); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 360 | Expected<std::string> SubstValue = StringSubstitution.getResult(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 361 | EXPECT_FALSE(bool(SubstValue)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 362 | expectUndefError("VAR404", SubstValue.takeError()); |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 363 | |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 364 | // Substitutions of defined pseudo and non-pseudo numeric variables return |
| 365 | // the right value. |
| 366 | FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 367 | FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 10); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 368 | FileCheckExpression LineExpression = FileCheckExpression(doAdd, &LineVar, 0); |
| 369 | FileCheckExpression NExpression = FileCheckExpression(doAdd, &NVar, 3); |
Thomas Preud'homme | f3b9bb3 | 2019-05-23 00:10:29 +0000 | [diff] [blame] | 370 | FileCheckNumericSubstitution SubstitutionLine = |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 371 | FileCheckNumericSubstitution(&Context, "@LINE", &LineExpression, 12); |
Thomas Preud'homme | f3b9bb3 | 2019-05-23 00:10:29 +0000 | [diff] [blame] | 372 | FileCheckNumericSubstitution SubstitutionN = |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 373 | FileCheckNumericSubstitution(&Context, "N", &NExpression, 30); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 374 | Expected<std::string> Value = SubstitutionLine.getResult(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 375 | EXPECT_TRUE(bool(Value)); |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 376 | EXPECT_EQ("42", *Value); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 377 | Value = SubstitutionN.getResult(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 378 | EXPECT_TRUE(bool(Value)); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 379 | EXPECT_EQ("13", *Value); |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 380 | |
Thomas Preud'homme | 1a944d2 | 2019-05-23 00:10:14 +0000 | [diff] [blame] | 381 | // Substitution of an undefined numeric variable fails. |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 382 | LineVar.clearValue(); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 383 | SubstValue = SubstitutionLine.getResult().takeError(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 384 | EXPECT_FALSE(bool(SubstValue)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 385 | expectUndefError("@LINE", SubstValue.takeError()); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 386 | NVar.clearValue(); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 387 | SubstValue = SubstitutionN.getResult().takeError(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 388 | EXPECT_FALSE(bool(SubstValue)); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 389 | expectUndefError("N", SubstValue.takeError()); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 390 | |
Thomas Preud'homme | 1a944d2 | 2019-05-23 00:10:14 +0000 | [diff] [blame] | 391 | // Substitution of a defined string variable returns the right value. |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 392 | FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context, 1); |
Thomas Preud'homme | f3b9bb3 | 2019-05-23 00:10:29 +0000 | [diff] [blame] | 393 | StringSubstitution = FileCheckStringSubstitution(&Context, "FOO", 42); |
| 394 | Value = StringSubstitution.getResult(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 395 | EXPECT_TRUE(bool(Value)); |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 396 | EXPECT_EQ("BAR", *Value); |
| 397 | } |
| 398 | |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 399 | TEST_F(FileCheckTest, FileCheckContext) { |
| 400 | FileCheckPatternContext Cxt = FileCheckPatternContext(); |
| 401 | std::vector<std::string> GlobalDefines; |
| 402 | SourceMgr SM; |
| 403 | |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 404 | // Missing equal sign. |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 405 | GlobalDefines.emplace_back(std::string("LocalVar")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 406 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 407 | GlobalDefines.clear(); |
| 408 | GlobalDefines.emplace_back(std::string("#LocalNumVar")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 409 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 410 | |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 411 | // Empty variable name. |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 412 | GlobalDefines.clear(); |
| 413 | GlobalDefines.emplace_back(std::string("=18")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 414 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 415 | GlobalDefines.clear(); |
| 416 | GlobalDefines.emplace_back(std::string("#=18")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 417 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 418 | |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 419 | // Invalid variable name. |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 420 | GlobalDefines.clear(); |
| 421 | GlobalDefines.emplace_back(std::string("18LocalVar=18")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 422 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 423 | GlobalDefines.clear(); |
| 424 | GlobalDefines.emplace_back(std::string("#18LocalNumVar=18")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 425 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 426 | |
| 427 | // Name conflict between pattern and numeric variable. |
| 428 | GlobalDefines.clear(); |
| 429 | GlobalDefines.emplace_back(std::string("LocalVar=18")); |
| 430 | GlobalDefines.emplace_back(std::string("#LocalVar=36")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 431 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 432 | Cxt = FileCheckPatternContext(); |
| 433 | GlobalDefines.clear(); |
| 434 | GlobalDefines.emplace_back(std::string("#LocalNumVar=18")); |
| 435 | GlobalDefines.emplace_back(std::string("LocalNumVar=36")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 436 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 437 | Cxt = FileCheckPatternContext(); |
| 438 | |
| 439 | // Invalid numeric value for numeric variable. |
| 440 | GlobalDefines.clear(); |
| 441 | GlobalDefines.emplace_back(std::string("#LocalNumVar=x")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 442 | EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 443 | |
| 444 | // Define local variables from command-line. |
| 445 | GlobalDefines.clear(); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 446 | GlobalDefines.emplace_back(std::string("LocalVar=FOO")); |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 447 | GlobalDefines.emplace_back(std::string("EmptyVar=")); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 448 | GlobalDefines.emplace_back(std::string("#LocalNumVar=18")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 449 | EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 450 | |
| 451 | // Check defined variables are present and undefined is absent. |
| 452 | StringRef LocalVarStr = "LocalVar"; |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 453 | StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar"); |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 454 | StringRef EmptyVarStr = "EmptyVar"; |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 455 | StringRef UnknownVarStr = "UnknownVar"; |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 456 | Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 457 | FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 458 | Optional<FileCheckNumericVariable *> DefinedNumericVariable; |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 459 | Expected<FileCheckExpression *> Expression = P.parseNumericSubstitutionBlock( |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 460 | LocalNumVarRef, DefinedNumericVariable, SM); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 461 | Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); |
| 462 | Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 463 | EXPECT_TRUE(bool(LocalVar)); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 464 | EXPECT_EQ(*LocalVar, "FOO"); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 465 | EXPECT_TRUE(bool(Expression)); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 466 | Expected<uint64_t> ExpressionVal = (*Expression)->eval(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 467 | EXPECT_TRUE(bool(ExpressionVal)); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 468 | EXPECT_EQ(*ExpressionVal, 18U); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 469 | EXPECT_TRUE(bool(EmptyVar)); |
Thomas Preud'homme | 5a33047 | 2019-04-29 13:32:36 +0000 | [diff] [blame] | 470 | EXPECT_EQ(*EmptyVar, ""); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 471 | EXPECT_TRUE(errorToBool(UnknownVar.takeError())); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 472 | |
| 473 | // Clear local variables and check they become absent. |
| 474 | Cxt.clearLocalVars(); |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 475 | LocalVar = Cxt.getPatternVarValue(LocalVarStr); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 476 | EXPECT_TRUE(errorToBool(LocalVar.takeError())); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 477 | // Check a numeric expression's evaluation fails if called after clearing of |
| 478 | // local variables, if it was created before. This is important because local |
| 479 | // variable clearing due to --enable-var-scope happens after numeric |
| 480 | // expressions are linked to the numeric variables they use. |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 481 | EXPECT_TRUE(errorToBool((*Expression)->eval().takeError())); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 482 | P = FileCheckPattern(Check::CheckPlain, &Cxt, 2); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 483 | Expression = P.parseNumericSubstitutionBlock(LocalNumVarRef, |
| 484 | DefinedNumericVariable, SM); |
Thomas Preud'homme | fe7ac17 | 2019-07-05 16:25:33 +0000 | [diff] [blame] | 485 | EXPECT_TRUE(bool(Expression)); |
| 486 | ExpressionVal = (*Expression)->eval(); |
| 487 | EXPECT_TRUE(errorToBool(ExpressionVal.takeError())); |
Thomas Preud'homme | 288ed91 | 2019-05-02 00:04:38 +0000 | [diff] [blame] | 488 | EmptyVar = Cxt.getPatternVarValue(EmptyVarStr); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 489 | EXPECT_TRUE(errorToBool(EmptyVar.takeError())); |
Thomas Preud'homme | fe7ac17 | 2019-07-05 16:25:33 +0000 | [diff] [blame] | 490 | // Clear again because parseNumericSubstitutionBlock would have created a |
| 491 | // dummy variable and stored it in GlobalNumericVariableTable. |
| 492 | Cxt.clearLocalVars(); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 493 | |
| 494 | // Redefine global variables and check variables are defined again. |
| 495 | GlobalDefines.emplace_back(std::string("$GlobalVar=BAR")); |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 496 | GlobalDefines.emplace_back(std::string("#$GlobalNumVar=36")); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 497 | EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM))); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 498 | StringRef GlobalVarStr = "$GlobalVar"; |
Thomas Preud'homme | 7b4ecdd | 2019-05-14 11:58:30 +0000 | [diff] [blame] | 499 | StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar"); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 500 | Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 501 | EXPECT_TRUE(bool(GlobalVar)); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 502 | EXPECT_EQ(*GlobalVar, "BAR"); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 503 | P = FileCheckPattern(Check::CheckPlain, &Cxt, 3); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 504 | Expression = P.parseNumericSubstitutionBlock(GlobalNumVarRef, |
| 505 | DefinedNumericVariable, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 506 | EXPECT_TRUE(bool(Expression)); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 507 | ExpressionVal = (*Expression)->eval(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 508 | EXPECT_TRUE(bool(ExpressionVal)); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 509 | EXPECT_EQ(*ExpressionVal, 36U); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 510 | |
| 511 | // Clear local variables and check global variables remain defined. |
| 512 | Cxt.clearLocalVars(); |
Thomas Preud'homme | baae41f | 2019-06-19 23:47:10 +0000 | [diff] [blame] | 513 | EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError())); |
Thomas Preud'homme | 71d3f22 | 2019-06-06 13:21:06 +0000 | [diff] [blame] | 514 | P = FileCheckPattern(Check::CheckPlain, &Cxt, 4); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 515 | Expression = P.parseNumericSubstitutionBlock(GlobalNumVarRef, |
| 516 | DefinedNumericVariable, SM); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 517 | EXPECT_TRUE(bool(Expression)); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 518 | ExpressionVal = (*Expression)->eval(); |
Thomas Preud'homme | f64b7f6 | 2019-07-10 15:31:19 +0000 | [diff] [blame^] | 519 | EXPECT_TRUE(bool(ExpressionVal)); |
Thomas Preud'homme | a2ef1ba | 2019-06-19 23:47:24 +0000 | [diff] [blame] | 520 | EXPECT_EQ(*ExpressionVal, 36U); |
Thomas Preud'homme | e038fa7 | 2019-04-15 10:10:11 +0000 | [diff] [blame] | 521 | } |
| 522 | } // namespace |