Skip to content

Commit 1b05977

Browse files
author
Thomas Preud'homme
committed
FileCheck [8/12]: Define numeric var from expr
Summary: This patch is part of a patch series to add support for FileCheck numeric expressions. This specific patch lift the restriction for a numeric expression to either be a variable definition or a numeric expression to try to match. This commit allows a numeric variable to be set to the result of the evaluation of a numeric expression after it has been matched successfully. When it happens, the variable is allowed to be used on the same line since its value is known at match time. It also makes use of this possibility to reuse the parsing code to parse a command-line definition by crafting a mirror string of the -D option with the equal sign replaced by a colon sign, e.g. for option '-D#NUMVAL=10' it creates the string '-D#NUMVAL=10 (parsed as [[#NUMVAL:10]])' where the numeric expression is parsed to define NUMVAL. This result in a few tests needing updating for the location diagnostics on top of the tests for the new feature. It also enables empty numeric expression which match any number without defining a variable. This is done here rather than in commit #5 of the patch series because it requires to dissociate automatic regex insertion in RegExStr from variable definition which would make commit #5 even bigger than it already is. Copyright: - Linaro (changes up to diff 183612 of revision D55940) - GraphCore (changes in later versions of revision D55940 and in new revision created off D55940) Reviewers: jhenderson, chandlerc, jdenny, probinson, grimar, arichardson, rnk Subscribers: hiraditya, llvm-commits, probinson, dblaikie, grimar, arichardson, tra, rnk, kristina, hfinkel, rogfer01, JonChesterfield Tags: #llvm Differential Revision: https://reviews.llvm.org/D60388 llvm-svn: 366860
1 parent f8552e6 commit 1b05977

File tree

7 files changed

+475
-251
lines changed

7 files changed

+475
-251
lines changed

Diff for: llvm/docs/CommandGuide/FileCheck.rst

+21-5
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ and from the command line.
107107
Sets a filecheck pattern variable ``VAR`` with value ``VALUE`` that can be
108108
used in ``CHECK:`` lines.
109109

110-
.. option:: -D#<NUMVAR>=<VALUE EXPRESSION>
110+
.. option:: -D#<NUMVAR>=<NUMERIC EXPRESSION>
111111

112112
Sets a filecheck numeric variable ``NUMVAR`` to the result of evaluating
113-
``<VALUE EXPRESSION>`` that can be used in ``CHECK:`` lines. See section
114-
``FileCheck Numeric Variables and Expressions`` for details on the format
115-
and meaning of ``<VALUE EXPRESSION>``.
113+
``<NUMERIC EXPRESSION>`` that can be used in ``CHECK:`` lines. See section
114+
``FileCheck Numeric Variables and Expressions`` for details on supported
115+
numeric expressions.
116116

117117
.. option:: -version
118118

@@ -625,11 +625,27 @@ but would not match the text:
625625
626626
due to ``7`` being unequal to ``5 + 1``.
627627

