Commit f9329c35 by Dodji Seketeli Committed by Dodji Seketeli

Emit DWARF for template parameters (PR debug/30161)

ChangeLog:
	PR debug/30161
	* include/dwarf2.h (enum dwarf_tag): Added
	DW_TAG_GNU_template_template_param
	(enum dwarf_attribute): Added DW_AT_GNU_template_name.

gcc/ChangeLog:
	PR debug/30161
	* cgraph.h (cgraph_get_node): Declare ...
	* cgraph.c (cgraph_get_node): ... new function.
	* dwarf2out.c (gen_generic_params_dies,
	generic_parameter_die, tree_add_const_value_attribute_for_decl,
	make_ith_pack_parameter_name,
	append_entry_to_tmpl_value_parm_die_table,
	gen_remaining_tmpl_value_param_die_attribute): New functions.
	(gen_subprogram_die): Generate debug info for template parameters
	if debug info level is higher than DINFO_LEVEL_TERSE.
	Use tree_add_const_value_attribute_for_decl instead of
	tree_add_const_value_attribute.
	(gen_const_die): Use tree_add_const_value_attribute_for_decl
	instead of tree_add_const_value_attribute.
	(gen_struct_or_union_type_die): Generate debug
	info for template parameters if debug info level is higher than
	DINFO_LEVEL_TERSE.
	(tree_add_const_value_attribute): Handle integral and pointer
	constants. Update comment.
	(dwarf_tag_name): Support DW_TAG_GNU_template_template_param.
	(dwarf_attr_name): Support DW_AT_GNU_template_name.
	(reference_to_unused): Fix thinko. Remove redundant predicates from
	tests.
	(tree_add_const_value_attribute): Make this work for constant
	expressions only.
	tree_add_const_value_attribute_for_decl is to be used for variable
	DECLs now.
	(add_location_or_const_value_attribute): Use
	tree_add_const_value_attribute_for_decl now.
	(dwarf2out_finish): Emit the DW_AT_const_value attribute of
	DW_TAG_template_value_param DIEs after function DIEs have been
	emitted.
	* langhooks.h (lang_hooks_for_types): Add
	get_argument_pack_elems.
	(lang_hooks_for_decls): Add generic_generic_parameter_decl_p.
	(lang_hooks): Added get_innermost_generic_parms,
	get_innermost_generic_args.
	* langhooks-def.h (LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS,
	LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS,
	LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS,
	LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P): New language hooks.

gcc/cp/ChangeLog:
	PR debug/30161
	* cp-tree.h (get_template_info): Parameter should be const.
	(CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): Fix typo.
	(get_template_argument_pack_elems,
	get_primary_template_innermost_parameters,
	get_template_innermost_arguments, template_template_parameter_p):
	Declare ...
	* pt.c (get_template_argument_pack_elems,
	get_template_innermost_parameters, get_template_innermost_arguments,
	template_template_parameter_p):
	... New C++ front end implementation of new language hooks.
	(primary_template_instantiation_p): New private helper.
	(make_ith_pack_parameter_name): Use snprintf and strnlen instead of
	printf and strlen.
	(get_template_info): Const-ify parameter.
	* cp-lang.c (LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS,
	LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS,
	LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS,
	LANG_HOOKS_GENERIC_TYPE_PARAMETER_DECL_P): Initialize these
	interfaces for the C++ front-end.

gcc/testsuite/ChangeLog:
	PR debug/30161
	* g++.dg/debug/dwarf2/template-params-1.C: New test.
	* g++.dg/debug/dwarf2/template-params-2.C: Likewise.
	* g++.dg/debug/dwarf2/template-params-3.C: Likewise.
	* g++.dg/debug/dwarf2/template-params-4.C: Likewise.
	* g++.dg/debug/dwarf2/template-params-5.C: Likewise.
	* g++.dg/debug/dwarf2/template-params-6.C: Likewise.
	* g++.dg/debug/dwarf2/template-func-params-1.C: Likewise.
	* g++.dg/debug/dwarf2/template-func-params-2.C: Likewise.
	* g++.dg/debug/dwarf2/template-func-params-3.C: Likewise.
	* g++.dg/debug/dwarf2/template-func-params-4.C: Likewise.
	* g++.dg/debug/dwarf2/template-func-params-5.C: Likewise.
	* g++.dg/debug/dwarf2/template-func-params-6.C: Likewise.
	* g++.dg/debug/dwarf2/template-func-params-7.C: Likewise.

