[llvm] r361434 - TableGen: Handle nontrivial foreach range bounds
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed May 22 14:28:20 PDT 2019
Author: arsenm
Date: Wed May 22 14:28:20 2019
New Revision: 361434
URL: http://llvm.org/viewvc/llvm-project?rev=361434&view=rev
Log:
TableGen: Handle nontrivial foreach range bounds
This allows using anything that isn't a literal integer as the bounds
for a foreach. Some of the diagnostics aren't perfect, but nobody ever
accused tablegen of having good errors. For example, the existing
wording suggests a bitrange is valid, but as far as I can tell this
has never worked.
Fixes bug 41958.
Added:
llvm/trunk/test/TableGen/foreach-range-parse-errors0.td
llvm/trunk/test/TableGen/foreach-range-parse-errors1.td
llvm/trunk/test/TableGen/foreach-range-parse-errors2.td
llvm/trunk/test/TableGen/foreach-range-parse-errors3.td
llvm/trunk/test/TableGen/foreach-range-parse-errors4.td
llvm/trunk/test/TableGen/foreach-range-parse-errors5.td
llvm/trunk/test/TableGen/foreach-variable-range.td
Modified:
llvm/trunk/lib/TableGen/TGParser.cpp
llvm/trunk/lib/TableGen/TGParser.h
Modified: llvm/trunk/lib/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=361434&r1=361433&r2=361434&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.cpp (original)
+++ llvm/trunk/lib/TableGen/TGParser.cpp Wed May 22 14:28:20 2019
@@ -666,35 +666,47 @@ ParseSubMultiClassReference(MultiClass *
/// RangePiece ::= INTVAL
/// RangePiece ::= INTVAL '-' INTVAL
/// RangePiece ::= INTVAL INTVAL
-bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges) {
- if (Lex.getCode() != tgtok::IntVal) {
- TokError("expected integer or bitrange");
- return true;
- }
- int64_t Start = Lex.getCurIntVal();
+bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
+ TypedInit *FirstItem) {
+ Init *CurVal = FirstItem;
+ if (!CurVal)
+ CurVal = ParseValue(nullptr);
+
+ IntInit *II = dyn_cast_or_null<IntInit>(CurVal);
+ if (!II)
+ return TokError("expected integer or bitrange");
+
+ int64_t Start = II->getValue();
int64_t End;
if (Start < 0)
return TokError("invalid range, cannot be negative");
- switch (Lex.Lex()) { // eat first character.
+ switch (Lex.getCode()) {
default:
Ranges.push_back(Start);
return false;
- case tgtok::minus:
- if (Lex.Lex() != tgtok::IntVal) {
+ case tgtok::minus: {
+ Lex.Lex(); // eat
+
+ Init *I_End = ParseValue(nullptr);
+ IntInit *II_End = dyn_cast_or_null<IntInit>(I_End);
+ if (!II_End) {
TokError("expected integer value as end of range");
return true;
}
- End = Lex.getCurIntVal();
+
+ End = II_End->getValue();
break;
- case tgtok::IntVal:
+ }
+ case tgtok::IntVal: {
End = -Lex.getCurIntVal();
+ Lex.Lex();
break;
}
+ }
if (End < 0)
return TokError("invalid range, cannot be negative");
- Lex.Lex();
// Add to the range.
if (Start < End)
@@ -2439,12 +2451,6 @@ VarInit *TGParser::ParseForeachDeclarati
SmallVector<unsigned, 16> Ranges;
switch (Lex.getCode()) {
- case tgtok::IntVal: { // RangePiece.
- if (ParseRangePiece(Ranges))
- return nullptr;
- break;
- }
-
case tgtok::l_brace: { // '{' RangeList '}'
Lex.Lex(); // eat the '{'
ParseRangeList(Ranges);
@@ -2459,23 +2465,35 @@ VarInit *TGParser::ParseForeachDeclarati
default: {
SMLoc ValueLoc = Lex.getLoc();
Init *I = ParseValue(nullptr);
- TypedInit *TI = dyn_cast<TypedInit>(I);
- if (!TI || !isa<ListRecTy>(TI->getType())) {
- std::string Type;
- if (TI)
- Type = (Twine("' of type '") + TI->getType()->getAsString()).str();
- Error(ValueLoc, "expected a list, got '" + I->getAsString() + Type + "'");
- if (CurMultiClass)
- PrintNote({}, "references to multiclass template arguments cannot be "
- "resolved at this time");
+ if (!I)
return nullptr;
+
+ TypedInit *TI = dyn_cast<TypedInit>(I);
+ if (TI && isa<ListRecTy>(TI->getType())) {
+ ForeachListValue = I;
+ IterType = cast<ListRecTy>(TI->getType())->getElementType();
+ break;
}
- ForeachListValue = I;
- IterType = cast<ListRecTy>(TI->getType())->getElementType();
- break;
+
+ if (TI) {
+ if (ParseRangePiece(Ranges, TI))
+ return nullptr;
+ break;
+ }
+
+ std::string Type;
+ if (TI)
+ Type = (Twine("' of type '") + TI->getType()->getAsString()).str();
+ Error(ValueLoc, "expected a list, got '" + I->getAsString() + Type + "'");
+ if (CurMultiClass) {
+ PrintNote({}, "references to multiclass template arguments cannot be "
+ "resolved at this time");
+ }
+ return nullptr;
}
}
+
if (!Ranges.empty()) {
assert(!IterType && "Type already initialized?");
IterType = IntRecTy::get();
Modified: llvm/trunk/lib/TableGen/TGParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.h?rev=361434&r1=361433&r2=361434&view=diff
==============================================================================
--- llvm/trunk/lib/TableGen/TGParser.h (original)
+++ llvm/trunk/lib/TableGen/TGParser.h Wed May 22 14:28:20 2019
@@ -190,7 +190,8 @@ private: // Parser methods.
bool ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges);
bool ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges);
void ParseRangeList(SmallVectorImpl<unsigned> &Result);
- bool ParseRangePiece(SmallVectorImpl<unsigned> &Ranges);
+ bool ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
+ TypedInit *FirstItem = nullptr);
RecTy *ParseType();
Init *ParseOperation(Record *CurRec, RecTy *ItemType);
Init *ParseOperationCond(Record *CurRec, RecTy *ItemType);
Added: llvm/trunk/test/TableGen/foreach-range-parse-errors0.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/foreach-range-parse-errors0.td?rev=361434&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/foreach-range-parse-errors0.td (added)
+++ llvm/trunk/test/TableGen/foreach-range-parse-errors0.td Wed May 22 14:28:20 2019
@@ -0,0 +1,19 @@
+// RUN: not llvm-tblgen %s 2>&1 | FileCheck -DFILE=%s %s
+
+class ConstantsImpl {
+ int Zero = 0;
+ int One = 1;
+ int Two = 2;
+ int Three = 3;
+ int Five = 5;
+}
+
+def Constants : ConstantsImpl;
+
+// CHECK-NOT: error: Unknown token when parsing a value
+// CHECK: [[FILE]]:[[@LINE+3]]:22: error: Unknown token when parsing a value
+// CHECK: [[FILE]]:[[@LINE+2]]:22: error: expected integer value as end of range
+// CHECK: [[FILE]]:[[@LINE+1]]:22: error: expected declaration in for
+foreach Index = 0 - in {
+
+}
Added: llvm/trunk/test/TableGen/foreach-range-parse-errors1.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/foreach-range-parse-errors1.td?rev=361434&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/foreach-range-parse-errors1.td (added)
+++ llvm/trunk/test/TableGen/foreach-range-parse-errors1.td Wed May 22 14:28:20 2019
@@ -0,0 +1,8 @@
+// RUN: not llvm-tblgen %s 2>&1 | FileCheck -DFILE=%s %s
+
+// CHECK: [[FILE]]:[[@LINE+2]]:20: error: invalid range, cannot be negative
+// CHECK: [[FILE]]:[[@LINE+1]]:20: error: expected declaration in for
+foreach Index = -1 - 0 in {
+
+}
+
Added: llvm/trunk/test/TableGen/foreach-range-parse-errors2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/foreach-range-parse-errors2.td?rev=361434&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/foreach-range-parse-errors2.td (added)
+++ llvm/trunk/test/TableGen/foreach-range-parse-errors2.td Wed May 22 14:28:20 2019
@@ -0,0 +1,13 @@
+// RUN: not llvm-tblgen %s 2>&1 | FileCheck -DFILE=%s %s
+
+class ConstantsImpl {
+ int NegOne = -1;
+}
+
+def Constants : ConstantsImpl;
+
+// CHECK: [[FILE]]:[[@LINE+2]]:38: error: invalid range, cannot be negative
+// CHECK: [[FILE]]:[[@LINE+1]]:38: error: expected declaration in for
+foreach Index = 0 - Constants.NegOne in {
+
+}
Added: llvm/trunk/test/TableGen/foreach-range-parse-errors3.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/foreach-range-parse-errors3.td?rev=361434&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/foreach-range-parse-errors3.td (added)
+++ llvm/trunk/test/TableGen/foreach-range-parse-errors3.td Wed May 22 14:28:20 2019
@@ -0,0 +1,8 @@
+// RUN: not llvm-tblgen %s 2>&1 | FileCheck -DFILE=%s %s
+
+// CHECK: [[FILE]]:[[@LINE+2]]:21: error: expected integer or bitrange
+// CHECK: [[FILE]]:[[@LINE+1]]:21: error: expected declaration in for
+foreach Index = "0" - 1 in {
+
+}
+
Added: llvm/trunk/test/TableGen/foreach-range-parse-errors4.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/foreach-range-parse-errors4.td?rev=361434&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/foreach-range-parse-errors4.td (added)
+++ llvm/trunk/test/TableGen/foreach-range-parse-errors4.td Wed May 22 14:28:20 2019
@@ -0,0 +1,9 @@
+// RUN: not llvm-tblgen %s 2>&1 | FileCheck -DFILE=%s %s
+// Make sure there is no crash on undefined variable
+
+// CHECK: [[FILE]]:[[@LINE+2]]:17: error: Variable not defined: 'foo'
+// CHECK: [[FILE]]:[[@LINE+1]]:21: error: expected declaration in for
+foreach Index = foo in {
+ def arst#Index;
+}
+
Added: llvm/trunk/test/TableGen/foreach-range-parse-errors5.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/foreach-range-parse-errors5.td?rev=361434&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/foreach-range-parse-errors5.td (added)
+++ llvm/trunk/test/TableGen/foreach-range-parse-errors5.td Wed May 22 14:28:20 2019
@@ -0,0 +1,8 @@
+// RUN: not llvm-tblgen %s 2>&1 | FileCheck -DFILE=%s %s
+
+// CHECK: [[FILE]]:[[@LINE+2]]:23: error: expected integer or bitrange
+// CHECK: [[FILE]]:[[@LINE+1]]:23: error: expected declaration in for
+foreach Index = 0b110 - 0b111 in {
+
+}
+
Added: llvm/trunk/test/TableGen/foreach-variable-range.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/foreach-variable-range.td?rev=361434&view=auto
==============================================================================
--- llvm/trunk/test/TableGen/foreach-variable-range.td (added)
+++ llvm/trunk/test/TableGen/foreach-variable-range.td Wed May 22 14:28:20 2019
@@ -0,0 +1,128 @@
+// RUN: llvm-tblgen %s
+
+class ConstantsImpl {
+ int Zero = 0;
+ int One = 1;
+ int Two = 2;
+ int Three = 3;
+ int Five = 5;
+}
+
+def Constants : ConstantsImpl;
+
+// CHECK-DAG: def var_bound_whitespaceA0
+// CHECK-DAG: def var_bound_whitespaceA1
+// CHECK-DAG: def var_bound_whitespaceA2
+foreach Index = Constants.Zero - Constants.Two in {
+ def var_bound_whitespaceA#Index;
+}
+
+// CHECK-DAG: def var_bound_whitespaceB0
+// CHECK-DAG: def var_bound_whitespaceB1
+// CHECK-DAG: def var_bound_whitespaceB2
+foreach Index = Constants.Zero-Constants.Two in {
+ def var_bounds_whitespaceB#Index;
+}
+
+// CHECK-DAG: def var_bound_whitespaceC0
+// CHECK-DAG: def var_bound_whitespaceC1
+// CHECK-DAG: def var_bound_whitespaceC2
+foreach Index = Constants.Zero -Constants.Two in {
+ def var_bounds_whitespaceC#Index;
+}
+
+// CHECK-DAG: def var_bound_whitespaceD0
+// CHECK-DAG: def var_bound_whitespaceD1
+// CHECK-DAG: def var_bound_whitespaceD2
+foreach Index = Constants.Zero- Constants.Two in {
+ def var_bounds_whitespaceD#Index;
+}
+
+// CHECK-DAG: def const_lower_whitespaceA0
+// CHECK-DAG: def const_lower_whitespaceA1
+// CHECK-DAG: def const_lower_whitespaceA2
+foreach Index = 0 - Constants.Two in {
+ def const_lower_whitespaceA#Index;
+}
+
+// CHECK-DAG: def const_lower_whitespaceB0
+// CHECK-DAG: def const_lower_whitespaceB1
+// CHECK-DAG: def const_lower_whitespaceB2
+foreach Index = 0-Constants.Two in {
+ def const_lower_whitespaceB#Index;
+}
+
+// CHECK-DAG: def const_lower_whitespaceC0
+// CHECK-DAG: def const_lower_whitespaceC1
+// CHECK-DAG: def const_lower_whitespaceC2
+foreach Index = 0 -Constants.Two in {
+ def const_lower_whitespaceC#Index;
+}
+
+// CHECK-DAG: def const_lower_whitespaceD0
+// CHECK-DAG: def const_lower_whitespaceD1
+// CHECK-DAG: def const_lower_whitespaceD2
+foreach Index = 0- Constants.Two in {
+ def const_lower_whitespaceD#Index;
+}
+
+// CHECK-DAG: def const_upper_whitespaceA0
+// CHECK-DAG: def const_upper_whitespaceA1
+// CHECK-DAG: def const_upper_whitespaceA2
+foreach Index = Constants.Zero - 2 in {
+ def const_upper_whitespaceA#Index;
+}
+
+// CHECK-DAG: def const_upper_whitespaceB0
+// CHECK-DAG: def const_upper_whitespaceB1
+// CHECK-DAG: def const_upper_whitespaceB2
+foreach Index = Constants.Zero-2 in {
+ def const_upper_whitespaceB#Index;
+}
+
+// CHECK-DAG: def const_upper_whitespaceC0
+// CHECK-DAG: def const_upper_whitespaceC1
+// CHECK-DAG: def const_upper_whitespaceC2
+foreach Index = Constants.Zero -2 in {
+ def const_upper_whitespaceC#Index;
+}
+
+// CHECK-DAG: def const_upper_whitespaceD0
+// CHECK-DAG: def const_upper_whitespaceD1
+// CHECK-DAG: def const_upper_whitespaceD2
+foreach Index = Constants.Zero- 2 in {
+ def const_upper_whitespaceD#Index;
+}
+
+// CHECK-DAG: def multi_rangeA0
+// CHECK-DAG: def multi_rangeA1
+// CHECK-DAG: def multi_rangeA2
+// CHECK-DAG: def multi_rangeA3
+foreach Index = {Constants.Zero-Constants.One, Constants.Two-Constants.Three} in {
+ def multi_rangeA#Index;
+}
+
+// CHECK-DAG: def multi_rangeB0
+// CHECK-DAG: def multi_rangeB1
+// CHECK-DAG: def multi_rangeB3
+// CHECK-DAG: def multi_rangeB4
+// CHECK-DAG: def multi_rangeB5
+foreach Index = {0-Constants.One, Constants.Three-Constants.Five} in {
+ def multi_rangeB#Index;
+}
+
+// CHECK-DAG: def multi_rangeC0
+// CHECK-DAG: def multi_rangeC1
+// CHECK-DAG: def multi_rangeC2
+// CHECK-DAG: def multi_rangeC3
+foreach Index = {0-Constants.One, 2-Constants.Three} in {
+ def multi_rangeC#Index;
+}
+
+// CHECK-DAG: def multi_rangeD0
+// CHECK-DAG: def multi_rangeD1
+// CHECK-DAG: def multi_rangeD2
+// CHECK-DAG: def multi_rangeD3
+foreach Index = {0-1, Constants.Two-3} in {
+ def multi_rangeD#Index;
+}
More information about the llvm-commits
mailing list