diff options
author | Jing Yu <jingyu@google.com> | 2012-02-15 15:40:16 -0800 |
---|---|---|
committer | Jing Yu <jingyu@google.com> | 2012-02-15 15:40:16 -0800 |
commit | 3f73d6ef90458b45bbbb33ef4c2b174d4662a22d (patch) | |
tree | 1b5f0d96c51b51168b3713058a1b62e92f1136eb /gcc-4.6/gcc/dwarf2out.c | |
parent | d7030123e04baab5dbff9c9ee04c0de99bd9a774 (diff) | |
download | toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.tar.gz toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.tar.bz2 toolchain_gcc-3f73d6ef90458b45bbbb33ef4c2b174d4662a22d.zip |
Sync down FSF r184235@google/gcc-4_6_2-mobile branch
1) Get mostly new patches from FSF gcc-4.6 branch
2) Fix PR52129
3) Insert GNU-stack note for all ARM targets
Change-Id: I2b9926981210e517e4021242908074319a91d6bd
Diffstat (limited to 'gcc-4.6/gcc/dwarf2out.c')
-rw-r--r-- | gcc-4.6/gcc/dwarf2out.c | 406 |
1 files changed, 321 insertions, 85 deletions
diff --git a/gcc-4.6/gcc/dwarf2out.c b/gcc-4.6/gcc/dwarf2out.c index b78627bb8..675a68270 100644 --- a/gcc-4.6/gcc/dwarf2out.c +++ b/gcc-4.6/gcc/dwarf2out.c @@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "tree-pass.h" #include "tree-flow.h" +#include "l-ipo.h" static void dwarf2out_source_line (unsigned int, const char *, int, bool); static rtx last_var_location_insn; @@ -4435,6 +4436,11 @@ typedef struct GTY(()) dw_loc_list_struct { const char *section; /* Section this loclist is relative to */ dw_loc_descr_ref expr; hashval_t hash; + /* True if all addresses in this and subsequent lists are known to be + resolved. */ + bool resolved_addr; + /* True if this list has been replaced by dw_loc_next. */ + bool replaced; bool emitted; } dw_loc_list_node; @@ -6095,6 +6101,19 @@ typedef struct var_loc_list_def var_loc_list; /* Table of decl location linked lists. */ static GTY ((param_is (var_loc_list))) htab_t decl_loc_table; +/* A cached location list. */ +struct GTY (()) cached_dw_loc_list_def { + /* The DECL_UID of the decl that this entry describes. */ + unsigned int decl_id; + + /* The cached location list. */ + dw_loc_list_ref loc_list; +}; +typedef struct cached_dw_loc_list_def cached_dw_loc_list; + +/* Table of cached location lists. */ +static GTY ((param_is (cached_dw_loc_list))) htab_t cached_dw_loc_list_table; + /* A pointer to the base of a list of references to DIE's that are uniquely identified by their tag, presence/absence of children DIE's, and list of attribute/value pairs. */ @@ -6394,6 +6413,7 @@ static void output_comp_unit (dw_die_ref, int); static void output_comdat_type_unit (comdat_type_node *); static const char *dwarf2_name (tree, int); static void add_pubname (tree, dw_die_ref); +static void add_enumerator_pubname (const char *, const char *, dw_die_ref); static void add_pubname_string (const char *, dw_die_ref); static void add_pubtype (tree, dw_die_ref); static void output_pubnames (VEC (pubname_entry,gc) *); @@ -6443,7 +6463,7 @@ static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *); static void insert_double (double_int, unsigned char *); static void insert_float (const_rtx, unsigned char *); static rtx rtl_for_decl_location (tree); -static bool add_location_or_const_value_attribute (dw_die_ref, tree, +static bool add_location_or_const_value_attribute (dw_die_ref, tree, bool, enum dwarf_attribute); static bool tree_add_const_value_attribute (dw_die_ref, tree); static bool tree_add_const_value_attribute_for_decl (dw_die_ref, tree); @@ -6598,6 +6618,12 @@ static void gen_scheduled_generic_parms_dies (void); #ifndef COLD_TEXT_SECTION_LABEL #define COLD_TEXT_SECTION_LABEL "Ltext_cold" #endif +#ifndef DEBUG_PUBNAMES_SECTION_LABEL +#define DEBUG_PUBNAMES_SECTION_LABEL "Ldebug_pubnames" +#endif +#ifndef DEBUG_PUBTYPES_SECTION_LABEL +#define DEBUG_PUBTYPES_SECTION_LABEL "Ldebug_pubtypes" +#endif #ifndef DEBUG_LINE_SECTION_LABEL #define DEBUG_LINE_SECTION_LABEL "Ldebug_line" #endif @@ -6631,6 +6657,8 @@ static char cold_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char debug_pubnames_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; +static char debug_pubtypes_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char macinfo_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char loc_section_label[MAX_ARTIFICIAL_LABEL_BYTES]; static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES]; @@ -8177,6 +8205,24 @@ lookup_decl_loc (const_tree decl) htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl)); } +/* Returns a hash value for X (which really is a cached_dw_loc_list_list). */ + +static hashval_t +cached_dw_loc_list_table_hash (const void *x) +{ + return (hashval_t) ((const cached_dw_loc_list *) x)->decl_id; +} + +/* Return nonzero if decl_id of cached_dw_loc_list X is the same as + UID of decl *Y. */ + +static int +cached_dw_loc_list_table_eq (const void *x, const void *y) +{ + return (((const cached_dw_loc_list *) x)->decl_id + == DECL_UID ((const_tree) y)); +} + /* Equate a DIE to a particular declaration. */ static void @@ -9726,6 +9772,22 @@ is_cu_die (dw_die_ref c) return c && c->die_tag == DW_TAG_compile_unit; } +/* Returns true iff C is a namespace DIE. */ + +static inline bool +is_namespace_die (dw_die_ref c) +{ + return c && c->die_tag == DW_TAG_namespace; +} + +/* Returns true iff C is a class DIE. */ + +static inline bool +is_class_die (dw_die_ref c) +{ + return c && c->die_tag == DW_TAG_class_type; +} + static char * gen_internal_sym (const char *prefix) { @@ -10256,6 +10318,15 @@ break_out_comdat_types (dw_die_ref die) type_node->root_die = unit; type_node->next = comdat_type_list; comdat_type_list = type_node; + if (targetm.want_debug_pub_sections) + { + /* FIXME: Should use add_AT_pubnamesptr. This works because most + targets don't care what the base section is. */ + add_AT_lineptr (unit, DW_AT_GNU_pubnames, + debug_pubnames_section_label); + add_AT_lineptr (unit, DW_AT_GNU_pubtypes, + debug_pubtypes_section_label); + } /* Generate the type signature. */ generate_type_signature (c, type_node); @@ -10651,7 +10722,15 @@ size_of_die (dw_die_ref die) size += size_of_sleb128 (AT_int (a)); break; case dw_val_class_unsigned_const: - size += constant_size (AT_unsigned (a)); + { + int csize = constant_size (AT_unsigned (a)); + if (dwarf_version == 3 + && a->dw_attr == DW_AT_data_member_location + && csize >= 4) + size += size_of_uleb128 (AT_unsigned (a)); + else + size += csize; + } break; case dw_val_class_const_double: size += 2 * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; @@ -10921,8 +11000,16 @@ value_format (dw_attr_ref a) case 2: return DW_FORM_data2; case 4: + /* In DWARF3 DW_AT_data_member_location with + DW_FORM_data4 or DW_FORM_data8 is a loclistptr, not + constant, so we need to use DW_FORM_udata if we need + a large constant. */ + if (dwarf_version == 3 && a->dw_attr == DW_AT_data_member_location) + return DW_FORM_udata; return DW_FORM_data4; case 8: + if (dwarf_version == 3 && a->dw_attr == DW_AT_data_member_location) + return DW_FORM_udata; return DW_FORM_data8; default: gcc_unreachable (); @@ -11229,8 +11316,15 @@ output_die (dw_die_ref die) break; case dw_val_class_unsigned_const: - dw2_asm_output_data (constant_size (AT_unsigned (a)), - AT_unsigned (a), "%s", name); + { + int csize = constant_size (AT_unsigned (a)); + if (dwarf_version == 3 + && a->dw_attr == DW_AT_data_member_location + && csize >= 4) + dw2_asm_output_data_uleb128 (AT_unsigned (a), "%s", name); + else + dw2_asm_output_data (csize, AT_unsigned (a), "%s", name); + } break; case dw_val_class_const_double: @@ -11574,16 +11668,35 @@ add_pubname_string (const char *str, dw_die_ref die) static void add_pubname (tree decl, dw_die_ref die) { - if (!GENERATE_MINIMUM_LINE_TABLE - && targetm.want_debug_pub_sections - && TREE_PUBLIC (decl)) + if (!GENERATE_MINIMUM_LINE_TABLE && targetm.want_debug_pub_sections) { - const char *name = dwarf2_name (decl, 1); - if (name) - add_pubname_string (name, die); + if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) + || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent)) + { + const char *name = dwarf2_name (decl, 1); + if (name) + add_pubname_string (name, die); + } } } +/* Add an enumerator to the pubnames section. */ + +static void +add_enumerator_pubname (const char *scope_name, const char *sep, dw_die_ref die) +{ + const char *name; + pubname_entry e; + + if (scope_name) + name = concat (scope_name, sep, get_AT_string (die, DW_AT_name), NULL); + else + name = xstrdup (get_AT_string (die, DW_AT_name)); + e.name = name; + e.die = die; + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); +} + /* Add a new entry to .debug_pubtypes if appropriate. */ static void @@ -11596,34 +11709,47 @@ add_pubtype (tree decl, dw_die_ref die) e.name = NULL; if ((TREE_PUBLIC (decl) - || is_cu_die (die->die_parent)) + || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent)) && (die->die_tag == DW_TAG_typedef || COMPLETE_TYPE_P (decl))) { - e.die = die; + tree scope = NULL; + const char *scope_name = NULL; + const char *sep = is_cxx () ? "::" : "."; + const char *name = NULL; + if (TYPE_P (decl)) - { - if (TYPE_NAME (decl)) - { - if (TREE_CODE (TYPE_NAME (decl)) == IDENTIFIER_NODE) - e.name = IDENTIFIER_POINTER (TYPE_NAME (decl)); - else if (TREE_CODE (TYPE_NAME (decl)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (decl))) - e.name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (decl))); - else - e.name = xstrdup ((const char *) get_AT_string (die, DW_AT_name)); - } - } + name = type_tag (decl); else - { - e.name = dwarf2_name (decl, 1); - if (e.name) - e.name = xstrdup (e.name); - } + name = lang_hooks.dwarf_name (decl, 1); /* If we don't have a name for the type, there's no point in adding it to the table. */ - if (e.name && e.name[0] != '\0') - VEC_safe_push (pubname_entry, gc, pubtype_table, &e); + if (name == NULL || name[0] == '\0') + return; + + e.die = die; + e.name = xstrdup (name); + + scope = TYPE_P (decl) ? TYPE_CONTEXT (decl) : NULL; + if (scope && TREE_CODE (scope) == NAMESPACE_DECL) + { + scope_name = lang_hooks.dwarf_name (scope, 1); + if (scope_name != NULL) + e.name = concat (scope_name, sep, e.name, NULL); + } + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); + + /* Although it might be more consistent to add the pubinfo for the + enumerators as their dies are created, they should only be added if the + enum type meets the criteria above. So rather than re-check the parent + enum type whenever an enumerator die is created, just output them all + here. */ + if (die->die_tag == DW_TAG_enumeration_type) + { + dw_die_ref c; + + FOR_EACH_CHILD (die, c, add_enumerator_pubname (scope_name, sep, c)); + } } } @@ -11637,6 +11763,18 @@ output_pubnames (VEC (pubname_entry, gc) * names) unsigned long pubnames_length = size_of_pubnames (names); pubname_ref pub; + if (!targetm.want_debug_pub_sections || !info_section_emitted) + return; + if (names == pubname_table) + { + switch_to_section (debug_pubnames_section); + ASM_OUTPUT_LABEL (asm_out_file, debug_pubnames_section_label); + } + else + { + switch_to_section (debug_pubtypes_section); + ASM_OUTPUT_LABEL (asm_out_file, debug_pubtypes_section_label); + } if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) dw2_asm_output_data (4, 0xffffffff, "Initial length escape value indicating 64-bit DWARF extension"); @@ -12774,6 +12912,7 @@ base_type_die (tree type) add_AT_unsigned (base_type_result, DW_AT_byte_size, int_size_in_bytes (type)); add_AT_unsigned (base_type_result, DW_AT_encoding, encoding); + add_pubtype (type, base_type_result); return base_type_result; } @@ -14591,7 +14730,8 @@ loc_descriptor (rtx rtl, enum machine_mode mode, up an entire register. For now, just assume that it is legitimate to make the Dwarf info refer to the whole register which contains the given subreg. */ - loc_result = loc_descriptor (SUBREG_REG (rtl), mode, initialized); + loc_result = loc_descriptor (SUBREG_REG (rtl), + GET_MODE (SUBREG_REG (rtl)), initialized); break; case REG: @@ -16977,15 +17117,22 @@ fortran_common (tree decl, HOST_WIDE_INT *value) these things can crop up in other ways also.) Note that one type of constant value which can be passed into an inlined function is a constant pointer. This can happen for example if an actual argument in an inlined - function call evaluates to a compile-time constant address. */ + function call evaluates to a compile-time constant address. + + CACHE_P is true if it is worth caching the location list for DECL, + so that future calls can reuse it rather than regenerate it from scratch. + This is true for BLOCK_NONLOCALIZED_VARS in inlined subroutines, + since we will need to refer to them each time the function is inlined. */ static bool -add_location_or_const_value_attribute (dw_die_ref die, tree decl, +add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p, enum dwarf_attribute attr) { rtx rtl; dw_loc_list_ref list; var_loc_list *loc_list; + cached_dw_loc_list *cache; + void **slot; if (TREE_CODE (decl) == ERROR_MARK) return false; @@ -17022,7 +17169,33 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, && add_const_value_attribute (die, rtl)) return true; } - list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2); + /* If this decl is from BLOCK_NONLOCALIZED_VARS, we might need its + list several times. See if we've already cached the contents. */ + list = NULL; + if (loc_list == NULL || cached_dw_loc_list_table == NULL) + cache_p = false; + if (cache_p) + { + cache = (cached_dw_loc_list *) + htab_find_with_hash (cached_dw_loc_list_table, decl, DECL_UID (decl)); + if (cache) + list = cache->loc_list; + } + if (list == NULL) + { + list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2); + /* It is usually worth caching this result if the decl is from + BLOCK_NONLOCALIZED_VARS and if the list has at least two elements. */ + if (cache_p && list && list->dw_loc_next) + { + slot = htab_find_slot_with_hash (cached_dw_loc_list_table, decl, + DECL_UID (decl), INSERT); + cache = ggc_alloc_cleared_cached_dw_loc_list (); + cache->decl_id = DECL_UID (decl); + cache->loc_list = list; + *slot = cache; + } + } if (list) { add_AT_location_description (die, attr, list); @@ -18721,7 +18894,7 @@ gen_formal_parameter_die (tree node, tree origin, bool emit_name_p, equate_decl_number_to_die (node, parm_die); if (! DECL_ABSTRACT (node_or_origin)) add_location_or_const_value_attribute (parm_die, node_or_origin, - DW_AT_location); + node == NULL, DW_AT_location); break; @@ -18906,6 +19079,7 @@ dwarf2out_abstract_function (tree decl) tree context; int was_abstract; htab_t old_decl_loc_table; + htab_t old_cached_dw_loc_list_table; /* Make sure we have the actual abstract inline, not a clone. */ decl = DECL_ORIGIN (decl); @@ -18920,6 +19094,8 @@ dwarf2out_abstract_function (tree decl) get locations in abstract instantces. */ old_decl_loc_table = decl_loc_table; decl_loc_table = NULL; + old_cached_dw_loc_list_table = cached_dw_loc_list_table; + cached_dw_loc_list_table = NULL; /* Be sure we've emitted the in-class declaration DIE (if any) first, so we don't get confused by DECL_ABSTRACT. */ @@ -18944,6 +19120,7 @@ dwarf2out_abstract_function (tree decl) current_function_decl = save_fn; decl_loc_table = old_decl_loc_table; + cached_dw_loc_list_table = old_cached_dw_loc_list_table; pop_cfun (); } @@ -19728,9 +19905,8 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin))) defer_location (decl_or_origin, var_die); else - add_location_or_const_value_attribute (var_die, - decl_or_origin, - DW_AT_location); + add_location_or_const_value_attribute (var_die, decl_or_origin, + decl == NULL, DW_AT_location); add_pubname (decl_or_origin, var_die); } else @@ -21035,6 +21211,8 @@ gen_namespace_die (tree decl, dw_die_ref context_die) add_AT_die_ref (namespace_die, DW_AT_import, origin_die); equate_decl_number_to_die (decl, namespace_die); } + /* Bypass dwarf2_name's check for DECL_NAMELESS. */ + add_pubname_string (lang_hooks.dwarf_name (decl, 1), namespace_die); } /* Generate Dwarf debug information for a decl described by DECL. @@ -21399,7 +21577,48 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context, void dwarf2out_decl (tree decl) { - dw_die_ref context_die = comp_unit_die (); + dw_die_ref context_die; + + /* In LIPO mode, we may output some functions whose type is defined + in another function that will not be output. This can result in + undefined location list symbols in the debug type info. + Here we disable the output of the type info for this case. + It is safe since this function and its debug info should never + be referenced. */ + if (L_IPO_COMP_MODE) + { + tree decl_context, orig_decl; + + decl_context = DECL_CONTEXT (decl); + while (decl_context && + TREE_CODE (decl_context) != TRANSLATION_UNIT_DECL) + { + struct cgraph_node *node; + + /* Refer to cgraph_mark_functions_to_output() in cgraphunit.c, + if cgraph_is_aux_decl_external() is true, + this function will not be output in LIPO mode. */ + if (TREE_CODE (decl_context) == FUNCTION_DECL && + TREE_PUBLIC (decl_context) && + (node = cgraph_get_node (decl_context)) && + cgraph_is_aux_decl_external (node)) + return; + + if (TYPE_P (decl_context)) + { + decl_context = TYPE_CONTEXT (decl_context); + continue; + } + + orig_decl = DECL_ORIGIN (decl_context); + while (orig_decl != DECL_ORIGIN (orig_decl)) + orig_decl = DECL_ORIGIN (orig_decl); + + decl_context = DECL_CONTEXT (orig_decl); + } + } + + context_die = comp_unit_die (); switch (TREE_CODE (decl)) { @@ -21521,6 +21740,7 @@ dwarf2out_function_decl (tree decl) dwarf2out_decl (decl); htab_empty (decl_loc_table); + htab_empty (cached_dw_loc_list_table); } /* Output a marker (i.e. a label) for the beginning of the generated code for @@ -22046,7 +22266,8 @@ dwarf2out_source_line (unsigned int line, const char *filename, fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0); last_is_stmt = is_stmt; } - if (SUPPORTS_DISCRIMINATOR && discriminator != 0) + if (SUPPORTS_DISCRIMINATOR && discriminator != 0 + && (dwarf_version >= 4 || !dwarf_strict)) fprintf (asm_out_file, " discriminator %d", discriminator); fputc ('\n', asm_out_file); @@ -22252,6 +22473,11 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) decl_loc_table = htab_create_ggc (10, decl_loc_table_hash, decl_loc_table_eq, NULL); + /* Allocate the cached_dw_loc_list_table. */ + cached_dw_loc_list_table + = htab_create_ggc (10, cached_dw_loc_list_table_hash, + cached_dw_loc_list_table_eq, NULL); + /* Allocate the initial hunk of the decl_scope_table. */ decl_scope_table = VEC_alloc (tree, gc, 256); @@ -22319,6 +22545,10 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label, DEBUG_INFO_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (debug_pubnames_section_label, + DEBUG_PUBNAMES_SECTION_LABEL, 0); + ASM_GENERATE_INTERNAL_LABEL (debug_pubtypes_section_label, + DEBUG_PUBTYPES_SECTION_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label, DEBUG_LINE_SECTION_LABEL, 0); ASM_GENERATE_INTERNAL_LABEL (ranges_section_label, @@ -22892,30 +23122,53 @@ resolve_addr (dw_die_ref die) { dw_die_ref c; dw_attr_ref a; - dw_loc_list_ref *curr; + dw_loc_list_ref *curr, *start, loc; unsigned ix; FOR_EACH_VEC_ELT (dw_attr_node, die->die_attr, ix, a) switch (AT_class (a)) { case dw_val_class_loc_list: - curr = AT_loc_list_ptr (a); - while (*curr) + start = curr = AT_loc_list_ptr (a); + loc = *curr; + gcc_assert (loc); + /* The same list can be referenced more than once. See if we have + already recorded the result from a previous pass. */ + if (loc->replaced) + *curr = loc->dw_loc_next; + else if (!loc->resolved_addr) { - if (!resolve_addr_in_expr ((*curr)->expr)) + /* As things stand, we do not expect or allow one die to + reference a suffix of another die's location list chain. + References must be identical or completely separate. + There is therefore no need to cache the result of this + pass on any list other than the first; doing so + would lead to unnecessary writes. */ + while (*curr) { - dw_loc_list_ref next = (*curr)->dw_loc_next; - if (next && (*curr)->ll_symbol) + gcc_assert (!(*curr)->replaced && !(*curr)->resolved_addr); + if (!resolve_addr_in_expr ((*curr)->expr)) { - gcc_assert (!next->ll_symbol); - next->ll_symbol = (*curr)->ll_symbol; + dw_loc_list_ref next = (*curr)->dw_loc_next; + if (next && (*curr)->ll_symbol) + { + gcc_assert (!next->ll_symbol); + next->ll_symbol = (*curr)->ll_symbol; + } + *curr = next; } - *curr = next; + else + curr = &(*curr)->dw_loc_next; } + if (loc == *start) + loc->resolved_addr = 1; else - curr = &(*curr)->dw_loc_next; + { + loc->replaced = 1; + loc->dw_loc_next = *start; + } } - if (!AT_loc_list (a)) + if (!*start) { remove_AT (die, a->dw_attr); ix--; @@ -23312,6 +23565,7 @@ optimize_location_lists (dw_die_ref die) htab_delete (htab); } + /* Output stuff that dwarf requires at the end of every file, and generate the DWARF-2 debugging info. */ @@ -23344,6 +23598,7 @@ dwarf2out_finish (const char *filename) add_location_or_const_value_attribute ( VEC_index (deferred_locations, deferred_locations_list, i)->die, VEC_index (deferred_locations, deferred_locations_list, i)->variable, + false, DW_AT_location); } @@ -23551,6 +23806,17 @@ dwarf2out_finish (const char *filename) } htab_delete (comdat_type_table); + /* Add the DW_AT_GNU_pubnames and DW_AT_GNU_pubtypes attributes. */ + if (targetm.want_debug_pub_sections) + { + /* FIXME: Should use add_AT_pubnamesptr. This works because most targets + don't care what the base section is. */ + add_AT_lineptr (comp_unit_die (), DW_AT_GNU_pubnames, + debug_pubnames_section_label); + add_AT_lineptr (comp_unit_die (), DW_AT_GNU_pubtypes, + debug_pubtypes_section_label); + } + /* Output the main compilation unit if non-empty or if .debug_macinfo will be emitted. */ output_comp_unit (comp_unit_die (), debug_info_level >= DINFO_LEVEL_VERBOSE); @@ -23571,42 +23837,12 @@ dwarf2out_finish (const char *filename) output_location_lists (comp_unit_die ()); } - /* Output public names table if necessary. */ - if (!VEC_empty (pubname_entry, pubname_table)) - { - gcc_assert (info_section_emitted); - switch_to_section (debug_pubnames_section); - output_pubnames (pubname_table); - } - - /* Output public types table if necessary. */ + /* Output public names and types tables if necessary. */ + output_pubnames (pubname_table); /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2. It shouldn't hurt to emit it always, since pure DWARF2 consumers simply won't look for the section. */ - if (!VEC_empty (pubname_entry, pubtype_table)) - { - bool empty = false; - - if (flag_eliminate_unused_debug_types) - { - /* The pubtypes table might be emptied by pruning unused items. */ - unsigned i; - pubname_ref p; - empty = true; - FOR_EACH_VEC_ELT (pubname_entry, pubtype_table, i, p) - if (p->die->die_offset != 0) - { - empty = false; - break; - } - } - if (!empty) - { - gcc_assert (info_section_emitted); - switch_to_section (debug_pubtypes_section); - output_pubnames (pubtype_table); - } - } + output_pubnames (pubtype_table); /* Output direct and virtual call tables if necessary. */ if (!VEC_empty (dcall_entry, dcall_table)) |