mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[FileCheck] Stop qualifying expressions as numeric
Summary: Stop referring to "numeric expression", using simply the term "expression" instead. Likewise for numeric operation since operations are only used in numeric expressions. Reviewers: jhenderson, jdenny, probinson, arichardson Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63500 llvm-svn: 363901
This commit is contained in:
parent
e49cb07725
commit
527ed6b4be
@ -592,12 +592,12 @@ The syntax of a numeric substitution is ``[[#<NUMVAR><op><offset>]]`` where:
|
||||
|
||||
* ``<NUMVAR>`` is the name of a defined numeric variable.
|
||||
|
||||
* ``<op>`` is an optional numeric operation to perform on the value of
|
||||
``<NUMVAR>``. Currently supported numeric operations are ``+`` and ``-``.
|
||||
* ``<op>`` is an optional operation to perform on the value of ``<NUMVAR>``.
|
||||
Currently supported operations are ``+`` and ``-``.
|
||||
|
||||
* ``<offset>`` is the immediate value that constitutes the second operand of
|
||||
the numeric operation <op>. It must be present if ``<op>`` is present,
|
||||
absent otherwise.
|
||||
the operation ``<op>``. It must be present if ``<op>`` is present, absent
|
||||
otherwise.
|
||||
|
||||
Spaces are accepted before, after and between any of these elements.
|
||||
|
||||
@ -627,8 +627,8 @@ due to ``7`` being unequal to ``5 + 1``.
|
||||
The ``--enable-var-scope`` option has the same effect on numeric variables as
|
||||
on string variables.
|
||||
|
||||
Important note: In its current implementation, a numeric expression cannot use
|
||||
a numeric variable defined on the same line.
|
||||
Important note: In its current implementation, an expression cannot use a
|
||||
numeric variable defined on the same line.
|
||||
|
||||
FileCheck Pseudo Numeric Variables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -639,9 +639,9 @@ fragility of the match file structure, as "``CHECK:``" lines contain absolute
|
||||
line numbers in the same file, which have to be updated whenever line numbers
|
||||
change due to text addition or deletion.
|
||||
|
||||
To support this case, FileCheck numeric expressions understand the ``@LINE``
|
||||
pseudo numeric variable which evaluates to the line number of the CHECK pattern
|
||||
where it is found.
|
||||
To support this case, FileCheck expressions understand the ``@LINE`` pseudo
|
||||
numeric variable which evaluates to the line number of the CHECK pattern where
|
||||
it is found.
|
||||
|
||||
This way match patterns can be put near the relevant test lines and include
|
||||
relative line number references, for example:
|
||||
|
@ -66,10 +66,10 @@ public:
|
||||
FileCheckNumericVariable(StringRef Name, uint64_t Value)
|
||||
: Name(Name), Value(Value), DefLineNumber(0) {}
|
||||
|
||||
/// \returns name of that numeric variable.
|
||||
/// \returns name of this numeric variable.
|
||||
StringRef getName() const { return Name; }
|
||||
|
||||
/// \returns value of this numeric variable.
|
||||
/// \returns this variable's value.
|
||||
Optional<uint64_t> getValue() const { return Value; }
|
||||
|
||||
/// Sets value of this numeric variable if not defined. \returns whether the
|
||||
@ -111,10 +111,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Class representing a numeric expression consisting of either a single
|
||||
/// numeric variable or a binary operation between a numeric variable and an
|
||||
/// Class representing an expression consisting of either a single numeric
|
||||
/// variable or a binary operation between a numeric variable and an
|
||||
/// immediate.
|
||||
class FileCheckNumExpr {
|
||||
class FileCheckExpression {
|
||||
private:
|
||||
/// Left operand.
|
||||
FileCheckNumericVariable *LeftOp;
|
||||
@ -126,13 +126,14 @@ private:
|
||||
binop_eval_t EvalBinop;
|
||||
|
||||
public:
|
||||
FileCheckNumExpr(binop_eval_t EvalBinop,
|
||||
FileCheckNumericVariable *OperandLeft, uint64_t OperandRight)
|
||||
FileCheckExpression(binop_eval_t EvalBinop,
|
||||
FileCheckNumericVariable *OperandLeft,
|
||||
uint64_t OperandRight)
|
||||
: LeftOp(OperandLeft), RightOp(OperandRight), EvalBinop(EvalBinop) {}
|
||||
|
||||
/// Evaluates the value of this numeric expression, using EvalBinop to
|
||||
/// perform the binary operation it consists of. \returns an error if the
|
||||
/// numeric variable used is undefined, or the expression value otherwise.
|
||||
/// Evaluates the value of this expression, using EvalBinop to perform the
|
||||
/// binary operation it consists of. \returns an error if the numeric
|
||||
/// variable used is undefined, or the expression value otherwise.
|
||||
Expected<uint64_t> eval() const;
|
||||
};
|
||||
|
||||
@ -144,14 +145,13 @@ protected:
|
||||
/// Pointer to a class instance holding, among other things, the table with
|
||||
/// the values of live string variables at the start of any given CHECK line.
|
||||
/// Used for substituting string variables with the text they were defined
|
||||
/// as. Numeric expressions are linked to the numeric variables they use at
|
||||
/// as. Expressions are linked to the numeric variables they use at
|
||||
/// parse time and directly access the value of the numeric variable to
|
||||
/// evaluate their value.
|
||||
FileCheckPatternContext *Context;
|
||||
|
||||
/// The string that needs to be substituted for something else. For a
|
||||
/// string variable this is its name, otherwise this is the whole numeric
|
||||
/// expression.
|
||||
/// string variable this is its name, otherwise this is the whole expression.
|
||||
StringRef FromStr;
|
||||
|
||||
// Index in RegExStr of where to do the substitution.
|
||||
@ -188,17 +188,20 @@ public:
|
||||
|
||||
class FileCheckNumericSubstitution : public FileCheckSubstitution {
|
||||
private:
|
||||
/// Pointer to the class representing the numeric expression whose value is
|
||||
/// to be substituted.
|
||||
FileCheckNumExpr *NumExpr;
|
||||
/// Pointer to the class representing the expression whose value is to be
|
||||
/// substituted.
|
||||
FileCheckExpression *Expression;
|
||||
|
||||
public:
|
||||
FileCheckNumericSubstitution(FileCheckPatternContext *Context, StringRef Expr,
|
||||
FileCheckNumExpr *NumExpr, size_t InsertIdx)
|
||||
: FileCheckSubstitution(Context, Expr, InsertIdx), NumExpr(NumExpr) {}
|
||||
FileCheckNumericSubstitution(FileCheckPatternContext *Context,
|
||||
StringRef ExpressionStr,
|
||||
FileCheckExpression *Expression,
|
||||
size_t InsertIdx)
|
||||
: FileCheckSubstitution(Context, ExpressionStr, InsertIdx),
|
||||
Expression(Expression) {}
|
||||
|
||||
/// \returns a string containing the result of evaluating the numeric
|
||||
/// expression in this substitution, or an error if evaluation failed.
|
||||
/// \returns a string containing the result of evaluating the expression in
|
||||
/// this substitution, or an error if evaluation failed.
|
||||
Expected<std::string> getResult() const override;
|
||||
};
|
||||
|
||||
@ -276,10 +279,9 @@ private:
|
||||
/// pattern.
|
||||
StringMap<FileCheckNumericVariable *> GlobalNumericVariableTable;
|
||||
|
||||
/// Vector holding pointers to all parsed numeric expressions. Used to
|
||||
/// automatically free the numeric expressions once they are guaranteed to no
|
||||
/// longer be used.
|
||||
std::vector<std::unique_ptr<FileCheckNumExpr>> NumExprs;
|
||||
/// Vector holding pointers to all parsed expressions. Used to automatically
|
||||
/// free the expressions once they are guaranteed to no longer be used.
|
||||
std::vector<std::unique_ptr<FileCheckExpression>> Expressions;
|
||||
|
||||
/// Vector holding pointers to all parsed numeric variables. Used to
|
||||
/// automatically free them once they are guaranteed to no longer be used.
|
||||
@ -308,11 +310,11 @@ public:
|
||||
void clearLocalVars();
|
||||
|
||||
private:
|
||||
/// Makes a new numeric expression instance and registers it for destruction
|
||||
/// when the context is destroyed.
|
||||
FileCheckNumExpr *makeNumExpr(binop_eval_t EvalBinop,
|
||||
FileCheckNumericVariable *OperandLeft,
|
||||
uint64_t OperandRight);
|
||||
/// Makes a new expression instance and registers it for destruction when
|
||||
/// the context is destroyed.
|
||||
FileCheckExpression *makeExpression(binop_eval_t EvalBinop,
|
||||
FileCheckNumericVariable *OperandLeft,
|
||||
uint64_t OperandRight);
|
||||
|
||||
/// Makes a new numeric variable and registers it for destruction when the
|
||||
/// context is destroyed.
|
||||
@ -326,9 +328,9 @@ private:
|
||||
|
||||
/// Makes a new numeric substitution and registers it for destruction when
|
||||
/// the context is destroyed.
|
||||
FileCheckSubstitution *makeNumericSubstitution(StringRef Expr,
|
||||
FileCheckNumExpr *NumExpr,
|
||||
size_t InsertIdx);
|
||||
FileCheckSubstitution *
|
||||
makeNumericSubstitution(StringRef ExpressionStr,
|
||||
FileCheckExpression *Expression, size_t InsertIdx);
|
||||
};
|
||||
|
||||
/// Class to represent an error holding a diagnostic with location information
|
||||
@ -384,12 +386,12 @@ class FileCheckPattern {
|
||||
/// a fixed string to match.
|
||||
std::string RegExStr;
|
||||
|
||||
/// Entries in this vector represent a substitution of a string variable or a
|
||||
/// numeric expression in the RegExStr regex at match time. For example, in
|
||||
/// the case of a CHECK directive with the pattern "foo[[bar]]baz[[#N+1]]",
|
||||
/// Entries in this vector represent a substitution of a string variable or
|
||||
/// an expression in the RegExStr regex at match time. For example, in the
|
||||
/// case of a CHECK directive with the pattern "foo[[bar]]baz[[#N+1]]",
|
||||
/// RegExStr will contain "foobaz" and we'll get two entries in this vector
|
||||
/// that tells us to insert the value of string variable "bar" at offset 3
|
||||
/// and the value of numeric expression "N+1" at offset 6.
|
||||
/// and the value of expression "N+1" at offset 6.
|
||||
std::vector<FileCheckSubstitution *> Substitutions;
|
||||
|
||||
/// Maps names of string variables defined in a pattern to the number of
|
||||
@ -409,7 +411,7 @@ class FileCheckPattern {
|
||||
/// It holds the pointer to the class representing the numeric variable whose
|
||||
/// value is being defined and the number of the parenthesis group in
|
||||
/// RegExStr to capture that value.
|
||||
struct FileCheckNumExprMatch {
|
||||
struct FileCheckNumericVariableMatch {
|
||||
/// Pointer to class representing the numeric variable whose value is being
|
||||
/// defined.
|
||||
FileCheckNumericVariable *DefinedNumericVariable;
|
||||
@ -423,7 +425,7 @@ class FileCheckPattern {
|
||||
/// corresponding FileCheckNumericVariable class instance of all numeric
|
||||
/// variable definitions. Used to set the matched value of all those
|
||||
/// variables.
|
||||
StringMap<FileCheckNumExprMatch> NumericVariableDefs;
|
||||
StringMap<FileCheckNumericVariableMatch> NumericVariableDefs;
|
||||
|
||||
/// Pointer to a class instance holding the global state shared by all
|
||||
/// patterns:
|
||||
@ -468,13 +470,12 @@ public:
|
||||
FileCheckPatternContext *Context,
|
||||
const SourceMgr &SM);
|
||||
/// Parses \p Expr for a numeric substitution block. \returns the class
|
||||
/// representing the AST of the numeric 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 defined in this
|
||||
/// numeric substitution block, or None if this block does not define any
|
||||
/// variable.
|
||||
Expected<FileCheckNumExpr *> parseNumericSubstitutionBlock(
|
||||
/// 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 defined in this numeric
|
||||
/// substitution block, or None if this block does not define any variable.
|
||||
Expected<FileCheckExpression *> parseNumericSubstitutionBlock(
|
||||
StringRef Expr,
|
||||
Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
|
||||
const SourceMgr &SM) const;
|
||||
@ -537,10 +538,10 @@ private:
|
||||
Expected<FileCheckNumericVariable *>
|
||||
parseNumericVariableUse(StringRef &Expr, const SourceMgr &SM) const;
|
||||
/// Parses \p Expr for a binary operation.
|
||||
/// \returns the class representing the binary operation of the numeric
|
||||
/// expression, or an error holding a diagnostic against \p SM otherwise.
|
||||
Expected<FileCheckNumExpr *> parseBinop(StringRef &Expr,
|
||||
const SourceMgr &SM) const;
|
||||
/// \returns the class representing the binary operation of the expression,
|
||||
/// or an error holding a diagnostic against \p SM otherwise.
|
||||
Expected<FileCheckExpression *> parseBinop(StringRef &Expr,
|
||||
const SourceMgr &SM) const;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -38,8 +38,8 @@ bool FileCheckNumericVariable::clearValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
Expected<uint64_t> FileCheckNumExpr::eval() const {
|
||||
assert(LeftOp && "Evaluating an empty numeric expression");
|
||||
Expected<uint64_t> FileCheckExpression::eval() const {
|
||||
assert(LeftOp && "Evaluating an empty expression");
|
||||
Optional<uint64_t> LeftOpValue = LeftOp->getValue();
|
||||
// Variable is undefined.
|
||||
if (!LeftOpValue)
|
||||
@ -48,7 +48,7 @@ Expected<uint64_t> FileCheckNumExpr::eval() const {
|
||||
}
|
||||
|
||||
Expected<std::string> FileCheckNumericSubstitution::getResult() const {
|
||||
Expected<uint64_t> EvaluatedValue = NumExpr->eval();
|
||||
Expected<uint64_t> EvaluatedValue = Expression->eval();
|
||||
if (!EvaluatedValue)
|
||||
return EvaluatedValue.takeError();
|
||||
return utostr(*EvaluatedValue);
|
||||
@ -174,7 +174,7 @@ static uint64_t sub(uint64_t LeftOp, uint64_t RightOp) {
|
||||
return LeftOp - RightOp;
|
||||
}
|
||||
|
||||
Expected<FileCheckNumExpr *>
|
||||
Expected<FileCheckExpression *>
|
||||
FileCheckPattern::parseBinop(StringRef &Expr, const SourceMgr &SM) const {
|
||||
Expected<FileCheckNumericVariable *> LeftParseResult =
|
||||
parseNumericVariableUse(Expr, SM);
|
||||
@ -187,7 +187,7 @@ FileCheckPattern::parseBinop(StringRef &Expr, const SourceMgr &SM) const {
|
||||
// it.
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
if (Expr.empty())
|
||||
return Context->makeNumExpr(add, LeftOp, 0);
|
||||
return Context->makeExpression(add, LeftOp, 0);
|
||||
SMLoc OpLoc = SMLoc::getFromPointer(Expr.data());
|
||||
char Operator = popFront(Expr);
|
||||
binop_eval_t EvalBinop;
|
||||
@ -200,29 +200,27 @@ FileCheckPattern::parseBinop(StringRef &Expr, const SourceMgr &SM) const {
|
||||
break;
|
||||
default:
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
SM, OpLoc,
|
||||
Twine("unsupported numeric operation '") + Twine(Operator) + "'");
|
||||
SM, OpLoc, Twine("unsupported operation '") + Twine(Operator) + "'");
|
||||
}
|
||||
|
||||
// Parse right operand.
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
if (Expr.empty())
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
SM, Expr, "missing operand in numeric expression");
|
||||
return FileCheckErrorDiagnostic::get(SM, Expr,
|
||||
"missing operand in expression");
|
||||
uint64_t RightOp;
|
||||
if (Expr.consumeInteger(10, RightOp))
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
SM, Expr, "invalid offset in numeric expression '" + Expr + "'");
|
||||
SM, Expr, "invalid offset in expression '" + Expr + "'");
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
if (!Expr.empty())
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
SM, Expr,
|
||||
"unexpected characters at end of numeric expression '" + Expr + "'");
|
||||
SM, Expr, "unexpected characters at end of expression '" + Expr + "'");
|
||||
|
||||
return Context->makeNumExpr(EvalBinop, LeftOp, RightOp);
|
||||
return Context->makeExpression(EvalBinop, LeftOp, RightOp);
|
||||
}
|
||||
|
||||
Expected<FileCheckNumExpr *> FileCheckPattern::parseNumericSubstitutionBlock(
|
||||
Expected<FileCheckExpression *> FileCheckPattern::parseNumericSubstitutionBlock(
|
||||
StringRef Expr,
|
||||
Optional<FileCheckNumericVariable *> &DefinedNumericVariable,
|
||||
const SourceMgr &SM) const {
|
||||
@ -252,10 +250,10 @@ Expected<FileCheckNumExpr *> FileCheckPattern::parseNumericSubstitutionBlock(
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
SM, UseExpr,
|
||||
"unexpected string after variable definition: '" + UseExpr + "'");
|
||||
return Context->makeNumExpr(add, nullptr, 0);
|
||||
return Context->makeExpression(add, nullptr, 0);
|
||||
}
|
||||
|
||||
// Parse the numeric expression itself.
|
||||
// Parse the expression itself.
|
||||
Expr = Expr.ltrim(SpaceChars);
|
||||
return parseBinop(Expr, SM);
|
||||
}
|
||||
@ -380,7 +378,7 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
StringRef MatchRegexp;
|
||||
size_t SubstInsertIdx = RegExStr.size();
|
||||
|
||||
// Parse string variable or legacy numeric expression.
|
||||
// Parse string variable or legacy expression.
|
||||
if (!IsNumBlock) {
|
||||
size_t VarEndIdx = MatchStr.find(":");
|
||||
size_t SpacePos = MatchStr.substr(0, VarEndIdx).find_first_of(" \t");
|
||||
@ -431,16 +429,16 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
}
|
||||
|
||||
// Parse numeric substitution block.
|
||||
FileCheckNumExpr *NumExpr;
|
||||
FileCheckExpression *Expression;
|
||||
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
|
||||
if (IsNumBlock) {
|
||||
Expected<FileCheckNumExpr *> ParseResult =
|
||||
Expected<FileCheckExpression *> ParseResult =
|
||||
parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable, SM);
|
||||
if (!ParseResult) {
|
||||
logAllUnhandledErrors(ParseResult.takeError(), errs());
|
||||
return true;
|
||||
}
|
||||
NumExpr = *ParseResult;
|
||||
Expression = *ParseResult;
|
||||
if (DefinedNumericVariable) {
|
||||
IsDefinition = true;
|
||||
DefName = (*DefinedNumericVariable)->getName();
|
||||
@ -452,9 +450,8 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
// Handle substitutions: [[foo]] and [[#<foo expr>]].
|
||||
if (!IsDefinition) {
|
||||
// Handle substitution of string variables that were defined earlier on
|
||||
// the same line by emitting a backreference. Numeric expressions do
|
||||
// not support substituting a numeric variable defined on the same
|
||||
// line.
|
||||
// the same line by emitting a backreference. Expressions do not
|
||||
// support substituting a numeric variable defined on the same line.
|
||||
if (!IsNumBlock && VariableDefs.find(SubstStr) != VariableDefs.end()) {
|
||||
unsigned CaptureParenGroup = VariableDefs[SubstStr];
|
||||
if (CaptureParenGroup < 1 || CaptureParenGroup > 9) {
|
||||
@ -466,10 +463,10 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
AddBackrefToRegEx(CaptureParenGroup);
|
||||
} else {
|
||||
// Handle substitution of string variables ([[<var>]]) defined in
|
||||
// previous CHECK patterns, and substitution of numeric expressions.
|
||||
// previous CHECK patterns, and substitution of expressions.
|
||||
FileCheckSubstitution *Substitution =
|
||||
IsNumBlock
|
||||
? Context->makeNumericSubstitution(SubstStr, NumExpr,
|
||||
? Context->makeNumericSubstitution(SubstStr, Expression,
|
||||
SubstInsertIdx)
|
||||
: Context->makeStringSubstitution(SubstStr, SubstInsertIdx);
|
||||
Substitutions.push_back(Substitution);
|
||||
@ -480,8 +477,9 @@ bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix,
|
||||
// Handle variable definitions: [[<def>:(...)]] and
|
||||
// [[#(...)<def>:(...)]].
|
||||
if (IsNumBlock) {
|
||||
FileCheckNumExprMatch NumExprDef = {*DefinedNumericVariable, CurParen};
|
||||
NumericVariableDefs[DefName] = NumExprDef;
|
||||
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
|
||||
@ -570,9 +568,9 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
TmpStr = RegExStr;
|
||||
|
||||
size_t InsertOffset = 0;
|
||||
// Substitute all string variables and numeric expressions whose values are
|
||||
// only now known. Use of string variables defined on the same line are
|
||||
// handled by back-references.
|
||||
// Substitute all string variables and expressions whose values are only
|
||||
// now known. Use of string variables defined on the same line are handled
|
||||
// by back-references.
|
||||
for (const auto &Substitution : Substitutions) {
|
||||
// Substitute and check for failure (e.g. use of undefined variable).
|
||||
Expected<std::string> Value = Substitution->getResult();
|
||||
@ -606,7 +604,7 @@ Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen,
|
||||
|
||||
// If this defines any numeric variables, remember their values.
|
||||
for (const auto &NumericVariableDef : NumericVariableDefs) {
|
||||
const FileCheckNumExprMatch &NumericVariableMatch =
|
||||
const FileCheckNumericVariableMatch &NumericVariableMatch =
|
||||
NumericVariableDef.getValue();
|
||||
unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup;
|
||||
assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error");
|
||||
@ -765,13 +763,13 @@ FileCheckPatternContext::getPatternVarValue(StringRef VarName) {
|
||||
return VarIter->second;
|
||||
}
|
||||
|
||||
FileCheckNumExpr *
|
||||
FileCheckPatternContext::makeNumExpr(binop_eval_t EvalBinop,
|
||||
FileCheckNumericVariable *OperandLeft,
|
||||
uint64_t OperandRight) {
|
||||
NumExprs.push_back(llvm::make_unique<FileCheckNumExpr>(EvalBinop, OperandLeft,
|
||||
OperandRight));
|
||||
return NumExprs.back().get();
|
||||
FileCheckExpression *
|
||||
FileCheckPatternContext::makeExpression(binop_eval_t EvalBinop,
|
||||
FileCheckNumericVariable *OperandLeft,
|
||||
uint64_t OperandRight) {
|
||||
Expressions.push_back(llvm::make_unique<FileCheckExpression>(
|
||||
EvalBinop, OperandLeft, OperandRight));
|
||||
return Expressions.back().get();
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
@ -791,9 +789,10 @@ FileCheckPatternContext::makeStringSubstitution(StringRef VarName,
|
||||
}
|
||||
|
||||
FileCheckSubstitution *FileCheckPatternContext::makeNumericSubstitution(
|
||||
StringRef Expr, FileCheckNumExpr *NumExpr, size_t InsertIdx) {
|
||||
StringRef ExpressionStr, FileCheckExpression *Expression,
|
||||
size_t InsertIdx) {
|
||||
Substitutions.push_back(llvm::make_unique<FileCheckNumericSubstitution>(
|
||||
this, Expr, NumExpr, InsertIdx));
|
||||
this, ExpressionStr, Expression, InsertIdx));
|
||||
return Substitutions.back().get();
|
||||
}
|
||||
|
||||
|
@ -47,13 +47,13 @@
|
||||
47 ERR8: line-count.txt:[[#@LINE-1]]:12: error: invalid pseudo numeric variable '@LIN'
|
||||
48
|
||||
49 BAD9: [[@LINE*2]]
|
||||
50 ERR9: line-count.txt:[[#@LINE-1]]:17: error: unsupported numeric operation '*'
|
||||
50 ERR9: line-count.txt:[[#@LINE-1]]:17: error: unsupported operation '*'
|
||||
51
|
||||
52 BAD10: [[@LINE-x]]
|
||||
53 ERR10: line-count.txt:[[#@LINE-1]]:19: error: invalid offset in numeric expression 'x'
|
||||
53 ERR10: line-count.txt:[[#@LINE-1]]:19: error: invalid offset in expression 'x'
|
||||
54
|
||||
55 BAD11: [[@LINE-1x]]
|
||||
56 ERR11: line-count.txt:[[#@LINE-1]]:20: error: unexpected characters at end of numeric expression 'x'
|
||||
56 ERR11: line-count.txt:[[#@LINE-1]]:20: error: unexpected characters at end of expression 'x'
|
||||
57
|
||||
58 CHECK: [[#@LINE]] CHECK
|
||||
59 CHECK: [[# @LINE]] CHECK
|
||||
|
@ -88,7 +88,7 @@ INVALID OPERATOR
|
||||
NUMVAR*2: 22
|
||||
INVAL-OP-LABEL: INVALID OPERATOR
|
||||
INVAL-OP-NEXT: NUMVAR*2: [[#NUMVAR*2]]
|
||||
INVAL-OP-MSG: numeric-expression.txt:[[#@LINE-1]]:35: error: unsupported numeric operation '*'
|
||||
INVAL-OP-MSG: numeric-expression.txt:[[#@LINE-1]]:35: error: unsupported operation '*'
|
||||
INVAL-OP-MSG-NEXT: {{I}}NVAL-OP-NEXT: NUMVAR*2: {{\[\[#NUMVAR\*2\]\]}}
|
||||
INVAL-OP-MSG-NEXT: {{^ \^$}}
|
||||
|
||||
|
@ -47,12 +47,12 @@ static void expectUndefError(const Twine &ExpectedStr, Error Err) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(FileCheckTest, NumExpr) {
|
||||
TEST_F(FileCheckTest, Expression) {
|
||||
FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 42);
|
||||
FileCheckNumExpr NumExpr = FileCheckNumExpr(doAdd, &FooVar, 18);
|
||||
FileCheckExpression Expression = FileCheckExpression(doAdd, &FooVar, 18);
|
||||
|
||||
// Defined variable: eval returns right value.
|
||||
Expected<uint64_t> Value = NumExpr.eval();
|
||||
Expected<uint64_t> Value = Expression.eval();
|
||||
EXPECT_TRUE(static_cast<bool>(Value));
|
||||
EXPECT_EQ(60U, *Value);
|
||||
|
||||
@ -60,7 +60,7 @@ TEST_F(FileCheckTest, NumExpr) {
|
||||
// getUndefVarName first to check that it can be called without calling
|
||||
// eval() first.
|
||||
FooVar.clearValue();
|
||||
Error EvalError = NumExpr.eval().takeError();
|
||||
Error EvalError = Expression.eval().takeError();
|
||||
EXPECT_TRUE(errorToBool(std::move(EvalError)));
|
||||
expectUndefError("FOO", std::move(EvalError));
|
||||
}
|
||||
@ -354,12 +354,12 @@ TEST_F(FileCheckTest, Substitution) {
|
||||
// the right value.
|
||||
FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE", 42);
|
||||
FileCheckNumericVariable NVar = FileCheckNumericVariable("N", 10);
|
||||
FileCheckNumExpr NumExprLine = FileCheckNumExpr(doAdd, &LineVar, 0);
|
||||
FileCheckNumExpr NumExprN = FileCheckNumExpr(doAdd, &NVar, 3);
|
||||
FileCheckExpression LineExpression = FileCheckExpression(doAdd, &LineVar, 0);
|
||||
FileCheckExpression NExpression = FileCheckExpression(doAdd, &NVar, 3);
|
||||
FileCheckNumericSubstitution SubstitutionLine =
|
||||
FileCheckNumericSubstitution(&Context, "@LINE", &NumExprLine, 12);
|
||||
FileCheckNumericSubstitution(&Context, "@LINE", &LineExpression, 12);
|
||||
FileCheckNumericSubstitution SubstitutionN =
|
||||
FileCheckNumericSubstitution(&Context, "N", &NumExprN, 30);
|
||||
FileCheckNumericSubstitution(&Context, "N", &NExpression, 30);
|
||||
Expected<std::string> Value = SubstitutionLine.getResult();
|
||||
EXPECT_TRUE(static_cast<bool>(Value));
|
||||
EXPECT_EQ("42", *Value);
|
||||
@ -445,16 +445,16 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
||||
Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
|
||||
FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1);
|
||||
Optional<FileCheckNumericVariable *> DefinedNumericVariable;
|
||||
Expected<FileCheckNumExpr *> NumExpr = P.parseNumericSubstitutionBlock(
|
||||
Expected<FileCheckExpression *> Expression = P.parseNumericSubstitutionBlock(
|
||||
LocalNumVarRef, DefinedNumericVariable, SM);
|
||||
Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
|
||||
Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
|
||||
EXPECT_TRUE(static_cast<bool>(LocalVar));
|
||||
EXPECT_EQ(*LocalVar, "FOO");
|
||||
EXPECT_TRUE(static_cast<bool>(NumExpr));
|
||||
Expected<uint64_t> NumExprVal = (*NumExpr)->eval();
|
||||
EXPECT_TRUE(static_cast<bool>(NumExprVal));
|
||||
EXPECT_EQ(*NumExprVal, 18U);
|
||||
EXPECT_TRUE(static_cast<bool>(Expression));
|
||||
Expected<uint64_t> ExpressionVal = (*Expression)->eval();
|
||||
EXPECT_TRUE(static_cast<bool>(ExpressionVal));
|
||||
EXPECT_EQ(*ExpressionVal, 18U);
|
||||
EXPECT_TRUE(static_cast<bool>(EmptyVar));
|
||||
EXPECT_EQ(*EmptyVar, "");
|
||||
EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
|
||||
@ -467,11 +467,11 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
||||
// local variables, if it was created before. This is important because local
|
||||
// variable clearing due to --enable-var-scope happens after numeric
|
||||
// expressions are linked to the numeric variables they use.
|
||||
EXPECT_TRUE(errorToBool((*NumExpr)->eval().takeError()));
|
||||
EXPECT_TRUE(errorToBool((*Expression)->eval().takeError()));
|
||||
P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
|
||||
NumExpr = P.parseNumericSubstitutionBlock(LocalNumVarRef,
|
||||
DefinedNumericVariable, SM);
|
||||
EXPECT_TRUE(errorToBool(NumExpr.takeError()));
|
||||
Expression = P.parseNumericSubstitutionBlock(LocalNumVarRef,
|
||||
DefinedNumericVariable, SM);
|
||||
EXPECT_TRUE(errorToBool(Expression.takeError()));
|
||||
EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
|
||||
EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
|
||||
|
||||
@ -485,22 +485,22 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
||||
EXPECT_TRUE(static_cast<bool>(GlobalVar));
|
||||
EXPECT_EQ(*GlobalVar, "BAR");
|
||||
P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
|
||||
NumExpr = P.parseNumericSubstitutionBlock(GlobalNumVarRef,
|
||||
DefinedNumericVariable, SM);
|
||||
EXPECT_TRUE(static_cast<bool>(NumExpr));
|
||||
NumExprVal = (*NumExpr)->eval();
|
||||
EXPECT_TRUE(static_cast<bool>(NumExprVal));
|
||||
EXPECT_EQ(*NumExprVal, 36U);
|
||||
Expression = P.parseNumericSubstitutionBlock(GlobalNumVarRef,
|
||||
DefinedNumericVariable, SM);
|
||||
EXPECT_TRUE(static_cast<bool>(Expression));
|
||||
ExpressionVal = (*Expression)->eval();
|
||||
EXPECT_TRUE(static_cast<bool>(ExpressionVal));
|
||||
EXPECT_EQ(*ExpressionVal, 36U);
|
||||
|
||||
// Clear local variables and check global variables remain defined.
|
||||
Cxt.clearLocalVars();
|
||||
EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
|
||||
P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
|
||||
NumExpr = P.parseNumericSubstitutionBlock(GlobalNumVarRef,
|
||||
DefinedNumericVariable, SM);
|
||||
EXPECT_TRUE(static_cast<bool>(NumExpr));
|
||||
NumExprVal = (*NumExpr)->eval();
|
||||
EXPECT_TRUE(static_cast<bool>(NumExprVal));
|
||||
EXPECT_EQ(*NumExprVal, 36U);
|
||||
Expression = P.parseNumericSubstitutionBlock(GlobalNumVarRef,
|
||||
DefinedNumericVariable, SM);
|
||||
EXPECT_TRUE(static_cast<bool>(Expression));
|
||||
ExpressionVal = (*Expression)->eval();
|
||||
EXPECT_TRUE(static_cast<bool>(ExpressionVal));
|
||||
EXPECT_EQ(*ExpressionVal, 36U);
|
||||
}
|
||||
} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user