From: ccoutant Date: Fri, 20 Jan 2012 18:57:44 +0000 (+0000) Subject: 2012-01-19 Cary Coutant X-Git-Tag: upstream/4.9.2~14877 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=946ae316776935573e599b10b8fe962848edbb62;p=platform%2Fupstream%2Flinaro-gcc.git 2012-01-19 Cary Coutant Dodji Seketeli gcc/ PR debug/45682 * dwarf2out.c (copy_declaration_context): Return ref to parent of declaration DIE, if necessary. (remove_child_or_replace_with_skeleton): Add new parameter; update caller. Place skeleton DIE under parent DIE of original declaration. Move call to copy_declaration_context to here ... (break_out_comdat_types): ... from here. gcc/testsuite/ PR debug/45682 * g++.dg/debug/dwarf2/nested-3.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183348 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 45bdc3d..9b05b3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-01-20 Cary Coutant + Dodji Seketeli + + PR debug/45682 + * dwarf2out.c (copy_declaration_context): Return ref to parent + of declaration DIE, if necessary. + (remove_child_or_replace_with_skeleton): Add new parameter; update + caller. Place skeleton DIE under parent DIE of original declaration. + Move call to copy_declaration_context to here ... + (break_out_comdat_types): ... from here. + 2012-01-20 Andreas Krebbel PR rtl-optimization/51856 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index f9f4295..ed279ba 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3302,11 +3302,12 @@ 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); static dw_die_ref remove_child_or_replace_with_skeleton (dw_die_ref, + dw_die_ref, dw_die_ref); static void break_out_comdat_types (dw_die_ref); static dw_die_ref copy_ancestor_tree (dw_die_ref, dw_die_ref, htab_t); @@ -7070,16 +7071,18 @@ clone_as_declaration (dw_die_ref die) return clone; } -/* Copy the declaration context to the new compile unit DIE. This includes +/* Copy the declaration context to the new type unit DIE. This includes any surrounding namespace or type declarations. If the DIE has an AT_specification attribute, it also includes attributes and children - attached to the specification. */ + attached to the specification, and returns a pointer to the original + parent of the declaration DIE. Returns NULL otherwise. */ -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 orig_parent = NULL; decl = get_AT_ref (die, DW_AT_specification); if (decl == NULL) @@ -7090,6 +7093,10 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die) dw_die_ref c; dw_attr_ref a; + /* The original DIE will be changed to a declaration, and must + be moved to be a child of the original declaration DIE. */ + orig_parent = decl->die_parent; + /* Copy the type node pointer from the new DIE to the original declaration DIE so we can forward references later. */ decl->die_id.die_type_node = die->die_id.die_type_node; @@ -7118,6 +7125,8 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die) add_AT_specification (die, new_decl); } } + + return orig_parent; } /* Generate the skeleton ancestor tree for the given NODE, then clone @@ -7201,17 +7210,23 @@ generate_skeleton (dw_die_ref die) return node.new_die; } -/* Remove the DIE from its parent, possibly replacing it with a cloned - declaration. The original DIE will be moved to a new compile unit - so that existing references to it follow it to the new location. If - any of the original DIE's descendants is a declaration, we need to - replace the original DIE with a skeleton tree and move the - declarations back into the skeleton tree. */ +/* Remove the CHILD DIE from its parent, possibly replacing it with a cloned + declaration. The original DIE is moved to a new compile unit so that + existing references to it follow it to the new location. If any of the + original DIE's descendants is a declaration, we need to replace the + original DIE with a skeleton tree and move the declarations back into the + skeleton tree. */ static dw_die_ref -remove_child_or_replace_with_skeleton (dw_die_ref child, dw_die_ref prev) +remove_child_or_replace_with_skeleton (dw_die_ref unit, dw_die_ref child, + dw_die_ref prev) { - dw_die_ref skeleton; + dw_die_ref skeleton, orig_parent; + + /* Copy the declaration context to the type unit DIE. If the returned + ORIG_PARENT is not NULL, the skeleton needs to be added as a child of + that DIE. */ + orig_parent = copy_declaration_context (unit, child); skeleton = generate_skeleton (child); if (skeleton == NULL) @@ -7219,7 +7234,19 @@ remove_child_or_replace_with_skeleton (dw_die_ref child, dw_die_ref prev) else { skeleton->die_id.die_type_node = child->die_id.die_type_node; - replace_child (child, skeleton, prev); + + /* If the original DIE was a specification, we need to put + the skeleton under the parent DIE of the declaration. + This leaves the original declaration in the tree, but + it will be pruned later since there are no longer any + references to it. */ + if (orig_parent != NULL) + { + remove_child_with_prev (child, prev); + add_child_die (orig_parent, skeleton); + } + else + replace_child (child, skeleton, prev); } return skeleton; @@ -7264,11 +7291,9 @@ break_out_comdat_types (dw_die_ref die) generate_type_signature (c, type_node); /* Copy the declaration context, attributes, and children of the - declaration into the new compile unit DIE. */ - copy_declaration_context (unit, c); - - /* Remove this DIE from the main CU. */ - replacement = remove_child_or_replace_with_skeleton (c, prev); + declaration into the new type unit DIE, then remove this DIE + from the main CU (or replace it with a skeleton if necessary). */ + replacement = remove_child_or_replace_with_skeleton (unit, c, prev); /* Break out nested types into their own type units. */ break_out_comdat_types (c); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7db1f79..860f7a8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-01-20 Cary Coutant + Dodji Seketeli + + PR debug/45682 + * g++.dg/debug/dwarf2/nested-3.C: New test. + 2012-01-20 Paolo Carlini PR c++/51402 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..707f02d --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/nested-3.C @@ -0,0 +1,54 @@ +// Origin: PR debug/45682 +// { dg-options "-g -fno-merge-debug-strings -gdwarf-4 -dA -fdebug-types-section" } + +namespace thread { + +class Executor { + public: + static Executor* CurrentExecutor(); +}; + +} + +namespace thread { + +Executor* Executor::CurrentExecutor() { + return 0; +} + +} + +thread::Executor *te; + +int +main () +{ + return 0; +} + +// We want to express the fact that the DIE for the definition of +// 'Executor::CurrentExecutor' is a grand-child of the DIE for the +// namespace 'thread'. We must have something like this output: +// .uleb128 0x8 # (DIE (0x29) DW_TAG_namespace) +// .ascii "thread\0" # DW_AT_name +// .byte 0x1 # DW_AT_decl_file (.../testsuite/g++.dg/debug/dwarf2/nested-3.C) +// .byte 0x4 # DW_AT_decl_line +// .long 0x4b # DW_AT_sibling +// .uleb128 0x9 # (DIE (0x34) DW_TAG_class_type) +// .long .LASF0 # DW_AT_name: "Executor" +// # DW_AT_declaration +// .uleb128 0x5 # (DIE (0x39) DW_TAG_subprogram) +// # DW_AT_external +// .long .LASF1 # DW_AT_name: "CurrentExecutor" +// .byte 0x1 # DW_AT_decl_file (.../testsuite/g++.dg/debug/dwarf2/nested-3.C) +// .byte 0x8 # DW_AT_decl_line +// .long .LASF2 # DW_AT_linkage_name: "_ZN6thread8Executor15CurrentExecutorEv" +// .long 0x4b # DW_AT_type +// .byte 0x1 # DW_AT_accessibility +// # DW_AT_declaration +// .byte 0 # end of children of DIE 0x34 +// .byte 0 # end of children of DIE 0x29 +// +// Hence the scary regexp: +// +// { dg-final { scan-assembler "\[^\n\r\]*\\(DIE \\(0x(\[0-9a-f\]+)\\) DW_TAG_namespace\\)\[\n\r\]+\[^\n\r\]*\"thread\[\^\n\r]+\[\n\r\]+(\[^\n\r\]*\[\n\r\]+)+\[^\n\r\]*\\(DIE \\(0x(\[0-9a-f\]+)\\) DW_TAG_class_type\\)\[\n\r\]+\[^\n\r\]*\"Executor\[^\n\r\]+\[\n\r\]+\[^\n\r\]*DW_AT_declaration\[\n\r\]+\[^\n\r\]*\\(DIE\[^\n\r\]*DW_TAG_subprogram\\)\[\n\r\]+(\[^\n\r\]*\[\n\r\]+)+\[^\n\r\]*\"CurrentExecutor\[^\n\r\]+\[\n\r\]+(\[^\n\r\]*\[\n\r\]+)+(\[^\n\r\]*\[\n\r\]+)+\[^\n\r\]*end of children of DIE 0x\\3\[\n\r]+\[^\n\r\]*end of children of DIE 0x\\1\[\n\r]+" } }