llvm.org GIT mirror llvm / d34a73b
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 David Greene 10 years ago
4 changed file(s) with 119 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
None // RUN: tblgen %s | grep {zing = 4} | count 4
0 // RUN: tblgen %s | grep {zing = 4} | count 28
11
22 class C1 {
33 int bar = A;
77
88 def T : C1<4, "blah">;
99
10 multiclass t {
11 def S1 : C1> {
10 multiclass t1> {
11 def S1 : C1 {
1212 int foo = 4;
1313 let bar = 1;
1414 }
15 def S2 : C1, "bar">;
15 def S2 : C11, "bar">;
1616 }
1717
18 multiclass s : t {
19 def S3 : C1> {
18 multiclass t2> {
19 def S3 : C1 {
20 int foo = 4;
21 let bar = 1;
22 }
23 def S4 : C1;
24 }
25
26 multiclass s1 : t1 {
27 def S5 : C1 {
2028 int moo = 3;
2129 let bar = 1;
2230 }
23 def S4 : C1, "baz">;
31 def S6 : C1, "baz">;
2432 }
2533
26 defm FOO : s<42, 24>;
34 multiclass s2 : t1, t2>;
35
36 multiclass s3 : t1, t2 {
37 def S7 : C1 {
38 int moo = 3;
39 let bar = 1;
40 }
41 def S8 : C1;
42 }
43
44 let zing = 4 in
45 defm FOO1 : s1<42, 24>;
46
47 let zing = 4 in
48 defm FOO2 : s2<99>;
49
50 let zing = 4 in
51 defm FOO3 : s3<84, 48>;
2752
2853 def T4 : C1<6, "foo">;
2954
3055 let zing = 4 in
31 defm BAZ : s<3, 4>;
56 defm BAZ1 : s1<3, 4>;
57
58 let zing = 4 in
59 defm BAZ2 : s2<5>;
60
61 let zing = 4 in
62 defm BAZ3 : s3<6, 7>;
63
10591059 }
10601060
10611061
1062 void MultiClass::dump() const {
1063 cerr << "Record:\n";
1064 Rec.dump();
1065
1066 cerr << "Defs:\n";
1067 for (RecordVector::const_iterator r = DefPrototypes.begin(),
1068 rend = DefPrototypes.end();
1069 r != rend;
1070 ++r) {
1071 (*r)->dump();
1072 }
1073 }
1074
1075
10621076 void RecordKeeper::dump() const { cerr << *this; }
10631077
10641078 std::ostream &llvm::operator<<(std::ostream &OS, const RecordKeeper &RK) {
11371137 Record Rec; // Placeholder for template args and Name.
11381138 typedef std::vector RecordVector;
11391139 RecordVector DefPrototypes;
1140
1140
1141 void dump() const;
1142
11411143 MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
11421144 };
11431145
1515 #include "TGParser.h"
1616 #include "Record.h"
1717 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/Streams.h"
1819 using namespace llvm;
1920
2021 //===----------------------------------------------------------------------===//
2728 Record *Rec;
2829 std::vector TemplateArgs;
2930 SubClassReference() : Rec(0) {}
30
31
3132 bool isInvalid() const { return Rec == 0; }
3233 };
3334
3839 SubMultiClassReference() : MC(0) {}
3940
4041 bool isInvalid() const { return MC == 0; }
42 void dump() const;
4143 };
42
44
45 void SubMultiClassReference::dump() const {
46 cerr << "Multiclass:\n";
47
48 MC->dump();
49
50 cerr << "Template args:\n";
51 for (std::vector::const_iterator i = TemplateArgs.begin(),
52 iend = TemplateArgs.end();
53 i != iend;
54 ++i) {
55 (*i)->dump();
56 }
57 }
58
4359 } // end namespace llvm
4460
4561 bool TGParser::AddValue(Record *CurRec, TGLoc Loc, const RecordVal &RV) {
181197 /// AddSubMultiClass - Add SubMultiClass as a subclass to
182198 /// CurMultiClass, resolving its template args as SubMultiClass's
183199 /// template arguments.
184 bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassReference &SubMultiClass) {
200 bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass,
201 class SubMultiClassReference &SubMultiClass) {
185202 MultiClass *SMC = SubMultiClass.MC;
186203 Record *CurRec = &CurMultiClass->Rec;
187204
192209 for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
193210 if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
194211 return true;
212
213 int newDefStart = CurMultiClass->DefPrototypes.size();
195214
196215 // Add all of the defs in the subclass into the current multiclass.
197216 for (MultiClass::RecordVector::const_iterator i = SMC->DefPrototypes.begin(),
211230
212231 const std::vector &SMCTArgs = SMC->Rec.getTemplateArgs();
213232
214 // Ensure that an appropriate number of template arguments are specified.
233 // Ensure that an appropriate number of template arguments are
234 // specified.
215235 if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
216 return Error(SubMultiClass.RefLoc, "More template args specified than expected");
236 return Error(SubMultiClass.RefLoc,
237 "More template args specified than expected");
217238
218239 // Loop over all of the template arguments, setting them to the specified
219240 // value or leaving them as the default if necessary.
220241 for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
221242 if (i < SubMultiClass.TemplateArgs.size()) {
222 // If a value is specified for this template arg, set it in the superclass now.
223 if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i], std::vector(),
243 // If a value is specified for this template arg, set it in the
244 // superclass now.
245 if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],
246 std::vector(),
224247 SubMultiClass.TemplateArgs[i]))
225248 return true;
226249
230253 // Now remove it.
231254 CurRec->removeValue(SMCTArgs[i]);
232255
233 // If a value is specified for this template arg, set it in the defs now.
234 for (MultiClass::RecordVector::iterator j = CurMultiClass->DefPrototypes.begin(),
256 // If a value is specified for this template arg, set it in the
257 // new defs now.
258 for (MultiClass::RecordVector::iterator j =
259 CurMultiClass->DefPrototypes.begin() + newDefStart,
235260 jend = CurMultiClass->DefPrototypes.end();
236261 j != jend;
237262 ++j) {
238263 Record *Def = *j;
239264
240 if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i], std::vector(),
265 if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],
266 std::vector(),
241267 SubMultiClass.TemplateArgs[i]))
242268 return true;
243269
248274 Def->removeValue(SMCTArgs[i]);
249275 }
250276 } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
251 return Error(SubMultiClass.RefLoc,"Value not specified for template argument #"
277 return Error(SubMultiClass.RefLoc,
278 "Value not specified for template argument #"
252279 + utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" +
253280 SMC->Rec.getName() + "'!");
254281 }
14891516 if (ParseTemplateArgList(0))
14901517 return true;
14911518
1519 bool inherits = false;
1520
14921521 // If there are submulticlasses, parse them.
14931522 if (Lex.getCode() == tgtok::colon) {
1523 inherits = true;
1524
14941525 Lex.Lex();
14951526
14961527 // Read all of the submulticlasses.
15091540 }
15101541 }
15111542
1512 if (Lex.getCode() != tgtok::l_brace)
1513 return TokError("expected '{' in multiclass definition");
1514
1515 if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
1516 return TokError("multiclass must contain at least one def");
1517
1518 while (Lex.getCode() != tgtok::r_brace)
1519 if (ParseMultiClassDef(CurMultiClass))
1520 return true;
1521
1522 Lex.Lex(); // eat the '}'.
1543 if (Lex.getCode() != tgtok::l_brace) {
1544 if (!inherits)
1545 return TokError("expected '{' in multiclass definition");
1546 else
1547 if (Lex.getCode() != tgtok::semi)
1548 return TokError("expected ';' in multiclass definition");
1549 else
1550 Lex.Lex(); // eat the ';'.
1551 }
1552 else {
1553 if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
1554 return TokError("multiclass must contain at least one def");
1555
1556 while (Lex.getCode() != tgtok::r_brace)
1557 if (ParseMultiClassDef(CurMultiClass))
1558 return true;
1559
1560 Lex.Lex(); // eat the '}'.
1561 }
15231562
15241563 CurMultiClass = 0;
15251564 return false;