1 //===- FileCheck.cpp - Check that File's Contents match what is expected --===// 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 // FileCheck does a line-by line check of a file that validates whether it 10 // contains the expected content. This is useful for regression tests etc. 11 // 12 // This file implements most of the API that will be used by the FileCheck utility 13 // as well as various unittests. 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/FileCheck/FileCheck.h" 17 #include "FileCheckImpl.h" 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/ADT/StringSet.h" 20 #include "llvm/ADT/Twine.h" 21 #include "llvm/Support/CheckedArithmetic.h" 22 #include "llvm/Support/FormatVariadic.h" 23 #include <cstdint> 24 #include <list> 25 #include <optional> 26 #include <set> 27 #include <tuple> 28 #include <utility> 29 30 using namespace llvm; 31 32 StringRef ExpressionFormat::toString() const { 33 switch (Value) { 34 case Kind::NoFormat: 35 return StringRef("<none>"); 36 case Kind::Unsigned: 37 return StringRef("%u"); 38 case Kind::Signed: 39 return StringRef("%d"); 40 case Kind::HexUpper: 41 return StringRef("%X"); 42 case Kind::HexLower: 43 return StringRef("%x"); 44 } 45 llvm_unreachable("unknown expression format"); 46 } 47 48 Expected<std::string> ExpressionFormat::getWildcardRegex() const { 49 StringRef AlternateFormPrefix = AlternateForm ? StringRef("0x") : StringRef(); 50 51 auto CreatePrecisionRegex = [&](StringRef S) { 52 return (Twine(AlternateFormPrefix) + S + Twine('{') + Twine(Precision) + 53 "}") 54 .str(); 55 }; 56 57 switch (Value) { 58 case Kind::Unsigned: 59 if (Precision) 60 return CreatePrecisionRegex("([1-9][0-9]*)?[0-9]"); 61 return std::string("[0-9]+"); 62 case Kind::Signed: 63 if (Precision) 64 return CreatePrecisionRegex("-?([1-9][0-9]*)?[0-9]"); 65 return std::string("-?[0-9]+"); 66 case Kind::HexUpper: 67 if (Precision) 68 return CreatePrecisionRegex("([1-9A-F][0-9A-F]*)?[0-9A-F]"); 69 return (Twine(AlternateFormPrefix) + Twine("[0-9A-F]+")).str(); 70 case Kind::HexLower: 71 if (Precision) 72 return CreatePrecisionRegex("([1-9a-f][0-9a-f]*)?[0-9a-f]"); 73 return (Twine(AlternateFormPrefix) + Twine("[0-9a-f]+")).str(); 74 default: 75 return createStringError(std::errc::invalid_argument, 76 "trying to match value with invalid format"); 77 } 78 } 79 80 Expected<std::string> 81 ExpressionFormat::getMatchingString(ExpressionValue IntegerValue) const { 82 uint64_t AbsoluteValue; 83 StringRef SignPrefix = IntegerValue.isNegative() ? "-" : ""; 84 85 if (Value == Kind::Signed) { 86 Expected<int64_t> SignedValue = IntegerValue.getSignedValue(); 87 if (!SignedValue) 88 return SignedValue.takeError(); 89 if (*SignedValue < 0) 90 AbsoluteValue = cantFail(IntegerValue.getAbsolute().getUnsignedValue()); 91 else 92 AbsoluteValue = *SignedValue; 93 } else { 94 Expected<uint64_t> UnsignedValue = IntegerValue.getUnsignedValue(); 95 if (!UnsignedValue) 96 return UnsignedValue.takeError(); 97 AbsoluteValue = *UnsignedValue; 98 } 99 100 std::string AbsoluteValueStr; 101 switch (Value) { 102 case Kind::Unsigned: 103 case Kind::Signed: 104 AbsoluteValueStr = utostr(AbsoluteValue); 105 break; 106 case Kind::HexUpper: 107 case Kind::HexLower: 108 AbsoluteValueStr = utohexstr(AbsoluteValue, Value == Kind::HexLower); 109 break; 110 default: 111 return createStringError(std::errc::invalid_argument, 112 "trying to match value with invalid format"); 113 } 114 115 StringRef AlternateFormPrefix = AlternateForm ? StringRef("0x") : StringRef(); 116 117 if (Precision > AbsoluteValueStr.size()) { 118 unsigned LeadingZeros = Precision - AbsoluteValueStr.size(); 119 return (Twine(SignPrefix) + Twine(AlternateFormPrefix) + 120 std::string(LeadingZeros, '0') + AbsoluteValueStr) 121 .str(); 122 } 123 124 return (Twine(SignPrefix) + Twine(AlternateFormPrefix) + AbsoluteValueStr) 125 .str(); 126 } 127 128 Expected<ExpressionValue> 129 ExpressionFormat::valueFromStringRepr(StringRef StrVal, 130 const SourceMgr &SM) const { 131 bool ValueIsSigned = Value == Kind::Signed; 132 // Both the FileCheck utility and library only call this method with a valid 133 // value in StrVal. This is guaranteed by the regex returned by 134 // getWildcardRegex() above. Only underflow and overflow errors can thus 135 // occur. However new uses of this method could be added in the future so 136 // the error message does not make assumptions about StrVal. 137 StringRef IntegerParseErrorStr = "unable to represent numeric value"; 138 if (ValueIsSigned) { 139 int64_t SignedValue; 140 141 if (StrVal.getAsInteger(10, SignedValue)) 142 return ErrorDiagnostic::get(SM, StrVal, IntegerParseErrorStr); 143 144 return ExpressionValue(SignedValue); 145 } 146 147 bool Hex = Value == Kind::HexUpper || Value == Kind::HexLower; 148 uint64_t UnsignedValue; 149 bool MissingFormPrefix = AlternateForm && !StrVal.consume_front("0x"); 150 if (StrVal.getAsInteger(Hex ? 16 : 10, UnsignedValue)) 151 return ErrorDiagnostic::get(SM, StrVal, IntegerParseErrorStr); 152 153 // Error out for a missing prefix only now that we know we have an otherwise 154 // valid integer. For example, "-0x18" is reported above instead. 155 if (MissingFormPrefix) 156 return ErrorDiagnostic::get(SM, StrVal, "missing alternate form prefix"); 157 158 return ExpressionValue(UnsignedValue); 159 } 160 161 static int64_t getAsSigned(uint64_t UnsignedValue) { 162 // Use memcpy to reinterpret the bitpattern in Value since casting to 163 // signed is implementation-defined if the unsigned value is too big to be 164 // represented in the signed type and using an union violates type aliasing 165 // rules. 166 int64_t SignedValue; 167 memcpy(&SignedValue, &UnsignedValue, sizeof(SignedValue)); 168 return SignedValue; 169 } 170 171 Expected<int64_t> ExpressionValue::getSignedValue() const { 172 if (Negative) 173 return getAsSigned(Value); 174 175 if (Value > (uint64_t)std::numeric_limits<int64_t>::max()) 176 return make_error<OverflowError>(); 177 178 // Value is in the representable range of int64_t so we can use cast. 179 return static_cast<int64_t>(Value); 180 } 181 182 Expected<uint64_t> ExpressionValue::getUnsignedValue() const { 183 if (Negative) 184 return make_error<OverflowError>(); 185 186 return Value; 187 } 188 189 ExpressionValue ExpressionValue::getAbsolute() const { 190 if (!Negative) 191 return *this; 192 193 int64_t SignedValue = getAsSigned(Value); 194 int64_t MaxInt64 = std::numeric_limits<int64_t>::max(); 195 // Absolute value can be represented as int64_t. 196 if (SignedValue >= -MaxInt64) 197 return ExpressionValue(-getAsSigned(Value)); 198 199 // -X == -(max int64_t + Rem), negate each component independently. 200 SignedValue += MaxInt64; 201 uint64_t RemainingValueAbsolute = -SignedValue; 202 return ExpressionValue(MaxInt64 + RemainingValueAbsolute); 203 } 204 205 Expected<ExpressionValue> llvm::operator+(const ExpressionValue &LeftOperand, 206 const ExpressionValue &RightOperand) { 207 if (LeftOperand.isNegative() && RightOperand.isNegative()) { 208 int64_t LeftValue = cantFail(LeftOperand.getSignedValue()); 209 int64_t RightValue = cantFail(RightOperand.getSignedValue()); 210 Optional<int64_t> Result = checkedAdd<int64_t>(LeftValue, RightValue); 211 if (!Result) 212 return make_error<OverflowError>(); 213 214 return ExpressionValue(*Result); 215 } 216 217 // (-A) + B == B - A. 218 if (LeftOperand.isNegative()) 219 return RightOperand - LeftOperand.getAbsolute(); 220 221 // A + (-B) == A - B. 222 if (RightOperand.isNegative()) 223 return LeftOperand - RightOperand.getAbsolute(); 224 225 // Both values are positive at this point. 226 uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); 227 uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); 228 Optional<uint64_t> Result = 229 checkedAddUnsigned<uint64_t>(LeftValue, RightValue); 230 if (!Result) 231 return make_error<OverflowError>(); 232 233 return ExpressionValue(*Result); 234 } 235 236 Expected<ExpressionValue> llvm::operator-(const ExpressionValue &LeftOperand, 237 const ExpressionValue &RightOperand) { 238 // Result will be negative and thus might underflow. 239 if (LeftOperand.isNegative() && !RightOperand.isNegative()) { 240 int64_t LeftValue = cantFail(LeftOperand.getSignedValue()); 241 uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); 242 // Result <= -1 - (max int64_t) which overflows on 1- and 2-complement. 243 if (RightValue > (uint64_t)std::numeric_limits<int64_t>::max()) 244 return make_error<OverflowError>(); 245 Optional<int64_t> Result = 246 checkedSub(LeftValue, static_cast<int64_t>(RightValue)); 247 if (!Result) 248 return make_error<OverflowError>(); 249 250 return ExpressionValue(*Result); 251 } 252 253 // (-A) - (-B) == B - A. 254 if (LeftOperand.isNegative()) 255 return RightOperand.getAbsolute() - LeftOperand.getAbsolute(); 256 257 // A - (-B) == A + B. 258 if (RightOperand.isNegative()) 259 return LeftOperand + RightOperand.getAbsolute(); 260 261 // Both values are positive at this point. 262 uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); 263 uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); 264 if (LeftValue >= RightValue) 265 return ExpressionValue(LeftValue - RightValue); 266 else { 267 uint64_t AbsoluteDifference = RightValue - LeftValue; 268 uint64_t MaxInt64 = std::numeric_limits<int64_t>::max(); 269 // Value might underflow. 270 if (AbsoluteDifference > MaxInt64) { 271 AbsoluteDifference -= MaxInt64; 272 int64_t Result = -MaxInt64; 273 int64_t MinInt64 = std::numeric_limits<int64_t>::min(); 274 // Underflow, tested by: 275 // abs(Result + (max int64_t)) > abs((min int64_t) + (max int64_t)) 276 if (AbsoluteDifference > static_cast<uint64_t>(-(MinInt64 - Result))) 277 return make_error<OverflowError>(); 278 Result -= static_cast<int64_t>(AbsoluteDifference); 279 return ExpressionValue(Result); 280 } 281 282 return ExpressionValue(-static_cast<int64_t>(AbsoluteDifference)); 283 } 284 } 285 286 Expected<ExpressionValue> llvm::operator*(const ExpressionValue &LeftOperand, 287 const ExpressionValue &RightOperand) { 288 // -A * -B == A * B 289 if (LeftOperand.isNegative() && RightOperand.isNegative()) 290 return LeftOperand.getAbsolute() * RightOperand.getAbsolute(); 291 292 // A * -B == -B * A 293 if (RightOperand.isNegative()) 294 return RightOperand * LeftOperand; 295 296 assert(!RightOperand.isNegative() && "Unexpected negative operand!"); 297 298 // Result will be negative and can underflow. 299 if (LeftOperand.isNegative()) { 300 auto Result = LeftOperand.getAbsolute() * RightOperand.getAbsolute(); 301 if (!Result) 302 return Result; 303 304 return ExpressionValue(0) - *Result; 305 } 306 307 // Result will be positive and can overflow. 308 uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); 309 uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); 310 Optional<uint64_t> Result = 311 checkedMulUnsigned<uint64_t>(LeftValue, RightValue); 312 if (!Result) 313 return make_error<OverflowError>(); 314 315 return ExpressionValue(*Result); 316 } 317 318 Expected<ExpressionValue> llvm::operator/(const ExpressionValue &LeftOperand, 319 const ExpressionValue &RightOperand) { 320 // -A / -B == A / B 321 if (LeftOperand.isNegative() && RightOperand.isNegative()) 322 return LeftOperand.getAbsolute() / RightOperand.getAbsolute(); 323 324 // Check for divide by zero. 325 if (RightOperand == ExpressionValue(0)) 326 return make_error<OverflowError>(); 327 328 // Result will be negative and can underflow. 329 if (LeftOperand.isNegative() || RightOperand.isNegative()) 330 return ExpressionValue(0) - 331 cantFail(LeftOperand.getAbsolute() / RightOperand.getAbsolute()); 332 333 uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); 334 uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); 335 return ExpressionValue(LeftValue / RightValue); 336 } 337 338 Expected<ExpressionValue> llvm::max(const ExpressionValue &LeftOperand, 339 const ExpressionValue &RightOperand) { 340 if (LeftOperand.isNegative() && RightOperand.isNegative()) { 341 int64_t LeftValue = cantFail(LeftOperand.getSignedValue()); 342 int64_t RightValue = cantFail(RightOperand.getSignedValue()); 343 return ExpressionValue(std::max(LeftValue, RightValue)); 344 } 345 346 if (!LeftOperand.isNegative() && !RightOperand.isNegative()) { 347 uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); 348 uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); 349 return ExpressionValue(std::max(LeftValue, RightValue)); 350 } 351 352 if (LeftOperand.isNegative()) 353 return RightOperand; 354 355 return LeftOperand; 356 } 357 358 Expected<ExpressionValue> llvm::min(const ExpressionValue &LeftOperand, 359 const ExpressionValue &RightOperand) { 360 if (cantFail(max(LeftOperand, RightOperand)) == LeftOperand) 361 return RightOperand; 362 363 return LeftOperand; 364 } 365 366 Expected<ExpressionValue> NumericVariableUse::eval() const { 367 Optional<ExpressionValue> Value = Variable->getValue(); 368 if (Value) 369 return *Value; 370 371 return make_error<UndefVarError>(getExpressionStr()); 372 } 373 374 Expected<ExpressionValue> BinaryOperation::eval() const { 375 Expected<ExpressionValue> LeftOp = LeftOperand->eval(); 376 Expected<ExpressionValue> RightOp = RightOperand->eval(); 377 378 // Bubble up any error (e.g. undefined variables) in the recursive 379 // evaluation. 380 if (!LeftOp || !RightOp) { 381 Error Err = Error::success(); 382 if (!LeftOp) 383 Err = joinErrors(std::move(Err), LeftOp.takeError()); 384 if (!RightOp) 385 Err = joinErrors(std::move(Err), RightOp.takeError()); 386 return std::move(Err); 387 } 388 389 return EvalBinop(*LeftOp, *RightOp); 390 } 391 392 Expected<ExpressionFormat> 393 BinaryOperation::getImplicitFormat(const SourceMgr &SM) const { 394 Expected<ExpressionFormat> LeftFormat = LeftOperand->getImplicitFormat(SM); 395 Expected<ExpressionFormat> RightFormat = RightOperand->getImplicitFormat(SM); 396 if (!LeftFormat || !RightFormat) { 397 Error Err = Error::success(); 398 if (!LeftFormat) 399 Err = joinErrors(std::move(Err), LeftFormat.takeError()); 400 if (!RightFormat) 401 Err = joinErrors(std::move(Err), RightFormat.takeError()); 402 return std::move(Err); 403 } 404 405 if (*LeftFormat != ExpressionFormat::Kind::NoFormat && 406 *RightFormat != ExpressionFormat::Kind::NoFormat && 407 *LeftFormat != *RightFormat) 408 return ErrorDiagnostic::get( 409 SM, getExpressionStr(), 410 "implicit format conflict between '" + LeftOperand->getExpressionStr() + 411 "' (" + LeftFormat->toString() + ") and '" + 412 RightOperand->getExpressionStr() + "' (" + RightFormat->toString() + 413 "), need an explicit format specifier"); 414 415 return *LeftFormat != ExpressionFormat::Kind::NoFormat ? *LeftFormat 416 : *RightFormat; 417 } 418 419 Expected<std::string> NumericSubstitution::getResult() const { 420 assert(ExpressionPointer->getAST() != nullptr && 421 "Substituting empty expression"); 422 Expected<ExpressionValue> EvaluatedValue = 423 ExpressionPointer->getAST()->eval(); 424 if (!EvaluatedValue) 425 return EvaluatedValue.takeError(); 426 ExpressionFormat Format = ExpressionPointer->getFormat(); 427 return Format.getMatchingString(*EvaluatedValue); 428 } 429 430 Expected<std::string> StringSubstitution::getResult() const { 431 // Look up the value and escape it so that we can put it into the regex. 432 Expected<StringRef> VarVal = Context->getPatternVarValue(FromStr); 433 if (!VarVal) 434 return VarVal.takeError(); 435 return Regex::escape(*VarVal); 436 } 437 438 bool Pattern::isValidVarNameStart(char C) { return C == '_' || isAlpha(C); } 439 440 Expected<Pattern::VariableProperties> 441 Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) { 442 if (Str.empty()) 443 return ErrorDiagnostic::get(SM, Str, "empty variable name"); 444 445 size_t I = 0; 446 bool IsPseudo = Str[0] == '@'; 447 448 // Global vars start with '$'. 449 if (Str[0] == '$' || IsPseudo) 450 ++I; 451 452 if (!isValidVarNameStart(Str[I++])) 453 return ErrorDiagnostic::get(SM, Str, "invalid variable name"); 454 455 for (size_t E = Str.size(); I != E; ++I) 456 // Variable names are composed of alphanumeric characters and underscores. 457 if (Str[I] != '_' && !isAlnum(Str[I])) 458 break; 459 460 StringRef Name = Str.take_front(I); 461 Str = Str.substr(I); 462 return VariableProperties {Name, IsPseudo}; 463 } 464 465 // StringRef holding all characters considered as horizontal whitespaces by 466 // FileCheck input canonicalization. 467 constexpr StringLiteral SpaceChars = " \t"; 468 469 // Parsing helper function that strips the first character in S and returns it. 470 static char popFront(StringRef &S) { 471 char C = S.front(); 472 S = S.drop_front(); 473 return C; 474 } 475 476 char OverflowError::ID = 0; 477 char UndefVarError::ID = 0; 478 char ErrorDiagnostic::ID = 0; 479 char NotFoundError::ID = 0; 480 char ErrorReported::ID = 0; 481 482 Expected<NumericVariable *> Pattern::parseNumericVariableDefinition( 483 StringRef &Expr, FileCheckPatternContext *Context, 484 Optional<size_t> LineNumber, ExpressionFormat ImplicitFormat, 485 const SourceMgr &SM) { 486 Expected<VariableProperties> ParseVarResult = parseVariable(Expr, SM); 487 if (!ParseVarResult) 488 return ParseVarResult.takeError(); 489 StringRef Name = ParseVarResult->Name; 490 491 if (ParseVarResult->IsPseudo) 492 return ErrorDiagnostic::get( 493 SM, Name, "definition of pseudo numeric variable unsupported"); 494 495 // Detect collisions between string and numeric variables when the latter 496 // is created later than the former. 497 if (Context->DefinedVariableTable.find(Name) != 498 Context->DefinedVariableTable.end()) 499 return ErrorDiagnostic::get( 500 SM, Name, "string variable with name '" + Name + "' already exists"); 501 502 Expr = Expr.ltrim(SpaceChars); 503 if (!Expr.empty()) 504 return ErrorDiagnostic::get( 505 SM, Expr, "unexpected characters after numeric variable name"); 506 507 NumericVariable *DefinedNumericVariable; 508 auto VarTableIter = Context->GlobalNumericVariableTable.find(Name); 509 if (VarTableIter != Context->GlobalNumericVariableTable.end()) { 510 DefinedNumericVariable = VarTableIter->second; 511 if (DefinedNumericVariable->getImplicitFormat() != ImplicitFormat) 512 return ErrorDiagnostic::get( 513 SM, Expr, "format different from previous variable definition"); 514 } else 515 DefinedNumericVariable = 516 Context->makeNumericVariable(Name, ImplicitFormat, LineNumber); 517 518 return DefinedNumericVariable; 519 } 520 521 Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse( 522 StringRef Name, bool IsPseudo, Optional<size_t> LineNumber, 523 FileCheckPatternContext *Context, const SourceMgr &SM) { 524 if (IsPseudo && !Name.equals("@LINE")) 525 return ErrorDiagnostic::get( 526 SM, Name, "invalid pseudo numeric variable '" + Name + "'"); 527 528 // Numeric variable definitions and uses are parsed in the order in which 529 // they appear in the CHECK patterns. For each definition, the pointer to the 530 // class instance of the corresponding numeric variable definition is stored 531 // in GlobalNumericVariableTable in parsePattern. Therefore, if the pointer 532 // we get below is null, it means no such variable was defined before. When 533 // that happens, we create a dummy variable so that parsing can continue. All 534 // uses of undefined variables, whether string or numeric, are then diagnosed 535 // in printNoMatch() after failing to match. 536 auto VarTableIter = Context->GlobalNumericVariableTable.find(Name); 537 NumericVariable *NumericVariable; 538 if (VarTableIter != Context->GlobalNumericVariableTable.end()) 539 NumericVariable = VarTableIter->second; 540 else { 541 NumericVariable = Context->makeNumericVariable( 542 Name, ExpressionFormat(ExpressionFormat::Kind::Unsigned)); 543 Context->GlobalNumericVariableTable[Name] = NumericVariable; 544 } 545 546 Optional<size_t> DefLineNumber = NumericVariable->getDefLineNumber(); 547 if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber) 548 return ErrorDiagnostic::get( 549 SM, Name, 550 "numeric variable '" + Name + 551 "' defined earlier in the same CHECK directive"); 552 553 return std::make_unique<NumericVariableUse>(Name, NumericVariable); 554 } 555 556 Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand( 557 StringRef &Expr, AllowedOperand AO, bool MaybeInvalidConstraint, 558 Optional<size_t> LineNumber, FileCheckPatternContext *Context, 559 const SourceMgr &SM) { 560 if (Expr.startswith("(")) { 561 if (AO != AllowedOperand::Any) 562 return ErrorDiagnostic::get( 563 SM, Expr, "parenthesized expression not permitted here"); 564 return parseParenExpr(Expr, LineNumber, Context, SM); 565 } 566 567 if (AO == AllowedOperand::LineVar || AO == AllowedOperand::Any) { 568 // Try to parse as a numeric variable use. 569 Expected<Pattern::VariableProperties> ParseVarResult = 570 parseVariable(Expr, SM); 571 if (ParseVarResult) { 572 // Try to parse a function call. 573 if (Expr.ltrim(SpaceChars).startswith("(")) { 574 if (AO != AllowedOperand::Any) 575 return ErrorDiagnostic::get(SM, ParseVarResult->Name, 576 "unexpected function call"); 577 578 return parseCallExpr(Expr, ParseVarResult->Name, LineNumber, Context, 579 SM); 580 } 581 582 return parseNumericVariableUse(ParseVarResult->Name, 583 ParseVarResult->IsPseudo, LineNumber, 584 Context, SM); 585 } 586 587 if (AO == AllowedOperand::LineVar) 588 return ParseVarResult.takeError(); 589 // Ignore the error and retry parsing as a literal. 590 consumeError(ParseVarResult.takeError()); 591 } 592 593 // Otherwise, parse it as a literal. 594 int64_t SignedLiteralValue; 595 uint64_t UnsignedLiteralValue; 596 StringRef SaveExpr = Expr; 597 // Accept both signed and unsigned literal, default to signed literal. 598 if (!Expr.consumeInteger((AO == AllowedOperand::LegacyLiteral) ? 10 : 0, 599 UnsignedLiteralValue)) 600 return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()), 601 UnsignedLiteralValue); 602 Expr = SaveExpr; 603 if (AO == AllowedOperand::Any && !Expr.consumeInteger(0, SignedLiteralValue)) 604 return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()), 605 SignedLiteralValue); 606 607 return ErrorDiagnostic::get( 608 SM, Expr, 609 Twine("invalid ") + 610 (MaybeInvalidConstraint ? "matching constraint or " : "") + 611 "operand format"); 612 } 613 614 Expected<std::unique_ptr<ExpressionAST>> 615 Pattern::parseParenExpr(StringRef &Expr, Optional<size_t> LineNumber, 616 FileCheckPatternContext *Context, const SourceMgr &SM) { 617 Expr = Expr.ltrim(SpaceChars); 618 assert(Expr.startswith("(")); 619 620 // Parse right operand. 621 Expr.consume_front("("); 622 Expr = Expr.ltrim(SpaceChars); 623 if (Expr.empty()) 624 return ErrorDiagnostic::get(SM, Expr, "missing operand in expression"); 625 626 // Note: parseNumericOperand handles nested opening parentheses. 627 Expected<std::unique_ptr<ExpressionAST>> SubExprResult = parseNumericOperand( 628 Expr, AllowedOperand::Any, /*MaybeInvalidConstraint=*/false, LineNumber, 629 Context, SM); 630 Expr = Expr.ltrim(SpaceChars); 631 while (SubExprResult && !Expr.empty() && !Expr.startswith(")")) { 632 StringRef OrigExpr = Expr; 633 SubExprResult = parseBinop(OrigExpr, Expr, std::move(*SubExprResult), false, 634 LineNumber, Context, SM); 635 Expr = Expr.ltrim(SpaceChars); 636 } 637 if (!SubExprResult) 638 return SubExprResult; 639 640 if (!Expr.consume_front(")")) { 641 return ErrorDiagnostic::get(SM, Expr, 642 "missing ')' at end of nested expression"); 643 } 644 return SubExprResult; 645 } 646 647 Expected<std::unique_ptr<ExpressionAST>> 648 Pattern::parseBinop(StringRef Expr, StringRef &RemainingExpr, 649 std::unique_ptr<ExpressionAST> LeftOp, 650 bool IsLegacyLineExpr, Optional<size_t> LineNumber, 651 FileCheckPatternContext *Context, const SourceMgr &SM) { 652 RemainingExpr = RemainingExpr.ltrim(SpaceChars); 653 if (RemainingExpr.empty()) 654 return std::move(LeftOp); 655 656 // Check if this is a supported operation and select a function to perform 657 // it. 658 SMLoc OpLoc = SMLoc::getFromPointer(RemainingExpr.data()); 659 char Operator = popFront(RemainingExpr); 660 binop_eval_t EvalBinop; 661 switch (Operator) { 662 case '+': 663 EvalBinop = operator+; 664 break; 665 case '-': 666 EvalBinop = operator-; 667 break; 668 default: 669 return ErrorDiagnostic::get( 670 SM, OpLoc, Twine("unsupported operation '") + Twine(Operator) + "'"); 671 } 672 673 // Parse right operand. 674 RemainingExpr = RemainingExpr.ltrim(SpaceChars); 675 if (RemainingExpr.empty()) 676 return ErrorDiagnostic::get(SM, RemainingExpr, 677 "missing operand in expression"); 678 // The second operand in a legacy @LINE expression is always a literal. 679 AllowedOperand AO = 680 IsLegacyLineExpr ? AllowedOperand::LegacyLiteral : AllowedOperand::Any; 681 Expected<std::unique_ptr<ExpressionAST>> RightOpResult = 682 parseNumericOperand(RemainingExpr, AO, /*MaybeInvalidConstraint=*/false, 683 LineNumber, Context, SM); 684 if (!RightOpResult) 685 return RightOpResult; 686 687 Expr = Expr.drop_back(RemainingExpr.size()); 688 return std::make_unique<BinaryOperation>(Expr, EvalBinop, std::move(LeftOp), 689 std::move(*RightOpResult)); 690 } 691 692 Expected<std::unique_ptr<ExpressionAST>> 693 Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName, 694 Optional<size_t> LineNumber, 695 FileCheckPatternContext *Context, const SourceMgr &SM) { 696 Expr = Expr.ltrim(SpaceChars); 697 assert(Expr.startswith("(")); 698 699 auto OptFunc = StringSwitch<std::optional<binop_eval_t>>(FuncName) 700 .Case("add", operator+) 701 .Case("div", operator/) 702 .Case("max", max) 703 .Case("min", min) 704 .Case("mul", operator*) 705 .Case("sub", operator-) 706 .Default(None); 707 708 if (!OptFunc) 709 return ErrorDiagnostic::get( 710 SM, FuncName, Twine("call to undefined function '") + FuncName + "'"); 711 712 Expr.consume_front("("); 713 Expr = Expr.ltrim(SpaceChars); 714 715 // Parse call arguments, which are comma separated. 716 SmallVector<std::unique_ptr<ExpressionAST>, 4> Args; 717 while (!Expr.empty() && !Expr.startswith(")")) { 718 if (Expr.startswith(",")) 719 return ErrorDiagnostic::get(SM, Expr, "missing argument"); 720 721 // Parse the argument, which is an arbitary expression. 722 StringRef OuterBinOpExpr = Expr; 723 Expected<std::unique_ptr<ExpressionAST>> Arg = parseNumericOperand( 724 Expr, AllowedOperand::Any, /*MaybeInvalidConstraint=*/false, LineNumber, 725 Context, SM); 726 while (Arg && !Expr.empty()) { 727 Expr = Expr.ltrim(SpaceChars); 728 // Have we reached an argument terminator? 729 if (Expr.startswith(",") || Expr.startswith(")")) 730 break; 731 732 // Arg = Arg <op> <expr> 733 Arg = parseBinop(OuterBinOpExpr, Expr, std::move(*Arg), false, LineNumber, 734 Context, SM); 735 } 736 737 // Prefer an expression error over a generic invalid argument message. 738 if (!Arg) 739 return Arg.takeError(); 740 Args.push_back(std::move(*Arg)); 741 742 // Have we parsed all available arguments? 743 Expr = Expr.ltrim(SpaceChars); 744 if (!Expr.consume_front(",")) 745 break; 746 747 Expr = Expr.ltrim(SpaceChars); 748 if (Expr.startswith(")")) 749 return ErrorDiagnostic::get(SM, Expr, "missing argument"); 750 } 751 752 if (!Expr.consume_front(")")) 753 return ErrorDiagnostic::get(SM, Expr, 754 "missing ')' at end of call expression"); 755 756 const unsigned NumArgs = Args.size(); 757 if (NumArgs == 2) 758 return std::make_unique<BinaryOperation>(Expr, *OptFunc, std::move(Args[0]), 759 std::move(Args[1])); 760 761 // TODO: Support more than binop_eval_t. 762 return ErrorDiagnostic::get(SM, FuncName, 763 Twine("function '") + FuncName + 764 Twine("' takes 2 arguments but ") + 765 Twine(NumArgs) + " given"); 766 } 767 768 Expected<std::unique_ptr<Expression>> Pattern::parseNumericSubstitutionBlock( 769 StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable, 770 bool IsLegacyLineExpr, Optional<size_t> LineNumber, 771 FileCheckPatternContext *Context, const SourceMgr &SM) { 772 std::unique_ptr<ExpressionAST> ExpressionASTPointer = nullptr; 773 StringRef DefExpr = StringRef(); 774 DefinedNumericVariable = None; 775 ExpressionFormat ExplicitFormat = ExpressionFormat(); 776 unsigned Precision = 0; 777 778 // Parse format specifier (NOTE: ',' is also an argument seperator). 779 size_t FormatSpecEnd = Expr.find(','); 780 size_t FunctionStart = Expr.find('('); 781 if (FormatSpecEnd != StringRef::npos && FormatSpecEnd < FunctionStart) { 782 StringRef FormatExpr = Expr.take_front(FormatSpecEnd); 783 Expr = Expr.drop_front(FormatSpecEnd + 1); 784 FormatExpr = FormatExpr.trim(SpaceChars); 785 if (!FormatExpr.consume_front("%")) 786 return ErrorDiagnostic::get( 787 SM, FormatExpr, 788 "invalid matching format specification in expression"); 789 790 // Parse alternate form flag. 791 SMLoc AlternateFormFlagLoc = SMLoc::getFromPointer(FormatExpr.data()); 792 bool AlternateForm = FormatExpr.consume_front("#"); 793 794 // Parse precision. 795 if (FormatExpr.consume_front(".")) { 796 if (FormatExpr.consumeInteger(10, Precision)) 797 return ErrorDiagnostic::get(SM, FormatExpr, 798 "invalid precision in format specifier"); 799 } 800 801 if (!FormatExpr.empty()) { 802 // Check for unknown matching format specifier and set matching format in 803 // class instance representing this expression. 804 SMLoc FmtLoc = SMLoc::getFromPointer(FormatExpr.data()); 805 switch (popFront(FormatExpr)) { 806 case 'u': 807 ExplicitFormat = 808 ExpressionFormat(ExpressionFormat::Kind::Unsigned, Precision); 809 break; 810 case 'd': 811 ExplicitFormat = 812 ExpressionFormat(ExpressionFormat::Kind::Signed, Precision); 813 break; 814 case 'x': 815 ExplicitFormat = ExpressionFormat(ExpressionFormat::Kind::HexLower, 816 Precision, AlternateForm); 817 break; 818 case 'X': 819 ExplicitFormat = ExpressionFormat(ExpressionFormat::Kind::HexUpper, 820 Precision, AlternateForm); 821 break; 822 default: 823 return ErrorDiagnostic::get(SM, FmtLoc, 824 "invalid format specifier in expression"); 825 } 826 } 827 828 if (AlternateForm && ExplicitFormat != ExpressionFormat::Kind::HexLower && 829 ExplicitFormat != ExpressionFormat::Kind::HexUpper) 830 return ErrorDiagnostic::get( 831 SM, AlternateFormFlagLoc, 832 "alternate form only supported for hex values"); 833 834 FormatExpr = FormatExpr.ltrim(SpaceChars); 835 if (!FormatExpr.empty()) 836 return ErrorDiagnostic::get( 837 SM, FormatExpr, 838 "invalid matching format specification in expression"); 839 } 840 841 // Save variable definition expression if any. 842 size_t DefEnd = Expr.find(':'); 843 if (DefEnd != StringRef::npos) { 844 DefExpr = Expr.substr(0, DefEnd); 845 Expr = Expr.substr(DefEnd + 1); 846 } 847 848 // Parse matching constraint. 849 Expr = Expr.ltrim(SpaceChars); 850 bool HasParsedValidConstraint = false; 851 if (Expr.consume_front("==")) 852 HasParsedValidConstraint = true; 853 854 // Parse the expression itself. 855 Expr = Expr.ltrim(SpaceChars); 856 if (Expr.empty()) { 857 if (HasParsedValidConstraint) 858 return ErrorDiagnostic::get( 859 SM, Expr, "empty numeric expression should not have a constraint"); 860 } else { 861 Expr = Expr.rtrim(SpaceChars); 862 StringRef OuterBinOpExpr = Expr; 863 // The first operand in a legacy @LINE expression is always the @LINE 864 // pseudo variable. 865 AllowedOperand AO = 866 IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any; 867 Expected<std::unique_ptr<ExpressionAST>> ParseResult = parseNumericOperand( 868 Expr, AO, !HasParsedValidConstraint, LineNumber, Context, SM); 869 while (ParseResult && !Expr.empty()) { 870 ParseResult = parseBinop(OuterBinOpExpr, Expr, std::move(*ParseResult), 871 IsLegacyLineExpr, LineNumber, Context, SM); 872 // Legacy @LINE expressions only allow 2 operands. 873 if (ParseResult && IsLegacyLineExpr && !Expr.empty()) 874 return ErrorDiagnostic::get( 875 SM, Expr, 876 "unexpected characters at end of expression '" + Expr + "'"); 877 } 878 if (!ParseResult) 879 return ParseResult.takeError(); 880 ExpressionASTPointer = std::move(*ParseResult); 881 } 882 883 // Select format of the expression, i.e. (i) its explicit format, if any, 884 // otherwise (ii) its implicit format, if any, otherwise (iii) the default 885 // format (unsigned). Error out in case of conflicting implicit format 886 // without explicit format. 887 ExpressionFormat Format; 888 if (ExplicitFormat) 889 Format = ExplicitFormat; 890 else if (ExpressionASTPointer) { 891 Expected<ExpressionFormat> ImplicitFormat = 892 ExpressionASTPointer->getImplicitFormat(SM); 893 if (!ImplicitFormat) 894 return ImplicitFormat.takeError(); 895 Format = *ImplicitFormat; 896 } 897 if (!Format) 898 Format = ExpressionFormat(ExpressionFormat::Kind::Unsigned, Precision); 899 900 std::unique_ptr<Expression> ExpressionPointer = 901 std::make_unique<Expression>(std::move(ExpressionASTPointer), Format); 902 903 // Parse the numeric variable definition. 904 if (DefEnd != StringRef::npos) { 905 DefExpr = DefExpr.ltrim(SpaceChars); 906 Expected<NumericVariable *> ParseResult = parseNumericVariableDefinition( 907 DefExpr, Context, LineNumber, ExpressionPointer->getFormat(), SM); 908 909 if (!ParseResult) 910 return ParseResult.takeError(); 911 DefinedNumericVariable = *ParseResult; 912 } 913 914 return std::move(ExpressionPointer); 915 } 916 917 bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, 918 SourceMgr &SM, const FileCheckRequest &Req) { 919 bool MatchFullLinesHere = Req.MatchFullLines && CheckTy != Check::CheckNot; 920 IgnoreCase = Req.IgnoreCase; 921 922 PatternLoc = SMLoc::getFromPointer(PatternStr.data()); 923 924 if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines)) 925 // Ignore trailing whitespace. 926 while (!PatternStr.empty() && 927 (PatternStr.back() == ' ' || PatternStr.back() == '\t')) 928 PatternStr = PatternStr.substr(0, PatternStr.size() - 1); 929 930 // Check that there is something on the line. 931 if (PatternStr.empty() && CheckTy != Check::CheckEmpty) { 932 SM.PrintMessage(PatternLoc, SourceMgr::DK_Error, 933 "found empty check string with prefix '" + Prefix + ":'"); 934 return true; 935 } 936 937 if (!PatternStr.empty() && CheckTy == Check::CheckEmpty) { 938 SM.PrintMessage( 939 PatternLoc, SourceMgr::DK_Error, 940 "found non-empty check string for empty check with prefix '" + Prefix + 941 ":'"); 942 return true; 943 } 944 945 if (CheckTy == Check::CheckEmpty) { 946 RegExStr = "(\n$)"; 947 return false; 948 } 949 950 // If literal check, set fixed string. 951 if (CheckTy.isLiteralMatch()) { 952 FixedStr = PatternStr; 953 return false; 954 } 955 956 // Check to see if this is a fixed string, or if it has regex pieces. 957 if (!MatchFullLinesHere && 958 (PatternStr.size() < 2 || 959 (!PatternStr.contains("{{") && !PatternStr.contains("[[")))) { 960 FixedStr = PatternStr; 961 return false; 962 } 963 964 if (MatchFullLinesHere) { 965 RegExStr += '^'; 966 if (!Req.NoCanonicalizeWhiteSpace) 967 RegExStr += " *"; 968 } 969 970 // Paren value #0 is for the fully matched string. Any new parenthesized 971 // values add from there. 972 unsigned CurParen = 1; 973 974 // Otherwise, there is at least one regex piece. Build up the regex pattern 975 // by escaping scary characters in fixed strings, building up one big regex. 976 while (!PatternStr.empty()) { 977 // RegEx matches. 978 if (PatternStr.startswith("{{")) { 979 // This is the start of a regex match. Scan for the }}. 980 size_t End = PatternStr.find("}}"); 981 if (End == StringRef::npos) { 982 SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 983 SourceMgr::DK_Error, 984 "found start of regex string with no end '}}'"); 985 return true; 986 } 987 988 // Enclose {{}} patterns in parens just like [[]] even though we're not 989 // capturing the result for any purpose. This is required in case the 990 // expression contains an alternation like: CHECK: abc{{x|z}}def. We 991 // want this to turn into: "abc(x|z)def" not "abcx|zdef". 992 RegExStr += '('; 993 ++CurParen; 994 995 if (AddRegExToRegEx(PatternStr.substr(2, End - 2), CurParen, SM)) 996 return true; 997 RegExStr += ')'; 998 999 PatternStr = PatternStr.substr(End + 2); 1000 continue; 1001 } 1002 1003 // String and numeric substitution blocks. Pattern substitution blocks come 1004 // in two forms: [[foo:.*]] and [[foo]]. The former matches .* (or some 1005 // other regex) and assigns it to the string variable 'foo'. The latter 1006 // substitutes foo's value. Numeric substitution blocks recognize the same 1007 // form as string ones, but start with a '#' sign after the double 1008 // brackets. They also accept a combined form which sets a numeric variable 1009 // to the evaluation of an expression. Both string and numeric variable 1010 // names must satisfy the regular expression "[a-zA-Z_][0-9a-zA-Z_]*" to be 1011 // valid, as this helps catch some common errors. If there are extra '['s 1012 // before the "[[", treat them literally. 1013 if (PatternStr.startswith("[[") && !PatternStr.startswith("[[[")) { 1014 StringRef UnparsedPatternStr = PatternStr.substr(2); 1015 // Find the closing bracket pair ending the match. End is going to be an 1016 // offset relative to the beginning of the match string. 1017 size_t End = FindRegexVarEnd(UnparsedPatternStr, SM); 1018 StringRef MatchStr = UnparsedPatternStr.substr(0, End); 1019 bool IsNumBlock = MatchStr.consume_front("#"); 1020 1021 if (End == StringRef::npos) { 1022 SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()), 1023 SourceMgr::DK_Error, 1024 "Invalid substitution block, no ]] found"); 1025 return true; 1026 } 1027 // Strip the substitution block we are parsing. End points to the start 1028 // of the "]]" closing the expression so account for it in computing the 1029 // index of the first unparsed character. 1030 PatternStr = UnparsedPatternStr.substr(End + 2); 1031 1032 bool IsDefinition = false; 1033 bool SubstNeeded = false; 1034 // Whether the substitution block is a legacy use of @LINE with string 1035 // substitution block syntax. 1036 bool IsLegacyLineExpr = false; 1037 StringRef DefName; 1038 StringRef SubstStr; 1039 StringRef MatchRegexp; 1040 std::string WildcardRegexp; 1041 size_t SubstInsertIdx = RegExStr.size(); 1042 1043 // Parse string variable or legacy @LINE expression. 1044 if (!IsNumBlock) { 1045 size_t VarEndIdx = MatchStr.find(':'); 1046 size_t SpacePos = MatchStr.substr(0, VarEndIdx).find_first_of(" \t"); 1047 if (SpacePos != StringRef::npos) { 1048 SM.PrintMessage(SMLoc::getFromPointer(MatchStr.data() + SpacePos), 1049 SourceMgr::DK_Error, "unexpected whitespace"); 1050 return true; 1051 } 1052 1053 // Get the name (e.g. "foo") and verify it is well formed. 1054 StringRef OrigMatchStr = MatchStr; 1055 Expected<Pattern::VariableProperties> ParseVarResult = 1056 parseVariable(MatchStr, SM); 1057 if (!ParseVarResult) { 1058 logAllUnhandledErrors(ParseVarResult.takeError(), errs()); 1059 return true; 1060 } 1061 StringRef Name = ParseVarResult->Name; 1062 bool IsPseudo = ParseVarResult->IsPseudo; 1063 1064 IsDefinition = (VarEndIdx != StringRef::npos); 1065 SubstNeeded = !IsDefinition; 1066 if (IsDefinition) { 1067 if ((IsPseudo || !MatchStr.consume_front(":"))) { 1068 SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 1069 SourceMgr::DK_Error, 1070 "invalid name in string variable definition"); 1071 return true; 1072 } 1073 1074 // Detect collisions between string and numeric variables when the 1075 // former is created later than the latter. 1076 if (Context->GlobalNumericVariableTable.find(Name) != 1077 Context->GlobalNumericVariableTable.end()) { 1078 SM.PrintMessage( 1079 SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error, 1080 "numeric variable with name '" + Name + "' already exists"); 1081 return true; 1082 } 1083 DefName = Name; 1084 MatchRegexp = MatchStr; 1085 } else { 1086 if (IsPseudo) { 1087 MatchStr = OrigMatchStr; 1088 IsLegacyLineExpr = IsNumBlock = true; 1089 } else { 1090 if (!MatchStr.empty()) { 1091 SM.PrintMessage(SMLoc::getFromPointer(Name.data()), 1092 SourceMgr::DK_Error, 1093 "invalid name in string variable use"); 1094 return true; 1095 } 1096 SubstStr = Name; 1097 } 1098 } 1099 } 1100 1101 // Parse numeric substitution block. 1102 std::unique_ptr<Expression> ExpressionPointer; 1103 Optional<NumericVariable *> DefinedNumericVariable; 1104 if (IsNumBlock) { 1105 Expected<std::unique_ptr<Expression>> ParseResult = 1106 parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable, 1107 IsLegacyLineExpr, LineNumber, Context, 1108 SM); 1109 if (!ParseResult) { 1110 logAllUnhandledErrors(ParseResult.takeError(), errs()); 1111 return true; 1112 } 1113 ExpressionPointer = std::move(*ParseResult); 1114 SubstNeeded = ExpressionPointer->getAST() != nullptr; 1115 if (DefinedNumericVariable) { 1116 IsDefinition = true; 1117 DefName = (*DefinedNumericVariable)->getName(); 1118 } 1119 if (SubstNeeded) 1120 SubstStr = MatchStr; 1121 else { 1122 ExpressionFormat Format = ExpressionPointer->getFormat(); 1123 WildcardRegexp = cantFail(Format.getWildcardRegex()); 1124 MatchRegexp = WildcardRegexp; 1125 } 1126 } 1127 1128 // Handle variable definition: [[<def>:(...)]] and [[#(...)<def>:(...)]]. 1129 if (IsDefinition) { 1130 RegExStr += '('; 1131 ++SubstInsertIdx; 1132 1133 if (IsNumBlock) { 1134 NumericVariableMatch NumericVariableDefinition = { 1135 *DefinedNumericVariable, CurParen}; 1136 NumericVariableDefs[DefName] = NumericVariableDefinition; 1137 // This store is done here rather than in match() to allow 1138 // parseNumericVariableUse() to get the pointer to the class instance 1139 // of the right variable definition corresponding to a given numeric 1140 // variable use. 1141 Context->GlobalNumericVariableTable[DefName] = 1142 *DefinedNumericVariable; 1143 } else { 1144 VariableDefs[DefName] = CurParen; 1145 // Mark string variable as defined to detect collisions between 1146 // string and numeric variables in parseNumericVariableUse() and 1147 // defineCmdlineVariables() when the latter is created later than the 1148 // former. We cannot reuse GlobalVariableTable for this by populating 1149 // it with an empty string since we would then lose the ability to 1150 // detect the use of an undefined variable in match(). 1151 Context->DefinedVariableTable[DefName] = true; 1152 } 1153 1154 ++CurParen; 1155 } 1156 1157 if (!MatchRegexp.empty() && AddRegExToRegEx(MatchRegexp, CurParen, SM)) 1158 return true; 1159 1160 if (IsDefinition) 1161 RegExStr += ')'; 1162 1163 // Handle substitutions: [[foo]] and [[#<foo expr>]]. 1164 if (SubstNeeded) { 1165 // Handle substitution of string variables that were defined earlier on 1166 // the same line by emitting a backreference. Expressions do not 1167 // support substituting a numeric variable defined on the same line. 1168 if (!IsNumBlock && VariableDefs.find(SubstStr) != VariableDefs.end()) { 1169 unsigned CaptureParenGroup = VariableDefs[SubstStr]; 1170 if (CaptureParenGroup < 1 || CaptureParenGroup > 9) { 1171 SM.PrintMessage(SMLoc::getFromPointer(SubstStr.data()), 1172 SourceMgr::DK_Error, 1173 "Can't back-reference more than 9 variables"); 1174 return true; 1175 } 1176 AddBackrefToRegEx(CaptureParenGroup); 1177 } else { 1178 // Handle substitution of string variables ([[<var>]]) defined in 1179 // previous CHECK patterns, and substitution of expressions. 1180 Substitution *Substitution = 1181 IsNumBlock 1182 ? Context->makeNumericSubstitution( 1183 SubstStr, std::move(ExpressionPointer), SubstInsertIdx) 1184 : Context->makeStringSubstitution(SubstStr, SubstInsertIdx); 1185 Substitutions.push_back(Substitution); 1186 } 1187 } 1188 1189 continue; 1190 } 1191 1192 // Handle fixed string matches. 1193 // Find the end, which is the start of the next regex. 1194 size_t FixedMatchEnd = 1195 std::min(PatternStr.find("{{", 1), PatternStr.find("[[", 1)); 1196 RegExStr += Regex::escape(PatternStr.substr(0, FixedMatchEnd)); 1197 PatternStr = PatternStr.substr(FixedMatchEnd); 1198 } 1199 1200 if (MatchFullLinesHere) { 1201 if (!Req.NoCanonicalizeWhiteSpace) 1202 RegExStr += " *"; 1203 RegExStr += '$'; 1204 } 1205 1206 return false; 1207 } 1208 1209 bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) { 1210 Regex R(RS); 1211 std::string Error; 1212 if (!R.isValid(Error)) { 1213 SM.PrintMessage(SMLoc::getFromPointer(RS.data()), SourceMgr::DK_Error, 1214 "invalid regex: " + Error); 1215 return true; 1216 } 1217 1218 RegExStr += RS.str(); 1219 CurParen += R.getNumMatches(); 1220 return false; 1221 } 1222 1223 void Pattern::AddBackrefToRegEx(unsigned BackrefNum) { 1224 assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number"); 1225 std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum); 1226 RegExStr += Backref; 1227 } 1228 1229 Pattern::MatchResult Pattern::match(StringRef Buffer, 1230 const SourceMgr &SM) const { 1231 // If this is the EOF pattern, match it immediately. 1232 if (CheckTy == Check::CheckEOF) 1233 return MatchResult(Buffer.size(), 0, Error::success()); 1234 1235 // If this is a fixed string pattern, just match it now. 1236 if (!FixedStr.empty()) { 1237 size_t Pos = 1238 IgnoreCase ? Buffer.find_insensitive(FixedStr) : Buffer.find(FixedStr); 1239 if (Pos == StringRef::npos) 1240 return make_error<NotFoundError>(); 1241 return MatchResult(Pos, /*MatchLen=*/FixedStr.size(), Error::success()); 1242 } 1243 1244 // Regex match. 1245 1246 // If there are substitutions, we need to create a temporary string with the 1247 // actual value. 1248 StringRef RegExToMatch = RegExStr; 1249 std::string TmpStr; 1250 if (!Substitutions.empty()) { 1251 TmpStr = RegExStr; 1252 if (LineNumber) 1253 Context->LineVariable->setValue(ExpressionValue(*LineNumber)); 1254 1255 size_t InsertOffset = 0; 1256 // Substitute all string variables and expressions whose values are only 1257 // now known. Use of string variables defined on the same line are handled 1258 // by back-references. 1259 Error Errs = Error::success(); 1260 for (const auto &Substitution : Substitutions) { 1261 // Substitute and check for failure (e.g. use of undefined variable). 1262 Expected<std::string> Value = Substitution->getResult(); 1263 if (!Value) { 1264 // Convert to an ErrorDiagnostic to get location information. This is 1265 // done here rather than printMatch/printNoMatch since now we know which 1266 // substitution block caused the overflow. 1267 Errs = joinErrors(std::move(Errs), 1268 handleErrors( 1269 Value.takeError(), 1270 [&](const OverflowError &E) { 1271 return ErrorDiagnostic::get( 1272 SM, Substitution->getFromString(), 1273 "unable to substitute variable or " 1274 "numeric expression: overflow error"); 1275 }, 1276 [&SM](const UndefVarError &E) { 1277 return ErrorDiagnostic::get(SM, E.getVarName(), 1278 E.message()); 1279 })); 1280 continue; 1281 } 1282 1283 // Plop it into the regex at the adjusted offset. 1284 TmpStr.insert(TmpStr.begin() + Substitution->getIndex() + InsertOffset, 1285 Value->begin(), Value->end()); 1286 InsertOffset += Value->size(); 1287 } 1288 if (Errs) 1289 return std::move(Errs); 1290 1291 // Match the newly constructed regex. 1292 RegExToMatch = TmpStr; 1293 } 1294 1295 SmallVector<StringRef, 4> MatchInfo; 1296 unsigned int Flags = Regex::Newline; 1297 if (IgnoreCase) 1298 Flags |= Regex::IgnoreCase; 1299 if (!Regex(RegExToMatch, Flags).match(Buffer, &MatchInfo)) 1300 return make_error<NotFoundError>(); 1301 1302 // Successful regex match. 1303 assert(!MatchInfo.empty() && "Didn't get any match"); 1304 StringRef FullMatch = MatchInfo[0]; 1305 1306 // If this defines any string variables, remember their values. 1307 for (const auto &VariableDef : VariableDefs) { 1308 assert(VariableDef.second < MatchInfo.size() && "Internal paren error"); 1309 Context->GlobalVariableTable[VariableDef.first] = 1310 MatchInfo[VariableDef.second]; 1311 } 1312 1313 // Like CHECK-NEXT, CHECK-EMPTY's match range is considered to start after 1314 // the required preceding newline, which is consumed by the pattern in the 1315 // case of CHECK-EMPTY but not CHECK-NEXT. 1316 size_t MatchStartSkip = CheckTy == Check::CheckEmpty; 1317 Match TheMatch; 1318 TheMatch.Pos = FullMatch.data() - Buffer.data() + MatchStartSkip; 1319 TheMatch.Len = FullMatch.size() - MatchStartSkip; 1320 1321 // If this defines any numeric variables, remember their values. 1322 for (const auto &NumericVariableDef : NumericVariableDefs) { 1323 const NumericVariableMatch &NumericVariableMatch = 1324 NumericVariableDef.getValue(); 1325 unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup; 1326 assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error"); 1327 NumericVariable *DefinedNumericVariable = 1328 NumericVariableMatch.DefinedNumericVariable; 1329 1330 StringRef MatchedValue = MatchInfo[CaptureParenGroup]; 1331 ExpressionFormat Format = DefinedNumericVariable->getImplicitFormat(); 1332 Expected<ExpressionValue> Value = 1333 Format.valueFromStringRepr(MatchedValue, SM); 1334 if (!Value) 1335 return MatchResult(TheMatch, Value.takeError()); 1336 DefinedNumericVariable->setValue(*Value, MatchedValue); 1337 } 1338 1339 return MatchResult(TheMatch, Error::success()); 1340 } 1341 1342 unsigned Pattern::computeMatchDistance(StringRef Buffer) const { 1343 // Just compute the number of matching characters. For regular expressions, we 1344 // just compare against the regex itself and hope for the best. 1345 // 1346 // FIXME: One easy improvement here is have the regex lib generate a single 1347 // example regular expression which matches, and use that as the example 1348 // string. 1349 StringRef ExampleString(FixedStr); 1350 if (ExampleString.empty()) 1351 ExampleString = RegExStr; 1352 1353 // Only compare up to the first line in the buffer, or the string size. 1354 StringRef BufferPrefix = Buffer.substr(0, ExampleString.size()); 1355 BufferPrefix = BufferPrefix.split('\n').first; 1356 return BufferPrefix.edit_distance(ExampleString); 1357 } 1358 1359 void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer, 1360 SMRange Range, 1361 FileCheckDiag::MatchType MatchTy, 1362 std::vector<FileCheckDiag> *Diags) const { 1363 // Print what we know about substitutions. 1364 if (!Substitutions.empty()) { 1365 for (const auto &Substitution : Substitutions) { 1366 SmallString<256> Msg; 1367 raw_svector_ostream OS(Msg); 1368 1369 Expected<std::string> MatchedValue = Substitution->getResult(); 1370 // Substitution failures are handled in printNoMatch(). 1371 if (!MatchedValue) { 1372 consumeError(MatchedValue.takeError()); 1373 continue; 1374 } 1375 1376 OS << "with \""; 1377 OS.write_escaped(Substitution->getFromString()) << "\" equal to \""; 1378 OS.write_escaped(*MatchedValue) << "\""; 1379 1380 // We report only the start of the match/search range to suggest we are 1381 // reporting the substitutions as set at the start of the match/search. 1382 // Indicating a non-zero-length range might instead seem to imply that the 1383 // substitution matches or was captured from exactly that range. 1384 if (Diags) 1385 Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy, 1386 SMRange(Range.Start, Range.Start), OS.str()); 1387 else 1388 SM.PrintMessage(Range.Start, SourceMgr::DK_Note, OS.str()); 1389 } 1390 } 1391 } 1392 1393 void Pattern::printVariableDefs(const SourceMgr &SM, 1394 FileCheckDiag::MatchType MatchTy, 1395 std::vector<FileCheckDiag> *Diags) const { 1396 if (VariableDefs.empty() && NumericVariableDefs.empty()) 1397 return; 1398 // Build list of variable captures. 1399 struct VarCapture { 1400 StringRef Name; 1401 SMRange Range; 1402 }; 1403 SmallVector<VarCapture, 2> VarCaptures; 1404 for (const auto &VariableDef : VariableDefs) { 1405 VarCapture VC; 1406 VC.Name = VariableDef.first; 1407 StringRef Value = Context->GlobalVariableTable[VC.Name]; 1408 SMLoc Start = SMLoc::getFromPointer(Value.data()); 1409 SMLoc End = SMLoc::getFromPointer(Value.data() + Value.size()); 1410 VC.Range = SMRange(Start, End); 1411 VarCaptures.push_back(VC); 1412 } 1413 for (const auto &VariableDef : NumericVariableDefs) { 1414 VarCapture VC; 1415 VC.Name = VariableDef.getKey(); 1416 Optional<StringRef> StrValue = 1417 VariableDef.getValue().DefinedNumericVariable->getStringValue(); 1418 if (!StrValue) 1419 continue; 1420 SMLoc Start = SMLoc::getFromPointer(StrValue->data()); 1421 SMLoc End = SMLoc::getFromPointer(StrValue->data() + StrValue->size()); 1422 VC.Range = SMRange(Start, End); 1423 VarCaptures.push_back(VC); 1424 } 1425 // Sort variable captures by the order in which they matched the input. 1426 // Ranges shouldn't be overlapping, so we can just compare the start. 1427 llvm::sort(VarCaptures, [](const VarCapture &A, const VarCapture &B) { 1428 if (&A == &B) 1429 return false; 1430 assert(A.Range.Start != B.Range.Start && 1431 "unexpected overlapping variable captures"); 1432 return A.Range.Start.getPointer() < B.Range.Start.getPointer(); 1433 }); 1434 // Create notes for the sorted captures. 1435 for (const VarCapture &VC : VarCaptures) { 1436 SmallString<256> Msg; 1437 raw_svector_ostream OS(Msg); 1438 OS << "captured var \"" << VC.Name << "\""; 1439 if (Diags) 1440 Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy, VC.Range, OS.str()); 1441 else 1442 SM.PrintMessage(VC.Range.Start, SourceMgr::DK_Note, OS.str(), VC.Range); 1443 } 1444 } 1445 1446 static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy, 1447 const SourceMgr &SM, SMLoc Loc, 1448 Check::FileCheckType CheckTy, 1449 StringRef Buffer, size_t Pos, size_t Len, 1450 std::vector<FileCheckDiag> *Diags, 1451 bool AdjustPrevDiags = false) { 1452 SMLoc Start = SMLoc::getFromPointer(Buffer.data() + Pos); 1453 SMLoc End = SMLoc::getFromPointer(Buffer.data() + Pos + Len); 1454 SMRange Range(Start, End); 1455 if (Diags) { 1456 if (AdjustPrevDiags) { 1457 SMLoc CheckLoc = Diags->rbegin()->CheckLoc; 1458 for (auto I = Diags->rbegin(), E = Diags->rend(); 1459 I != E && I->CheckLoc == CheckLoc; ++I) 1460 I->MatchTy = MatchTy; 1461 } else 1462 Diags->emplace_back(SM, CheckTy, Loc, MatchTy, Range); 1463 } 1464 return Range; 1465 } 1466 1467 void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer, 1468 std::vector<FileCheckDiag> *Diags) const { 1469 // Attempt to find the closest/best fuzzy match. Usually an error happens 1470 // because some string in the output didn't exactly match. In these cases, we 1471 // would like to show the user a best guess at what "should have" matched, to 1472 // save them having to actually check the input manually. 1473 size_t NumLinesForward = 0; 1474 size_t Best = StringRef::npos; 1475 double BestQuality = 0; 1476 1477 // Use an arbitrary 4k limit on how far we will search. 1478 for (size_t i = 0, e = std::min(size_t(4096), Buffer.size()); i != e; ++i) { 1479 if (Buffer[i] == '\n') 1480 ++NumLinesForward; 1481 1482 // Patterns have leading whitespace stripped, so skip whitespace when 1483 // looking for something which looks like a pattern. 1484 if (Buffer[i] == ' ' || Buffer[i] == '\t') 1485 continue; 1486 1487 // Compute the "quality" of this match as an arbitrary combination of the 1488 // match distance and the number of lines skipped to get to this match. 1489 unsigned Distance = computeMatchDistance(Buffer.substr(i)); 1490 double Quality = Distance + (NumLinesForward / 100.); 1491 1492 if (Quality < BestQuality || Best == StringRef::npos) { 1493 Best = i; 1494 BestQuality = Quality; 1495 } 1496 } 1497 1498 // Print the "possible intended match here" line if we found something 1499 // reasonable and not equal to what we showed in the "scanning from here" 1500 // line. 1501 if (Best && Best != StringRef::npos && BestQuality < 50) { 1502 SMRange MatchRange = 1503 ProcessMatchResult(FileCheckDiag::MatchFuzzy, SM, getLoc(), 1504 getCheckTy(), Buffer, Best, 0, Diags); 1505 SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, 1506 "possible intended match here"); 1507 1508 // FIXME: If we wanted to be really friendly we would show why the match 1509 // failed, as it can be hard to spot simple one character differences. 1510 } 1511 } 1512 1513 Expected<StringRef> 1514 FileCheckPatternContext::getPatternVarValue(StringRef VarName) { 1515 auto VarIter = GlobalVariableTable.find(VarName); 1516 if (VarIter == GlobalVariableTable.end()) 1517 return make_error<UndefVarError>(VarName); 1518 1519 return VarIter->second; 1520 } 1521 1522 template <class... Types> 1523 NumericVariable *FileCheckPatternContext::makeNumericVariable(Types... args) { 1524 NumericVariables.push_back(std::make_unique<NumericVariable>(args...)); 1525 return NumericVariables.back().get(); 1526 } 1527 1528 Substitution * 1529 FileCheckPatternContext::makeStringSubstitution(StringRef VarName, 1530 size_t InsertIdx) { 1531 Substitutions.push_back( 1532 std::make_unique<StringSubstitution>(this, VarName, InsertIdx)); 1533 return Substitutions.back().get(); 1534 } 1535 1536 Substitution *FileCheckPatternContext::makeNumericSubstitution( 1537 StringRef ExpressionStr, std::unique_ptr<Expression> Expression, 1538 size_t InsertIdx) { 1539 Substitutions.push_back(std::make_unique<NumericSubstitution>( 1540 this, ExpressionStr, std::move(Expression), InsertIdx)); 1541 return Substitutions.back().get(); 1542 } 1543 1544 size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) { 1545 // Offset keeps track of the current offset within the input Str 1546 size_t Offset = 0; 1547 // [...] Nesting depth 1548 size_t BracketDepth = 0; 1549 1550 while (!Str.empty()) { 1551 if (Str.startswith("]]") && BracketDepth == 0) 1552 return Offset; 1553 if (Str[0] == '\\') { 1554 // Backslash escapes the next char within regexes, so skip them both. 1555 Str = Str.substr(2); 1556 Offset += 2; 1557 } else { 1558 switch (Str[0]) { 1559 default: 1560 break; 1561 case '[': 1562 BracketDepth++; 1563 break; 1564 case ']': 1565 if (BracketDepth == 0) { 1566 SM.PrintMessage(SMLoc::getFromPointer(Str.data()), 1567 SourceMgr::DK_Error, 1568 "missing closing \"]\" for regex variable"); 1569 exit(1); 1570 } 1571 BracketDepth--; 1572 break; 1573 } 1574 Str = Str.substr(1); 1575 Offset++; 1576 } 1577 } 1578 1579 return StringRef::npos; 1580 } 1581 1582 StringRef FileCheck::CanonicalizeFile(MemoryBuffer &MB, 1583 SmallVectorImpl<char> &OutputBuffer) { 1584 OutputBuffer.reserve(MB.getBufferSize()); 1585 1586 for (const char *Ptr = MB.getBufferStart(), *End = MB.getBufferEnd(); 1587 Ptr != End; ++Ptr) { 1588 // Eliminate trailing dosish \r. 1589 if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') { 1590 continue; 1591 } 1592 1593 // If current char is not a horizontal whitespace or if horizontal 1594 // whitespace canonicalization is disabled, dump it to output as is. 1595 if (Req.NoCanonicalizeWhiteSpace || (*Ptr != ' ' && *Ptr != '\t')) { 1596 OutputBuffer.push_back(*Ptr); 1597 continue; 1598 } 1599 1600 // Otherwise, add one space and advance over neighboring space. 1601 OutputBuffer.push_back(' '); 1602 while (Ptr + 1 != End && (Ptr[1] == ' ' || Ptr[1] == '\t')) 1603 ++Ptr; 1604 } 1605 1606 // Add a null byte and then return all but that byte. 1607 OutputBuffer.push_back('\0'); 1608 return StringRef(OutputBuffer.data(), OutputBuffer.size() - 1); 1609 } 1610 1611 FileCheckDiag::FileCheckDiag(const SourceMgr &SM, 1612 const Check::FileCheckType &CheckTy, 1613 SMLoc CheckLoc, MatchType MatchTy, 1614 SMRange InputRange, StringRef Note) 1615 : CheckTy(CheckTy), CheckLoc(CheckLoc), MatchTy(MatchTy), Note(Note) { 1616 auto Start = SM.getLineAndColumn(InputRange.Start); 1617 auto End = SM.getLineAndColumn(InputRange.End); 1618 InputStartLine = Start.first; 1619 InputStartCol = Start.second; 1620 InputEndLine = End.first; 1621 InputEndCol = End.second; 1622 } 1623 1624 static bool IsPartOfWord(char c) { 1625 return (isAlnum(c) || c == '-' || c == '_'); 1626 } 1627 1628 Check::FileCheckType &Check::FileCheckType::setCount(int C) { 1629 assert(Count > 0 && "zero and negative counts are not supported"); 1630 assert((C == 1 || Kind == CheckPlain) && 1631 "count supported only for plain CHECK directives"); 1632 Count = C; 1633 return *this; 1634 } 1635 1636 std::string Check::FileCheckType::getModifiersDescription() const { 1637 if (Modifiers.none()) 1638 return ""; 1639 std::string Ret; 1640 raw_string_ostream OS(Ret); 1641 OS << '{'; 1642 if (isLiteralMatch()) 1643 OS << "LITERAL"; 1644 OS << '}'; 1645 return OS.str(); 1646 } 1647 1648 std::string Check::FileCheckType::getDescription(StringRef Prefix) const { 1649 // Append directive modifiers. 1650 auto WithModifiers = [this, Prefix](StringRef Str) -> std::string { 1651 return (Prefix + Str + getModifiersDescription()).str(); 1652 }; 1653 1654 switch (Kind) { 1655 case Check::CheckNone: 1656 return "invalid"; 1657 case Check::CheckMisspelled: 1658 return "misspelled"; 1659 case Check::CheckPlain: 1660 if (Count > 1) 1661 return WithModifiers("-COUNT"); 1662 return WithModifiers(""); 1663 case Check::CheckNext: 1664 return WithModifiers("-NEXT"); 1665 case Check::CheckSame: 1666 return WithModifiers("-SAME"); 1667 case Check::CheckNot: 1668 return WithModifiers("-NOT"); 1669 case Check::CheckDAG: 1670 return WithModifiers("-DAG"); 1671 case Check::CheckLabel: 1672 return WithModifiers("-LABEL"); 1673 case Check::CheckEmpty: 1674 return WithModifiers("-EMPTY"); 1675 case Check::CheckComment: 1676 return std::string(Prefix); 1677 case Check::CheckEOF: 1678 return "implicit EOF"; 1679 case Check::CheckBadNot: 1680 return "bad NOT"; 1681 case Check::CheckBadCount: 1682 return "bad COUNT"; 1683 } 1684 llvm_unreachable("unknown FileCheckType"); 1685 } 1686 1687 static std::pair<Check::FileCheckType, StringRef> 1688 FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix, 1689 bool &Misspelled) { 1690 if (Buffer.size() <= Prefix.size()) 1691 return {Check::CheckNone, StringRef()}; 1692 1693 StringRef Rest = Buffer.drop_front(Prefix.size()); 1694 // Check for comment. 1695 if (llvm::is_contained(Req.CommentPrefixes, Prefix)) { 1696 if (Rest.consume_front(":")) 1697 return {Check::CheckComment, Rest}; 1698 // Ignore a comment prefix if it has a suffix like "-NOT". 1699 return {Check::CheckNone, StringRef()}; 1700 } 1701 1702 auto ConsumeModifiers = [&](Check::FileCheckType Ret) 1703 -> std::pair<Check::FileCheckType, StringRef> { 1704 if (Rest.consume_front(":")) 1705 return {Ret, Rest}; 1706 if (!Rest.consume_front("{")) 1707 return {Check::CheckNone, StringRef()}; 1708 1709 // Parse the modifiers, speparated by commas. 1710 do { 1711 // Allow whitespace in modifiers list. 1712 Rest = Rest.ltrim(); 1713 if (Rest.consume_front("LITERAL")) 1714 Ret.setLiteralMatch(); 1715 else 1716 return {Check::CheckNone, Rest}; 1717 // Allow whitespace in modifiers list. 1718 Rest = Rest.ltrim(); 1719 } while (Rest.consume_front(",")); 1720 if (!Rest.consume_front("}:")) 1721 return {Check::CheckNone, Rest}; 1722 return {Ret, Rest}; 1723 }; 1724 1725 // Verify that the prefix is followed by directive modifiers or a colon. 1726 if (Rest.consume_front(":")) 1727 return {Check::CheckPlain, Rest}; 1728 if (Rest.front() == '{') 1729 return ConsumeModifiers(Check::CheckPlain); 1730 1731 if (Rest.consume_front("_")) 1732 Misspelled = true; 1733 else if (!Rest.consume_front("-")) 1734 return {Check::CheckNone, StringRef()}; 1735 1736 if (Rest.consume_front("COUNT-")) { 1737 int64_t Count; 1738 if (Rest.consumeInteger(10, Count)) 1739 // Error happened in parsing integer. 1740 return {Check::CheckBadCount, Rest}; 1741 if (Count <= 0 || Count > INT32_MAX) 1742 return {Check::CheckBadCount, Rest}; 1743 if (Rest.front() != ':' && Rest.front() != '{') 1744 return {Check::CheckBadCount, Rest}; 1745 return ConsumeModifiers( 1746 Check::FileCheckType(Check::CheckPlain).setCount(Count)); 1747 } 1748 1749 // You can't combine -NOT with another suffix. 1750 if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") || 1751 Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") || 1752 Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") || 1753 Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:")) 1754 return {Check::CheckBadNot, Rest}; 1755 1756 if (Rest.consume_front("NEXT")) 1757 return ConsumeModifiers(Check::CheckNext); 1758 1759 if (Rest.consume_front("SAME")) 1760 return ConsumeModifiers(Check::CheckSame); 1761 1762 if (Rest.consume_front("NOT")) 1763 return ConsumeModifiers(Check::CheckNot); 1764 1765 if (Rest.consume_front("DAG")) 1766 return ConsumeModifiers(Check::CheckDAG); 1767 1768 if (Rest.consume_front("LABEL")) 1769 return ConsumeModifiers(Check::CheckLabel); 1770 1771 if (Rest.consume_front("EMPTY")) 1772 return ConsumeModifiers(Check::CheckEmpty); 1773 1774 return {Check::CheckNone, Rest}; 1775 } 1776 1777 static std::pair<Check::FileCheckType, StringRef> 1778 FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix) { 1779 bool Misspelled = false; 1780 auto Res = FindCheckType(Req, Buffer, Prefix, Misspelled); 1781 if (Res.first != Check::CheckNone && Misspelled) 1782 return {Check::CheckMisspelled, Res.second}; 1783 return Res; 1784 } 1785 1786 // From the given position, find the next character after the word. 1787 static size_t SkipWord(StringRef Str, size_t Loc) { 1788 while (Loc < Str.size() && IsPartOfWord(Str[Loc])) 1789 ++Loc; 1790 return Loc; 1791 } 1792 1793 /// Searches the buffer for the first prefix in the prefix regular expression. 1794 /// 1795 /// This searches the buffer using the provided regular expression, however it 1796 /// enforces constraints beyond that: 1797 /// 1) The found prefix must not be a suffix of something that looks like 1798 /// a valid prefix. 1799 /// 2) The found prefix must be followed by a valid check type suffix using \c 1800 /// FindCheckType above. 1801 /// 1802 /// \returns a pair of StringRefs into the Buffer, which combines: 1803 /// - the first match of the regular expression to satisfy these two is 1804 /// returned, 1805 /// otherwise an empty StringRef is returned to indicate failure. 1806 /// - buffer rewound to the location right after parsed suffix, for parsing 1807 /// to continue from 1808 /// 1809 /// If this routine returns a valid prefix, it will also shrink \p Buffer to 1810 /// start at the beginning of the returned prefix, increment \p LineNumber for 1811 /// each new line consumed from \p Buffer, and set \p CheckTy to the type of 1812 /// check found by examining the suffix. 1813 /// 1814 /// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy 1815 /// is unspecified. 1816 static std::pair<StringRef, StringRef> 1817 FindFirstMatchingPrefix(const FileCheckRequest &Req, Regex &PrefixRE, 1818 StringRef &Buffer, unsigned &LineNumber, 1819 Check::FileCheckType &CheckTy) { 1820 SmallVector<StringRef, 2> Matches; 1821 1822 while (!Buffer.empty()) { 1823 // Find the first (longest) match using the RE. 1824 if (!PrefixRE.match(Buffer, &Matches)) 1825 // No match at all, bail. 1826 return {StringRef(), StringRef()}; 1827 1828 StringRef Prefix = Matches[0]; 1829 Matches.clear(); 1830 1831 assert(Prefix.data() >= Buffer.data() && 1832 Prefix.data() < Buffer.data() + Buffer.size() && 1833 "Prefix doesn't start inside of buffer!"); 1834 size_t Loc = Prefix.data() - Buffer.data(); 1835 StringRef Skipped = Buffer.substr(0, Loc); 1836 Buffer = Buffer.drop_front(Loc); 1837 LineNumber += Skipped.count('\n'); 1838 1839 // Check that the matched prefix isn't a suffix of some other check-like 1840 // word. 1841 // FIXME: This is a very ad-hoc check. it would be better handled in some 1842 // other way. Among other things it seems hard to distinguish between 1843 // intentional and unintentional uses of this feature. 1844 if (Skipped.empty() || !IsPartOfWord(Skipped.back())) { 1845 // Now extract the type. 1846 StringRef AfterSuffix; 1847 std::tie(CheckTy, AfterSuffix) = FindCheckType(Req, Buffer, Prefix); 1848 1849 // If we've found a valid check type for this prefix, we're done. 1850 if (CheckTy != Check::CheckNone) 1851 return {Prefix, AfterSuffix}; 1852 } 1853 1854 // If we didn't successfully find a prefix, we need to skip this invalid 1855 // prefix and continue scanning. We directly skip the prefix that was 1856 // matched and any additional parts of that check-like word. 1857 Buffer = Buffer.drop_front(SkipWord(Buffer, Prefix.size())); 1858 } 1859 1860 // We ran out of buffer while skipping partial matches so give up. 1861 return {StringRef(), StringRef()}; 1862 } 1863 1864 void FileCheckPatternContext::createLineVariable() { 1865 assert(!LineVariable && "@LINE pseudo numeric variable already created"); 1866 StringRef LineName = "@LINE"; 1867 LineVariable = makeNumericVariable( 1868 LineName, ExpressionFormat(ExpressionFormat::Kind::Unsigned)); 1869 GlobalNumericVariableTable[LineName] = LineVariable; 1870 } 1871 1872 FileCheck::FileCheck(FileCheckRequest Req) 1873 : Req(Req), PatternContext(std::make_unique<FileCheckPatternContext>()), 1874 CheckStrings(std::make_unique<std::vector<FileCheckString>>()) {} 1875 1876 FileCheck::~FileCheck() = default; 1877 1878 bool FileCheck::readCheckFile( 1879 SourceMgr &SM, StringRef Buffer, Regex &PrefixRE, 1880 std::pair<unsigned, unsigned> *ImpPatBufferIDRange) { 1881 if (ImpPatBufferIDRange) 1882 ImpPatBufferIDRange->first = ImpPatBufferIDRange->second = 0; 1883 1884 Error DefineError = 1885 PatternContext->defineCmdlineVariables(Req.GlobalDefines, SM); 1886 if (DefineError) { 1887 logAllUnhandledErrors(std::move(DefineError), errs()); 1888 return true; 1889 } 1890 1891 PatternContext->createLineVariable(); 1892 1893 std::vector<Pattern> ImplicitNegativeChecks; 1894 for (StringRef PatternString : Req.ImplicitCheckNot) { 1895 // Create a buffer with fake command line content in order to display the 1896 // command line option responsible for the specific implicit CHECK-NOT. 1897 std::string Prefix = "-implicit-check-not='"; 1898 std::string Suffix = "'"; 1899 std::unique_ptr<MemoryBuffer> CmdLine = MemoryBuffer::getMemBufferCopy( 1900 (Prefix + PatternString + Suffix).str(), "command line"); 1901 1902 StringRef PatternInBuffer = 1903 CmdLine->getBuffer().substr(Prefix.size(), PatternString.size()); 1904 unsigned BufferID = SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc()); 1905 if (ImpPatBufferIDRange) { 1906 if (ImpPatBufferIDRange->first == ImpPatBufferIDRange->second) { 1907 ImpPatBufferIDRange->first = BufferID; 1908 ImpPatBufferIDRange->second = BufferID + 1; 1909 } else { 1910 assert(BufferID == ImpPatBufferIDRange->second && 1911 "expected consecutive source buffer IDs"); 1912 ++ImpPatBufferIDRange->second; 1913 } 1914 } 1915 1916 ImplicitNegativeChecks.push_back( 1917 Pattern(Check::CheckNot, PatternContext.get())); 1918 ImplicitNegativeChecks.back().parsePattern(PatternInBuffer, 1919 "IMPLICIT-CHECK", SM, Req); 1920 } 1921 1922 std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks; 1923 1924 // LineNumber keeps track of the line on which CheckPrefix instances are 1925 // found. 1926 unsigned LineNumber = 1; 1927 1928 std::set<StringRef> PrefixesNotFound(Req.CheckPrefixes.begin(), 1929 Req.CheckPrefixes.end()); 1930 const size_t DistinctPrefixes = PrefixesNotFound.size(); 1931 while (true) { 1932 Check::FileCheckType CheckTy; 1933 1934 // See if a prefix occurs in the memory buffer. 1935 StringRef UsedPrefix; 1936 StringRef AfterSuffix; 1937 std::tie(UsedPrefix, AfterSuffix) = 1938 FindFirstMatchingPrefix(Req, PrefixRE, Buffer, LineNumber, CheckTy); 1939 if (UsedPrefix.empty()) 1940 break; 1941 if (CheckTy != Check::CheckComment) 1942 PrefixesNotFound.erase(UsedPrefix); 1943 1944 assert(UsedPrefix.data() == Buffer.data() && 1945 "Failed to move Buffer's start forward, or pointed prefix outside " 1946 "of the buffer!"); 1947 assert(AfterSuffix.data() >= Buffer.data() && 1948 AfterSuffix.data() < Buffer.data() + Buffer.size() && 1949 "Parsing after suffix doesn't start inside of buffer!"); 1950 1951 // Location to use for error messages. 1952 const char *UsedPrefixStart = UsedPrefix.data(); 1953 1954 // Skip the buffer to the end of parsed suffix (or just prefix, if no good 1955 // suffix was processed). 1956 Buffer = AfterSuffix.empty() ? Buffer.drop_front(UsedPrefix.size()) 1957 : AfterSuffix; 1958 1959 // Complain about misspelled directives. 1960 if (CheckTy == Check::CheckMisspelled) { 1961 StringRef UsedDirective(UsedPrefix.data(), 1962 AfterSuffix.data() - UsedPrefix.data()); 1963 SM.PrintMessage(SMLoc::getFromPointer(UsedDirective.data()), 1964 SourceMgr::DK_Error, 1965 "misspelled directive '" + UsedDirective + "'"); 1966 return true; 1967 } 1968 1969 // Complain about useful-looking but unsupported suffixes. 1970 if (CheckTy == Check::CheckBadNot) { 1971 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Error, 1972 "unsupported -NOT combo on prefix '" + UsedPrefix + "'"); 1973 return true; 1974 } 1975 1976 // Complain about invalid count specification. 1977 if (CheckTy == Check::CheckBadCount) { 1978 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Error, 1979 "invalid count in -COUNT specification on prefix '" + 1980 UsedPrefix + "'"); 1981 return true; 1982 } 1983 1984 // Okay, we found the prefix, yay. Remember the rest of the line, but ignore 1985 // leading whitespace. 1986 if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines)) 1987 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t")); 1988 1989 // Scan ahead to the end of line. 1990 size_t EOL = Buffer.find_first_of("\n\r"); 1991 1992 // Remember the location of the start of the pattern, for diagnostics. 1993 SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data()); 1994 1995 // Extract the pattern from the buffer. 1996 StringRef PatternBuffer = Buffer.substr(0, EOL); 1997 Buffer = Buffer.substr(EOL); 1998 1999 // If this is a comment, we're done. 2000 if (CheckTy == Check::CheckComment) 2001 continue; 2002 2003 // Parse the pattern. 2004 Pattern P(CheckTy, PatternContext.get(), LineNumber); 2005 if (P.parsePattern(PatternBuffer, UsedPrefix, SM, Req)) 2006 return true; 2007 2008 // Verify that CHECK-LABEL lines do not define or use variables 2009 if ((CheckTy == Check::CheckLabel) && P.hasVariable()) { 2010 SM.PrintMessage( 2011 SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error, 2012 "found '" + UsedPrefix + "-LABEL:'" 2013 " with variable definition or use"); 2014 return true; 2015 } 2016 2017 // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them. 2018 if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame || 2019 CheckTy == Check::CheckEmpty) && 2020 CheckStrings->empty()) { 2021 StringRef Type = CheckTy == Check::CheckNext 2022 ? "NEXT" 2023 : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME"; 2024 SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart), 2025 SourceMgr::DK_Error, 2026 "found '" + UsedPrefix + "-" + Type + 2027 "' without previous '" + UsedPrefix + ": line"); 2028 return true; 2029 } 2030 2031 // Handle CHECK-DAG/-NOT. 2032 if (CheckTy == Check::CheckDAG || CheckTy == Check::CheckNot) { 2033 DagNotMatches.push_back(P); 2034 continue; 2035 } 2036 2037 // Okay, add the string we captured to the output vector and move on. 2038 CheckStrings->emplace_back(P, UsedPrefix, PatternLoc); 2039 std::swap(DagNotMatches, CheckStrings->back().DagNotStrings); 2040 DagNotMatches = ImplicitNegativeChecks; 2041 } 2042 2043 // When there are no used prefixes we report an error except in the case that 2044 // no prefix is specified explicitly but -implicit-check-not is specified. 2045 const bool NoPrefixesFound = PrefixesNotFound.size() == DistinctPrefixes; 2046 const bool SomePrefixesUnexpectedlyNotUsed = 2047 !Req.AllowUnusedPrefixes && !PrefixesNotFound.empty(); 2048 if ((NoPrefixesFound || SomePrefixesUnexpectedlyNotUsed) && 2049 (ImplicitNegativeChecks.empty() || !Req.IsDefaultCheckPrefix)) { 2050 errs() << "error: no check strings found with prefix" 2051 << (PrefixesNotFound.size() > 1 ? "es " : " "); 2052 bool First = true; 2053 for (StringRef MissingPrefix : PrefixesNotFound) { 2054 if (!First) 2055 errs() << ", "; 2056 errs() << "\'" << MissingPrefix << ":'"; 2057 First = false; 2058 } 2059 errs() << '\n'; 2060 return true; 2061 } 2062 2063 // Add an EOF pattern for any trailing --implicit-check-not/CHECK-DAG/-NOTs, 2064 // and use the first prefix as a filler for the error message. 2065 if (!DagNotMatches.empty()) { 2066 CheckStrings->emplace_back( 2067 Pattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1), 2068 *Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data())); 2069 std::swap(DagNotMatches, CheckStrings->back().DagNotStrings); 2070 } 2071 2072 return false; 2073 } 2074 2075 /// Returns either (1) \c ErrorSuccess if there was no error or (2) 2076 /// \c ErrorReported if an error was reported, such as an unexpected match. 2077 static Error printMatch(bool ExpectedMatch, const SourceMgr &SM, 2078 StringRef Prefix, SMLoc Loc, const Pattern &Pat, 2079 int MatchedCount, StringRef Buffer, 2080 Pattern::MatchResult MatchResult, 2081 const FileCheckRequest &Req, 2082 std::vector<FileCheckDiag> *Diags) { 2083 // Suppress some verbosity if there's no error. 2084 bool HasError = !ExpectedMatch || MatchResult.TheError; 2085 bool PrintDiag = true; 2086 if (!HasError) { 2087 if (!Req.Verbose) 2088 return ErrorReported::reportedOrSuccess(HasError); 2089 if (!Req.VerboseVerbose && Pat.getCheckTy() == Check::CheckEOF) 2090 return ErrorReported::reportedOrSuccess(HasError); 2091 // Due to their verbosity, we don't print verbose diagnostics here if we're 2092 // gathering them for Diags to be rendered elsewhere, but we always print 2093 // other diagnostics. 2094 PrintDiag = !Diags; 2095 } 2096 2097 // Add "found" diagnostic, substitutions, and variable definitions to Diags. 2098 FileCheckDiag::MatchType MatchTy = ExpectedMatch 2099 ? FileCheckDiag::MatchFoundAndExpected 2100 : FileCheckDiag::MatchFoundButExcluded; 2101 SMRange MatchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(), 2102 Buffer, MatchResult.TheMatch->Pos, 2103 MatchResult.TheMatch->Len, Diags); 2104 if (Diags) { 2105 Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, Diags); 2106 Pat.printVariableDefs(SM, MatchTy, Diags); 2107 } 2108 if (!PrintDiag) { 2109 assert(!HasError && "expected to report more diagnostics for error"); 2110 return ErrorReported::reportedOrSuccess(HasError); 2111 } 2112 2113 // Print the match. 2114 std::string Message = formatv("{0}: {1} string found in input", 2115 Pat.getCheckTy().getDescription(Prefix), 2116 (ExpectedMatch ? "expected" : "excluded")) 2117 .str(); 2118 if (Pat.getCount() > 1) 2119 Message += formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str(); 2120 SM.PrintMessage( 2121 Loc, ExpectedMatch ? SourceMgr::DK_Remark : SourceMgr::DK_Error, Message); 2122 SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, "found here", 2123 {MatchRange}); 2124 2125 // Print additional information, which can be useful even if there are errors. 2126 Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, nullptr); 2127 Pat.printVariableDefs(SM, MatchTy, nullptr); 2128 2129 // Print errors and add them to Diags. We report these errors after the match 2130 // itself because we found them after the match. If we had found them before 2131 // the match, we'd be in printNoMatch. 2132 handleAllErrors(std::move(MatchResult.TheError), 2133 [&](const ErrorDiagnostic &E) { 2134 E.log(errs()); 2135 if (Diags) { 2136 Diags->emplace_back(SM, Pat.getCheckTy(), Loc, 2137 FileCheckDiag::MatchFoundErrorNote, 2138 E.getRange(), E.getMessage().str()); 2139 } 2140 }); 2141 return ErrorReported::reportedOrSuccess(HasError); 2142 } 2143 2144 /// Returns either (1) \c ErrorSuccess if there was no error, or (2) 2145 /// \c ErrorReported if an error was reported, such as an expected match not 2146 /// found. 2147 static Error printNoMatch(bool ExpectedMatch, const SourceMgr &SM, 2148 StringRef Prefix, SMLoc Loc, const Pattern &Pat, 2149 int MatchedCount, StringRef Buffer, Error MatchError, 2150 bool VerboseVerbose, 2151 std::vector<FileCheckDiag> *Diags) { 2152 // Print any pattern errors, and record them to be added to Diags later. 2153 bool HasError = ExpectedMatch; 2154 bool HasPatternError = false; 2155 FileCheckDiag::MatchType MatchTy = ExpectedMatch 2156 ? FileCheckDiag::MatchNoneButExpected 2157 : FileCheckDiag::MatchNoneAndExcluded; 2158 SmallVector<std::string, 4> ErrorMsgs; 2159 handleAllErrors( 2160 std::move(MatchError), 2161 [&](const ErrorDiagnostic &E) { 2162 HasError = HasPatternError = true; 2163 MatchTy = FileCheckDiag::MatchNoneForInvalidPattern; 2164 E.log(errs()); 2165 if (Diags) 2166 ErrorMsgs.push_back(E.getMessage().str()); 2167 }, 2168 // NotFoundError is why printNoMatch was invoked. 2169 [](const NotFoundError &E) {}); 2170 2171 // Suppress some verbosity if there's no error. 2172 bool PrintDiag = true; 2173 if (!HasError) { 2174 if (!VerboseVerbose) 2175 return ErrorReported::reportedOrSuccess(HasError); 2176 // Due to their verbosity, we don't print verbose diagnostics here if we're 2177 // gathering them for Diags to be rendered elsewhere, but we always print 2178 // other diagnostics. 2179 PrintDiag = !Diags; 2180 } 2181 2182 // Add "not found" diagnostic, substitutions, and pattern errors to Diags. 2183 // 2184 // We handle Diags a little differently than the errors we print directly: 2185 // we add the "not found" diagnostic to Diags even if there are pattern 2186 // errors. The reason is that we need to attach pattern errors as notes 2187 // somewhere in the input, and the input search range from the "not found" 2188 // diagnostic is all we have to anchor them. 2189 SMRange SearchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(), 2190 Buffer, 0, Buffer.size(), Diags); 2191 if (Diags) { 2192 SMRange NoteRange = SMRange(SearchRange.Start, SearchRange.Start); 2193 for (StringRef ErrorMsg : ErrorMsgs) 2194 Diags->emplace_back(SM, Pat.getCheckTy(), Loc, MatchTy, NoteRange, 2195 ErrorMsg); 2196 Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, Diags); 2197 } 2198 if (!PrintDiag) { 2199 assert(!HasError && "expected to report more diagnostics for error"); 2200 return ErrorReported::reportedOrSuccess(HasError); 2201 } 2202 2203 // Print "not found" diagnostic, except that's implied if we already printed a 2204 // pattern error. 2205 if (!HasPatternError) { 2206 std::string Message = formatv("{0}: {1} string not found in input", 2207 Pat.getCheckTy().getDescription(Prefix), 2208 (ExpectedMatch ? "expected" : "excluded")) 2209 .str(); 2210 if (Pat.getCount() > 1) 2211 Message += 2212 formatv(" ({0} out of {1})", MatchedCount, Pat.getCount()).str(); 2213 SM.PrintMessage(Loc, 2214 ExpectedMatch ? SourceMgr::DK_Error : SourceMgr::DK_Remark, 2215 Message); 2216 SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note, 2217 "scanning from here"); 2218 } 2219 2220 // Print additional information, which can be useful even after a pattern 2221 // error. 2222 Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, nullptr); 2223 if (ExpectedMatch) 2224 Pat.printFuzzyMatch(SM, Buffer, Diags); 2225 return ErrorReported::reportedOrSuccess(HasError); 2226 } 2227 2228 /// Returns either (1) \c ErrorSuccess if there was no error, or (2) 2229 /// \c ErrorReported if an error was reported. 2230 static Error reportMatchResult(bool ExpectedMatch, const SourceMgr &SM, 2231 StringRef Prefix, SMLoc Loc, const Pattern &Pat, 2232 int MatchedCount, StringRef Buffer, 2233 Pattern::MatchResult MatchResult, 2234 const FileCheckRequest &Req, 2235 std::vector<FileCheckDiag> *Diags) { 2236 if (MatchResult.TheMatch) 2237 return printMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer, 2238 std::move(MatchResult), Req, Diags); 2239 return printNoMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer, 2240 std::move(MatchResult.TheError), Req.VerboseVerbose, 2241 Diags); 2242 } 2243 2244 /// Counts the number of newlines in the specified range. 2245 static unsigned CountNumNewlinesBetween(StringRef Range, 2246 const char *&FirstNewLine) { 2247 unsigned NumNewLines = 0; 2248 while (true) { 2249 // Scan for newline. 2250 Range = Range.substr(Range.find_first_of("\n\r")); 2251 if (Range.empty()) 2252 return NumNewLines; 2253 2254 ++NumNewLines; 2255 2256 // Handle \n\r and \r\n as a single newline. 2257 if (Range.size() > 1 && (Range[1] == '\n' || Range[1] == '\r') && 2258 (Range[0] != Range[1])) 2259 Range = Range.substr(1); 2260 Range = Range.substr(1); 2261 2262 if (NumNewLines == 1) 2263 FirstNewLine = Range.begin(); 2264 } 2265 } 2266 2267 size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer, 2268 bool IsLabelScanMode, size_t &MatchLen, 2269 FileCheckRequest &Req, 2270 std::vector<FileCheckDiag> *Diags) const { 2271 size_t LastPos = 0; 2272 std::vector<const Pattern *> NotStrings; 2273 2274 // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL 2275 // bounds; we have not processed variable definitions within the bounded block 2276 // yet so cannot handle any final CHECK-DAG yet; this is handled when going 2277 // over the block again (including the last CHECK-LABEL) in normal mode. 2278 if (!IsLabelScanMode) { 2279 // Match "dag strings" (with mixed "not strings" if any). 2280 LastPos = CheckDag(SM, Buffer, NotStrings, Req, Diags); 2281 if (LastPos == StringRef::npos) 2282 return StringRef::npos; 2283 } 2284 2285 // Match itself from the last position after matching CHECK-DAG. 2286 size_t LastMatchEnd = LastPos; 2287 size_t FirstMatchPos = 0; 2288 // Go match the pattern Count times. Majority of patterns only match with 2289 // count 1 though. 2290 assert(Pat.getCount() != 0 && "pattern count can not be zero"); 2291 for (int i = 1; i <= Pat.getCount(); i++) { 2292 StringRef MatchBuffer = Buffer.substr(LastMatchEnd); 2293 // get a match at current start point 2294 Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM); 2295 2296 // report 2297 if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix, Loc, 2298 Pat, i, MatchBuffer, 2299 std::move(MatchResult), Req, Diags)) { 2300 cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {})); 2301 return StringRef::npos; 2302 } 2303 2304 size_t MatchPos = MatchResult.TheMatch->Pos; 2305 if (i == 1) 2306 FirstMatchPos = LastPos + MatchPos; 2307 2308 // move start point after the match 2309 LastMatchEnd += MatchPos + MatchResult.TheMatch->Len; 2310 } 2311 // Full match len counts from first match pos. 2312 MatchLen = LastMatchEnd - FirstMatchPos; 2313 2314 // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT 2315 // or CHECK-NOT 2316 if (!IsLabelScanMode) { 2317 size_t MatchPos = FirstMatchPos - LastPos; 2318 StringRef MatchBuffer = Buffer.substr(LastPos); 2319 StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos); 2320 2321 // If this check is a "CHECK-NEXT", verify that the previous match was on 2322 // the previous line (i.e. that there is one newline between them). 2323 if (CheckNext(SM, SkippedRegion)) { 2324 ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc, 2325 Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen, 2326 Diags, Req.Verbose); 2327 return StringRef::npos; 2328 } 2329 2330 // If this check is a "CHECK-SAME", verify that the previous match was on 2331 // the same line (i.e. that there is no newline between them). 2332 if (CheckSame(SM, SkippedRegion)) { 2333 ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc, 2334 Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen, 2335 Diags, Req.Verbose); 2336 return StringRef::npos; 2337 } 2338 2339 // If this match had "not strings", verify that they don't exist in the 2340 // skipped region. 2341 if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags)) 2342 return StringRef::npos; 2343 } 2344 2345 return FirstMatchPos; 2346 } 2347 2348 bool FileCheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const { 2349 if (Pat.getCheckTy() != Check::CheckNext && 2350 Pat.getCheckTy() != Check::CheckEmpty) 2351 return false; 2352 2353 Twine CheckName = 2354 Prefix + 2355 Twine(Pat.getCheckTy() == Check::CheckEmpty ? "-EMPTY" : "-NEXT"); 2356 2357 // Count the number of newlines between the previous match and this one. 2358 const char *FirstNewLine = nullptr; 2359 unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine); 2360 2361 if (NumNewLines == 0) { 2362 SM.PrintMessage(Loc, SourceMgr::DK_Error, 2363 CheckName + ": is on the same line as previous match"); 2364 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note, 2365 "'next' match was here"); 2366 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 2367 "previous match ended here"); 2368 return true; 2369 } 2370 2371 if (NumNewLines != 1) { 2372 SM.PrintMessage(Loc, SourceMgr::DK_Error, 2373 CheckName + 2374 ": is not on the line after the previous match"); 2375 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note, 2376 "'next' match was here"); 2377 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 2378 "previous match ended here"); 2379 SM.PrintMessage(SMLoc::getFromPointer(FirstNewLine), SourceMgr::DK_Note, 2380 "non-matching line after previous match is here"); 2381 return true; 2382 } 2383 2384 return false; 2385 } 2386 2387 bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const { 2388 if (Pat.getCheckTy() != Check::CheckSame) 2389 return false; 2390 2391 // Count the number of newlines between the previous match and this one. 2392 const char *FirstNewLine = nullptr; 2393 unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine); 2394 2395 if (NumNewLines != 0) { 2396 SM.PrintMessage(Loc, SourceMgr::DK_Error, 2397 Prefix + 2398 "-SAME: is not on the same line as the previous match"); 2399 SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note, 2400 "'next' match was here"); 2401 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, 2402 "previous match ended here"); 2403 return true; 2404 } 2405 2406 return false; 2407 } 2408 2409 bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer, 2410 const std::vector<const Pattern *> &NotStrings, 2411 const FileCheckRequest &Req, 2412 std::vector<FileCheckDiag> *Diags) const { 2413 bool DirectiveFail = false; 2414 for (const Pattern *Pat : NotStrings) { 2415 assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!"); 2416 Pattern::MatchResult MatchResult = Pat->match(Buffer, SM); 2417 if (Error Err = reportMatchResult(/*ExpectedMatch=*/false, SM, Prefix, 2418 Pat->getLoc(), *Pat, 1, Buffer, 2419 std::move(MatchResult), Req, Diags)) { 2420 cantFail(handleErrors(std::move(Err), [&](const ErrorReported &E) {})); 2421 DirectiveFail = true; 2422 continue; 2423 } 2424 } 2425 return DirectiveFail; 2426 } 2427 2428 size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, 2429 std::vector<const Pattern *> &NotStrings, 2430 const FileCheckRequest &Req, 2431 std::vector<FileCheckDiag> *Diags) const { 2432 if (DagNotStrings.empty()) 2433 return 0; 2434 2435 // The start of the search range. 2436 size_t StartPos = 0; 2437 2438 struct MatchRange { 2439 size_t Pos; 2440 size_t End; 2441 }; 2442 // A sorted list of ranges for non-overlapping CHECK-DAG matches. Match 2443 // ranges are erased from this list once they are no longer in the search 2444 // range. 2445 std::list<MatchRange> MatchRanges; 2446 2447 // We need PatItr and PatEnd later for detecting the end of a CHECK-DAG 2448 // group, so we don't use a range-based for loop here. 2449 for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end(); 2450 PatItr != PatEnd; ++PatItr) { 2451 const Pattern &Pat = *PatItr; 2452 assert((Pat.getCheckTy() == Check::CheckDAG || 2453 Pat.getCheckTy() == Check::CheckNot) && 2454 "Invalid CHECK-DAG or CHECK-NOT!"); 2455 2456 if (Pat.getCheckTy() == Check::CheckNot) { 2457 NotStrings.push_back(&Pat); 2458 continue; 2459 } 2460 2461 assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!"); 2462 2463 // CHECK-DAG always matches from the start. 2464 size_t MatchLen = 0, MatchPos = StartPos; 2465 2466 // Search for a match that doesn't overlap a previous match in this 2467 // CHECK-DAG group. 2468 for (auto MI = MatchRanges.begin(), ME = MatchRanges.end(); true; ++MI) { 2469 StringRef MatchBuffer = Buffer.substr(MatchPos); 2470 Pattern::MatchResult MatchResult = Pat.match(MatchBuffer, SM); 2471 // With a group of CHECK-DAGs, a single mismatching means the match on 2472 // that group of CHECK-DAGs fails immediately. 2473 if (MatchResult.TheError || Req.VerboseVerbose) { 2474 if (Error Err = reportMatchResult(/*ExpectedMatch=*/true, SM, Prefix, 2475 Pat.getLoc(), Pat, 1, MatchBuffer, 2476 std::move(MatchResult), Req, Diags)) { 2477 cantFail( 2478 handleErrors(std::move(Err), [&](const ErrorReported &E) {})); 2479 return StringRef::npos; 2480 } 2481 } 2482 MatchLen = MatchResult.TheMatch->Len; 2483 // Re-calc it as the offset relative to the start of the original 2484 // string. 2485 MatchPos += MatchResult.TheMatch->Pos; 2486 MatchRange M{MatchPos, MatchPos + MatchLen}; 2487 if (Req.AllowDeprecatedDagOverlap) { 2488 // We don't need to track all matches in this mode, so we just maintain 2489 // one match range that encompasses the current CHECK-DAG group's 2490 // matches. 2491 if (MatchRanges.empty()) 2492 MatchRanges.insert(MatchRanges.end(), M); 2493 else { 2494 auto Block = MatchRanges.begin(); 2495 Block->Pos = std::min(Block->Pos, M.Pos); 2496 Block->End = std::max(Block->End, M.End); 2497 } 2498 break; 2499 } 2500 // Iterate previous matches until overlapping match or insertion point. 2501 bool Overlap = false; 2502 for (; MI != ME; ++MI) { 2503 if (M.Pos < MI->End) { 2504 // !Overlap => New match has no overlap and is before this old match. 2505 // Overlap => New match overlaps this old match. 2506 Overlap = MI->Pos < M.End; 2507 break; 2508 } 2509 } 2510 if (!Overlap) { 2511 // Insert non-overlapping match into list. 2512 MatchRanges.insert(MI, M); 2513 break; 2514 } 2515 if (Req.VerboseVerbose) { 2516 // Due to their verbosity, we don't print verbose diagnostics here if 2517 // we're gathering them for a different rendering, but we always print 2518 // other diagnostics. 2519 if (!Diags) { 2520 SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos); 2521 SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End); 2522 SMRange OldRange(OldStart, OldEnd); 2523 SM.PrintMessage(OldStart, SourceMgr::DK_Note, 2524 "match discarded, overlaps earlier DAG match here", 2525 {OldRange}); 2526 } else { 2527 SMLoc CheckLoc = Diags->rbegin()->CheckLoc; 2528 for (auto I = Diags->rbegin(), E = Diags->rend(); 2529 I != E && I->CheckLoc == CheckLoc; ++I) 2530 I->MatchTy = FileCheckDiag::MatchFoundButDiscarded; 2531 } 2532 } 2533 MatchPos = MI->End; 2534 } 2535 if (!Req.VerboseVerbose) 2536 cantFail(printMatch( 2537 /*ExpectedMatch=*/true, SM, Prefix, Pat.getLoc(), Pat, 1, Buffer, 2538 Pattern::MatchResult(MatchPos, MatchLen, Error::success()), Req, 2539 Diags)); 2540 2541 // Handle the end of a CHECK-DAG group. 2542 if (std::next(PatItr) == PatEnd || 2543 std::next(PatItr)->getCheckTy() == Check::CheckNot) { 2544 if (!NotStrings.empty()) { 2545 // If there are CHECK-NOTs between two CHECK-DAGs or from CHECK to 2546 // CHECK-DAG, verify that there are no 'not' strings occurred in that 2547 // region. 2548 StringRef SkippedRegion = 2549 Buffer.slice(StartPos, MatchRanges.begin()->Pos); 2550 if (CheckNot(SM, SkippedRegion, NotStrings, Req, Diags)) 2551 return StringRef::npos; 2552 // Clear "not strings". 2553 NotStrings.clear(); 2554 } 2555 // All subsequent CHECK-DAGs and CHECK-NOTs should be matched from the 2556 // end of this CHECK-DAG group's match range. 2557 StartPos = MatchRanges.rbegin()->End; 2558 // Don't waste time checking for (impossible) overlaps before that. 2559 MatchRanges.clear(); 2560 } 2561 } 2562 2563 return StartPos; 2564 } 2565 2566 static bool ValidatePrefixes(StringRef Kind, StringSet<> &UniquePrefixes, 2567 ArrayRef<StringRef> SuppliedPrefixes) { 2568 for (StringRef Prefix : SuppliedPrefixes) { 2569 if (Prefix.empty()) { 2570 errs() << "error: supplied " << Kind << " prefix must not be the empty " 2571 << "string\n"; 2572 return false; 2573 } 2574 static const Regex Validator("^[a-zA-Z0-9_-]*$"); 2575 if (!Validator.match(Prefix)) { 2576 errs() << "error: supplied " << Kind << " prefix must start with a " 2577 << "letter and contain only alphanumeric characters, hyphens, and " 2578 << "underscores: '" << Prefix << "'\n"; 2579 return false; 2580 } 2581 if (!UniquePrefixes.insert(Prefix).second) { 2582 errs() << "error: supplied " << Kind << " prefix must be unique among " 2583 << "check and comment prefixes: '" << Prefix << "'\n"; 2584 return false; 2585 } 2586 } 2587 return true; 2588 } 2589 2590 static const char *DefaultCheckPrefixes[] = {"CHECK"}; 2591 static const char *DefaultCommentPrefixes[] = {"COM", "RUN"}; 2592 2593 bool FileCheck::ValidateCheckPrefixes() { 2594 StringSet<> UniquePrefixes; 2595 // Add default prefixes to catch user-supplied duplicates of them below. 2596 if (Req.CheckPrefixes.empty()) { 2597 for (const char *Prefix : DefaultCheckPrefixes) 2598 UniquePrefixes.insert(Prefix); 2599 } 2600 if (Req.CommentPrefixes.empty()) { 2601 for (const char *Prefix : DefaultCommentPrefixes) 2602 UniquePrefixes.insert(Prefix); 2603 } 2604 // Do not validate the default prefixes, or diagnostics about duplicates might 2605 // incorrectly indicate that they were supplied by the user. 2606 if (!ValidatePrefixes("check", UniquePrefixes, Req.CheckPrefixes)) 2607 return false; 2608 if (!ValidatePrefixes("comment", UniquePrefixes, Req.CommentPrefixes)) 2609 return false; 2610 return true; 2611 } 2612 2613 Regex FileCheck::buildCheckPrefixRegex() { 2614 if (Req.CheckPrefixes.empty()) { 2615 for (const char *Prefix : DefaultCheckPrefixes) 2616 Req.CheckPrefixes.push_back(Prefix); 2617 Req.IsDefaultCheckPrefix = true; 2618 } 2619 if (Req.CommentPrefixes.empty()) { 2620 for (const char *Prefix : DefaultCommentPrefixes) 2621 Req.CommentPrefixes.push_back(Prefix); 2622 } 2623 2624 // We already validated the contents of CheckPrefixes and CommentPrefixes so 2625 // just concatenate them as alternatives. 2626 SmallString<32> PrefixRegexStr; 2627 for (size_t I = 0, E = Req.CheckPrefixes.size(); I != E; ++I) { 2628 if (I != 0) 2629 PrefixRegexStr.push_back('|'); 2630 PrefixRegexStr.append(Req.CheckPrefixes[I]); 2631 } 2632 for (StringRef Prefix : Req.CommentPrefixes) { 2633 PrefixRegexStr.push_back('|'); 2634 PrefixRegexStr.append(Prefix); 2635 } 2636 2637 return Regex(PrefixRegexStr); 2638 } 2639 2640 Error FileCheckPatternContext::defineCmdlineVariables( 2641 ArrayRef<StringRef> CmdlineDefines, SourceMgr &SM) { 2642 assert(GlobalVariableTable.empty() && GlobalNumericVariableTable.empty() && 2643 "Overriding defined variable with command-line variable definitions"); 2644 2645 if (CmdlineDefines.empty()) 2646 return Error::success(); 2647 2648 // Create a string representing the vector of command-line definitions. Each 2649 // definition is on its own line and prefixed with a definition number to 2650 // clarify which definition a given diagnostic corresponds to. 2651 unsigned I = 0; 2652 Error Errs = Error::success(); 2653 std::string CmdlineDefsDiag; 2654 SmallVector<std::pair<size_t, size_t>, 4> CmdlineDefsIndices; 2655 for (StringRef CmdlineDef : CmdlineDefines) { 2656 std::string DefPrefix = ("Global define #" + Twine(++I) + ": ").str(); 2657 size_t EqIdx = CmdlineDef.find('='); 2658 if (EqIdx == StringRef::npos) { 2659 CmdlineDefsIndices.push_back(std::make_pair(CmdlineDefsDiag.size(), 0)); 2660 continue; 2661 } 2662 // Numeric variable definition. 2663 if (CmdlineDef[0] == '#') { 2664 // Append a copy of the command-line definition adapted to use the same 2665 // format as in the input file to be able to reuse 2666 // parseNumericSubstitutionBlock. 2667 CmdlineDefsDiag += (DefPrefix + CmdlineDef + " (parsed as: [[").str(); 2668 std::string SubstitutionStr = std::string(CmdlineDef); 2669 SubstitutionStr[EqIdx] = ':'; 2670 CmdlineDefsIndices.push_back( 2671 std::make_pair(CmdlineDefsDiag.size(), SubstitutionStr.size())); 2672 CmdlineDefsDiag += (SubstitutionStr + Twine("]])\n")).str(); 2673 } else { 2674 CmdlineDefsDiag += DefPrefix; 2675 CmdlineDefsIndices.push_back( 2676 std::make_pair(CmdlineDefsDiag.size(), CmdlineDef.size())); 2677 CmdlineDefsDiag += (CmdlineDef + "\n").str(); 2678 } 2679 } 2680 2681 // Create a buffer with fake command line content in order to display 2682 // parsing diagnostic with location information and point to the 2683 // global definition with invalid syntax. 2684 std::unique_ptr<MemoryBuffer> CmdLineDefsDiagBuffer = 2685 MemoryBuffer::getMemBufferCopy(CmdlineDefsDiag, "Global defines"); 2686 StringRef CmdlineDefsDiagRef = CmdLineDefsDiagBuffer->getBuffer(); 2687 SM.AddNewSourceBuffer(std::move(CmdLineDefsDiagBuffer), SMLoc()); 2688 2689 for (std::pair<size_t, size_t> CmdlineDefIndices : CmdlineDefsIndices) { 2690 StringRef CmdlineDef = CmdlineDefsDiagRef.substr(CmdlineDefIndices.first, 2691 CmdlineDefIndices.second); 2692 if (CmdlineDef.empty()) { 2693 Errs = joinErrors( 2694 std::move(Errs), 2695 ErrorDiagnostic::get(SM, CmdlineDef, 2696 "missing equal sign in global definition")); 2697 continue; 2698 } 2699 2700 // Numeric variable definition. 2701 if (CmdlineDef[0] == '#') { 2702 // Now parse the definition both to check that the syntax is correct and 2703 // to create the necessary class instance. 2704 StringRef CmdlineDefExpr = CmdlineDef.substr(1); 2705 Optional<NumericVariable *> DefinedNumericVariable; 2706 Expected<std::unique_ptr<Expression>> ExpressionResult = 2707 Pattern::parseNumericSubstitutionBlock( 2708 CmdlineDefExpr, DefinedNumericVariable, false, None, this, SM); 2709 if (!ExpressionResult) { 2710 Errs = joinErrors(std::move(Errs), ExpressionResult.takeError()); 2711 continue; 2712 } 2713 std::unique_ptr<Expression> Expression = std::move(*ExpressionResult); 2714 // Now evaluate the expression whose value this variable should be set 2715 // to, since the expression of a command-line variable definition should 2716 // only use variables defined earlier on the command-line. If not, this 2717 // is an error and we report it. 2718 Expected<ExpressionValue> Value = Expression->getAST()->eval(); 2719 if (!Value) { 2720 Errs = joinErrors(std::move(Errs), Value.takeError()); 2721 continue; 2722 } 2723 2724 assert(DefinedNumericVariable && "No variable defined"); 2725 (*DefinedNumericVariable)->setValue(*Value); 2726 2727 // Record this variable definition. 2728 GlobalNumericVariableTable[(*DefinedNumericVariable)->getName()] = 2729 *DefinedNumericVariable; 2730 } else { 2731 // String variable definition. 2732 std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('='); 2733 StringRef CmdlineName = CmdlineNameVal.first; 2734 StringRef OrigCmdlineName = CmdlineName; 2735 Expected<Pattern::VariableProperties> ParseVarResult = 2736 Pattern::parseVariable(CmdlineName, SM); 2737 if (!ParseVarResult) { 2738 Errs = joinErrors(std::move(Errs), ParseVarResult.takeError()); 2739 continue; 2740 } 2741 // Check that CmdlineName does not denote a pseudo variable is only 2742 // composed of the parsed numeric variable. This catches cases like 2743 // "FOO+2" in a "FOO+2=10" definition. 2744 if (ParseVarResult->IsPseudo || !CmdlineName.empty()) { 2745 Errs = joinErrors(std::move(Errs), 2746 ErrorDiagnostic::get( 2747 SM, OrigCmdlineName, 2748 "invalid name in string variable definition '" + 2749 OrigCmdlineName + "'")); 2750 continue; 2751 } 2752 StringRef Name = ParseVarResult->Name; 2753 2754 // Detect collisions between string and numeric variables when the former 2755 // is created later than the latter. 2756 if (GlobalNumericVariableTable.find(Name) != 2757 GlobalNumericVariableTable.end()) { 2758 Errs = joinErrors(std::move(Errs), 2759 ErrorDiagnostic::get(SM, Name, 2760 "numeric variable with name '" + 2761 Name + "' already exists")); 2762 continue; 2763 } 2764 GlobalVariableTable.insert(CmdlineNameVal); 2765 // Mark the string variable as defined to detect collisions between 2766 // string and numeric variables in defineCmdlineVariables when the latter 2767 // is created later than the former. We cannot reuse GlobalVariableTable 2768 // for this by populating it with an empty string since we would then 2769 // lose the ability to detect the use of an undefined variable in 2770 // match(). 2771 DefinedVariableTable[Name] = true; 2772 } 2773 } 2774 2775 return Errs; 2776 } 2777 2778 void FileCheckPatternContext::clearLocalVars() { 2779 SmallVector<StringRef, 16> LocalPatternVars, LocalNumericVars; 2780 for (const StringMapEntry<StringRef> &Var : GlobalVariableTable) 2781 if (Var.first()[0] != '$') 2782 LocalPatternVars.push_back(Var.first()); 2783 2784 // Numeric substitution reads the value of a variable directly, not via 2785 // GlobalNumericVariableTable. Therefore, we clear local variables by 2786 // clearing their value which will lead to a numeric substitution failure. We 2787 // also mark the variable for removal from GlobalNumericVariableTable since 2788 // this is what defineCmdlineVariables checks to decide that no global 2789 // variable has been defined. 2790 for (const auto &Var : GlobalNumericVariableTable) 2791 if (Var.first()[0] != '$') { 2792 Var.getValue()->clearValue(); 2793 LocalNumericVars.push_back(Var.first()); 2794 } 2795 2796 for (const auto &Var : LocalPatternVars) 2797 GlobalVariableTable.erase(Var); 2798 for (const auto &Var : LocalNumericVars) 2799 GlobalNumericVariableTable.erase(Var); 2800 } 2801 2802 bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer, 2803 std::vector<FileCheckDiag> *Diags) { 2804 bool ChecksFailed = false; 2805 2806 unsigned i = 0, j = 0, e = CheckStrings->size(); 2807 while (true) { 2808 StringRef CheckRegion; 2809 if (j == e) { 2810 CheckRegion = Buffer; 2811 } else { 2812 const FileCheckString &CheckLabelStr = (*CheckStrings)[j]; 2813 if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) { 2814 ++j; 2815 continue; 2816 } 2817 2818 // Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG 2819 size_t MatchLabelLen = 0; 2820 size_t MatchLabelPos = 2821 CheckLabelStr.Check(SM, Buffer, true, MatchLabelLen, Req, Diags); 2822 if (MatchLabelPos == StringRef::npos) 2823 // Immediately bail if CHECK-LABEL fails, nothing else we can do. 2824 return false; 2825 2826 CheckRegion = Buffer.substr(0, MatchLabelPos + MatchLabelLen); 2827 Buffer = Buffer.substr(MatchLabelPos + MatchLabelLen); 2828 ++j; 2829 } 2830 2831 // Do not clear the first region as it's the one before the first 2832 // CHECK-LABEL and it would clear variables defined on the command-line 2833 // before they get used. 2834 if (i != 0 && Req.EnableVarScope) 2835 PatternContext->clearLocalVars(); 2836 2837 for (; i != j; ++i) { 2838 const FileCheckString &CheckStr = (*CheckStrings)[i]; 2839 2840 // Check each string within the scanned region, including a second check 2841 // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG) 2842 size_t MatchLen = 0; 2843 size_t MatchPos = 2844 CheckStr.Check(SM, CheckRegion, false, MatchLen, Req, Diags); 2845 2846 if (MatchPos == StringRef::npos) { 2847 ChecksFailed = true; 2848 i = j; 2849 break; 2850 } 2851 2852 CheckRegion = CheckRegion.substr(MatchPos + MatchLen); 2853 } 2854 2855 if (j == e) 2856 break; 2857 } 2858 2859 // Success if no checks failed. 2860 return !ChecksFailed; 2861 } 2862