C++ PATCH: PR 20599 (variadic templates, take two) (1/4)

Douglas Gregor doug.gregor@gmail.com
Tue Sep 19 14:54:00 GMT 2006

This patch addresses PR c++/20599 by introducing support for variadic


This is a revised version of the patch posted previously. It  
addresses several bugs in the original patch and includes changes to  
libstdc++ that use variadic templates for the implementation of  
Library TR1 tuples and function objects. In particular, the changes  
from the first patch are:
	- Warn about variadic templates by default; -Wno-variadic-templates  
turns off this warning.
	- Support printing parameter packs in function types (for error  
	- Support for nested expansion of parameter packs.
	- Tighter error checking.

More information about variadic templates is available here:


This is part 1 of 4. It contains all of the C++ front end changes.

Tested on mainline with powerpc-apply-darwin8.7.0 and i686-pc-linux- 
gnu; no new regressions. All new tests pass.

	Doug Gregor
	Open Systems Lab @ Indiana University

2006-09-19	Douglas Gregor <doug.gregor@gmail.com>

	PR c++/20599
	* typeck.c (comptypes): Compare template parameter packs and
         PACK_UNPACK_TYPE types.
         * decl.c (grokdeclarator): Deal	with the declaration of  
	parameter packs.
	(grokparms): Verify that the (optional) function parameter pack is
	at the end of the parameter list.
	* cp-tree.def (TYPE_ARGUMENT_PACK): New.
	* cp-objcp-common.c (cp_tree_size): Compute size of
	* error.c (dump_template_argument): Print template argument packs.
	(dump_template_argument_list): Ditto.
	(dump_template_parameter): Dump `...' for template type parameter
	(dump_type): Dump PACK_UNPACK_TYPE nodes.
	(dump_parameters): Print function parameter packs.
	(dump_template_parms): Print template argument packs.
	(dump_expr): Dump PACK_UNPACK_EXPR nodes.
	(maybe_warn_variadic_templates): New.
	* operators.def: Add ellipsis operator for PACK_UNPACK_EXPR.
	* mangle.c (write_type): Mangle PACK_UNPACK_TYPE.
	(write_template_arg): Write argument packs as separate arguments.
	* cp-tree.h (template_parm_index_s): Add flag that indicates that
	the template parameter is actually a parameter pack.
	(struct cp_declarator): Add pack_unpack_p flag.
	(maybe_warn_variadic_templates): Declare.
	(process_template_parm): Added bool parameter.
	(uses_parameter_packs): Declare.
	(template_parms_variadic_p): Declare.
	(make_argument_pack_unpack): Declare.
	(check_for_bare_parameter_packs): Declare.
	* pt.c (comp_template_parms): Compare template parameter packs.
	(template_parms_variadic_p): New.
	(template_args_variadic_p): New.
	(make_ith_pack_parameter_name): New.
	(find_parameter_pack_data): New.
	(find_parameter_packs_r): New.
	(uses_parameter_packs): New.
	(make_argument_pack_unpack): New.
	(check_for_bare_parameter_packs): New.
	(expand_template_argument_pack): New.
	(reduce_template_parm_level): Propagate parameter pack flag.
	(process_template_parm): Add is_parameter_pack parameter to state
	when the parameter is actually a parameter pack. Create template
	parameter packs when is_parameter_pack is true.
	(current_template_args): The argument for a template parameter
	pack is an argument pack containing a single pack/unpack type or
	(process_partial_specialization): When checking that non-type
	argument expressions do not involve template parameters, loop over
	the arguments in argument packs separately.
	(push_template_decl_real): Check that the type of a function
	template does not have any bare parameter packs.  Check that
	primary templates have no more than one parameter pack, and that
	it comes at the end of the template parameter list.
	(convert_template_argument): Handle coercions for pack/unpack
	expressions by coercing the pattern then rebuilding the
	pack/unpack expression.
	(coerce_template_parms): When coercing the arguments for a
	variadic template, pack "extra" arguments into an argument pack.
	(template_args_equal): Compare PACK_UNPACK_P expressions.
	(comp_template_args): Expand all template arguments packs before
	comparing template argument lists.
	(mangle_class_name_for_template): Make argument packs as separate
	template arguments.
	(for_each_template_parm_r): Visit all arguments in an argument
	pack or visit the pattern of a pack/unpack type or expression.
	(tsubst_argument_pack): New.
	(tsubst_template_args): Handle substitutions of argument packs and
	pack/unpack types and expressions into template argument lists.
	(tsubst_decl): Expand function parameter packs into separate
	function parameters.
	(tsubst_arg_types): Unpack a pack/unpack type into separate
	argument types.
	(tsubst): Handle substitutions into argument packs.
	(tsubst_copy): sizeof(X...) returns the number of elements in
	parameter pack X.
	(tsubst_expr): Pack/unpack expressions and argument packs cannot
	show up here; they will all be handled through function calls,
	sizeof, and template argument lists.
	(tsubst_copy_and_build): sizeof(X...) returns the number of
	elements in parameter pack X.
	Substitute into pack/unpack expressions in TREE_LIST nodes.
	(fn_type_unification): Handle "incomplete" explicit template
	argument lists that specify some of the arguments for a template
	parameter pack.
	(type_unification_real): Unify arguments against pack/unpack
	(template_parm_level_and_index): New, helper function.
	(unify_with_pack_expr): New.
	(unify): Unify argument packs on an argument-by-argument basis,
	handling variadic argument packs as well.
	(more_specialized_fn): Handle unification of function parameter
	packs. All things being equal, prefer non-variadic function
	templates to variadic function templates.
	(more_specialized_class): Prefer the variadic class template
	partial specialization that binds fewer arguments to a parameter
	(regenerate_decl_from_template): Expand function parameter packs
	into separate parameters.
	(instantiate_decl): Ditto.
	(dependent_type_p_r): Determine dependent types in argument packs
	and pack/unpack types.
	(value_dependent_expression_p): Determine value-dependence of
	non-type argument packs.
	* semantics.c (finish_cond): Check for bare parameter packs.
	(finish_expr_stmt): Ditto.
	(finish_return_stmt): Ditto.
	(finish_for_expr): Ditto.
	(finish_switch_cond): Ditto.
	(finish_mem_initializers): Ditto.
	* name-lookup.c (arg_assoc_type): Handle pack/unpack types and
	argument packs.
	* decl2.c (cp_build_parm_decl): Mark function parameter packs.
	* parser.c (make_declarator): Declarator is not a pack/unpack.
	(make_pointer_declarator): Transfer pack/unpack flag to outer
	(make_reference_declarator): Ditto.
	(make_ptrmem_declarator): Ditto.
	(make_call_declarator): Ditto.
	(make_array_declarator): Ditto.
	(cp_parser_postfix_expression): Allow pack/unpack expressions in
	the argument list for a call expression.
	(cp_parser_parenthesized_expression_list): Add new parameter
	ALLOW_UNPACK_P. When true, parse the ellipsis to mean "expand into
	separate arguments."
	(cp_parser_new_placement): Allow pack/unpack expressions.
	(cp_parser_new_initializer): Ditto.
	(cp_parser_mem_initializer): Ditto.
	(cp_parser_template_parameter_list): Keep track of whether the
	template parameter is a template parameter pack.
	(cp_parser_template_parameter): Parse the ellipsis to indicate a
	template parameter pack.
	(cp_parser_type_parameter): Ditto.
	(cp_parser_template_argument_list): Parse the ellipsis to indicate
	a pack/unpack expression or type.
	(cp_parser_direct_declarator): Parse the ellipsis to indicate that
	this declarator is a parameter pack.
	(cp_parser_parameter_declaration): The ellipsis does not end the
	parameter declaration, because it might be a parameter pack. Parse
	the ellipsis to indicate a parameter pack.
	(cp_parser_initializer): Allow pack/unpack expressions.
	(cp_parser_base_specifier): Check for bare parameter packs.
	(cp_parser_attribute_list): Don't allow pack/unpack expressions.
	(cp_parser_functional_cast): Allow pack/unpack expressions.
	(cp_parser_sizeof_operand): Allow ellipsis in parenthesized form
	to indicate an "unpack" in sizeof (which computes the length of
	the pack).
	(cp_parser_next_token_ends_template_argument_p): An ellipsis can
	end a template argument.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: vt-cp-trunk-v2.patch
Type: application/octet-stream
Size: 138669 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20060919/b4734d28/attachment.obj>

More information about the Libstdc++ mailing list