forked from OSchip/llvm-project
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. llvm-svn: 69974
This commit is contained in:
parent
62d47d2361
commit
7049e79e45
|
@ -1,4 +1,4 @@
|
|||
// RUN: tblgen %s | grep {zing = 4} | count 4
|
||||
// RUN: tblgen %s | grep {zing = 4} | count 28
|
||||
|
||||
class C1<int A, string B> {
|
||||
int bar = A;
|
||||
|
@ -8,25 +8,57 @@ class C1<int A, string B> {
|
|||
|
||||
def T : C1<4, "blah">;
|
||||
|
||||
multiclass t<int a> {
|
||||
def S1 : C1<a, "foo"> {
|
||||
multiclass t1<int a1> {
|
||||
def S1 : C1<a1, "foo"> {
|
||||
int foo = 4;
|
||||
let bar = 1;
|
||||
}
|
||||
def S2 : C1<a, "bar">;
|
||||
def S2 : C1<a1, "bar">;
|
||||
}
|
||||
|
||||
multiclass s<int a, int b> : t<a> {
|
||||
def S3 : C1<b, "moo"> {
|
||||
multiclass t2<int a2> {
|
||||
def S3 : C1<a2, "foo"> {
|
||||
int foo = 4;
|
||||
let bar = 1;
|
||||
}
|
||||
def S4 : C1<a2, "bar">;
|
||||
}
|
||||
|
||||
multiclass s1<int as1, int bs1> : t1<as1> {
|
||||
def S5 : C1<bs1, "moo"> {
|
||||
int moo = 3;
|
||||
let bar = 1;
|
||||
}
|
||||
def S4 : C1<b, "baz">;
|
||||
def S6 : C1<bs1, "baz">;
|
||||
}
|
||||
|
||||
defm FOO : s<42, 24>;
|
||||
multiclass s2<int as2> : t1<as2>, t2<as2>;
|
||||
|
||||
multiclass s3<int as3, int bs3> : t1<as3>, t2<as3> {
|
||||
def S7 : C1<bs3, "moo"> {
|
||||
int moo = 3;
|
||||
let bar = 1;
|
||||
}
|
||||
def S8 : C1<bs3, "baz">;
|
||||
}
|
||||
|
||||
let zing = 4 in
|
||||
defm FOO1 : s1<42, 24>;
|
||||
|
||||
let zing = 4 in
|
||||
defm FOO2 : s2<99>;
|
||||
|
||||
let zing = 4 in
|
||||
defm FOO3 : s3<84, 48>;
|
||||
|
||||
def T4 : C1<6, "foo">;
|
||||
|
||||
let zing = 4 in
|
||||
defm BAZ : s<3, 4>;
|
||||
defm BAZ1 : s1<3, 4>;
|
||||
|
||||
let zing = 4 in
|
||||
defm BAZ2 : s2<5>;
|
||||
|
||||
let zing = 4 in
|
||||
defm BAZ3 : s3<6, 7>;
|
||||
|
||||
|
|
|
@ -1060,6 +1060,20 @@ std::string Record::getValueAsCode(const std::string &FieldName) const {
|
|||
}
|
||||
|
||||
|
||||
void MultiClass::dump() const {
|
||||
cerr << "Record:\n";
|
||||
Rec.dump();
|
||||
|
||||
cerr << "Defs:\n";
|
||||
for (RecordVector::const_iterator r = DefPrototypes.begin(),
|
||||
rend = DefPrototypes.end();
|
||||
r != rend;
|
||||
++r) {
|
||||
(*r)->dump();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RecordKeeper::dump() const { cerr << *this; }
|
||||
|
||||
std::ostream &llvm::operator<<(std::ostream &OS, const RecordKeeper &RK) {
|
||||
|
|
|
@ -1138,7 +1138,9 @@ struct MultiClass {
|
|||
Record Rec; // Placeholder for template args and Name.
|
||||
typedef std::vector<Record*> RecordVector;
|
||||
RecordVector DefPrototypes;
|
||||
|
||||
|
||||
void dump() const;
|
||||
|
||||
MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue