Re: [PATCH] c++: Implement C++26 P2893R3 - Variadic friends [PR114459]
On 5/3/24 12:35, Jakub Jelinek wrote: Hi! The following patch imeplements the C++26 P2893R3 - Variadic friends paper. The paper allows for the friend type declarations to specify more than one friend type specifier and allows to specify ... at the end of each. The patch doesn't introduce tentative parsing of friend-type-declaration non-terminal, but rather just extends existing parsing where it is a friend declaration which ends with ; after the declaration specifiers to the cases where it ends with ...; or , or ..., In that case it pedwarns for cxx_dialect < cxx26, handles the ... and if there is , continues in a loop to parse the further friend type specifiers. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-05-03 Jakub Jelinek PR c++/114459 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Predefine __cpp_variadic_friend=202403L for C++26. gcc/cp/ * parser.cc (cp_parser_member_declaration): Implement C++26 P2893R3 - Variadic friends. Parse friend type declarations with ... or with more than one friend type specifier. * friend.cc (make_friend_class): Allow TYPE_PACK_EXPANSION. * pt.cc (instantiate_class_template): Handle PACK_EXPANSION_P in friend classes. gcc/testsuite/ * g++.dg/cpp26/feat-cxx26.C (__cpp_variadic_friend): Add test. * g++.dg/cpp26/variadic-friend1.C: New test. --- gcc/c-family/c-cppbuiltin.cc.jj 2024-05-02 09:31:17.746298275 +0200 +++ gcc/c-family/c-cppbuiltin.cc2024-05-03 14:50:08.008242950 +0200 @@ -1093,6 +1093,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_placeholder_variables=202306L"); cpp_define (pfile, "__cpp_structured_bindings=202403L"); cpp_define (pfile, "__cpp_deleted_function=202403L"); + cpp_define (pfile, "__cpp_variadic_friend=202403L"); } if (flag_concepts) { --- gcc/cp/parser.cc.jj 2024-05-03 09:43:47.781511477 +0200 +++ gcc/cp/parser.cc2024-05-03 13:26:38.208088017 +0200 @@ -28102,7 +28102,14 @@ cp_parser_member_declaration (cp_parser* goto out; /* If there is no declarator, then the decl-specifier-seq should specify a type. */ Let's mention C++26 variadic friends in this comment. OK with that change. - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) + || (cp_parser_friend_p (_specifiers) + && cxx_dialect >= cxx11 + && (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) + || (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS) + && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_SEMICOLON) + || cp_lexer_nth_token_is (parser->lexer, 2, + CPP_COMMA)) { /* If there was no decl-specifier-seq, and the next token is a `;', then we have something like: @@ -28137,44 +28144,81 @@ cp_parser_member_declaration (cp_parser* { /* If the `friend' keyword was present, the friend must be introduced with a class-key. */ - if (!declares_class_or_enum && cxx_dialect < cxx11) -pedwarn (decl_spec_token_start->location, OPT_Wpedantic, - "in C++03 a class-key must be used " - "when declaring a friend"); - /* In this case: + if (!declares_class_or_enum && cxx_dialect < cxx11) + pedwarn (decl_spec_token_start->location, OPT_Wpedantic, +"in C++03 a class-key must be used " +"when declaring a friend"); + if (!cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) + && cxx_dialect < cxx26) + pedwarn (cp_lexer_peek_token (parser->lexer)->location, +OPT_Wc__26_extensions, +"variadic friends or friend type declarations with " +"multiple types only available with " +"%<-std=c++2c%> or %<-std=gnu++2c%>"); + location_t friend_loc = decl_specifiers.locations[ds_friend]; + do + { + /* In this case: - template struct A { - friend struct A::B; - }; +template struct A { + friend struct A::B; +}; - A::B will be represented by a TYPENAME_TYPE, and - therefore not recognized by check_tag_decl. */ - if (!type) -{ - type = decl_specifiers.type; - if (type && TREE_CODE (type) == TYPE_DECL) -type = TREE_TYPE (type); -} - /* Warn if an attribute cannot appear here, as per - [dcl.attr.grammar]/5. But not when
[PATCH] c++: Implement C++26 P2893R3 - Variadic friends [PR114459]
Hi! The following patch imeplements the C++26 P2893R3 - Variadic friends paper. The paper allows for the friend type declarations to specify more than one friend type specifier and allows to specify ... at the end of each. The patch doesn't introduce tentative parsing of friend-type-declaration non-terminal, but rather just extends existing parsing where it is a friend declaration which ends with ; after the declaration specifiers to the cases where it ends with ...; or , or ..., In that case it pedwarns for cxx_dialect < cxx26, handles the ... and if there is , continues in a loop to parse the further friend type specifiers. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-05-03 Jakub Jelinek PR c++/114459 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Predefine __cpp_variadic_friend=202403L for C++26. gcc/cp/ * parser.cc (cp_parser_member_declaration): Implement C++26 P2893R3 - Variadic friends. Parse friend type declarations with ... or with more than one friend type specifier. * friend.cc (make_friend_class): Allow TYPE_PACK_EXPANSION. * pt.cc (instantiate_class_template): Handle PACK_EXPANSION_P in friend classes. gcc/testsuite/ * g++.dg/cpp26/feat-cxx26.C (__cpp_variadic_friend): Add test. * g++.dg/cpp26/variadic-friend1.C: New test. --- gcc/c-family/c-cppbuiltin.cc.jj 2024-05-02 09:31:17.746298275 +0200 +++ gcc/c-family/c-cppbuiltin.cc2024-05-03 14:50:08.008242950 +0200 @@ -1093,6 +1093,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_placeholder_variables=202306L"); cpp_define (pfile, "__cpp_structured_bindings=202403L"); cpp_define (pfile, "__cpp_deleted_function=202403L"); + cpp_define (pfile, "__cpp_variadic_friend=202403L"); } if (flag_concepts) { --- gcc/cp/parser.cc.jj 2024-05-03 09:43:47.781511477 +0200 +++ gcc/cp/parser.cc2024-05-03 13:26:38.208088017 +0200 @@ -28102,7 +28102,14 @@ cp_parser_member_declaration (cp_parser* goto out; /* If there is no declarator, then the decl-specifier-seq should specify a type. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) + || (cp_parser_friend_p (_specifiers) + && cxx_dialect >= cxx11 + && (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) + || (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS) + && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_SEMICOLON) + || cp_lexer_nth_token_is (parser->lexer, 2, + CPP_COMMA)) { /* If there was no decl-specifier-seq, and the next token is a `;', then we have something like: @@ -28137,44 +28144,81 @@ cp_parser_member_declaration (cp_parser* { /* If the `friend' keyword was present, the friend must be introduced with a class-key. */ - if (!declares_class_or_enum && cxx_dialect < cxx11) -pedwarn (decl_spec_token_start->location, OPT_Wpedantic, - "in C++03 a class-key must be used " - "when declaring a friend"); - /* In this case: + if (!declares_class_or_enum && cxx_dialect < cxx11) + pedwarn (decl_spec_token_start->location, OPT_Wpedantic, +"in C++03 a class-key must be used " +"when declaring a friend"); + if (!cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) + && cxx_dialect < cxx26) + pedwarn (cp_lexer_peek_token (parser->lexer)->location, +OPT_Wc__26_extensions, +"variadic friends or friend type declarations with " +"multiple types only available with " +"%<-std=c++2c%> or %<-std=gnu++2c%>"); + location_t friend_loc = decl_specifiers.locations[ds_friend]; + do + { + /* In this case: - template struct A { - friend struct A::B; - }; +template struct A { + friend struct A::B; +}; - A::B will be represented by a TYPENAME_TYPE, and - therefore not recognized by check_tag_decl. */ - if (!type) -{ - type = decl_specifiers.type; - if (type && TREE_CODE (type) == TYPE_DECL) -type = TREE_TYPE (type); -} - /* Warn if an attribute cannot appear here, as per - [dcl.attr.grammar]/5. But not when declares_class_or_enum: - we ignore attributes in elaborated-type-specifiers. */ -