Run all CodeView names through a new function get_name, which chains together a DIE's DW_AT_name with that of its parent to create a C++-style name.
gcc/ * dwarf2codeview.cc (get_name): New function. (add_enum_forward_def): Call get_name. (get_type_num_enumeration_type): Call get_name. (add_struct_forward_def): Call get_name. (get_type_num_struct): Call get_name. (add_variable): Call get_name. (add function): Call get_name. * dwarf2out.cc (get_die_parent): Rename to dw_get_die_parent and make non-static. (generate_type_signature): Handle renamed get_die_parent. * dwarf2out.h (dw_get_die_parent): Add declaration. --- gcc/dwarf2codeview.cc | 92 +++++++++++++++++++++++++++++++++++++------ gcc/dwarf2out.cc | 6 +-- gcc/dwarf2out.h | 1 + 3 files changed, 83 insertions(+), 16 deletions(-) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index e4c67f921cd..b71c592b70c 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -4511,6 +4511,79 @@ get_type_num_volatile_type (dw_die_ref type, bool in_struct) return ct->num; } +/* Return the name of a DIE, traversing its parents in order to construct a + C++-style name if necessary. */ +static char * +get_name (dw_die_ref die) +{ + dw_die_ref decl = get_AT_ref (die, DW_AT_specification); + dw_die_ref parent; + const char *name; + char *str; + size_t len; + + static const char anon[] = "<unnamed-tag>"; + static const char sep[] = "::"; + + if (decl) + die = decl; + + name = get_AT_string (die, DW_AT_name); + + if (!name) + return NULL; + + parent = dw_get_die_parent (die); + + if (!parent || dw_get_die_tag (parent) == DW_TAG_compile_unit) + return xstrdup (name); + + len = strlen (name); + while (parent && dw_get_die_tag (parent) != DW_TAG_compile_unit) + { + const char *ns_name = get_AT_string (parent, DW_AT_name); + + len += sizeof (sep) - 1; + + if (ns_name) + len += strlen (ns_name); + else + len += sizeof (anon) - 1; + + parent = dw_get_die_parent (parent); + } + + str = (char *) xmalloc (len + 1); + str[len] = 0; + + len -= strlen (name); + memcpy (str + len, name, strlen (name)); + + parent = dw_get_die_parent (die); + while (parent && dw_get_die_tag (parent) != DW_TAG_compile_unit) + { + const char *ns_name = get_AT_string (parent, DW_AT_name); + + len -= sizeof (sep) - 1; + memcpy (str + len, sep, sizeof (sep) - 1); + + if (ns_name) + { + len -= strlen (ns_name); + memcpy (str + len, ns_name, strlen (ns_name)); + } + else + { + len -= sizeof (anon) - 1; + memcpy (str + len, anon, sizeof (anon) - 1); + } + + parent = dw_get_die_parent (parent); + } + + return str; +} + /* Add a forward declaration for an enum. This is legal from C++11 onwards. */ static uint32_t @@ -4528,7 +4601,7 @@ add_enum_forward_def (dw_die_ref type) ct->lf_enum.underlying_type = get_type_num (get_AT_ref (type, DW_AT_type), false, false); ct->lf_enum.fieldlist = 0; - ct->lf_enum.name = xstrdup (get_AT_string (type, DW_AT_name)); + ct->lf_enum.name = get_name (type); add_custom_type (ct); @@ -4688,7 +4761,7 @@ get_type_num_enumeration_type (dw_die_ref type, bool in_struct) ct->lf_enum.underlying_type = get_type_num (get_AT_ref (type, DW_AT_type), in_struct, false); ct->lf_enum.fieldlist = last_type; - ct->lf_enum.name = xstrdup (get_AT_string (type, DW_AT_name)); + ct->lf_enum.name = get_name (type); add_custom_type (ct); @@ -4775,7 +4848,7 @@ add_struct_forward_def (dw_die_ref type) ct->lf_structure.vshape = 0; ct->lf_structure.length.neg = false; ct->lf_structure.length.num = 0; - ct->lf_structure.name = xstrdup (get_AT_string (type, DW_AT_name)); + ct->lf_structure.name = get_name (type); add_custom_type (ct); @@ -4823,7 +4896,6 @@ get_type_num_struct (dw_die_ref type, bool in_struct, bool *is_fwd_ref) codeview_custom_type *ct; uint16_t num_members = 0; uint32_t last_type = 0; - const char *name; if ((in_struct && get_AT_string (type, DW_AT_name)) || get_AT_flag (type, DW_AT_declaration)) @@ -5010,13 +5082,7 @@ get_type_num_struct (dw_die_ref type, bool in_struct, bool *is_fwd_ref) ct->lf_structure.vshape = 0; ct->lf_structure.length.neg = false; ct->lf_structure.length.num = get_AT_unsigned (type, DW_AT_byte_size); - - name = get_AT_string (type, DW_AT_name); - - if (name) - ct->lf_structure.name = xstrdup (name); - else - ct->lf_structure.name = NULL; + ct->lf_structure.name = get_name (type); add_custom_type (ct); @@ -5384,7 +5450,7 @@ add_variable (dw_die_ref die) s->kind = get_AT (die, DW_AT_external) ? S_GDATA32 : S_LDATA32; s->data_symbol.type = get_type_num (get_AT_ref (die, DW_AT_type), false, false); - s->data_symbol.name = xstrdup (name); + s->data_symbol.name = get_name (die); s->data_symbol.die = die; if (last_sym) @@ -5436,7 +5502,7 @@ add_function (dw_die_ref die) s->function.next = 0; s->function.type = func_id_type; s->function.flags = 0; - s->function.name = xstrdup (name); + s->function.name = get_name (die); s->function.die = die; if (last_sym) diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 633900b035f..ae8edaba236 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -5450,8 +5450,8 @@ get_AT (dw_die_ref die, enum dwarf_attribute attr_kind) /* Returns the parent of the declaration of DIE. */ -static dw_die_ref -get_die_parent (dw_die_ref die) +dw_die_ref +dw_get_die_parent (dw_die_ref die) { dw_die_ref t; @@ -7783,7 +7783,7 @@ generate_type_signature (dw_die_ref die, comdat_type_node *type_node) name = get_AT_string (die, DW_AT_name); decl = get_AT_ref (die, DW_AT_specification); - parent = get_die_parent (die); + parent = dw_get_die_parent (die); /* First, compute a signature for just the type name (and its surrounding context, if any. This is stored in the type unit DIE for link-time diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index f8270c8601f..ded1697ecf6 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -522,6 +522,7 @@ extern dw_die_ref lookup_type_die (tree); extern dw_die_ref dw_get_die_child (dw_die_ref); extern dw_die_ref dw_get_die_sib (dw_die_ref); +extern dw_die_ref dw_get_die_parent (dw_die_ref); extern enum dwarf_tag dw_get_die_tag (dw_die_ref); /* Data about a single source file. */ -- 2.44.2