summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2009-04-22 22:17:51 +0000
committerDavid Greene <greened@obbligato.org>2009-04-22 22:17:51 +0000
commit5654613a013b94a92f9ed65e1a2f34e0a8d9cfdf (patch)
treed29f21688078d41bdb26dc0a2ae1503978ccebe5 /utils
parentc7cafcd815519b06318629b424abe746437e1389 (diff)
downloadllvm-5654613a013b94a92f9ed65e1a2f34e0a8d9cfdf.tar.gz
llvm-5654613a013b94a92f9ed65e1a2f34e0a8d9cfdf.tar.bz2
llvm-5654613a013b94a92f9ed65e1a2f34e0a8d9cfdf.tar.xz
Allow defm to inherit from multiple multiclasses.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69832 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/TGParser.cpp144
1 files changed, 76 insertions, 68 deletions
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index 45ad5792f9..d7feb98d2a 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -1482,77 +1482,85 @@ bool TGParser::ParseDefm() {
TGLoc SubClassLoc = Lex.getLoc();
SubClassReference Ref = ParseSubClassReference(0, true);
- if (Ref.Rec == 0) return true;
-
- if (Lex.getCode() != tgtok::semi)
- return TokError("expected ';' at end of defm");
- Lex.Lex();
-
- // To instantiate a multiclass, we need to first get the multiclass, then
- // instantiate each def contained in the multiclass with the SubClassRef
- // template parameters.
- MultiClass *MC = MultiClasses[Ref.Rec->getName()];
- assert(MC && "Didn't lookup multiclass correctly?");
- std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
-
- // Verify that the correct number of template arguments were specified.
- const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
- if (TArgs.size() < TemplateVals.size())
- return Error(SubClassLoc,
- "more template args specified than multiclass expects");
-
- // Loop over all the def's in the multiclass, instantiating each one.
- for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
- Record *DefProto = MC->DefPrototypes[i];
-
- // Add the suffix to the defm name to get the new name.
- Record *CurRec = new Record(DefmPrefix + DefProto->getName(),DefmPrefixLoc);
-
- SubClassReference Ref;
- Ref.RefLoc = DefmPrefixLoc;
- Ref.Rec = DefProto;
- AddSubClass(CurRec, Ref);
-
- // Loop over all of the template arguments, setting them to the specified
- // value or leaving them as the default if necessary.
- for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
- if (i < TemplateVals.size()) { // A value is specified for this temp-arg?
- // Set it now.
- if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
- TemplateVals[i]))
- return true;
-
- // Resolve it next.
- CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-
- // Now remove it.
- CurRec->removeValue(TArgs[i]);
-
- } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
- return Error(SubClassLoc, "value not specified for template argument #"+
- utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
- MC->Rec.getName() + "'");
+
+ while (1) {
+ if (Ref.Rec == 0) return true;
+
+ // To instantiate a multiclass, we need to first get the multiclass, then
+ // instantiate each def contained in the multiclass with the SubClassRef
+ // template parameters.
+ MultiClass *MC = MultiClasses[Ref.Rec->getName()];
+ assert(MC && "Didn't lookup multiclass correctly?");
+ std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
+
+ // Verify that the correct number of template arguments were specified.
+ const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
+ if (TArgs.size() < TemplateVals.size())
+ return Error(SubClassLoc,
+ "more template args specified than multiclass expects");
+
+ // Loop over all the def's in the multiclass, instantiating each one.
+ for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
+ Record *DefProto = MC->DefPrototypes[i];
+
+ // Add the suffix to the defm name to get the new name.
+ Record *CurRec = new Record(DefmPrefix + DefProto->getName(), DefmPrefixLoc);
+
+ SubClassReference Ref;
+ Ref.RefLoc = DefmPrefixLoc;
+ Ref.Rec = DefProto;
+ AddSubClass(CurRec, Ref);
+
+ // Loop over all of the template arguments, setting them to the specified
+ // value or leaving them as the default if necessary.
+ for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+ if (i < TemplateVals.size()) { // A value is specified for this temp-arg?
+ // Set it now.
+ if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
+ TemplateVals[i]))
+ return true;
+
+ // Resolve it next.
+ CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+
+ // Now remove it.
+ CurRec->removeValue(TArgs[i]);
+
+ } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
+ return Error(SubClassLoc, "value not specified for template argument #"+
+ utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
+ MC->Rec.getName() + "'");
+ }
}
+
+ // If the mdef is inside a 'let' expression, add to each def.
+ for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
+ for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
+ if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
+ LetStack[i][j].Bits, LetStack[i][j].Value)) {
+ Error(DefmPrefixLoc, "when instantiating this defm");
+ return true;
+ }
+
+ // Ensure redefinition doesn't happen.
+ if (Records.getDef(CurRec->getName()))
+ return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
+ "' already defined, instantiating defm with subdef '" +
+ DefProto->getName() + "'");
+ Records.addDef(CurRec);
+ CurRec->resolveReferences();
}
-
- // If the mdef is inside a 'let' expression, add to each def.
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
- LetStack[i][j].Bits, LetStack[i][j].Value)) {
- Error(DefmPrefixLoc, "when instantiating this defm");
- return true;
- }
-
-
- // Ensure redefinition doesn't happen.
- if (Records.getDef(CurRec->getName()))
- return Error(DefmPrefixLoc, "def '" + CurRec->getName() +
- "' already defined, instantiating defm with subdef '" +
- DefProto->getName() + "'");
- Records.addDef(CurRec);
- CurRec->resolveReferences();
+
+ if (Lex.getCode() != tgtok::comma) break;
+ Lex.Lex(); // eat ','.
+
+ SubClassLoc = Lex.getLoc();
+ Ref = ParseSubClassReference(0, true);
}
+
+ if (Lex.getCode() != tgtok::semi)
+ return TokError("expected ';' at end of defm");
+ Lex.Lex();
return false;
}