re PR debug/41266 (Emit DW_TAG_template_parameter_pack and DW_TAG_formal_parameter_pack)

Fix for PR debug/41266

ChangeLog:

	* include/dwarf2.h (enum dwarf_tag): Add
	DW_TAG_template_parameter_pack and DW_TAG_formal_parameter_pack.

gcc/ChangeLog:

	* dwarf2out.c (template_parameter_pack_die,
	gen_formal_parameter_pack_die ): New functions.
	(make_ith_pack_parameter_name): Remove this function.
	(dwarf_tag_name): Support printing DW_TAG_template_parameter_pack and
	DW_TAG_formal_parameter_pack.
	(gen_generic_params_dies): Represent each template parameter pack
	by a DW_TAG_template_parameter_pack DIE. Argument pack elements are
	represented by usual DW_TAG_template_*_parameter DIEs that are
	children of the DW_TAG_template_parameter_pack element DIE.
	(generic_parameter_die): This doesn't deal with parameter pack
	names anymore. Don't generate DW_AT_name for some DIEs, e.g. children of
	parameter pack DIEs.
	(gen_formal_parameter_die): Add a flag to not emit DW_AT_name
	in certain cases, e.g. for pack elements.
	(gen_formal_types_die, gen_decl_die): Adjust usage of
	gen_formal_parameter_die.
	(gen_subprogram_die): Represent each function parameter pack by a
	DW_TAG_formal_parameter_pack DIE. Arguments of of the pack are
	represented by usual DW_TAG_formal_parameter DIEs that are children
	of the DW_TAG_formal_parameter_pack DIE. Remove references to
	____builtin_va_alist decls as no part of the compiler uses those
	anymore.
	* langhooks.h (struct lang_hooks_for_decls): Add
	function_parm_expanded_from_pack_p, get_generic_function_decl
	and function_parameter_pack_p hooks.  Fix comment for
	get_innermost_generic_parms hook.
	* langhooks-def.h (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
	LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P ): Declare new hook
	macros and use them to initialize lang_hook.

gcc/cp/ChangeLog:

	* cp-lang.c (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
	LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P,
	LANG_HOOKS_GET_GENERIC_FUNCTION_DECL): Initialize these
	hooks for the c++ FE.
	* cp-tree.h (function_parameter_pack_p, get_function_template_decl,
	function_parameter_expanded_from_pack_p): Declare ...
	* pt.c (function_parameter_pack_p, get_function_template_decl,
	function_parameter_expanded_from_pack_p): ... new hooks.
	(get_template_info): Make this more robust.
	(template_args_variadic_p, make_ith_pack_parameter_name): Add a new
	line between comment and function.
	(get_template_argument_pack_elems): Fix comment.
	(tsubst_decl): Arguments of function parameter packs are not
	parameter packs themselves.

gcc/testsuite/ChangeLog:
	* g++.dg/debug/dwarf2/template-func-params-4.C: Adjust.
	* g++.dg/debug/dwarf2/template-func-params-7.C: Likewise.
	* g++.dg/debug/dwarf2/template-params-4.C: Likewise.

From-SVN: r152043
This commit is contained in:
Dodji Seketeli 2009-09-22 20:20:03 +00:00 committed by Dodji Seketeli
parent 8249770055
commit d40a19da13
14 changed files with 339 additions and 101 deletions

View file

