diff mbox

PR debug/49348 (DW_TAG_template_* missing from template specializations)

Message ID m3mxhpfs7u.fsf@redhat.com
State New
Headers show

Commit Message

Dodji Seketeli June 10, 2011, 6:37 p.m. UTC
Hello,

For a given template instantiation, the dwarf backend emits debug info
that describes its template parameters and arguments if generic_type_p
returns TRUE on the the instantiation.  For that,
primary_template_instantiation_p must be also return TRUE.

The problem in this PR is that primary_template_instantiation_p doesn't
return TRUE for explicit specializations.  This patch makes it return
TRUE for explicit specializations and instantiations of a primary
template.

I have renamed the function primary_template_instantiation_p into
primary_template_specialization_p, as [temp.spec]/4 reads:

    A specialization is a class, function, or class member that is
    either instantiated or explicitly specialized

Tested on x86_64-unknown-linux-gnu against trunk.

gcc/cp/

	* cp-tree.h (primary_template_specialization_p): Rename
	primary_template_instantiatiation_p into this.
	* pt.c (primary_template_specialization_p): Likewise.  Don't rule
	out explicit template specializations.
	(get_function_template_decl)
	(get_primary_template_innermost_parameters): Adjust.
	* call.c (non_placement_deallocation_fn_p): Adjust.

gcc/testsuite/

	* g++.dg/debug/dwarf2/typedef1.C: Adjust to test that a
	DW_TAG_template_value_param DIE is emitted.
---
 gcc/cp/call.c                                |    2 +-
 gcc/cp/cp-tree.h                             |    2 +-
 gcc/cp/pt.c                                  |   11 +++++------
 gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C |    1 +
 4 files changed, 8 insertions(+), 8 deletions(-)

Comments

Jason Merrill June 10, 2011, 6:46 p.m. UTC | #1
Hmm, I'm not sure about this; it seems to me that we want to know about 
the actual parameters that a particular specialization has, which in the 
case of an explicit specialization is none.  Or for a partial 
specialization,

template <class T> struct A;
template <class T> struct A<T*> { }
A<int*> a;

here A<int*> has a type parameter named T, with the value 'int'.  It 
would be very surprising for T to resolve to int* in the debugger when 
it resolves to int in the body of A<T*>.

Which suggests that perhaps we want to leave the template arguments in 
the name after all.

Jason
diff mbox

Patch

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4ee0eaf..51a2a2c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5183,7 +5183,7 @@  non_placement_deallocation_fn_p (tree t)
   /* A template instance is never a usual deallocation function,
      regardless of its signature.  */
   if (TREE_CODE (t) == TEMPLATE_DECL
-      || primary_template_instantiation_p (t))
+      || primary_template_specialization_p (t))
     return false;
 
   /* If a class T has a member deallocation function named operator delete
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 06b5926..aef7053 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5200,7 +5200,7 @@  extern bool parameter_of_template_p		(tree, tree);
 extern void init_template_processing		(void);
 extern void print_template_statistics		(void);
 bool template_template_parameter_p		(const_tree);
-extern bool primary_template_instantiation_p    (const_tree);
+extern bool primary_template_specialization_p   (const_tree);
 extern tree get_primary_template_innermost_parameters	(const_tree);
 extern tree get_template_parms_at_level (tree, int);
 extern tree get_template_innermost_arguments	(const_tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 814a08f..01bafe8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2760,7 +2760,7 @@  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))
+      || ! primary_template_specialization_p (primary_func_tmpl_inst))
     return NULL;
 
   return DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (primary_func_tmpl_inst));
@@ -2829,18 +2829,17 @@  make_ith_pack_parameter_name (tree name, int i)
    or class template instantiation.  */
 
 bool
-primary_template_instantiation_p (const_tree t)
+primary_template_specialization_p (const_tree t)
 {
   if (!t)
     return false;
 
   if (TREE_CODE (t) == FUNCTION_DECL)
     return DECL_LANG_SPECIFIC (t)
-	   && DECL_TEMPLATE_INSTANTIATION (t)
+	   && DECL_USE_TEMPLATE (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 CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (t);
   return false;
 }
 
@@ -2861,7 +2860,7 @@  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))
+      && primary_template_specialization_p (t))
     parms = INNERMOST_TEMPLATE_PARMS
 	(DECL_TEMPLATE_PARMS (TI_TEMPLATE (template_info)));
 
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C b/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C
index a9ce44d..38a6753 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C
@@ -9,6 +9,7 @@ 
 // { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_enumeration_type" 1 } }
 // { dg-final { scan-assembler-times "\"e0..\"\[^\n\]*DW_AT_name" 1 } }
 // { dg-final { scan-assembler-times "\"e1..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "DIE \\(0x\[^\n\r\]*\\) DW_TAG_template_value_param" 1 } }
 
 template <unsigned int n>
 struct foo