diff options
author | Thomas Preud'homme <thomasp@graphcore.ai> | 2019-07-05 16:25:46 +0000 |
---|---|---|
committer | Thomas Preud'homme <thomasp@graphcore.ai> | 2019-07-05 16:25:46 +0000 |
commit | 56f6308b2d8094fb8fa2a93f91f3ea90ee5d144b (patch) | |
tree | 81fac51c0b7394fd2ad4bf07cbba5b2a0373ba11 /llvm/lib/Support/FileCheck.cpp | |
parent | fe7ac170a7977079a6ce49e836bb0ab60455c986 (diff) | |
download | llvm-56f6308b2d8094fb8fa2a93f91f3ea90ee5d144b.zip llvm-56f6308b2d8094fb8fa2a93f91f3ea90ee5d144b.tar.gz llvm-56f6308b2d8094fb8fa2a93f91f3ea90ee5d144b.tar.bz2 |
[FileCheck] Share variable instance among uses
Summary:
This patch changes expression support to use one instance of
FileCheckNumericVariable per numeric variable rather than one per
variable and per definition. The current system was only necessary for
the last patch of the numeric expression support patch series in order
to handle a line using a variable defined earlier on the same line from
the input text. However this can be dealt more efficiently.
Reviewers: jhenderson, chandlerc, jdenny, probinson, grimar, arichardson, rnk
Subscribers: JonChesterfield, rogfer01, hfinkel, kristina, rnk, tra, arichardson, grimar, dblaikie, probinson, llvm-commits, hiraditya
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64229
llvm-svn: 365220
Diffstat (limited to 'llvm/lib/Support/FileCheck.cpp')
-rw-r--r-- | llvm/lib/Support/FileCheck.cpp | 67 |
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. |