summaryrefslogtreecommitdiffstats
path: root/llvm/lib/TableGen/TGParser.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2019-05-22 21:28:20 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2019-05-22 21:28:20 +0000
commitb79a25b124376262b5df89686bf0c374ada0e977 (patch)
tree1054aaa6769bca5cfbdb7b465a198c6384c719a1 /llvm/lib/TableGen/TGParser.cpp
parent5498486b46658d7c55bba7fcfc4257629baa3285 (diff)
downloadbcm5719-llvm-b79a25b124376262b5df89686bf0c374ada0e977.tar.gz
bcm5719-llvm-b79a25b124376262b5df89686bf0c374ada0e977.zip
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. llvm-svn: 361434
Diffstat (limited to 'llvm/lib/TableGen/TGParser.cpp')
-rw-r--r--llvm/lib/TableGen/TGParser.cpp78
1 files changed, 48 insertions, 30 deletions
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 6a460870aa9..a9ace152d59 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -666,35 +666,47 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
/// 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::ParseForeachDeclaration(Init *&ForeachListValue) {
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::ParseForeachDeclaration(Init *&ForeachListValue) {
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();
OpenPOWER on IntegriCloud