mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 04:29:42 +00:00
[FileCheck] Remove FileCheck prefix in API
Summary: When FileCheck was made a library, types in the public API were renamed to add a FileCheck prefix, such as Pattern to FileCheckPattern. Many types were moved into a private interface and thus don't need this prefix anymore. This commit removes those unneeded prefixes. Reviewers: jhenderson, jdenny, probinson, grimar, arichardson, rnk Reviewed By: jhenderson Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D72186
This commit is contained in:
parent
24ee4edee8
commit
d8fd92eaaa
@ -25,15 +25,15 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
Expected<uint64_t> FileCheckNumericVariableUse::eval() const {
|
||||
Optional<uint64_t> Value = NumericVariable->getValue();
|
||||
Expected<uint64_t> NumericVariableUse::eval() const {
|
||||
Optional<uint64_t> Value = Variable->getValue();
|
||||
if (Value)
|
||||
return *Value;
|
||||
|
||||
return make_error<FileCheckUndefVarError>(Name);
|
||||
return make_error<UndefVarError>(Name);
|
||||
}
|
||||
|
||||
Expected<uint64_t> FileCheckASTBinop::eval() const {
|
||||
Expected<uint64_t> BinaryOperation::eval() const {
|
||||
Expected<uint64_t> LeftOp = LeftOperand->eval();
|
||||
Expected<uint64_t> RightOp = RightOperand->eval();
|
||||
|
||||
@ -51,14 +51,14 @@ Expected<uint64_t> FileCheckASTBinop::eval() const {
|
||||
return EvalBinop(*LeftOp, *RightOp);
|
||||
}
|
||||
|
||||
Expected<std::string> FileCheckNumericSubstitution::getResult() const {
|
||||
Expected<uint64_t> EvaluatedValue = ExpressionAST->eval();
|
||||
Expected<std::string> NumericSubstitution::getResult() const {
|
||||
Expected<uint64_t> EvaluatedValue = ExpressionASTPointer->eval();
|
||||
if (!EvaluatedValue)
|
||||
return EvaluatedValue.takeError();
|
||||
return utostr(*EvaluatedValue);
|
||||
}
|
||||
|
||||
Expected<std::string> FileCheckStringSubstitution::getResult() const {
|
||||
Expected<std::string> StringSubstitution::getResult() const {
|
||||
// Look up the value and escape it so that we can put it into the regex.
|
||||
Expected<StringRef> VarVal = Context->getPatternVarValue(FromStr);
|
||||
if (!VarVal)
|
||||
@ -66,14 +66,12 @@ Expected<std::string> FileCheckStringSubstitution::getResult() const {
|
||||
return Regex::escape(*VarVal);
|
||||
}
|
||||
|
||||
bool FileCheckPattern::isValidVarNameStart(char C) {
|
||||
return C == '_' || isalpha(C);
|
||||
}
|
||||
bool Pattern::isValidVarNameStart(char C) { return C == '_' || isalpha(C); }
|
||||
|
||||
Expected<FileCheckPattern::VariableProperties>
|
||||
FileCheckPattern::parseVariable(StringRef &Str, const SourceMgr &SM) {
|
||||
Expected<Pattern::VariableProperties>
|
||||
Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) {
|
||||
if (Str.empty())
|
||||
return FileCheckErrorDiagnostic::get(SM, Str, "empty variable name");
|
||||
return ErrorDiagnostic::get(SM, Str, "empty variable name");
|
||||
|
||||
bool ParsedOneChar = false;
|
||||
unsigned I = 0;
|
||||
@ -85,7 +83,7 @@ FileCheckPattern::parseVariable(StringRef &Str, const SourceMgr &SM) {
|
||||
|
||||
for (unsigned E = Str.size(); I != E; ++I) {
|
||||
if (!ParsedOneChar && !isValidVarNameStart(Str[I]))
|
||||
return FileCheckErrorDiagnostic::get(SM, Str, "invalid variable name");
|
||||
return ErrorDiagnostic::get(SM, Str, "invalid variable name");
|
||||
|
||||
// Variable names are composed of alphanumeric characters and underscores.
|
||||
if (Str[I] != '_' && !isalnum(Str[I]))
|
||||
@ -109,12 +107,11 @@ static char popFront(StringRef &S) {
|
||||
return C;
|
||||
}
|
||||
|
||||
char FileCheckUndefVarError::ID = 0;
|
||||
char FileCheckErrorDiagnostic::ID = 0;
|
||||
char FileCheckNotFoundError::ID = 0;
|
||||
char UndefVarError::ID = 0;
|
||||
char ErrorDiagnostic::ID = 0;
|
||||
char NotFoundError::ID = 0;
|
||||
|
||||
Expected<FileCheckNumericVariable *>
|
||||
FileCheckPattern::parseNumericVariableDefinition(
|
||||
Expected<NumericVariable *> Pattern::parseNumericVariableDefinition(
|
||||
StringRef &Expr, FileCheckPatternContext *Context,
|
||||
Optional<size_t> LineNumber, const SourceMgr &SM) {
|
||||
Expected<VariableProperties> ParseVarResult = parseVariable(Expr, SM);
|
||||
@ -123,22 +120,22 @@ FileCheckPattern::parseNumericVariableDefinition(
|
||||
StringRef Name = ParseVarResult->Name;
|
||||
|
||||
if (ParseVarResult->IsPseudo)
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
return ErrorDiagnostic::get(
|
||||
SM, Name, "definition of pseudo numeric variable unsupported");
|
||||
|
||||
// Detect collisions between string and numeric variables when the latter
|
||||
// is created later than the former.
|
||||
if (Context->DefinedVariableTable.find(Name) !=
|
||||
Context->DefinedVariableTable.end())
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
return ErrorDiagnostic::get(
|
||||
SM, Name, "string variable with name '" + Name + "' already exists");
|
||||
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
if (!Expr.empty())
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
return ErrorDiagnostic::get(
|
||||
SM, Expr, "unexpected characters after numeric variable name");
|
||||
|
||||
FileCheckNumericVariable *DefinedNumericVariable;
|
||||
NumericVariable *DefinedNumericVariable;
|
||||
auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
|
||||
if (VarTableIter != Context->GlobalNumericVariableTable.end())
|
||||
DefinedNumericVariable = VarTableIter->second;
|
||||
@ -148,13 +145,11 @@ FileCheckPattern::parseNumericVariableDefinition(
|
||||
return DefinedNumericVariable;
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<FileCheckNumericVariableUse>>
|
||||
FileCheckPattern::parseNumericVariableUse(StringRef Name, bool IsPseudo,
|
||||
Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context,
|
||||
const SourceMgr &SM) {
|
||||
Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse(
|
||||
StringRef Name, bool IsPseudo, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM) {
|
||||
if (IsPseudo && !Name.equals("@LINE"))
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
return ErrorDiagnostic::get(
|
||||
SM, Name, "invalid pseudo numeric variable '" + Name + "'");
|
||||
|
||||
// Numeric variable definitions and uses are parsed in the order in which
|
||||
@ -166,7 +161,7 @@ FileCheckPattern::parseNumericVariableUse(StringRef Name, bool IsPseudo,
|
||||
// uses of undefined variables, whether string or numeric, are then diagnosed
|
||||
// in printSubstitutions() after failing to match.
|
||||
auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
|
||||
FileCheckNumericVariable *NumericVariable;
|
||||
NumericVariable *NumericVariable;
|
||||
if (VarTableIter != Context->GlobalNumericVariableTable.end())
|
||||
NumericVariable = VarTableIter->second;
|
||||
else {
|
||||
@ -176,22 +171,20 @@ FileCheckPattern::parseNumericVariableUse(StringRef Name, bool IsPseudo,
|
||||
|
||||
Optional<size_t> DefLineNumber = NumericVariable->getDefLineNumber();
|
||||
if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber)
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
return ErrorDiagnostic::get(
|
||||
SM, Name,
|
||||
"numeric variable '" + Name +
|
||||
"' defined earlier in the same CHECK directive");
|
||||
|
||||
return std::make_unique<FileCheckNumericVariableUse>(Name, NumericVariable);
|
||||
return std::make_unique<NumericVariableUse>(Name, NumericVariable);
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>>
|
||||
FileCheckPattern::parseNumericOperand(StringRef &Expr, AllowedOperand AO,
|
||||
Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context,
|
||||
const SourceMgr &SM) {
|
||||
Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
|
||||
StringRef &Expr, AllowedOperand AO, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM) {
|
||||
if (AO == AllowedOperand::LineVar || AO == AllowedOperand::Any) {
|
||||
// Try to parse as a numeric variable use.
|
||||
Expected<FileCheckPattern::VariableProperties> ParseVarResult =
|
||||
Expected<Pattern::VariableProperties> ParseVarResult =
|
||||
parseVariable(Expr, SM);
|
||||
if (ParseVarResult)
|
||||
return parseNumericVariableUse(ParseVarResult->Name,
|
||||
@ -206,10 +199,10 @@ FileCheckPattern::parseNumericOperand(StringRef &Expr, AllowedOperand AO,
|
||||
// Otherwise, parse it as a literal.
|
||||
uint64_t LiteralValue;
|
||||
if (!Expr.consumeInteger(/*Radix=*/10, LiteralValue))
|
||||
return std::make_unique<FileCheckExpressionLiteral>(LiteralValue);
|
||||
return std::make_unique<ExpressionLiteral>(LiteralValue);
|
||||
|
||||
return FileCheckErrorDiagnostic::get(SM, Expr,
|
||||
"invalid operand format '" + Expr + "'");
|
||||
return ErrorDiagnostic::get(SM, Expr,
|
||||
"invalid operand format '" + Expr + "'");
|
||||
}
|
||||
|
||||
static uint64_t add(uint64_t LeftOp, uint64_t RightOp) {
|
||||
@ -220,10 +213,10 @@ static uint64_t sub(uint64_t LeftOp, uint64_t RightOp) {
|
||||
return LeftOp - RightOp;
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>> FileCheckPattern::parseBinop(
|
||||
StringRef &Expr, std::unique_ptr<FileCheckExpressionAST> LeftOp,
|
||||
bool IsLegacyLineExpr, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM) {
|
||||
Expected<std::unique_ptr<ExpressionAST>>
|
||||
Pattern::parseBinop(StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp,
|
||||
bool IsLegacyLineExpr, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM) {
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
if (Expr.empty())
|
||||
return std::move(LeftOp);
|
||||
@ -241,35 +234,32 @@ Expected<std::unique_ptr<FileCheckExpressionAST>> FileCheckPattern::parseBinop(
|
||||
EvalBinop = sub;
|
||||
break;
|
||||
default:
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
return ErrorDiagnostic::get(
|
||||
SM, OpLoc, Twine("unsupported operation '") + Twine(Operator) + "'");
|
||||
}
|
||||
|
||||
// Parse right operand.
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
if (Expr.empty())
|
||||
return FileCheckErrorDiagnostic::get(SM, Expr,
|
||||
"missing operand in expression");
|
||||
return ErrorDiagnostic::get(SM, Expr, "missing operand in expression");
|
||||
// The second operand in a legacy @LINE expression is always a literal.
|
||||
AllowedOperand AO =
|
||||
IsLegacyLineExpr ? AllowedOperand::Literal : AllowedOperand::Any;
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>> RightOpResult =
|
||||
Expected<std::unique_ptr<ExpressionAST>> RightOpResult =
|
||||
parseNumericOperand(Expr, AO, LineNumber, Context, SM);
|
||||
if (!RightOpResult)
|
||||
return RightOpResult;
|
||||
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
return std::make_unique<FileCheckASTBinop>(EvalBinop, std::move(LeftOp),
|
||||
std::move(*RightOpResult));
|
||||
return std::make_unique<BinaryOperation>(EvalBinop, std::move(LeftOp),
|
||||
std::move(*RightOpResult));
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>>
|
||||
FileCheckPattern::parseNumericSubstitutionBlock(
|
||||
StringRef Expr,
|
||||
Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
|
||||
Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericSubstitutionBlock(
|
||||
StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable,
|
||||
bool IsLegacyLineExpr, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM) {
|
||||
std::unique_ptr<FileCheckExpressionAST> ExpressionAST = nullptr;
|
||||
std::unique_ptr<ExpressionAST> ExpressionASTPointer = nullptr;
|
||||
StringRef DefExpr = StringRef();
|
||||
DefinedNumericVariable = None;
|
||||
// Save variable definition expression if any.
|
||||
@ -286,26 +276,26 @@ FileCheckPattern::parseNumericSubstitutionBlock(
|
||||
// pseudo variable.
|
||||
AllowedOperand AO =
|
||||
IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>> ParseResult =
|
||||
Expected<std::unique_ptr<ExpressionAST>> ParseResult =
|
||||
parseNumericOperand(Expr, AO, LineNumber, Context, SM);
|
||||
while (ParseResult && !Expr.empty()) {
|
||||
ParseResult = parseBinop(Expr, std::move(*ParseResult), IsLegacyLineExpr,
|
||||
LineNumber, Context, SM);
|
||||
// Legacy @LINE expressions only allow 2 operands.
|
||||
if (ParseResult && IsLegacyLineExpr && !Expr.empty())
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
return ErrorDiagnostic::get(
|
||||
SM, Expr,
|
||||
"unexpected characters at end of expression '" + Expr + "'");
|
||||
}
|
||||
if (!ParseResult)
|
||||
return ParseResult;
|
||||
ExpressionAST = std::move(*ParseResult);
|
||||
ExpressionASTPointer = std::move(*ParseResult);
|
||||
}
|
||||
|
||||
// Parse the numeric variable definition.
|
||||
if (DefEnd != StringRef::npos) {
|
||||
DefExpr = DefExpr.ltrim(SpaceChars);
|
||||
Expected<FileCheckNumericVariable *> ParseResult =
|
||||
Expected<NumericVariable *> ParseResult =
|
||||
parseNumericVariableDefinition(DefExpr, Context, LineNumber, SM);
|
||||
|
||||
if (!ParseResult)
|
||||
@ -313,12 +303,11 @@ FileCheckPattern::parseNumericSubstitutionBlock(
|
||||
DefinedNumericVariable = *ParseResult;
|
||||
}
|
||||
|
||||
return std::move(ExpressionAST);
|
||||
return std::move(ExpressionASTPointer);
|
||||
}
|
||||
|
||||
bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
SourceMgr &SM,
|
||||
const FileCheckRequest &Req) {
|
||||
bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
SourceMgr &SM, const FileCheckRequest &Req) {
|
||||
bool MatchFullLinesHere = Req.MatchFullLines && CheckTy != Check::CheckNot;
|
||||
IgnoreCase = Req.IgnoreCase;
|
||||
|
||||
@ -447,7 +436,7 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
|
||||
// Get the name (e.g. "foo") and verify it is well formed.
|
||||
StringRef OrigMatchStr = MatchStr;
|
||||
Expected<FileCheckPattern::VariableProperties> ParseVarResult =
|
||||
Expected<Pattern::VariableProperties> ParseVarResult =
|
||||
parseVariable(MatchStr, SM);
|
||||
if (!ParseVarResult) {
|
||||
logAllUnhandledErrors(ParseVarResult.takeError(), errs());
|
||||
@ -487,10 +476,10 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
}
|
||||
|
||||
// Parse numeric substitution block.
|
||||
std::unique_ptr<FileCheckExpressionAST> ExpressionAST;
|
||||
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
|
||||
std::unique_ptr<ExpressionAST> ExpressionASTPointer;
|
||||
Optional<NumericVariable *> DefinedNumericVariable;
|
||||
if (IsNumBlock) {
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>> ParseResult =
|
||||
Expected<std::unique_ptr<ExpressionAST>> ParseResult =
|
||||
parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable,
|
||||
IsLegacyLineExpr, LineNumber, Context,
|
||||
SM);
|
||||
@ -498,8 +487,8 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
logAllUnhandledErrors(ParseResult.takeError(), errs());
|
||||
return true;
|
||||
}
|
||||
ExpressionAST = std::move(*ParseResult);
|
||||
SubstNeeded = ExpressionAST != nullptr;
|
||||
ExpressionASTPointer = std::move(*ParseResult);
|
||||
SubstNeeded = ExpressionASTPointer != nullptr;
|
||||
if (DefinedNumericVariable) {
|
||||
IsDefinition = true;
|
||||
DefName = (*DefinedNumericVariable)->getName();
|
||||
@ -516,7 +505,7 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
++SubstInsertIdx;
|
||||
|
||||
if (IsNumBlock) {
|
||||
FileCheckNumericVariableMatch NumericVariableDefinition = {
|
||||
NumericVariableMatch NumericVariableDefinition = {
|
||||
*DefinedNumericVariable, CurParen};
|
||||
NumericVariableDefs[DefName] = NumericVariableDefinition;
|
||||
// This store is done here rather than in match() to allow
|
||||
@ -562,10 +551,11 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
} else {
|
||||
// Handle substitution of string variables ([[<var>]]) defined in
|
||||
// previous CHECK patterns, and substitution of expressions.
|
||||
FileCheckSubstitution *Substitution =
|
||||
Substitution *Substitution =
|
||||
IsNumBlock
|
||||
? Context->makeNumericSubstitution(
|
||||
SubstStr, std::move(ExpressionAST), SubstInsertIdx)
|
||||
SubstStr, std::move(ExpressionASTPointer),
|
||||
SubstInsertIdx)
|
||||
: Context->makeStringSubstitution(SubstStr, SubstInsertIdx);
|
||||
Substitutions.push_back(Substitution);
|
||||
}
|
||||
@ -589,7 +579,7 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileCheckPattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
|
||||
bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
|
||||
Regex R(RS);
|
||||
std::string Error;
|
||||
if (!R.isValid(Error)) {
|
||||
@ -603,14 +593,14 @@ bool FileCheckPattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceM
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileCheckPattern::AddBackrefToRegEx(unsigned BackrefNum) {
|
||||
void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
|
||||
assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number");
|
||||
std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum);
|
||||
RegExStr += Backref;
|
||||
}
|
||||
|
||||
Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
const SourceMgr &SM) const {
|
||||
Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
const SourceMgr &SM) const {
|
||||
// If this is the EOF pattern, match it immediately.
|
||||
if (CheckTy == Check::CheckEOF) {
|
||||
MatchLen = 0;
|
||||
@ -620,10 +610,10 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
// If this is a fixed string pattern, just match it now.
|
||||
if (!FixedStr.empty()) {
|
||||
MatchLen = FixedStr.size();
|
||||
size_t Pos = IgnoreCase ? Buffer.find_lower(FixedStr)
|
||||
: Buffer.find(FixedStr);
|
||||
size_t Pos =
|
||||
IgnoreCase ? Buffer.find_lower(FixedStr) : Buffer.find(FixedStr);
|
||||
if (Pos == StringRef::npos)
|
||||
return make_error<FileCheckNotFoundError>();
|
||||
return make_error<NotFoundError>();
|
||||
return Pos;
|
||||
}
|
||||
|
||||
@ -663,7 +653,7 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
if (IgnoreCase)
|
||||
Flags |= Regex::IgnoreCase;
|
||||
if (!Regex(RegExToMatch, Flags).match(Buffer, &MatchInfo))
|
||||
return make_error<FileCheckNotFoundError>();
|
||||
return make_error<NotFoundError>();
|
||||
|
||||
// Successful regex match.
|
||||
assert(!MatchInfo.empty() && "Didn't get any match");
|
||||
@ -678,18 +668,18 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
|
||||
// If this defines any numeric variables, remember their values.
|
||||
for (const auto &NumericVariableDef : NumericVariableDefs) {
|
||||
const FileCheckNumericVariableMatch &NumericVariableMatch =
|
||||
const NumericVariableMatch &NumericVariableMatch =
|
||||
NumericVariableDef.getValue();
|
||||
unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup;
|
||||
assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error");
|
||||
FileCheckNumericVariable *DefinedNumericVariable =
|
||||
NumericVariable *DefinedNumericVariable =
|
||||
NumericVariableMatch.DefinedNumericVariable;
|
||||
|
||||
StringRef MatchedValue = MatchInfo[CaptureParenGroup];
|
||||
uint64_t Val;
|
||||
if (MatchedValue.getAsInteger(10, Val))
|
||||
return FileCheckErrorDiagnostic::get(SM, MatchedValue,
|
||||
"Unable to represent numeric value");
|
||||
return ErrorDiagnostic::get(SM, MatchedValue,
|
||||
"Unable to represent numeric value");
|
||||
DefinedNumericVariable->setValue(Val);
|
||||
}
|
||||
|
||||
@ -701,7 +691,7 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
return FullMatch.data() - Buffer.data() + MatchStartSkip;
|
||||
}
|
||||
|
||||
unsigned FileCheckPattern::computeMatchDistance(StringRef Buffer) const {
|
||||
unsigned Pattern::computeMatchDistance(StringRef Buffer) const {
|
||||
// Just compute the number of matching characters. For regular expressions, we
|
||||
// just compare against the regex itself and hope for the best.
|
||||
//
|
||||
@ -718,8 +708,8 @@ unsigned FileCheckPattern::computeMatchDistance(StringRef Buffer) const {
|
||||
return BufferPrefix.edit_distance(ExampleString);
|
||||
}
|
||||
|
||||
void FileCheckPattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
|
||||
SMRange MatchRange) const {
|
||||
void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
|
||||
SMRange MatchRange) const {
|
||||
// Print what we know about substitutions.
|
||||
if (!Substitutions.empty()) {
|
||||
for (const auto &Substitution : Substitutions) {
|
||||
@ -731,11 +721,10 @@ void FileCheckPattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
|
||||
// variables it uses.
|
||||
if (!MatchedValue) {
|
||||
bool UndefSeen = false;
|
||||
handleAllErrors(MatchedValue.takeError(),
|
||||
[](const FileCheckNotFoundError &E) {},
|
||||
handleAllErrors(MatchedValue.takeError(), [](const NotFoundError &E) {},
|
||||
// Handled in PrintNoMatch().
|
||||
[](const FileCheckErrorDiagnostic &E) {},
|
||||
[&](const FileCheckUndefVarError &E) {
|
||||
[](const ErrorDiagnostic &E) {},
|
||||
[&](const UndefVarError &E) {
|
||||
if (!UndefSeen) {
|
||||
OS << "uses undefined variable(s):";
|
||||
UndefSeen = true;
|
||||
@ -778,9 +767,8 @@ static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy,
|
||||
return Range;
|
||||
}
|
||||
|
||||
void FileCheckPattern::printFuzzyMatch(
|
||||
const SourceMgr &SM, StringRef Buffer,
|
||||
std::vector<FileCheckDiag> *Diags) const {
|
||||
void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
|
||||
std::vector<FileCheckDiag> *Diags) const {
|
||||
// Attempt to find the closest/best fuzzy match. Usually an error happens
|
||||
// because some string in the output didn't exactly match. In these cases, we
|
||||
// would like to show the user a best guess at what "should have" matched, to
|
||||
@ -829,36 +817,34 @@ Expected<StringRef>
|
||||
FileCheckPatternContext::getPatternVarValue(StringRef VarName) {
|
||||
auto VarIter = GlobalVariableTable.find(VarName);
|
||||
if (VarIter == GlobalVariableTable.end())
|
||||
return make_error<FileCheckUndefVarError>(VarName);
|
||||
return make_error<UndefVarError>(VarName);
|
||||
|
||||
return VarIter->second;
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
FileCheckNumericVariable *
|
||||
FileCheckPatternContext::makeNumericVariable(Types... args) {
|
||||
NumericVariables.push_back(
|
||||
std::make_unique<FileCheckNumericVariable>(args...));
|
||||
NumericVariable *FileCheckPatternContext::makeNumericVariable(Types... args) {
|
||||
NumericVariables.push_back(std::make_unique<NumericVariable>(args...));
|
||||
return NumericVariables.back().get();
|
||||
}
|
||||
|
||||
FileCheckSubstitution *
|
||||
Substitution *
|
||||
FileCheckPatternContext::makeStringSubstitution(StringRef VarName,
|
||||
size_t InsertIdx) {
|
||||
Substitutions.push_back(
|
||||
std::make_unique<FileCheckStringSubstitution>(this, VarName, InsertIdx));
|
||||
std::make_unique<StringSubstitution>(this, VarName, InsertIdx));
|
||||
return Substitutions.back().get();
|
||||
}
|
||||
|
||||
FileCheckSubstitution *FileCheckPatternContext::makeNumericSubstitution(
|
||||
Substitution *FileCheckPatternContext::makeNumericSubstitution(
|
||||
StringRef ExpressionStr,
|
||||
std::unique_ptr<FileCheckExpressionAST> ExpressionAST, size_t InsertIdx) {
|
||||
Substitutions.push_back(std::make_unique<FileCheckNumericSubstitution>(
|
||||
this, ExpressionStr, std::move(ExpressionAST), InsertIdx));
|
||||
std::unique_ptr<ExpressionAST> ExpressionASTPointer, size_t InsertIdx) {
|
||||
Substitutions.push_back(std::make_unique<NumericSubstitution>(
|
||||
this, ExpressionStr, std::move(ExpressionASTPointer), InsertIdx));
|
||||
return Substitutions.back().get();
|
||||
}
|
||||
|
||||
size_t FileCheckPattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
|
||||
size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
|
||||
// Offset keeps track of the current offset within the input Str
|
||||
size_t Offset = 0;
|
||||
// [...] Nesting depth
|
||||
@ -1139,7 +1125,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
|
||||
|
||||
PatternContext->createLineVariable();
|
||||
|
||||
std::vector<FileCheckPattern> ImplicitNegativeChecks;
|
||||
std::vector<Pattern> ImplicitNegativeChecks;
|
||||
for (const auto &PatternString : Req.ImplicitCheckNot) {
|
||||
// Create a buffer with fake command line content in order to display the
|
||||
// command line option responsible for the specific implicit CHECK-NOT.
|
||||
@ -1153,12 +1139,12 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
|
||||
SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
|
||||
|
||||
ImplicitNegativeChecks.push_back(
|
||||
FileCheckPattern(Check::CheckNot, PatternContext.get()));
|
||||
Pattern(Check::CheckNot, PatternContext.get()));
|
||||
ImplicitNegativeChecks.back().parsePattern(PatternInBuffer,
|
||||
"IMPLICIT-CHECK", SM, Req);
|
||||
}
|
||||
|
||||
std::vector<FileCheckPattern> DagNotMatches = ImplicitNegativeChecks;
|
||||
std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
|
||||
|
||||
// LineNumber keeps track of the line on which CheckPrefix instances are
|
||||
// found.
|
||||
@ -1216,7 +1202,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
|
||||
SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
|
||||
|
||||
// Parse the pattern.
|
||||
FileCheckPattern P(CheckTy, PatternContext.get(), LineNumber);
|
||||
Pattern P(CheckTy, PatternContext.get(), LineNumber);
|
||||
if (P.parsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, Req))
|
||||
return true;
|
||||
|
||||
@ -1261,7 +1247,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
|
||||
// prefix as a filler for the error message.
|
||||
if (!DagNotMatches.empty()) {
|
||||
CheckStrings->emplace_back(
|
||||
FileCheckPattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1),
|
||||
Pattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1),
|
||||
*Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data()));
|
||||
std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
|
||||
}
|
||||
@ -1286,7 +1272,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
|
||||
}
|
||||
|
||||
static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM,
|
||||
StringRef Prefix, SMLoc Loc, const FileCheckPattern &Pat,
|
||||
StringRef Prefix, SMLoc Loc, const Pattern &Pat,
|
||||
int MatchedCount, StringRef Buffer, size_t MatchPos,
|
||||
size_t MatchLen, const FileCheckRequest &Req,
|
||||
std::vector<FileCheckDiag> *Diags) {
|
||||
@ -1332,10 +1318,10 @@ static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM,
|
||||
}
|
||||
|
||||
static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
|
||||
StringRef Prefix, SMLoc Loc,
|
||||
const FileCheckPattern &Pat, int MatchedCount,
|
||||
StringRef Buffer, bool VerboseVerbose,
|
||||
std::vector<FileCheckDiag> *Diags, Error MatchErrors) {
|
||||
StringRef Prefix, SMLoc Loc, const Pattern &Pat,
|
||||
int MatchedCount, StringRef Buffer,
|
||||
bool VerboseVerbose, std::vector<FileCheckDiag> *Diags,
|
||||
Error MatchErrors) {
|
||||
assert(MatchErrors && "Called on successful match");
|
||||
bool PrintDiag = true;
|
||||
if (!ExpectedMatch) {
|
||||
@ -1361,9 +1347,8 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
|
||||
return;
|
||||
}
|
||||
|
||||
MatchErrors =
|
||||
handleErrors(std::move(MatchErrors),
|
||||
[](const FileCheckErrorDiagnostic &E) { E.log(errs()); });
|
||||
MatchErrors = handleErrors(std::move(MatchErrors),
|
||||
[](const ErrorDiagnostic &E) { E.log(errs()); });
|
||||
|
||||
// No problem matching the string per se.
|
||||
if (!MatchErrors)
|
||||
@ -1427,7 +1412,7 @@ size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
|
||||
FileCheckRequest &Req,
|
||||
std::vector<FileCheckDiag> *Diags) const {
|
||||
size_t LastPos = 0;
|
||||
std::vector<const FileCheckPattern *> NotStrings;
|
||||
std::vector<const Pattern *> NotStrings;
|
||||
|
||||
// IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
|
||||
// bounds; we have not processed variable definitions within the bounded block
|
||||
@ -1565,11 +1550,11 @@ bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileCheckString::CheckNot(
|
||||
const SourceMgr &SM, StringRef Buffer,
|
||||
const std::vector<const FileCheckPattern *> &NotStrings,
|
||||
const FileCheckRequest &Req, std::vector<FileCheckDiag> *Diags) const {
|
||||
for (const FileCheckPattern *Pat : NotStrings) {
|
||||
bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
|
||||
const std::vector<const Pattern *> &NotStrings,
|
||||
const FileCheckRequest &Req,
|
||||
std::vector<FileCheckDiag> *Diags) const {
|
||||
for (const Pattern *Pat : NotStrings) {
|
||||
assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
|
||||
|
||||
size_t MatchLen = 0;
|
||||
@ -1591,11 +1576,10 @@ bool FileCheckString::CheckNot(
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
|
||||
std::vector<const FileCheckPattern *> &NotStrings,
|
||||
const FileCheckRequest &Req,
|
||||
std::vector<FileCheckDiag> *Diags) const {
|
||||
size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
|
||||
std::vector<const Pattern *> &NotStrings,
|
||||
const FileCheckRequest &Req,
|
||||
std::vector<FileCheckDiag> *Diags) const {
|
||||
if (DagNotStrings.empty())
|
||||
return 0;
|
||||
|
||||
@ -1615,7 +1599,7 @@ FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
|
||||
// group, so we don't use a range-based for loop here.
|
||||
for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end();
|
||||
PatItr != PatEnd; ++PatItr) {
|
||||
const FileCheckPattern &Pat = *PatItr;
|
||||
const Pattern &Pat = *PatItr;
|
||||
assert((Pat.getCheckTy() == Check::CheckDAG ||
|
||||
Pat.getCheckTy() == Check::CheckNot) &&
|
||||
"Invalid CHECK-DAG or CHECK-NOT!");
|
||||
@ -1820,8 +1804,8 @@ Error FileCheckPatternContext::defineCmdlineVariables(
|
||||
if (CmdlineDef.empty()) {
|
||||
Errs = joinErrors(
|
||||
std::move(Errs),
|
||||
FileCheckErrorDiagnostic::get(
|
||||
SM, CmdlineDef, "missing equal sign in global definition"));
|
||||
ErrorDiagnostic::get(SM, CmdlineDef,
|
||||
"missing equal sign in global definition"));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1830,21 +1814,21 @@ Error FileCheckPatternContext::defineCmdlineVariables(
|
||||
// Now parse the definition both to check that the syntax is correct and
|
||||
// to create the necessary class instance.
|
||||
StringRef CmdlineDefExpr = CmdlineDef.substr(1);
|
||||
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionASTResult =
|
||||
FileCheckPattern::parseNumericSubstitutionBlock(
|
||||
Optional<NumericVariable *> DefinedNumericVariable;
|
||||
Expected<std::unique_ptr<ExpressionAST>> ExpressionASTResult =
|
||||
Pattern::parseNumericSubstitutionBlock(
|
||||
CmdlineDefExpr, DefinedNumericVariable, false, None, this, SM);
|
||||
if (!ExpressionASTResult) {
|
||||
Errs = joinErrors(std::move(Errs), ExpressionASTResult.takeError());
|
||||
continue;
|
||||
}
|
||||
std::unique_ptr<FileCheckExpressionAST> ExpressionAST =
|
||||
std::unique_ptr<ExpressionAST> ExpressionASTPointer =
|
||||
std::move(*ExpressionASTResult);
|
||||
// Now evaluate the expression whose value this variable should be set
|
||||
// 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<uint64_t> Value = ExpressionAST->eval();
|
||||
Expected<uint64_t> Value = ExpressionASTPointer->eval();
|
||||
if (!Value) {
|
||||
Errs = joinErrors(std::move(Errs), Value.takeError());
|
||||
continue;
|
||||
@ -1861,8 +1845,8 @@ Error FileCheckPatternContext::defineCmdlineVariables(
|
||||
std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('=');
|
||||
StringRef CmdlineName = CmdlineNameVal.first;
|
||||
StringRef OrigCmdlineName = CmdlineName;
|
||||
Expected<FileCheckPattern::VariableProperties> ParseVarResult =
|
||||
FileCheckPattern::parseVariable(CmdlineName, SM);
|
||||
Expected<Pattern::VariableProperties> ParseVarResult =
|
||||
Pattern::parseVariable(CmdlineName, SM);
|
||||
if (!ParseVarResult) {
|
||||
Errs = joinErrors(std::move(Errs), ParseVarResult.takeError());
|
||||
continue;
|
||||
@ -1872,7 +1856,7 @@ Error FileCheckPatternContext::defineCmdlineVariables(
|
||||
// "FOO+2" in a "FOO+2=10" definition.
|
||||
if (ParseVarResult->IsPseudo || !CmdlineName.empty()) {
|
||||
Errs = joinErrors(std::move(Errs),
|
||||
FileCheckErrorDiagnostic::get(
|
||||
ErrorDiagnostic::get(
|
||||
SM, OrigCmdlineName,
|
||||
"invalid name in string variable definition '" +
|
||||
OrigCmdlineName + "'"));
|
||||
@ -1884,8 +1868,8 @@ Error FileCheckPatternContext::defineCmdlineVariables(
|
||||
// is created later than the latter.
|
||||
if (GlobalNumericVariableTable.find(Name) !=
|
||||
GlobalNumericVariableTable.end()) {
|
||||
Errs = joinErrors(std::move(Errs), FileCheckErrorDiagnostic::get(
|
||||
SM, Name,
|
||||
Errs = joinErrors(std::move(Errs),
|
||||
ErrorDiagnostic::get(SM, Name,
|
||||
"numeric variable with name '" +
|
||||
Name + "' already exists"));
|
||||
continue;
|
||||
|
@ -31,9 +31,9 @@ namespace llvm {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Base class representing the AST of a given expression.
|
||||
class FileCheckExpressionAST {
|
||||
class ExpressionAST {
|
||||
public:
|
||||
virtual ~FileCheckExpressionAST() = default;
|
||||
virtual ~ExpressionAST() = default;
|
||||
|
||||
/// Evaluates and \returns the value of the expression represented by this
|
||||
/// AST or an error if evaluation fails.
|
||||
@ -41,14 +41,14 @@ public:
|
||||
};
|
||||
|
||||
/// Class representing an unsigned literal in the AST of an expression.
|
||||
class FileCheckExpressionLiteral : public FileCheckExpressionAST {
|
||||
class ExpressionLiteral : public ExpressionAST {
|
||||
private:
|
||||
/// Actual value of the literal.
|
||||
uint64_t Value;
|
||||
|
||||
public:
|
||||
/// Constructs a literal with the specified value.
|
||||
FileCheckExpressionLiteral(uint64_t Val) : Value(Val) {}
|
||||
ExpressionLiteral(uint64_t Val) : Value(Val) {}
|
||||
|
||||
/// \returns the literal's value.
|
||||
Expected<uint64_t> eval() const override { return Value; }
|
||||
@ -56,14 +56,14 @@ public:
|
||||
|
||||
/// Class to represent an undefined variable error, which quotes that
|
||||
/// variable's name when printed.
|
||||
class FileCheckUndefVarError : public ErrorInfo<FileCheckUndefVarError> {
|
||||
class UndefVarError : public ErrorInfo<UndefVarError> {
|
||||
private:
|
||||
StringRef VarName;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
FileCheckUndefVarError(StringRef VarName) : VarName(VarName) {}
|
||||
UndefVarError(StringRef VarName) : VarName(VarName) {}
|
||||
|
||||
StringRef getVarName() const { return VarName; }
|
||||
|
||||
@ -79,7 +79,7 @@ public:
|
||||
};
|
||||
|
||||
/// Class representing a numeric variable and its associated current value.
|
||||
class FileCheckNumericVariable {
|
||||
class NumericVariable {
|
||||
private:
|
||||
/// Name of the numeric variable.
|
||||
StringRef Name;
|
||||
@ -95,8 +95,8 @@ private:
|
||||
public:
|
||||
/// Constructor for a variable \p Name defined at line \p DefLineNumber or
|
||||
/// defined before input is parsed if \p DefLineNumber is None.
|
||||
explicit FileCheckNumericVariable(StringRef Name,
|
||||
Optional<size_t> DefLineNumber = None)
|
||||
explicit NumericVariable(StringRef Name,
|
||||
Optional<size_t> DefLineNumber = None)
|
||||
: Name(Name), DefLineNumber(DefLineNumber) {}
|
||||
|
||||
/// \returns name of this numeric variable.
|
||||
@ -119,18 +119,17 @@ public:
|
||||
|
||||
/// Class representing the use of a numeric variable in the AST of an
|
||||
/// expression.
|
||||
class FileCheckNumericVariableUse : public FileCheckExpressionAST {
|
||||
class NumericVariableUse : public ExpressionAST {
|
||||
private:
|
||||
/// Name of the numeric variable.
|
||||
StringRef Name;
|
||||
|
||||
/// Pointer to the class instance for the variable this use is about.
|
||||
FileCheckNumericVariable *NumericVariable;
|
||||
NumericVariable *Variable;
|
||||
|
||||
public:
|
||||
FileCheckNumericVariableUse(StringRef Name,
|
||||
FileCheckNumericVariable *NumericVariable)
|
||||
: Name(Name), NumericVariable(NumericVariable) {}
|
||||
NumericVariableUse(StringRef Name, NumericVariable *Variable)
|
||||
: Name(Name), Variable(Variable) {}
|
||||
|
||||
/// \returns the value of the variable referenced by this instance.
|
||||
Expected<uint64_t> eval() const override;
|
||||
@ -140,21 +139,20 @@ public:
|
||||
using binop_eval_t = uint64_t (*)(uint64_t, uint64_t);
|
||||
|
||||
/// Class representing a single binary operation in the AST of an expression.
|
||||
class FileCheckASTBinop : public FileCheckExpressionAST {
|
||||
class BinaryOperation : public ExpressionAST {
|
||||
private:
|
||||
/// Left operand.
|
||||
std::unique_ptr<FileCheckExpressionAST> LeftOperand;
|
||||
std::unique_ptr<ExpressionAST> LeftOperand;
|
||||
|
||||
/// Right operand.
|
||||
std::unique_ptr<FileCheckExpressionAST> RightOperand;
|
||||
std::unique_ptr<ExpressionAST> RightOperand;
|
||||
|
||||
/// Pointer to function that can evaluate this binary operation.
|
||||
binop_eval_t EvalBinop;
|
||||
|
||||
public:
|
||||
FileCheckASTBinop(binop_eval_t EvalBinop,
|
||||
std::unique_ptr<FileCheckExpressionAST> LeftOp,
|
||||
std::unique_ptr<FileCheckExpressionAST> RightOp)
|
||||
BinaryOperation(binop_eval_t EvalBinop, std::unique_ptr<ExpressionAST> LeftOp,
|
||||
std::unique_ptr<ExpressionAST> RightOp)
|
||||
: EvalBinop(EvalBinop) {
|
||||
LeftOperand = std::move(LeftOp);
|
||||
RightOperand = std::move(RightOp);
|
||||
@ -170,7 +168,7 @@ public:
|
||||
class FileCheckPatternContext;
|
||||
|
||||
/// Class representing a substitution to perform in the RegExStr string.
|
||||
class FileCheckSubstitution {
|
||||
class Substitution {
|
||||
protected:
|
||||
/// Pointer to a class instance holding, among other things, the table with
|
||||
/// the values of live string variables at the start of any given CHECK line.
|
||||
@ -188,11 +186,11 @@ protected:
|
||||
size_t InsertIdx;
|
||||
|
||||
public:
|
||||
FileCheckSubstitution(FileCheckPatternContext *Context, StringRef VarName,
|
||||
size_t InsertIdx)
|
||||
Substitution(FileCheckPatternContext *Context, StringRef VarName,
|
||||
size_t InsertIdx)
|
||||
: Context(Context), FromStr(VarName), InsertIdx(InsertIdx) {}
|
||||
|
||||
virtual ~FileCheckSubstitution() = default;
|
||||
virtual ~Substitution() = default;
|
||||
|
||||
/// \returns the string to be substituted for something else.
|
||||
StringRef getFromString() const { return FromStr; }
|
||||
@ -205,29 +203,28 @@ public:
|
||||
virtual Expected<std::string> getResult() const = 0;
|
||||
};
|
||||
|
||||
class FileCheckStringSubstitution : public FileCheckSubstitution {
|
||||
class StringSubstitution : public Substitution {
|
||||
public:
|
||||
FileCheckStringSubstitution(FileCheckPatternContext *Context,
|
||||
StringRef VarName, size_t InsertIdx)
|
||||
: FileCheckSubstitution(Context, VarName, InsertIdx) {}
|
||||
StringSubstitution(FileCheckPatternContext *Context, StringRef VarName,
|
||||
size_t InsertIdx)
|
||||
: Substitution(Context, VarName, InsertIdx) {}
|
||||
|
||||
/// \returns the text that the string variable in this substitution matched
|
||||
/// when defined, or an error if the variable is undefined.
|
||||
Expected<std::string> getResult() const override;
|
||||
};
|
||||
|
||||
class FileCheckNumericSubstitution : public FileCheckSubstitution {
|
||||
class NumericSubstitution : public Substitution {
|
||||
private:
|
||||
/// Pointer to the class representing the expression whose value is to be
|
||||
/// substituted.
|
||||
std::unique_ptr<FileCheckExpressionAST> ExpressionAST;
|
||||
std::unique_ptr<ExpressionAST> ExpressionASTPointer;
|
||||
|
||||
public:
|
||||
FileCheckNumericSubstitution(FileCheckPatternContext *Context, StringRef Expr,
|
||||
std::unique_ptr<FileCheckExpressionAST> ExprAST,
|
||||
size_t InsertIdx)
|
||||
: FileCheckSubstitution(Context, Expr, InsertIdx) {
|
||||
ExpressionAST = std::move(ExprAST);
|
||||
NumericSubstitution(FileCheckPatternContext *Context, StringRef Expr,
|
||||
std::unique_ptr<ExpressionAST> ExprAST, size_t InsertIdx)
|
||||
: Substitution(Context, Expr, InsertIdx) {
|
||||
ExpressionASTPointer = std::move(ExprAST);
|
||||
}
|
||||
|
||||
/// \returns a string containing the result of evaluating the expression in
|
||||
@ -241,11 +238,11 @@ public:
|
||||
|
||||
struct FileCheckDiag;
|
||||
|
||||
/// Class holding the FileCheckPattern global state, shared by all patterns:
|
||||
/// tables holding values of variables and whether they are defined or not at
|
||||
/// any given time in the matching process.
|
||||
/// Class holding the Pattern global state, shared by all patterns: tables
|
||||
/// holding values of variables and whether they are defined or not at any
|
||||
/// given time in the matching process.
|
||||
class FileCheckPatternContext {
|
||||
friend class FileCheckPattern;
|
||||
friend class Pattern;
|
||||
|
||||
private:
|
||||
/// When matching a given pattern, this holds the value of all the string
|
||||
@ -262,21 +259,20 @@ private:
|
||||
/// When matching a given pattern, this holds the pointers to the classes
|
||||
/// representing the numeric variables defined in previous patterns. When
|
||||
/// matching a pattern all definitions for that pattern are recorded in the
|
||||
/// NumericVariableDefs table in the FileCheckPattern instance of that
|
||||
/// pattern.
|
||||
StringMap<FileCheckNumericVariable *> GlobalNumericVariableTable;
|
||||
/// NumericVariableDefs table in the Pattern instance of that pattern.
|
||||
StringMap<NumericVariable *> GlobalNumericVariableTable;
|
||||
|
||||
/// Pointer to the class instance representing the @LINE pseudo variable for
|
||||
/// easily updating its value.
|
||||
FileCheckNumericVariable *LineVariable = nullptr;
|
||||
NumericVariable *LineVariable = nullptr;
|
||||
|
||||
/// Vector holding pointers to all parsed numeric variables. Used to
|
||||
/// automatically free them once they are guaranteed to no longer be used.
|
||||
std::vector<std::unique_ptr<FileCheckNumericVariable>> NumericVariables;
|
||||
std::vector<std::unique_ptr<NumericVariable>> NumericVariables;
|
||||
|
||||
/// Vector holding pointers to all substitutions. Used to automatically free
|
||||
/// them once they are guaranteed to no longer be used.
|
||||
std::vector<std::unique_ptr<FileCheckSubstitution>> Substitutions;
|
||||
std::vector<std::unique_ptr<Substitution>> Substitutions;
|
||||
|
||||
public:
|
||||
/// \returns the value of string variable \p VarName or an error if no such
|
||||
@ -303,32 +299,30 @@ public:
|
||||
private:
|
||||
/// Makes a new numeric variable and registers it for destruction when the
|
||||
/// context is destroyed.
|
||||
template <class... Types>
|
||||
FileCheckNumericVariable *makeNumericVariable(Types... args);
|
||||
template <class... Types> NumericVariable *makeNumericVariable(Types... args);
|
||||
|
||||
/// Makes a new string substitution and registers it for destruction when the
|
||||
/// context is destroyed.
|
||||
FileCheckSubstitution *makeStringSubstitution(StringRef VarName,
|
||||
size_t InsertIdx);
|
||||
Substitution *makeStringSubstitution(StringRef VarName, size_t InsertIdx);
|
||||
|
||||
/// Makes a new numeric substitution and registers it for destruction when
|
||||
/// the context is destroyed.
|
||||
FileCheckSubstitution *
|
||||
Substitution *
|
||||
makeNumericSubstitution(StringRef ExpressionStr,
|
||||
std::unique_ptr<FileCheckExpressionAST> ExpressionAST,
|
||||
std::unique_ptr<ExpressionAST> ExpressionAST,
|
||||
size_t InsertIdx);
|
||||
};
|
||||
|
||||
/// Class to represent an error holding a diagnostic with location information
|
||||
/// used when printing it.
|
||||
class FileCheckErrorDiagnostic : public ErrorInfo<FileCheckErrorDiagnostic> {
|
||||
class ErrorDiagnostic : public ErrorInfo<ErrorDiagnostic> {
|
||||
private:
|
||||
SMDiagnostic Diagnostic;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
FileCheckErrorDiagnostic(SMDiagnostic &&Diag) : Diagnostic(Diag) {}
|
||||
ErrorDiagnostic(SMDiagnostic &&Diag) : Diagnostic(Diag) {}
|
||||
|
||||
std::error_code convertToErrorCode() const override {
|
||||
return inconvertibleErrorCode();
|
||||
@ -338,7 +332,7 @@ public:
|
||||
void log(raw_ostream &OS) const override { Diagnostic.print(nullptr, OS); }
|
||||
|
||||
static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg) {
|
||||
return make_error<FileCheckErrorDiagnostic>(
|
||||
return make_error<ErrorDiagnostic>(
|
||||
SM.GetMessage(Loc, SourceMgr::DK_Error, ErrMsg));
|
||||
}
|
||||
|
||||
@ -347,7 +341,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class FileCheckNotFoundError : public ErrorInfo<FileCheckNotFoundError> {
|
||||
class NotFoundError : public ErrorInfo<NotFoundError> {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
@ -361,7 +355,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class FileCheckPattern {
|
||||
class Pattern {
|
||||
SMLoc PatternLoc;
|
||||
|
||||
/// A fixed string to match as the pattern or empty if this pattern requires
|
||||
@ -378,7 +372,7 @@ class FileCheckPattern {
|
||||
/// RegExStr will contain "foobaz" and we'll get two entries in this vector
|
||||
/// that tells us to insert the value of string variable "bar" at offset 3
|
||||
/// and the value of expression "N+1" at offset 6.
|
||||
std::vector<FileCheckSubstitution *> Substitutions;
|
||||
std::vector<Substitution *> Substitutions;
|
||||
|
||||
/// Maps names of string variables defined in a pattern to the number of
|
||||
/// their parenthesis group in RegExStr capturing their last definition.
|
||||
@ -397,10 +391,10 @@ class FileCheckPattern {
|
||||
/// It holds the pointer to the class representing the numeric variable whose
|
||||
/// value is being defined and the number of the parenthesis group in
|
||||
/// RegExStr to capture that value.
|
||||
struct FileCheckNumericVariableMatch {
|
||||
struct NumericVariableMatch {
|
||||
/// Pointer to class representing the numeric variable whose value is being
|
||||
/// defined.
|
||||
FileCheckNumericVariable *DefinedNumericVariable;
|
||||
NumericVariable *DefinedNumericVariable;
|
||||
|
||||
/// Number of the parenthesis group in RegExStr that captures the value of
|
||||
/// this numeric variable definition.
|
||||
@ -408,10 +402,9 @@ class FileCheckPattern {
|
||||
};
|
||||
|
||||
/// Holds the number of the parenthesis group in RegExStr and pointer to the
|
||||
/// corresponding FileCheckNumericVariable class instance of all numeric
|
||||
/// variable definitions. Used to set the matched value of all those
|
||||
/// variables.
|
||||
StringMap<FileCheckNumericVariableMatch> NumericVariableDefs;
|
||||
/// corresponding NumericVariable class instance of all numeric variable
|
||||
/// definitions. Used to set the matched value of all those variables.
|
||||
StringMap<NumericVariableMatch> NumericVariableDefs;
|
||||
|
||||
/// Pointer to a class instance holding the global state shared by all
|
||||
/// patterns:
|
||||
@ -432,8 +425,8 @@ class FileCheckPattern {
|
||||
bool IgnoreCase = false;
|
||||
|
||||
public:
|
||||
FileCheckPattern(Check::FileCheckType Ty, FileCheckPatternContext *Context,
|
||||
Optional<size_t> Line = None)
|
||||
Pattern(Check::FileCheckType Ty, FileCheckPatternContext *Context,
|
||||
Optional<size_t> Line = None)
|
||||
: Context(Context), CheckTy(Ty), LineNumber(Line) {}
|
||||
|
||||
/// \returns the location in source code.
|
||||
@ -469,14 +462,12 @@ public:
|
||||
/// substitution was successful, sets \p DefinedNumericVariable to point to
|
||||
/// the class representing the numeric variable defined in this numeric
|
||||
/// substitution block, or None if this block does not define any variable.
|
||||
static Expected<std::unique_ptr<FileCheckExpressionAST>>
|
||||
parseNumericSubstitutionBlock(
|
||||
StringRef Expr,
|
||||
Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
|
||||
static Expected<std::unique_ptr<ExpressionAST>> parseNumericSubstitutionBlock(
|
||||
StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable,
|
||||
bool IsLegacyLineExpr, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM);
|
||||
/// Parses the pattern in \p PatternStr and initializes this FileCheckPattern
|
||||
/// instance accordingly.
|
||||
/// Parses the pattern in \p PatternStr and initializes this Pattern instance
|
||||
/// accordingly.
|
||||
///
|
||||
/// \p Prefix provides which prefix is being matched, \p Req describes the
|
||||
/// global options that influence the parsing such as whitespace
|
||||
@ -491,8 +482,8 @@ public:
|
||||
/// matched string.
|
||||
///
|
||||
/// The GlobalVariableTable StringMap in the FileCheckPatternContext class
|
||||
/// instance provides the current values of FileCheck string variables and
|
||||
/// is updated if this match defines new values. Likewise, the
|
||||
/// instance provides the current values of FileCheck string variables and is
|
||||
/// updated if this match defines new values. Likewise, the
|
||||
/// GlobalNumericVariableTable StringMap in the same class provides the
|
||||
/// current values of FileCheck numeric variables and is updated if this
|
||||
/// match defines new numeric values.
|
||||
@ -533,7 +524,7 @@ private:
|
||||
/// \returns a pointer to the class instance representing that variable,
|
||||
/// creating it if needed, or an error holding a diagnostic against \p SM
|
||||
/// should defining such a variable be invalid.
|
||||
static Expected<FileCheckNumericVariable *> parseNumericVariableDefinition(
|
||||
static Expected<NumericVariable *> parseNumericVariableDefinition(
|
||||
StringRef &Expr, FileCheckPatternContext *Context,
|
||||
Optional<size_t> LineNumber, const SourceMgr &SM);
|
||||
/// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use
|
||||
@ -542,11 +533,9 @@ private:
|
||||
/// string and numeric variables. \returns the pointer to the class instance
|
||||
/// representing that variable if successful, or an error holding a
|
||||
/// diagnostic against \p SM otherwise.
|
||||
static Expected<std::unique_ptr<FileCheckNumericVariableUse>>
|
||||
parseNumericVariableUse(StringRef Name, bool IsPseudo,
|
||||
Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context,
|
||||
const SourceMgr &SM);
|
||||
static Expected<std::unique_ptr<NumericVariableUse>> parseNumericVariableUse(
|
||||
StringRef Name, bool IsPseudo, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM);
|
||||
enum class AllowedOperand { LineVar, Literal, Any };
|
||||
/// Parses \p Expr for use of a numeric operand at line \p LineNumber, or
|
||||
/// before input is parsed if \p LineNumber is None. Accepts both literal
|
||||
@ -555,7 +544,7 @@ private:
|
||||
/// numeric variables. \returns the class representing that operand in the
|
||||
/// AST of the expression or an error holding a diagnostic against \p SM
|
||||
/// otherwise.
|
||||
static Expected<std::unique_ptr<FileCheckExpressionAST>>
|
||||
static Expected<std::unique_ptr<ExpressionAST>>
|
||||
parseNumericOperand(StringRef &Expr, AllowedOperand AO,
|
||||
Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM);
|
||||
@ -566,8 +555,8 @@ private:
|
||||
/// the class instance holding the live string and numeric variables.
|
||||
/// \returns the class representing the binary operation in the AST of the
|
||||
/// expression, or an error holding a diagnostic against \p SM otherwise.
|
||||
static Expected<std::unique_ptr<FileCheckExpressionAST>>
|
||||
parseBinop(StringRef &Expr, std::unique_ptr<FileCheckExpressionAST> LeftOp,
|
||||
static Expected<std::unique_ptr<ExpressionAST>>
|
||||
parseBinop(StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp,
|
||||
bool IsLegacyLineExpr, Optional<size_t> LineNumber,
|
||||
FileCheckPatternContext *Context, const SourceMgr &SM);
|
||||
};
|
||||
@ -579,7 +568,7 @@ private:
|
||||
/// A check that we found in the input file.
|
||||
struct FileCheckString {
|
||||
/// The pattern to match.
|
||||
FileCheckPattern Pat;
|
||||
Pattern Pat;
|
||||
|
||||
/// Which prefix name this check matched.
|
||||
StringRef Prefix;
|
||||
@ -589,9 +578,9 @@ struct FileCheckString {
|
||||
|
||||
/// All of the strings that are disallowed from occurring between this match
|
||||
/// string and the previous one (or start of file).
|
||||
std::vector<FileCheckPattern> DagNotStrings;
|
||||
std::vector<Pattern> DagNotStrings;
|
||||
|
||||
FileCheckString(const FileCheckPattern &P, StringRef S, SMLoc L)
|
||||
FileCheckString(const Pattern &P, StringRef S, SMLoc L)
|
||||
: Pat(P), Prefix(S), Loc(L) {}
|
||||
|
||||
/// Matches check string and its "not strings" and/or "dag strings".
|
||||
@ -609,12 +598,12 @@ struct FileCheckString {
|
||||
/// \p Buffer. Errors are reported against \p SM and diagnostics recorded in
|
||||
/// \p Diags according to the verbosity level set in \p Req.
|
||||
bool CheckNot(const SourceMgr &SM, StringRef Buffer,
|
||||
const std::vector<const FileCheckPattern *> &NotStrings,
|
||||
const std::vector<const Pattern *> &NotStrings,
|
||||
const FileCheckRequest &Req,
|
||||
std::vector<FileCheckDiag> *Diags) const;
|
||||
/// Matches "dag strings" and their mixed "not strings".
|
||||
size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
|
||||
std::vector<const FileCheckPattern *> &NotStrings,
|
||||
std::vector<const Pattern *> &NotStrings,
|
||||
const FileCheckRequest &Req,
|
||||
std::vector<FileCheckDiag> *Diags) const;
|
||||
};
|
||||
|
@ -19,13 +19,13 @@ class FileCheckTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(FileCheckTest, Literal) {
|
||||
// Eval returns the literal's value.
|
||||
FileCheckExpressionLiteral Ten(10);
|
||||
ExpressionLiteral Ten(10);
|
||||
Expected<uint64_t> Value = Ten.eval();
|
||||
ASSERT_TRUE(bool(Value));
|
||||
EXPECT_EQ(10U, *Value);
|
||||
|
||||
// Max value can be correctly represented.
|
||||
FileCheckExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
|
||||
ExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
|
||||
Value = Max.eval();
|
||||
ASSERT_TRUE(bool(Value));
|
||||
EXPECT_EQ(std::numeric_limits<uint64_t>::max(), *Value);
|
||||
@ -45,14 +45,14 @@ static std::string toString(const std::unordered_set<std::string> &Set) {
|
||||
static void
|
||||
expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames,
|
||||
Error Err) {
|
||||
handleAllErrors(std::move(Err), [&](const FileCheckUndefVarError &E) {
|
||||
handleAllErrors(std::move(Err), [&](const UndefVarError &E) {
|
||||
ExpectedUndefVarNames.erase(E.getVarName());
|
||||
});
|
||||
EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
|
||||
}
|
||||
|
||||
// Return whether Err contains any FileCheckUndefVarError whose associated name
|
||||
// is not ExpectedUndefVarName.
|
||||
// Return whether Err contains any UndefVarError whose associated name is not
|
||||
// ExpectedUndefVarName.
|
||||
static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
|
||||
expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
|
||||
}
|
||||
@ -62,9 +62,9 @@ uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
|
||||
TEST_F(FileCheckTest, NumericVariable) {
|
||||
// Undefined variable: getValue and eval fail, error returned by eval holds
|
||||
// the name of the undefined variable.
|
||||
FileCheckNumericVariable FooVar("FOO", 1);
|
||||
NumericVariable FooVar("FOO", 1);
|
||||
EXPECT_EQ("FOO", FooVar.getName());
|
||||
FileCheckNumericVariableUse FooVarUse("FOO", &FooVar);
|
||||
NumericVariableUse FooVarUse("FOO", &FooVar);
|
||||
EXPECT_FALSE(FooVar.getValue());
|
||||
Expected<uint64_t> EvalResult = FooVarUse.eval();
|
||||
ASSERT_FALSE(EvalResult);
|
||||
@ -90,15 +90,15 @@ TEST_F(FileCheckTest, NumericVariable) {
|
||||
}
|
||||
|
||||
TEST_F(FileCheckTest, Binop) {
|
||||
FileCheckNumericVariable FooVar("FOO", 1);
|
||||
NumericVariable FooVar("FOO", 1);
|
||||
FooVar.setValue(42);
|
||||
std::unique_ptr<FileCheckNumericVariableUse> FooVarUse =
|
||||
std::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
|
||||
FileCheckNumericVariable BarVar("BAR", 2);
|
||||
std::unique_ptr<NumericVariableUse> FooVarUse =
|
||||
std::make_unique<NumericVariableUse>("FOO", &FooVar);
|
||||
NumericVariable BarVar("BAR", 2);
|
||||
BarVar.setValue(18);
|
||||
std::unique_ptr<FileCheckNumericVariableUse> BarVarUse =
|
||||
std::make_unique<FileCheckNumericVariableUse>("BAR", &BarVar);
|
||||
FileCheckASTBinop Binop(doAdd, std::move(FooVarUse), std::move(BarVarUse));
|
||||
std::unique_ptr<NumericVariableUse> BarVarUse =
|
||||
std::make_unique<NumericVariableUse>("BAR", &BarVar);
|
||||
BinaryOperation Binop(doAdd, std::move(FooVarUse), std::move(BarVarUse));
|
||||
|
||||
// Defined variable: eval returns right value.
|
||||
Expected<uint64_t> Value = Binop.eval();
|
||||
@ -121,15 +121,15 @@ TEST_F(FileCheckTest, Binop) {
|
||||
}
|
||||
|
||||
TEST_F(FileCheckTest, ValidVarNameStart) {
|
||||
EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a'));
|
||||
EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G'));
|
||||
EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('_'));
|
||||
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('2'));
|
||||
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('$'));
|
||||
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('@'));
|
||||
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('+'));
|
||||
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('-'));
|
||||
EXPECT_FALSE(FileCheckPattern::isValidVarNameStart(':'));
|
||||
EXPECT_TRUE(Pattern::isValidVarNameStart('a'));
|
||||
EXPECT_TRUE(Pattern::isValidVarNameStart('G'));
|
||||
EXPECT_TRUE(Pattern::isValidVarNameStart('_'));
|
||||
EXPECT_FALSE(Pattern::isValidVarNameStart('2'));
|
||||
EXPECT_FALSE(Pattern::isValidVarNameStart('$'));
|
||||
EXPECT_FALSE(Pattern::isValidVarNameStart('@'));
|
||||
EXPECT_FALSE(Pattern::isValidVarNameStart('+'));
|
||||
EXPECT_FALSE(Pattern::isValidVarNameStart('-'));
|
||||
EXPECT_FALSE(Pattern::isValidVarNameStart(':'));
|
||||
}
|
||||
|
||||
static StringRef bufferize(SourceMgr &SM, StringRef Str) {
|
||||
@ -144,65 +144,65 @@ TEST_F(FileCheckTest, ParseVar) {
|
||||
SourceMgr SM;
|
||||
StringRef OrigVarName = bufferize(SM, "GoodVar42");
|
||||
StringRef VarName = OrigVarName;
|
||||
Expected<FileCheckPattern::VariableProperties> ParsedVarResult =
|
||||
FileCheckPattern::parseVariable(VarName, SM);
|
||||
Expected<Pattern::VariableProperties> ParsedVarResult =
|
||||
Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
|
||||
EXPECT_TRUE(VarName.empty());
|
||||
EXPECT_FALSE(ParsedVarResult->IsPseudo);
|
||||
|
||||
VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
|
||||
EXPECT_TRUE(VarName.empty());
|
||||
EXPECT_FALSE(ParsedVarResult->IsPseudo);
|
||||
|
||||
VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
|
||||
EXPECT_TRUE(VarName.empty());
|
||||
EXPECT_TRUE(ParsedVarResult->IsPseudo);
|
||||
|
||||
VarName = bufferize(SM, "42BadVar");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
|
||||
|
||||
VarName = bufferize(SM, "$@");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
|
||||
|
||||
VarName = OrigVarName = bufferize(SM, "B@dVar");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(VarName, OrigVarName.substr(1));
|
||||
EXPECT_EQ(ParsedVarResult->Name, "B");
|
||||
EXPECT_FALSE(ParsedVarResult->IsPseudo);
|
||||
|
||||
VarName = OrigVarName = bufferize(SM, "B$dVar");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(VarName, OrigVarName.substr(1));
|
||||
EXPECT_EQ(ParsedVarResult->Name, "B");
|
||||
EXPECT_FALSE(ParsedVarResult->IsPseudo);
|
||||
|
||||
VarName = bufferize(SM, "BadVar+");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(VarName, "+");
|
||||
EXPECT_EQ(ParsedVarResult->Name, "BadVar");
|
||||
EXPECT_FALSE(ParsedVarResult->IsPseudo);
|
||||
|
||||
VarName = bufferize(SM, "BadVar-");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(VarName, "-");
|
||||
EXPECT_EQ(ParsedVarResult->Name, "BadVar");
|
||||
EXPECT_FALSE(ParsedVarResult->IsPseudo);
|
||||
|
||||
VarName = bufferize(SM, "BadVar:");
|
||||
ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
|
||||
ParsedVarResult = Pattern::parseVariable(VarName, SM);
|
||||
ASSERT_TRUE(bool(ParsedVarResult));
|
||||
EXPECT_EQ(VarName, ":");
|
||||
EXPECT_EQ(ParsedVarResult->Name, "BadVar");
|
||||
@ -215,7 +215,7 @@ private:
|
||||
SourceMgr SM;
|
||||
FileCheckRequest Req;
|
||||
FileCheckPatternContext Context;
|
||||
FileCheckPattern P{Check::CheckPlain, &Context, LineNumber++};
|
||||
Pattern P{Check::CheckPlain, &Context, LineNumber++};
|
||||
|
||||
public:
|
||||
PatternTester() {
|
||||
@ -236,12 +236,12 @@ public:
|
||||
}
|
||||
|
||||
void initNextPattern() {
|
||||
P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
|
||||
P = Pattern(Check::CheckPlain, &Context, LineNumber++);
|
||||
}
|
||||
|
||||
bool parseSubstExpect(StringRef Expr) {
|
||||
StringRef ExprBufferRef = bufferize(SM, Expr);
|
||||
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
|
||||
Optional<NumericVariable *> DefinedNumericVariable;
|
||||
return errorToBool(
|
||||
P.parseNumericSubstitutionBlock(ExprBufferRef, DefinedNumericVariable,
|
||||
false, LineNumber - 1, &Context, SM)
|
||||
@ -406,24 +406,22 @@ TEST_F(FileCheckTest, Substitution) {
|
||||
|
||||
// Substitution of an undefined string variable fails and error holds that
|
||||
// variable's name.
|
||||
FileCheckStringSubstitution StringSubstitution(&Context, "VAR404", 42);
|
||||
StringSubstitution StringSubstitution(&Context, "VAR404", 42);
|
||||
Expected<std::string> SubstValue = StringSubstitution.getResult();
|
||||
ASSERT_FALSE(bool(SubstValue));
|
||||
expectUndefError("VAR404", SubstValue.takeError());
|
||||
|
||||
// Substitutions of defined pseudo and non-pseudo numeric variables return
|
||||
// the right value.
|
||||
FileCheckNumericVariable LineVar("@LINE", 1);
|
||||
FileCheckNumericVariable NVar("N", 1);
|
||||
NumericVariable LineVar("@LINE", 1);
|
||||
NumericVariable NVar("N", 1);
|
||||
LineVar.setValue(42);
|
||||
NVar.setValue(10);
|
||||
auto LineVarUse =
|
||||
std::make_unique<FileCheckNumericVariableUse>("@LINE", &LineVar);
|
||||
auto NVarUse = std::make_unique<FileCheckNumericVariableUse>("N", &NVar);
|
||||
FileCheckNumericSubstitution SubstitutionLine(&Context, "@LINE",
|
||||
std::move(LineVarUse), 12);
|
||||
FileCheckNumericSubstitution SubstitutionN(&Context, "N", std::move(NVarUse),
|
||||
30);
|
||||
auto LineVarUse = std::make_unique<NumericVariableUse>("@LINE", &LineVar);
|
||||
auto NVarUse = std::make_unique<NumericVariableUse>("N", &NVar);
|
||||
NumericSubstitution SubstitutionLine(&Context, "@LINE", std::move(LineVarUse),
|
||||
12);
|
||||
NumericSubstitution SubstitutionN(&Context, "N", std::move(NVarUse), 30);
|
||||
SubstValue = SubstitutionLine.getResult();
|
||||
ASSERT_TRUE(bool(SubstValue));
|
||||
EXPECT_EQ("42", *SubstValue);
|
||||
@ -443,8 +441,8 @@ TEST_F(FileCheckTest, Substitution) {
|
||||
expectUndefError("N", SubstValue.takeError());
|
||||
|
||||
// Substitution of a defined string variable returns the right value.
|
||||
FileCheckPattern P(Check::CheckPlain, &Context, 1);
|
||||
StringSubstitution = FileCheckStringSubstitution(&Context, "FOO", 42);
|
||||
Pattern P(Check::CheckPlain, &Context, 1);
|
||||
StringSubstitution = llvm::StringSubstitution(&Context, "FOO", 42);
|
||||
SubstValue = StringSubstitution.getResult();
|
||||
ASSERT_TRUE(bool(SubstValue));
|
||||
EXPECT_EQ("BAR", *SubstValue);
|
||||
@ -514,9 +512,9 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
||||
StringRef EmptyVarStr = "EmptyVar";
|
||||
StringRef UnknownVarStr = "UnknownVar";
|
||||
Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
|
||||
FileCheckPattern P(Check::CheckPlain, &Cxt, 1);
|
||||
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
|
||||
Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionAST =
|
||||
Pattern P(Check::CheckPlain, &Cxt, 1);
|
||||
Optional<NumericVariable *> DefinedNumericVariable;
|
||||
Expected<std::unique_ptr<ExpressionAST>> ExpressionASTPointer =
|
||||
P.parseNumericSubstitutionBlock(LocalNumVar1Ref, DefinedNumericVariable,
|
||||
/*IsLegacyLineExpr=*/false,
|
||||
/*LineNumber=*/1, &Cxt, SM);
|
||||
@ -524,16 +522,16 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
||||
EXPECT_EQ(*LocalVar, "FOO");
|
||||
Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
|
||||
Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
|
||||
ASSERT_TRUE(bool(ExpressionAST));
|
||||
Expected<uint64_t> ExpressionVal = (*ExpressionAST)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionASTPointer));
|
||||
Expected<uint64_t> ExpressionVal = (*ExpressionASTPointer)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionVal));
|
||||
EXPECT_EQ(*ExpressionVal, 18U);
|
||||
ExpressionAST =
|
||||
ExpressionASTPointer =
|
||||
P.parseNumericSubstitutionBlock(LocalNumVar2Ref, DefinedNumericVariable,
|
||||
/*IsLegacyLineExpr=*/false,
|
||||
/*LineNumber=*/1, &Cxt, SM);
|
||||
ASSERT_TRUE(bool(ExpressionAST));
|
||||
ExpressionVal = (*ExpressionAST)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionASTPointer));
|
||||
ExpressionVal = (*ExpressionASTPointer)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionVal));
|
||||
EXPECT_EQ(*ExpressionVal, 20U);
|
||||
ASSERT_TRUE(bool(EmptyVar));
|
||||
@ -548,19 +546,19 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
||||
// local variables, if it was created before. This is important because local
|
||||
// variable clearing due to --enable-var-scope happens after numeric
|
||||
// expressions are linked to the numeric variables they use.
|
||||
EXPECT_TRUE(errorToBool((*ExpressionAST)->eval().takeError()));
|
||||
P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
|
||||
ExpressionAST = P.parseNumericSubstitutionBlock(
|
||||
EXPECT_TRUE(errorToBool((*ExpressionASTPointer)->eval().takeError()));
|
||||
P = Pattern(Check::CheckPlain, &Cxt, 2);
|
||||
ExpressionASTPointer = P.parseNumericSubstitutionBlock(
|
||||
LocalNumVar1Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
|
||||
/*LineNumber=*/2, &Cxt, SM);
|
||||
ASSERT_TRUE(bool(ExpressionAST));
|
||||
ExpressionVal = (*ExpressionAST)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionASTPointer));
|
||||
ExpressionVal = (*ExpressionASTPointer)->eval();
|
||||
EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
|
||||
ExpressionAST = P.parseNumericSubstitutionBlock(
|
||||
ExpressionASTPointer = P.parseNumericSubstitutionBlock(
|
||||
LocalNumVar2Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
|
||||
/*LineNumber=*/2, &Cxt, SM);
|
||||
ASSERT_TRUE(bool(ExpressionAST));
|
||||
ExpressionVal = (*ExpressionAST)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionASTPointer));
|
||||
ExpressionVal = (*ExpressionASTPointer)->eval();
|
||||
EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
|
||||
EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
|
||||
EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
|
||||
@ -577,24 +575,24 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
||||
Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
|
||||
ASSERT_TRUE(bool(GlobalVar));
|
||||
EXPECT_EQ(*GlobalVar, "BAR");
|
||||
P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
|
||||
ExpressionAST = P.parseNumericSubstitutionBlock(
|
||||
P = Pattern(Check::CheckPlain, &Cxt, 3);
|
||||
ExpressionASTPointer = P.parseNumericSubstitutionBlock(
|
||||
GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
|
||||
/*LineNumber=*/3, &Cxt, SM);
|
||||
ASSERT_TRUE(bool(ExpressionAST));
|
||||
ExpressionVal = (*ExpressionAST)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionASTPointer));
|
||||
ExpressionVal = (*ExpressionASTPointer)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionVal));
|
||||
EXPECT_EQ(*ExpressionVal, 36U);
|
||||
|
||||
// Clear local variables and check global variables remain defined.
|
||||
Cxt.clearLocalVars();
|
||||
EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
|
||||
P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
|
||||
ExpressionAST = P.parseNumericSubstitutionBlock(
|
||||
P = Pattern(Check::CheckPlain, &Cxt, 4);
|
||||
ExpressionASTPointer = P.parseNumericSubstitutionBlock(
|
||||
GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
|
||||
/*LineNumber=*/4, &Cxt, SM);
|
||||
ASSERT_TRUE(bool(ExpressionAST));
|
||||
ExpressionVal = (*ExpressionAST)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionASTPointer));
|
||||
ExpressionVal = (*ExpressionASTPointer)->eval();
|
||||
ASSERT_TRUE(bool(ExpressionVal));
|
||||
EXPECT_EQ(*ExpressionVal, 36U);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user