@@ -3262,13 +3262,19 @@ bool TGParser::ParseTemplateArgValueList(
32623262// /
32633263// / Declaration ::= FIELD? Type ID ('=' Value)?
32643264// /
3265- Init *TGParser::ParseDeclaration (Record *CurRec,
3266- bool ParsingTemplateArgs ) {
3265+ Init *TGParser::ParseDeclaration (Record *CurRec, bool ParsingTemplateArgs,
3266+ bool AllowAuto = false ) {
32673267 // Read the field prefix if present.
32683268 bool HasField = consume (tgtok::Field);
32693269
3270- RecTy *Type = ParseType ();
3271- if (!Type) return nullptr ;
3270+ RecTy *Type;
3271+ if (AllowAuto && consume (tgtok::Auto)) {
3272+ Type = nullptr ;
3273+ } else {
3274+ Type = ParseType ();
3275+ if (!Type)
3276+ return nullptr ;
3277+ }
32723278
32733279 if (Lex.getCode () != tgtok::Id) {
32743280 TokError (" Expected identifier in declaration" );
@@ -3290,6 +3296,32 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
32903296 Init *DeclName = StringInit::get (Records, Str);
32913297 Lex.Lex ();
32923298
3299+ bool HasValue = consume (tgtok::equal);
3300+
3301+ // When 'auto' is used, parse the value and infer the type based on the
3302+ // value's type.
3303+ SMLoc ValLoc;
3304+ Init *Val = nullptr ;
3305+ if (!Type) {
3306+ if (!HasValue) {
3307+ // auto used without a value.
3308+ TokError (" auto requires assigning a value" );
3309+ return nullptr ;
3310+ }
3311+ ValLoc = Lex.getLoc ();
3312+ // When no item type is supplied to ParseValue, it will either infer the
3313+ // type from the value, or fail to parse
3314+ Val = ParseValue (CurRec);
3315+
3316+ // Infer type from the value.
3317+ if (TypedInit *TI = dyn_cast_or_null<TypedInit>(Val)) {
3318+ Type = TI->getType ();
3319+ } else {
3320+ Error (ValLoc, " unable to infer type" );
3321+ return nullptr ;
3322+ }
3323+ }
3324+
32933325 bool BadField;
32943326 if (!ParsingTemplateArgs) { // def, possibly in a multiclass
32953327 BadField = AddValue (CurRec, IdLoc,
@@ -3311,10 +3343,14 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
33113343 if (BadField)
33123344 return nullptr ;
33133345
3314- // If a value is present, parse it and set new field's value.
3315- if (consume (tgtok::equal)) {
3316- SMLoc ValLoc = Lex.getLoc ();
3317- Init *Val = ParseValue (CurRec, Type);
3346+ // For the non-auto case, if a value is present, parse it.
3347+ if (!Val && HasValue) {
3348+ ValLoc = Lex.getLoc ();
3349+ Val = ParseValue (CurRec, Type);
3350+ }
3351+
3352+ // Set the new field's value.
3353+ if (HasValue) {
33183354 if (!Val ||
33193355 SetValue (CurRec, ValLoc, DeclName, {}, Val,
33203356 /* AllowSelfAssignment=*/ false , /* OverrideDefLoc=*/ false )) {
@@ -3423,7 +3459,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
34233459 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec ;
34243460
34253461 // Read the first declaration.
3426- Init *TemplArg = ParseDeclaration (CurRec, true /* templateargs */ );
3462+ Init *TemplArg = ParseDeclaration (CurRec, /* ParsingTemplateArgs= */ true );
34273463 if (!TemplArg)
34283464 return true ;
34293465
@@ -3432,7 +3468,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
34323468 while (consume (tgtok::comma)) {
34333469 // Read the following declarations.
34343470 SMLoc Loc = Lex.getLoc ();
3435- TemplArg = ParseDeclaration (CurRec, true /* templateargs */ );
3471+ TemplArg = ParseDeclaration (CurRec, /* ParsingTemplateArgs= */ true );
34363472 if (!TemplArg)
34373473 return true ;
34383474
@@ -3467,7 +3503,9 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
34673503 return ParseDump (nullptr , CurRec);
34683504
34693505 if (Lex.getCode () != tgtok::Let) {
3470- if (!ParseDeclaration (CurRec, false ))
3506+ // Allow 'auto' when parsing declarations in the body of a def or class.
3507+ if (!ParseDeclaration (CurRec, /* ParsingTemplateArgs=*/ false ,
3508+ /* AllowAuto=*/ true ))
34713509 return true ;
34723510
34733511 if (!consume (tgtok::semi))
0 commit comments