diff --git a/llvm/include/llvm/Support/FileCheck.h b/llvm/include/llvm/Support/FileCheck.h --- a/llvm/include/llvm/Support/FileCheck.h +++ b/llvm/include/llvm/Support/FileCheck.h @@ -49,19 +49,21 @@ /// Value of numeric variable, if defined, or None otherwise. Optional Value; - /// Line number where this variable is defined. Used to determine whether a - /// variable is defined on the same line as a given use. - size_t DefLineNumber; + /// Line number where this variable's value becomes available. + size_t AvailLineNumber; public: - /// Constructor for a variable \p Name defined at line \p DefLineNumber. - FileCheckNumericVariable(size_t DefLineNumber, StringRef Name) - : Name(Name), DefLineNumber(DefLineNumber) {} - - /// Constructor for numeric variable \p Name with a known \p Value at parse - /// time (e.g. the @LINE numeric variable). - FileCheckNumericVariable(StringRef Name, uint64_t Value) - : Name(Name), Value(Value), DefLineNumber(0) {} + /// Constructor for a numeric variable \p Name defined from a value in the + /// input and whose value becomes available at line \p AvailLineNumber. + FileCheckNumericVariable(StringRef Name, size_t AvailLineNumber) + : Name(Name), AvailLineNumber(AvailLineNumber) {} + + /// Constructor for a numeric variable \p Name whose \p Value is known at + /// parse time and becomes available at line \p AvailLineNumber (e.g. the + /// @LINE numeric variable). + FileCheckNumericVariable(StringRef Name, uint64_t Value, + size_t AvailLineNumber) + : Name(Name), Value(Value), AvailLineNumber(AvailLineNumber) {} /// \returns name of this numeric variable. StringRef getName() const { return Name; } @@ -77,8 +79,8 @@ /// already undefined. bool clearValue(); - /// \returns the line number where this variable is defined. - size_t getDefLineNumber() { return DefLineNumber; } + /// \returns the line number where this variable's value becomes available. + size_t getAvailLineNumber() { return AvailLineNumber; } }; /// Type of functions evaluating a given binary operation. @@ -465,14 +467,15 @@ /// name. static Expected parseVariable(StringRef &Str, bool &IsPseudo, const SourceMgr &SM); - /// Parses \p Expr for the name of a numeric variable to be defined at line - /// \p LineNumber. \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. + /// Parses \p Expr for the name of a numeric variable whose value becomes + /// available at line \p AvailLineNumber. \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 parseNumericVariableDefinition(StringRef &Expr, FileCheckPatternContext *Context, - size_t LineNumber, const SourceMgr &SM); + size_t AvailLineNumber, const SourceMgr &SM); /// Parses \p Expr for a numeric substitution block. \returns the class /// representing the AST of the expression whose value must be substituted, /// or an error holding a diagnostic against \p SM if parsing fails. If diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp --- a/llvm/lib/Support/FileCheck.cpp +++ b/llvm/lib/Support/FileCheck.cpp @@ -112,7 +112,7 @@ Expected FileCheckPattern::parseNumericVariableDefinition( - StringRef &Expr, FileCheckPatternContext *Context, size_t LineNumber, + StringRef &Expr, FileCheckPatternContext *Context, size_t AvailLineNumber, const SourceMgr &SM) { bool IsPseudo; Expected ParseVarResult = parseVariable(Expr, IsPseudo, SM); @@ -141,7 +141,8 @@ if (VarTableIter != Context->GlobalNumericVariableTable.end()) DefinedNumericVariable = VarTableIter->second; else - DefinedNumericVariable = Context->makeNumericVariable(LineNumber, Name); + DefinedNumericVariable = + Context->makeNumericVariable(Name, AvailLineNumber); return DefinedNumericVariable; } @@ -172,11 +173,11 @@ if (VarTableIter != Context->GlobalNumericVariableTable.end()) NumericVariable = VarTableIter->second; else { - NumericVariable = Context->makeNumericVariable(0, Name); + NumericVariable = Context->makeNumericVariable(Name, 0); Context->GlobalNumericVariableTable[Name] = NumericVariable; } - if (!IsPseudo && NumericVariable->getDefLineNumber() == LineNumber) + if (!IsPseudo && NumericVariable->getAvailLineNumber() > LineNumber) return FileCheckErrorDiagnostic::get( SM, Name, "numeric variable '" + Name + "' defined on the same line as used"); @@ -257,7 +258,7 @@ DefExpr = DefExpr.ltrim(SpaceChars); Expected ParseResult = - parseNumericVariableDefinition(DefExpr, Context, LineNumber, SM); + parseNumericVariableDefinition(DefExpr, Context, LineNumber + 1, SM); if (!ParseResult) return ParseResult.takeError(); DefinedNumericVariable = *ParseResult; @@ -1063,7 +1064,7 @@ void FileCheckPatternContext::createLineVariable() { assert(!LineVariable && "@LINE pseudo numeric variable already created"); StringRef LineName = "@LINE"; - LineVariable = makeNumericVariable(0, LineName); + LineVariable = makeNumericVariable(LineName, 1); GlobalNumericVariableTable[LineName] = LineVariable; } @@ -1751,7 +1752,7 @@ if (CmdlineDef[0] == '#') { StringRef CmdlineName = CmdlineDef.substr(1, EqIdx - 1); Expected ParseResult = - FileCheckPattern::parseNumericVariableDefinition(CmdlineName, this, 0, + FileCheckPattern::parseNumericVariableDefinition(CmdlineName, this, 1, SM); if (!ParseResult) { Errs = joinErrors(std::move(Errs), ParseResult.takeError()); diff --git a/llvm/unittests/Support/FileCheckTest.cpp b/llvm/unittests/Support/FileCheckTest.cpp --- a/llvm/unittests/Support/FileCheckTest.cpp +++ b/llvm/unittests/Support/FileCheckTest.cpp @@ -16,7 +16,7 @@ TEST_F(FileCheckTest, NumericVariable) { // Undefined variable: getValue and clearValue fails, setValue works. - FileCheckNumericVariable FooVar = FileCheckNumericVariable(1, "FOO"); + FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1); EXPECT_EQ("FOO", FooVar.getName()); llvm::Optional Value = FooVar.getValue(); EXPECT_FALSE(Value); @@ -48,7 +48,7 @@ } TEST_F(FileCheckTest, Expression) { - FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42); + FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42, 1); FileCheckExpression Expression = FileCheckExpression(doAdd, &FooVar, 18); // Defined variable: eval returns right value. @@ -353,8 +353,8 @@ // Substitutions of defined pseudo and non-pseudo numeric variables return // the right value. - FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42); - FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 10); + FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42, 1); + FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 10, 1); FileCheckExpression LineExpression = FileCheckExpression(doAdd, &LineVar, 0); FileCheckExpression NExpression = FileCheckExpression(doAdd, &NVar, 3); FileCheckNumericSubstitution SubstitutionLine =