Fix PR debug/46955
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Jan 2011 21:20:07 +0000 (21:20 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Jan 2011 21:20:07 +0000 (21:20 +0000)
gcc/cp/

* cp-lang.c (get_template_innermost_arguments_folded)
(get_template_argument_pack_elems_folded)
(template_arg_needs_folding, fold_cplus_constants): New static
functions.
(LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS): Set this hook to
get_template_innermost_arguments_folded.
(LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS): Set this hook to
get_template_argument_pack_elems_folded.

gcc/testsuite/

* g++.dg/debug/dwarf2/template-params-8.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168681 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-lang.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/template-params-8.C [new file with mode: 0644]

index ba3eca3..95b8d18 100644 (file)
@@ -1,3 +1,15 @@
+2011-01-11  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/46955
+       * cp-lang.c (get_template_innermost_arguments_folded)
+       (get_template_argument_pack_elems_folded)
+       (template_arg_needs_folding, fold_cplus_constants): New static
+       functions.
+       (LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS): Set this hook to
+       get_template_innermost_arguments_folded.
+       (LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS): Set this hook to
+       get_template_argument_pack_elems_folded.
+
 2011-01-11  Jason Merrill  <jason@redhat.com>
 
        PR c++/46658
index ff92666..e5c1c09 100644 (file)
@@ -38,6 +38,8 @@ static void cp_init_ts (void);
 static const char * cxx_dwarf_name (tree t, int verbosity);
 static enum classify_record cp_classify_record (tree type);
 static tree cp_eh_personality (void);
+static tree get_template_innermost_arguments_folded (const_tree);
+static tree get_template_argument_pack_elems_folded (const_tree);
 
 /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
    consequently, there should be very few hooks below.  */
@@ -56,13 +58,13 @@ static tree cp_eh_personality (void);
        get_primary_template_innermost_parameters
 #undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS
 #define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \
-       get_template_innermost_arguments
+       get_template_innermost_arguments_folded
 #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
+       get_template_argument_pack_elems_folded
 #undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P
 #define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \
        template_template_parameter_p
@@ -165,5 +167,76 @@ cp_eh_personality (void)
   return cp_eh_personality_decl;
 }
 
+/* This is a subroutine of fold_cplus_constants.  It returns TRUE if T
+   is a C++ specific constant that needs to be folded further before
+   being passed to the debug info emitter.  */
+
+static bool
+template_arg_needs_folding (const_tree t)
+{
+  /* For now only PTRMEM_CST nodes are to be folded further.  */
+  if (TREE_CODE (t) == PTRMEM_CST)
+    return true;
+  return false;
+}
+
+/* Fold the elements of the TREE_VEC C which are C++ specific nodes
+   that would need folding so that they can be processed by the debug
+   info emitter. This is a subroutine of
+   get_template_innermost_arguments_folded and
+   get_template_argument_pack_elems_folded.  */
+
+static tree
+fold_cplus_constants (const_tree c)
+{
+  tree folded_elems, elems = CONST_CAST_TREE (c);
+  int vec_len, i;
+
+  if (elems == NULL_TREE || elems == error_mark_node)
+    return elems;
+
+  vec_len = TREE_VEC_LENGTH (elems);
+
+  /* First check if there is at least one element that needs
+     folding. If there is none, we just return ELEMS. Otherwise create
+     and return a new tree vector that contains the folded versions of
+     ELEMS. This is to avoid allocating memory if we don't need
+     to.  */
+  for (i = 0; i < vec_len; ++i)
+    {
+      if (template_arg_needs_folding (TREE_VEC_ELT (elems, i)))
+       break;
+    }
+  if (i == vec_len)
+    return elems;
+
+  folded_elems = make_tree_vec (vec_len);
+  for (i = 0; i < vec_len; ++i)
+    {
+      tree elem = TREE_VEC_ELT (elems, i);
+      TREE_VEC_ELT (folded_elems, i) =  
+       (elem && !TYPE_P (elem)) ? cplus_expand_constant (elem) : elem;
+
+    }
+  return folded_elems;
+}
+
+/* The C++ implementation of the LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS
+   hook. It returns the innermost template arguments of type T, and
+   makes sure those arguments are folded enough for the debug info
+   emitter.  */
+
+static tree
+get_template_innermost_arguments_folded (const_tree t)
+{
+  return fold_cplus_constants (get_template_innermost_arguments (t));
+}
+
+static tree
+get_template_argument_pack_elems_folded (const_tree t)
+{
+  return fold_cplus_constants (get_template_argument_pack_elems (t));
+}
+
 #include "gt-cp-cp-lang.h"
 #include "gtype-cp.h"
index f9ec7ac..4671aae 100644 (file)
@@ -1,3 +1,8 @@
+2011-01-11  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/46955
+       * g++.dg/debug/dwarf2/template-params-8.C: New test.
+
 2011-01-11  Richard Henderson  <rth@redhat.com>
 
        * gcc-dg/tree-ssa/vrp47.c: Disable for mn10300 as well.
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/template-params-8.C b/gcc/testsuite/g++.dg/debug/dwarf2/template-params-8.C
new file mode 100644 (file)
index 0000000..db4e058
--- /dev/null
@@ -0,0 +1,15 @@
+// Origin PR debug/46955
+// { dg-options "-g -dA" }
+// { dg-do compile }
+
+struct S { int f; };
+template<int S::*MP> struct T { };
+T<&S::f> v;
+
+// For the type of v, we should have this DWARF generated:
+//     .uleb128 0x6    # (DIE (0x57) DW_TAG_template_value_param)
+//     .ascii "MP\0"   # DW_AT_name
+//     .long   0x61    # DW_AT_type
+//     .byte   0       # DW_AT_const_value
+// So let's look for that.
+// { dg-final { scan-assembler-times "\[^\n\r\]*DIE \\(\[^\n\r\]*\\) DW_TAG_template_value_param\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*DW_AT_name\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type\[\n\r\]{1,2}\[^\n\r\]*DW_AT_const_value\[\n\r\]{1,2}" 1 } }