628+
The syntax also supports an empty expression, equivalent to writing {{[0-9]+}},
629+
for cases where the input must contain a numeric value but the value itself
630+
does not matter:
631+
632+
.. code-block:: gas
633+
634+
; CHECK-NOT: mov r0, r[[#]]
635+
636+
to check that a value is synthesized rather than moved around.
637+
638+
A numeric variable can also be defined to the result of a numeric expression,
639+
in which case the numeric expression is checked and if verified the variable is
640+
assigned to the value. The unified syntax for both defining numeric variables
641+
and checking a numeric expression is thus ``[[#<NUMVAR>: <expr>]]`` with each
642+
element as described previously.
643+
628644
The ``--enable-var-scope`` option has the same effect on numeric variables as
629645
on string variables.
630646

631647
Important note: In its current implementation, an expression cannot use a
632-
numeric variable defined on the same line.
648+
numeric variable with a non-empty expression defined on the same line.
633649

634650
FileCheck Pseudo Numeric Variables
635651
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Diff for: llvm/include/llvm/Support/FileCheck.h

+77-39
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ class FileCheckNumericVariable {
9494
/// Name of the numeric variable.
9595
StringRef Name;
9696

97+
/// Pointer to expression defining this numeric variable. Null for pseudo
98+
/// variable whose value is known at parse time (e.g. @LINE pseudo variable)
99+
/// or cleared local variable.
100+
FileCheckExpressionAST *ExpressionAST;
101+
97102
/// Value of numeric variable, if defined, or None otherwise.
98103
Optional<uint64_t> Value;
99104

@@ -104,23 +109,40 @@ class FileCheckNumericVariable {
104109

105110
public:
106111
/// Constructor for a variable \p Name defined at line \p DefLineNumber or
107-
/// defined before input is parsed if DefLineNumber is None.
112+
/// defined before input is parsed if \p DefLineNumber is None. If not null,
113+
/// the value set with setValue must match the result of evaluating
114+
/// \p ExpressionAST.
108115
FileCheckNumericVariable(StringRef Name,
109-
Optional<size_t> DefLineNumber = None)
110-
: Name(Name), DefLineNumber(DefLineNumber) {}
116+
Optional<size_t> DefLineNumber = None,
117+
FileCheckExpressionAST *ExpressionAST = nullptr)
118+
: Name(Name), ExpressionAST(ExpressionAST), DefLineNumber(DefLineNumber) {
119+
}
111120

112121
/// \returns name of this numeric variable.
113122
StringRef getName() const { return Name; }
114123

115124
/// \returns this variable's value.
116125
Optional<uint64_t> getValue() const { return Value; }
117126

118-
/// Sets value of this numeric variable to \p NewValue.
119-
void setValue(uint64_t NewValue) { Value = NewValue; }
127+
/// \returns the pointer to the expression defining this numeric variable, if
128+
/// any, or null otherwise.
129+
FileCheckExpressionAST *getExpressionAST() const { return ExpressionAST; }
130+
131+
/// \returns whether this variable's value is known when performing the
132+
/// substitutions of the line where it is defined.
133+
bool isValueKnownAtMatchTime() const;
134+
135+
/// Sets value of this numeric variable to \p NewValue. Triggers an assertion
136+
/// failure if the variable is defined by an expression and the expression
137+
/// cannot be evaluated to be equal to \p NewValue.
138+
void setValue(uint64_t NewValue);
120139

121140
/// Clears value of this numeric variable, regardless of whether it is
122141
/// currently defined or not.
123-
void clearValue() { Value = None; }
142+
void clearValue() {
143+
Value = None;
144+
ExpressionAST = nullptr;
145+
}
124146

125147
/// \returns the line number where this variable is defined, if any, or None
126148
/// if defined before input is parsed.
@@ -507,27 +529,22 @@ class FileCheckPattern {
507529
/// \p Str from the variable name.
508530
static Expected<VariableProperties> parseVariable(StringRef &Str,
509531
const SourceMgr &SM);
510-
/// Parses \p Expr for the name of a numeric variable to be defined at line
511-
/// \p LineNumber or before input is parsed if \p LineNumber is None.
512-
/// \returns a pointer to the class instance representing that variable,
513-
/// creating it if needed, or an error holding a diagnostic against \p SM
514-
/// should defining such a variable be invalid.
515-
static Expected<FileCheckNumericVariable *> parseNumericVariableDefinition(
516-
StringRef &Expr, FileCheckPatternContext *Context,
517-
Optional<size_t> LineNumber, const SourceMgr &SM);
518-
/// Parses \p Expr for a numeric substitution block. Parameter
532+
/// Parses \p Expr for a numeric substitution block at line \p LineNumber,
533+
/// or before input is parsed if \p LineNumber is None. Parameter
519534
/// \p IsLegacyLineExpr indicates whether \p Expr should be a legacy @LINE
520-
/// expression. \returns a pointer to the class instance representing the AST
521-
/// of the expression whose value must be substituted, or an error holding a
522-
/// diagnostic against \p SM if parsing fails. If substitution was
523-
/// successful, sets \p DefinedNumericVariable to point to the class
524-
/// representing the numeric variable being defined in this numeric
535+
/// expression and \p Context points to the class instance holding the live
536+
/// string and numeric variables. \returns a pointer to the class instance
537+
/// representing the AST of the expression whose value must be substitued, or
538+
/// an error holding a diagnostic against \p SM if parsing fails. If
539+
/// substitution was successful, sets \p DefinedNumericVariable to point to
540+
/// the class representing the numeric variable defined in this numeric
525541
/// substitution block, or None if this block does not define any variable.
526-
Expected<std::unique_ptr<FileCheckExpressionAST>>
542+
static Expected<std::unique_ptr<FileCheckExpressionAST>>
527543
parseNumericSubstitutionBlock(
528544
StringRef Expr,
529545
Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
530-
bool IsLegacyLineExpr, const SourceMgr &SM) const;
546+
bool IsLegacyLineExpr, Optional<size_t> LineNumber,
547+
FileCheckPatternContext *Context, const SourceMgr &SM);
531548
/// Parses the pattern in \p PatternStr and initializes this FileCheckPattern
532549
/// instance accordingly.
533550
///
@@ -581,28 +598,49 @@ class FileCheckPattern {
581598
/// was not found.
582599
size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM);
583600

584-
/// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use.
585-
/// \returns the pointer to the class instance representing that variable if
586-
/// successful, or an error holding a diagnostic against \p SM otherwise.
587-
Expected<std::unique_ptr<FileCheckNumericVariableUse>>
601+
/// Parses \p Expr for the name of a numeric variable to be defined at line
602+
/// \p LineNumber, or before input is parsed if \p LineNumber is None.
603+
/// \returns a pointer to the class instance representing that variable,
604+
/// creating it if needed, or an error holding a diagnostic against \p SM
605+
/// should defining such a variable be invalid.
606+
static Expected<FileCheckNumericVariable *> parseNumericVariableDefinition(
607+
StringRef &Expr, FileCheckPatternContext *Context,
608+
Optional<size_t> LineNumber, FileCheckExpressionAST *ExpressionAST,
609+
const SourceMgr &SM);
610+
/// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use
611+
/// at line \p LineNumber, or before input is parsed if \p LineNumber is
612+
/// None. Parameter \p Context points to the class instance holding the live
613+
/// string and numeric variables. \returns the pointer to the class instance
614+
/// representing that variable if successful, or an error holding a
615+
/// diagnostic against \p SM otherwise.
616+
static Expected<std::unique_ptr<FileCheckNumericVariableUse>>
588617
parseNumericVariableUse(StringRef Name, bool IsPseudo,
589-
const SourceMgr &SM) const;
618+
Optional<size_t> LineNumber,
619+
FileCheckPatternContext *Context,
620+
const SourceMgr &SM);
590621
enum class AllowedOperand { LineVar, Literal, Any };
591-
/// Parses \p Expr for use of a numeric operand. Accepts both literal values
592-
/// and numeric variables, depending on the value of \p AO. \returns the
593-
/// class representing that operand in the AST of the expression or an error
594-
/// holding a diagnostic against \p SM otherwise.
595-
Expected<std::unique_ptr<FileCheckExpressionAST>>
622+
/// Parses \p Expr for use of a numeric operand at line \p LineNumber, or
623+
/// before input is parsed if \p LineNumber is None. Accepts both literal
624+
/// values and numeric variables, depending on the value of \p AO. Parameter
625+
/// \p Context points to the class instance holding the live string and
626+
/// numeric variables. \returns the class representing that operand in the
627+
/// AST of the expression or an error holding a diagnostic against \p SM
628+
/// otherwise.
629+
static Expected<std::unique_ptr<FileCheckExpressionAST>>
596630
parseNumericOperand(StringRef &Expr, AllowedOperand AO,
597-
const SourceMgr &SM) const;
598-
/// Parses \p Expr for a binary operation. The left operand of this binary
631+
Optional<size_t> LineNumber,
632+
FileCheckPatternContext *Context, const SourceMgr &SM);
633+
/// Parses \p Expr for a binary operation at line \p LineNumber, or before
634+
/// input is parsed if \p LineNumber is None. The left operand of this binary
599635
/// operation is given in \p LeftOp and \p IsLegacyLineExpr indicates whether
600-
/// we are parsing a legacy @LINE expression. \returns the class representing
601-
/// the binary operation in the AST of the expression, or an error holding a
602-
/// diagnostic against \p SM otherwise.
603-
Expected<std::unique_ptr<FileCheckExpressionAST>>
636+
/// we are parsing a legacy @LINE expression. Parameter \p Context points to
637+
/// the class instance holding the live string and numeric variables.
638+
/// \returns the class representing the binary operation in the AST of the
639+
/// expression, or an error holding a diagnostic against \p SM otherwise.
640+
static Expected<std::unique_ptr<FileCheckExpressionAST>>
604641
parseBinop(StringRef &Expr, std::unique_ptr<FileCheckExpressionAST> LeftOp,
605-
bool IsLegacyLineExpr, const SourceMgr &SM) const;
642+
bool IsLegacyLineExpr, Optional<size_t> LineNumber,
643+
FileCheckPatternContext *Context, const SourceMgr &SM);
606644
};
607645

608646
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)