@@ -229,33 +229,38 @@ 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.
232
246
MapResolver R (CurRec);
233
247
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))
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]))
241
253
return true ;
242
- }
243
- }
244
-
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]))
254
+ } else if (!CurRec->getValue (TArgs[i])->getValue ()->isComplete ()) {
255
255
return Error (SubClass.RefRange .Start ,
256
256
" Value not specified for template argument #" +
257
- Twine (I) + " (" + TArgs[I]->getAsUnquotedString () +
258
- " ) of parent class '" + SC->getNameInitAsString () + " '" );
257
+ Twine (i) + " (" + TArgs[i]->getAsUnquotedString () +
258
+ " ) of subclass '" + SC->getNameInitAsString () + " '!" );
259
+ }
260
+
261
+ R.set (TArgs[i], CurRec->getValue (TArgs[i])->getValue ());
262
+
263
+ CurRec->removeValue (TArgs[i]);
259
264
}
260
265
261
266
Init *Name;
@@ -2574,8 +2579,8 @@ void TGParser::ParseValueList(SmallVectorImpl<Init*> &Result, Record *CurRec,
2574
2579
}
2575
2580
2576
2581
// / ParseDeclaration - Read a declaration, returning the name of field ID, or an
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
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
2579
2584
// / CurRec will be non-null) and within the template args for a multiclass (in
2580
2585
// / which case CurRec will be null, but CurMultiClass will be set). This can
2581
2586
// / also happen within a def that is within a multiclass, which will set both
@@ -2606,30 +2611,23 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
2606
2611
Init *DeclName = StringInit::get (Str);
2607
2612
Lex.Lex ();
2608
2613
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)
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)))
2630
2628
return nullptr ;
2631
2629
2632
- // If a value is present, parse it and set new field's value .
2630
+ // If a value is present, parse it.
2633
2631
if (consume (tgtok::equal)) {
2634
2632
SMLoc ValLoc = Lex.getLoc ();
2635
2633
Init *Val = ParseValue (CurRec, Type);
@@ -2730,7 +2728,7 @@ VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
2730
2728
2731
2729
// / ParseTemplateArgList - Read a template argument list, which is a non-empty
2732
2730
// / sequence of template-declarations in <>'s. If CurRec is non-null, these are
2733
- // / template args for a class , which may or may not be in a multiclass. If null,
2731
+ // / template args for a def , which may or may not be in a multiclass. If null,
2734
2732
// / these are the template args for a multiclass.
2735
2733
// /
2736
2734
// / TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
0 commit comments