Commit 063cc99c by Douglas Gregor Committed by Doug Gregor

pt.c (tsubst_copy): Cope with tsubst_pack_expansion returning a pack expansion...

2008-03-27  Douglas Gregor  <doug.gregor@gmail.com>

	* pt.c (tsubst_copy) <case SIZEOF_EXPR>: Cope with
	tsubst_pack_expansion returning a pack expansion, or a TREE_VEC
	ending in a pack expansion, both of which can occur when
	substituting into a nested template.
	(tsubst_copy_and_build) <case SIZEOF_EXPR>: When we're
	instantiating the sizeof...(X) form, make tsubst_copy do the work.
	* parser.c (cp_parser_template_parameter): Deal with unnamed
	non-type template parameter packs identified by pack expansions in
	the parameter type.

2008-03-27  Douglas Gregor  <doug.gregor@gmail.com>

       * g++.dg/cpp0x/variadic91.C: New.

From-SVN: r133642
parent c91c9c2e
2008-03-27 Douglas Gregor <doug.gregor@gmail.com>
* pt.c (tsubst_copy) <case SIZEOF_EXPR>: Cope with
tsubst_pack_expansion returning a pack expansion, or a TREE_VEC
ending in a pack expansion, both of which can occur when
substituting into a nested template.
(tsubst_copy_and_build) <case SIZEOF_EXPR>: When we're
instantiating the sizeof...(X) form, make tsubst_copy do the work.
* parser.c (cp_parser_template_parameter): Deal with unnamed
non-type template parameter packs identified by pack expansions in
the parameter type.
2008-03-26 Jakub Jelinek <jakub@redhat.com> 2008-03-26 Jakub Jelinek <jakub@redhat.com>
PR c++/35546 PR c++/35546
......
...@@ -9435,29 +9435,41 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type, ...@@ -9435,29 +9435,41 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
maybe_warn_variadic_templates (); maybe_warn_variadic_templates ();
*is_parameter_pack = true; *is_parameter_pack = true;
}
/* We might end up with a pack expansion as the type of the non-type
template parameter, in which case this is a non-type template
parameter pack. */
else if (parameter_declarator
&& parameter_declarator->decl_specifiers.type
&& PACK_EXPANSION_P (parameter_declarator->decl_specifiers.type))
{
*is_parameter_pack = true;
parameter_declarator->decl_specifiers.type =
PACK_EXPANSION_PATTERN (parameter_declarator->decl_specifiers.type);
}
if (*is_parameter_pack && cp_lexer_next_token_is (parser->lexer, CPP_EQ))
{
/* Parameter packs cannot have default arguments. However, a /* Parameter packs cannot have default arguments. However, a
user may try to do so, so we'll parse them and give an user may try to do so, so we'll parse them and give an
appropriate diagnostic here. */ appropriate diagnostic here. */
if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
{
/* Consume the `='. */
cp_lexer_consume_token (parser->lexer);
/* Find the name of the parameter pack. */ /* Consume the `='. */
id_declarator = parameter_declarator->declarator; cp_lexer_consume_token (parser->lexer);
while (id_declarator && id_declarator->kind != cdk_id)
id_declarator = id_declarator->declarator; /* Find the name of the parameter pack. */
id_declarator = parameter_declarator->declarator;
if (id_declarator && id_declarator->kind == cdk_id) while (id_declarator && id_declarator->kind != cdk_id)
error ("template parameter pack %qD cannot have a default argument", id_declarator = id_declarator->declarator;
id_declarator->u.id.unqualified_name);
else if (id_declarator && id_declarator->kind == cdk_id)
error ("template parameter pack cannot have a default argument"); error ("template parameter pack %qD cannot have a default argument",
id_declarator->u.id.unqualified_name);
/* Parse the default argument, but throw away the result. */ else
cp_parser_default_argument (parser, /*template_parm_p=*/true); error ("template parameter pack cannot have a default argument");
}
/* Parse the default argument, but throw away the result. */
cp_parser_default_argument (parser, /*template_parm_p=*/true);
} }
parm = grokdeclarator (parameter_declarator->declarator, parm = grokdeclarator (parameter_declarator->declarator,
......
...@@ -9916,9 +9916,30 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -9916,9 +9916,30 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/* We only want to compute the number of arguments. */ /* We only want to compute the number of arguments. */
tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args, tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
complain, in_decl); complain, in_decl);
int len;
if (TREE_CODE (expanded) == TREE_VEC)
len = TREE_VEC_LENGTH (expanded);
if (expanded == error_mark_node) if (expanded == error_mark_node)
return error_mark_node; return error_mark_node;
return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded)); else if (PACK_EXPANSION_P (expanded)
|| (TREE_CODE (expanded) == TREE_VEC
&& len > 0
&& PACK_EXPANSION_P (TREE_VEC_ELT (expanded, len-1))))
{
if (TREE_CODE (expanded) == TREE_VEC)
expanded = TREE_VEC_ELT (expanded, len - 1);
if (TYPE_P (expanded))
return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
complain & tf_error);
else
return cxx_sizeof_or_alignof_expr (expanded, SIZEOF_EXPR,
complain & tf_error);
}
else
return build_int_cst (size_type_node, len);
} }
/* Fall through */ /* Fall through */
...@@ -10918,14 +10939,7 @@ tsubst_copy_and_build (tree t, ...@@ -10918,14 +10939,7 @@ tsubst_copy_and_build (tree t,
case SIZEOF_EXPR: case SIZEOF_EXPR:
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
{ return tsubst_copy (t, args, complain, in_decl);
/* We only want to compute the number of arguments. */
tree expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
complain, in_decl);
if (expanded == error_mark_node)
return error_mark_node;
return build_int_cst (size_type_node, TREE_VEC_LENGTH (expanded));
}
/* Fall through */ /* Fall through */
case ALIGNOF_EXPR: case ALIGNOF_EXPR:
...@@ -12920,7 +12934,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -12920,7 +12934,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
tree parmvec = TYPE_TI_ARGS (parm); tree parmvec = TYPE_TI_ARGS (parm);
tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg)); tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
tree parm_parms tree parm_parms
= DECL_INNERMOST_TEMPLATE_PARMS = DECL_INNERMOST_TEMPLATE_PARMS
(TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm)); (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (parm));
int i, len; int i, len;
int parm_variadic_p = 0; int parm_variadic_p = 0;
......
2008-03-27 Douglas Gregor <doug.gregor@gmail.com>
* g++.dg/cpp0x/variadic91.C: New.
2008-03-27 Zdenek Dvorak <ook@ucw.cz> 2008-03-27 Zdenek Dvorak <ook@ucw.cz>
* gcc.dg/tree-ssa/loop-32.c: New testcase. * gcc.dg/tree-ssa/loop-32.c: New testcase.
// { dg-options "-std=c++0x" }
template<int N> struct Int2Type { };
template<typename... T>
struct Outer {
template<typename... U>
void foo(Int2Type<sizeof...(T)>, Int2Type<sizeof...(U)>);
};
Outer<short, int, long> outer;
void g4() {
outer.foo<float, double>(Int2Type<3>(), Int2Type<2>());
}
template<typename... T, template<T...> class X> void f1();
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