aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/dwarf2out.c105
2 files changed, 89 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b2d6c30..c3b52cd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 24022aa..66cbfb0 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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);
}