Message ID | 20120601175840.DC7DC160730@sterling.mtv.corp.google.com |
---|---|
State | New |
Headers | show |
On 06/01/2012 01:58 PM, Sterling Augustine wrote: > It also adds and documents a new option "-g[no-]pubtypes" which allows users > to generate pubtypes even if the target disables them by default. Hmm, I thought the convention for this sort of flag was to start with -f, that -g flags were only for selecting the type and level of debug info. But I see that there are other debug dialect switches that use -g, so I guess this is OK. > + if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) Why not include public class members? Is the theory that you'll need to read the type DIE anyway to do anything with the member, so you might as well read it to look up the member in the first place? There should be a comment about this. > + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); Why add enumerators to pubtypes rather than pubnames? They seem more like variables than types to me. > + here. This isn't protected by the name conditional because anoymous Missing an 'n' in "anonymous". A C++ opaque enumeration is considered complete, but does not yet have its enumerators, which can be added later. Does this code handle that? > + if (use_debug_types && names == pubtype_table) This should check pub->die->comdat_type_p Jason
On Fri, Jun 08, 2012 at 02:45:09PM -0400, Jason Merrill wrote: > On 06/01/2012 01:58 PM, Sterling Augustine wrote: > >It also adds and documents a new option "-g[no-]pubtypes" which allows users > >to generate pubtypes even if the target disables them by default. > > Hmm, I thought the convention for this sort of flag was to start > with -f, that -g flags were only for selecting the type and level of > debug info. But I see that there are other debug dialect switches > that use -g, so I guess this is OK. But we have -f{,no-}debug-types-section, so perhaps consistent with that would be -f{,no-}debug-pubtypes-section ? Jakub
> Hmm, I thought the convention for this sort of flag was to start with -f, > that -g flags were only for selecting the type and level of debug info. But > I see that there are other debug dialect switches that use -g, so I guess > this is OK. I kind of prefer -g, but I did notice that it's -fdebug-types-section, so I could go with -f[no-]pubnames (or, as Jakub suggests, -f[no-]debug-pubnames-section). On the other hand, there's -g[no-]record-gcc-switches. What would you prefer? If we change it, should we also change (in a later patch) -gsplit-dwarf (orig. -gfission) to -fsplit-dwarf? >> + if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) > > Why not include public class members? Is the theory that you'll need to > read the type DIE anyway to do anything with the member, so you might as > well read it to look up the member in the first place? There should be a > comment about this. Yes, that's the theory. We're just trying to do the same thing that GDB does when it builds .gdb_index. >> + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); > > Why add enumerators to pubtypes rather than pubnames? They seem more like > variables than types to me. That looks like a typo. It hasn't caused us any trouble because the linker just throws all the names into the same table in .gdb_index, but yes, I think it should go in pubnames_table. -cary
On Fri, Jun 8, 2012 at 2:22 PM, Cary Coutant <ccoutant@google.com> wrote: >> Hmm, I thought the convention for this sort of flag was to start with -f, >> that -g flags were only for selecting the type and level of debug info. But >> I see that there are other debug dialect switches that use -g, so I guess >> this is OK. > > I kind of prefer -g, but I did notice that it's -fdebug-types-section, > so I could go with -f[no-]pubnames (or, as Jakub suggests, > -f[no-]debug-pubnames-section). On the other hand, there's > -g[no-]record-gcc-switches. What would you prefer? > > If we change it, should we also change (in a later patch) > -gsplit-dwarf (orig. -gfission) to -fsplit-dwarf? > >>> + if ((TREE_PUBLIC (decl) && !is_class_die (die->die_parent)) >> >> Why not include public class members? Is the theory that you'll need to >> read the type DIE anyway to do anything with the member, so you might as >> well read it to look up the member in the first place? There should be a >> comment about this. > > Yes, that's the theory. We're just trying to do the same thing that > GDB does when it builds .gdb_index. > >>> + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); >> >> Why add enumerators to pubtypes rather than pubnames? They seem more like >> variables than types to me. > > That looks like a typo. It hasn't caused us any trouble because the > linker just throws all the names into the same table in .gdb_index, > but yes, I think it should go in pubnames_table. > > -cary OK, I've updated the patch with all these additional comments. Just waiting on the decision between -f and -g. I'll repost and then commit it when that is settled--hopefully soon. Next up, the big fission patch! Sterling
On Fri, Jun 8, 2012 at 3:03 PM, Sterling Augustine <saugustine@google.com> wrote: [Regarding generating pubnames] > OK, I've updated the patch with all these additional comments. Just > waiting on the decision between -f and -g. I'll repost and then commit > it when that is settled--hopefully soon. > > Next up, the big fission patch! > > Sterling Ping
On 06/08/2012 05:22 PM, Cary Coutant wrote: > I kind of prefer -g, but I did notice that it's -fdebug-types-section, > so I could go with -f[no-]pubnames (or, as Jakub suggests, > -f[no-]debug-pubnames-section). On the other hand, there's > -g[no-]record-gcc-switches. What would you prefer? > > If we change it, should we also change (in a later patch) > -gsplit-dwarf (orig. -gfission) to -fsplit-dwarf? I lean toward -g myself, since there doesn't seem to be a strong rule one way or the other. Jason
> I lean toward -g myself, since there doesn't seem to be a strong rule one > way or the other. Unless there are further comments, I'll stick with -g then. I think that covers all the comments, so I think I will commit this Friday morning unless I hear anything further. Sterling
On 06/13/2012 04:26 PM, Sterling Augustine wrote: >> I lean toward -g myself, since there doesn't seem to be a strong rule one >> way or the other. > > Unless there are further comments, I'll stick with -g then. > > I think that covers all the comments, so I think I will commit this > Friday morning unless I hear anything further. Weren't you going to repost the patch first? :) Jason
On Wed, Jun 13, 2012 at 10:47 PM, Jason Merrill <jason@redhat.com> wrote: > On 06/13/2012 04:26 PM, Sterling Augustine wrote: >>> >>> I lean toward -g myself, since there doesn't seem to be a strong rule one >>> way or the other. >> >> >> Unless there are further comments, I'll stick with -g then. >> >> I think that covers all the comments, so I think I will commit this >> Friday morning unless I hear anything further. > > > Weren't you going to repost the patch first? :) I hate how codereview.appspot.com doesn't connect some messages properly. After this prompting, I re-posted the patch here: http://gcc.gnu.org/ml/gcc-patches/2012-06/msg00949.html As this has addressed all previous comments, and barring any objections, I'll check it in tomorrow morning. Sterling
On 06/19/2012 10:12 AM, Sterling Augustine wrote: > + /* If we're putting types in their own .debug_types sections, > + the .debug_pubtypes table will still point to the compile > + unit (not the type unit), so we want to use the offset of > + the skeleton DIE (if there is one). */ > + if (pub->die->comdat_type_p && names == pubtype_table) > + { > + comdat_type_node_ref type_node = pub->die->die_id.die_type_node; > + > + if (type_node != NULL && type_node->skeleton_die != NULL) > + die_offset = type_node->skeleton_die->die_offset; > + } I think we had agreed that if there is no skeleton, we should use an offset of 0. Jason
>> + /* If we're putting types in their own .debug_types sections, >> + the .debug_pubtypes table will still point to the compile >> + unit (not the type unit), so we want to use the offset of >> + the skeleton DIE (if there is one). */ >> + if (pub->die->comdat_type_p && names == pubtype_table) >> >> + { >> + comdat_type_node_ref type_node = >> pub->die->die_id.die_type_node; >> + >> + if (type_node != NULL && type_node->skeleton_die != NULL) >> + die_offset = type_node->skeleton_die->die_offset; >> + } > > > I think we had agreed that if there is no skeleton, we should use an offset > of 0. You're right, I forgot to handle that case. How's this look? if (type_node != NULL) die_offset = (type_node->skeleton_die != NULL ? type_node->skeleton_die->die_offset : 0); Is that OK if it passes regression tests? -cary
OK. Jason
Committed as attached. Thanks for your reviews. Sterling gcc/ChangeLog 2012-06-21 Sterling Augustine <saugustine@google.com> Cary Coutant <ccoutant@google.com> * dwarf2out.c (is_cu_die, is_namespace_die, is_class_die, add_AT_pubnames, add_enumerator_pubname, want_pubnames): New functions. (comdat_type_struct): New field 'skeleton_die'. (breakout_comdat_types): Update it. (add_pubname): Rework logic. Call is_class_die, is_cu_die and is_namespace_die. Fix minor style violation. Call want_pubnames. (add_pubname_string): Call want_pubnames. (add_pubtype): Rework logic for calculating type name. Call is_namespace_die. Call want_pubnames. (output_pubnames): Move conditional logic deciding when to produce the section from dwarf2out_finish. Use new skeleton_die field. (base_type_die): Call add_pubtype. (gen_enumeration_type_die): Unconditionally call add_pubtype. (gen_subprogram_die): Adjust calls to add_pubname. (gen_namespace_die): Call add_pubname_string. (dwarf2out_finish): Call add_AT_pubnames; Move logic on when to produce pubnames and pubtypes sections to output_pubnames. (common.opt): New option '-gpubnames'. (invoke.texi): Document it. On Wed, Jun 20, 2012 at 5:27 PM, Jason Merrill <jason@redhat.com> wrote: > OK. > > Jason
On 06/21/2012 11:18 AM, Sterling Augustine wrote:
> Committed as attached. Thanks for your reviews.
I've heard reports of new test failures due to this patch:
FAIL: gcc.dg/pubtypes-2.c scan-assembler long+[ \\t]+0x6a+[ \\t]+[#;]+[
\\t]+Length of Public Type Names Info
FAIL: gcc.dg/pubtypes-3.c scan-assembler long+[ \\t]+0x6a+[ \\t]+[#;]+[
\\t]+Length of Public Type Names Info
FAIL: gcc.dg/pubtypes-4.c scan-assembler long+[ \\t]+0xa1+[ \\t]+[#;]+[
\\t]+Length of Public Type Names Info
FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++98
scan-assembler-not DW_TAG_enumerator
FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++98
scan-assembler-not DW_TAG_enumeration_type
FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++11
scan-assembler-not DW_TAG_enumerator
FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++11
scan-assembler-not DW_TAG_enumeration_type
For the first group, you probably just need to update the test. For the
second, we still don't want to emit unused enumerations.
Jason
On Fri, Jun 22, 2012 at 2:35 AM, Jason Merrill <jason@redhat.com> wrote: > FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++98 > scan-assembler-not DW_TAG_enumerator > FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++98 > scan-assembler-not DW_TAG_enumeration_type > FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++11 > scan-assembler-not DW_TAG_enumerator > FAIL: g++.dg/debug/dwarf2/static-data-member2.C -std=gnu++11 > scan-assembler-not DW_TAG_enumeration_type This is a side effect of moving enumerators from pubnames to pubtypes as requested in an earlier message in this thread. I should have pushed back harder on this change. prune_unused_types marks everything in the pubnames_table. If the enumerators go in the pubname table (but the enum itself goes in the pubtype table), then the unused enum becomes reachable from the pubnames table. The least complicated solution is to put them back in the pubtypes_table. I could also defer adding them until after types are pruned, I guess. One somewhat unsatisfying way to rationalize it in my mind is to say that as fields are to structs, so are enumerators to enums. What do you think? Sterling gcc/ChangeLog 2012-06-22 Sterling Augustine <sagustine@google.com> * dwarf2out.c (add_enumerator_pubname): Use pubtypes_table.
> prune_unused_types marks everything in the pubnames_table. If the > enumerators go in the pubname table (but the enum itself goes in the > pubtype table), then the unused enum becomes reachable from the > pubnames table. > > The least complicated solution is to put them back in the > pubtypes_table. I could also defer adding them until after types are > pruned, I guess. > > One somewhat unsatisfying way to rationalize it in my mind is to say > that as fields are to structs, so are enumerators to enums. It doesn't matter much to me -- it was working with enumerators in the pubtypes table, as far as I can tell. But if the consensus turns out to be that enumerators should be in pubnames, wouldn't it also be fairly easy to change prune_unused_types so that it doesn't mark enumerators, and change output_pubnames to skip enumerators that have been pruned? -cary
On 06/22/2012 02:15 PM, Cary Coutant wrote: > But if the consensus turns out to be that enumerators should be in > pubnames, wouldn't it also be fairly easy to change prune_unused_types > so that it doesn't mark enumerators, and change output_pubnames to > skip enumerators that have been pruned? This makes sense to me. Jason
On Fri, Jun 22, 2012 at 9:46 PM, Jason Merrill <jason@redhat.com> wrote: > On 06/22/2012 02:15 PM, Cary Coutant wrote: >> >> But if the consensus turns out to be that enumerators should be in >> pubnames, wouldn't it also be fairly easy to change prune_unused_types >> so that it doesn't mark enumerators, and change output_pubnames to >> skip enumerators that have been pruned? > > > This makes sense to me. Enclosed is a patch that does it this way. It requires special-casing enumerators in two places. Personally, it seems cleaner to me just to put them in the pubtypes table, but I am happy to do it whichever way you want. Let me know, Sterling gcc/ChangeLog 2012-06-25 Sterling Augustine <saugustine@google.com> * dwarf2out.c (output_pubnames): Add check for DW_TAG_enumerator. (prune_unused_types): Add check for DW_TAG_enumerator.
OK. Jason
Committed as posted. On Mon, Jun 25, 2012 at 8:35 PM, Jason Merrill <jason@redhat.com> wrote: > OK. > > Jason
>>> But if the consensus turns out to be that enumerators should be in >>> pubnames, wouldn't it also be fairly easy to change prune_unused_types >>> so that it doesn't mark enumerators, and change output_pubnames to >>> skip enumerators that have been pruned? >> >> This makes sense to me. > > Enclosed is a patch that does it this way. It requires special-casing > enumerators in two places. > > Personally, it seems cleaner to me just to put them in the pubtypes > table, but I am happy to do it whichever way you want. Sterling, I think you were right all along -- this fails with -fdebug-types-section. When we move an enumeration type out to a separate types section, the DIE isn't marked when we try to add the enumerators to the pubnames table, so the enumerators never get added to the pubnames table. I'm not sure if there's an easy way to get them added to pubnames in that case; it might be easier to go back to putting them in pubtypes. -cary
Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 188035) +++ gcc/dwarf2out.c (working copy) @@ -2539,6 +2539,7 @@ { dw_die_ref root_die; dw_die_ref type_die; + dw_die_ref skeleton_die; char signature[DWARF_TYPE_SIGNATURE_SIZE]; struct comdat_type_struct *next; } @@ -3013,6 +3014,7 @@ 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 *, 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) *); @@ -3142,6 +3144,7 @@ const char *, const char *); static void output_loc_list (dw_loc_list_ref); static char *gen_internal_sym (const char *); +static bool want_pubnames (void); static void prune_unmark_dies (dw_die_ref); static void prune_unused_types_mark_generic_parms_dies (dw_die_ref); @@ -5972,6 +5975,23 @@ 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 or structure DIE. */ + +static inline bool +is_class_die (dw_die_ref c) +{ + return c && (c->die_tag == DW_TAG_class_type + || c->die_tag == DW_TAG_structure_type); +} + static char * gen_internal_sym (const char *prefix) { @@ -6559,6 +6579,7 @@ declaration into the new type unit DIE, then remove this DIE from the main CU (or replace it with a skeleton if necessary). */ 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); @@ -8034,6 +8055,27 @@ } } +/* Whether to generate the DWARF accelerator tables in .debug_pubnames + and .debug_pubtypes. This is configured per-target, but can be + overridden by the -gpubnames or -gno-pubnames options. */ + +static inline bool +want_pubnames (void) +{ + return (debug_generate_pub_sections != -1 + ? debug_generate_pub_sections + : targetm.want_debug_pub_sections); +} + +/* Add the DW_AT_GNU_pubnames and DW_AT_GNU_pubtypes attributes. */ + +static void +add_AT_pubnames (dw_die_ref die) +{ + if (want_pubnames ()) + add_AT_flag (die, DW_AT_GNU_pubnames, 1); +} + /* Output a comdat type unit DIE and its children. */ static void @@ -8104,7 +8146,7 @@ static void add_pubname_string (const char *str, dw_die_ref die) { - if (targetm.want_debug_pub_sections) + if (want_pubnames ()) { pubname_entry e; @@ -8117,14 +8159,32 @@ static void add_pubname (tree decl, dw_die_ref die) { - if (targetm.want_debug_pub_sections && TREE_PUBLIC (decl)) + if (!want_pubnames ()) + return; + + 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, dw_die_ref die) +{ + pubname_entry e; + + gcc_assert (scope_name); + e.name = concat (scope_name, get_AT_string (die, DW_AT_name), NULL); + e.die = die; + VEC_safe_push (pubname_entry, gc, pubtype_table, &e); +} + /* Add a new entry to .debug_pubtypes if appropriate. */ static void @@ -8132,40 +8192,55 @@ { pubname_entry e; - if (!targetm.want_debug_pub_sections) + if (!want_pubnames ()) return; - 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; - if (TYPE_P (decl)) - { - if (TYPE_NAME (decl)) + tree scope = NULL; + const char *scope_name = ""; + const char *sep = is_cxx () ? "::" : "."; + const char *name; + + scope = TYPE_P (decl) ? TYPE_CONTEXT (decl) : NULL; + if (scope && TREE_CODE (scope) == NAMESPACE_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))); + scope_name = lang_hooks.dwarf_name (scope, 1); + if (scope_name != NULL && scope_name[0] != '\0') + scope_name = concat (scope_name, sep, NULL); else - e.name = xstrdup ((const char *) get_AT_string (die, DW_AT_name)); - } + scope_name = ""; } + + if (TYPE_P (decl)) + 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') + if (name != NULL && name[0] != '\0') + { + e.die = die; + e.name = concat (scope_name, 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. This isn't protected by the name conditional because anoymous + enums don't have names. */ + if (die->die_tag == DW_TAG_enumeration_type) + { + dw_die_ref c; + + FOR_EACH_CHILD (die, c, add_enumerator_pubname (scope_name, c)); + } + } } /* Output the public names table used to speed up access to externally @@ -8178,6 +8253,12 @@ unsigned long pubnames_length = size_of_pubnames (names); pubname_ref pub; + if (!want_pubnames () || !info_section_emitted) + return; + if (names == pubname_table) + switch_to_section (debug_pubnames_section); + else + switch_to_section (debug_pubtypes_section); if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4) dw2_asm_output_data (4, 0xffffffff, "Initial length escape value indicating 64-bit DWARF extension"); @@ -8205,9 +8286,22 @@ || pub->die->die_offset != 0 || !flag_eliminate_unused_debug_types) { - dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset, - "DIE offset"); + dw_offset die_offset = pub->die->die_offset; + /* If we're putting types in their own .debug_types sections, + the .debug_pubtypes table will still point to the compile + unit (not the type unit), so we want to use the offset of + the skeleton DIE (if there is one). */ + if (use_debug_types && names == pubtype_table) + { + comdat_type_node_ref type_node = pub->die->die_id.die_type_node; + + if (type_node != NULL && type_node->skeleton_die != NULL) + die_offset = type_node->skeleton_die->die_offset; + } + + dw2_asm_output_data (DWARF_OFFSET_SIZE, die_offset, "DIE offset"); + dw2_asm_output_nstring (pub->name, -1, "external name"); } } @@ -9091,6 +9185,7 @@ 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; } @@ -16173,7 +16268,6 @@ else add_AT_flag (type_die, DW_AT_declaration, 1); - if (get_AT (type_die, DW_AT_name)) add_pubtype (type, type_die); return type_die; @@ -16813,6 +16907,7 @@ { subr_die = new_die (DW_TAG_subprogram, context_die, decl); add_AT_specification (subr_die, old_die); + add_pubname (decl, subr_die); if (get_AT_file (old_die, DW_AT_decl_file) != file_index) add_AT_file (subr_die, DW_AT_decl_file, file_index); if (get_AT_unsigned (old_die, DW_AT_decl_line) != (unsigned) s.line) @@ -16827,6 +16922,7 @@ add_AT_flag (subr_die, DW_AT_external, 1); add_name_and_src_coords_attributes (subr_die, decl); + add_pubname (decl, subr_die); if (debug_info_level > DINFO_LEVEL_TERSE) { add_prototyped_attribute (subr_die, TREE_TYPE (decl)); @@ -16938,7 +17034,6 @@ } #endif - add_pubname (decl, subr_die); } else { @@ -16959,7 +17054,6 @@ add_ranges_by_labels (subr_die, fde->dw_fde_second_begin, fde->dw_fde_second_end, &range_list_added); - add_pubname (decl, subr_die); if (range_list_added) add_ranges (NULL); } @@ -16981,8 +17075,6 @@ fde->dw_fde_begin); add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end); - /* Add it. */ - add_pubname (decl, subr_die); /* Build a minimal DIE for the secondary section. */ seg_die = new_die (DW_TAG_subprogram, @@ -17018,7 +17110,6 @@ { add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin); add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end); - add_pubname (decl, subr_die); } } @@ -19049,6 +19140,8 @@ 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. @@ -22309,6 +22402,8 @@ } htab_delete (comdat_type_table); + add_AT_pubnames (comp_unit_die ()); + /* Output the main compilation unit if non-empty or if .debug_macinfo or .debug_macro will be emitted. */ output_comp_unit (comp_unit_die (), have_macinfo); @@ -22332,42 +22427,12 @@ 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 the address range information if a CU (.debug_info section) was emitted. We output an empty table even if we had no functions Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 188034) +++ gcc/common.opt (working copy) @@ -2239,6 +2239,14 @@ Common JoinedOrMissing Generate debug information in default extended format +gno-pubnames +Common RejectNegative Var(debug_generate_pub_sections, 0) Init(-1) +Don't generate DWARF pubnames and pubtypes sections. + +gpubnames +Common RejectNegative Var(debug_generate_pub_sections, 1) +Generate DWARF pubnames and pubtypes sections. + gno-record-gcc-switches Common RejectNegative Var(dwarf_record_gcc_switches,0) Init(1) Don't record gcc command line switches in DWARF DW_AT_producer. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 188034) +++ gcc/doc/invoke.texi (working copy) @@ -4799,6 +4799,10 @@ if neither of those are supported), including GDB extensions if at all possible. +@item -gpubnames +@opindex gpubnames +Generate dwarf .debug_pubnames and .debug_pubtypes sections. + @item -gstabs @opindex gstabs Produce debugging information in stabs format (if that is supported),