@ -1,3 +1,35 @@
2009-09-22 Dodji Seketeli <dodji@redhat.com>
* dwarf2out.c (template_parameter_pack_die,
gen_formal_parameter_pack_die ): New functions.
(make_ith_pack_parameter_name): Remove this function.
(dwarf_tag_name): Support printing DW_TAG_template_parameter_pack and
DW_TAG_formal_parameter_pack.
(gen_generic_params_dies): Represent each template parameter pack
by a DW_TAG_template_parameter_pack DIE. Argument pack elements are
represented by usual DW_TAG_template_*_parameter DIEs that are
children of the DW_TAG_template_parameter_pack element DIE.
(generic_parameter_die): This doesn't deal with parameter pack
names anymore. Don't generate DW_AT_name for some DIEs, e.g. children of
parameter pack DIEs.
(gen_formal_parameter_die): Add a flag to not emit DW_AT_name
in certain cases, e.g. for pack elements.
(gen_formal_types_die, gen_decl_die): Adjust usage of
gen_formal_parameter_die.
(gen_subprogram_die): Represent each function parameter pack by a
DW_TAG_formal_parameter_pack DIE. Arguments of of the pack are
represented by usual DW_TAG_formal_parameter DIEs that are children
of the DW_TAG_formal_parameter_pack DIE. Remove references to
____builtin_va_alist decls as no part of the compiler uses those
anymore.
* langhooks.h (struct lang_hooks_for_decls): Add
function_parm_expanded_from_pack_p, get_generic_function_decl
and function_parameter_pack_p hooks. Fix comment for
get_innermost_generic_parms hook.
* langhooks-def.h (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P ): Declare new hook
macros and use them to initialize lang_hook.
2009-09-22 Richard Henderson <rth@redhat.com>
* system.h (TRAMPOLINE_TEMPLATE, INITIALIZE_TRAMPOLINE): Poison.

View file

@ -1,3 +1,20 @@
2009-09-22 Dodji Seketeli <dodji@redhat.com>
* cp-lang.c (LANG_HOOKS_FUNCTION_PARAMETER_PACK_P,
LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P,
LANG_HOOKS_GET_GENERIC_FUNCTION_DECL): Initialize these
hooks for the c++ FE.
* cp-tree.h (function_parameter_pack_p, get_function_template_decl,
function_parameter_expanded_from_pack_p): Declare ...
* pt.c (function_parameter_pack_p, get_function_template_decl,
function_parameter_expanded_from_pack_p): ... new hooks.
(get_template_info): Make this more robust.
(template_args_variadic_p, make_ith_pack_parameter_name): Add a new
line between comment and function.
(get_template_argument_pack_elems): Fix comment.
(tsubst_decl): Arguments of function parameter packs are not
parameter packs themselves.
2009-09-21 Jason Merrill <jason@redhat.com>
PR c++/41421

View file

@ -59,13 +59,20 @@ static tree cp_eh_personality (void);
#undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS
#define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \
get_template_innermost_arguments
#undef LANG_HOOKS_FUNCTION_PARAMETER_PACK_P
#define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P \
function_parameter_pack_p
#undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS
#define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \
get_template_argument_pack_elems
#undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P
#define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \
template_template_parameter_p
#undef LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P
#define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \
function_parameter_expanded_from_pack_p
#undef LANG_HOOKS_GET_GENERIC_FUNCTION_DECL
#define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL get_function_template_decl
#undef LANG_HOOKS_DECL_PRINTABLE_NAME
#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
#undef LANG_HOOKS_DWARF_NAME

View file

@ -4643,6 +4643,8 @@ extern tree instantiate_decl (tree, int, bool);
extern int comp_template_parms (const_tree, const_tree);
extern bool uses_parameter_packs (tree);
extern bool template_parameter_pack_p (const_tree);
extern bool function_parameter_pack_p (const_tree);
extern bool function_parameter_expanded_from_pack_p (tree, tree);
extern tree make_pack_expansion (tree);
extern bool check_for_bare_parameter_packs (tree);
extern tree get_template_info (const_tree);
@ -4692,7 +4694,7 @@ bool template_template_parameter_p (const_tree);
extern tree get_primary_template_innermost_parameters (const_tree);
extern tree get_template_innermost_arguments (const_tree);
extern tree get_template_argument_pack_elems (const_tree);
extern tree get_function_template_decl (const_tree);
/* in repo.c */
extern void init_repo (void);
extern int repo_emit_p (tree);

View file

