Support implicit parameter packs.
* pt.c (convert_generic_types_to_packs): New function to transform a range of implicitly introduced non-pack template parms to be parameter packs. * cp-tree.h (convert_generic_types_to_packs): Declare. * parser.c (cp_parser_parameter_declaration_list): If a function parameter pack contains generic types, convert them to packs prior to grokdeclarator. From-SVN: r204715
This commit is contained in:
parent
0dca5025f0
commit
91f1c20826
4 changed files with 92 additions and 7 deletions
|
@ -1,3 +1,13 @@
|
|||
2013-11-12 Adam Butcher <adam@jessamine.co.uk>
|
||||
|
||||
* pt.c (convert_generic_types_to_packs): New function to transform
|
||||
a range of implicitly introduced non-pack template parms to be parameter
|
||||
packs.
|
||||
* cp-tree.h (convert_generic_types_to_packs): Declare.
|
||||
* parser.c (cp_parser_parameter_declaration_list): If a function
|
||||
parameter pack contains generic types, convert them to packs prior to
|
||||
grokdeclarator.
|
||||
|
||||
2013-11-12 Adam Butcher <adam@jessamine.co.uk>
|
||||
|
||||
PR c++/58534
|
||||
|
|
|
@ -5469,6 +5469,7 @@ extern tree type_uses_auto (tree);
|
|||
extern tree type_uses_auto_or_concept (tree);
|
||||
extern void append_type_to_template_for_access_check (tree, tree, tree,
|
||||
location_t);
|
||||
extern tree convert_generic_types_to_packs (tree, int, int);
|
||||
extern tree splice_late_return_type (tree, tree);
|
||||
extern bool is_auto (const_tree);
|
||||
extern bool is_auto_or_concept (const_tree);
|
||||
|
|
|
@ -18112,7 +18112,7 @@ static tree
|
|||
cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
|
||||
{
|
||||
tree parameters = NULL_TREE;
|
||||
tree *tail = ¶meters;
|
||||
tree *tail = ¶meters;
|
||||
bool saved_in_unbraced_linkage_specification_p;
|
||||
int index = 0;
|
||||
|
||||
|
@ -18121,7 +18121,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
|
|||
/* The special considerations that apply to a function within an
|
||||
unbraced linkage specifications do not apply to the parameters
|
||||
to the function. */
|
||||
saved_in_unbraced_linkage_specification_p
|
||||
saved_in_unbraced_linkage_specification_p
|
||||
= parser->in_unbraced_linkage_specification_p;
|
||||
parser->in_unbraced_linkage_specification_p = false;
|
||||
|
||||
|
@ -18131,6 +18131,10 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
|
|||
cp_parameter_declarator *parameter;
|
||||
tree decl = error_mark_node;
|
||||
bool parenthesized_p = false;
|
||||
int template_parm_idx = (parser->num_template_parameter_lists?
|
||||
TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
|
||||
(current_template_parms)) : 0);
|
||||
|
||||
/* Parse the parameter. */
|
||||
parameter
|
||||
= cp_parser_parameter_declaration (parser,
|
||||
|
@ -18142,11 +18146,29 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
|
|||
deprecated_state = DEPRECATED_SUPPRESS;
|
||||
|
||||
if (parameter)
|
||||
decl = grokdeclarator (parameter->declarator,
|
||||
¶meter->decl_specifiers,
|
||||
PARM,
|
||||
parameter->default_argument != NULL_TREE,
|
||||
¶meter->decl_specifiers.attributes);
|
||||
{
|
||||
/* If a function parameter pack was specified and an implicit template
|
||||
parameter was introduced during cp_parser_parameter_declaration,
|
||||
change any implicit parameters introduced into packs. */
|
||||
if (parser->implicit_template_parms
|
||||
&& parameter->declarator
|
||||
&& parameter->declarator->parameter_pack_p)
|
||||
{
|
||||
int latest_template_parm_idx = TREE_VEC_LENGTH
|
||||
(INNERMOST_TEMPLATE_PARMS (current_template_parms));
|
||||
|
||||
if (latest_template_parm_idx != template_parm_idx)
|
||||
parameter->decl_specifiers.type = convert_generic_types_to_packs
|
||||
(parameter->decl_specifiers.type,
|
||||
template_parm_idx, latest_template_parm_idx);
|
||||
}
|
||||
|
||||
decl = grokdeclarator (parameter->declarator,
|
||||
¶meter->decl_specifiers,
|
||||
PARM,
|
||||
parameter->default_argument != NULL_TREE,
|
||||
¶meter->decl_specifiers.attributes);
|
||||
}
|
||||
|
||||
deprecated_state = DEPRECATED_NORMAL;
|
||||
|
||||
|
|
52
gcc/cp/pt.c
52
gcc/cp/pt.c
|
@ -21630,6 +21630,58 @@ append_type_to_template_for_access_check (tree templ,
|
|||
scope, location);
|
||||
}
|
||||
|
||||
/* Convert the generic type parameters in PARM that match the types given in the
|
||||
range [START_IDX, END_IDX) from the current_template_parms into generic type
|
||||
packs. */
|
||||
|
||||
tree
|
||||
convert_generic_types_to_packs (tree parm, int start_idx, int end_idx)
|
||||
{
|
||||
tree current = current_template_parms;
|
||||
int depth = TMPL_PARMS_DEPTH (current);
|
||||
current = INNERMOST_TEMPLATE_PARMS (current);
|
||||
tree replacement = make_tree_vec (TREE_VEC_LENGTH (current));
|
||||
|
||||
for (int i = 0; i < start_idx; ++i)
|
||||
TREE_VEC_ELT (replacement, i)
|
||||
= TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i)));
|
||||
|
||||
for (int i = start_idx; i < end_idx; ++i)
|
||||
{
|
||||
/* Create a distinct parameter pack type from the current parm and add it
|
||||
to the replacement args to tsubst below into the generic function
|
||||
parameter. */
|
||||
|
||||
tree o = TREE_TYPE (TREE_VALUE
|
||||
(TREE_VEC_ELT (current, i)));
|
||||
tree t = copy_type (o);
|
||||
TEMPLATE_TYPE_PARM_INDEX (t)
|
||||
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (o),
|
||||
o, 0, 0, tf_none);
|
||||
TREE_TYPE (TEMPLATE_TYPE_DECL (t)) = t;
|
||||
TYPE_STUB_DECL (t) = TYPE_NAME (t) = TEMPLATE_TYPE_DECL (t);
|
||||
TYPE_MAIN_VARIANT (t) = t;
|
||||
TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
|
||||
TYPE_CANONICAL (t) = canonical_type_parameter (t);
|
||||
TREE_VEC_ELT (replacement, i) = t;
|
||||
TREE_VALUE (TREE_VEC_ELT (current, i)) = TREE_CHAIN (t);
|
||||
}
|
||||
|
||||
for (int i = end_idx, e = TREE_VEC_LENGTH (current); i < e; ++i)
|
||||
TREE_VEC_ELT (replacement, i)
|
||||
= TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i)));
|
||||
|
||||
/* If there are more levels then build up the replacement with the outer
|
||||
template parms. */
|
||||
if (depth > 1)
|
||||
replacement = add_to_template_args (template_parms_to_args
|
||||
(TREE_CHAIN (current_template_parms)),
|
||||
replacement);
|
||||
|
||||
return tsubst (parm, replacement, tf_none, NULL_TREE);
|
||||
}
|
||||
|
||||
|
||||
/* Set up the hash tables for template instantiations. */
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Reference in a new issue