From 8173d80aef500e3325938bbff881a569d8bb51ec Mon Sep 17 00:00:00 2001 From: jason Date: Mon, 23 Mar 2009 21:03:01 +0000 Subject: [PATCH] * gcc/cp/pt.c (make_fnparm_pack): Split out from... (instantiate_decl): ...here. (tsubst_pack_expansion): Handle being called in a late-specified return type. * libiberty/cp-demangle.c (d_expression): Handle pack expansion. (d_find_pack): Handle DEMANGLE_COMPONENT_FUNCTION_PARAM. (d_print_subexpr): Don't wrap function parms in (). (d_print_comp) [DEMANGLE_COMPONENT_PACK_EXPANSION]: Handle not finding a pack. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145013 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 5 ++ gcc/cp/pt.c | 94 ++++++++++++++++++++++++----------- gcc/testsuite/ChangeLog | 2 + gcc/testsuite/g++.dg/cpp0x/auto12.C | 11 ++++ libiberty/ChangeLog | 8 +++ libiberty/cp-demangle.c | 24 +++++++-- libiberty/testsuite/demangle-expected | 10 ++-- 7 files changed, 119 insertions(+), 35 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 77c195a56c8..e9e424d28fc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2009-03-23 Jason Merrill + * pt.c (make_fnparm_pack): Split out from... + (instantiate_decl): ...here. + (tsubst_pack_expansion): Handle being called in a late-specified + return type. + PR c++/39526 * name-lookup.c (pushdecl_maybe_friend): Don't warn about shadowing a parm with a parm. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1c408237c6f..5092c72b177 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -174,6 +174,7 @@ static tree tsubst (tree, tree, tsubst_flags_t, tree); static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree); +static tree tsubst_decl (tree, tree, tsubst_flags_t); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function @@ -7435,6 +7436,37 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) return r; } +/* Give a chain SPEC_PARM of PARM_DECLs, pack them into a + NONTYPE_ARGUMENT_PACK. */ + +static tree +make_fnparm_pack (tree spec_parm) +{ + /* Collect all of the extra "packed" parameters into an + argument pack. */ + tree parmvec; + tree parmtypevec; + tree argpack = make_node (NONTYPE_ARGUMENT_PACK); + tree argtypepack = make_node (TYPE_ARGUMENT_PACK); + int i, len = list_length (spec_parm); + + /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ + parmvec = make_tree_vec (len); + parmtypevec = make_tree_vec (len); + for (i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) + { + TREE_VEC_ELT (parmvec, i) = spec_parm; + TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); + } + + /* Build the argument packs. */ + SET_ARGUMENT_PACK_ARGS (argpack, parmvec); + SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); + TREE_TYPE (argpack) = argtypepack; + + return argpack; +} + /* Substitute ARGS into T, which is an pack expansion (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a TREE_VEC with the substituted arguments, a PACK_EXPANSION_* node @@ -7449,6 +7481,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree first_arg_pack; int i, len = -1; tree result; int incomplete = 0; + bool very_local_specializations = false; gcc_assert (PACK_EXPANSION_P (t)); pattern = PACK_EXPANSION_PATTERN (t); @@ -7465,7 +7498,18 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree orig_arg = NULL_TREE; if (TREE_CODE (parm_pack) == PARM_DECL) - arg_pack = retrieve_local_specialization (parm_pack); + { + arg_pack = retrieve_local_specialization (parm_pack); + if (arg_pack == NULL_TREE) + { + /* This can happen for a parameter name used later in a function + declaration (such as in a late-specified return type). Just + make a dummy decl, since it's only used for its type. */ + gcc_assert (skip_evaluation); + arg_pack = tsubst_decl (parm_pack, args, complain); + arg_pack = make_fnparm_pack (arg_pack); + } + } else { int level, idx, levels; @@ -7559,6 +7603,17 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) return error_mark_node; + if (!local_specializations) + { + /* We're in a late-specified return type, so we don't have a local + specializations table. Create one for doing this expansion. */ + very_local_specializations = true; + local_specializations = htab_create (37, + hash_local_specialization, + eq_local_specializations, + NULL); + } + /* For each argument in each argument pack, substitute into the pattern. */ result = make_tree_vec (len + incomplete); @@ -7620,7 +7675,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, break; } } - + /* Update ARGS to restore the substitution from parameter packs to their argument packs. */ for (pack = packs; pack; pack = TREE_CHAIN (pack)) @@ -7643,6 +7698,12 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } } + if (very_local_specializations) + { + htab_delete (local_specializations); + local_specializations = NULL; + } + return result; } @@ -15477,37 +15538,12 @@ instantiate_decl (tree d, int defer_ok, } if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm)) { - /* Collect all of the extra "packed" parameters into an - argument pack. */ - tree parmvec; - tree parmtypevec; - tree argpack = make_node (NONTYPE_ARGUMENT_PACK); - tree argtypepack = make_node (TYPE_ARGUMENT_PACK); - int i, len = 0; - tree t; - - /* Count how many parameters remain. */ - for (t = spec_parm; t; t = TREE_CHAIN (t)) - len++; - - /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ - parmvec = make_tree_vec (len); - parmtypevec = make_tree_vec (len); - for(i = 0; i < len; i++, spec_parm = TREE_CHAIN (spec_parm)) - { - TREE_VEC_ELT (parmvec, i) = spec_parm; - TREE_VEC_ELT (parmtypevec, i) = TREE_TYPE (spec_parm); - } - - /* Build the argument packs. */ - SET_ARGUMENT_PACK_ARGS (argpack, parmvec); - SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); - TREE_TYPE (argpack) = argtypepack; - /* Register the (value) argument pack as a specialization of TMPL_PARM, then move on. */ + tree argpack = make_fnparm_pack (spec_parm); register_local_specialization (argpack, tmpl_parm); tmpl_parm = TREE_CHAIN (tmpl_parm); + spec_parm = NULL_TREE; } gcc_assert (!spec_parm); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 16a2c5478df..40205fa7dae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2009-03-23 Jason Merrill + * g++.dg/cpp0x/auto12.C: Add variadic test. + PR c++/39526 * g++.dg/warn/Wshadow-4.C: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/auto12.C b/gcc/testsuite/g++.dg/cpp0x/auto12.C index 45ceedfdc88..34dc8c90b84 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto12.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto12.C @@ -35,6 +35,15 @@ auto A::f(U u) -> decltype (u + i) return u + i; } +template +int f (Args... args); + +template +auto g (Args... args) -> decltype (f ((args+1)...)) +{ + return (f ((args+1)...)); +} + int main() { // { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplfp_L_ZNS0_1iEEET_" } } @@ -49,4 +58,6 @@ int main() A().h(1); // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } } A().j(1); + // { dg-final { scan-assembler "_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_" } } + g(42, 1.0); } diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 00aa57a84e4..a15a86005ff 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,11 @@ +2009-03-23 Jason Merrill + + * cp-demangle.c (d_expression): Handle pack expansion. + (d_find_pack): Handle DEMANGLE_COMPONENT_FUNCTION_PARAM. + (d_print_subexpr): Don't wrap function parms in (). + (d_print_comp) [DEMANGLE_COMPONENT_PACK_EXPANSION]: Handle + not finding a pack. + 2009-03-17 Jason Merrill * cp-demangle.c (d_make_function_param): new fn. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index e6d3d5ea902..b02f9bbf97e 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -2586,6 +2586,12 @@ d_expression (struct d_info *di) d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name, d_template_args (di))); } + else if (peek == 's' && d_peek_next_char (di) == 'p') + { + d_advance (di, 2); + return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION, + d_expression (di), NULL); + } else if (peek == 'f' && d_peek_next_char (di) == 'p') { /* Function parameter used in a late-specified return type. */ @@ -3244,6 +3250,7 @@ d_find_pack (struct d_print_info *dpi, case DEMANGLE_COMPONENT_BUILTIN_TYPE: case DEMANGLE_COMPONENT_SUB_STD: case DEMANGLE_COMPONENT_CHARACTER: + case DEMANGLE_COMPONENT_FUNCTION_PARAM: return NULL; case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: @@ -3284,7 +3291,8 @@ d_print_subexpr (struct d_print_info *dpi, const struct demangle_component *dc) { int simple = 0; - if (dc->type == DEMANGLE_COMPONENT_NAME) + if (dc->type == DEMANGLE_COMPONENT_NAME + || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM) simple = 1; if (!simple) d_append_char (dpi, '('); @@ -4012,10 +4020,20 @@ d_print_comp (struct d_print_info *dpi, case DEMANGLE_COMPONENT_PACK_EXPANSION: { - struct demangle_component *a = d_find_pack (dpi, d_left (dc)); - int len = d_pack_length (a); + int len; int i; + struct demangle_component *a = d_find_pack (dpi, d_left (dc)); + if (a == NULL) + { + /* d_find_pack won't find anything if the only packs involved + in this expansion are function parameter packs; in that + case, just print the pattern and "...". */ + d_print_subexpr (dpi, d_left (dc)); + d_append_string (dpi, "..."); + return; + } + len = d_pack_length (a); dc = d_left (dc); for (i = 0; i < len; ++i) { diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index cded6b5d71a..0c451184fc4 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3885,7 +3885,7 @@ java resource java/util/iso4217.properties # decltype/param placeholder test --format=gnu-v3 _Z3addIidEDTplfp_fp0_ET_T0_ -decltype ((parm#1)+(parm#2)) add(int, double) +decltype (parm#1+parm#2) add(int, double) # decltype/fn call test --format=gnu-v3 _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_ @@ -3901,8 +3901,12 @@ void f(int*, float*, double*) # '.' test --format=gnu-v3 _Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_ -decltype (((parm#1).(g))()) h, double>(A, double) +decltype ((parm#1.(g))()) h, double>(A, double) # test for typed function in decltype --format=gnu-v3 _ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_ -decltype ((parm#1)+((x())())) A::j(int) +decltype (parm#1+((x())())) A::j(int) +# test for expansion of function parameter pack +--format=gnu-v3 +_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_ +decltype (f((parm#1+(1))...)) g(int, double) -- 2.11.0