dwarf2out.c (die_checksum_ordered): Don't include template instantiations in signature.
authorCary Coutant <ccoutant@google.com>
Fri, 26 Jul 2013 20:14:43 +0000 (20:14 +0000)
committerCary Coutant <ccoutant@gcc.gnu.org>
Fri, 26 Jul 2013 20:14:43 +0000 (13:14 -0700)
gcc/
* dwarf2out.c (die_checksum_ordered): Don't include template
instantiations in signature.
(is_template_parameter): New function.
(is_template_instantiation): New function.
(generate_skeleton_bottom_up): Don't include template instantiations
in type unit DIE.
(generate_skeleton): Likewise.
(break_out_comdat_types): Move recursive call to break out nested
types earlier.
(prune_unused_types_mark_generic_parms_dies): Call
is_template_parameter.

From-SVN: r201275

gcc/ChangeLog
gcc/dwarf2out.c

index b2d6c30..c3b52cd 100644 (file)
@@ -1,3 +1,17 @@
+2013-07-26  Cary Coutant  <ccoutant@google.com>
+
+       * dwarf2out.c (die_checksum_ordered): Don't include template
+       instantiations in signature.
+       (is_template_parameter): New function.
+       (is_template_instantiation): New function.
+       (generate_skeleton_bottom_up): Don't include template instantiations
+       in type unit DIE.
+       (generate_skeleton): Likewise.
+       (break_out_comdat_types): Move recursive call to break out nested
+       types earlier.
+       (prune_unused_types_mark_generic_parms_dies): Call
+       is_template_parameter.
+
 2013-07-26  Ian Bolton  <ian.bolton@arm.com>
 
        * config/aarch64/aarch64.md (neg<mode>2): Offer alternative that
index 24022aa..66cbfb0 100644 (file)
@@ -3023,6 +3023,7 @@ static void compute_section_prefix (dw_die_ref);
 static int is_type_die (dw_die_ref);
 static int is_comdat_die (dw_die_ref);
 static int is_symbol_die (dw_die_ref);
+static inline bool is_template_instantiation (dw_die_ref);
 static void assign_symbol_names (dw_die_ref);
 static void break_out_includes (dw_die_ref);
 static int is_declaration_die (dw_die_ref);
@@ -6077,22 +6078,29 @@ die_checksum_ordered (dw_die_ref die, struct md5_ctx *ctx, int *mark)
   CHECKSUM_ATTR (attrs.at_type);
   CHECKSUM_ATTR (attrs.at_friend);
 
-  /* Checksum the child DIEs, except for nested types and member functions.  */
+  /* Checksum the child DIEs.  */
   c = die->die_child;
   if (c) do {
     dw_attr_ref name_attr;
 
     c = c->die_sib;
     name_attr = get_AT (c, DW_AT_name);
-    if ((is_type_die (c) || c->die_tag == DW_TAG_subprogram)
-        && name_attr != NULL)
+    if (is_template_instantiation (c))
       {
+       /* Ignore instantiations of member type and function templates.  */
+      }
+    else if (name_attr != NULL
+            && (is_type_die (c) || c->die_tag == DW_TAG_subprogram))
+      {
+       /* Use a shallow checksum for named nested types and member
+          functions.  */
         CHECKSUM_ULEB128 ('S');
         CHECKSUM_ULEB128 (c->die_tag);
         CHECKSUM_STRING (AT_string (name_attr));
       }
     else
       {
+       /* Use a deep checksum for other children.  */
         /* Mark this DIE so it gets processed when unmarking.  */
         if (c->die_mark == 0)
           c->die_mark = -1;
@@ -6505,6 +6513,36 @@ is_class_die (dw_die_ref c)
                || c->die_tag == DW_TAG_structure_type);
 }
 
+/* Return non-zero if this DIE is a template parameter.  */
+
+static inline bool
+is_template_parameter (dw_die_ref die)
+{
+  switch (die->die_tag)
+    {
+    case DW_TAG_template_type_param:
+    case DW_TAG_template_value_param:
+    case DW_TAG_GNU_template_template_param:
+    case DW_TAG_GNU_template_parameter_pack:
+      return true;
+    default:
+      return false;
+    }
+}
+
+/* Return non-zero if this DIE represents a template instantiation.  */
+
+static inline bool
+is_template_instantiation (dw_die_ref die)
+{
+  dw_die_ref c;
+
+  if (!is_type_die (die) && die->die_tag != DW_TAG_subprogram)
+    return false;
+  FOR_EACH_CHILD (die, c, if (is_template_parameter (c)) return true);
+  return false;
+}
+
 static char *
 gen_internal_sym (const char *prefix)
 {
@@ -7064,17 +7102,30 @@ generate_skeleton_bottom_up (skeleton_chain_node *parent)
     node.new_die = NULL;
     if (is_declaration_die (c))
       {
-        /* Clone the existing DIE, move the original to the skeleton
-           tree (which is in the main CU), and put the clone, with
-           all the original's children, where the original came from.  */
-        dw_die_ref clone = clone_die (c);
-        move_all_children (c, clone);
-
-        replace_child (c, clone, prev);
-        generate_skeleton_ancestor_tree (parent);
-        add_child_die (parent->new_die, c);
-        node.new_die = c;
-        c = clone;
+       if (is_template_instantiation (c))
+         {
+           /* Instantiated templates do not need to be cloned into the
+              type unit.  Just move the DIE and its children back to
+              the skeleton tree (in the main CU).  */
+           remove_child_with_prev (c, prev);
+           add_child_die (parent->new_die, c);
+           c = prev;
+         }
+       else
+         {
+           /* Clone the existing DIE, move the original to the skeleton
+              tree (which is in the main CU), and put the clone, with
+              all the original's children, where the original came from
+              (which is about to be moved to the type unit).  */
+           dw_die_ref clone = clone_die (c);
+           move_all_children (c, clone);
+
+           replace_child (c, clone, prev);
+           generate_skeleton_ancestor_tree (parent);
+           add_child_die (parent->new_die, c);
+           node.new_die = c;
+           c = clone;
+         }
       }
     generate_skeleton_bottom_up (&node);
   } while (next != NULL);
@@ -7092,8 +7143,11 @@ generate_skeleton (dw_die_ref die)
   node.parent = NULL;
 
   /* If this type definition is nested inside another type,
-     always leave at least a declaration in its place.  */
-  if (die->die_parent != NULL && is_type_die (die->die_parent))
+     and is not an instantiation of a template, always leave
+     at least a declaration in its place.  */
+  if (die->die_parent != NULL
+      && is_type_die (die->die_parent)
+      && !is_template_instantiation (die))
     node.new_die = clone_as_declaration (die);
 
   generate_skeleton_bottom_up (&node);
@@ -7168,6 +7222,9 @@ break_out_comdat_types (dw_die_ref die)
         dw_die_ref replacement;
        comdat_type_node_ref type_node;
 
+        /* Break out nested types into their own type units.  */
+        break_out_comdat_types (c);
+
         /* Create a new type unit DIE as the root for the new tree, and
            add it to the list of comdat types.  */
         unit = new_die (DW_TAG_type_unit, NULL, NULL);
@@ -7187,9 +7244,6 @@ break_out_comdat_types (dw_die_ref die)
        replacement = remove_child_or_replace_with_skeleton (unit, c, prev);
        type_node->skeleton_die = replacement;
 
-        /* Break out nested types into their own type units.  */
-        break_out_comdat_types (c);
-
         /* Add the DIE to the new compunit.  */
        add_child_die (unit, c);
 
@@ -22142,17 +22196,8 @@ prune_unused_types_mark_generic_parms_dies (dw_die_ref die)
   c = die->die_child;
   do
     {
-      switch (c->die_tag)
-       {
-       case DW_TAG_template_type_param:
-       case DW_TAG_template_value_param:
-       case DW_TAG_GNU_template_template_param:
-       case DW_TAG_GNU_template_parameter_pack:
-         prune_unused_types_mark (c, 1);
-         break;
-       default:
-         break;
-       }
+      if (is_template_parameter (c))
+       prune_unused_types_mark (c, 1);
       c = c->die_sib;
     } while (c && c != die->die_child);
 }