aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/FileCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/FileCheck.cpp')
-rw-r--r--llvm/lib/Support/FileCheck.cpp67
1 files changed, 39 insertions, 28 deletions
diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp
index f93dde2..03e892af 100644
--- a/llvm/lib/Support/FileCheck.cpp
+++ b/llvm/lib/Support/FileCheck.cpp
@@ -110,14 +110,15 @@ char FileCheckUndefVarError::ID = 0;
char FileCheckErrorDiagnostic::ID = 0;
char FileCheckNotFoundError::ID = 0;
-Error FileCheckPattern::parseNumericVariableDefinition(
- StringRef &Expr, StringRef &Name, FileCheckPatternContext *Context,
+Expected<FileCheckNumericVariable *>
+FileCheckPattern::parseNumericVariableDefinition(
+ StringRef &Expr, FileCheckPatternContext *Context, size_t LineNumber,
const SourceMgr &SM) {
bool IsPseudo;
Expected<StringRef> ParseVarResult = parseVariable(Expr, IsPseudo, SM);
if (!ParseVarResult)
return ParseVarResult.takeError();
- Name = *ParseVarResult;
+ StringRef Name = *ParseVarResult;
if (IsPseudo)
return FileCheckErrorDiagnostic::get(
@@ -135,7 +136,14 @@ Error FileCheckPattern::parseNumericVariableDefinition(
return FileCheckErrorDiagnostic::get(
SM, Expr, "unexpected characters after numeric variable name");
- return Error::success();
+ FileCheckNumericVariable *DefinedNumericVariable;
+ auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
+ if (VarTableIter != Context->GlobalNumericVariableTable.end())
+ DefinedNumericVariable = VarTableIter->second;
+ else
+ DefinedNumericVariable = Context->makeNumericVariable(LineNumber, Name);
+
+ return DefinedNumericVariable;
}
Expected<FileCheckNumericVariable *>
@@ -154,12 +162,11 @@ FileCheckPattern::parseNumericVariableUse(StringRef &Expr,
// Numeric variable definitions and uses are parsed in the order in which
// they appear in the CHECK patterns. For each definition, the pointer to the
// class instance of the corresponding numeric variable definition is stored
- // in GlobalNumericVariableTable in parsePattern. Therefore, the pointer we
- // get below is for the class instance corresponding to the last definition
- // of this variable use. If we don't find a variable definition we create a
- // dummy one so that parsing can continue. All uses of undefined variables,
- // whether string or numeric, are then diagnosed in printSubstitutions()
- // after failing to match.
+ // in GlobalNumericVariableTable in parsePattern. Therefore, if the pointer
+ // we get below is null, it means no such variable was defined before. When
+ // that happens, we create a dummy variable so that parsing can continue. All
+ // 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;
if (VarTableIter != Context->GlobalNumericVariableTable.end())
@@ -249,11 +256,11 @@ Expected<FileCheckExpression *> FileCheckPattern::parseNumericSubstitutionBlock(
"unexpected string after variable definition: '" + UseExpr + "'");
DefExpr = DefExpr.ltrim(SpaceChars);
- StringRef Name;
- Error Err = parseNumericVariableDefinition(DefExpr, Name, Context, SM);
- if (Err)
- return std::move(Err);
- DefinedNumericVariable = Context->makeNumericVariable(LineNumber, Name);
+ Expected<FileCheckNumericVariable *> ParseResult =
+ parseNumericVariableDefinition(DefExpr, Context, LineNumber, SM);
+ if (!ParseResult)
+ return ParseResult.takeError();
+ DefinedNumericVariable = *ParseResult;
return Context->makeExpression(add, nullptr, 0);
}
@@ -270,13 +277,6 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
PatternLoc = SMLoc::getFromPointer(PatternStr.data());
- // Create fake @LINE pseudo variable definition.
- StringRef LinePseudo = "@LINE";
- uint64_t LineNumber64 = LineNumber;
- FileCheckNumericVariable *LinePseudoVar =
- Context->makeNumericVariable(LinePseudo, LineNumber64);
- Context->GlobalNumericVariableTable[LinePseudo] = LinePseudoVar;
-
if (!(Req.NoCanonicalizeWhiteSpace && Req.MatchFullLines))
// Ignore trailing whitespace.
while (!PatternStr.empty() &&
@@ -571,6 +571,7 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
std::string TmpStr;
if (!Substitutions.empty()) {
TmpStr = RegExStr;
+ Context->LineVariable->setValue(LineNumber);
size_t InsertOffset = 0;
// Substitute all string variables and expressions whose values are only
@@ -590,6 +591,7 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
// Match the newly constructed regex.
RegExToMatch = TmpStr;
+ Context->LineVariable->clearValue();
}
SmallVector<StringRef, 4> MatchInfo;
@@ -1058,6 +1060,13 @@ FindFirstMatchingPrefix(Regex &PrefixRE, StringRef &Buffer,
return {StringRef(), StringRef()};
}
+void FileCheckPatternContext::createLineVariable() {
+ assert(!LineVariable && "@LINE pseudo numeric variable already created");
+ StringRef LineName = "@LINE";
+ LineVariable = makeNumericVariable(0, LineName);
+ GlobalNumericVariableTable[LineName] = LineVariable;
+}
+
bool FileCheck::ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
std::vector<FileCheckString> &CheckStrings) {
Error DefineError =
@@ -1067,6 +1076,8 @@ bool FileCheck::ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
return true;
}
+ PatternContext.createLineVariable();
+
std::vector<FileCheckPattern> ImplicitNegativeChecks;
for (const auto &PatternString : Req.ImplicitCheckNot) {
// Create a buffer with fake command line content in order to display the
@@ -1739,11 +1750,11 @@ Error FileCheckPatternContext::defineCmdlineVariables(
// Numeric variable definition.
if (CmdlineDef[0] == '#') {
StringRef CmdlineName = CmdlineDef.substr(1, EqIdx - 1);
- StringRef VarName;
- Error ErrorDiagnostic = FileCheckPattern::parseNumericVariableDefinition(
- CmdlineName, VarName, this, SM);
- if (ErrorDiagnostic) {
- Errs = joinErrors(std::move(Errs), std::move(ErrorDiagnostic));
+ Expected<FileCheckNumericVariable *> ParseResult =
+ FileCheckPattern::parseNumericVariableDefinition(CmdlineName, this, 0,
+ SM);
+ if (!ParseResult) {
+ Errs = joinErrors(std::move(Errs), ParseResult.takeError());
continue;
}
@@ -1757,7 +1768,7 @@ Error FileCheckPatternContext::defineCmdlineVariables(
CmdlineVal + "'"));
continue;
}
- auto DefinedNumericVariable = makeNumericVariable(0, VarName);
+ FileCheckNumericVariable *DefinedNumericVariable = *ParseResult;
DefinedNumericVariable->setValue(Val);
// Record this variable definition.