aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2011-10-19 13:04:35 +0000
committerDavid Greene <greened@obbligato.org>2011-10-19 13:04:35 +0000
commite5b252f9fe7a3dfc85ae25ca1603cb406071851b (patch)
tree3d6a8bdc7b67510854f6ec8944e2161a63f3d357
parent7be867e48300861b7b1bf614eb204463533d6724 (diff)
Process NAME
During multiclass def instantiation, replace NAME in any expressions with the value of the def or defm ID. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142524 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/TableGen/TGParser.cpp43
1 files changed, 35 insertions, 8 deletions
diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp
index e88a23256c..53e4fdcae0 100644
--- a/lib/TableGen/TGParser.cpp
+++ b/lib/TableGen/TGParser.cpp
@@ -2022,6 +2022,41 @@ InstantiateMulticlassDef(MultiClass &MC,
Ref.Rec = DefProto;
AddSubClass(CurRec, Ref);
+ if (DefNameString == 0) {
+ // We must resolve references to NAME.
+ if (SetValue(CurRec, Ref.RefLoc, "NAME", std::vector<unsigned>(),
+ DefmPrefix)) {
+ Error(DefmPrefixLoc, "Could not resolve "
+ + CurRec->getNameInitAsString() + ":NAME to '"
+ + DefmPrefix->getAsUnquotedString() + "'");
+ return 0;
+ }
+
+ RecordVal *DefNameRV = CurRec->getValue("NAME");
+ CurRec->resolveReferencesTo(DefNameRV);
+ }
+
+ if (!CurMultiClass) {
+ // We do this after resolving NAME because before resolution, many
+ // multiclass defs will have the same name expression. If we are
+ // currently in a multiclass, it means this defm appears inside a
+ // multiclass and its name won't be fully resolvable until we see
+ // the top-level defm. Therefore, we don't add this to the
+ // RecordKeeper at this point. If we did we could get duplicate
+ // defs as more than one probably refers to NAME or some other
+ // common internal placeholder.
+
+ // Ensure redefinition doesn't happen.
+ if (Records.getDef(CurRec->getNameInitAsString())) {
+ Error(DefmPrefixLoc, "def '" + CurRec->getNameInitAsString() +
+ "' already defined, instantiating defm with subdef '" +
+ DefProto->getNameInitAsString() + "'");
+ return 0;
+ }
+
+ Records.addDef(CurRec);
+ }
+
return CurRec;
}
@@ -2070,12 +2105,6 @@ bool TGParser::ResolveMulticlassDef(MultiClass &MC,
LetStack[i][j].Bits, LetStack[i][j].Value))
return Error(DefmPrefixLoc, "when instantiating this defm");
- // Ensure redefinition doesn't happen.
- if (Records.getDef(CurRec->getName()))
- return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
- "' already defined, instantiating defm with subdef '" +
- DefProto->getName() + "'");
-
// Don't create a top level definition for defm inside multiclasses,
// instead, only update the prototypes and bind the template args
// with the new created definition.
@@ -2097,8 +2126,6 @@ bool TGParser::ResolveMulticlassDef(MultiClass &MC,
assert(RV && "Template arg doesn't exist?");
CurRec->addValue(*RV);
}
- } else {
- Records.addDef(CurRec);
}
return false;