mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 02:33:33 +00:00
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
This commit is contained in:
parent
1c2c462d0f
commit
d34a73b3b7
@ -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…
x
Reference in New Issue
Block a user