diff options
author | cor3ntin <corentinjabot@gmail.com> | 2024-04-28 20:25:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-28 20:25:44 +0200 |
commit | 6dd90616c477d83c156eed62c880e951bb508cfd (patch) | |
tree | 97249d834b0bb458a7509d5bab7abac35c000108 /clang/lib/Parse/ParseDecl.cpp | |
parent | 216787cffc4a864e0effb165c1c32b92328a0a06 (diff) | |
download | llvm-6dd90616c477d83c156eed62c880e951bb508cfd.zip llvm-6dd90616c477d83c156eed62c880e951bb508cfd.tar.gz llvm-6dd90616c477d83c156eed62c880e951bb508cfd.tar.bz2 |
[Clang] Implement C++26 Attributes for Structured Bindings (P0609R3) (#89906)
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0609r3.pdf
We support this feature in all language mode.
maybe_unused applied to a binding makes the whole declaration unused.
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 05ad5ec..a7846e1 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -7038,18 +7038,23 @@ void Parser::ParseDirectDeclarator(Declarator &D) { void Parser::ParseDecompositionDeclarator(Declarator &D) { assert(Tok.is(tok::l_square)); + TentativeParsingAction PA(*this); + BalancedDelimiterTracker T(*this, tok::l_square); + T.consumeOpen(); + + if (isCXX11AttributeSpecifier()) + DiagnoseAndSkipCXX11Attributes(); + // If this doesn't look like a structured binding, maybe it's a misplaced // array declarator. - // FIXME: Consume the l_square first so we don't need extra lookahead for - // this. - if (!(NextToken().is(tok::identifier) && - GetLookAheadToken(2).isOneOf(tok::comma, tok::r_square)) && - !(NextToken().is(tok::r_square) && - GetLookAheadToken(2).isOneOf(tok::equal, tok::l_brace))) + if (!(Tok.is(tok::identifier) && + NextToken().isOneOf(tok::comma, tok::r_square, tok::kw_alignas, + tok::l_square)) && + !(Tok.is(tok::r_square) && + NextToken().isOneOf(tok::equal, tok::l_brace))) { + PA.Revert(); return ParseMisplacedBracketDeclarator(D); - - BalancedDelimiterTracker T(*this, tok::l_square); - T.consumeOpen(); + } SmallVector<DecompositionDeclarator::Binding, 32> Bindings; while (Tok.isNot(tok::r_square)) { @@ -7074,13 +7079,27 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { } } + if (isCXX11AttributeSpecifier()) + DiagnoseAndSkipCXX11Attributes(); + if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected) << tok::identifier; break; } - Bindings.push_back({Tok.getIdentifierInfo(), Tok.getLocation()}); + IdentifierInfo *II = Tok.getIdentifierInfo(); + SourceLocation Loc = Tok.getLocation(); ConsumeToken(); + + ParsedAttributes Attrs(AttrFactory); + if (isCXX11AttributeSpecifier()) { + Diag(Tok, getLangOpts().CPlusPlus26 + ? diag::warn_cxx23_compat_decl_attrs_on_binding + : diag::ext_decl_attrs_on_binding); + MaybeParseCXX11Attributes(Attrs); + } + + Bindings.push_back({II, Loc, std::move(Attrs)}); } if (Tok.isNot(tok::r_square)) @@ -7095,6 +7114,8 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { T.consumeClose(); } + PA.Commit(); + return D.setDecompositionBindings(T.getOpenLocation(), Bindings, T.getCloseLocation()); } |