From-SVN: r151249
parent e756464b
2009-08-31 Dodji Seketeli <dodji@redhat.com>
PR debug/30161
* include/dwarf2.h (enum dwarf_tag): Added
DW_TAG_GNU_template_template_param
(enum dwarf_attribute): Added DW_AT_GNU_template_name.
2009-08-30 Paolo Bonzini <bonzini@gnu.org> 2009-08-30 Paolo Bonzini <bonzini@gnu.org>
* Makefile.tpl (AWK): Fix typo. * Makefile.tpl (AWK): Fix typo.
......
2009-08-31 Dodji Seketeli <dodji@redhat.com>
PR debug/30161
* cgraph.h (cgraph_get_node): Declare ...
* cgraph.c (cgraph_get_node): ... new function.
* dwarf2out.c (gen_generic_params_dies,
generic_parameter_die, tree_add_const_value_attribute_for_decl,
make_ith_pack_parameter_name,
append_entry_to_tmpl_value_parm_die_table,
gen_remaining_tmpl_value_param_die_attribute): New functions.
(gen_subprogram_die): Generate debug info for template parameters
if debug info level is higher than DINFO_LEVEL_TERSE.
Use tree_add_const_value_attribute_for_decl instead of
tree_add_const_value_attribute.
(gen_const_die): Use tree_add_const_value_attribute_for_decl
instead of tree_add_const_value_attribute.
(gen_struct_or_union_type_die): Generate debug
info for template parameters if debug info level is higher than
DINFO_LEVEL_TERSE.
(tree_add_const_value_attribute): Handle integral and pointer
constants. Update comment.
(dwarf_tag_name): Support DW_TAG_GNU_template_template_param.
(dwarf_attr_name): Support DW_AT_GNU_template_name.
(reference_to_unused): Fix thinko. Remove redundant predicates from
tests.
(tree_add_const_value_attribute): Make this work for constant
expressions only.
tree_add_const_value_attribute_for_decl is to be used for variable
DECLs now.
(add_location_or_const_value_attribute): Use
tree_add_const_value_attribute_for_decl now.
(dwarf2out_finish): Emit the DW_AT_const_value attribute of
DW_TAG_template_value_param DIEs after function DIEs have been
emitted.
* langhooks.h (lang_hooks_for_types): Add
get_argument_pack_elems.
(lang_hooks_for_decls): Add generic_generic_parameter_decl_p.
(lang_hooks): Added get_innermost_generic_parms,
get_innermost_generic_args.
* langhooks-def.h (LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS,
LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS,
LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS,
LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P): New language hooks.
2009-08-31 DJ Delorie <dj@redhat.com> 2009-08-31 DJ Delorie <dj@redhat.com>
* config/mep/mep.c (machine_function): Add frame_locked flag. Set * config/mep/mep.c (machine_function): Add frame_locked flag. Set
...@@ -11,6 +55,7 @@ ...@@ -11,6 +55,7 @@
(mep_return_in_memory): Zero-sized objects are passed in memory. (mep_return_in_memory): Zero-sized objects are passed in memory.
(mep_reorg_noframe): Make sure we have accurate REG_DEAD notes. (mep_reorg_noframe): Make sure we have accurate REG_DEAD notes.
2009-08-31 Richard Guenther <rguenther@suse.de> 2009-08-31 Richard Guenther <rguenther@suse.de>
* builtins.c (fold_builtin_memory_op): Use the alias oracle * builtins.c (fold_builtin_memory_op): Use the alias oracle
......
...@@ -493,6 +493,29 @@ cgraph_node (tree decl) ...@@ -493,6 +493,29 @@ cgraph_node (tree decl)
return node; return node;
} }
/* Returns the cgraph node assigned to DECL or NULL if no cgraph node
is assigned. */
struct cgraph_node *
cgraph_get_node (tree decl)
{
struct cgraph_node key, *node = NULL, **slot;
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
if (!cgraph_hash)
cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
key.decl = decl;
slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key,
NO_INSERT);
if (slot && *slot)
node = *slot;
return node;
}
/* Insert already constructed node into hashtable. */ /* Insert already constructed node into hashtable. */
void void
......
...@@ -388,6 +388,8 @@ void cgraph_node_remove_callees (struct cgraph_node *node); ...@@ -388,6 +388,8 @@ void cgraph_node_remove_callees (struct cgraph_node *node);
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
struct cgraph_node *, struct cgraph_node *,
gimple, gcov_type, int, int); gimple, gcov_type, int, int);
struct cgraph_node * cgraph_get_node (tree);
struct cgraph_node *cgraph_node (tree); struct cgraph_node *cgraph_node (tree);
struct cgraph_node *cgraph_node_for_asm (tree asmname); struct cgraph_node *cgraph_node_for_asm (tree asmname);
struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple); struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple);
......
2009-08-31 Dodji Seketeli <dodji@redhat.com>
PR debug/30161
* cp-tree.h (get_template_info): Parameter should be const.
(CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P): Fix typo.
(get_template_argument_pack_elems,
get_primary_template_innermost_parameters,
get_template_innermost_arguments, template_template_parameter_p):
Declare ...
* pt.c (get_template_argument_pack_elems,
get_template_innermost_parameters, get_template_innermost_arguments,
template_template_parameter_p):
... New C++ front end implementation of new language hooks.
(primary_template_instantiation_p): New private helper.
(make_ith_pack_parameter_name): Use snprintf and strnlen instead of
printf and strlen.
(get_template_info): Const-ify parameter.
* cp-lang.c (LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS,
LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS,
LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS,
LANG_HOOKS_GENERIC_TYPE_PARAMETER_DECL_P): Initialize these
interfaces for the C++ front-end.
2009-08-31 Jason Merrill <jason@redhat.com> 2009-08-31 Jason Merrill <jason@redhat.com>
PR c++/41127 PR c++/41127
......
...@@ -49,6 +49,20 @@ static enum classify_record cp_classify_record (tree type); ...@@ -49,6 +49,20 @@ static enum classify_record cp_classify_record (tree type);
#define LANG_HOOKS_CLASSIFY_RECORD cp_classify_record #define LANG_HOOKS_CLASSIFY_RECORD cp_classify_record
#undef LANG_HOOKS_GENERIC_TYPE_P #undef LANG_HOOKS_GENERIC_TYPE_P
#define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p #define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p
#undef LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS
#define LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS \
get_primary_template_innermost_parameters
#undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS
#define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \
get_template_innermost_arguments
#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_DECL_PRINTABLE_NAME #undef LANG_HOOKS_DECL_PRINTABLE_NAME
#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name #define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
#undef LANG_HOOKS_DWARF_NAME #undef LANG_HOOKS_DWARF_NAME
......
...@@ -3283,7 +3283,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) ...@@ -3283,7 +3283,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P(NODE) \ #define CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P(NODE) \
(CLASS_TYPE_P (NODE) \ (CLASS_TYPE_P (NODE) \
&& CLASSTYPE_USE_TEMPLATE (NODE) \ && CLASSTYPE_USE_TEMPLATE (NODE) \
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (arg))) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))
#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1) #define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1)
#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \ #define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
...@@ -4638,7 +4638,7 @@ extern bool uses_parameter_packs (tree); ...@@ -4638,7 +4638,7 @@ extern bool uses_parameter_packs (tree);
extern bool template_parameter_pack_p (const_tree); extern bool template_parameter_pack_p (const_tree);
extern tree make_pack_expansion (tree); extern tree make_pack_expansion (tree);
extern bool check_for_bare_parameter_packs (tree); extern bool check_for_bare_parameter_packs (tree);
extern tree get_template_info (tree); extern tree get_template_info (const_tree);
extern tree get_types_needing_access_check (tree); extern tree get_types_needing_access_check (tree);
extern int template_class_depth (tree); extern int template_class_depth (tree);
extern int is_specialization_of (tree, tree); extern int is_specialization_of (tree, tree);
...@@ -4680,6 +4680,10 @@ extern bool explicit_class_specialization_p (tree); ...@@ -4680,6 +4680,10 @@ extern bool explicit_class_specialization_p (tree);
extern struct tinst_level *outermost_tinst_level(void); extern struct tinst_level *outermost_tinst_level(void);
extern bool parameter_of_template_p (tree, tree); extern bool parameter_of_template_p (tree, tree);
extern void init_template_processing (void); extern void init_template_processing (void);
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);
/* in repo.c */ /* in repo.c */
extern void init_repo (void); extern void init_repo (void);
......
...@@ -191,6 +191,7 @@ static tree tsubst_decl (tree, tree, tsubst_flags_t); ...@@ -191,6 +191,7 @@ static tree tsubst_decl (tree, tree, tsubst_flags_t);
static void perform_typedefs_access_check (tree tmpl, tree targs); static void perform_typedefs_access_check (tree tmpl, tree targs);
static void append_type_to_template_for_access_check_1 (tree, tree, tree); static void append_type_to_template_for_access_check_1 (tree, tree, tree);
static hashval_t iterative_hash_template_arg (tree arg, hashval_t val); static hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
static bool primary_template_instantiation_p (const_tree);
/* Make the current scope suitable for access checking when we are /* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function processing T. T can be FUNCTION_DECL for instantiated function
...@@ -287,7 +288,7 @@ finish_member_template_decl (tree decl) ...@@ -287,7 +288,7 @@ finish_member_template_decl (tree decl)
/* Return the template info node corresponding to T, whatever T is. */ /* Return the template info node corresponding to T, whatever T is. */
tree tree
get_template_info (tree t) get_template_info (const_tree t)
{ {
tree tinfo = NULL_TREE; tree tinfo = NULL_TREE;
...@@ -2660,15 +2661,90 @@ static tree ...@@ -2660,15 +2661,90 @@ static tree
make_ith_pack_parameter_name (tree name, int i) make_ith_pack_parameter_name (tree name, int i)
{ {
/* Munge the name to include the parameter index. */ /* Munge the name to include the parameter index. */
char numbuf[128]; #define NUMBUF_LEN 128
char numbuf[NUMBUF_LEN];
char* newname; char* newname;
int newname_len;
sprintf(numbuf, "%i", i);
newname = (char*)alloca (IDENTIFIER_LENGTH (name) + strlen(numbuf) + 2); snprintf (numbuf, NUMBUF_LEN, "%i", i);
sprintf(newname, "%s#%i", IDENTIFIER_POINTER (name), i); newname_len = IDENTIFIER_LENGTH (name)
+ strnlen (numbuf, NUMBUF_LEN) + 2;
newname = (char*)alloca (newname_len);
snprintf (newname, newname_len,
"%s#%i", IDENTIFIER_POINTER (name), i);
return get_identifier (newname); return get_identifier (newname);
} }
/* Return true if T is a primary function
or class template instantiation. */
static bool
primary_template_instantiation_p (const_tree t)
{
if (!t)
return false;
if (TREE_CODE (t) == FUNCTION_DECL)
return DECL_LANG_SPECIFIC (t)
&& DECL_TEMPLATE_INSTANTIATION (t)
&& PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t));
else if (CLASS_TYPE_P (t))
return CLASSTYPE_TEMPLATE_INSTANTIATION (t)
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t));
return false;
}
/* Return true if PARM is a template template parameter. */
bool
template_template_parameter_p (const_tree parm)
{
return DECL_TEMPLATE_TEMPLATE_PARM_P (parm);
}
/* Return the template parameters of T if T is a
primary template instantiation, NULL otherwise. */
tree
get_primary_template_innermost_parameters (const_tree t)
{
tree parms = NULL, template_info = NULL;
if ((template_info = get_template_info (t))
&& primary_template_instantiation_p (t))
parms = INNERMOST_TEMPLATE_PARMS
(DECL_TEMPLATE_PARMS (TI_TEMPLATE (template_info)));
return parms;
}
/* Returns the template arguments of T if T is a template instantiation,
NULL otherwise. */
tree
get_template_innermost_arguments (const_tree t)
{
tree args = NULL, template_info = NULL;
if ((template_info = get_template_info (t))
&& TI_ARGS (template_info))
args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (template_info));
return args;
}
/* Return the arguments pack of T if T is a template, NULL otherwise. */
tree
get_template_argument_pack_elems (const_tree t)
{
if (TREE_CODE (t) != TYPE_ARGUMENT_PACK
&& TREE_CODE (t) != NONTYPE_ARGUMENT_PACK)
return NULL;
return ARGUMENT_PACK_ARGS (t);
}
/* Structure used to track the progress of find_parameter_packs_r. */ /* Structure used to track the progress of find_parameter_packs_r. */
struct find_parameter_pack_data struct find_parameter_pack_data
{ {
......
...@@ -153,6 +153,10 @@ extern tree lhd_make_node (enum tree_code); ...@@ -153,6 +153,10 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_CLASSIFY_RECORD NULL #define LANG_HOOKS_CLASSIFY_RECORD NULL
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
#define LANG_HOOKS_GENERIC_TYPE_P hook_bool_const_tree_false #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_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_TYPE_PROMOTES_TO lhd_type_promotes_to #define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
#define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_const_tree #define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_const_tree
...@@ -170,6 +174,7 @@ extern tree lhd_make_node (enum tree_code); ...@@ -170,6 +174,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_TYPE_FOR_MODE, \ LANG_HOOKS_TYPE_FOR_MODE, \
LANG_HOOKS_TYPE_FOR_SIZE, \ LANG_HOOKS_TYPE_FOR_SIZE, \
LANG_HOOKS_GENERIC_TYPE_P, \ LANG_HOOKS_GENERIC_TYPE_P, \
LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS, \
LANG_HOOKS_TYPE_PROMOTES_TO, \ LANG_HOOKS_TYPE_PROMOTES_TO, \
LANG_HOOKS_REGISTER_BUILTIN_TYPE, \ LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \ LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
...@@ -206,6 +211,7 @@ extern tree lhd_make_node (enum tree_code); ...@@ -206,6 +211,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_PUSHDECL, \ LANG_HOOKS_PUSHDECL, \
LANG_HOOKS_GETDECLS, \ LANG_HOOKS_GETDECLS, \
LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \ LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \
LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \ LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
LANG_HOOKS_WRITE_GLOBALS, \ LANG_HOOKS_WRITE_GLOBALS, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \ LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
...@@ -259,6 +265,8 @@ extern tree lhd_make_node (enum tree_code); ...@@ -259,6 +265,8 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_TREE_DUMP_INITIALIZER, \ LANG_HOOKS_TREE_DUMP_INITIALIZER, \
LANG_HOOKS_DECLS, \ LANG_HOOKS_DECLS, \
LANG_HOOKS_FOR_TYPES_INITIALIZER, \ LANG_HOOKS_FOR_TYPES_INITIALIZER, \
LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS, \
LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS, \
LANG_HOOKS_GIMPLIFY_EXPR, \ LANG_HOOKS_GIMPLIFY_EXPR, \
LANG_HOOKS_FOLD_OBJ_TYPE_REF, \ LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
LANG_HOOKS_BUILTIN_FUNCTION, \ LANG_HOOKS_BUILTIN_FUNCTION, \
......
...@@ -91,6 +91,9 @@ struct lang_hooks_for_types ...@@ -91,6 +91,9 @@ struct lang_hooks_for_types
e.g. C++ template implicit specializations. */ e.g. C++ template implicit specializations. */
bool (*generic_p) (const_tree); bool (*generic_p) (const_tree);
/* Returns the TREE_VEC of elements of a given generic argument pack. */
tree (*get_argument_pack_elems) (const_tree);
/* Given a type, apply default promotions to unnamed function /* Given a type, apply default promotions to unnamed function
arguments and return the new type. Return the same type if no arguments and return the new type. Return the same type if no
change. Required by any language that supports variadic change. Required by any language that supports variadic
...@@ -165,6 +168,10 @@ struct lang_hooks_for_decls ...@@ -165,6 +168,10 @@ struct lang_hooks_for_decls
/* Returns true if DECL is explicit member function. */ /* Returns true if DECL is explicit member function. */
bool (*function_decl_explicit_p) (tree); bool (*function_decl_explicit_p) (tree);
/* Returns True if the parameter is a generic parameter decl
of a generic type, e.g a template template parameter for the C++ FE. */
bool (*generic_generic_parameter_decl_p) (const_tree);
/* Returns true when we should warn for an unused global DECL. /* Returns true when we should warn for an unused global DECL.
We will already have checked that it has static binding. */ We will already have checked that it has static binding. */
bool (*warn_unused_global) (const_tree); bool (*warn_unused_global) (const_tree);
...@@ -380,6 +387,14 @@ struct lang_hooks ...@@ -380,6 +387,14 @@ struct lang_hooks
struct lang_hooks_for_types types; struct lang_hooks_for_types types;
/* Retuns the generic parameters of an instantiation of
a generic type or decl, e.g. C++ template instantiation. */
tree (*get_innermost_generic_parms) (const_tree);
/* Returns the TREE_VEC of arguments of an instantiation
of a generic type of decl, e.g. C++ template instantiation. */
tree (*get_innermost_generic_args) (const_tree);
/* Perform language-specific gimplification on the argument. Returns an /* Perform language-specific gimplification on the argument. Returns an
enum gimplify_status, though we can't see that type here. */ enum gimplify_status, though we can't see that type here. */
int (*gimplify_expr) (tree *, gimple_seq *, gimple_seq *); int (*gimplify_expr) (tree *, gimple_seq *, gimple_seq *);
......
2009-08-31 Dodji Seketeli <dodji@redhat.com>
PR debug/30161
* g++.dg/debug/dwarf2/template-params-1.C: New test.
* g++.dg/debug/dwarf2/template-params-2.C: Likewise.
* g++.dg/debug/dwarf2/template-params-3.C: Likewise.
* g++.dg/debug/dwarf2/template-params-4.C: Likewise.
* g++.dg/debug/dwarf2/template-params-5.C: Likewise.
* g++.dg/debug/dwarf2/template-params-6.C: Likewise.
* g++.dg/debug/dwarf2/template-func-params-1.C: Likewise.
* g++.dg/debug/dwarf2/template-func-params-2.C: Likewise.
* g++.dg/debug/dwarf2/template-func-params-3.C: Likewise.
* g++.dg/debug/dwarf2/template-func-params-4.C: Likewise.
* g++.dg/debug/dwarf2/template-func-params-5.C: Likewise.
* g++.dg/debug/dwarf2/template-func-params-6.C: Likewise.
* g++.dg/debug/dwarf2/template-func-params-7.C: Likewise.
2009-08-31 Jason Merrill <jason@redhat.com> 2009-08-31 Jason Merrill <jason@redhat.com>
PR c++/41127 PR c++/41127
......
// Contributed by Dodji Seketeli <dodji@redhat.com>
// origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-do compile }
// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
// { dg-final { scan-assembler "U.*DW_AT_name" } }
template <class U>
U
func(U m)
{
return m;
}
int i = func<int>(2);
// Contributed by Dodji Seketeli <dodji@redhat.com>
// origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-do compile }
// { dg-final { scan-assembler "DW_TAG_template_value_param" } }
// { dg-final { scan-assembler "i.*DW_AT_name" } }
// { dg-final { scan-assembler "3.*DW_AT_const_value" } }
template <int i>
int
func()
{
int j = i;
return j;
}
const int foo = 1;
const int bar = 2;
int h = func<foo+bar>();
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-final { scan-assembler "DW_TAG_template_value_param" } }
// { dg-final { scan-assembler "f.*DW_AT_name" } }
// { dg-final { scan-assembler "_Z4blehv.*DW_AT_const_value" } }
typedef void (*func_ptr)();
template <func_ptr f>
int
func()
{
f();
return 0;
}
void
bleh()
{
}
int c = func<bleh>();
// 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" } }
template <typename... Args> struct count;
template <>
struct count<>
{
static const int value = 0;
};
template <typename T, typename... Args>
struct count<T, Args...>
{
static const int value = 1 + count<Args...>::value;
};
template<typename... P>
int
do_count()
{
return count<P...>::value;
}
int c = do_count<int, char, long>();
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
// { dg-final { scan-assembler "T.*DW_AT_name" } }
template <class T>
struct vector
{
int size;
vector () : size (0)
{
}
};
template<template <class T> class U>
int
bar()
{
U<int> u;
return u.size;
}
vector<int> v;
int j = bar<vector>();
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-final { scan-assembler-times "DW_TAG_GNU_template_template_param" 2 } }
// { dg-final { scan-assembler-times "DW_AT_GNU_template_name: \"vector\"" 1 } }
// { dg-final { scan-assembler-times ".ascii \"U.0\".*?DW_AT_name" 1 } }
template <class T>
struct vector_base
{
static int get_sizeof_t()
{
return 0;
}
};
template <class T>
struct vector : public vector_base<T>
{
static int get_sizeof_t()
{
return sizeof (T);
}
T member1;
T member2;
};
template <template <class T> class U>
int
bar()
{
return U<int>::get_sizeof_t();
}
int i = bar<vector>();
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-g -dA -std=c++0x" }
// { dg-do compile }
// There must be 5 subprograms generated:
// printf(const char*), printf<int, char, int>,
// printf<char, int>, printf<int> and foo().
// { dg-final {scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_subprogram" 5 } }
// That makes 6 template type parameters.
// { dg-final {scan-assembler-times "DIE \\(0x.*?\\) DW_TAG_template_type_param" 6 } }
// { dg-final {scan-assembler-times "DW_AT_name: \"printf<int, char, int>\"" 1 } }
// { dg-final {scan-assembler-times "DW_AT_name: \"printf<char, int>\"" 1 } }
// { dg-final {scan-assembler-times "DW_AT_name: \"printf<int>\"" 1 } }
// { dg-final {scan-assembler-times "DW_AT_name: \"printf\"" 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 "DW_AT_name: \"args#0\"" 2 } }
// { dg-final {scan-assembler-times "DW_AT_name: \"PackTypes#1\"" 1 } }
// { dg-final {scan-assembler-times "DW_AT_name: \"args#1\"" 1 } }
// { dg_final {scan-assembler-times "\.ascii \"T.0\"\[\t \]+.*?DW_AT_name" 3 } }
void
printf(const char* s)
{
/* Commented this to not pull std::cout into what should be
a simple test.
while (*s)
std::cout << *s++;
*/
}
template<typename T, typename... PackTypes>
void
printf(const char* s,
T value,
PackTypes... args)
{
while (*s)
{
if (*s == '%' && *++s != '%')
{
/* std::cout << value; */
return printf(++s, args...);
}
}
}
void
foo ()
{
int x;
printf("%c %d", x, 'x', 3);
}
// Contributed by Dodji Seketeli <dodji@redhat.com>
// origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-do compile }
// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
// { dg-final { scan-assembler "U.*DW_AT_name" } }
template <class U>
class A
{
U m;
};
A<int> a;
// Contributed by Dodji Seketeli <dodji@redhat.com>
// origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-do compile }
// { dg-final { scan-assembler "DW_TAG_template_value_param" } }
// { dg-final { scan-assembler "i.*DW_AT_name" } }
// { dg-final { scan-assembler "3.*DW_AT_const_value" } }
template <int i>
struct A
{
int m;
A ()
{
m = i;
}
};
const int foo = 1;
const int bar = 2;
A<foo+bar> a;
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-final { scan-assembler "DW_TAG_template_value_param" } }
// { dg-final { scan-assembler "f.*DW_AT_name" } }
// { dg-final { scan-assembler "_Z4blehv.*DW_AT_const_value" } }
typedef void (*func_ptr) ();
template <func_ptr f>
struct A
{
A ()
{
f ();
}
};
void
bleh ()
{
}
A<bleh> a;
// 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" } }
template <typename... Args> struct count;
template <>
struct count<>
{
static const int value = 0;
};
template <typename T, typename... Args>
struct count<T, Args...>
{
static const int value = 1 + count<Args...>::value;
};
int
foo ()
{
count<int, char, long> c;
int nb = count<int, char, long>::value;
return nb;
}
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-final { scan-assembler "DW_TAG_template_type_param" } }
// { dg-final { scan-assembler "T.*DW_AT_name" } }
template <class T>
struct vector
{
int size;
vector () : size (0)
{
}
};
template<template <class T> class U>
struct bar
{
U<int> u;
int m;
bar () : m (u.size)
{
}
};
vector<int> v;
bar<vector> b;
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR debug/30161
// { dg-options "-g -dA" }
// { dg-final { scan-assembler-times "DW_TAG_GNU_template_template_param" 2 } }
// { dg-final { scan-assembler-times "DW_AT_GNU_template_name: \"vector\"" 1 } }
// { dg-final { scan-assembler-times ".ascii \"U.0\".*?DW_AT_name" 1 } }
template <class T>
struct vector_base
{
T tab[3 + 1];
static int get_sizeof_t()
{
return sizeof (tab);
}
};
template <class T>
struct vector : public vector_base<T>
{
static int get_sizeof_t()
{
return sizeof (T);
}
T member1;
T member2;
};
template <template <class T> class U>
struct bar
{
int foo()
{
return U<int>::get_sizeof_t ();
}
};
int
foo_func ()
{
bar<vector> b;
return b.foo ();
}
...@@ -210,6 +210,9 @@ enum dwarf_tag ...@@ -210,6 +210,9 @@ enum dwarf_tag
DW_TAG_class_template = 0x4103, /* For C++. */ DW_TAG_class_template = 0x4103, /* For C++. */
DW_TAG_GNU_BINCL = 0x4104, DW_TAG_GNU_BINCL = 0x4104,
DW_TAG_GNU_EINCL = 0x4105, DW_TAG_GNU_EINCL = 0x4105,
/* Template template parameter.
See http://gcc.gnu.org/wiki/TemplateParmsDwarf . */
DW_TAG_GNU_template_template_param = 0x4106,
/* Extensions for UPC. See: http://upc.gwu.edu/~upc. */ /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
DW_TAG_upc_shared_type = 0x8765, DW_TAG_upc_shared_type = 0x8765,
DW_TAG_upc_strict_type = 0x8766, DW_TAG_upc_strict_type = 0x8766,
...@@ -390,6 +393,9 @@ enum dwarf_attribute ...@@ -390,6 +393,9 @@ enum dwarf_attribute
DW_AT_body_begin = 0x2105, DW_AT_body_begin = 0x2105,
DW_AT_body_end = 0x2106, DW_AT_body_end = 0x2106,
DW_AT_GNU_vector = 0x2107, DW_AT_GNU_vector = 0x2107,
/* Template template argument name.
See http://gcc.gnu.org/wiki/TemplateParmsDwarf . */
DW_AT_GNU_template_name = 0x2110,
/* VMS extensions. */ /* VMS extensions. */
DW_AT_VMS_rtnbeg_pd_address = 0x2201, DW_AT_VMS_rtnbeg_pd_address = 0x2201,
/* UPC extension. */ /* UPC extension. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment