@@ -2109,6 +2109,8 @@ static tree cp_parser_late_parsing_omp_declare_simd
static tree synthesize_implicit_template_parm
(cp_parser *);
+static tree convert_generic_types_to_packs
+ (tree, tree, int, int);
static tree finish_fully_implicit_template
(cp_parser *, tree);
@@ -18069,7 +18071,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;
@@ -18078,7 +18080,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;
@@ -18088,6 +18090,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,
@@ -18099,11 +18105,30 @@ 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,
+ current_template_parms,
+ 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;
@@ -31213,6 +31238,48 @@ synthesize_implicit_template_parm (cp_parser *parser)
return new_type;
}
+/* Convert the generic type parameters in PARM that match the types given in the
+ range [START_IDX, END_IDX) from the template parameters CURRENT into generic
+ type packs. */
+
+tree
+convert_generic_types_to_packs (tree parm,
+ tree current, int start_idx, int end_idx)
+{
+ int depth = TMPL_PARMS_DEPTH (current);
+ current = INNERMOST_TEMPLATE_PARMS (current);
+ tree replacement = make_tree_vec (TREE_VEC_LENGTH (current));
+
+ 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 t = copy_type (TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (current, i))));
+ TYPE_STUB_DECL (t) = TYPE_NAME (t) = TEMPLATE_TYPE_DECL (t);
+ TYPE_MAIN_VARIANT (t) = t;
+ TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ TREE_VEC_ELT (replacement, i) = t;
+ }
+
+ if (depth > 1)
+ {
+ /* Build up a tree vec of empty tree vecs up to the inner substitution
+ args built above. */
+
+ tree inner = replacement;
+ replacement = make_tree_vec (depth);
+ int last = depth - 1;
+ for (int i = 0; i < last; ++i)
+ TREE_VEC_ELT (replacement, i) = make_tree_vec (0);
+ TREE_VEC_ELT (replacement, last) = inner;
+ }
+
+ return tsubst (parm, replacement, tf_none, NULL_TREE);
+}
+
/* Finish the declaration of a fully implicit function template. Such a
template has no explicit template parameter list so has not been through the
normal template head and tail processing. synthesize_implicit_template_parm