summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/TableGen/TGParser.cpp47
1 files changed, 42 insertions, 5 deletions
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index be5a524251..2a6b3f4049 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -1225,8 +1225,36 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
// Add info about the subclass to NewRec.
if (AddSubClass(NewRec, SCRef))
return 0;
- NewRec->resolveReferences();
- Records.addDef(NewRec);
+ if (!CurMultiClass) {
+ NewRec->resolveReferences();
+ Records.addDef(NewRec);
+ } else {
+ // Otherwise, we're inside a multiclass, add it to the multiclass.
+ CurMultiClass->DefPrototypes.push_back(NewRec);
+
+ // Copy the template arguments for the multiclass into the def.
+ const std::vector<Init *> &TArgs =
+ CurMultiClass->Rec.getTemplateArgs();
+
+ for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+ const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
+ assert(RV && "Template arg doesn't exist?");
+ NewRec->addValue(*RV);
+ }
+
+ // 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");
+
+ return UnOpInit::get(UnOpInit::CAST,
+ BinOpInit::get(BinOpInit::STRCONCAT,
+ VarInit::get(MCNameRV->getName(),
+ MCNameRV->getType()),
+ NewRec->getNameInit(),
+ StringRecTy::get()),
+ Class->getDefInit()->getType());
+ }
// The result of the expression is a reference to the new record.
return DefInit::get(NewRec);
@@ -1962,7 +1990,18 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
return true;
}
Records.addDef(CurRec);
+
+ if (ParseObjectBody(CurRec))
+ return true;
} else if (CurMultiClass) {
+ // Parse the body before adding this prototype to the DefPrototypes vector.
+ // That way implicit definitions will be added to the DefPrototypes vector
+ // before this object, instantiated prior to defs derived from this object,
+ // and this available for indirect name resolution when defs derived from
+ // this object are instantiated.
+ if (ParseObjectBody(CurRec))
+ return true;
+
// Otherwise, a def inside a multiclass, add it to the multiclass.
for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i)
if (CurMultiClass->DefPrototypes[i]->getNameInit()
@@ -1972,9 +2011,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
return true;
}
CurMultiClass->DefPrototypes.push_back(CurRec);
- }
-
- if (ParseObjectBody(CurRec))
+ } else if (ParseObjectBody(CurRec))
return true;
if (CurMultiClass == 0) // Def's in multiclasses aren't really defs.