diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 105 |
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); } |