Commit 6afcfe0a by Jason Merrill Committed by Jason Merrill

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
parent 6ab282f6
2009-03-23 Jason Merrill <jason@redhat.com> 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 PR c++/39526
* name-lookup.c (pushdecl_maybe_friend): Don't warn about shadowing * name-lookup.c (pushdecl_maybe_friend): Don't warn about shadowing
a parm with a parm. a parm with a parm.
......
...@@ -174,6 +174,7 @@ static tree tsubst (tree, tree, tsubst_flags_t, tree); ...@@ -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_expr (tree, tree, tsubst_flags_t, tree, bool);
static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); static tree tsubst_copy (tree, tree, tsubst_flags_t, tree);
static tree tsubst_pack_expansion (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 /* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function 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) ...@@ -7435,6 +7436,37 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return r; 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 /* Substitute ARGS into T, which is an pack expansion
(i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a
TREE_VEC with the substituted arguments, a PACK_EXPANSION_* node 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, ...@@ -7449,6 +7481,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
tree first_arg_pack; int i, len = -1; tree first_arg_pack; int i, len = -1;
tree result; tree result;
int incomplete = 0; int incomplete = 0;
bool very_local_specializations = false;
gcc_assert (PACK_EXPANSION_P (t)); gcc_assert (PACK_EXPANSION_P (t));
pattern = PACK_EXPANSION_PATTERN (t); pattern = PACK_EXPANSION_PATTERN (t);
...@@ -7465,7 +7498,18 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -7465,7 +7498,18 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
tree orig_arg = NULL_TREE; tree orig_arg = NULL_TREE;
if (TREE_CODE (parm_pack) == PARM_DECL) 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 else
{ {
int level, idx, levels; int level, idx, levels;
...@@ -7559,6 +7603,17 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -7559,6 +7603,17 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
if (len < 0) if (len < 0)
return error_mark_node; 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 /* For each argument in each argument pack, substitute into the
pattern. */ pattern. */
result = make_tree_vec (len + incomplete); result = make_tree_vec (len + incomplete);
...@@ -7643,6 +7698,12 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -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; return result;
} }
...@@ -15477,37 +15538,12 @@ instantiate_decl (tree d, int defer_ok, ...@@ -15477,37 +15538,12 @@ instantiate_decl (tree d, int defer_ok,
} }
if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm)) 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 /* Register the (value) argument pack as a specialization of
TMPL_PARM, then move on. */ TMPL_PARM, then move on. */
tree argpack = make_fnparm_pack (spec_parm);
register_local_specialization (argpack, tmpl_parm); register_local_specialization (argpack, tmpl_parm);
tmpl_parm = TREE_CHAIN (tmpl_parm); tmpl_parm = TREE_CHAIN (tmpl_parm);
spec_parm = NULL_TREE;
} }
gcc_assert (!spec_parm); gcc_assert (!spec_parm);
......
2009-03-23 Jason Merrill <jason@redhat.com> 2009-03-23 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/auto12.C: Add variadic test.
PR c++/39526 PR c++/39526
* g++.dg/warn/Wshadow-4.C: New test. * g++.dg/warn/Wshadow-4.C: New test.
......
...@@ -35,6 +35,15 @@ auto A<T>::f(U u) -> decltype (u + i) ...@@ -35,6 +35,15 @@ auto A<T>::f(U u) -> decltype (u + i)
return 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() int main()
{ {
// { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplfp_L_ZNS0_1iEEET_" } } // { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplfp_L_ZNS0_1iEEET_" } }
...@@ -49,4 +58,6 @@ int main() ...@@ -49,4 +58,6 @@ int main()
A<int>().h(1); A<int>().h(1);
// { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } } // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } }
A<int>().j(1); A<int>().j(1);
// { dg-final { scan-assembler "_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_" } }
g(42, 1.0);
} }
2009-03-23 Jason Merrill <jason@redhat.com>
* 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 <jason@redhat.com> 2009-03-17 Jason Merrill <jason@redhat.com>
* cp-demangle.c (d_make_function_param): new fn. * cp-demangle.c (d_make_function_param): new fn.
......
...@@ -2586,6 +2586,12 @@ d_expression (struct d_info *di) ...@@ -2586,6 +2586,12 @@ d_expression (struct d_info *di)
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name, d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
d_template_args (di))); 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') else if (peek == 'f' && d_peek_next_char (di) == 'p')
{ {
/* Function parameter used in a late-specified return type. */ /* Function parameter used in a late-specified return type. */
...@@ -3244,6 +3250,7 @@ d_find_pack (struct d_print_info *dpi, ...@@ -3244,6 +3250,7 @@ d_find_pack (struct d_print_info *dpi,
case DEMANGLE_COMPONENT_BUILTIN_TYPE: case DEMANGLE_COMPONENT_BUILTIN_TYPE:
case DEMANGLE_COMPONENT_SUB_STD: case DEMANGLE_COMPONENT_SUB_STD:
case DEMANGLE_COMPONENT_CHARACTER: case DEMANGLE_COMPONENT_CHARACTER:
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
return NULL; return NULL;
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR: case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
...@@ -3284,7 +3291,8 @@ d_print_subexpr (struct d_print_info *dpi, ...@@ -3284,7 +3291,8 @@ d_print_subexpr (struct d_print_info *dpi,
const struct demangle_component *dc) const struct demangle_component *dc)
{ {
int simple = 0; int simple = 0;
if (dc->type == DEMANGLE_COMPONENT_NAME) if (dc->type == DEMANGLE_COMPONENT_NAME
|| dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
simple = 1; simple = 1;
if (!simple) if (!simple)
d_append_char (dpi, '('); d_append_char (dpi, '(');
...@@ -4012,10 +4020,20 @@ d_print_comp (struct d_print_info *dpi, ...@@ -4012,10 +4020,20 @@ d_print_comp (struct d_print_info *dpi,
case DEMANGLE_COMPONENT_PACK_EXPANSION: case DEMANGLE_COMPONENT_PACK_EXPANSION:
{ {
struct demangle_component *a = d_find_pack (dpi, d_left (dc)); int len;
int len = d_pack_length (a);
int i; 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); dc = d_left (dc);
for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
{ {
......
...@@ -3885,7 +3885,7 @@ java resource java/util/iso4217.properties ...@@ -3885,7 +3885,7 @@ java resource java/util/iso4217.properties
# decltype/param placeholder test # decltype/param placeholder test
--format=gnu-v3 --format=gnu-v3
_Z3addIidEDTplfp_fp0_ET_T0_ _Z3addIidEDTplfp_fp0_ET_T0_
decltype ((parm#1)+(parm#2)) add<int, double>(int, double) decltype (parm#1+parm#2) add<int, double>(int, double)
# decltype/fn call test # decltype/fn call test
--format=gnu-v3 --format=gnu-v3
_Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_ _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
...@@ -3901,8 +3901,12 @@ void f<int*, float*, double*>(int*, float*, double*) ...@@ -3901,8 +3901,12 @@ void f<int*, float*, double*>(int*, float*, double*)
# '.' test # '.' test
--format=gnu-v3 --format=gnu-v3
_Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_ _Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_
decltype (((parm#1).(g<double>))()) h<A<int>, double>(A<int>, double) decltype ((parm#1.(g<double>))()) h<A<int>, double>(A<int>, double)
# test for typed function in decltype # test for typed function in decltype
--format=gnu-v3 --format=gnu-v3
_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_ _ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_
decltype ((parm#1)+((x())())) A<int>::j<int>(int) decltype (parm#1+((x())())) A<int>::j<int>(int)
# test for expansion of function parameter pack
--format=gnu-v3
_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_
decltype (f((parm#1+(1))...)) g<int, double>(int, double)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment