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