@@ -7038,18 +7038,23 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
70387038void Parser::ParseDecompositionDeclarator (Declarator &D) {
70397039 assert (Tok.is (tok::l_square));
70407040
7041+ TentativeParsingAction PA (*this );
7042+ BalancedDelimiterTracker T (*this , tok::l_square);
7043+ T.consumeOpen ();
7044+
7045+ if (isCXX11AttributeSpecifier ())
7046+ DiagnoseAndSkipCXX11Attributes ();
7047+
70417048 // If this doesn't look like a structured binding, maybe it's a misplaced
70427049 // array declarator.
7043- // FIXME: Consume the l_square first so we don't need extra lookahead for
7044- // this.
7045- if (!( NextToken (). is ( tok::identifier ) &&
7046- GetLookAheadToken ( 2 ). isOneOf (tok::comma, tok:: r_square) ) &&
7047- !( NextToken ().is (tok::r_square) &&
7048- GetLookAheadToken ( 2 ). isOneOf (tok::equal, tok::l_brace)))
7050+ if (!(Tok. is (tok::identifier) &&
7051+ NextToken (). isOneOf (tok::comma, tok::r_square, tok::kw_alignas,
7052+ tok::l_square) ) &&
7053+ !(Tok. is (tok::r_square) &&
7054+ NextToken ().isOneOf (tok::equal, tok::l_brace))) {
7055+ PA. Revert ();
70497056 return ParseMisplacedBracketDeclarator (D);
7050-
7051- BalancedDelimiterTracker T (*this , tok::l_square);
7052- T.consumeOpen ();
7057+ }
70537058
70547059 SmallVector<DecompositionDeclarator::Binding, 32 > Bindings;
70557060 while (Tok.isNot (tok::r_square)) {
@@ -7074,13 +7079,27 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) {
70747079 }
70757080 }
70767081
7082+ if (isCXX11AttributeSpecifier ())
7083+ DiagnoseAndSkipCXX11Attributes ();
7084+
70777085 if (Tok.isNot (tok::identifier)) {
70787086 Diag (Tok, diag::err_expected) << tok::identifier;
70797087 break ;
70807088 }
70817089
7082- Bindings.push_back ({Tok.getIdentifierInfo (), Tok.getLocation ()});
7090+ IdentifierInfo *II = Tok.getIdentifierInfo ();
7091+ SourceLocation Loc = Tok.getLocation ();
70837092 ConsumeToken ();
7093+
7094+ ParsedAttributes Attrs (AttrFactory);
7095+ if (isCXX11AttributeSpecifier ()) {
7096+ Diag (Tok, getLangOpts ().CPlusPlus26
7097+ ? diag::warn_cxx23_compat_decl_attrs_on_binding
7098+ : diag::ext_decl_attrs_on_binding);
7099+ MaybeParseCXX11Attributes (Attrs);
7100+ }
7101+
7102+ Bindings.push_back ({II, Loc, std::move (Attrs)});
70847103 }
70857104
70867105 if (Tok.isNot (tok::r_square))
@@ -7095,6 +7114,8 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) {
70957114 T.consumeClose ();
70967115 }
70977116
7117+ PA.Commit ();
7118+
70987119 return D.setDecompositionBindings (T.getOpenLocation (), Bindings,
70997120 T.getCloseLocation ());
71007121}
0 commit comments