diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/FileCheck/FileCheck.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/FileCheck/FileCheck.cpp | 382 |
1 files changed, 187 insertions, 195 deletions
diff --git a/contrib/llvm-project/llvm/lib/FileCheck/FileCheck.cpp b/contrib/llvm-project/llvm/lib/FileCheck/FileCheck.cpp index 3e4514f2545b..b728c14d288a 100644 --- a/contrib/llvm-project/llvm/lib/FileCheck/FileCheck.cpp +++ b/contrib/llvm-project/llvm/lib/FileCheck/FileCheck.cpp @@ -78,18 +78,9 @@ Expected<std::string> ExpressionFormat::getWildcardRegex() const { } Expected<std::string> -ExpressionFormat::getMatchingString(ExpressionValue IntegerValue) const { - APInt IntValue = IntegerValue.getAPIntValue(); - // Error out for values that cannot be represented by the appropriate 64-bit - // integer (e.g. int64_t for a signed format) to keep the getter of - // ExpressionValue as an APInt an NFC. - if (Value == Kind::Signed) { - if (!IntValue.isSignedIntN(64)) - return make_error<OverflowError>(); - } else { - if (!IntValue.isIntN(64)) - return make_error<OverflowError>(); - } +ExpressionFormat::getMatchingString(APInt IntValue) const { + if (Value != Kind::Signed && IntValue.isNegative()) + return make_error<OverflowError>(); unsigned Radix; bool UpperCase = false; @@ -129,140 +120,122 @@ ExpressionFormat::getMatchingString(ExpressionValue IntegerValue) const { .str(); } -Expected<ExpressionValue> -ExpressionFormat::valueFromStringRepr(StringRef StrVal, - const SourceMgr &SM) const { - bool ValueIsSigned = Value == Kind::Signed; - // Both the FileCheck utility and library only call this method with a valid - // value in StrVal. This is guaranteed by the regex returned by - // getWildcardRegex() above. Only underflow and overflow errors can thus - // occur. However new uses of this method could be added in the future so - // the error message does not make assumptions about StrVal. - StringRef IntegerParseErrorStr = "unable to represent numeric value"; - if (ValueIsSigned) { - int64_t SignedValue; - - if (StrVal.getAsInteger(10, SignedValue)) - return ErrorDiagnostic::get(SM, StrVal, IntegerParseErrorStr); +static unsigned nextAPIntBitWidth(unsigned BitWidth) { + return (BitWidth < APInt::APINT_BITS_PER_WORD) ? APInt::APINT_BITS_PER_WORD + : BitWidth * 2; +} - return ExpressionValue(SignedValue); - } +static APInt toSigned(APInt AbsVal, bool Negative) { + if (AbsVal.isSignBitSet()) + AbsVal = AbsVal.zext(nextAPIntBitWidth(AbsVal.getBitWidth())); + APInt Result = AbsVal; + if (Negative) + Result.negate(); + return Result; +} +APInt ExpressionFormat::valueFromStringRepr(StringRef StrVal, + const SourceMgr &SM) const { + bool ValueIsSigned = Value == Kind::Signed; + bool Negative = StrVal.consume_front("-"); bool Hex = Value == Kind::HexUpper || Value == Kind::HexLower; - uint64_t UnsignedValue; - bool MissingFormPrefix = AlternateForm && !StrVal.consume_front("0x"); + bool MissingFormPrefix = + !ValueIsSigned && AlternateForm && !StrVal.consume_front("0x"); (void)MissingFormPrefix; assert(!MissingFormPrefix && "missing alternate form prefix"); - if (StrVal.getAsInteger(Hex ? 16 : 10, UnsignedValue)) - return ErrorDiagnostic::get(SM, StrVal, IntegerParseErrorStr); - - return ExpressionValue(UnsignedValue); + APInt ResultValue; + [[maybe_unused]] bool ParseFailure = + StrVal.getAsInteger(Hex ? 16 : 10, ResultValue); + // Both the FileCheck utility and library only call this method with a valid + // value in StrVal. This is guaranteed by the regex returned by + // getWildcardRegex() above. + assert(!ParseFailure && "unable to represent numeric value"); + return toSigned(ResultValue, Negative); } -Expected<ExpressionValue> llvm::operator+(const ExpressionValue &LeftOperand, - const ExpressionValue &RightOperand) { - bool Overflow; - APInt Result = LeftOperand.getAPIntValue().sadd_ov( - RightOperand.getAPIntValue(), Overflow); - if (Overflow || - (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) - return make_error<OverflowError>(); - - if (Result.isNegative()) - return ExpressionValue(Result.getSExtValue()); - else - return ExpressionValue(Result.getZExtValue()); +Expected<APInt> llvm::exprAdd(const APInt &LeftOperand, + const APInt &RightOperand, bool &Overflow) { + return LeftOperand.sadd_ov(RightOperand, Overflow); } -Expected<ExpressionValue> llvm::operator-(const ExpressionValue &LeftOperand, - const ExpressionValue &RightOperand) { - bool Overflow; - APInt Result = LeftOperand.getAPIntValue().ssub_ov( - RightOperand.getAPIntValue(), Overflow); - if (Overflow || - (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) - return make_error<OverflowError>(); - - if (Result.isNegative()) - return ExpressionValue(Result.getSExtValue()); - else - return ExpressionValue(Result.getZExtValue()); +Expected<APInt> llvm::exprSub(const APInt &LeftOperand, + const APInt &RightOperand, bool &Overflow) { + return LeftOperand.ssub_ov(RightOperand, Overflow); } -Expected<ExpressionValue> llvm::operator*(const ExpressionValue &LeftOperand, - const ExpressionValue &RightOperand) { - bool Overflow; - APInt Result = LeftOperand.getAPIntValue().smul_ov( - RightOperand.getAPIntValue(), Overflow); - if (Overflow || - (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) - return make_error<OverflowError>(); - - if (Result.isNegative()) - return ExpressionValue(Result.getSExtValue()); - else - return ExpressionValue(Result.getZExtValue()); +Expected<APInt> llvm::exprMul(const APInt &LeftOperand, + const APInt &RightOperand, bool &Overflow) { + return LeftOperand.smul_ov(RightOperand, Overflow); } -Expected<ExpressionValue> llvm::operator/(const ExpressionValue &LeftOperand, - const ExpressionValue &RightOperand) { +Expected<APInt> llvm::exprDiv(const APInt &LeftOperand, + const APInt &RightOperand, bool &Overflow) { // Check for division by zero. - if (RightOperand.getAPIntValue().isZero()) + if (RightOperand.isZero()) return make_error<OverflowError>(); - bool Overflow; - APInt Result = LeftOperand.getAPIntValue().sdiv_ov( - RightOperand.getAPIntValue(), Overflow); - if (Overflow || - (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) - return make_error<OverflowError>(); - - if (Result.isNegative()) - return ExpressionValue(Result.getSExtValue()); - else - return ExpressionValue(Result.getZExtValue()); + return LeftOperand.sdiv_ov(RightOperand, Overflow); } -Expected<ExpressionValue> llvm::max(const ExpressionValue &LeftOperand, - const ExpressionValue &RightOperand) { - return LeftOperand.getAPIntValue().slt(RightOperand.getAPIntValue()) - ? RightOperand - : LeftOperand; +Expected<APInt> llvm::exprMax(const APInt &LeftOperand, + const APInt &RightOperand, bool &Overflow) { + Overflow = false; + return LeftOperand.slt(RightOperand) ? RightOperand : LeftOperand; } -Expected<ExpressionValue> llvm::min(const ExpressionValue &LeftOperand, - const ExpressionValue &RightOperand) { - if (cantFail(max(LeftOperand, RightOperand)).getAPIntValue() == - LeftOperand.getAPIntValue()) +Expected<APInt> llvm::exprMin(const APInt &LeftOperand, + const APInt &RightOperand, bool &Overflow) { + Overflow = false; + if (cantFail(exprMax(LeftOperand, RightOperand, Overflow)) == LeftOperand) return RightOperand; return LeftOperand; } -Expected<ExpressionValue> NumericVariableUse::eval() const { - std::optional<ExpressionValue> Value = Variable->getValue(); +Expected<APInt> NumericVariableUse::eval() const { + std::optional<APInt> Value = Variable->getValue(); if (Value) return *Value; return make_error<UndefVarError>(getExpressionStr()); } -Expected<ExpressionValue> BinaryOperation::eval() const { - Expected<ExpressionValue> LeftOp = LeftOperand->eval(); - Expected<ExpressionValue> RightOp = RightOperand->eval(); +Expected<APInt> BinaryOperation::eval() const { + Expected<APInt> MaybeLeftOp = LeftOperand->eval(); + Expected<APInt> MaybeRightOp = RightOperand->eval(); // Bubble up any error (e.g. undefined variables) in the recursive // evaluation. - if (!LeftOp || !RightOp) { + if (!MaybeLeftOp || !MaybeRightOp) { Error Err = Error::success(); - if (!LeftOp) - Err = joinErrors(std::move(Err), LeftOp.takeError()); - if (!RightOp) - Err = joinErrors(std::move(Err), RightOp.takeError()); + if (!MaybeLeftOp) + Err = joinErrors(std::move(Err), MaybeLeftOp.takeError()); + if (!MaybeRightOp) + Err = joinErrors(std::move(Err), MaybeRightOp.takeError()); return std::move(Err); } - return EvalBinop(*LeftOp, *RightOp); + APInt LeftOp = *MaybeLeftOp; + APInt RightOp = *MaybeRightOp; + bool Overflow; + // Ensure both operands have the same bitwidth. + unsigned LeftBitWidth = LeftOp.getBitWidth(); + unsigned RightBitWidth = RightOp.getBitWidth(); + unsigned NewBitWidth = std::max(LeftBitWidth, RightBitWidth); + LeftOp = LeftOp.sext(NewBitWidth); + RightOp = RightOp.sext(NewBitWidth); + do { + Expected<APInt> MaybeResult = EvalBinop(LeftOp, RightOp, Overflow); + if (!MaybeResult) + return MaybeResult.takeError(); + + if (!Overflow) + return MaybeResult; + + NewBitWidth = nextAPIntBitWidth(NewBitWidth); + LeftOp = LeftOp.sext(NewBitWidth); + RightOp = RightOp.sext(NewBitWidth); + } while (true); } Expected<ExpressionFormat> @@ -295,8 +268,7 @@ BinaryOperation::getImplicitFormat(const SourceMgr &SM) const { Expected<std::string> NumericSubstitution::getResult() const { assert(ExpressionPointer->getAST() != nullptr && "Substituting empty expression"); - Expected<ExpressionValue> EvaluatedValue = - ExpressionPointer->getAST()->eval(); + Expected<APInt> EvaluatedValue = ExpressionPointer->getAST()->eval(); if (!EvaluatedValue) return EvaluatedValue.takeError(); ExpressionFormat Format = ExpressionPointer->getFormat(); @@ -432,7 +404,7 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand( StringRef &Expr, AllowedOperand AO, bool MaybeInvalidConstraint, std::optional<size_t> LineNumber, FileCheckPatternContext *Context, const SourceMgr &SM) { - if (Expr.startswith("(")) { + if (Expr.starts_with("(")) { if (AO != AllowedOperand::Any) return ErrorDiagnostic::get( SM, Expr, "parenthesized expression not permitted here"); @@ -445,7 +417,7 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand( parseVariable(Expr, SM); if (ParseVarResult) { // Try to parse a function call. - if (Expr.ltrim(SpaceChars).startswith("(")) { + if (Expr.ltrim(SpaceChars).starts_with("(")) { if (AO != AllowedOperand::Any) return ErrorDiagnostic::get(SM, ParseVarResult->Name, "unexpected function call"); @@ -466,21 +438,17 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand( } // Otherwise, parse it as a literal. - int64_t SignedLiteralValue; - uint64_t UnsignedLiteralValue; + APInt LiteralValue; StringRef SaveExpr = Expr; - // Accept both signed and unsigned literal, default to signed literal. + bool Negative = Expr.consume_front("-"); if (!Expr.consumeInteger((AO == AllowedOperand::LegacyLiteral) ? 10 : 0, - UnsignedLiteralValue)) + LiteralValue)) { + LiteralValue = toSigned(LiteralValue, Negative); return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()), - UnsignedLiteralValue); - Expr = SaveExpr; - if (AO == AllowedOperand::Any && !Expr.consumeInteger(0, SignedLiteralValue)) - return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()), - SignedLiteralValue); - + LiteralValue); + } return ErrorDiagnostic::get( - SM, Expr, + SM, SaveExpr, Twine("invalid ") + (MaybeInvalidConstraint ? "matching constraint or " : "") + "operand format"); @@ -490,7 +458,7 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseParenExpr(StringRef &Expr, std::optional<size_t> LineNumber, FileCheckPatternContext *Context, const SourceMgr &SM) { Expr = Expr.ltrim(SpaceChars); - assert(Expr.startswith("(")); + assert(Expr.starts_with("(")); // Parse right operand. Expr.consume_front("("); @@ -503,7 +471,7 @@ Pattern::parseParenExpr(StringRef &Expr, std::optional<size_t> LineNumber, Expr, AllowedOperand::Any, /*MaybeInvalidConstraint=*/false, LineNumber, Context, SM); Expr = Expr.ltrim(SpaceChars); - while (SubExprResult && !Expr.empty() && !Expr.startswith(")")) { + while (SubExprResult && !Expr.empty() && !Expr.starts_with(")")) { StringRef OrigExpr = Expr; SubExprResult = parseBinop(OrigExpr, Expr, std::move(*SubExprResult), false, LineNumber, Context, SM); @@ -535,10 +503,10 @@ Pattern::parseBinop(StringRef Expr, StringRef &RemainingExpr, binop_eval_t EvalBinop; switch (Operator) { case '+': - EvalBinop = operator+; + EvalBinop = exprAdd; break; case '-': - EvalBinop = operator-; + EvalBinop = exprSub; break; default: return ErrorDiagnostic::get( @@ -569,15 +537,15 @@ Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName, std::optional<size_t> LineNumber, FileCheckPatternContext *Context, const SourceMgr &SM) { Expr = Expr.ltrim(SpaceChars); - assert(Expr.startswith("(")); + assert(Expr.starts_with("(")); auto OptFunc = StringSwitch<binop_eval_t>(FuncName) - .Case("add", operator+) - .Case("div", operator/) - .Case("max", max) - .Case("min", min) - .Case("mul", operator*) - .Case("sub", operator-) + .Case("add", exprAdd) + .Case("div", exprDiv) + .Case("max", exprMax) + .Case("min", exprMin) + .Case("mul", exprMul) + .Case("sub", exprSub) .Default(nullptr); if (!OptFunc) @@ -589,8 +557,8 @@ Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName, // Parse call arguments, which are comma separated. SmallVector<std::unique_ptr<ExpressionAST>, 4> Args; - while (!Expr.empty() && !Expr.startswith(")")) { - if (Expr.startswith(",")) + while (!Expr.empty() && !Expr.starts_with(")")) { + if (Expr.starts_with(",")) return ErrorDiagnostic::get(SM, Expr, "missing argument"); // Parse the argument, which is an arbitary expression. @@ -601,7 +569,7 @@ Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName, while (Arg && !Expr.empty()) { Expr = Expr.ltrim(SpaceChars); // Have we reached an argument terminator? - if (Expr.startswith(",") || Expr.startswith(")")) + if (Expr.starts_with(",") || Expr.starts_with(")")) break; // Arg = Arg <op> <expr> @@ -620,7 +588,7 @@ Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName, break; Expr = Expr.ltrim(SpaceChars); - if (Expr.startswith(")")) + if (Expr.starts_with(")")) return ErrorDiagnostic::get(SM, Expr, "missing argument"); } @@ -850,7 +818,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, // by escaping scary characters in fixed strings, building up one big regex. while (!PatternStr.empty()) { // RegEx matches. - if (PatternStr.startswith("{{")) { + if (PatternStr.starts_with("{{")) { // This is the start of a regex match. Scan for the }}. size_t End = PatternStr.find("}}"); if (End == StringRef::npos) { @@ -864,12 +832,16 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, // capturing the result for any purpose. This is required in case the // expression contains an alternation like: CHECK: abc{{x|z}}def. We // want this to turn into: "abc(x|z)def" not "abcx|zdef". - RegExStr += '('; - ++CurParen; + bool HasAlternation = PatternStr.contains('|'); + if (HasAlternation) { + RegExStr += '('; + ++CurParen; + } if (AddRegExToRegEx(PatternStr.substr(2, End - 2), CurParen, SM)) return true; - RegExStr += ')'; + if (HasAlternation) + RegExStr += ')'; PatternStr = PatternStr.substr(End + 2); continue; @@ -885,7 +857,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, // names must satisfy the regular expression "[a-zA-Z_][0-9a-zA-Z_]*" to be // valid, as this helps catch some common errors. If there are extra '['s // before the "[[", treat them literally. - if (PatternStr.startswith("[[") && !PatternStr.startswith("[[[")) { + if (PatternStr.starts_with("[[") && !PatternStr.starts_with("[[[")) { StringRef UnparsedPatternStr = PatternStr.substr(2); // Find the closing bracket pair ending the match. End is going to be an // offset relative to the beginning of the match string. @@ -1124,7 +1096,8 @@ Pattern::MatchResult Pattern::match(StringRef Buffer, if (!Substitutions.empty()) { TmpStr = RegExStr; if (LineNumber) - Context->LineVariable->setValue(ExpressionValue(*LineNumber)); + Context->LineVariable->setValue( + APInt(sizeof(*LineNumber) * 8, *LineNumber)); size_t InsertOffset = 0; // Substitute all string variables and expressions whose values are only @@ -1203,11 +1176,8 @@ Pattern::MatchResult Pattern::match(StringRef Buffer, StringRef MatchedValue = MatchInfo[CaptureParenGroup]; ExpressionFormat Format = DefinedNumericVariable->getImplicitFormat(); - Expected<ExpressionValue> Value = - Format.valueFromStringRepr(MatchedValue, SM); - if (!Value) - return MatchResult(TheMatch, Value.takeError()); - DefinedNumericVariable->setValue(*Value, MatchedValue); + APInt Value = Format.valueFromStringRepr(MatchedValue, SM); + DefinedNumericVariable->setValue(Value, MatchedValue); } return MatchResult(TheMatch, Error::success()); @@ -1422,7 +1392,7 @@ size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) { size_t BracketDepth = 0; while (!Str.empty()) { - if (Str.startswith("]]") && BracketDepth == 0) + if (Str.starts_with("]]") && BracketDepth == 0) return Offset; if (Str[0] == '\\') { // Backslash escapes the next char within regexes, so skip them both. @@ -1621,10 +1591,10 @@ FindCheckType(const FileCheckRequest &Req, StringRef Buffer, StringRef Prefix, } // You can't combine -NOT with another suffix. - if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") || - Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") || - Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") || - Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:")) + if (Rest.starts_with("DAG-NOT:") || Rest.starts_with("NOT-DAG:") || + Rest.starts_with("NEXT-NOT:") || Rest.starts_with("NOT-NEXT:") || + Rest.starts_with("SAME-NOT:") || Rest.starts_with("NOT-SAME:") || + Rest.starts_with("EMPTY-NOT:") || Rest.starts_with("NOT-EMPTY:")) return {Check::CheckBadNot, Rest}; if (Rest.consume_front("NEXT")) @@ -1664,6 +1634,60 @@ static size_t SkipWord(StringRef Str, size_t Loc) { return Loc; } +static const char *DefaultCheckPrefixes[] = {"CHECK"}; +static const char *DefaultCommentPrefixes[] = {"COM", "RUN"}; + +static void addDefaultPrefixes(FileCheckRequest &Req) { + if (Req.CheckPrefixes.empty()) { + for (const char *Prefix : DefaultCheckPrefixes) + Req.CheckPrefixes.push_back(Prefix); + Req.IsDefaultCheckPrefix = true; + } + if (Req.CommentPrefixes.empty()) + for (const char *Prefix : DefaultCommentPrefixes) + Req.CommentPrefixes.push_back(Prefix); +} + +struct PrefixMatcher { + /// Prefixes and their first occurrence past the current position. + SmallVector<std::pair<StringRef, size_t>> Prefixes; + StringRef Input; + + PrefixMatcher(ArrayRef<StringRef> CheckPrefixes, + ArrayRef<StringRef> CommentPrefixes, StringRef Input) + : Input(Input) { + for (StringRef Prefix : CheckPrefixes) + Prefixes.push_back({Prefix, Input.find(Prefix)}); + for (StringRef Prefix : CommentPrefixes) + Prefixes.push_back({Prefix, Input.find(Prefix)}); + + // Sort by descending length. + llvm::sort(Prefixes, + [](auto A, auto B) { return A.first.size() > B.first.size(); }); + } + + /// Find the next match of a prefix in Buffer. + /// Returns empty StringRef if not found. + StringRef match(StringRef Buffer) { + assert(Buffer.data() >= Input.data() && + Buffer.data() + Buffer.size() == Input.data() + Input.size() && + "Buffer must be suffix of Input"); + + size_t From = Buffer.data() - Input.data(); + StringRef Match; + for (auto &[Prefix, Pos] : Prefixes) { + // If the last occurrence was before From, find the next one after From. + if (Pos < From) + Pos = Input.find(Prefix, From); + // Find the first prefix with the lowest position. + if (Pos != StringRef::npos && + (Match.empty() || size_t(Match.data() - Input.data()) > Pos)) + Match = StringRef(Input.substr(Pos, Prefix.size())); + } + return Match; + } +}; + /// Searches the buffer for the first prefix in the prefix regular expression. /// /// This searches the buffer using the provided regular expression, however it @@ -1688,20 +1712,16 @@ static size_t SkipWord(StringRef Str, size_t Loc) { /// If no valid prefix is found, the state of Buffer, LineNumber, and CheckTy /// is unspecified. static std::pair<StringRef, StringRef> -FindFirstMatchingPrefix(const FileCheckRequest &Req, Regex &PrefixRE, +FindFirstMatchingPrefix(const FileCheckRequest &Req, PrefixMatcher &Matcher, StringRef &Buffer, unsigned &LineNumber, Check::FileCheckType &CheckTy) { - SmallVector<StringRef, 2> Matches; - while (!Buffer.empty()) { - // Find the first (longest) match using the RE. - if (!PrefixRE.match(Buffer, &Matches)) + // Find the first (longest) prefix match. + StringRef Prefix = Matcher.match(Buffer); + if (Prefix.empty()) // No match at all, bail. return {StringRef(), StringRef()}; - StringRef Prefix = Matches[0]; - Matches.clear(); - assert(Prefix.data() >= Buffer.data() && Prefix.data() < Buffer.data() + Buffer.size() && "Prefix doesn't start inside of buffer!"); @@ -1750,7 +1770,7 @@ FileCheck::FileCheck(FileCheckRequest Req) FileCheck::~FileCheck() = default; bool FileCheck::readCheckFile( - SourceMgr &SM, StringRef Buffer, Regex &PrefixRE, + SourceMgr &SM, StringRef Buffer, std::pair<unsigned, unsigned> *ImpPatBufferIDRange) { if (ImpPatBufferIDRange) ImpPatBufferIDRange->first = ImpPatBufferIDRange->second = 0; @@ -1799,6 +1819,8 @@ bool FileCheck::readCheckFile( // found. unsigned LineNumber = 1; + addDefaultPrefixes(Req); + PrefixMatcher Matcher(Req.CheckPrefixes, Req.CommentPrefixes, Buffer); std::set<StringRef> PrefixesNotFound(Req.CheckPrefixes.begin(), Req.CheckPrefixes.end()); const size_t DistinctPrefixes = PrefixesNotFound.size(); @@ -1809,7 +1831,7 @@ bool FileCheck::readCheckFile( StringRef UsedPrefix; StringRef AfterSuffix; std::tie(UsedPrefix, AfterSuffix) = - FindFirstMatchingPrefix(Req, PrefixRE, Buffer, LineNumber, CheckTy); + FindFirstMatchingPrefix(Req, Matcher, Buffer, LineNumber, CheckTy); if (UsedPrefix.empty()) break; if (CheckTy != Check::CheckComment) @@ -2461,9 +2483,6 @@ static bool ValidatePrefixes(StringRef Kind, StringSet<> &UniquePrefixes, return true; } -static const char *DefaultCheckPrefixes[] = {"CHECK"}; -static const char *DefaultCommentPrefixes[] = {"COM", "RUN"}; - bool FileCheck::ValidateCheckPrefixes() { StringSet<> UniquePrefixes; // Add default prefixes to catch user-supplied duplicates of them below. @@ -2484,33 +2503,6 @@ bool FileCheck::ValidateCheckPrefixes() { return true; } -Regex FileCheck::buildCheckPrefixRegex() { - if (Req.CheckPrefixes.empty()) { - for (const char *Prefix : DefaultCheckPrefixes) - Req.CheckPrefixes.push_back(Prefix); - Req.IsDefaultCheckPrefix = true; - } - if (Req.CommentPrefixes.empty()) { - for (const char *Prefix : DefaultCommentPrefixes) - Req.CommentPrefixes.push_back(Prefix); - } - - // We already validated the contents of CheckPrefixes and CommentPrefixes so - // just concatenate them as alternatives. - SmallString<32> PrefixRegexStr; - for (size_t I = 0, E = Req.CheckPrefixes.size(); I != E; ++I) { - if (I != 0) - PrefixRegexStr.push_back('|'); - PrefixRegexStr.append(Req.CheckPrefixes[I]); - } - for (StringRef Prefix : Req.CommentPrefixes) { - PrefixRegexStr.push_back('|'); - PrefixRegexStr.append(Prefix); - } - - return Regex(PrefixRegexStr); -} - Error FileCheckPatternContext::defineCmdlineVariables( ArrayRef<StringRef> CmdlineDefines, SourceMgr &SM) { assert(GlobalVariableTable.empty() && GlobalNumericVariableTable.empty() && @@ -2590,7 +2582,7 @@ Error FileCheckPatternContext::defineCmdlineVariables( // to, since the expression of a command-line variable definition should // only use variables defined earlier on the command-line. If not, this // is an error and we report it. - Expected<ExpressionValue> Value = Expression->getAST()->eval(); + Expected<APInt> Value = Expression->getAST()->eval(); if (!Value) { Errs = joinErrors(std::move(Errs), Value.takeError()); continue; |
