re PR debug/47510 (DW_TAG_typedef can have children when designating a naming typedef)
authorDodji Seketeli <dodji@redhat.com>
Wed, 16 Mar 2011 21:04:58 +0000 (21:04 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Wed, 16 Mar 2011 21:04:58 +0000 (22:04 +0100)
PR debug/47510

gcc/

PR debug/47510
* dwarf2out.c (strip_naming_typedef): Factorize out of ...
(lookup_type_die_strip_naming_typedef): ... here.
(get_context_die): Use it.
(gen_typedef_die): Add a DW_AT_{,MIPS_}linkage_name attribute to
the anonymous struct named by the naming typedef.

gcc/testsuite/

        PR debug/47510
* g++.dg/debug/dwarf2/typedef6.C: New test.

From-SVN: r171073

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C [new file with mode: 0644]

index 10a154899b455a680f14a4ccddd5cabe21f049d7..8ab1bd0a3f6b67423b0586e149de0b22202a8367 100644 (file)
@@ -1,3 +1,12 @@
+2011-03-16  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/47510
+       * dwarf2out.c (strip_naming_typedef): Factorize out of ...
+       (lookup_type_die_strip_naming_typedef): ... here.
+       (get_context_die): Use it.
+       (gen_typedef_die): Add a DW_AT_{,MIPS_}linkage_name attribute to
+       the anonymous struct named by the naming typedef.
+
 2011-03-16  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/48154
index 733c849396d4e2cf9df5f8aa618b3428cbb84d0b..b28025fcdf7d0556d2284187ce091377e25a4b5c 100644 (file)
@@ -6341,6 +6341,7 @@ static void remove_child_TAG (dw_die_ref, enum dwarf_tag);
 static void add_child_die (dw_die_ref, dw_die_ref);
 static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
 static dw_die_ref lookup_type_die (tree);
+static dw_die_ref strip_naming_typedef (tree, dw_die_ref);
 static dw_die_ref lookup_type_die_strip_naming_typedef (tree);
 static void equate_type_number_to_die (tree, dw_die_ref);
 static hashval_t decl_die_table_hash (const void *);
@@ -8129,6 +8130,22 @@ lookup_type_die (tree type)
   return TYPE_SYMTAB_DIE (type);
 }
 
+/* Given a TYPE_DIE representing the type TYPE, if TYPE is an
+   anonymous type named by the typedef TYPE_DIE, return the DIE of the
+   anonymous type instead the one of the naming typedef.  */
+
+static inline dw_die_ref
+strip_naming_typedef (tree type, dw_die_ref type_die)
+{
+  if (type
+      && TREE_CODE (type) == RECORD_TYPE
+      && type_die
+      && type_die->die_tag == DW_TAG_typedef
+      && is_naming_typedef_decl (TYPE_NAME (type)))
+    type_die = get_AT_ref (type_die, DW_AT_type);
+  return type_die;
+}
+
 /* Like lookup_type_die, but if type is an anonymous type named by a
    typedef[1], return the DIE of the anonymous type instead the one of
    the naming typedef.  This is because in gen_typedef_die, we did
@@ -8143,11 +8160,7 @@ static inline dw_die_ref
 lookup_type_die_strip_naming_typedef (tree type)
 {
   dw_die_ref die = lookup_type_die (type);
-  if (TREE_CODE (type) == RECORD_TYPE
-      && die->die_tag == DW_TAG_typedef
-      && is_naming_typedef_decl (TYPE_NAME (type)))
-    die = get_AT_ref (die, DW_AT_type);
-  return die;
+  return strip_naming_typedef (type, die);
 }
 
 /* Equate a DIE to a given type specifier.  */
@@ -20443,6 +20456,14 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
                 anonymous struct DIE.  */
              if (!TREE_ASM_WRITTEN (type))
                gen_tagged_type_die (type, context_die, DINFO_USAGE_DIR_USE);
+
+             /* This is a GNU Extension.  We are adding a
+                DW_AT_linkage_name attribute to the DIE of the
+                anonymous struct TYPE.  The value of that attribute
+                is the name of the typedef decl naming the anonymous
+                struct.  This greatly eases the work of consumers of
+                this debug info.  */
+             add_linkage_attr (lookup_type_die (type), decl);
            }
        }
 
@@ -20923,7 +20944,10 @@ get_context_die (tree context)
     {
       /* Find die that represents this context.  */
       if (TYPE_P (context))
-       return force_type_die (TYPE_MAIN_VARIANT (context));
+       {
+         context = TYPE_MAIN_VARIANT (context);
+         return strip_naming_typedef (context, force_type_die (context));
+       }
       else
        return force_decl_die (context);
     }
index 5685b45576c93eb7cbf9d0aa852fb29d796025c0..fd64f48e49b41c4fd3fa6f001e9a5f8fb3be7472 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-16  Dodji Seketeli  <dodji@redhat.com>
+
+       PR debug/47510
+       * ++.dg/debug/dwarf2/typedef6.C: New test.
+
 2011-03-16  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/elision2.C: New.
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C b/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C
new file mode 100644 (file)
index 0000000..8896446
--- /dev/null
@@ -0,0 +1,30 @@
+// Origin PR debug/
+// { dg-options "-g -dA" }
+
+class C {
+public:
+  C() {}
+  ~C() {}
+};
+typedef struct {
+  C m;
+} t;
+typedef t s;
+s v;
+
+/*
+  We want to check that we have a DIE describing the typedef t like this:
+
+       .uleb128 0xc    # (DIE (0xb8) DW_TAG_typedef)
+       .ascii "t\0"    # DW_AT_name
+       .byte   0x1     # DW_AT_decl_file (../../prtests/test.cc)
+       .byte   0xb     # DW_AT_decl_line
+       .long   0x78    # DW_AT_type
+
+  e.g, it should not haven any child DIE -- the bug here was that this
+  DIE had children DIEs. So we check that the last line is immediately
+  followed by a line containing the pattern "(DIE (", instead of a
+  line containing a DW_AT_sibling attribute.
+ */
+
+// { dg-final { scan-assembler-times "\[^\n\r\]*\\(DIE \[^\n\r\]* DW_TAG_typedef\\)\[\n\r\]{1,2}\[^\n\r\].*\"t\\\\0\"\[^\n\r\]*DW_AT_name\[\n\r\]{1,2}\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type\[\n\r\]{1,2}\[^\n\r\]*\\(DIE" 1 } }