[llvm] r366872 - Revert "FileCheck [8/12]: Define numeric var from expr"
Thomas Preud'homme via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 24 00:32:35 PDT 2019
Author: thopre
Date: Wed Jul 24 00:32:34 2019
New Revision: 366872
URL: http://llvm.org/viewvc/llvm-project?rev=366872&view=rev
Log:
Revert "FileCheck [8/12]: Define numeric var from expr"
This reverts commit 1b05977538d9487aa845ee2f3bec8b89c63c4f29.
Modified:
llvm/trunk/docs/CommandGuide/FileCheck.rst
llvm/trunk/include/llvm/Support/FileCheck.h
llvm/trunk/lib/Support/FileCheck.cpp
llvm/trunk/test/FileCheck/numeric-defines-diagnostics.txt
llvm/trunk/test/FileCheck/numeric-defines.txt
llvm/trunk/test/FileCheck/numeric-expression.txt
llvm/trunk/unittests/Support/FileCheckTest.cpp
Modified: llvm/trunk/docs/CommandGuide/FileCheck.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/FileCheck.rst?rev=366872&r1=366871&r2=366872&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/FileCheck.rst (original)
+++ llvm/trunk/docs/CommandGuide/FileCheck.rst Wed Jul 24 00:32:34 2019
@@ -107,12 +107,12 @@ and from the command line.
Sets a filecheck pattern variable ``VAR`` with value ``VALUE`` that can be
used in ``CHECK:`` lines.
-.. option:: -D#<NUMVAR>=<NUMERIC EXPRESSION>
+.. option:: -D#<NUMVAR>=<VALUE EXPRESSION>
Sets a filecheck numeric variable ``NUMVAR`` to the result of evaluating
- ``<NUMERIC EXPRESSION>`` that can be used in ``CHECK:`` lines. See section
- ``FileCheck Numeric Variables and Expressions`` for details on supported
- numeric expressions.
+ ``<VALUE EXPRESSION>`` that can be used in ``CHECK:`` lines. See section
+ ``FileCheck Numeric Variables and Expressions`` for details on the format
+ and meaning of ``<VALUE EXPRESSION>``.
.. option:: -version
@@ -625,27 +625,11 @@ but would not match the text:
due to ``7`` being unequal to ``5 + 1``.
-The syntax also supports an empty expression, equivalent to writing {{[0-9]+}},
-for cases where the input must contain a numeric value but the value itself
-does not matter:
-
-.. code-block:: gas
-
- ; CHECK-NOT: mov r0, r[[#]]
-
-to check that a value is synthesized rather than moved around.
-
-A numeric variable can also be defined to the result of a numeric expression,
-in which case the numeric expression is checked and if verified the variable is
-assigned to the value. The unified syntax for both defining numeric variables
-and checking a numeric expression is thus ``[[#<NUMVAR>: <expr>]]`` with each
-element as described previously.
-
The ``--enable-var-scope`` option has the same effect on numeric variables as
on string variables.
Important note: In its current implementation, an expression cannot use a
-numeric variable with a non-empty expression defined on the same line.
+numeric variable defined on the same line.
FileCheck Pseudo Numeric Variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: llvm/trunk/include/llvm/Support/FileCheck.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/FileCheck.h?rev=366872&r1=366871&r2=366872&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/FileCheck.h (original)
+++ llvm/trunk/include/llvm/Support/FileCheck.h Wed Jul 24 00:32:34 2019
@@ -94,11 +94,6 @@ private:
/// Name of the numeric variable.
StringRef Name;
- /// Pointer to expression defining this numeric variable. Null for pseudo
- /// variable whose value is known at parse time (e.g. @LINE pseudo variable)
- /// or cleared local variable.
- FileCheckExpressionAST *ExpressionAST;
-
/// Value of numeric variable, if defined, or None otherwise.
Optional<uint64_t> Value;
@@ -109,14 +104,10 @@ private:
public:
/// Constructor for a variable \p Name defined at line \p DefLineNumber or
- /// defined before input is parsed if \p DefLineNumber is None. If not null,
- /// the value set with setValue must match the result of evaluating
- /// \p ExpressionAST.
+ /// defined before input is parsed if DefLineNumber is None.
FileCheckNumericVariable(StringRef Name,
- Optional<size_t> DefLineNumber = None,
- FileCheckExpressionAST *ExpressionAST = nullptr)
- : Name(Name), ExpressionAST(ExpressionAST), DefLineNumber(DefLineNumber) {
- }
+ Optional<size_t> DefLineNumber = None)
+ : Name(Name), DefLineNumber(DefLineNumber) {}
/// \returns name of this numeric variable.
StringRef getName() const { return Name; }
@@ -124,25 +115,12 @@ public:
/// \returns this variable's value.
Optional<uint64_t> getValue() const { return Value; }
- /// \returns the pointer to the expression defining this numeric variable, if
- /// any, or null otherwise.
- FileCheckExpressionAST *getExpressionAST() const { return ExpressionAST; }
-
- /// \returns whether this variable's value is known when performing the
- /// substitutions of the line where it is defined.
- bool isValueKnownAtMatchTime() const;
-
- /// Sets value of this numeric variable to \p NewValue. Triggers an assertion
- /// failure if the variable is defined by an expression and the expression
- /// cannot be evaluated to be equal to \p NewValue.
- void setValue(uint64_t NewValue);
+ /// Sets value of this numeric variable to \p NewValue.
+ void setValue(uint64_t NewValue) { Value = NewValue; }
/// Clears value of this numeric variable, regardless of whether it is
/// currently defined or not.
- void clearValue() {
- Value = None;
- ExpressionAST = nullptr;
- }
+ void clearValue() { Value = None; }
/// \returns the line number where this variable is defined, if any, or None
/// if defined before input is parsed.
@@ -529,22 +507,27 @@ public:
/// \p Str from the variable name.
static Expected<VariableProperties> parseVariable(StringRef &Str,
const SourceMgr &SM);
- /// Parses \p Expr for a numeric substitution block at line \p LineNumber,
- /// or before input is parsed if \p LineNumber is None. Parameter
+ /// Parses \p Expr for the name of a numeric variable to be defined at line
+ /// \p LineNumber or before input is parsed if \p LineNumber is None.
+ /// \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(
+ StringRef &Expr, FileCheckPatternContext *Context,
+ Optional<size_t> LineNumber, const SourceMgr &SM);
+ /// Parses \p Expr for a numeric substitution block. Parameter
/// \p IsLegacyLineExpr indicates whether \p Expr should be a legacy @LINE
- /// expression and \p Context points to the class instance holding the live
- /// string and numeric variables. \returns a pointer to the class instance
- /// representing the AST of the expression whose value must be substitued, or
- /// an error holding a diagnostic against \p SM if parsing fails. If
- /// substitution was successful, sets \p DefinedNumericVariable to point to
- /// the class representing the numeric variable defined in this numeric
+ /// expression. \returns a pointer to the class instance representing the AST
+ /// of the expression whose value must be substituted, or an error holding a
+ /// diagnostic against \p SM if parsing fails. If substitution was
+ /// successful, sets \p DefinedNumericVariable to point to the class
+ /// representing the numeric variable being defined in this numeric
/// substitution block, or None if this block does not define any variable.
- static Expected<std::unique_ptr<FileCheckExpressionAST>>
+ Expected<std::unique_ptr<FileCheckExpressionAST>>
parseNumericSubstitutionBlock(
StringRef Expr,
Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
- bool IsLegacyLineExpr, Optional<size_t> LineNumber,
- FileCheckPatternContext *Context, const SourceMgr &SM);
+ bool IsLegacyLineExpr, const SourceMgr &SM) const;
/// Parses the pattern in \p PatternStr and initializes this FileCheckPattern
/// instance accordingly.
///
@@ -598,49 +581,28 @@ private:
/// was not found.
size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
- /// Parses \p Expr for the name of a numeric variable to be defined at line
- /// \p LineNumber, or before input is parsed if \p LineNumber is None.
- /// \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(
- StringRef &Expr, FileCheckPatternContext *Context,
- Optional<size_t> LineNumber, FileCheckExpressionAST *ExpressionAST,
- const SourceMgr &SM);
- /// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use
- /// at line \p LineNumber, or before input is parsed if \p LineNumber is
- /// None. Parameter \p Context points to the class instance holding the live
- /// 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>>
+ /// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use.
+ /// \returns the pointer to the class instance representing that variable if
+ /// successful, or an error holding a diagnostic against \p SM otherwise.
+ Expected<std::unique_ptr<FileCheckNumericVariableUse>>
parseNumericVariableUse(StringRef Name, bool IsPseudo,
- Optional<size_t> LineNumber,
- FileCheckPatternContext *Context,
- const SourceMgr &SM);
+ const SourceMgr &SM) const;
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
- /// values and numeric variables, depending on the value of \p AO. Parameter
- /// \p Context points to the class instance holding the live string and
- /// 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>>
+ /// Parses \p Expr for use of a numeric operand. Accepts both literal values
+ /// and numeric variables, depending on the value of \p AO. \returns the
+ /// class representing that operand in the AST of the expression or an error
+ /// holding a diagnostic against \p SM otherwise.
+ Expected<std::unique_ptr<FileCheckExpressionAST>>
parseNumericOperand(StringRef &Expr, AllowedOperand AO,
- Optional<size_t> LineNumber,
- FileCheckPatternContext *Context, const SourceMgr &SM);
- /// Parses \p Expr for a binary operation at line \p LineNumber, or before
- /// input is parsed if \p LineNumber is None. The left operand of this binary
+ const SourceMgr &SM) const;
+ /// Parses \p Expr for a binary operation. The left operand of this binary
/// operation is given in \p LeftOp and \p IsLegacyLineExpr indicates whether
- /// we are parsing a legacy @LINE expression. Parameter \p Context points to
- /// 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>>
+ /// we are parsing a legacy @LINE expression. \returns the class representing
+ /// the binary operation in the AST of the expression, or an error holding a
+ /// diagnostic against \p SM otherwise.
+ Expected<std::unique_ptr<FileCheckExpressionAST>>
parseBinop(StringRef &Expr, std::unique_ptr<FileCheckExpressionAST> LeftOp,
- bool IsLegacyLineExpr, Optional<size_t> LineNumber,
- FileCheckPatternContext *Context, const SourceMgr &SM);
+ bool IsLegacyLineExpr, const SourceMgr &SM) const;
};
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/Support/FileCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/FileCheck.cpp?rev=366872&r1=366871&r2=366872&view=diff
==============================================================================
--- llvm/trunk/lib/Support/FileCheck.cpp (original)
+++ llvm/trunk/lib/Support/FileCheck.cpp Wed Jul 24 00:32:34 2019
@@ -24,38 +24,11 @@
using namespace llvm;
-bool FileCheckNumericVariable::isValueKnownAtMatchTime() const {
- if (Value)
- return true;
-
- return ExpressionAST != nullptr;
-}
-
-void FileCheckNumericVariable::setValue(uint64_t NewValue) {
- if (ExpressionAST != nullptr) {
- // Caller is expected to call setValue only if substitution was successful.
- assert(NewValue == cantFail(ExpressionAST->eval(),
- "Failed to evaluate associated expression when "
- "sanity checking value") &&
- "Value being set to different from variable evaluation");
- }
- Value = NewValue;
- // Clear pointer to AST to ensure it is not used after the numeric
- // substitution defining this variable is processed since it's the
- // substitution that owns the pointer.
- ExpressionAST = nullptr;
-}
-
Expected<uint64_t> FileCheckNumericVariableUse::eval() const {
Optional<uint64_t> Value = NumericVariable->getValue();
if (Value)
return *Value;
-
- FileCheckExpressionAST *ExpressionAST = NumericVariable->getExpressionAST();
- if (!ExpressionAST)
- return make_error<FileCheckUndefVarError>(Name);
-
- return ExpressionAST->eval();
+ return make_error<FileCheckUndefVarError>(Name);
}
Expected<uint64_t> FileCheckASTBinop::eval() const {
@@ -141,8 +114,7 @@ char FileCheckNotFoundError::ID = 0;
Expected<FileCheckNumericVariable *>
FileCheckPattern::parseNumericVariableDefinition(
StringRef &Expr, FileCheckPatternContext *Context,
- Optional<size_t> LineNumber, FileCheckExpressionAST *ExpressionAST,
- const SourceMgr &SM) {
+ Optional<size_t> LineNumber, const SourceMgr &SM) {
Expected<VariableProperties> ParseVarResult = parseVariable(Expr, SM);
if (!ParseVarResult)
return ParseVarResult.takeError();
@@ -169,17 +141,14 @@ FileCheckPattern::parseNumericVariableDe
if (VarTableIter != Context->GlobalNumericVariableTable.end())
DefinedNumericVariable = VarTableIter->second;
else
- DefinedNumericVariable =
- Context->makeNumericVariable(Name, LineNumber, ExpressionAST);
+ DefinedNumericVariable = Context->makeNumericVariable(Name, LineNumber);
return DefinedNumericVariable;
}
Expected<std::unique_ptr<FileCheckNumericVariableUse>>
FileCheckPattern::parseNumericVariableUse(StringRef Name, bool IsPseudo,
- Optional<size_t> LineNumber,
- FileCheckPatternContext *Context,
- const SourceMgr &SM) {
+ const SourceMgr &SM) const {
if (IsPseudo && !Name.equals("@LINE"))
return FileCheckErrorDiagnostic::get(
SM, Name, "invalid pseudo numeric variable '" + Name + "'");
@@ -202,29 +171,24 @@ FileCheckPattern::parseNumericVariableUs
}
Optional<size_t> DefLineNumber = NumericVariable->getDefLineNumber();
- if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber &&
- !NumericVariable->isValueKnownAtMatchTime())
+ if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber)
return FileCheckErrorDiagnostic::get(
SM, Name,
- "numeric variable '" + Name +
- "' defined from input on the same line as used");
+ "numeric variable '" + Name + "' defined on the same line as used");
return llvm::make_unique<FileCheckNumericVariableUse>(Name, NumericVariable);
}
Expected<std::unique_ptr<FileCheckExpressionAST>>
FileCheckPattern::parseNumericOperand(StringRef &Expr, AllowedOperand AO,
- Optional<size_t> LineNumber,
- FileCheckPatternContext *Context,
- const SourceMgr &SM) {
+ const SourceMgr &SM) const {
if (AO == AllowedOperand::LineVar || AO == AllowedOperand::Any) {
// Try to parse as a numeric variable use.
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.
@@ -248,10 +212,10 @@ static uint64_t sub(uint64_t LeftOp, uin
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<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);
@@ -282,7 +246,7 @@ Expected<std::unique_ptr<FileCheckExpres
AllowedOperand AO =
IsLegacyLineExpr ? AllowedOperand::Literal : AllowedOperand::Any;
Expected<std::unique_ptr<FileCheckExpressionAST>> RightOpResult =
- parseNumericOperand(Expr, AO, LineNumber, Context, SM);
+ parseNumericOperand(Expr, AO, SM);
if (!RightOpResult)
return RightOpResult;
@@ -295,54 +259,50 @@ Expected<std::unique_ptr<FileCheckExpres
FileCheckPattern::parseNumericSubstitutionBlock(
StringRef Expr,
Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
- bool IsLegacyLineExpr, Optional<size_t> LineNumber,
- FileCheckPatternContext *Context, const SourceMgr &SM) {
- std::unique_ptr<FileCheckExpressionAST> ExpressionAST = nullptr;
- StringRef DefExpr = StringRef();
+ 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<FileCheckExpressionAST>> 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(
- SM, Expr,
- "unexpected characters at end of expression '" + Expr + "'");
- }
- if (!ParseResult)
- return ParseResult;
- ExpressionAST = 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<FileCheckNumericVariable *> ParseResult =
- parseNumericVariableDefinition(DefExpr, Context, LineNumber,
- ExpressionAST.get(), SM);
-
+ parseNumericVariableDefinition(DefExpr, Context, LineNumber, SM);
if (!ParseResult)
return ParseResult.takeError();
DefinedNumericVariable = *ParseResult;
+
+ return nullptr;
}
- return ExpressionAST;
+ // 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 FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
@@ -425,15 +385,14 @@ bool FileCheckPattern::parsePattern(Stri
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
@@ -454,7 +413,6 @@ bool FileCheckPattern::parsePattern(Stri
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;
@@ -485,7 +443,6 @@ bool FileCheckPattern::parsePattern(Stri
bool IsPseudo = ParseVarResult->IsPseudo;
IsDefinition = (VarEndIdx != StringRef::npos);
- SubstNeeded = !IsDefinition;
if (IsDefinition) {
if ((IsPseudo || !MatchStr.consume_front(":"))) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
@@ -520,61 +477,22 @@ bool FileCheckPattern::parsePattern(Stri
if (IsNumBlock) {
Expected<std::unique_ptr<FileCheckExpressionAST>> ParseResult =
parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable,
- IsLegacyLineExpr, LineNumber, Context,
- SM);
+ IsLegacyLineExpr, SM);
if (!ParseResult) {
logAllUnhandledErrors(ParseResult.takeError(), errs());
return true;
}
ExpressionAST = std::move(*ParseResult);
- SubstNeeded = ExpressionAST != nullptr;
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) {
- 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 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.
@@ -597,7 +515,37 @@ bool FileCheckPattern::parsePattern(Stri
: 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.
@@ -1797,32 +1745,11 @@ Error FileCheckPatternContext::defineCmd
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
@@ -1832,10 +1759,14 @@ Error FileCheckPatternContext::defineCmd
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),
FileCheckErrorDiagnostic::get(
@@ -1845,35 +1776,31 @@ Error FileCheckPatternContext::defineCmd
// 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<FileCheckNumericVariable *> DefinedNumericVariable;
- Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionASTResult =
- FileCheckPattern::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<FileCheckExpressionAST> ExpressionAST =
- 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();
- 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('=');
@@ -1910,7 +1837,7 @@ Error FileCheckPatternContext::defineCmd
}
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
Modified: llvm/trunk/test/FileCheck/numeric-defines-diagnostics.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/numeric-defines-diagnostics.txt?rev=366872&r1=366871&r2=366872&view=diff
==============================================================================
--- llvm/trunk/test/FileCheck/numeric-defines-diagnostics.txt (original)
+++ llvm/trunk/test/FileCheck/numeric-defines-diagnostics.txt Wed Jul 24 00:32:34 2019
@@ -4,22 +4,30 @@
RUN: not FileCheck -D#10VALUE=10 --input-file %s %s 2>&1 \
RUN: | FileCheck %s --strict-whitespace --check-prefix NUMERRCLIFMT
-NUMERRCLIFMT: Global defines:1:46: error: invalid variable name
-NUMERRCLIFMT-NEXT: Global define #1: #10VALUE=10 (parsed as: {{\[\[#10VALUE:10\]\]}})
-NUMERRCLIFMT-NEXT: {{^ \^$}}
+NUMERRCLIFMT: Global defines:1:20: error: invalid variable name
+NUMERRCLIFMT-NEXT: Global define #1: #10VALUE=10
+NUMERRCLIFMT-NEXT: {{^ \^$}}
; Invalid definition of pseudo variable.
RUN: not FileCheck -D#@VALUE=10 --input-file %s %s 2>&1 \
RUN: | FileCheck %s --strict-whitespace --check-prefix NUMERRCLIPSEUDO
-NUMERRCLIPSEUDO: Global defines:1:45: error: definition of pseudo numeric variable unsupported
-NUMERRCLIPSEUDO-NEXT: Global define #1: #@VALUE=10 (parsed as: {{\[\[#@VALUE:10\]\]}})
-NUMERRCLIPSEUDO-NEXT: {{^ \^$}}
+NUMERRCLIPSEUDO: Global defines:1:20: error: definition of pseudo numeric variable unsupported
+NUMERRCLIPSEUDO-NEXT: Global define #1: #@VALUE=10
+NUMERRCLIPSEUDO-NEXT: {{^ \^$}}
; Invalid definition of an expression.
RUN: not FileCheck -D#VALUE+2=10 --input-file %s %s 2>&1 \
RUN: | FileCheck %s --strict-whitespace --check-prefix NUMERRCLITRAIL
-NUMERRCLITRAIL: Global defines:1:51: error: unexpected characters after numeric variable name
-NUMERRCLITRAIL-NEXT: Global define #1: #VALUE+2=10 (parsed as: {{\[\[#VALUE\+2:10\]\]}})
-NUMERRCLITRAIL-NEXT: {{^ \^$}}
+NUMERRCLITRAIL: Global defines:1:25: error: unexpected characters after numeric variable name
+NUMERRCLITRAIL-NEXT: Global define #1: #VALUE+2=10
+NUMERRCLITRAIL-NEXT: {{^ \^$}}
+
+; Invalid value: numeric expression instead of literal.
+RUN: not FileCheck -D#VALUE1=3 -D#VALUE2='VALUE1 + 2' --input-file %s %s 2>&1 \
+RUN: | FileCheck %s --strict-whitespace --check-prefix NUMERRCLIEXPR
+
+NUMERRCLIEXPR: Global defines:2:27: error: invalid value in numeric variable definition 'VALUE1 + 2'
+NUMERRCLIEXPR-NEXT: Global define #2: #VALUE2=VALUE1 + 2
+NUMERRCLIEXPR-NEXT: {{^ \^$}}
Modified: llvm/trunk/test/FileCheck/numeric-defines.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/numeric-defines.txt?rev=366872&r1=366871&r2=366872&view=diff
==============================================================================
--- llvm/trunk/test/FileCheck/numeric-defines.txt (original)
+++ llvm/trunk/test/FileCheck/numeric-defines.txt Wed Jul 24 00:32:34 2019
@@ -1,38 +1,22 @@
; Test functionality of -D# option: numeric variables are defined to the right
; value and CHECK directives using them match as expected given the value set.
-RUN: FileCheck -D#NUMVAL1=8 -D#NUMVAL2='NUMVAL1 + 4' -check-prefixes CHECKNUM1,CHECKNUM2 -input-file %s %s
-RUN: not FileCheck -D#NUMVAL1=7 -D#NUMVAL2=12 -check-prefix CHECKNUM1 -input-file %s %s 2>&1 \
-RUN: | FileCheck %s --strict-whitespace -check-prefix NUMERRMSG1
-RUN: not FileCheck -D#NUMVAL1=8 -D#NUMVAL2=8 -check-prefix CHECKNUM2 -input-file %s %s 2>&1 \
-RUN: | FileCheck %s --strict-whitespace -check-prefix NUMERRMSG2
-RUN: not FileCheck -D#NUMVAL1=8 -D#NUMVAL2=8 -check-prefix NUMNOT -input-file %s %s 2>&1 \
-RUN: | FileCheck %s --strict-whitespace -check-prefixes NOT-NUMERRMSG1
-RUN: not FileCheck -D#NUMVAL1=7 -D#NUMVAL2=12 -check-prefix NUMNOT -input-file %s %s 2>&1 \
-RUN: | FileCheck %s --strict-whitespace -check-prefixes NOT-NUMERRMSG2
-RUN: FileCheck -D#NUMVAL1=7 -D#NUMVAL2=8 -check-prefixes NUMNOT -input-file %s %s
-
-Numeric value #1 = 8
-Numeric value #2 = 12
-CHECKNUM1: Numeric value #1 = [[#NUMVAL1]]
-CHECKNUM2: Numeric value #2 = [[#NUMVAL2]]
-NUMNOT-NOT: Numeric value #1 = [[#NUMVAL1]]
-NUMNOT-NOT: Numeric value #2 = [[#NUMVAL2]]
-
-NUMERRMSG1: defines.txt:[[#@LINE-5]]:12: error: CHECKNUM1: expected string not found in input
-NUMERRMSG1: defines.txt:1:1: note: scanning from here
-NUMERRMSG1: defines.txt:1:1: note: with "NUMVAL1" equal to "7"
-NUMERRMSG1: defines.txt:[[#@LINE-10]]:1: note: possible intended match here
-
-NUMERRMSG2: defines.txt:[[#@LINE-9]]:12: error: CHECKNUM2: expected string not found in input
-NUMERRMSG2: defines.txt:1:1: note: scanning from here
-NUMERRMSG2: defines.txt:1:1: note: with "NUMVAL2" equal to "8"
-NUMERRMSG2: defines.txt:[[#@LINE-14]]:1: note: possible intended match here
-
-NOT-NUMERRMSG1: defines.txt:[[#@LINE-13]]:13: error: {{NUMNOT}}-NOT: excluded string found in input
-NOT-NUMERRMSG1: defines.txt:[[#@LINE-18]]:1: note: found here
-NOT-NUMERRMSG1: defines.txt:[[#@LINE-19]]:1: note: with "NUMVAL1" equal to "8"
-
-NOT-NUMERRMSG2: defines.txt:[[#@LINE-16]]:13: error: {{NUMNOT}}-NOT: excluded string found in input
-NOT-NUMERRMSG2: defines.txt:[[#@LINE-21]]:1: note: found here
-NOT-NUMERRMSG2: defines.txt:[[#@LINE-22]]:1: note: with "NUMVAL2" equal to "12"
+RUN: FileCheck -D#NUMVAL=12 --check-prefix CHECKNUM --input-file %s %s
+RUN: not FileCheck -D#NUMVAL=8 --check-prefix CHECKNUM --input-file %s %s 2>&1 \
+RUN: | FileCheck %s --strict-whitespace --check-prefix NUMERRMSG
+RUN: not FileCheck -D#NUMVAL=12 --check-prefix NUMNOT --input-file %s %s 2>&1 \
+RUN: | FileCheck %s --strict-whitespace --check-prefix NOT-NUMERRMSG
+RUN: FileCheck -D#NUMVAL=8 --check-prefixes NUMNOT --input-file %s %s
+
+Numeric value = 12
+CHECKNUM: Numeric value = [[#NUMVAL]]
+NUMNOT-NOT: Numeric value = [[#NUMVAL]]
+
+NUMERRMSG: defines.txt:[[#@LINE-3]]:11: error: CHECKNUM: expected string not found in input
+NUMERRMSG: defines.txt:1:1: note: scanning from here
+NUMERRMSG: defines.txt:1:1: note: with "NUMVAL" equal to "8"
+NUMERRMSG: defines.txt:[[#@LINE-7]]:1: note: possible intended match here
+
+NOT-NUMERRMSG: defines.txt:[[#@LINE-7]]:13: error: {{NUMNOT}}-NOT: excluded string found in input
+NOT-NUMERRMSG: defines.txt:[[#@LINE-10]]:1: note: found here
+NOT-NUMERRMSG: defines.txt:[[#@LINE-11]]:1: note: with "NUMVAL" equal to "12"
Modified: llvm/trunk/test/FileCheck/numeric-expression.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FileCheck/numeric-expression.txt?rev=366872&r1=366871&r2=366872&view=diff
==============================================================================
--- llvm/trunk/test/FileCheck/numeric-expression.txt (original)
+++ llvm/trunk/test/FileCheck/numeric-expression.txt Wed Jul 24 00:32:34 2019
@@ -82,20 +82,6 @@ CHECK-LABEL: USE MULTI VAR
CHECK-NEXT: [[#VAR2:]]
CHECK-NEXT: [[#VAR1+VAR2]]
-; Numeric expression using a variable defined from a numeric expression.
-DEF EXPR GOOD MATCH
-42
-41 43
-; CHECK-LABEL: DEF EXPR GOOD MATCH
-; CHECK-NEXT: [[# VAR42:VAR1+31]]
-; CHECK-NEXT: [[# VAR41: VAR42-1]] [[# VAR41 + 2]]
-
-; Empty numeric expression.
-EMPTY NUM EXPR
-foo 104 bar
-; CHECK-LABEL: EMPTY NUM EXPR
-; CHECK-NEXT: foo [[#]] bar
-
; Numeric expression using undefined variables.
RUN: not FileCheck --check-prefix UNDEF-USE --input-file %s %s 2>&1 \
RUN: | FileCheck --strict-whitespace --check-prefix UNDEF-USE-MSG %s
@@ -159,9 +145,9 @@ CLI-STR-CONFLICT-NEXT: {{^
INPUT-NUM-CONFLICT: numeric-expression.txt:[[#@LINE-7]]:22: error: string variable with name 'STRVAR' already exists
INPUT-NUM-CONFLICT-NEXT: CONFLICT4: redef2 {{\[\[#STRVAR:\]\]}}
INPUT-NUM-CONFLICT-NEXT: {{^ \^$}}
-CLI-NUM-CONFLICT: Global defines:2:45: error: string variable with name 'STRVAR' already exists
-CLI-NUM-CONFLICT-NEXT: Global define #2: #STRVAR=42 (parsed as: {{\[\[#STRVAR:42\]\]}})
-CLI-NUM-CONFLICT-NEXT: {{^ \^$}}
+CLI-NUM-CONFLICT: Global defines:2:20: error: string variable with name 'STRVAR' already exists
+CLI-NUM-CONFLICT-NEXT: Global define #2: #STRVAR=42
+CLI-NUM-CONFLICT-NEXT: {{^ \^$}}
; Numeric variable definition with too big value.
RUN: not FileCheck --check-prefix BIGVAL --input-file %s %s 2>&1 \
@@ -174,18 +160,3 @@ BIGVAL-NEXT: NUMVAR: [[#NUMVAR:]]
BIGVAL-MSG: numeric-expression.txt:[[#@LINE-3]]:9: error: Unable to represent numeric value
BIGVAL-MSG-NEXT: {{N}}UMVAR: 10000000000000000000000
BIGVAL-MSG-NEXT: {{^ \^$}}
-
-; Verify that when a variable is set to an expression the expression is still
-; checked.
-RUN: not FileCheck --check-prefix DEF-EXPR-FAIL --input-file %s %s 2>&1 \
-RUN: | FileCheck --strict-whitespace --check-prefix DEF-EXPR-FAIL-MSG %s
-
-DEF EXPR WRONG MATCH
-20
-43
-DEF-EXPR-FAIL-LABEL: DEF EXPR WRONG MATCH
-DEF-EXPR-FAIL-NEXT: [[# VAR20:]]
-DEF-EXPR-FAIL-NEXT: [[# VAR42: VAR20+22]]
-DEF-EXPR-FAIL-MSG: numeric-expression.txt:[[#@LINE-1]]:21: error: {{D}}EF-EXPR-FAIL-NEXT: is not on the line after the previous match
-DEF-EXPR-FAIL-MSG-NEXT: {{D}}EF-EXPR-FAIL-NEXT: {{\[\[# VAR42: VAR20\+22\]\]}}
-DEF-EXPR-FAIL-MSG-NEXT: {{^ \^$}}
Modified: llvm/trunk/unittests/Support/FileCheckTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/FileCheckTest.cpp?rev=366872&r1=366871&r2=366872&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/FileCheckTest.cpp (original)
+++ llvm/trunk/unittests/Support/FileCheckTest.cpp Wed Jul 24 00:32:34 2019
@@ -49,21 +49,15 @@ expectUndefErrors(std::unordered_set<std
EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
}
-// Return whether Err contains any FileCheckUndefVarError whose associated name
-// is not ExpectedUndefVarName.
static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
}
-uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
-
TEST_F(FileCheckTest, NumericVariable) {
- // Undefined variable: isValueKnownAtMatchTime returns false, getValue and
- // eval fail, error returned by eval holds the name of the undefined
- // variable.
+ // Undefined variable: getValue and eval fail, error returned by eval holds
+ // the name of the undefined variable.
FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1);
EXPECT_EQ("FOO", FooVar.getName());
- EXPECT_FALSE(FooVar.isValueKnownAtMatchTime());
FileCheckNumericVariableUse FooVarUse =
FileCheckNumericVariableUse("FOO", &FooVar);
EXPECT_FALSE(FooVar.getValue());
@@ -73,9 +67,7 @@ TEST_F(FileCheckTest, NumericVariable) {
FooVar.setValue(42);
- // Defined variable: isValueKnownAtMatchTime returns true, getValue and eval
- // return value set.
- EXPECT_TRUE(FooVar.isValueKnownAtMatchTime());
+ // Defined variable: getValue and eval return value set.
Optional<uint64_t> Value = FooVar.getValue();
EXPECT_TRUE(bool(Value));
EXPECT_EQ(42U, *Value);
@@ -83,51 +75,24 @@ TEST_F(FileCheckTest, NumericVariable) {
EXPECT_TRUE(bool(EvalResult));
EXPECT_EQ(42U, *EvalResult);
- // Variable defined by numeric expression: isValueKnownAtMatchTime
- // returns true, getValue and eval return value of expression, setValue
- // clears expression.
- std::unique_ptr<FileCheckNumericVariableUse> FooVarUsePtr =
- llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
- std::unique_ptr<FileCheckExpressionLiteral> One =
- llvm::make_unique<FileCheckExpressionLiteral>(1);
- FileCheckASTBinop Binop =
- FileCheckASTBinop(doAdd, std::move(FooVarUsePtr), std::move(One));
- FileCheckNumericVariable FoobarExprVar =
- FileCheckNumericVariable("FOOBAR", 2, &Binop);
- EXPECT_TRUE(FoobarExprVar.isValueKnownAtMatchTime());
- EXPECT_FALSE(FoobarExprVar.getValue());
- FileCheckNumericVariableUse FoobarExprVarUse =
- FileCheckNumericVariableUse("FOOBAR", &FoobarExprVar);
- EvalResult = FoobarExprVarUse.eval();
- EXPECT_TRUE(bool(EvalResult));
- EXPECT_EQ(43U, *EvalResult);
- EXPECT_TRUE(FoobarExprVar.getExpressionAST());
- FoobarExprVar.setValue(43);
- EXPECT_FALSE(FoobarExprVar.getExpressionAST());
- FoobarExprVar = FileCheckNumericVariable("FOOBAR", 2, &Binop);
- EXPECT_TRUE(FoobarExprVar.getExpressionAST());
-
// Clearing variable: getValue and eval fail. Error returned by eval holds
// the name of the cleared variable.
FooVar.clearValue();
- FoobarExprVar.clearValue();
- EXPECT_FALSE(FoobarExprVar.getExpressionAST());
- EXPECT_FALSE(FooVar.getValue());
- EXPECT_FALSE(FoobarExprVar.getValue());
+ Value = FooVar.getValue();
+ EXPECT_FALSE(Value);
EvalResult = FooVarUse.eval();
EXPECT_FALSE(EvalResult);
expectUndefError("FOO", EvalResult.takeError());
- EvalResult = FoobarExprVarUse.eval();
- EXPECT_FALSE(EvalResult);
- expectUndefError("FOOBAR", EvalResult.takeError());
}
+uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
+
TEST_F(FileCheckTest, Binop) {
- FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1);
+ FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO");
FooVar.setValue(42);
std::unique_ptr<FileCheckNumericVariableUse> FooVarUse =
llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
- FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR", 2);
+ FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR");
BarVar.setValue(18);
std::unique_ptr<FileCheckNumericVariableUse> BarVarUse =
llvm::make_unique<FileCheckNumericVariableUse>("BAR", &BarVar);
@@ -272,13 +237,19 @@ public:
P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
}
+ bool parseNumVarDefExpect(StringRef Expr) {
+ StringRef ExprBufferRef = bufferize(SM, Expr);
+ return errorToBool(FileCheckPattern::parseNumericVariableDefinition(
+ ExprBufferRef, &Context, LineNumber, SM)
+ .takeError());
+ }
+
bool parseSubstExpect(StringRef Expr) {
StringRef ExprBufferRef = bufferize(SM, Expr);
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
- return errorToBool(
- P.parseNumericSubstitutionBlock(ExprBufferRef, DefinedNumericVariable,
- false, LineNumber - 1, &Context, SM)
- .takeError());
+ return errorToBool(P.parseNumericSubstitutionBlock(
+ ExprBufferRef, DefinedNumericVariable, false, SM)
+ .takeError());
}
bool parsePatternExpect(StringRef Pattern) {
@@ -293,6 +264,19 @@ public:
}
};
+TEST_F(FileCheckTest, ParseNumericVariableDefinition) {
+ PatternTester Tester;
+
+ // Invalid definition of pseudo.
+ EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE"));
+
+ // Conflict with pattern variable.
+ EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR"));
+
+ // Defined variable.
+ EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO"));
+}
+
TEST_F(FileCheckTest, ParseExpr) {
PatternTester Tester;
@@ -303,18 +287,17 @@ TEST_F(FileCheckTest, ParseExpr) {
EXPECT_TRUE(Tester.parseSubstExpect("@FOO:"));
EXPECT_TRUE(Tester.parseSubstExpect("@LINE:"));
- // Conflict with pattern variable.
- EXPECT_TRUE(Tester.parseSubstExpect("BAR:"));
-
// Garbage after name of variable being defined.
EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:"));
+ // Variable defined to numeric expression.
+ EXPECT_TRUE(Tester.parseSubstExpect("VAR1: FOO"));
+
// Acceptable variable definition.
EXPECT_FALSE(Tester.parseSubstExpect("VAR1:"));
EXPECT_FALSE(Tester.parseSubstExpect(" VAR2:"));
EXPECT_FALSE(Tester.parseSubstExpect("VAR3 :"));
EXPECT_FALSE(Tester.parseSubstExpect("VAR3: "));
- EXPECT_FALSE(Tester.parsePatternExpect("[[#FOOBAR: FOO+1]]"));
// Numeric expression.
@@ -327,21 +310,9 @@ TEST_F(FileCheckTest, ParseExpr) {
EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
- // Valid empty expression.
- EXPECT_FALSE(Tester.parseSubstExpect(""));
-
- // Valid use of variable defined on the same line from expression. Note that
- // the same pattern object is used for the parsePatternExpect and
- // parseSubstExpect since no initNextPattern is called, thus appearing as
- // being on the same line from the pattern's point of view.
- EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:FOO+1]]"));
- EXPECT_FALSE(Tester.parseSubstExpect("LINE1VAR"));
-
- // Invalid use of variable defined on same line from input. As above, the
- // absence of a call to initNextPattern makes it appear to be on the same
- // line from the pattern's point of view.
- EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE2VAR:]]"));
- EXPECT_TRUE(Tester.parseSubstExpect("LINE2VAR"));
+ // Use variable defined on same line.
+ EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
+ EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR"));
// Unsupported operator.
EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2"));
@@ -352,7 +323,6 @@ TEST_F(FileCheckTest, ParseExpr) {
// Valid expression.
EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5"));
EXPECT_FALSE(Tester.parseSubstExpect("FOO+4"));
- EXPECT_FALSE(Tester.parseSubstExpect("FOOBAR"));
Tester.initNextPattern();
EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+FOO]]"));
EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+3-FOO]]"));
@@ -384,6 +354,7 @@ TEST_F(FileCheckTest, ParsePattern) {
EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]"));
EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]"));
EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]"));
+ EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]"));
// Valid numeric expressions and numeric variable definition.
EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]"));
@@ -394,16 +365,9 @@ TEST_F(FileCheckTest, ParsePattern) {
TEST_F(FileCheckTest, Match) {
PatternTester Tester;
- // Check matching an empty expression only matches a number.
- Tester.parsePatternExpect("[[#]]");
- EXPECT_TRUE(Tester.matchExpect("FAIL"));
- EXPECT_FALSE(Tester.matchExpect("18"));
-
// Check matching a definition only matches a number.
- Tester.initNextPattern();
Tester.parsePatternExpect("[[#NUMVAR:]]");
EXPECT_TRUE(Tester.matchExpect("FAIL"));
- EXPECT_TRUE(Tester.matchExpect(""));
EXPECT_FALSE(Tester.matchExpect("18"));
// Check matching the variable defined matches the correct number only
@@ -417,16 +381,16 @@ TEST_F(FileCheckTest, Match) {
// the correct value for @LINE.
Tester.initNextPattern();
EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
- // Ok, @LINE is 5 now.
- EXPECT_FALSE(Tester.matchExpect("5"));
+ // Ok, @LINE is 4 now.
+ EXPECT_FALSE(Tester.matchExpect("4"));
Tester.initNextPattern();
- // @LINE is now 6, match with substitution failure.
+ // @LINE is now 5, match with substitution failure.
EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]"));
EXPECT_TRUE(Tester.matchExpect("FOO"));
Tester.initNextPattern();
- // Check that @LINE is 7 as expected.
+ // Check that @LINE is 6 as expected.
EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
- EXPECT_FALSE(Tester.matchExpect("7"));
+ EXPECT_FALSE(Tester.matchExpect("6"));
}
TEST_F(FileCheckTest, Substitution) {
@@ -446,9 +410,9 @@ TEST_F(FileCheckTest, Substitution) {
// Substitutions of defined pseudo and non-pseudo numeric variables return
// the right value.
- FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 1);
- FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 1);
+ FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE");
LineVar.setValue(42);
+ FileCheckNumericVariable NVar = FileCheckNumericVariable("N");
NVar.setValue(10);
auto LineVarUse =
llvm::make_unique<FileCheckNumericVariableUse>("@LINE", &LineVar);
@@ -530,29 +494,22 @@ TEST_F(FileCheckTest, FileCheckContext)
// Define local variables from command-line.
GlobalDefines.clear();
- // Clear local variables to remove dummy numeric variable x that
- // parseNumericSubstitutionBlock would have created and stored in
- // GlobalNumericVariableTable.
- Cxt.clearLocalVars();
GlobalDefines.emplace_back(std::string("LocalVar=FOO"));
GlobalDefines.emplace_back(std::string("EmptyVar="));
- GlobalDefines.emplace_back(std::string("#LocalNumVar1=18"));
- GlobalDefines.emplace_back(std::string("#LocalNumVar2=LocalNumVar1+2"));
+ GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
// Check defined variables are present and undefined is absent.
StringRef LocalVarStr = "LocalVar";
- StringRef LocalNumVar1Ref = bufferize(SM, "LocalNumVar1");
- StringRef LocalNumVar2Ref = bufferize(SM, "LocalNumVar2");
+ StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar");
StringRef EmptyVarStr = "EmptyVar";
StringRef UnknownVarStr = "UnknownVar";
Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1);
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionAST =
- P.parseNumericSubstitutionBlock(LocalNumVar1Ref, DefinedNumericVariable,
- /*IsLegacyLineExpr=*/false,
- /*LineNumber=*/1, &Cxt, SM);
+ P.parseNumericSubstitutionBlock(LocalNumVarRef, DefinedNumericVariable,
+ /*IsLegacyLineExpr=*/false, SM);
EXPECT_TRUE(bool(LocalVar));
EXPECT_EQ(*LocalVar, "FOO");
Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
@@ -561,14 +518,6 @@ TEST_F(FileCheckTest, FileCheckContext)
Expected<uint64_t> ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(bool(ExpressionVal));
EXPECT_EQ(*ExpressionVal, 18U);
- ExpressionAST =
- P.parseNumericSubstitutionBlock(LocalNumVar2Ref, DefinedNumericVariable,
- /*IsLegacyLineExpr=*/false,
- /*LineNumber=*/1, &Cxt, SM);
- EXPECT_TRUE(bool(ExpressionAST));
- ExpressionVal = (*ExpressionAST)->eval();
- EXPECT_TRUE(bool(ExpressionVal));
- EXPECT_EQ(*ExpressionVal, 20U);
EXPECT_TRUE(bool(EmptyVar));
EXPECT_EQ(*EmptyVar, "");
EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
@@ -584,14 +533,7 @@ TEST_F(FileCheckTest, FileCheckContext)
EXPECT_TRUE(errorToBool((*ExpressionAST)->eval().takeError()));
P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
ExpressionAST = P.parseNumericSubstitutionBlock(
- LocalNumVar1Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
- /*LineNumber=*/2, &Cxt, SM);
- EXPECT_TRUE(bool(ExpressionAST));
- ExpressionVal = (*ExpressionAST)->eval();
- EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
- ExpressionAST = P.parseNumericSubstitutionBlock(
- LocalNumVar2Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
- /*LineNumber=*/2, &Cxt, SM);
+ LocalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
EXPECT_TRUE(bool(ExpressionAST));
ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
@@ -612,8 +554,7 @@ TEST_F(FileCheckTest, FileCheckContext)
EXPECT_EQ(*GlobalVar, "BAR");
P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
ExpressionAST = P.parseNumericSubstitutionBlock(
- GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
- /*LineNumber=*/3, &Cxt, SM);
+ GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
EXPECT_TRUE(bool(ExpressionAST));
ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(bool(ExpressionVal));
@@ -624,8 +565,7 @@ TEST_F(FileCheckTest, FileCheckContext)
EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
ExpressionAST = P.parseNumericSubstitutionBlock(
- GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
- /*LineNumber=*/4, &Cxt, SM);
+ GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
EXPECT_TRUE(bool(ExpressionAST));
ExpressionVal = (*ExpressionAST)->eval();
EXPECT_TRUE(bool(ExpressionVal));
More information about the llvm-commits
mailing list