@ -294,6 +294,9 @@ get_template_info (const_tree t)
{
tree tinfo = NULL_TREE;
if (!t || t == error_mark_node)
return NULL;
if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
tinfo = DECL_TEMPLATE_INFO (t);
@ -2617,6 +2620,7 @@ comp_template_parms (const_tree parms1, const_tree parms2)
}
/* Determine whether PARM is a parameter pack. */
bool
template_parameter_pack_p (const_tree parm)
{
@ -2635,8 +2639,49 @@ template_parameter_pack_p (const_tree parm)
&& TEMPLATE_TYPE_PARAMETER_PACK (parm));
}
/* Determine if T is a function parameter pack. */
bool
function_parameter_pack_p (const_tree t)
{
if (t && TREE_CODE (t) == PARM_DECL)
return FUNCTION_PARAMETER_PACK_P (t);
return false;
}
/* Return the function template declaration of PRIMARY_FUNC_TMPL_INST.
PRIMARY_FUNC_TMPL_INST is a primary function template instantiation. */
tree
get_function_template_decl (const_tree primary_func_tmpl_inst)
{
if (! primary_func_tmpl_inst
|| TREE_CODE (primary_func_tmpl_inst) != FUNCTION_DECL
|| ! primary_template_instantiation_p (primary_func_tmpl_inst))
return NULL;
return DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (primary_func_tmpl_inst));
}
/* Return true iff the function parameter PARAM_DECL was expanded
from the function parameter pack PACK. */
bool
function_parameter_expanded_from_pack_p (tree param_decl, tree pack)
{
if (! function_parameter_pack_p (pack))
return false;
gcc_assert (DECL_NAME (param_decl) && DECL_NAME (pack));
/* The parameter pack and its pack arguments have the same
DECL_PARM_INDEX. */
return DECL_PARM_INDEX (pack) == DECL_PARM_INDEX (param_decl);
}
/* Determine whether ARGS describes a variadic template args list,
i.e., one that is terminated by a template argument pack. */
static bool
template_args_variadic_p (tree args)
{
@ -2659,6 +2704,7 @@ template_args_variadic_p (tree args)
/* Generate a new name for the parameter pack name NAME (an
IDENTIFIER_NODE) that incorporates its */
static tree
make_ith_pack_parameter_name (tree name, int i)
{
@ -2735,7 +2781,8 @@ get_template_innermost_arguments (const_tree t)
return args;
}
/* Return the arguments pack of T if T is a template, NULL otherwise. */
/* Return the argument pack elements of T if T is a template argument pack,
NULL otherwise. */
tree
get_template_argument_pack_elems (const_tree t)
@ -8825,6 +8872,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
if (DECL_TEMPLATE_PARM_P (t))
SET_DECL_TEMPLATE_PARM_P (r);
/* An argument of a function parameter pack is not a parameter
pack. */
FUNCTION_PARAMETER_PACK_P (r) = false;
if (expanded_types)
/* We're on the Ith parameter of the function parameter
pack. */

View file

@ -5932,7 +5932,8 @@ static dw_die_ref base_type_die (tree);
static int is_base_type (tree);
static dw_die_ref subrange_type_die (tree, tree, tree, dw_die_ref);
static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
static dw_die_ref generic_parameter_die (tree, tree, dw_die_ref, int);
static dw_die_ref generic_parameter_die (tree, tree, bool, dw_die_ref);
static dw_die_ref template_parameter_pack_die (tree, tree, dw_die_ref);
static int type_is_enum (const_tree);
static unsigned int dbx_reg_number (const_rtx);
static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
@ -6000,7 +6001,8 @@ static void gen_descr_array_type_die (tree, struct array_descr_info *, dw_die_re
static void gen_entry_point_die (tree, dw_die_ref);
#endif
static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
static dw_die_ref gen_formal_parameter_die (tree, tree, dw_die_ref);
static dw_die_ref gen_formal_parameter_die (tree, tree, bool, dw_die_ref);
static dw_die_ref gen_formal_parameter_pack_die (tree, tree, dw_die_ref, tree*);
static void gen_unspecified_parameters_die (tree, dw_die_ref);
static void gen_formal_types_die (tree, dw_die_ref);
static void gen_subprogram_die (tree, dw_die_ref);
@ -6032,7 +6034,6 @@ static dw_die_ref declare_in_namespace (tree, dw_die_ref);
static struct dwarf_file_data * lookup_filename (const char *);
static void retry_incomplete_types (void);
static void gen_type_die_for_member (tree, tree, dw_die_ref);
static tree make_ith_pack_parameter_name (tree, int);
static void gen_generic_params_dies (tree);
static void splice_child_die (dw_die_ref, dw_die_ref);
static int file_info_cmp (const void *, const void *);
@ -6337,6 +6338,10 @@ dwarf_tag_name (unsigned int tag)
return "DW_TAG_condition";
case DW_TAG_shared_type:
return "DW_TAG_shared_type";
case DW_TAG_template_parameter_pack:
return "DW_TAG_template_parameter_pack";
case DW_TAG_formal_parameter_pack:
return "DW_TAG_formal_parameter_pack";
case DW_TAG_MIPS_loop:
return "DW_TAG_MIPS_loop";
case DW_TAG_format_label:
@ -10512,27 +10517,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
return mod_type_die;
}
/* Generate a new name for the parameter pack name NAME (an
IDENTIFIER_NODE) that incorporates its */
static tree
make_ith_pack_parameter_name (tree name, int i)
{
/* Munge the name to include the parameter index. */
#define NUMBUF_LEN 128
char numbuf[NUMBUF_LEN];
char* newname;
int newname_len;
snprintf (numbuf, NUMBUF_LEN, "%i", i);
newname_len = IDENTIFIER_LENGTH (name)
+ strlen (numbuf) + 2;
newname = (char*) alloca (newname_len);
snprintf (newname, newname_len,
"%s#%i", IDENTIFIER_POINTER (name), i);
return get_identifier (newname);
}
/* Generate DIEs for the generic parameters of T.
T must be either a generic type or a generic function.
See http://gcc.gnu.org/wiki/TemplateParmsDwarf for more. */
@ -10564,30 +10548,27 @@ gen_generic_params_dies (tree t)
args = lang_hooks.get_innermost_generic_args (t);
for (i = 0; i < parms_num; i++)
{
tree parm, arg;
tree parm, arg, arg_pack_elems;
parm = TREE_VEC_ELT (parms, i);
arg = TREE_VEC_ELT (args, i);
arg_pack_elems = lang_hooks.types.get_argument_pack_elems (arg);
gcc_assert (parm && TREE_VALUE (parm) && arg);
if (parm && TREE_VALUE (parm) && arg)
{
tree pack_elems =
lang_hooks.types.get_argument_pack_elems (arg);
if (pack_elems)
{
/* So ARG is an argument pack and the elements of that pack
are stored in PACK_ELEMS. */
int i, len;
len = TREE_VEC_LENGTH (pack_elems);
for (i = 0; i < len; i++)
generic_parameter_die (TREE_VALUE (parm),
TREE_VEC_ELT (pack_elems, i),
die, i);
}
else /* Arg is not an argument pack. */
generic_parameter_die (TREE_VALUE (parm),
arg, die,
-1/* Not a param pack. */);
/* If PARM represents a template parameter pack,
emit a DW_TAG_template_parameter_pack DIE, followed
by DW_TAG_template_*_parameter DIEs for the argument
pack elements of ARG. Note that ARG would then be
an argument pack. */
if (arg_pack_elems)
template_parameter_pack_die (TREE_VALUE (parm),
arg_pack_elems,
die);
else
generic_parameter_die (TREE_VALUE (parm), arg,
true /* Emit DW_AT_name */, die);
}
}
}
@ -10596,15 +10577,15 @@ gen_generic_params_dies (tree t)
the representation of a generic type parameter.
For instance, in the C++ front end, PARM would be a template parameter.
ARG is the argument to PARM.
EMIT_NAME_P if tree, the DIE will have DW_AT_name attribute set to the
name of the PARM.
PARENT_DIE is the parent DIE which the new created DIE should be added to,
as a child node.
PACK_ELEM_INDEX is >= 0 if PARM is a generic parameter pack, and if ARG
is one of the unpacked elements of the parameter PACK. In that case,
PACK_ELEM_INDEX is the index of ARG in the parameter pack. */
as a child node. */
static dw_die_ref
generic_parameter_die (tree parm, tree arg, dw_die_ref parent_die,
int pack_elem_index)
generic_parameter_die (tree parm, tree arg,
bool emit_name_p,
dw_die_ref parent_die)
{
dw_die_ref tmpl_die = NULL;
const char *name = NULL;
@ -10637,20 +10618,17 @@ generic_parameter_die (tree parm, tree arg, dw_die_ref parent_die,
{
tree tmpl_type;
if (pack_elem_index >= 0)
/* If PARM is a generic parameter pack, it means we are
emitting debug info for a template argument pack element.
In other terms, ARG is a template argument pack element.
In that case, we don't emit any DW_AT_name attribute for
the die. */
if (emit_name_p)
{
/* PARM is an element of a parameter pack.
Generate a name for it. */
tree identifier = make_ith_pack_parameter_name (DECL_NAME (parm),
pack_elem_index);
if (identifier)
name = IDENTIFIER_POINTER (identifier);
name = IDENTIFIER_POINTER (DECL_NAME (parm));
gcc_assert (name);
add_AT_string (tmpl_die, DW_AT_name, name);
}
else
name = IDENTIFIER_POINTER (DECL_NAME (parm));
gcc_assert (name);
add_AT_string (tmpl_die, DW_AT_name, name);
if (!lang_hooks.decls.generic_generic_parameter_decl_p (parm))
{
@ -10695,6 +10673,33 @@ generic_parameter_die (tree parm, tree arg, dw_die_ref parent_die,
return tmpl_die;
}
/* Generate and return a DW_TAG_template_parameter_pack DIE representing.
PARM_PACK must be a template parameter pack. The returned DIE
will be child DIE of PARENT_DIE. */
static dw_die_ref
template_parameter_pack_die (tree parm_pack,
tree parm_pack_args,
dw_die_ref parent_die)
{
dw_die_ref die;
int j;
gcc_assert (parent_die
&& parm_pack
&& DECL_NAME (parm_pack));
die = new_die (DW_TAG_template_parameter_pack, parent_die, parm_pack);
add_AT_string (die, DW_AT_name, IDENTIFIER_POINTER (DECL_NAME (parm_pack)));
for (j = 0; j < TREE_VEC_LENGTH (parm_pack_args); j++)
generic_parameter_die (parm_pack,
TREE_VEC_ELT (parm_pack_args, j),
false /* Don't emit DW_AT_name */,
die);
return die;
}
/* Given a pointer to an arbitrary ..._TYPE tree node, return true if it is
an enumerated type. */
@ -15380,10 +15385,13 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
DIE to represent a formal parameter object (or some inlining thereof). If
it's the latter, then this function is only being called to output a
DW_TAG_formal_parameter DIE to stand as a placeholder for some formal
argument type of some subprogram type. */
argument type of some subprogram type.
If EMIT_NAME_P is true, name and source coordinate attributes
are emitted. */
static dw_die_ref
gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
gen_formal_parameter_die (tree node, tree origin, bool emit_name_p,
dw_die_ref context_die)
{
tree node_or_origin = node ? node : origin;
dw_die_ref parm_die
@ -15399,7 +15407,8 @@ gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
else
{
tree type = TREE_TYPE (node);
add_name_and_src_coords_attributes (parm_die, node);
if (emit_name_p)
add_name_and_src_coords_attributes (parm_die, node);
if (decl_by_reference_p (node))
add_type_attribute (parm_die, TREE_TYPE (type), 0, 0,
context_die);
@ -15432,6 +15441,49 @@ gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
return parm_die;
}
/* Generate and return a DW_TAG_formal_parameter_pack. Also generate
children DW_TAG_formal_parameter DIEs representing the arguments of the
parameter pack.
PARM_PACK must be a function parameter pack.
PACK_ARG is the first argument of the parameter pack. Its TREE_CHAIN
must point to the subsequent arguments of the function PACK_ARG belongs to.
SUBR_DIE is the DIE of the function PACK_ARG belongs to.
If NEXT_ARG is non NULL, *NEXT_ARG is set to the function argument
following the last one for which a DIE was generated. */
static dw_die_ref
gen_formal_parameter_pack_die (tree parm_pack,
tree pack_arg,
dw_die_ref subr_die,
tree *next_arg)
{
tree arg;
dw_die_ref parm_pack_die;
gcc_assert (parm_pack
&& lang_hooks.function_parameter_pack_p (parm_pack)
&& DECL_NAME (parm_pack)
&& subr_die);
parm_pack_die = new_die (DW_TAG_formal_parameter_pack, subr_die, parm_pack);
add_AT_string (parm_pack_die, DW_AT_name,
IDENTIFIER_POINTER (DECL_NAME (parm_pack)));
for (arg = pack_arg; arg; arg = TREE_CHAIN (arg))
{
if (! lang_hooks.decls.function_parm_expanded_from_pack_p (arg,
parm_pack))
break;
gen_formal_parameter_die (arg, NULL,
false /* Don't emit name attribute. */,
parm_pack_die);
}
if (next_arg)
*next_arg = arg;
return parm_pack_die;
}
/* Generate a special type of DIE used as a stand-in for a trailing ellipsis
at the end of an (ANSI prototyped) formal parameters list. */
@ -15475,7 +15527,9 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
break;
/* Output a (nameless) DIE to represent the formal parameter itself. */
parm_die = gen_formal_parameter_die (formal_type, NULL, context_die);
parm_die = gen_formal_parameter_die (formal_type, NULL,
true /* Emit name attribute. */,
context_die);
if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
&& link == first_parm_type)
|| (arg && DECL_ARTIFICIAL (arg)))
@ -15887,21 +15941,46 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
else
{
/* Generate DIEs to represent all known formal parameters. */
tree arg_decls = DECL_ARGUMENTS (decl);
tree parm;
tree parm = DECL_ARGUMENTS (decl);
tree generic_decl = lang_hooks.decls.get_generic_function_decl (decl);
tree generic_decl_parm = generic_decl
? DECL_ARGUMENTS (generic_decl)
: NULL;
/* When generating DIEs, generate the unspecified_parameters DIE
instead if we come across the arg "__builtin_va_alist" */
for (parm = arg_decls; parm; parm = TREE_CHAIN (parm))
if (TREE_CODE (parm) == PARM_DECL)
{
if (DECL_NAME (parm)
&& !strcmp (IDENTIFIER_POINTER (DECL_NAME (parm)),
"__builtin_va_alist"))
gen_unspecified_parameters_die (parm, subr_die);
else
/* Now we want to walk the list of parameters of the function and
emit their relevant DIEs.
We consider the case of DECL being an instance of a generic function
as well as it being a normal function.
If DECL is an instance of a generic function we walk the
parameters of the generic function declaration _and_ the parameters of
DECL itself. This is useful because we want to emit specific DIEs for
function parameter packs and those are declared as part of the
generic function declaration. In that particular case,
the parameter pack yields a DW_TAG_formal_parameter_pack DIE.
That DIE has children DIEs representing the set of arguments
of the pack. Note that the set of pack arguments can be empty.
In that case, the DW_TAG_formal_parameter_pack DIE will not have any
children DIE.
Otherwise, we just consider the parameters of DECL. */
while (generic_decl_parm || parm)
{
if (generic_decl_parm
&& lang_hooks.function_parameter_pack_p (generic_decl_parm))
gen_formal_parameter_pack_die (generic_decl_parm,
parm, subr_die,
&parm);
else if (parm)
{
gen_decl_die (parm, NULL, subr_die);
}
parm = TREE_CHAIN (parm);
}
if (generic_decl_parm)
generic_decl_parm = TREE_CHAIN (generic_decl_parm);
}
/* Decide whether we need an unspecified_parameters DIE at the end.
There are 2 more cases to do this for: 1) the ansi ... declaration -
@ -17489,7 +17568,9 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
if (!origin)
origin = decl_ultimate_origin (decl);
if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
gen_formal_parameter_die (decl, origin, context_die);
gen_formal_parameter_die (decl, origin,
true /* Emit name attribute. */,
context_die);
else
gen_variable_die (decl, origin, context_die);
break;
@ -17511,7 +17592,9 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
else
gen_type_die (TREE_TYPE (decl_or_origin), context_die);
gen_formal_parameter_die (decl, origin, context_die);
gen_formal_parameter_die (decl, origin,
true /* Emit name attribute. */,
context_die);
break;
case NAMESPACE_DECL:

View file

@ -157,8 +157,12 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_GENERIC_TYPE_P hook_bool_const_tree_false
#define LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS hook_tree_const_tree_null
#define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS hook_tree_const_tree_null
#define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P hook_bool_const_tree_false
#define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS hook_tree_const_tree_null
#define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P hook_bool_const_tree_false
#define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \
hook_bool_tree_tree_false
#define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL hook_tree_const_tree_null
#define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
#define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_const_tree
@ -214,6 +218,8 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_GETDECLS, \
LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \
LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P, \
LANG_HOOKS_GET_GENERIC_FUNCTION_DECL, \
LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
LANG_HOOKS_WRITE_GLOBALS, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
@ -268,6 +274,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_FOR_TYPES_INITIALIZER, \
LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS, \
LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS, \
LANG_HOOKS_FUNCTION_PARAMETER_PACK_P, \
LANG_HOOKS_GIMPLIFY_EXPR, \
LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
LANG_HOOKS_BUILTIN_FUNCTION, \

View file

@ -172,6 +172,13 @@ struct lang_hooks_for_decls
of a generic type, e.g a template template parameter for the C++ FE. */
bool (*generic_generic_parameter_decl_p) (const_tree);
/* Determine if a function parameter got expanded from a
function parameter pack. */
bool (*function_parm_expanded_from_pack_p) (tree, tree);
/* Returns the generic declaration of a generic function instantiations. */
tree (*get_generic_function_decl) (const_tree);
/* Returns true when we should warn for an unused global DECL.
We will already have checked that it has static binding. */
bool (*warn_unused_global) (const_tree);
@ -379,7 +386,7 @@ struct lang_hooks
struct lang_hooks_for_types types;
/* Retuns the generic parameters of an instantiation of
/* Returns the generic parameters of an instantiation of
a generic type or decl, e.g. C++ template instantiation. */
tree (*get_innermost_generic_parms) (const_tree);
@ -387,6 +394,9 @@ struct lang_hooks
of a generic type of decl, e.g. C++ template instantiation. */
tree (*get_innermost_generic_args) (const_tree);
/* Determine if a tree is a function parameter pack. */
bool (*function_parameter_pack_p) (const_tree);
/* Perform language-specific gimplification on the argument. Returns an
enum gimplify_status, though we can't see that type here. */
int (*gimplify_expr) (tree *, gimple_seq *, gimple_seq *);

View file

@ -1,3 +1,9 @@
2009-09-22 Dodji Seketeli <dodji@redhat.com>
* g++.dg/debug/dwarf2/template-func-params-4.C: Adjust.
* g++.dg/debug/dwarf2/template-func-params-7.C: Likewise.
* g++.dg/debug/dwarf2/template-params-4.C: Likewise.
2009-09-22 Alexandre Oliva <aoliva@redhat.com>
PR debug/41295

View file

@ -1,10 +1,16 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-std=c++0x -g -dA" }
// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
// { dg-final { scan-assembler "DW_AT_name.*P#0" } }
// { dg-final { scan-assembler "DW_AT_name.*P#1" } }
// { dg-final { scan-assembler "DW_AT_name.*P#2" } }
//
// In theory the compiler instantiates count<int, char, long>,
// count<char, long> and count<long>. In practice, only
// count<int, char, long> is emitted, thanks to constant folding.
// So in theory, each of the 3 instances of count yields a
// DW_TAG_tempalate_parameter_pack DIE, but in practise, there is only one
// DW_TAG_template_parameter_pack as there is only count<int, char, long>
// is emitted.
// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_parameter_pack" 1} }
// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_type_param" 3} }
template <typename... Args> struct count;

View file

@ -16,17 +16,15 @@
// { dg-final {scan-assembler-times "\"printf.0\".*?DW_AT_name" 1 } }
// printf<int, char, int> and printf<char, int> have a pack expansion as
// function parameters. In the former, the elements of the parameter pack
// expansion are PackTypes#0, PackTypes#1 and the arguments are args#0 and
// args#1. In the later, the element of the parameter pack expansion
// is PackTypes#0 and the argument is args#0.
// { dg-final {scan-assembler-times "DW_AT_name: \"PackTypes#0\"" 2 } }
// { dg-final {scan-assembler-times "\"args#0.0\".*?DW_AT_name" 2 } }
// { dg-final {scan-assembler-times "\"PackTypes#1.0\".*?DW_AT_name" 1 } }
// { dg-final {scan-assembler-times "\"args#1.0\".*?DW_AT_name" 1 } }
// function parameters. There should then be 3
// DW_TAG_template_parameter_pack and 3 DW_TAG_formal_parameter_pack DIEs
// { dg-final {scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_parameter_pack" 3 } }
// { dg-final {scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_formal_parameter_pack" 3 } }
// These 3 function template instantiations has a total of 3 template
// parameters named T.
// { dg_final {scan-assembler-times "\.ascii \"T.0\"\[\t \]+.*?DW_AT_name" 3 } }
void
printf(const char* s)
{

View file

@ -1,10 +1,16 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-std=c++0x -g -dA" }
// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
// { dg-final { scan-assembler "DW_AT_name.*Args#0" } }
// { dg-final { scan-assembler "DW_AT_name.*Args#1" } }
// { dg-final { scan-assembler "DW_AT_name.*Args#2" } }
//
// In theory the compiler instantiates count<int, char, long>,
// count<char, long> and count<long>. In practice, only
// count<int, char, long> is emitted, thanks to constant folding.
// So in theory, each of the 3 instances of count yields a
// DW_TAG_tempalate_parameter_pack DIE, but in practise, there is only one
// DW_TAG_template_parameter_pack as there is only count<int, char, long>
// is emitted.
// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_parameter_pack" 1} }
// { dg-final { scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_type_param" 3} }
template <typename... Args> struct count;

View file

@ -1,3 +1,8 @@
2009-09-22 Dodji Seketeli <dodji@redhat.com>
* dwarf2.h (enum dwarf_tag): Add
DW_TAG_template_parameter_pack and DW_TAG_formal_parameter_pack.
2009-07-24 Ian Lance Taylor <iant@google.com>
PR bootstrap/40854

View file

@ -200,6 +200,14 @@ enum dwarf_tag
DW_TAG_lo_user = 0x4080,
DW_TAG_hi_user = 0xffff,
/* DWARF 5? */
/* Template parameter pack extension, specified at
http://wiki.dwarfstd.org/index.php?title=C%2B%2B0x:_Variadic_templates
. */
DW_TAG_template_parameter_pack = 0x43,
DW_TAG_formal_parameter_pack = 0x44,
/* SGI/MIPS Extensions. */
DW_TAG_MIPS_loop = 0x4081,
/* HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */