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>
* 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>
* config/mep/mep.c (machine_function): Add frame_locked flag. Set
......@@ -11,6 +55,7 @@
(mep_return_in_memory): Zero-sized objects are passed in memory.
(mep_reorg_noframe): Make sure we have accurate REG_DEAD notes.
2009-08-31 Richard Guenther <rguenther@suse.de>
* builtins.c (fold_builtin_memory_op): Use the alias oracle
......
......@@ -493,6 +493,29 @@ cgraph_node (tree decl)
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. */
void
......
......@@ -388,6 +388,8 @@ void cgraph_node_remove_callees (struct cgraph_node *node);
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
struct cgraph_node *,
gimple, gcov_type, int, int);
struct cgraph_node * cgraph_get_node (tree);
struct cgraph_node *cgraph_node (tree);
struct cgraph_node *cgraph_node_for_asm (tree asmname);
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>
PR c++/41127
......
......@@ -49,6 +49,20 @@ static enum classify_record cp_classify_record (tree type);
#define LANG_HOOKS_CLASSIFY_RECORD cp_classify_record
#undef LANG_HOOKS_GENERIC_TYPE_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
#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
#undef LANG_HOOKS_DWARF_NAME
......
......@@ -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) \
(CLASS_TYPE_P (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 CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \
......@@ -4638,7 +4638,7 @@ extern bool uses_parameter_packs (tree);
extern bool template_parameter_pack_p (const_tree);
extern tree make_pack_expansion (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 int template_class_depth (tree);
extern int is_specialization_of (tree, tree);
......@@ -4680,6 +4680,10 @@ extern bool explicit_class_specialization_p (tree);
extern struct tinst_level *outermost_tinst_level(void);
extern bool parameter_of_template_p (tree, tree);
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 */
extern void init_repo (void);
......
......@@ -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 append_type_to_template_for_access_check_1 (tree, tree, tree);
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
processing T. T can be FUNCTION_DECL for instantiated function
......@@ -287,7 +288,7 @@ finish_member_template_decl (tree decl)
/* Return the template info node corresponding to T, whatever T is. */
tree
get_template_info (tree t)
get_template_info (const_tree t)
{
tree tinfo = NULL_TREE;
......@@ -2660,15 +2661,90 @@ static tree
make_ith_pack_parameter_name (tree name, int i)
{
/* Munge the name to include the parameter index. */
char numbuf[128];
#define NUMBUF_LEN 128
char numbuf[NUMBUF_LEN];
char* newname;
sprintf(numbuf, "%i", i);
newname = (char*)alloca (IDENTIFIER_LENGTH (name) + strlen(numbuf) + 2);
sprintf(newname, "%s#%i", IDENTIFIER_POINTER (name), i);
int newname_len;
snprintf (numbuf, NUMBUF_LEN, "%i", 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 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. */
struct find_parameter_pack_data
{
......
......@@ -153,6 +153,10 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_CLASSIFY_RECORD NULL
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
#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_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
#define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_const_tree
......@@ -170,6 +174,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_TYPE_FOR_MODE, \
LANG_HOOKS_TYPE_FOR_SIZE, \
LANG_HOOKS_GENERIC_TYPE_P, \
LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS, \
LANG_HOOKS_TYPE_PROMOTES_TO, \
LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
......@@ -206,6 +211,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_PUSHDECL, \
LANG_HOOKS_GETDECLS, \
LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P, \
LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P, \
LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
LANG_HOOKS_WRITE_GLOBALS, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
......@@ -259,6 +265,8 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_TREE_DUMP_INITIALIZER, \
LANG_HOOKS_DECLS, \
LANG_HOOKS_FOR_TYPES_INITIALIZER, \
LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS, \
LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS, \
LANG_HOOKS_GIMPLIFY_EXPR, \
LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
LANG_HOOKS_BUILTIN_FUNCTION, \
......
......@@ -91,6 +91,9 @@ struct lang_hooks_for_types
e.g. C++ template implicit specializations. */
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
arguments and return the new type. Return the same type if no
change. Required by any language that supports variadic
......@@ -165,6 +168,10 @@ struct lang_hooks_for_decls
/* Returns true if DECL is explicit member function. */
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.
We will already have checked that it has static binding. */
bool (*warn_unused_global) (const_tree);
......@@ -380,6 +387,14 @@ struct lang_hooks
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
enum gimplify_status, though we can't see that type here. */
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>
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
DW_TAG_class_template = 0x4103, /* For C++. */
DW_TAG_GNU_BINCL = 0x4104,
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. */
DW_TAG_upc_shared_type = 0x8765,
DW_TAG_upc_strict_type = 0x8766,
......@@ -390,6 +393,9 @@ enum dwarf_attribute
DW_AT_body_begin = 0x2105,
DW_AT_body_end = 0x2106,
DW_AT_GNU_vector = 0x2107,
/* Template template argument name.
See http://gcc.gnu.org/wiki/TemplateParmsDwarf . */
DW_AT_GNU_template_name = 0x2110,
/* VMS extensions. */
DW_AT_VMS_rtnbeg_pd_address = 0x2201,
/* 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