llvm.org GIT mirror llvm / 0a3368c
[TableGen] Correctly generate implicit anonymous prototype defs in multiclasses Even within a multiclass, we had been generating concrete implicit anonymous defs when parsing values (generally in value lists). This behavior was incorrect, and led to errors when multiclass parameters were used in the parameter list of the implicit anonymous def. If we had some multiclass: multiclass mc<string n> { ... : SomeClass<SomeOtherClass<n> > The capture of the multiclass parameter 'n' would not work correctly, and depending on how the implicit SomeOtherClass was used, either TableGen would ignore something it shouldn't, or would crash. To fix this problem, when inside a multiclass, we generate prototype anonymous defs for implicit anonymous defs (just as we do for explicit anonymous defs). Within the multiclass, the current record prototype is populated with a node that is essentially: !cast<SomeOtherClass>(!strconcat(NAME, anon_value_name)). This is then resolved to the correct concrete anonymous def, in the usual way, when NAME is resolved during multiclass instantiation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198348 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 5 years ago
2 changed file(s) with 52 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
12241224 // Add info about the subclass to NewRec.
12251225 if (AddSubClass(NewRec, SCRef))
12261226 return 0;
1227 NewRec->resolveReferences();
1228 Records.addDef(NewRec);
1227 if (!CurMultiClass) {
1228 NewRec->resolveReferences();
1229 Records.addDef(NewRec);
1230 } else {
1231 // Otherwise, we're inside a multiclass, add it to the multiclass.
1232 CurMultiClass->DefPrototypes.push_back(NewRec);
1233
1234 // Copy the template arguments for the multiclass into the def.
1235 const std::vector &TArgs =
1236 CurMultiClass->Rec.getTemplateArgs();
1237
1238 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1239 const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
1240 assert(RV && "Template arg doesn't exist?");
1241 NewRec->addValue(*RV);
1242 }
1243
1244 // We can't return the prototype def here, instead return:
1245 // !cast(!strconcat(NAME, AnonName)).
1246 const RecordVal *MCNameRV = CurMultiClass->Rec.getValue("NAME");
1247 assert(MCNameRV && "multiclass record must have a NAME");
1248
1249 return UnOpInit::get(UnOpInit::CAST,
1250 BinOpInit::get(BinOpInit::STRCONCAT,
1251 VarInit::get(MCNameRV->getName(),
1252 MCNameRV->getType()),
1253 NewRec->getNameInit(),
1254 StringRecTy::get()),
1255 Class->getDefInit()->getType());
1256 }
12291257
12301258 // The result of the expression is a reference to the new record.
12311259 return DefInit::get(NewRec);
19611989 return true;
19621990 }
19631991 Records.addDef(CurRec);
1992
1993 if (ParseObjectBody(CurRec))
1994 return true;
19641995 } else if (CurMultiClass) {
1996 // Parse the body before adding this prototype to the DefPrototypes vector.
1997 // That way implicit definitions will be added to the DefPrototypes vector
1998 // before this object, instantiated prior to defs derived from this object,
1999 // and this available for indirect name resolution when defs derived from
2000 // this object are instantiated.
2001 if (ParseObjectBody(CurRec))
2002 return true;
2003
19652004 // Otherwise, a def inside a multiclass, add it to the multiclass.
19662005 for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i)
19672006 if (CurMultiClass->DefPrototypes[i]->getNameInit()
19712010 return true;
19722011 }
19732012 CurMultiClass->DefPrototypes.push_back(CurRec);
1974 }
1975
1976 if (ParseObjectBody(CurRec))
2013 } else if (ParseObjectBody(CurRec))
19772014 return true;
19782015
19792016 if (CurMultiClass == 0) // Def's in multiclasses aren't really defs.
2828
2929 defm : MC<"foo">;
3030
31 multiclass MC2 {
32 def there : Outer >;
33 }
34
35 // Ensure that we've correctly captured the reference to name from the implicit
36 // anonymous C def in the template parameter list of Outer.
37 // CHECK-NOT: MC2::name
38
39 defm : MC2<"bar">;
40