[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