Commit 5175cbaf by Sterling Augustine Committed by Sterling Augustine

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
parent 8ca92d04
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> 2012-06-21 Steven Bosscher <steven@gcc.gnu.org>
* config/m32c/m32c-pragma.c: Remove unnecessary includes. * config/m32c/m32c-pragma.c: Remove unnecessary includes.
......
...@@ -2243,6 +2243,14 @@ ggdb ...@@ -2243,6 +2243,14 @@ ggdb
Common JoinedOrMissing Common JoinedOrMissing
Generate debug information in default extended format 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 gno-record-gcc-switches
Common RejectNegative Var(dwarf_record_gcc_switches,0) Init(1) Common RejectNegative Var(dwarf_record_gcc_switches,0) Init(1)
Don't record gcc command line switches in DWARF DW_AT_producer. Don't record gcc command line switches in DWARF DW_AT_producer.
......
...@@ -4795,6 +4795,10 @@ most expressive format available (DWARF 2, stabs, or the native format ...@@ -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 if neither of those are supported), including GDB extensions if at all
possible. possible.
@item -gpubnames
@opindex gpubnames
Generate dwarf .debug_pubnames and .debug_pubtypes sections.
@item -gstabs @item -gstabs
@opindex gstabs @opindex gstabs
Produce debugging information in stabs format (if that is supported), Produce debugging information in stabs format (if that is supported),
......
...@@ -2538,6 +2538,7 @@ typedef struct GTY(()) comdat_type_struct ...@@ -2538,6 +2538,7 @@ typedef struct GTY(()) comdat_type_struct
{ {
dw_die_ref root_die; dw_die_ref root_die;
dw_die_ref type_die; dw_die_ref type_die;
dw_die_ref skeleton_die;
char signature[DWARF_TYPE_SIGNATURE_SIZE]; char signature[DWARF_TYPE_SIGNATURE_SIZE];
struct comdat_type_struct *next; struct comdat_type_struct *next;
} }
...@@ -3012,6 +3013,7 @@ static void output_comp_unit (dw_die_ref, int); ...@@ -3012,6 +3013,7 @@ static void output_comp_unit (dw_die_ref, int);
static void output_comdat_type_unit (comdat_type_node *); static void output_comdat_type_unit (comdat_type_node *);
static const char *dwarf2_name (tree, int); static const char *dwarf2_name (tree, int);
static void add_pubname (tree, dw_die_ref); 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_pubname_string (const char *, dw_die_ref);
static void add_pubtype (tree, dw_die_ref); static void add_pubtype (tree, dw_die_ref);
static void output_pubnames (VEC (pubname_entry,gc) *); 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 *, ...@@ -3141,6 +3143,7 @@ static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *,
const char *, const char *); const char *, const char *);
static void output_loc_list (dw_loc_list_ref); static void output_loc_list (dw_loc_list_ref);
static char *gen_internal_sym (const char *); static char *gen_internal_sym (const char *);
static bool want_pubnames (void);
static void prune_unmark_dies (dw_die_ref); static void prune_unmark_dies (dw_die_ref);
static void prune_unused_types_mark_generic_parms_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) ...@@ -5981,6 +5984,23 @@ is_unit_die (dw_die_ref c)
|| c->die_tag == DW_TAG_type_unit); || 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 * static char *
gen_internal_sym (const char *prefix) gen_internal_sym (const char *prefix)
{ {
...@@ -6567,6 +6587,7 @@ break_out_comdat_types (dw_die_ref die) ...@@ -6567,6 +6587,7 @@ break_out_comdat_types (dw_die_ref die)
declaration into the new type unit DIE, then remove this DIE declaration into the new type unit DIE, then remove this DIE
from the main CU (or replace it with a skeleton if necessary). */ from the main CU (or replace it with a skeleton if necessary). */
replacement = remove_child_or_replace_with_skeleton (unit, c, prev); 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 nested types into their own type units. */
break_out_comdat_types (c); break_out_comdat_types (c);
...@@ -8040,6 +8061,27 @@ output_comp_unit (dw_die_ref die, int output_if_empty) ...@@ -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. */ /* Output a comdat type unit DIE and its children. */
static void static void
...@@ -8110,7 +8152,7 @@ dwarf2_name (tree decl, int scope) ...@@ -8110,7 +8152,7 @@ dwarf2_name (tree decl, int scope)
static void static void
add_pubname_string (const char *str, dw_die_ref die) add_pubname_string (const char *str, dw_die_ref die)
{ {
if (targetm.want_debug_pub_sections) if (want_pubnames ())
{ {
pubname_entry e; pubname_entry e;
...@@ -8123,14 +8165,32 @@ add_pubname_string (const char *str, dw_die_ref die) ...@@ -8123,14 +8165,32 @@ add_pubname_string (const char *str, dw_die_ref die)
static void static void
add_pubname (tree decl, dw_die_ref die) 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); const char *name = dwarf2_name (decl, 1);
if (name) if (name)
add_pubname_string (name, die); 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. */ /* Add a new entry to .debug_pubtypes if appropriate. */
static void static void
...@@ -8138,40 +8198,55 @@ add_pubtype (tree decl, dw_die_ref die) ...@@ -8138,40 +8198,55 @@ add_pubtype (tree decl, dw_die_ref die)
{ {
pubname_entry e; pubname_entry e;
if (!targetm.want_debug_pub_sections) if (!want_pubnames ())
return; return;
e.name = NULL;
if ((TREE_PUBLIC (decl) 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))) && (die->die_tag == DW_TAG_typedef || COMPLETE_TYPE_P (decl)))
{ {
e.die = die; tree scope = NULL;
if (TYPE_P (decl)) const char *scope_name = "";
{ const char *sep = is_cxx () ? "::" : ".";
if (TYPE_NAME (decl)) 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) scope_name = lang_hooks.dwarf_name (scope, 1);
e.name = IDENTIFIER_POINTER (TYPE_NAME (decl)); if (scope_name != NULL && scope_name[0] != '\0')
else if (TREE_CODE (TYPE_NAME (decl)) == TYPE_DECL scope_name = concat (scope_name, sep, NULL);
&& DECL_NAME (TYPE_NAME (decl)))
e.name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (decl)));
else else
e.name = xstrdup ((const char *) get_AT_string (die, DW_AT_name)); scope_name = "";
}
} }
if (TYPE_P (decl))
name = type_tag (decl);
else else
{ name = lang_hooks.dwarf_name (decl, 1);
e.name = dwarf2_name (decl, 1);
if (e.name)
e.name = xstrdup (e.name);
}
/* If we don't have a name for the type, there's no point in adding /* If we don't have a name for the type, there's no point in adding
it to the table. */ 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); 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 /* Output the public names table used to speed up access to externally
...@@ -8184,6 +8259,12 @@ output_pubnames (VEC (pubname_entry, gc) * names) ...@@ -8184,6 +8259,12 @@ output_pubnames (VEC (pubname_entry, gc) * names)
unsigned long pubnames_length = size_of_pubnames (names); unsigned long pubnames_length = size_of_pubnames (names);
pubname_ref pub; 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) if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
dw2_asm_output_data (4, 0xffffffff, dw2_asm_output_data (4, 0xffffffff,
"Initial length escape value indicating 64-bit DWARF extension"); "Initial length escape value indicating 64-bit DWARF extension");
...@@ -8211,8 +8292,23 @@ output_pubnames (VEC (pubname_entry, gc) * names) ...@@ -8211,8 +8292,23 @@ output_pubnames (VEC (pubname_entry, gc) * names)
|| pub->die->die_offset != 0 || pub->die->die_offset != 0
|| !flag_eliminate_unused_debug_types) || !flag_eliminate_unused_debug_types)
{ {
dw2_asm_output_data (DWARF_OFFSET_SIZE, pub->die->die_offset, dw_offset die_offset = pub->die->die_offset;
"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"); dw2_asm_output_nstring (pub->name, -1, "external name");
} }
...@@ -9097,6 +9193,7 @@ base_type_die (tree type) ...@@ -9097,6 +9193,7 @@ base_type_die (tree type)
add_AT_unsigned (base_type_result, DW_AT_byte_size, add_AT_unsigned (base_type_result, DW_AT_byte_size,
int_size_in_bytes (type)); int_size_in_bytes (type));
add_AT_unsigned (base_type_result, DW_AT_encoding, encoding); add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
add_pubtype (type, base_type_result);
return base_type_result; return base_type_result;
} }
...@@ -16179,7 +16276,6 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) ...@@ -16179,7 +16276,6 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
else else
add_AT_flag (type_die, DW_AT_declaration, 1); add_AT_flag (type_die, DW_AT_declaration, 1);
if (get_AT (type_die, DW_AT_name))
add_pubtype (type, type_die); add_pubtype (type, type_die);
return type_die; return type_die;
...@@ -16843,6 +16939,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_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); subr_die = new_die (DW_TAG_subprogram, context_die, decl);
add_AT_specification (subr_die, old_die); add_AT_specification (subr_die, old_die);
add_pubname (decl, subr_die);
if (get_AT_file (old_die, DW_AT_decl_file) != file_index) if (get_AT_file (old_die, DW_AT_decl_file) != file_index)
add_AT_file (subr_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) 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) ...@@ -16857,6 +16954,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
add_AT_flag (subr_die, DW_AT_external, 1); add_AT_flag (subr_die, DW_AT_external, 1);
add_name_and_src_coords_attributes (subr_die, decl); add_name_and_src_coords_attributes (subr_die, decl);
add_pubname (decl, subr_die);
if (debug_info_level > DINFO_LEVEL_TERSE) if (debug_info_level > DINFO_LEVEL_TERSE)
{ {
add_prototyped_attribute (subr_die, TREE_TYPE (decl)); add_prototyped_attribute (subr_die, TREE_TYPE (decl));
...@@ -16968,7 +17066,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -16968,7 +17066,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
} }
#endif #endif
add_pubname (decl, subr_die);
} }
else else
{ {
...@@ -16989,7 +17086,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -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, add_ranges_by_labels (subr_die, fde->dw_fde_second_begin,
fde->dw_fde_second_end, fde->dw_fde_second_end,
&range_list_added); &range_list_added);
add_pubname (decl, subr_die);
if (range_list_added) if (range_list_added)
add_ranges (NULL); add_ranges (NULL);
} }
...@@ -17011,8 +17107,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -17011,8 +17107,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
fde->dw_fde_begin); fde->dw_fde_begin);
add_AT_lbl_id (subr_die, DW_AT_high_pc, add_AT_lbl_id (subr_die, DW_AT_high_pc,
fde->dw_fde_end); fde->dw_fde_end);
/* Add it. */
add_pubname (decl, subr_die);
/* Build a minimal DIE for the secondary section. */ /* Build a minimal DIE for the secondary section. */
seg_die = new_die (DW_TAG_subprogram, seg_die = new_die (DW_TAG_subprogram,
...@@ -17048,7 +17142,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -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_low_pc, fde->dw_fde_begin);
add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end); 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) ...@@ -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); add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
equate_decl_number_to_die (decl, namespace_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. /* Generate Dwarf debug information for a decl described by DECL.
...@@ -22364,6 +22459,8 @@ dwarf2out_finish (const char *filename) ...@@ -22364,6 +22459,8 @@ dwarf2out_finish (const char *filename)
} }
htab_delete (comdat_type_table); htab_delete (comdat_type_table);
add_AT_pubnames (comp_unit_die ());
/* Output the main compilation unit if non-empty or if .debug_macinfo /* Output the main compilation unit if non-empty or if .debug_macinfo
or .debug_macro will be emitted. */ or .debug_macro will be emitted. */
output_comp_unit (comp_unit_die (), have_macinfo); output_comp_unit (comp_unit_die (), have_macinfo);
...@@ -22387,42 +22484,12 @@ dwarf2out_finish (const char *filename) ...@@ -22387,42 +22484,12 @@ dwarf2out_finish (const char *filename)
output_location_lists (comp_unit_die ()); output_location_lists (comp_unit_die ());
} }
/* Output public names table if necessary. */ /* Output public names and types tables 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_pubnames (pubname_table);
}
/* Output public types table if necessary. */
/* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2. /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
It shouldn't hurt to emit it always, since pure DWARF2 consumers It shouldn't hurt to emit it always, since pure DWARF2 consumers
simply won't look for the section. */ 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) /* Output the address range information if a CU (.debug_info section)
was emitted. We output an empty table even if we had no functions was emitted. We output an empty table even if we had no functions
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment