[google/gcc-4_7] Fix GDB test suite regression with -fdebug-types-section patch

Message ID 20120831235540.5AC2FE0C04@ccoutant.mtv.corp.google.com
State New
Headers show

Commit Message

Cary Coutant Aug. 31, 2012, 11:55 p.m.
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  <ccoutant@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))
+	        {
+		      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);