mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-26 21:51:12 +08:00
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:
parent
6ab282f650
commit
6afcfe0a80
@ -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.
|
||||
|
94
gcc/cp/pt.c
94
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);
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user