aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/FileCheck.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Support/FileCheck.cpp562
1 files changed, 269 insertions, 293 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp b/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp
index 2261ecc236c2..e0f17787bdf8 100644
--- a/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp
+++ b/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp
@@ -14,26 +14,35 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/FileCheck.h"
-#include "FileCheckImpl.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/FormatVariadic.h"
#include <cstdint>
#include <list>
+#include <map>
#include <tuple>
#include <utility>
using namespace llvm;
-Expected<uint64_t> NumericVariableUse::eval() const {
- Optional<uint64_t> Value = Variable->getValue();
+void FileCheckNumericVariable::setValue(uint64_t NewValue) {
+ assert(!Value && "Overwriting numeric variable's value is not allowed");
+ Value = NewValue;
+}
+
+void FileCheckNumericVariable::clearValue() {
+ if (!Value)
+ return;
+ Value = None;
+}
+
+Expected<uint64_t> FileCheckNumericVariableUse::eval() const {
+ Optional<uint64_t> Value = NumericVariable->getValue();
if (Value)
return *Value;
-
- return make_error<UndefVarError>(Name);
+ return make_error<FileCheckUndefVarError>(Name);
}
-Expected<uint64_t> BinaryOperation::eval() const {
+Expected<uint64_t> FileCheckASTBinop::eval() const {
Expected<uint64_t> LeftOp = LeftOperand->eval();
Expected<uint64_t> RightOp = RightOperand->eval();
@@ -51,14 +60,14 @@ Expected<uint64_t> BinaryOperation::eval() const {
return EvalBinop(*LeftOp, *RightOp);
}
-Expected<std::string> NumericSubstitution::getResult() const {
- Expected<uint64_t> EvaluatedValue = ExpressionASTPointer->eval();
+Expected<std::string> FileCheckNumericSubstitution::getResult() const {
+ Expected<uint64_t> EvaluatedValue = ExpressionAST->eval();
if (!EvaluatedValue)
return EvaluatedValue.takeError();
return utostr(*EvaluatedValue);
}
-Expected<std::string> StringSubstitution::getResult() const {
+Expected<std::string> FileCheckStringSubstitution::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,12 +75,14 @@ Expected<std::string> StringSubstitution::getResult() const {
return Regex::escape(*VarVal);
}
-bool Pattern::isValidVarNameStart(char C) { return C == '_' || isalpha(C); }
+bool FileCheckPattern::isValidVarNameStart(char C) {
+ return C == '_' || isalpha(C);
+}
-Expected<Pattern::VariableProperties>
-Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) {
+Expected<FileCheckPattern::VariableProperties>
+FileCheckPattern::parseVariable(StringRef &Str, const SourceMgr &SM) {
if (Str.empty())
- return ErrorDiagnostic::get(SM, Str, "empty variable name");
+ return FileCheckErrorDiagnostic::get(SM, Str, "empty variable name");
bool ParsedOneChar = false;
unsigned I = 0;
@@ -83,7 +94,7 @@ Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) {
for (unsigned E = Str.size(); I != E; ++I) {
if (!ParsedOneChar && !isValidVarNameStart(Str[I]))
- return ErrorDiagnostic::get(SM, Str, "invalid variable name");
+ return FileCheckErrorDiagnostic::get(SM, Str, "invalid variable name");
// Variable names are composed of alphanumeric characters and underscores.
if (Str[I] != '_' && !isalnum(Str[I]))
@@ -98,7 +109,7 @@ Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) {
// StringRef holding all characters considered as horizontal whitespaces by
// FileCheck input canonicalization.
-constexpr StringLiteral SpaceChars = " \t";
+StringRef SpaceChars = " \t";
// Parsing helper function that strips the first character in S and returns it.
static char popFront(StringRef &S) {
@@ -107,11 +118,12 @@ static char popFront(StringRef &S) {
return C;
}
-char UndefVarError::ID = 0;
-char ErrorDiagnostic::ID = 0;
-char NotFoundError::ID = 0;
+char FileCheckUndefVarError::ID = 0;
+char FileCheckErrorDiagnostic::ID = 0;
+char FileCheckNotFoundError::ID = 0;
-Expected<NumericVariable *> Pattern::parseNumericVariableDefinition(
+Expected<FileCheckNumericVariable *>
+FileCheckPattern::parseNumericVariableDefinition(
StringRef &Expr, FileCheckPatternContext *Context,
Optional<size_t> LineNumber, const SourceMgr &SM) {
Expected<VariableProperties> ParseVarResult = parseVariable(Expr, SM);
@@ -120,22 +132,22 @@ Expected<NumericVariable *> Pattern::parseNumericVariableDefinition(
StringRef Name = ParseVarResult->Name;
if (ParseVarResult->IsPseudo)
- return ErrorDiagnostic::get(
+ return FileCheckErrorDiagnostic::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 ErrorDiagnostic::get(
+ return FileCheckErrorDiagnostic::get(
SM, Name, "string variable with name '" + Name + "' already exists");
Expr = Expr.ltrim(SpaceChars);
if (!Expr.empty())
- return ErrorDiagnostic::get(
+ return FileCheckErrorDiagnostic::get(
SM, Expr, "unexpected characters after numeric variable name");
- NumericVariable *DefinedNumericVariable;
+ FileCheckNumericVariable *DefinedNumericVariable;
auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
if (VarTableIter != Context->GlobalNumericVariableTable.end())
DefinedNumericVariable = VarTableIter->second;
@@ -145,11 +157,11 @@ Expected<NumericVariable *> Pattern::parseNumericVariableDefinition(
return DefinedNumericVariable;
}
-Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse(
- StringRef Name, bool IsPseudo, Optional<size_t> LineNumber,
- FileCheckPatternContext *Context, const SourceMgr &SM) {
+Expected<std::unique_ptr<FileCheckNumericVariableUse>>
+FileCheckPattern::parseNumericVariableUse(StringRef Name, bool IsPseudo,
+ const SourceMgr &SM) const {
if (IsPseudo && !Name.equals("@LINE"))
- return ErrorDiagnostic::get(
+ return FileCheckErrorDiagnostic::get(
SM, Name, "invalid pseudo numeric variable '" + Name + "'");
// Numeric variable definitions and uses are parsed in the order in which
@@ -161,7 +173,7 @@ Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse(
// uses of undefined variables, whether string or numeric, are then diagnosed
// in printSubstitutions() after failing to match.
auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
- NumericVariable *NumericVariable;
+ FileCheckNumericVariable *NumericVariable;
if (VarTableIter != Context->GlobalNumericVariableTable.end())
NumericVariable = VarTableIter->second;
else {
@@ -171,25 +183,23 @@ Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse(
Optional<size_t> DefLineNumber = NumericVariable->getDefLineNumber();
if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber)
- return ErrorDiagnostic::get(
+ return FileCheckErrorDiagnostic::get(
SM, Name,
- "numeric variable '" + Name +
- "' defined earlier in the same CHECK directive");
+ "numeric variable '" + Name + "' defined on the same line as used");
- return std::make_unique<NumericVariableUse>(Name, NumericVariable);
+ return llvm::make_unique<FileCheckNumericVariableUse>(Name, NumericVariable);
}
-Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
- StringRef &Expr, AllowedOperand AO, Optional<size_t> LineNumber,
- FileCheckPatternContext *Context, const SourceMgr &SM) {
+Expected<std::unique_ptr<FileCheckExpressionAST>>
+FileCheckPattern::parseNumericOperand(StringRef &Expr, AllowedOperand AO,
+ const SourceMgr &SM) const {
if (AO == AllowedOperand::LineVar || AO == AllowedOperand::Any) {
// Try to parse as a numeric variable use.
- Expected<Pattern::VariableProperties> ParseVarResult =
+ Expected<FileCheckPattern::VariableProperties> ParseVarResult =
parseVariable(Expr, SM);
if (ParseVarResult)
return parseNumericVariableUse(ParseVarResult->Name,
- ParseVarResult->IsPseudo, LineNumber,
- Context, SM);
+ ParseVarResult->IsPseudo, SM);
if (AO == AllowedOperand::LineVar)
return ParseVarResult.takeError();
// Ignore the error and retry parsing as a literal.
@@ -199,10 +209,10 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
// Otherwise, parse it as a literal.
uint64_t LiteralValue;
if (!Expr.consumeInteger(/*Radix=*/10, LiteralValue))
- return std::make_unique<ExpressionLiteral>(LiteralValue);
+ return llvm::make_unique<FileCheckExpressionLiteral>(LiteralValue);
- return ErrorDiagnostic::get(SM, Expr,
- "invalid operand format '" + Expr + "'");
+ return FileCheckErrorDiagnostic::get(SM, Expr,
+ "invalid operand format '" + Expr + "'");
}
static uint64_t add(uint64_t LeftOp, uint64_t RightOp) {
@@ -213,10 +223,10 @@ static uint64_t sub(uint64_t LeftOp, uint64_t RightOp) {
return LeftOp - RightOp;
}
-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) {
+Expected<std::unique_ptr<FileCheckExpressionAST>>
+FileCheckPattern::parseBinop(StringRef &Expr,
+ std::unique_ptr<FileCheckExpressionAST> LeftOp,
+ bool IsLegacyLineExpr, const SourceMgr &SM) const {
Expr = Expr.ltrim(SpaceChars);
if (Expr.empty())
return std::move(LeftOp);
@@ -234,82 +244,82 @@ Pattern::parseBinop(StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp,
EvalBinop = sub;
break;
default:
- return ErrorDiagnostic::get(
+ return FileCheckErrorDiagnostic::get(
SM, OpLoc, Twine("unsupported operation '") + Twine(Operator) + "'");
}
// Parse right operand.
Expr = Expr.ltrim(SpaceChars);
if (Expr.empty())
- return ErrorDiagnostic::get(SM, Expr, "missing operand in expression");
+ return FileCheckErrorDiagnostic::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<ExpressionAST>> RightOpResult =
- parseNumericOperand(Expr, AO, LineNumber, Context, SM);
+ Expected<std::unique_ptr<FileCheckExpressionAST>> RightOpResult =
+ parseNumericOperand(Expr, AO, SM);
if (!RightOpResult)
return RightOpResult;
Expr = Expr.ltrim(SpaceChars);
- return std::make_unique<BinaryOperation>(EvalBinop, std::move(LeftOp),
- std::move(*RightOpResult));
+ return llvm::make_unique<FileCheckASTBinop>(EvalBinop, std::move(LeftOp),
+ std::move(*RightOpResult));
}
-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<ExpressionAST> ExpressionASTPointer = nullptr;
- StringRef DefExpr = StringRef();
+Expected<std::unique_ptr<FileCheckExpressionAST>>
+FileCheckPattern::parseNumericSubstitutionBlock(
+ StringRef Expr,
+ Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
+ bool IsLegacyLineExpr, const SourceMgr &SM) const {
+ // Parse the numeric variable definition.
DefinedNumericVariable = None;
- // Save variable definition expression if any.
size_t DefEnd = Expr.find(':');
if (DefEnd != StringRef::npos) {
- DefExpr = Expr.substr(0, DefEnd);
- Expr = Expr.substr(DefEnd + 1);
- }
+ StringRef DefExpr = Expr.substr(0, DefEnd);
+ StringRef UseExpr = Expr.substr(DefEnd + 1);
- // Parse the expression itself.
- Expr = Expr.ltrim(SpaceChars);
- if (!Expr.empty()) {
- // The first operand in a legacy @LINE expression is always the @LINE
- // pseudo variable.
- AllowedOperand AO =
- IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
- 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 ErrorDiagnostic::get(
- SM, Expr,
- "unexpected characters at end of expression '" + Expr + "'");
- }
- if (!ParseResult)
- return ParseResult;
- ExpressionASTPointer = std::move(*ParseResult);
- }
+ UseExpr = UseExpr.ltrim(SpaceChars);
+ if (!UseExpr.empty())
+ return FileCheckErrorDiagnostic::get(
+ SM, UseExpr,
+ "unexpected string after variable definition: '" + UseExpr + "'");
- // Parse the numeric variable definition.
- if (DefEnd != StringRef::npos) {
DefExpr = DefExpr.ltrim(SpaceChars);
- Expected<NumericVariable *> ParseResult =
+ Expected<FileCheckNumericVariable *> ParseResult =
parseNumericVariableDefinition(DefExpr, Context, LineNumber, SM);
-
if (!ParseResult)
return ParseResult.takeError();
DefinedNumericVariable = *ParseResult;
+
+ return nullptr;
}
- return std::move(ExpressionASTPointer);
+ // Parse the expression itself.
+ Expr = Expr.ltrim(SpaceChars);
+ // The first operand in a legacy @LINE expression is always the @LINE pseudo
+ // variable.
+ AllowedOperand AO =
+ IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
+ Expected<std::unique_ptr<FileCheckExpressionAST>> ParseResult =
+ parseNumericOperand(Expr, AO, SM);
+ while (ParseResult && !Expr.empty()) {
+ ParseResult =
+ parseBinop(Expr, std::move(*ParseResult), IsLegacyLineExpr, SM);
+ // Legacy @LINE expressions only allow 2 operands.
+ if (ParseResult && IsLegacyLineExpr && !Expr.empty())
+ return FileCheckErrorDiagnostic::get(
+ SM, Expr,
+ "unexpected characters at end of expression '" + Expr + "'");
+ }
+ if (!ParseResult)
+ return ParseResult;
+ return std::move(*ParseResult);
}
-bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
- SourceMgr &SM, const FileCheckRequest &Req) {
+bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
+ SourceMgr &SM,
+ const FileCheckRequest &Req) {
bool MatchFullLinesHere = Req.MatchFullLines && CheckTy != Check::CheckNot;
- IgnoreCase = Req.IgnoreCase;
PatternLoc = SMLoc::getFromPointer(PatternStr.data());
@@ -386,15 +396,14 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
continue;
}
- // String and numeric substitution blocks. Pattern substitution blocks come
+ // String and numeric substitution blocks. String substitution blocks come
// in two forms: [[foo:.*]] and [[foo]]. The former matches .* (or some
// other regex) and assigns it to the string variable 'foo'. The latter
- // substitutes foo's value. Numeric substitution blocks recognize the same
- // form as string ones, but start with a '#' sign after the double
- // brackets. They also accept a combined form which sets a numeric variable
- // to the evaluation of an expression. Both string and numeric variable
- // names must satisfy the regular expression "[a-zA-Z_][0-9a-zA-Z_]*" to be
- // valid, as this helps catch some common errors.
+ // substitutes foo's value. Numeric substitution blocks work the same way
+ // as string ones, but start with a '#' sign after the double brackets.
+ // Both string and numeric variable names must satisfy the regular
+ // expression "[a-zA-Z_][0-9a-zA-Z_]*" to be valid, as this helps catch
+ // some common errors.
if (PatternStr.startswith("[[")) {
StringRef UnparsedPatternStr = PatternStr.substr(2);
// Find the closing bracket pair ending the match. End is going to be an
@@ -415,7 +424,6 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
PatternStr = UnparsedPatternStr.substr(End + 2);
bool IsDefinition = false;
- bool SubstNeeded = false;
// Whether the substitution block is a legacy use of @LINE with string
// substitution block syntax.
bool IsLegacyLineExpr = false;
@@ -436,7 +444,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
// Get the name (e.g. "foo") and verify it is well formed.
StringRef OrigMatchStr = MatchStr;
- Expected<Pattern::VariableProperties> ParseVarResult =
+ Expected<FileCheckPattern::VariableProperties> ParseVarResult =
parseVariable(MatchStr, SM);
if (!ParseVarResult) {
logAllUnhandledErrors(ParseVarResult.takeError(), errs());
@@ -446,7 +454,6 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
bool IsPseudo = ParseVarResult->IsPseudo;
IsDefinition = (VarEndIdx != StringRef::npos);
- SubstNeeded = !IsDefinition;
if (IsDefinition) {
if ((IsPseudo || !MatchStr.consume_front(":"))) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
@@ -476,66 +483,27 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
}
// Parse numeric substitution block.
- std::unique_ptr<ExpressionAST> ExpressionASTPointer;
- Optional<NumericVariable *> DefinedNumericVariable;
+ std::unique_ptr<FileCheckExpressionAST> ExpressionAST;
+ Optional<FileCheckNumericVariable *> DefinedNumericVariable;
if (IsNumBlock) {
- Expected<std::unique_ptr<ExpressionAST>> ParseResult =
+ Expected<std::unique_ptr<FileCheckExpressionAST>> ParseResult =
parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable,
- IsLegacyLineExpr, LineNumber, Context,
- SM);
+ IsLegacyLineExpr, SM);
if (!ParseResult) {
logAllUnhandledErrors(ParseResult.takeError(), errs());
return true;
}
- ExpressionASTPointer = std::move(*ParseResult);
- SubstNeeded = ExpressionASTPointer != nullptr;
+ ExpressionAST = std::move(*ParseResult);
if (DefinedNumericVariable) {
IsDefinition = true;
DefName = (*DefinedNumericVariable)->getName();
- }
- if (SubstNeeded)
+ MatchRegexp = StringRef("[0-9]+");
+ } else
SubstStr = MatchStr;
- else
- MatchRegexp = "[0-9]+";
- }
-
- // Handle variable definition: [[<def>:(...)]] and [[#(...)<def>:(...)]].
- if (IsDefinition) {
- RegExStr += '(';
- ++SubstInsertIdx;
-
- if (IsNumBlock) {
- NumericVariableMatch NumericVariableDefinition = {
- *DefinedNumericVariable, CurParen};
- NumericVariableDefs[DefName] = NumericVariableDefinition;
- // This store is done here rather than in match() to allow
- // parseNumericVariableUse() to get the pointer to the class instance
- // of the right variable definition corresponding to a given numeric
- // variable use.
- Context->GlobalNumericVariableTable[DefName] =
- *DefinedNumericVariable;
- } else {
- VariableDefs[DefName] = CurParen;
- // Mark string variable as defined to detect collisions between
- // string and numeric variables in parseNumericVariableUse() and
- // defineCmdlineVariables() when the latter is created later than the
- // former. We cannot reuse GlobalVariableTable for this by populating
- // it with an empty string since we would then lose the ability to
- // detect the use of an undefined variable in match().
- Context->DefinedVariableTable[DefName] = true;
- }
-
- ++CurParen;
}
- if (!MatchRegexp.empty() && AddRegExToRegEx(MatchRegexp, CurParen, SM))
- return true;
-
- if (IsDefinition)
- RegExStr += ')';
-
// Handle substitutions: [[foo]] and [[#<foo expr>]].
- if (SubstNeeded) {
+ if (!IsDefinition) {
// Handle substitution of string variables that were defined earlier on
// the same line by emitting a backreference. Expressions do not
// support substituting a numeric variable defined on the same line.
@@ -551,15 +519,44 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
} else {
// Handle substitution of string variables ([[<var>]]) defined in
// previous CHECK patterns, and substitution of expressions.
- Substitution *Substitution =
+ FileCheckSubstitution *Substitution =
IsNumBlock
? Context->makeNumericSubstitution(
- SubstStr, std::move(ExpressionASTPointer),
- SubstInsertIdx)
+ SubstStr, std::move(ExpressionAST), SubstInsertIdx)
: Context->makeStringSubstitution(SubstStr, SubstInsertIdx);
Substitutions.push_back(Substitution);
}
+ continue;
}
+
+ // Handle variable definitions: [[<def>:(...)]] and
+ // [[#(...)<def>:(...)]].
+ if (IsNumBlock) {
+ FileCheckNumericVariableMatch NumericVariableDefinition = {
+ *DefinedNumericVariable, CurParen};
+ NumericVariableDefs[DefName] = NumericVariableDefinition;
+ // This store is done here rather than in match() to allow
+ // parseNumericVariableUse() to get the pointer to the class instance
+ // of the right variable definition corresponding to a given numeric
+ // variable use.
+ Context->GlobalNumericVariableTable[DefName] = *DefinedNumericVariable;
+ } else {
+ VariableDefs[DefName] = CurParen;
+ // Mark the string variable as defined to detect collisions between
+ // string and numeric variables in parseNumericVariableUse() and
+ // DefineCmdlineVariables() when the latter is created later than the
+ // former. We cannot reuse GlobalVariableTable for this by populating
+ // it with an empty string since we would then lose the ability to
+ // detect the use of an undefined variable in match().
+ Context->DefinedVariableTable[DefName] = true;
+ }
+ RegExStr += '(';
+ ++CurParen;
+
+ if (AddRegExToRegEx(MatchRegexp, CurParen, SM))
+ return true;
+
+ RegExStr += ')';
}
// Handle fixed string matches.
@@ -579,7 +576,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
return false;
}
-bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
+bool FileCheckPattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
Regex R(RS);
std::string Error;
if (!R.isValid(Error)) {
@@ -593,14 +590,14 @@ bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) {
return false;
}
-void Pattern::AddBackrefToRegEx(unsigned BackrefNum) {
+void FileCheckPattern::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> Pattern::match(StringRef Buffer, size_t &MatchLen,
- const SourceMgr &SM) const {
+Expected<size_t> FileCheckPattern::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;
@@ -610,10 +607,9 @@ Expected<size_t> Pattern::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 = Buffer.find(FixedStr);
if (Pos == StringRef::npos)
- return make_error<NotFoundError>();
+ return make_error<FileCheckNotFoundError>();
return Pos;
}
@@ -635,8 +631,10 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen,
for (const auto &Substitution : Substitutions) {
// Substitute and check for failure (e.g. use of undefined variable).
Expected<std::string> Value = Substitution->getResult();
- if (!Value)
+ if (!Value) {
+ Context->LineVariable->clearValue();
return Value.takeError();
+ }
// Plop it into the regex at the adjusted offset.
TmpStr.insert(TmpStr.begin() + Substitution->getIndex() + InsertOffset,
@@ -646,14 +644,12 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen,
// Match the newly constructed regex.
RegExToMatch = TmpStr;
+ Context->LineVariable->clearValue();
}
SmallVector<StringRef, 4> MatchInfo;
- unsigned int Flags = Regex::Newline;
- if (IgnoreCase)
- Flags |= Regex::IgnoreCase;
- if (!Regex(RegExToMatch, Flags).match(Buffer, &MatchInfo))
- return make_error<NotFoundError>();
+ if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
+ return make_error<FileCheckNotFoundError>();
// Successful regex match.
assert(!MatchInfo.empty() && "Didn't get any match");
@@ -668,18 +664,18 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen,
// If this defines any numeric variables, remember their values.
for (const auto &NumericVariableDef : NumericVariableDefs) {
- const NumericVariableMatch &NumericVariableMatch =
+ const FileCheckNumericVariableMatch &NumericVariableMatch =
NumericVariableDef.getValue();
unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup;
assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error");
- NumericVariable *DefinedNumericVariable =
+ FileCheckNumericVariable *DefinedNumericVariable =
NumericVariableMatch.DefinedNumericVariable;
StringRef MatchedValue = MatchInfo[CaptureParenGroup];
uint64_t Val;
if (MatchedValue.getAsInteger(10, Val))
- return ErrorDiagnostic::get(SM, MatchedValue,
- "Unable to represent numeric value");
+ return FileCheckErrorDiagnostic::get(SM, MatchedValue,
+ "Unable to represent numeric value");
DefinedNumericVariable->setValue(Val);
}
@@ -691,7 +687,7 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen,
return FullMatch.data() - Buffer.data() + MatchStartSkip;
}
-unsigned Pattern::computeMatchDistance(StringRef Buffer) const {
+unsigned FileCheckPattern::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.
//
@@ -708,8 +704,8 @@ unsigned Pattern::computeMatchDistance(StringRef Buffer) const {
return BufferPrefix.edit_distance(ExampleString);
}
-void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
- SMRange MatchRange) const {
+void FileCheckPattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
+ SMRange MatchRange) const {
// Print what we know about substitutions.
if (!Substitutions.empty()) {
for (const auto &Substitution : Substitutions) {
@@ -721,10 +717,11 @@ void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
// variables it uses.
if (!MatchedValue) {
bool UndefSeen = false;
- handleAllErrors(MatchedValue.takeError(), [](const NotFoundError &E) {},
+ handleAllErrors(MatchedValue.takeError(),
+ [](const FileCheckNotFoundError &E) {},
// Handled in PrintNoMatch().
- [](const ErrorDiagnostic &E) {},
- [&](const UndefVarError &E) {
+ [](const FileCheckErrorDiagnostic &E) {},
+ [&](const FileCheckUndefVarError &E) {
if (!UndefSeen) {
OS << "uses undefined variable(s):";
UndefSeen = true;
@@ -767,8 +764,9 @@ static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy,
return Range;
}
-void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
- std::vector<FileCheckDiag> *Diags) const {
+void FileCheckPattern::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
@@ -817,34 +815,36 @@ Expected<StringRef>
FileCheckPatternContext::getPatternVarValue(StringRef VarName) {
auto VarIter = GlobalVariableTable.find(VarName);
if (VarIter == GlobalVariableTable.end())
- return make_error<UndefVarError>(VarName);
+ return make_error<FileCheckUndefVarError>(VarName);
return VarIter->second;
}
template <class... Types>
-NumericVariable *FileCheckPatternContext::makeNumericVariable(Types... args) {
- NumericVariables.push_back(std::make_unique<NumericVariable>(args...));
+FileCheckNumericVariable *
+FileCheckPatternContext::makeNumericVariable(Types... args) {
+ NumericVariables.push_back(
+ llvm::make_unique<FileCheckNumericVariable>(args...));
return NumericVariables.back().get();
}
-Substitution *
+FileCheckSubstitution *
FileCheckPatternContext::makeStringSubstitution(StringRef VarName,
size_t InsertIdx) {
Substitutions.push_back(
- std::make_unique<StringSubstitution>(this, VarName, InsertIdx));
+ llvm::make_unique<FileCheckStringSubstitution>(this, VarName, InsertIdx));
return Substitutions.back().get();
}
-Substitution *FileCheckPatternContext::makeNumericSubstitution(
+FileCheckSubstitution *FileCheckPatternContext::makeNumericSubstitution(
StringRef ExpressionStr,
- std::unique_ptr<ExpressionAST> ExpressionASTPointer, size_t InsertIdx) {
- Substitutions.push_back(std::make_unique<NumericSubstitution>(
- this, ExpressionStr, std::move(ExpressionASTPointer), InsertIdx));
+ std::unique_ptr<FileCheckExpressionAST> ExpressionAST, size_t InsertIdx) {
+ Substitutions.push_back(llvm::make_unique<FileCheckNumericSubstitution>(
+ this, ExpressionStr, std::move(ExpressionAST), InsertIdx));
return Substitutions.back().get();
}
-size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
+size_t FileCheckPattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) {
// Offset keeps track of the current offset within the input Str
size_t Offset = 0;
// [...] Nesting depth
@@ -1108,24 +1108,18 @@ void FileCheckPatternContext::createLineVariable() {
GlobalNumericVariableTable[LineName] = LineVariable;
}
-FileCheck::FileCheck(FileCheckRequest Req)
- : Req(Req), PatternContext(std::make_unique<FileCheckPatternContext>()),
- CheckStrings(std::make_unique<std::vector<FileCheckString>>()) {}
-
-FileCheck::~FileCheck() = default;
-
-bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
- Regex &PrefixRE) {
+bool FileCheck::ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
+ std::vector<FileCheckString> &CheckStrings) {
Error DefineError =
- PatternContext->defineCmdlineVariables(Req.GlobalDefines, SM);
+ PatternContext.defineCmdlineVariables(Req.GlobalDefines, SM);
if (DefineError) {
logAllUnhandledErrors(std::move(DefineError), errs());
return true;
}
- PatternContext->createLineVariable();
+ PatternContext.createLineVariable();
- std::vector<Pattern> ImplicitNegativeChecks;
+ std::vector<FileCheckPattern> 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.
@@ -1139,12 +1133,12 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
ImplicitNegativeChecks.push_back(
- Pattern(Check::CheckNot, PatternContext.get()));
+ FileCheckPattern(Check::CheckNot, &PatternContext));
ImplicitNegativeChecks.back().parsePattern(PatternInBuffer,
"IMPLICIT-CHECK", SM, Req);
}
- std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks;
+ std::vector<FileCheckPattern> DagNotMatches = ImplicitNegativeChecks;
// LineNumber keeps track of the line on which CheckPrefix instances are
// found.
@@ -1202,7 +1196,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data());
// Parse the pattern.
- Pattern P(CheckTy, PatternContext.get(), LineNumber);
+ FileCheckPattern P(CheckTy, &PatternContext, LineNumber);
if (P.parsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, Req))
return true;
@@ -1220,7 +1214,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
// Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them.
if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame ||
CheckTy == Check::CheckEmpty) &&
- CheckStrings->empty()) {
+ CheckStrings.empty()) {
StringRef Type = CheckTy == Check::CheckNext
? "NEXT"
: CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME";
@@ -1238,21 +1232,21 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
}
// Okay, add the string we captured to the output vector and move on.
- CheckStrings->emplace_back(P, UsedPrefix, PatternLoc);
- std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
+ CheckStrings.emplace_back(P, UsedPrefix, PatternLoc);
+ std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
DagNotMatches = ImplicitNegativeChecks;
}
// Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first
// prefix as a filler for the error message.
if (!DagNotMatches.empty()) {
- CheckStrings->emplace_back(
- Pattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1),
+ CheckStrings.emplace_back(
+ FileCheckPattern(Check::CheckEOF, &PatternContext, LineNumber + 1),
*Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data()));
- std::swap(DagNotMatches, CheckStrings->back().DagNotStrings);
+ std::swap(DagNotMatches, CheckStrings.back().DagNotStrings);
}
- if (CheckStrings->empty()) {
+ if (CheckStrings.empty()) {
errs() << "error: no check strings found with prefix"
<< (Req.CheckPrefixes.size() > 1 ? "es " : " ");
auto I = Req.CheckPrefixes.begin();
@@ -1272,7 +1266,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
}
static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM,
- StringRef Prefix, SMLoc Loc, const Pattern &Pat,
+ StringRef Prefix, SMLoc Loc, const FileCheckPattern &Pat,
int MatchedCount, StringRef Buffer, size_t MatchPos,
size_t MatchLen, const FileCheckRequest &Req,
std::vector<FileCheckDiag> *Diags) {
@@ -1318,10 +1312,10 @@ static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM,
}
static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
- StringRef Prefix, SMLoc Loc, const Pattern &Pat,
- int MatchedCount, StringRef Buffer,
- bool VerboseVerbose, std::vector<FileCheckDiag> *Diags,
- Error MatchErrors) {
+ StringRef Prefix, SMLoc Loc,
+ const FileCheckPattern &Pat, int MatchedCount,
+ StringRef Buffer, bool VerboseVerbose,
+ std::vector<FileCheckDiag> *Diags, Error MatchErrors) {
assert(MatchErrors && "Called on successful match");
bool PrintDiag = true;
if (!ExpectedMatch) {
@@ -1347,8 +1341,9 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM,
return;
}
- MatchErrors = handleErrors(std::move(MatchErrors),
- [](const ErrorDiagnostic &E) { E.log(errs()); });
+ MatchErrors =
+ handleErrors(std::move(MatchErrors),
+ [](const FileCheckErrorDiagnostic &E) { E.log(errs()); });
// No problem matching the string per se.
if (!MatchErrors)
@@ -1412,7 +1407,7 @@ size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
FileCheckRequest &Req,
std::vector<FileCheckDiag> *Diags) const {
size_t LastPos = 0;
- std::vector<const Pattern *> NotStrings;
+ std::vector<const FileCheckPattern *> NotStrings;
// IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
// bounds; we have not processed variable definitions within the bounded block
@@ -1550,11 +1545,11 @@ bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
return false;
}
-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) {
+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) {
assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!");
size_t MatchLen = 0;
@@ -1576,10 +1571,11 @@ bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer,
return false;
}
-size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
- std::vector<const Pattern *> &NotStrings,
- const FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) const {
+size_t
+FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
+ std::vector<const FileCheckPattern *> &NotStrings,
+ const FileCheckRequest &Req,
+ std::vector<FileCheckDiag> *Diags) const {
if (DagNotStrings.empty())
return 0;
@@ -1599,7 +1595,7 @@ size_t 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 Pattern &Pat = *PatItr;
+ const FileCheckPattern &Pat = *PatItr;
assert((Pat.getCheckTy() == Check::CheckDAG ||
Pat.getCheckTy() == Check::CheckNot) &&
"Invalid CHECK-DAG or CHECK-NOT!");
@@ -1708,7 +1704,7 @@ size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
// A check prefix must contain only alphanumeric, hyphens and underscores.
static bool ValidateCheckPrefix(StringRef CheckPrefix) {
- static const Regex Validator("^[a-zA-Z0-9_-]*$");
+ Regex Validator("^[a-zA-Z0-9_-]*$");
return Validator.match(CheckPrefix);
}
@@ -1763,32 +1759,11 @@ Error FileCheckPatternContext::defineCmdlineVariables(
unsigned I = 0;
Error Errs = Error::success();
std::string CmdlineDefsDiag;
- SmallVector<std::pair<size_t, size_t>, 4> CmdlineDefsIndices;
- for (StringRef CmdlineDef : CmdlineDefines) {
- std::string DefPrefix = ("Global define #" + Twine(++I) + ": ").str();
- size_t EqIdx = CmdlineDef.find('=');
- if (EqIdx == StringRef::npos) {
- CmdlineDefsIndices.push_back(std::make_pair(CmdlineDefsDiag.size(), 0));
- continue;
- }
- // Numeric variable definition.
- if (CmdlineDef[0] == '#') {
- // Append a copy of the command-line definition adapted to use the same
- // format as in the input file to be able to reuse
- // parseNumericSubstitutionBlock.
- CmdlineDefsDiag += (DefPrefix + CmdlineDef + " (parsed as: [[").str();
- std::string SubstitutionStr = CmdlineDef;
- SubstitutionStr[EqIdx] = ':';
- CmdlineDefsIndices.push_back(
- std::make_pair(CmdlineDefsDiag.size(), SubstitutionStr.size()));
- CmdlineDefsDiag += (SubstitutionStr + Twine("]])\n")).str();
- } else {
- CmdlineDefsDiag += DefPrefix;
- CmdlineDefsIndices.push_back(
- std::make_pair(CmdlineDefsDiag.size(), CmdlineDef.size()));
- CmdlineDefsDiag += (CmdlineDef + "\n").str();
- }
- }
+ StringRef Prefix1 = "Global define #";
+ StringRef Prefix2 = ": ";
+ for (StringRef CmdlineDef : CmdlineDefines)
+ CmdlineDefsDiag +=
+ (Prefix1 + Twine(++I) + Prefix2 + CmdlineDef + "\n").str();
// Create a buffer with fake command line content in order to display
// parsing diagnostic with location information and point to the
@@ -1798,55 +1773,55 @@ Error FileCheckPatternContext::defineCmdlineVariables(
StringRef CmdlineDefsDiagRef = CmdLineDefsDiagBuffer->getBuffer();
SM.AddNewSourceBuffer(std::move(CmdLineDefsDiagBuffer), SMLoc());
- for (std::pair<size_t, size_t> CmdlineDefIndices : CmdlineDefsIndices) {
- StringRef CmdlineDef = CmdlineDefsDiagRef.substr(CmdlineDefIndices.first,
- CmdlineDefIndices.second);
- if (CmdlineDef.empty()) {
+ SmallVector<StringRef, 4> CmdlineDefsDiagVec;
+ CmdlineDefsDiagRef.split(CmdlineDefsDiagVec, '\n', -1 /*MaxSplit*/,
+ false /*KeepEmpty*/);
+ for (StringRef CmdlineDefDiag : CmdlineDefsDiagVec) {
+ unsigned DefStart = CmdlineDefDiag.find(Prefix2) + Prefix2.size();
+ StringRef CmdlineDef = CmdlineDefDiag.substr(DefStart);
+ size_t EqIdx = CmdlineDef.find('=');
+ if (EqIdx == StringRef::npos) {
Errs = joinErrors(
std::move(Errs),
- ErrorDiagnostic::get(SM, CmdlineDef,
- "missing equal sign in global definition"));
+ FileCheckErrorDiagnostic::get(
+ SM, CmdlineDef, "missing equal sign in global definition"));
continue;
}
// Numeric variable definition.
if (CmdlineDef[0] == '#') {
- // 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<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());
+ StringRef CmdlineName = CmdlineDef.substr(1, EqIdx - 1);
+ Expected<FileCheckNumericVariable *> ParseResult =
+ FileCheckPattern::parseNumericVariableDefinition(CmdlineName, this,
+ None, SM);
+ if (!ParseResult) {
+ Errs = joinErrors(std::move(Errs), ParseResult.takeError());
continue;
}
- 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 = ExpressionASTPointer->eval();
- if (!Value) {
- Errs = joinErrors(std::move(Errs), Value.takeError());
+
+ StringRef CmdlineVal = CmdlineDef.substr(EqIdx + 1);
+ uint64_t Val;
+ if (CmdlineVal.getAsInteger(10, Val)) {
+ Errs = joinErrors(std::move(Errs),
+ FileCheckErrorDiagnostic::get(
+ SM, CmdlineVal,
+ "invalid value in numeric variable definition '" +
+ CmdlineVal + "'"));
continue;
}
-
- assert(DefinedNumericVariable && "No variable defined");
- (*DefinedNumericVariable)->setValue(*Value);
+ FileCheckNumericVariable *DefinedNumericVariable = *ParseResult;
+ DefinedNumericVariable->setValue(Val);
// Record this variable definition.
- GlobalNumericVariableTable[(*DefinedNumericVariable)->getName()] =
- *DefinedNumericVariable;
+ GlobalNumericVariableTable[DefinedNumericVariable->getName()] =
+ DefinedNumericVariable;
} else {
// String variable definition.
std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('=');
StringRef CmdlineName = CmdlineNameVal.first;
StringRef OrigCmdlineName = CmdlineName;
- Expected<Pattern::VariableProperties> ParseVarResult =
- Pattern::parseVariable(CmdlineName, SM);
+ Expected<FileCheckPattern::VariableProperties> ParseVarResult =
+ FileCheckPattern::parseVariable(CmdlineName, SM);
if (!ParseVarResult) {
Errs = joinErrors(std::move(Errs), ParseVarResult.takeError());
continue;
@@ -1856,7 +1831,7 @@ Error FileCheckPatternContext::defineCmdlineVariables(
// "FOO+2" in a "FOO+2=10" definition.
if (ParseVarResult->IsPseudo || !CmdlineName.empty()) {
Errs = joinErrors(std::move(Errs),
- ErrorDiagnostic::get(
+ FileCheckErrorDiagnostic::get(
SM, OrigCmdlineName,
"invalid name in string variable definition '" +
OrigCmdlineName + "'"));
@@ -1868,15 +1843,15 @@ Error FileCheckPatternContext::defineCmdlineVariables(
// is created later than the latter.
if (GlobalNumericVariableTable.find(Name) !=
GlobalNumericVariableTable.end()) {
- Errs = joinErrors(std::move(Errs),
- ErrorDiagnostic::get(SM, Name,
+ Errs = joinErrors(std::move(Errs), FileCheckErrorDiagnostic::get(
+ SM, Name,
"numeric variable with name '" +
Name + "' already exists"));
continue;
}
GlobalVariableTable.insert(CmdlineNameVal);
// Mark the string variable as defined to detect collisions between
- // string and numeric variables in defineCmdlineVariables when the latter
+ // string and numeric variables in DefineCmdlineVariables when the latter
// is created later than the former. We cannot reuse GlobalVariableTable
// for this by populating it with an empty string since we would then
// lose the ability to detect the use of an undefined variable in
@@ -1912,17 +1887,18 @@ void FileCheckPatternContext::clearLocalVars() {
GlobalNumericVariableTable.erase(Var);
}
-bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer,
+bool FileCheck::CheckInput(SourceMgr &SM, StringRef Buffer,
+ ArrayRef<FileCheckString> CheckStrings,
std::vector<FileCheckDiag> *Diags) {
bool ChecksFailed = false;
- unsigned i = 0, j = 0, e = CheckStrings->size();
+ unsigned i = 0, j = 0, e = CheckStrings.size();
while (true) {
StringRef CheckRegion;
if (j == e) {
CheckRegion = Buffer;
} else {
- const FileCheckString &CheckLabelStr = (*CheckStrings)[j];
+ const FileCheckString &CheckLabelStr = CheckStrings[j];
if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) {
++j;
continue;
@@ -1945,10 +1921,10 @@ bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer,
// CHECK-LABEL and it would clear variables defined on the command-line
// before they get used.
if (i != 0 && Req.EnableVarScope)
- PatternContext->clearLocalVars();
+ PatternContext.clearLocalVars();
for (; i != j; ++i) {
- const FileCheckString &CheckStr = (*CheckStrings)[i];
+ const FileCheckString &CheckStr = CheckStrings[i];
// Check each string within the scanned region, including a second check
// of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)