25
25
26
26
using namespace llvm ;
27
27
28
+ StringRef ExpressionFormat::toString () const {
29
+ switch (Value) {
30
+ case Kind::NoFormat:
31
+ return StringRef (" <none>" );
32
+ case Kind::Unsigned:
33
+ return StringRef (" %u" );
34
+ case Kind::HexUpper:
35
+ return StringRef (" %X" );
36
+ case Kind::HexLower:
37
+ return StringRef (" %x" );
38
+ }
39
+ llvm_unreachable (" unknown expression format" );
40
+ }
41
+
28
42
Expected<StringRef> ExpressionFormat::getWildcardRegex () const {
29
43
switch (Value) {
30
44
case Kind::Unsigned:
@@ -71,7 +85,7 @@ Expected<uint64_t> NumericVariableUse::eval() const {
71
85
if (Value)
72
86
return *Value;
73
87
74
- return make_error<UndefVarError>(Name );
88
+ return make_error<UndefVarError>(getExpressionStr () );
75
89
}
76
90
77
91
Expected<uint64_t > BinaryOperation::eval () const {
@@ -92,18 +106,31 @@ Expected<uint64_t> BinaryOperation::eval() const {
92
106
return EvalBinop (*LeftOp, *RightOp);
93
107
}
94
108
95
- ExpressionFormat BinaryOperation::getImplicitFormat () const {
96
- ExpressionFormat LeftFormat = LeftOperand->getImplicitFormat ();
97
- ExpressionFormat RightFormat = RightOperand->getImplicitFormat ();
98
-
99
- ExpressionFormat Format =
100
- LeftFormat != ExpressionFormat::Kind::NoFormat ? LeftFormat : RightFormat;
101
- if (LeftFormat != ExpressionFormat::Kind::NoFormat &&
102
- RightFormat != ExpressionFormat::Kind::NoFormat &&
103
- LeftFormat != RightFormat)
104
- Format = ExpressionFormat (ExpressionFormat::Kind::Conflict);
109
+ Expected<ExpressionFormat>
110
+ BinaryOperation::getImplicitFormat (const SourceMgr &SM) const {
111
+ Expected<ExpressionFormat> LeftFormat = LeftOperand->getImplicitFormat (SM);
112
+ Expected<ExpressionFormat> RightFormat = RightOperand->getImplicitFormat (SM);
113
+ if (!LeftFormat || !RightFormat) {
114
+ Error Err = Error::success ();
115
+ if (!LeftFormat)
116
+ Err = joinErrors (std::move (Err), LeftFormat.takeError ());
117
+ if (!RightFormat)
118
+ Err = joinErrors (std::move (Err), RightFormat.takeError ());
119
+ return std::move (Err);
120
+ }
105
121
106
- return Format;
122
+ if (*LeftFormat != ExpressionFormat::Kind::NoFormat &&
123
+ *RightFormat != ExpressionFormat::Kind::NoFormat &&
124
+ *LeftFormat != *RightFormat)
125
+ return ErrorDiagnostic::get (
126
+ SM, getExpressionStr (),
127
+ " implicit format conflict between '" + LeftOperand->getExpressionStr () +
128
+ " ' (" + LeftFormat->toString () + " ) and '" +
129
+ RightOperand->getExpressionStr () + " ' (" + RightFormat->toString () +
130
+ " ), need an explicit format specifier" );
131
+
132
+ return *LeftFormat != ExpressionFormat::Kind::NoFormat ? *LeftFormat
133
+ : *RightFormat;
107
134
}
108
135
109
136
Expected<std::string> NumericSubstitution::getResult () const {
@@ -262,9 +289,12 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
262
289
263
290
// Otherwise, parse it as a literal.
264
291
uint64_t LiteralValue;
292
+ StringRef OperandExpr = Expr;
265
293
if (!Expr.consumeInteger ((AO == AllowedOperand::LegacyLiteral) ? 10 : 0 ,
266
- LiteralValue))
267
- return std::make_unique<ExpressionLiteral>(LiteralValue);
294
+ LiteralValue)) {
295
+ return std::make_unique<ExpressionLiteral>(
296
+ OperandExpr.drop_back (Expr.size ()), LiteralValue);
297
+ }
268
298
269
299
return ErrorDiagnostic::get (SM, Expr,
270
300
" invalid operand format '" + Expr + " '" );
@@ -279,17 +309,18 @@ static uint64_t sub(uint64_t LeftOp, uint64_t RightOp) {
279
309
}
280
310
281
311
Expected<std::unique_ptr<ExpressionAST>>
282
- Pattern::parseBinop (StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp,
312
+ Pattern::parseBinop (StringRef Expr, StringRef &RemainingExpr,
313
+ std::unique_ptr<ExpressionAST> LeftOp,
283
314
bool IsLegacyLineExpr, Optional<size_t > LineNumber,
284
315
FileCheckPatternContext *Context, const SourceMgr &SM) {
285
- Expr = Expr .ltrim (SpaceChars);
286
- if (Expr .empty ())
316
+ RemainingExpr = RemainingExpr .ltrim (SpaceChars);
317
+ if (RemainingExpr .empty ())
287
318
return std::move (LeftOp);
288
319
289
320
// Check if this is a supported operation and select a function to perform
290
321
// it.
291
- SMLoc OpLoc = SMLoc::getFromPointer (Expr .data ());
292
- char Operator = popFront (Expr );
322
+ SMLoc OpLoc = SMLoc::getFromPointer (RemainingExpr .data ());
323
+ char Operator = popFront (RemainingExpr );
293
324
binop_eval_t EvalBinop;
294
325
switch (Operator) {
295
326
case ' +' :
@@ -304,19 +335,20 @@ Pattern::parseBinop(StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp,
304
335
}
305
336
306
337
// Parse right operand.
307
- Expr = Expr.ltrim (SpaceChars);
308
- if (Expr.empty ())
309
- return ErrorDiagnostic::get (SM, Expr, " missing operand in expression" );
338
+ RemainingExpr = RemainingExpr.ltrim (SpaceChars);
339
+ if (RemainingExpr.empty ())
340
+ return ErrorDiagnostic::get (SM, RemainingExpr,
341
+ " missing operand in expression" );
310
342
// The second operand in a legacy @LINE expression is always a literal.
311
343
AllowedOperand AO =
312
344
IsLegacyLineExpr ? AllowedOperand::LegacyLiteral : AllowedOperand::Any;
313
345
Expected<std::unique_ptr<ExpressionAST>> RightOpResult =
314
- parseNumericOperand (Expr , AO, LineNumber, Context, SM);
346
+ parseNumericOperand (RemainingExpr , AO, LineNumber, Context, SM);
315
347
if (!RightOpResult)
316
348
return RightOpResult;
317
349
318
- Expr = Expr.ltrim (SpaceChars );
319
- return std::make_unique<BinaryOperation>(EvalBinop, std::move (LeftOp),
350
+ Expr = Expr.drop_back (RemainingExpr. size () );
351
+ return std::make_unique<BinaryOperation>(Expr, EvalBinop, std::move (LeftOp),
320
352
std::move (*RightOpResult));
321
353
}
322
354
@@ -370,17 +402,18 @@ Expected<std::unique_ptr<Expression>> Pattern::parseNumericSubstitutionBlock(
370
402
371
403
// Parse the expression itself.
372
404
Expr = Expr.ltrim (SpaceChars);
373
- StringRef UseExpr = Expr;
374
405
if (!Expr.empty ()) {
406
+ Expr = Expr.rtrim (SpaceChars);
407
+ StringRef OuterBinOpExpr = Expr;
375
408
// The first operand in a legacy @LINE expression is always the @LINE
376
409
// pseudo variable.
377
410
AllowedOperand AO =
378
411
IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
379
412
Expected<std::unique_ptr<ExpressionAST>> ParseResult =
380
413
parseNumericOperand (Expr, AO, LineNumber, Context, SM);
381
414
while (ParseResult && !Expr.empty ()) {
382
- ParseResult = parseBinop (Expr, std::move (*ParseResult), IsLegacyLineExpr ,
383
- LineNumber, Context, SM);
415
+ ParseResult = parseBinop (OuterBinOpExpr, Expr, std::move (*ParseResult),
416
+ IsLegacyLineExpr, LineNumber, Context, SM);
384
417
// Legacy @LINE expressions only allow 2 operands.
385
418
if (ParseResult && IsLegacyLineExpr && !Expr.empty ())
386
419
return ErrorDiagnostic::get (
@@ -396,19 +429,17 @@ Expected<std::unique_ptr<Expression>> Pattern::parseNumericSubstitutionBlock(
396
429
// otherwise (ii) its implicit format, if any, otherwise (iii) the default
397
430
// format (unsigned). Error out in case of conflicting implicit format
398
431
// without explicit format.
399
- ExpressionFormat Format,
400
- ImplicitFormat = ExpressionASTPointer
401
- ? ExpressionASTPointer->getImplicitFormat ()
402
- : ExpressionFormat (ExpressionFormat::Kind::NoFormat);
403
- if (bool (ExplicitFormat))
432
+ ExpressionFormat Format;
433
+ if (ExplicitFormat)
404
434
Format = ExplicitFormat;
405
- else if (ImplicitFormat == ExpressionFormat::Kind::Conflict)
406
- return ErrorDiagnostic::get (
407
- SM, UseExpr,
408
- " variables with conflicting format specifier: need an explicit one" );
409
- else if (bool (ImplicitFormat))
410
- Format = ImplicitFormat;
411
- else
435
+ else if (ExpressionASTPointer) {
436
+ Expected<ExpressionFormat> ImplicitFormat =
437
+ ExpressionASTPointer->getImplicitFormat (SM);
438
+ if (!ImplicitFormat)
439
+ return ImplicitFormat.takeError ();
440
+ Format = *ImplicitFormat;
441
+ }
442
+ if (!Format)
412
443
Format = ExpressionFormat (ExpressionFormat::Kind::Unsigned);
413
444
414
445
std::unique_ptr<Expression> ExpressionPointer =
0 commit comments