@@ -3240,13 +3240,19 @@ bool TGParser::ParseTemplateArgValueList(
32403240// /
32413241// / Declaration ::= FIELD? Type ID ('=' Value)?
32423242// /
3243- Init *TGParser::ParseDeclaration (Record *CurRec,
3244- bool ParsingTemplateArgs ) {
3243+ Init *TGParser::ParseDeclaration (Record *CurRec, bool ParsingTemplateArgs,
3244+ bool AllowAuto = false ) {
32453245 // Read the field prefix if present.
32463246 bool HasField = consume (tgtok::Field);
32473247
3248- RecTy *Type = ParseType ();
3249- if (!Type) return nullptr ;
3248+ RecTy *Type;
3249+ if (AllowAuto && consume (tgtok::Auto)) {
3250+ Type = nullptr ;
3251+ } else {
3252+ Type = ParseType ();
3253+ if (!Type)
3254+ return nullptr ;
3255+ }
32503256
32513257 if (Lex.getCode () != tgtok::Id) {
32523258 TokError (" Expected identifier in declaration" );
@@ -3268,6 +3274,30 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
32683274 Init *DeclName = StringInit::get (Records, Str);
32693275 Lex.Lex ();
32703276
3277+ bool HasValue = consume (tgtok::equal);
3278+
3279+ // When 'auto' is used, parse the value and infer the type based on the
3280+ // value's type.
3281+ SMLoc ValLoc;
3282+ Init *Val = nullptr ;
3283+ if (!Type) {
3284+ if (!HasValue) {
3285+ // auto used without a value.
3286+ TokError (" auto requires assigning a value" );
3287+ return nullptr ;
3288+ }
3289+ ValLoc = Lex.getLoc ();
3290+ Val = ParseValue (CurRec, Type);
3291+
3292+ // Infer type from the value.
3293+ if (TypedInit *TI = dyn_cast_or_null<TypedInit>(Val)) {
3294+ Type = TI->getType ();
3295+ } else {
3296+ Error (ValLoc, " unable to infer type" );
3297+ return nullptr ;
3298+ }
3299+ }
3300+
32713301 bool BadField;
32723302 if (!ParsingTemplateArgs) { // def, possibly in a multiclass
32733303 BadField = AddValue (CurRec, IdLoc,
@@ -3289,10 +3319,14 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
32893319 if (BadField)
32903320 return nullptr ;
32913321
3292- // If a value is present, parse it and set new field's value.
3293- if (consume (tgtok::equal)) {
3294- SMLoc ValLoc = Lex.getLoc ();
3295- Init *Val = ParseValue (CurRec, Type);
3322+ // For the non-auto case, if a value is present, parse it.
3323+ if (!Val && HasValue) {
3324+ ValLoc = Lex.getLoc ();
3325+ Val = ParseValue (CurRec, Type);
3326+ }
3327+
3328+ // Set the new field's value.
3329+ if (HasValue) {
32963330 if (!Val ||
32973331 SetValue (CurRec, ValLoc, DeclName, {}, Val,
32983332 /* AllowSelfAssignment=*/ false , /* OverrideDefLoc=*/ false )) {
@@ -3401,7 +3435,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
34013435 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec ;
34023436
34033437 // Read the first declaration.
3404- Init *TemplArg = ParseDeclaration (CurRec, true /* templateargs */ );
3438+ Init *TemplArg = ParseDeclaration (CurRec, /* ParsingTemplateArgs= */ true );
34053439 if (!TemplArg)
34063440 return true ;
34073441
@@ -3410,7 +3444,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
34103444 while (consume (tgtok::comma)) {
34113445 // Read the following declarations.
34123446 SMLoc Loc = Lex.getLoc ();
3413- TemplArg = ParseDeclaration (CurRec, true /* templateargs */ );
3447+ TemplArg = ParseDeclaration (CurRec, /* ParsingTemplateArgs= */ true );
34143448 if (!TemplArg)
34153449 return true ;
34163450
@@ -3445,7 +3479,9 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
34453479 return ParseDump (nullptr , CurRec);
34463480
34473481 if (Lex.getCode () != tgtok::Let) {
3448- if (!ParseDeclaration (CurRec, false ))
3482+ // Allow 'auto' when parsing declarations in the body of a def or class.
3483+ if (!ParseDeclaration (CurRec, /* ParsingTemplateArgs=*/ false ,
3484+ /* AllowAuto=*/ true ))
34493485 return true ;
34503486
34513487 if (!consume (tgtok::semi))
0 commit comments