@@ -229,38 +229,33 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
229
229
// / args as SubClass's template arguments.
230
230
bool TGParser::AddSubClass (Record *CurRec, SubClassReference &SubClass) {
231
231
Record *SC = SubClass.Rec ;
232
- // Add all of the values in the subclass into the current class.
233
- for (const RecordVal &Val : SC->getValues ())
234
- if (AddValue (CurRec, SubClass.RefRange .Start , Val))
235
- return true ;
236
-
237
- ArrayRef<Init *> TArgs = SC->getTemplateArgs ();
238
-
239
- // Ensure that an appropriate number of template arguments are specified.
240
- if (TArgs.size () < SubClass.TemplateArgs .size ())
241
- return Error (SubClass.RefRange .Start ,
242
- " More template args specified than expected" );
243
-
244
- // Loop over all of the template arguments, setting them to the specified
245
- // value or leaving them as the default if necessary.
246
232
MapResolver R (CurRec);
247
233
248
- for (unsigned i = 0 , e = TArgs.size (); i != e; ++i) {
249
- if (i < SubClass.TemplateArgs .size ()) {
250
- // If a value is specified for this template arg, set it now.
251
- if (SetValue (CurRec, SubClass.RefRange .Start , TArgs[i],
252
- None, SubClass.TemplateArgs [i]))
234
+ // Loop over all the subclass record's fields. Add template arguments
235
+ // to the resolver map. Add regular fields to the new record.
236
+ for (const RecordVal &Field : SC->getValues ()) {
237
+ if (Field.isTemplateArg ()) {
238
+ R.set (Field.getNameInit (), Field.getValue ());
239
+ } else {
240
+ if (AddValue (CurRec, SubClass.RefRange .Start , Field))
253
241
return true ;
254
- } else if (!CurRec->getValue (TArgs[i])->getValue ()->isComplete ()) {
255
- return Error (SubClass.RefRange .Start ,
256
- " Value not specified for template argument #" +
257
- Twine (i) + " (" + TArgs[i]->getAsUnquotedString () +
258
- " ) of subclass '" + SC->getNameInitAsString () + " '!" );
259
242
}
243
+ }
260
244
261
- R.set (TArgs[i], CurRec->getValue (TArgs[i])->getValue ());
262
-
263
- CurRec->removeValue (TArgs[i]);
245
+ ArrayRef<Init *> TArgs = SC->getTemplateArgs ();
246
+ assert (SubClass.TemplateArgs .size () <= TArgs.size () &&
247
+ " Too many template arguments allowed" );
248
+
249
+ // Loop over the template argument names. If a value was specified,
250
+ // reset the map value. If not and there was no default, complain.
251
+ for (unsigned I = 0 , E = TArgs.size (); I != E; ++I) {
252
+ if (I < SubClass.TemplateArgs .size ())
253
+ R.set (TArgs[I], SubClass.TemplateArgs [I]);
254
+ else if (!R.isComplete (TArgs[I]))
255
+ return Error (SubClass.RefRange .Start ,
256
+ " Value not specified for template argument #" +
257
+ Twine (I) + " (" + TArgs[I]->getAsUnquotedString () +
258
+ " ) of parent class '" + SC->getNameInitAsString () + " '" );
264
259
}
265
260
266
261
Init *Name;
@@ -2579,8 +2574,8 @@ void TGParser::ParseValueList(SmallVectorImpl<Init*> &Result, Record *CurRec,
2579
2574
}
2580
2575
2581
2576
// / ParseDeclaration - Read a declaration, returning the name of field ID, or an
2582
- // / empty string on error. This can happen in a number of different context's ,
2583
- // / including within a def or in the template args for a def (which which case
2577
+ // / empty string on error. This can happen in a number of different contexts ,
2578
+ // / including within a def or in the template args for a class (in which case
2584
2579
// / CurRec will be non-null) and within the template args for a multiclass (in
2585
2580
// / which case CurRec will be null, but CurMultiClass will be set). This can
2586
2581
// / also happen within a def that is within a multiclass, which will set both
@@ -2611,23 +2606,30 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
2611
2606
Init *DeclName = StringInit::get (Str);
2612
2607
Lex.Lex ();
2613
2608
2614
- if (ParsingTemplateArgs) {
2615
- if (CurRec)
2616
- DeclName = QualifyName (*CurRec, CurMultiClass, DeclName, " :" );
2617
- else
2618
- assert (CurMultiClass);
2619
- if (CurMultiClass)
2620
- DeclName = QualifyName (CurMultiClass->Rec , CurMultiClass, DeclName,
2621
- " ::" );
2622
- }
2623
-
2624
- // Add the field to the record.
2625
- if (AddValue (CurRec, IdLoc, RecordVal (DeclName, IdLoc, Type,
2626
- HasField ? RecordVal::FK_NonconcreteOK
2627
- : RecordVal::FK_Normal)))
2609
+ bool BadField;
2610
+ if (!ParsingTemplateArgs) { // def, possibly in a multiclass
2611
+ BadField = AddValue (CurRec, IdLoc,
2612
+ RecordVal (DeclName, IdLoc, Type,
2613
+ HasField ? RecordVal::FK_NonconcreteOK
2614
+ : RecordVal::FK_Normal));
2615
+
2616
+ } else if (CurRec) { // class template argument
2617
+ DeclName = QualifyName (*CurRec, CurMultiClass, DeclName, " :" );
2618
+ BadField = AddValue (CurRec, IdLoc,
2619
+ RecordVal (DeclName, IdLoc, Type,
2620
+ RecordVal::FK_TemplateArg));
2621
+
2622
+ } else { // multiclass template argument
2623
+ assert (CurMultiClass && " invalid context for template argument" );
2624
+ DeclName = QualifyName (CurMultiClass->Rec , CurMultiClass, DeclName, " ::" );
2625
+ BadField = AddValue (CurRec, IdLoc,
2626
+ RecordVal (DeclName, IdLoc, Type,
2627
+ RecordVal::FK_TemplateArg));
2628
+ }
2629
+ if (BadField)
2628
2630
return nullptr ;
2629
2631
2630
- // If a value is present, parse it.
2632
+ // If a value is present, parse it and set new field's value .
2631
2633
if (consume (tgtok::equal)) {
2632
2634
SMLoc ValLoc = Lex.getLoc ();
2633
2635
Init *Val = ParseValue (CurRec, Type);
@@ -2728,7 +2730,7 @@ VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
2728
2730
2729
2731
// / ParseTemplateArgList - Read a template argument list, which is a non-empty
2730
2732
// / sequence of template-declarations in <>'s. If CurRec is non-null, these are
2731
- // / template args for a def , which may or may not be in a multiclass. If null,
2733
+ // / template args for a class , which may or may not be in a multiclass. If null,
2732
2734
// / these are the template args for a multiclass.
2733
2735
// /
2734
2736
// / TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
0 commit comments