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 <a...@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
>

Reply via email to