Hello,

In the example of the patch below, the DIE for the definition of the
class 'Executor', when put in the type unit section is not put under
the DIE for the 'thread' namespace.  Rather, it's put under the DIE
for the global namespace.

One thing to note is that the DIE for the declaration of 'Executor'
(the DIE that has a DW_AT_declaration attribute, and which is referred
to by the DW_AT_specification attribute of the DIE for the definition
of 'Executor') is correctly positioned as a children of the DIE for
the 'thread' namespace.

My understanding is that during the moving of a given type DIE into
its type unit section, we correctly move the declaration DIE of that
type along with its ancestor tree, but we fail to do the same for the
definition DIE.  For the later, we just omit its ancestor DIE in the
process.

Fixed thus, bootstrapped and tested on x86_64-unknown-linux-gnu
against trunk.

gcc/

        PR debug/45682
        * dwarf2out.c (copy_declaration_context): Return the copied DIE.
        (break_out_comdat_types): Move the definition DIE to under the
        same DIE as the declaration DIE.

gcc/testsuite/

        PR debug/45682
        * g++.dg/debug/dwarf2/nested-3.C: New test.
---
 gcc/dwarf2out.c                              |   13 ++++++----
 gcc/testsuite/g++.dg/debug/dwarf2/nested-3.C |   34 ++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/nested-3.C

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 850eb55..96c247c 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3302,7 +3302,7 @@ static int should_move_die_to_comdat (dw_die_ref);
 static dw_die_ref clone_as_declaration (dw_die_ref);
 static dw_die_ref clone_die (dw_die_ref);
 static dw_die_ref clone_tree (dw_die_ref);
-static void copy_declaration_context (dw_die_ref, dw_die_ref);
+static dw_die_ref copy_declaration_context (dw_die_ref, dw_die_ref);
 static void generate_skeleton_ancestor_tree (skeleton_chain_node *);
 static void generate_skeleton_bottom_up (skeleton_chain_node *);
 static dw_die_ref generate_skeleton (dw_die_ref);
@@ -7075,11 +7075,11 @@ clone_as_declaration (dw_die_ref die)
    AT_specification attribute, it also includes attributes and children
    attached to the specification.  */
 
-static void
+static dw_die_ref
 copy_declaration_context (dw_die_ref unit, dw_die_ref die)
 {
   dw_die_ref decl;
-  dw_die_ref new_decl;
+  dw_die_ref new_decl = NULL;
 
   decl = get_AT_ref (die, DW_AT_specification);
   if (decl == NULL)
@@ -7118,6 +7118,7 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die)
           add_AT_specification (die, new_decl);
         }
     }
+  return new_decl ;
 }
 
 /* Generate the skeleton ancestor tree for the given NODE, then clone
@@ -7247,7 +7248,7 @@ break_out_comdat_types (dw_die_ref die)
     next = (c == first ? NULL : c->die_sib);
     if (should_move_die_to_comdat (c))
       {
-        dw_die_ref replacement;
+        dw_die_ref replacement, copied = NULL;
        comdat_type_node_ref type_node;
 
         /* Create a new type unit DIE as the root for the new tree, and
@@ -7265,7 +7266,7 @@ break_out_comdat_types (dw_die_ref die)
 
         /* Copy the declaration context, attributes, and children of the
            declaration into the new compile unit DIE.  */
-       copy_declaration_context (unit, c);
+       copied = copy_declaration_context (unit, c);
 
         /* Remove this DIE from the main CU.  */
        replacement = remove_child_or_replace_with_skeleton (c, prev);
@@ -7274,6 +7275,8 @@ break_out_comdat_types (dw_die_ref die)
         break_out_comdat_types (c);
 
         /* Add the DIE to the new compunit.  */
+       if (copied != NULL && copied->die_parent)
+         unit = copied->die_parent;
        add_child_die (unit, c);
 
         if (replacement != NULL)
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/nested-3.C 
b/gcc/testsuite/g++.dg/debug/dwarf2/nested-3.C
new file mode 100644
index 0000000..847afd7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/nested-3.C
@@ -0,0 +1,34 @@
+// Origin: PR debug/45682
+// { dg-options "-g -gdwarf-4 -dA -fdebug-types-section" }
+
+namespace thread {
+    class Executor {};
+}
+
+thread::Executor *te;
+
+int
+main ()
+{
+    return 0;
+}
+
+// We want to express the fact that the DIE for the definition of
+// 'Executor' is a child of the DIE for the namespace 'thread'. E.g,
+// we must have this outout:
+//     .uleb128 0x2    # (DIE (0x25) DW_TAG_namespace)
+//     .long   .LASF0  # DW_AT_name: "thread"
+//                     # DW_AT_declaration
+//     .uleb128 0x3    # (DIE (0x2a) DW_TAG_class_type)
+//     .long   .LASF1  # DW_AT_name: "Executor"
+//                     # DW_AT_declaration
+//     .uleb128 0x4    # (DIE (0x2f) DW_TAG_class_type)
+//     .byte   0x1     # DW_AT_byte_size
+//     .byte   0x1     # DW_AT_decl_file (../../prtests/test-PR45682-2.cc)
+//     .byte   0x2     # DW_AT_decl_line
+//     .long   0x2a    # DW_AT_specification
+//     .byte   0       # end of children of DIE 0x25
+//
+//     Hence the scary regexp:
+//
+//     { dg-final { scan-assembler "\[^\n\r\]*\\(DIE \\(0x(\[0-9a-f\]+)\\) 
DW_TAG_namespace\\)\[\n\r\]+\[^\n\r\]*DW_AT_name: 
\"thread\"\[\n\r\]+\[^\n\r\]*DW_AT_declaration\[\n\r\]+\[^\n\r\]*\\(DIE 
\\(0x(\[0-9a-f\]+)\\)\[^\n\r\]*DW_TAG_class_type\\)\[\n\r\]+\[^\n\r\]*DW_AT_name:
 
\"Executor\"\[\n\r\]+\[^\n\r\]*DW_AT_declaration\[\n\r\]+\[^\n\r\]*\\(DIE\[^\n\r\]*DW_TAG_class_type\\)\[\n\r\]+(\[^\n\r\]*\[\n\r\]+)+\[^\n\r\]*0x\\2\[^\n\r\]*\[\n\r\]+\[^\n\r\]*end
 of children of DIE 0x\\1" } }
-- 
1.7.6.4


-- 
                Dodji

Reply via email to