dwarf2out.c (is_cu_die, [...]): New functions.

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.


Co-Authored-By: Cary Coutant <ccoutant@google.com>

From-SVN: r188857
This commit is contained in:
Sterling Augustine 2012-06-21 18:16:05 +00:00 committed by Sterling Augustine
parent 8ca92d04e1
commit 5175cbafd2
4 changed files with 165 additions and 63 deletions

View file

@ -1,3 +1,26 @@
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.
2012-06-21 Steven Bosscher <steven@gcc.gnu.org>
* config/m32c/m32c-pragma.c: Remove unnecessary includes.

View file

@ -2243,6 +2243,14 @@ ggdb
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.

View file

@ -4795,6 +4795,10 @@ most expressive format available (DWARF 2, stabs, or the native format
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),

View file

@ -2538,6 +2538,7 @@ typedef struct GTY(()) comdat_type_struct
{
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;
}
@ -3012,6 +3013,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 *, 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) *);
@ -3141,6 +3143,7 @@ static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *,
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);
@ -5981,6 +5984,23 @@ is_unit_die (dw_die_ref c)
|| c->die_tag == DW_TAG_type_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)
{
@ -6567,6 +6587,7 @@ break_out_comdat_types (dw_die_ref die)
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);
@ -8040,6 +8061,27 @@ output_comp_unit (dw_die_ref die, int output_if_empty)
}
}
/* 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
@ -8110,7 +8152,7 @@ dwarf2_name (tree decl, int scope)
static void
add_pubname_string (const char *str, dw_die_ref die)
{
if (targetm.want_debug_pub_sections)
if (want_pubnames ())
{
pubname_entry e;
@ -8123,14 +8165,32 @@ add_pubname_string (const char *str, dw_die_ref die)
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, pubname_table, &e);
}
/* Add a new entry to .debug_pubtypes if appropriate. */
static void
@ -8138,40 +8198,55 @@ add_pubtype (tree decl, dw_die_ref die)
{
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 anonymous
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
@ -8184,6 +8259,12 @@ output_pubnames (VEC (pubname_entry, gc) * names)
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");
@ -8211,8 +8292,23 @@ output_pubnames (VEC (pubname_entry, gc) * names)
|| 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 (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)
die_offset = (type_node->skeleton_die != NULL
? type_node->skeleton_die->die_offset
: 0);
}
dw2_asm_output_data (DWARF_OFFSET_SIZE, die_offset, "DIE offset");
dw2_asm_output_nstring (pub->name, -1, "external name");
}
@ -9097,6 +9193,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;
}
@ -16179,7 +16276,6 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
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;
@ -16843,6 +16939,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
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)
@ -16857,6 +16954,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
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));
@ -16968,7 +17066,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
}
#endif
add_pubname (decl, subr_die);
}
else
{
@ -16989,7 +17086,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
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);
}
@ -17011,8 +17107,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
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,
@ -17048,7 +17142,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
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);
}
}
@ -19089,6 +19182,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.
@ -22364,6 +22459,8 @@ dwarf2out_finish (const char *filename)
}
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);
@ -22387,42 +22484,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 the address range information if a CU (.debug_info section)
was emitted. We output an empty table even if we had no functions