aboutsummaryrefslogtreecommitdiff
path: root/lib/TableGen/TGParser.cpp
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2011-10-05 22:42:45 +0000
committerDavid Greene <greened@obbligato.org>2011-10-05 22:42:45 +0000
commita6d442e65179092542d161679414b1e4e063ec4d (patch)
treea8537253d874eacf898a5456412f410c030d7345 /lib/TableGen/TGParser.cpp
parent6da674cda1587c9b09e01f65219cec54f54d90b8 (diff)
Process Multidefs
Process each multidef declared in a multiclass. Iterate through the list and instantiate a def in the multiclass for each item, resolving the list item to the temporary iterator (possibly) used in the multidef ObjectBody. We then process each generated def in the normal way. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141233 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/TableGen/TGParser.cpp')
-rw-r--r--lib/TableGen/TGParser.cpp86
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index fafac0c29d..ed51977c3d 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -2174,6 +2174,92 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
NewRecDefs.push_back(CurRec);
}
+ // Loop over multidefs, instantiating them.
+ for (unsigned i = 0, e = MC->MultiDefPrototypes.size(); i != e; ++i) {
+ // Each multidef generates a set of defs, one per item in the
+ // given list.
+
+ // Resolve the list now. This record serves as a base class for
+ // the individual records created below.
+
+ Record *DefProto = MC->MultiDefPrototypes[i].Rec;
+ TypedInit *List = MC->MultiDefPrototypes[i].List;
+ IntInit *Start = MC->MultiDefPrototypes[i].Start;
+
+ // This is the name of the second item in the multidef <> list.
+ // It is a temporary iterator that holds the current value of
+ // the list element being processed.
+ std::string &ItemName = MC->MultiDefPrototypes[i].ItemName;
+
+ Record *BaseRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix,
+ DefmPrefixLoc);
+
+ // Make the list a member of the base record.
+ RecordVal ListV("__MDListInit__", List->getType(), 0);
+ ListV.setValue(List);
+ BaseRec->addValue(ListV);
+
+ // Resolve the base multidef record to template args. This
+ // should resolve the list. We don't delete the arguments
+ // values because we want the created defs to inherit them.
+ // Each list item needs to be resolved against these values.
+ // They will be deleted when we do final processing of the
+ // instantiated def.
+ if (ResolveMulticlassDefArgs(*MC, BaseRec, DefmPrefixLoc,
+ SubClassLoc, TArgs, TemplateVals,
+ false/*Do not delete args*/))
+ return Error(SubClassLoc, "could not instantiate def");
+
+ RecordVal *ListVP = BaseRec->getValue("__MDListInit__");
+ ListInit *ListIn = dynamic_cast<ListInit *>(ListVP->getValue());
+ if (ListIn == 0)
+ return Error(SubClassLoc, "multidef init must be of list type");
+
+ // Remove the temporary list since we've resolve it and don't
+ // need it to be part of the defs.
+ BaseRec->removeValue("__MDListInit__");
+
+ // For each item in the list, create a def.
+ for(int64_t it = Start->getValue(); it < ListIn->getSize(); ++it) {
+ std::stringstream id;
+ id << it;
+
+ // Create a record prefixed with MD<n>., where <n> is an
+ // incrementing value. This guarantees that defs created via
+ // multidefs are named uniquely.
+ Record *CurRec = InstantiateMulticlassDef(*MC, BaseRec,
+ "MD" + id.str() + ".",
+ DefmPrefixLoc);
+
+ // Get the list item and resolve it.
+ Init *ItemVal = ListIn->resolveListElementReference(*CurRec, 0, it);
+
+ if (!ItemVal)
+ return Error(SubClassLoc, "invalid list item");
+
+ // Set the temporary item (iterator) value now.
+ if (SetValue(CurRec, SubClassLoc, ItemName, std::vector<unsigned>(), ItemVal)) {
+ Error(DefmPrefixLoc, "when instantiating this defm");
+ return true;
+ }
+
+ // Resolve it next.
+ CurRec->resolveReferencesTo(CurRec->getValue(ItemName));
+
+ // Remove it.
+ CurRec->removeValue(ItemName);
+
+ // Now instantiate the def as if it had been declared directly
+ // as part of the multicass.
+ if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc,
+ SubClassLoc, TArgs, TemplateVals,
+ true/*Delete args*/))
+ return Error(SubClassLoc, "could not instantiate def");
+
+ if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc))
+ return Error(SubClassLoc, "could not instantiate def");
+ }
+ }
if (Lex.getCode() != tgtok::comma) break;
Lex.Lex(); // eat ','.