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 >