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
This commit is contained in:
Jason Merrill 2009-03-23 17:03:01 -04:00 committed by Jason Merrill
parent 6ab282f650
commit 6afcfe0a80
7 changed files with 119 additions and 35 deletions

View File

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

View File

@ -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);

View File

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

View File

@ -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);
}

View File

@ -1,3 +1,11 @@
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>
* cp-demangle.c (d_make_function_param): new fn.

View File

@ -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)
{

View File

@ -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>(int, double)
decltype (parm#1+parm#2) add<int, double>(int, double)
# decltype/fn call test
--format=gnu-v3
_Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
@ -3901,8 +3901,12 @@ void f<int*, float*, double*>(int*, float*, double*)
# '.' test
--format=gnu-v3
_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
--format=gnu-v3
_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)