aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/TGParser.cpp
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2009-04-24 16:55:41 +0000
committerDavid Greene <greened@obbligato.org>2009-04-24 16:55:41 +0000
commitd34a73b3b709001c56db68a4d9a84e5d2002b1f0 (patch)
treee6b18f83f4e8efce6b3b11b73c3eec31327a4477 /utils/TableGen/TGParser.cpp
parent1c2c462d0f993e3575888d5825b9c25348e6e4e8 (diff)
Fix multiclass inheritance to limit value resolution to new defs added
by base multiclasses. Do not attempt to alter defs from previous base multiclasses. This fixes multiple multiclass inheritance. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/TGParser.cpp')
-rw-r--r--utils/TableGen/TGParser.cpp79
1 files changed, 59 insertions, 20 deletions
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index c3b17ac603..8d0c9e5002 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -16,6 +16,7 @@
#include "TGParser.h"
#include "Record.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Streams.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -28,7 +29,7 @@ struct SubClassReference {
Record *Rec;
std::vector<Init*> TemplateArgs;
SubClassReference() : Rec(0) {}
-
+
bool isInvalid() const { return Rec == 0; }
};
@@ -39,8 +40,23 @@ struct SubMultiClassReference {
SubMultiClassReference() : MC(0) {}
bool isInvalid() const { return MC == 0; }
+ void dump() const;
};
-
+
+void SubMultiClassReference::dump() const {
+ cerr << "Multiclass:\n";
+
+ MC->dump();
+
+ cerr << "Template args:\n";
+ for (std::vector<Init *>::const_iterator i = TemplateArgs.begin(),
+ iend = TemplateArgs.end();
+ i != iend;
+ ++i) {
+ (*i)->dump();
+ }
+}
+
} // end namespace llvm
bool TGParser::AddValue(Record *CurRec, TGLoc Loc, const RecordVal &RV) {
@@ -182,7 +198,8 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
/// AddSubMultiClass - Add SubMultiClass as a subclass to
/// CurMultiClass, resolving its template args as SubMultiClass's
/// template arguments.
-bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassReference &SubMultiClass) {
+bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass,
+ class SubMultiClassReference &SubMultiClass) {
MultiClass *SMC = SubMultiClass.MC;
Record *CurRec = &CurMultiClass->Rec;
@@ -194,6 +211,8 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassRe
if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
return true;
+ int newDefStart = CurMultiClass->DefPrototypes.size();
+
// Add all of the defs in the subclass into the current multiclass.
for (MultiClass::RecordVector::const_iterator i = SMC->DefPrototypes.begin(),
iend = SMC->DefPrototypes.end();
@@ -212,16 +231,20 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassRe
const std::vector<std::string> &SMCTArgs = SMC->Rec.getTemplateArgs();
- // Ensure that an appropriate number of template arguments are specified.
+ // Ensure that an appropriate number of template arguments are
+ // specified.
if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
- return Error(SubMultiClass.RefLoc, "More template args specified than expected");
+ return Error(SubMultiClass.RefLoc,
+ "More template args specified than expected");
// 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 = SMCTArgs.size(); i != e; ++i) {
if (i < SubMultiClass.TemplateArgs.size()) {
- // If a value is specified for this template arg, set it in the superclass now.
- if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i], std::vector<unsigned>(),
+ // If a value is specified for this template arg, set it in the
+ // superclass now.
+ if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],
+ std::vector<unsigned>(),
SubMultiClass.TemplateArgs[i]))
return true;
@@ -231,14 +254,17 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassRe
// Now remove it.
CurRec->removeValue(SMCTArgs[i]);
- // If a value is specified for this template arg, set it in the defs now.
- for (MultiClass::RecordVector::iterator j = CurMultiClass->DefPrototypes.begin(),
+ // If a value is specified for this template arg, set it in the
+ // new defs now.
+ for (MultiClass::RecordVector::iterator j =
+ CurMultiClass->DefPrototypes.begin() + newDefStart,
jend = CurMultiClass->DefPrototypes.end();
j != jend;
++j) {
Record *Def = *j;
- if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i], std::vector<unsigned>(),
+ if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],
+ std::vector<unsigned>(),
SubMultiClass.TemplateArgs[i]))
return true;
@@ -249,7 +275,8 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassRe
Def->removeValue(SMCTArgs[i]);
}
} else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
- return Error(SubMultiClass.RefLoc,"Value not specified for template argument #"
+ return Error(SubMultiClass.RefLoc,
+ "Value not specified for template argument #"
+ utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" +
SMC->Rec.getName() + "'!");
}
@@ -1490,8 +1517,12 @@ bool TGParser::ParseMultiClass() {
if (ParseTemplateArgList(0))
return true;
+ bool inherits = false;
+
// If there are submulticlasses, parse them.
if (Lex.getCode() == tgtok::colon) {
+ inherits = true;
+
Lex.Lex();
// Read all of the submulticlasses.
@@ -1510,17 +1541,25 @@ bool TGParser::ParseMultiClass() {
}
}
- if (Lex.getCode() != tgtok::l_brace)
- return TokError("expected '{' in multiclass definition");
-
- if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
- return TokError("multiclass must contain at least one def");
+ if (Lex.getCode() != tgtok::l_brace) {
+ if (!inherits)
+ return TokError("expected '{' in multiclass definition");
+ else
+ if (Lex.getCode() != tgtok::semi)
+ return TokError("expected ';' in multiclass definition");
+ else
+ Lex.Lex(); // eat the ';'.
+ }
+ else {
+ if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
+ return TokError("multiclass must contain at least one def");
- while (Lex.getCode() != tgtok::r_brace)
- if (ParseMultiClassDef(CurMultiClass))
- return true;
+ while (Lex.getCode() != tgtok::r_brace)
+ if (ParseMultiClassDef(CurMultiClass))
+ return true;
- Lex.Lex(); // eat the '}'.
+ Lex.Lex(); // eat the '}'.
+ }
CurMultiClass = 0;
return false;