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:
parent
8249770055
commit
d40a19da13
14 changed files with 339 additions and 101 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
53
gcc/cp/pt.c
53
gcc/cp/pt.c
|
@ -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. */
|
||||
|
|
243
gcc/dwarf2out.c
243
gcc/dwarf2out.c
|
@ -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:
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 . */
|
||||
|
|
Loading…
Add table
Reference in a new issue