diff options
author | Jason Merrill <jason@redhat.com> | 2009-03-23 17:03:01 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-03-23 17:03:01 -0400 |
commit | 6afcfe0a8080cf3816e841f0f1c2b96a73baed43 (patch) | |
tree | ea6d54ba1fb63d8cc661d04df277796e02ed2ac1 /gcc | |
parent | 6ab282f65064d9d22b04a89b0958fefbec50ebc3 (diff) | |
download | gcc-6afcfe0a8080cf3816e841f0f1c2b96a73baed43.zip gcc-6afcfe0a8080cf3816e841f0f1c2b96a73baed43.tar.gz gcc-6afcfe0a8080cf3816e841f0f1c2b96a73baed43.tar.bz2 |
pt.c (make_fnparm_pack): Split out from...
* 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.
From-SVN: r145013
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 94 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/auto12.C | 11 |
4 files changed, 83 insertions, 29 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 77c195a..e9e424d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2009-03-23 Jason Merrill <jason@redhat.com> + * 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 1c408237..5092c72 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 16a2c54..40205fa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2009-03-23 Jason Merrill <jason@redhat.com> + * 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 45ceedf..34dc8c9 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto12.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto12.C @@ -35,6 +35,15 @@ auto A<T>::f(U u) -> decltype (u + i) return u + i; } +template <class... Args> +int f (Args... args); + +template <class... Args> +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<int>().h(1); // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } } A<int>().j(1); + // { dg-final { scan-assembler "_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_" } } + g(42, 1.0); } |