This patch is for the google/gcc-4_7 branch. This patch fixes a problem caused by the previous patch that removed the code to copy children of a DIE referenced by a type unit.
> I don't believe that it's necessary to copy the children of the class > declaration at all, and this patch simply removes the code that copies > those children. If there's a reference in the type unit to one of the > children of that class, that one child will get copied in as needed. The problem was that it IS necessary to copy the children of a non-declaration -- such as a DW_TAG_array_type. I've restored the loop that calls clone_tree_partial, but placed it within a test for is_declaration_die. Bootstraps and passes regression tests. Also tested with parts of the GDB testsuite, and is still able to build a large internal test case that previously resulted in out-of-memory during compilation. Google ref b/7041390. 2012-08-31 Cary Coutant <ccout...@google.com> * gcc/dwarf2out.c (clone_tree_partial): Restore. (copy_decls_walk): Call clone_tree_partial to copy children of non-declaration DIEs. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 190842) +++ gcc/dwarf2out.c (working copy) @@ -7745,6 +7745,40 @@ copy_ancestor_tree (dw_die_ref unit, dw_ return copy; } +/* Like clone_tree, but copy DW_TAG_subprogram DIEs as declarations. + Enter all the cloned children into the hash table decl_table. */ + +static dw_die_ref +clone_tree_partial (dw_die_ref die, htab_t decl_table) +{ + dw_die_ref c; + dw_die_ref clone; + struct decl_table_entry *entry; + void **slot; + + if (die->die_tag == DW_TAG_subprogram) + clone = clone_as_declaration (die); + else + clone = clone_die (die); + + slot = htab_find_slot_with_hash (decl_table, die, + htab_hash_pointer (die), INSERT); + /* Assert that DIE isn't in the hash table yet. If it would be there + before, the ancestors would be necessarily there as well, therefore + clone_tree_partial wouldn't be called. */ + gcc_assert (*slot == HTAB_EMPTY_ENTRY); + entry = XCNEW (struct decl_table_entry); + entry->orig = die; + entry->copy = clone; + *slot = entry; + + if (die->die_tag != DW_TAG_subprogram) + FOR_EACH_CHILD (die, c, + add_child_die (clone, clone_tree_partial (c, decl_table))); + + return clone; +} + /* Walk the DIE and its children, looking for references to incomplete or trivial types that are unmarked (i.e., that are not in the current type_unit). */ @@ -7792,6 +7826,16 @@ copy_decls_walk (dw_die_ref unit, dw_die entry->copy = copy; *slot = entry; + /* If TARG is not a declaration DIE, we need to copy its + children. */ + if (!is_declaration_die (targ)) + { + FOR_EACH_CHILD ( + targ, c, + add_child_die (copy, + clone_tree_partial (c, decl_table))); + } + /* Make sure the cloned tree is marked as part of the type unit. */ mark_dies (copy);