This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] [C++ RFC] Support named type capture for generic lambdas and generic functions as proposed by N3878


It's not clear that this feature will be part of concepts. It will not
be included in the initial working paper, so the proposal will need to
be re-evaluated.

Andrew


On Tue, Mar 25, 2014 at 3:03 AM, Adam Butcher <adam@jessamine.co.uk> wrote:
>         * parser.c (cp_parser_simple_type_specifier): Lookahead for a braced
>         identifier after a generic type ('auto') parameter and, if present, use
>         that as the type identifier name.  Otherwise generate one with
>         make_generic_type_name.  Pass the resulting identifier as the new second
>         parameter ...
>         (synthesize_implicit_template_parm): ... here.  Synthesize the template
>         type parm with the provided name rather than generating one.
>
>         * g++.dg/cpp1y/generic-fn-typeid.C: New testcase.
> ---
>  gcc/cp/parser.c                                | 55 +++++++++++++++++++++-----
>  gcc/testsuite/g++.dg/cpp1y/generic-fn-typeid.C | 42 ++++++++++++++++++++
>  2 files changed, 88 insertions(+), 9 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp1y/generic-fn-typeid.C
>
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 49fb731..4d6f8fe 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -2128,8 +2128,10 @@ static tree cp_parser_late_parsing_omp_declare_simd
>  static tree cp_parser_late_parsing_cilk_simd_fn_info
>    (cp_parser *, tree);
>
> +static tree make_generic_type_name
> +  ();
>  static tree synthesize_implicit_template_parm
> -  (cp_parser *);
> +  (cp_parser *, tree);
>  static tree finish_fully_implicit_template
>    (cp_parser *, tree);
>
> @@ -14530,23 +14532,58 @@ cp_parser_simple_type_specifier (cp_parser* parser,
>        maybe_warn_cpp0x (CPP0X_AUTO);
>        if (parser->auto_is_implicit_function_template_parm_p)
>         {
> -         type = synthesize_implicit_template_parm (parser);
> +         /* Synthesize an implicit template parameter named as specified by
> +            the IDENTIFIER_NODE of a braced identifier (as proposed by section
> +            2.2 of N3878).  If no braced identifier is present then a name is
> +            generated a via make_generic_type_name.  */
> +
> +         if (cp_lexer_peek_nth_token
> +             (parser->lexer, 2)->type == CPP_OPEN_BRACE)
> +           {
> +             /* The 'auto' has only been peeked and is expected to be consumed
> +                later; parse the braced identifier leaving the closing brace as
> +                the next token.  */
> +
> +             cp_lexer_consume_token (parser->lexer); /* RID_AUTO */
> +             cp_lexer_consume_token (parser->lexer); /* CPP_OPEN_BRACE */
> +
> +             tree synth_id = cp_parser_identifier (parser);
> +             if (synth_id != error_mark_node)
> +               type = synthesize_implicit_template_parm (parser, synth_id);
> +
> +             if (cp_parser_require
> +                 (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE) == 0
> +                 || synth_id == error_mark_node)
> +               {
> +                 error_at (input_location,
> +                    "expected braced identifier for generic type capture");
> +                 return error_mark_node;
> +               }
> +
> +             /* Roll-back one token to allow for consume below.  */
> +             cp_lexer_set_token_position (parser->lexer,
> +                                          cp_lexer_previous_token_position
> +                                          (parser->lexer));
> +           }
> +         else
> +           type = synthesize_implicit_template_parm
> +             (parser, make_generic_type_name ());
>
>           if (current_class_type && LAMBDA_TYPE_P (current_class_type))
>             {
>               if (cxx_dialect < cxx1y)
> -               pedwarn (location_of (type), 0,
> +               pedwarn (token->location, 0,
>                          "use of %<auto%> in lambda parameter declaration "
>                          "only available with "
>                          "-std=c++1y or -std=gnu++1y");
>             }
>           else if (cxx_dialect < cxx1y)
> -           pedwarn (location_of (type), 0,
> +           pedwarn (token->location, 0,
>                      "use of %<auto%> in parameter declaration "
>                      "only available with "
>                      "-std=c++1y or -std=gnu++1y");
>           else
> -           pedwarn (location_of (type), OPT_Wpedantic,
> +           pedwarn (token->location, OPT_Wpedantic,
>                      "ISO C++ forbids use of %<auto%> in parameter "
>                      "declaration");
>         }
> @@ -31957,11 +31994,12 @@ tree_type_is_auto_or_concept (const_tree t)
>  }
>
>  /* Add an implicit template type parameter to the CURRENT_TEMPLATE_PARMS
> -   (creating a new template parameter list if necessary).  Returns the newly
> -   created template type parm.  */
> +   (creating a new template parameter list if necessary).  The template type
> +   parameter is given the id SYNTH_ID.  Returns the newly created template type
> +   parm.  */
>
>  tree
> -synthesize_implicit_template_parm  (cp_parser *parser)
> +synthesize_implicit_template_parm  (cp_parser *parser, tree synth_id)
>  {
>    gcc_assert (current_binding_level->kind == sk_function_parms);
>
> @@ -32073,7 +32111,6 @@ synthesize_implicit_template_parm  (cp_parser *parser)
>    /* Synthesize a new template parameter and track the current template
>       parameter chain with implicit_template_parms.  */
>
> -  tree synth_id = make_generic_type_name ();
>    tree synth_tmpl_parm = finish_template_type_parm (class_type_node,
>                                                     synth_id);
>    tree new_parm
> diff --git a/gcc/testsuite/g++.dg/cpp1y/generic-fn-typeid.C b/gcc/testsuite/g++.dg/cpp1y/generic-fn-typeid.C
> new file mode 100644
> index 0000000..ab208a4
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1y/generic-fn-typeid.C
> @@ -0,0 +1,42 @@
> +// Check braced type capture for generic parameter types (from N3878)
> +// { dg-do compile { target c++1y } }
> +// { dg-options "" }
> +
> +auto f(auto {MyType} a, MyType b)
> +{
> +}
> +auto f2(auto {A} a, auto {B} b)
> +{
> +}
> +auto g(auto {g} x)  // { dg-error "declaration|shadows" }
> +{
> +}
> +auto h(auto {x} x)  // { dg-error "declaration|shadows" }
> +{
> +}
> +auto i(auto {})         // { dg-error "braced identifier|auto" }
> +{                // { dg-error "expected" }
> +}
> +auto j(auto {int})  // { dg-error "braced identifier|auto" }
> +{                   // { dg-error "expected" }
> +}
> +auto k(auto {;})  // { dg-error "braced identifier|auto" }
> +{                 // { dg-error "expected" }
> +}
> +
> +int main()
> +{
> +  auto l = [] (auto {X} x1, X x2) {};
> +
> +  l("a", "b");
> +  f("a", "b");
> +  f2("a", "b");
> +
> +  l(1, 2);
> +  f(1, 2);
> +  f2(1, 2);
> +
> +  l(1, 2.d);  // { dg-error "no match" }
> +  f(1, 2.d);  // { dg-error "no match" }
> +  f2(1, 2.d);
> +}
> --
> 1.9.0
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]