summaryrefslogtreecommitdiffstats
path: root/llvm/lib/TableGen/TGParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/TableGen/TGParser.cpp')
-rw-r--r--llvm/lib/TableGen/TGParser.cpp76
1 files changed, 32 insertions, 44 deletions
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 642812d5ceb..654b4fd1ce5 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -1346,61 +1346,49 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
return nullptr;
}
- SubClassReference SCRef;
- ParseValueList(SCRef.TemplateArgs, CurRec, Class);
- if (SCRef.TemplateArgs.empty()) return nullptr;
+ SmallVector<Init *, 8> Args;
+ ParseValueList(Args, CurRec, Class);
+ if (Args.empty()) return nullptr;
if (Lex.getCode() != tgtok::greater) {
TokError("expected '>' at end of value list");
return nullptr;
}
Lex.Lex(); // eat the '>'
- SMLoc EndLoc = Lex.getLoc();
-
- // Create the new record, set it as CurRec temporarily.
- auto NewRecOwner =
- make_unique<Record>(Records.getNewAnonymousName(), NameLoc, Records,
- /*IsAnonymous=*/true);
- Record *NewRec = NewRecOwner.get(); // Keep a copy since we may release.
- SCRef.RefRange = SMRange(NameLoc, EndLoc);
- SCRef.Rec = Class;
- // Add info about the subclass to NewRec.
- if (AddSubClass(NewRec, SCRef))
- return nullptr;
- if (!CurMultiClass) {
- NewRec->resolveReferences();
- Records.addDef(std::move(NewRecOwner));
- } else {
- // This needs to get resolved once the multiclass template arguments are
- // known before any use.
- NewRec->setResolveFirst(true);
- // Otherwise, we're inside a multiclass, add it to the multiclass.
- CurMultiClass->DefPrototypes.push_back(std::move(NewRecOwner));
-
- // Copy the template arguments for the multiclass into the def.
- for (Init *TArg : CurMultiClass->Rec.getTemplateArgs()) {
- const RecordVal *RV = CurMultiClass->Rec.getValue(TArg);
- assert(RV && "Template arg doesn't exist?");
- NewRec->addValue(*RV);
- }
+ // Typecheck the template arguments list
+ ArrayRef<Init *> ExpectedArgs = Class->getTemplateArgs();
+ if (ExpectedArgs.size() < Args.size()) {
+ Error(NameLoc,
+ "More template args specified than expected");
+ return nullptr;
+ }
- // We can't return the prototype def here, instead return:
- // !cast<ItemType>(!strconcat(NAME, AnonName)).
- const RecordVal *MCNameRV = CurMultiClass->Rec.getValue("NAME");
- assert(MCNameRV && "multiclass record must have a NAME");
+ for (unsigned i = 0, e = ExpectedArgs.size(); i != e; ++i) {
+ RecordVal *ExpectedArg = Class->getValue(ExpectedArgs[i]);
+ if (i < Args.size()) {
+ if (TypedInit *TI = dyn_cast<TypedInit>(Args[i])) {
+ RecTy *ExpectedType = ExpectedArg->getType();
+ if (!TI->getType()->typeIsConvertibleTo(ExpectedType)) {
+ Error(NameLoc,
+ "Value specified for template argument #" + Twine(i) + " (" +
+ ExpectedArg->getNameInitAsString() + ") is of type '" +
+ TI->getType()->getAsString() + "', expected '" +
+ ExpectedType->getAsString() + "': " + TI->getAsString());
+ return nullptr;
+ }
+ continue;
+ }
+ } else if (ExpectedArg->getValue()->isComplete())
+ continue;
- return UnOpInit::get(UnOpInit::CAST,
- BinOpInit::get(BinOpInit::STRCONCAT,
- VarInit::get(MCNameRV->getName(),
- MCNameRV->getType()),
- NewRec->getNameInit(),
- StringRecTy::get()),
- NewRec->getDefInit()->getType());
+ Error(NameLoc,
+ "Value not specified for template argument #" + Twine(i) + " (" +
+ ExpectedArgs[i]->getAsUnquotedString() + ")");
+ return nullptr;
}
- // The result of the expression is a reference to the new record.
- return DefInit::get(NewRec);
+ return VarDefInit::get(Class, Args)->Fold();
}
case tgtok::l_brace: { // Value ::= '{' ValueList '}'
SMLoc BraceLoc = Lex.getLoc();
OpenPOWER on IntegriCloud