summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2004-04-02 02:47:30 +0000
committerDaniel Jacobowitz <dan@debian.org>2004-04-02 02:47:30 +0000
commita440813af887693e6ef62246fe4807680d848ec9 (patch)
tree0966ded3b309bbd45cbbc2f1ce61ca72266593fe
parent024143a9771b2744804210caf6c5e4d191487739 (diff)
downloadgdb-a440813af887693e6ef62246fe4807680d848ec9.tar.gz
* dwarf2read.c (struct partial_die_info): Replace full_name and
full_name_set with scope and scope_set. (partial_die_parent_scope): New function. (partial_die_full_name): Use it. (add_partial_symbol): Don't check full_name_set or set full_name. (add_partial_namespace): Remove unused variable. (guess_partial_structure): New function, broken out from add_partial_structure. Set the name field of the partial DIE. (add_partial_structure): Simplify. (find_partial_die): Always set *TARGET_CU. (fixup_partial_die): Call guess_structure_scope. Set the names of anonymous classes and namespaces.
-rw-r--r--gdb/ChangeLog.intercu15
-rw-r--r--gdb/dwarf2read.c210
2 files changed, 151 insertions, 74 deletions
diff --git a/gdb/ChangeLog.intercu b/gdb/ChangeLog.intercu
index 36dad0de076..772d2a8f3b1 100644
--- a/gdb/ChangeLog.intercu
+++ b/gdb/ChangeLog.intercu
@@ -1,5 +1,20 @@
2004-04-01 Daniel Jacobowitz <drow@mvista.com>
+ * dwarf2read.c (struct partial_die_info): Replace full_name and
+ full_name_set with scope and scope_set.
+ (partial_die_parent_scope): New function.
+ (partial_die_full_name): Use it.
+ (add_partial_symbol): Don't check full_name_set or set full_name.
+ (add_partial_namespace): Remove unused variable.
+ (guess_partial_structure): New function, broken out from
+ add_partial_structure. Set the name field of the partial DIE.
+ (add_partial_structure): Simplify.
+ (find_partial_die): Always set *TARGET_CU.
+ (fixup_partial_die): Call guess_structure_scope. Set the names
+ of anonymous classes and namespaces.
+
+2004-04-01 Daniel Jacobowitz <drow@mvista.com>
+
* dwarf2read.c (struct dwarf2_cu): Add has_form_ref_addr and
has_namespace_info.
(dwarf2_read_abbrevs): Set the new flags. Change return type back
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 5b66cb2f3dc..f80edb099ea 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -526,9 +526,14 @@ struct partial_die_info
unsigned int has_type : 1;
unsigned int has_specification : 1;
unsigned int has_pc_info : 1;
- unsigned int full_name_set : 1;
+ unsigned int scope_set : 1;
char *name;
- char *full_name;
+
+ /* The scope to prepend to our children. This is generally
+ allocated on the partial_die_obstack, so will disappear
+ when this compilation unit leaves the cache. */
+ char *scope;
+
struct dwarf_block *locdesc;
CORE_ADDR lowpc;
CORE_ADDR highpc;
@@ -1747,64 +1752,98 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
}
}
-/* Return the fully scoped name associated with PDI, from compilation unit
- CU. The result will be allocated with malloc, or NULL if PDI->NAME should
- be used. */
+/* Functions used to compute the fully scoped name of a partial DIE.
+
+ Normally, this is simple. For C++, the parent DIE's fully scoped
+ name is concatenated with "::" and the partial DIE's name.
+ Enumerators are an exception; they use the scope of their parent
+ enumeration type, i.e. the name of the enumeration type is not
+ prepended to the enumerator.
+
+ There are two complexities. One is DW_AT_specification; in this
+ case "parent" means the parent of the target of the specification,
+ instead of the direct parent of the DIE. The other is compilers
+ which do not emit DW_TAG_namespace; in this case we try to guess
+ the fully qualified name of structure types from their members'
+ linkage names. This must be done using the DIE's children rather
+ than the children of any DW_AT_specification target. We only need
+ to do this for structures at the top level, i.e. if the target of
+ any DW_AT_specification (if any; otherwise the DIE itself) does not
+ have a parent. */
+
+/* Compute the scope prefix associated with PDI's parent, in
+ compilation unit CU. The result will be allocated on CU's
+ partial_die_obstack, or a copy of the already allocated PDI->NAME
+ field. NULL is returned if no prefix is necessary. */
static char *
-partial_die_full_name (struct partial_die_info *pdi,
- struct dwarf2_cu *cu)
+partial_die_parent_scope (struct partial_die_info *pdi,
+ struct dwarf2_cu *cu)
{
- char *parent_name = NULL, *full_name;
- struct partial_die_info *real_pdi, *real_parent;
+ char *grandparent_scope;
+ struct partial_die_info *parent, *real_pdi;
struct dwarf2_cu *spec_cu;
- int free_parent_name = 0;
- /* We shouldn't even have been called in this case. */
- gdb_assert (!pdi->full_name_set);
-
- /* Note: this code could probably be micro-optimized. We may be
- able to avoid redoing the hash table lookup, and we might be able
- to use real_pdi->full_name if there is a specification. */
+ /* We need to look at our parent DIE; if we have a DW_AT_specification,
+ then this means the parent of the specification DIE. */
real_pdi = pdi;
spec_cu = cu;
while (real_pdi->has_specification)
real_pdi = find_partial_die (real_pdi->spec_offset, spec_cu, &spec_cu);
- /* NOTE drow/2004-02-22: The following code is a hack. It's only used when
- visiting the DIEs out of order, i.e. due to DW_AT_specification in another
- CU or later in this CU. It's correct, but somewhat inefficient. */
+ parent = real_pdi->die_parent;
+ if (parent == NULL)
+ return NULL;
+
+ if (parent->scope_set)
+ return parent->scope;
- if (real_pdi->full_name_set)
- return xstrdup (real_pdi->full_name);
+ fixup_partial_die (parent, cu);
- real_parent = real_pdi->die_parent;
- if (real_parent == NULL)
+ grandparent_scope = partial_die_parent_scope (parent, spec_cu);
+
+ if (parent->tag == DW_TAG_namespace
+ || parent->tag == DW_TAG_structure_type
+ || parent->tag == DW_TAG_class_type
+ || parent->tag == DW_TAG_union_type)
{
- real_pdi->full_name_set = 1;
- return NULL;
+ if (grandparent_scope == NULL)
+ parent->scope = parent->name;
+ else
+ parent->scope = obconcat (&cu->partial_die_obstack, grandparent_scope,
+ "::", parent->name);
}
-
- if (!real_parent->full_name_set)
+ else if (parent->tag == DW_TAG_enumeration_type)
+ /* Enumerators should not get the name of the enumeration as a prefix. */
+ parent->scope = grandparent_scope;
+ else
{
- fixup_partial_die (real_parent, spec_cu);
- parent_name = partial_die_full_name (real_parent, spec_cu);
- /* Could cache the full name, too. */
- if (parent_name != NULL)
- free_parent_name = 1;
+ /* FIXME drow/2004-04-01: What should we be doing with
+ function-local names? For partial symbols, we should probably be
+ ignoring them. */
+ complaint (&symfile_complaints,
+ "unhandled containing DIE tag %d for DIE at %d",
+ parent->tag, pdi->offset);
+ parent->scope = grandparent_scope;
}
+
+ parent->scope_set = 1;
+ return parent->scope;
+}
- /* End hack zone. */
-
- if (parent_name == NULL)
- parent_name = real_parent->full_name;
- if (parent_name == NULL)
- parent_name = real_parent->name;
+/* Return the fully scoped name associated with PDI, from compilation unit
+ CU. The result will be allocated with malloc. */
+static char *
+partial_die_full_name (struct partial_die_info *pdi,
+ struct dwarf2_cu *cu)
+{
+ char *parent_scope;
- full_name = concat (parent_name, "::", real_pdi->name, NULL);
- if (free_parent_name)
- free (parent_name);
- return full_name;
+ parent_scope = partial_die_parent_scope (pdi, cu);
+ if (parent_scope == NULL)
+ return NULL;
+ else
+ return concat (parent_scope, "::", pdi->name, NULL);
}
static void
@@ -1821,9 +1860,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
actual_name = NULL;
- if (!pdi->full_name_set
- && pdi_needs_namespace (pdi->tag)
- && pdi->full_name == NULL)
+
+ if (pdi_needs_namespace (pdi->tag))
{
actual_name = partial_die_full_name (pdi, cu);
if (actual_name)
@@ -1831,14 +1869,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
}
if (actual_name == NULL)
- {
- if (pdi->full_name != NULL)
- actual_name = pdi->full_name;
- else
- actual_name = pdi->name;
- }
-
- pdi->full_name_set = 1;
+ actual_name = pdi->name;
switch (pdi->tag)
{
@@ -1976,7 +2007,6 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
/* psym2 should always be set in the built_actual_name case,
because the same set are used in pdi_needs_namespace. See
FIXME above. */
- pdi->full_name = SYMBOL_LINKAGE_NAME (psym2);
xfree (actual_name);
}
}
@@ -2013,7 +2043,6 @@ add_partial_namespace (struct partial_die_info *pdi,
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- char *full_name;
/* Calculate the full name of the namespace that we just entered. */
@@ -2028,27 +2057,18 @@ add_partial_namespace (struct partial_die_info *pdi,
scan_partial_symbols (pdi->die_child, lowpc, highpc, cu);
}
-/* Read a partial die corresponding to a class or structure. */
+/* See if we can figure out if the class lives in a namespace. We do
+ this by looking for a member function; its demangled name will
+ contain namespace info, if there is any. */
-static void
-add_partial_structure (struct partial_die_info *struct_pdi,
- struct dwarf2_cu *cu)
+void
+guess_structure_name (struct partial_die_info *struct_pdi,
+ struct dwarf2_cu *cu)
{
- bfd *abfd = cu->objfile->obfd;
- char *full_name;
-
- if (struct_pdi->name == NULL)
- struct_pdi->name = "(anonymous class)";
-
if (cu->language == language_cplus
&& cu->has_namespace_info == 0
&& struct_pdi->has_children)
{
- /* See if we can figure out if the class lives in a namespace
- (or is nested within another class.) We do this by looking
- for a member function; its demangled name will contain
- namespace info, if there is any. */
-
/* NOTE: carlton/2003-10-07: Getting the info this way changes
what template types look like, because the demangler
frequently doesn't give the same name as the debug info. We
@@ -2056,6 +2076,20 @@ add_partial_structure (struct partial_die_info *struct_pdi,
prefix (but see comment in read_structure_type). */
struct partial_die_info *child_pdi = struct_pdi->die_child;
+ struct partial_die_info *real_pdi;
+ struct dwarf2_cu *spec_cu;
+
+ /* If this DIE (this DIE's specification, if any) has a parent, then
+ we should not do this. We'll prepend the parent's fully qualified
+ name when we create the partial symbol. */
+
+ real_pdi = struct_pdi;
+ spec_cu = cu;
+ while (real_pdi->has_specification)
+ real_pdi = find_partial_die (real_pdi->spec_offset, spec_cu, &spec_cu);
+
+ if (real_pdi->die_parent != NULL)
+ return;
while (child_pdi != NULL)
{
@@ -2065,7 +2099,7 @@ add_partial_structure (struct partial_die_info *struct_pdi,
= class_name_from_physname (child_pdi->name);
if (actual_class_name != NULL)
{
- struct_pdi->full_name
+ struct_pdi->name
= obsavestring (actual_class_name,
strlen (actual_class_name),
&cu->partial_die_obstack);
@@ -2077,6 +2111,18 @@ add_partial_structure (struct partial_die_info *struct_pdi,
child_pdi = child_pdi->die_sibling;
}
}
+}
+
+/* Read a partial die corresponding to a class or structure. */
+
+static void
+add_partial_structure (struct partial_die_info *struct_pdi,
+ struct dwarf2_cu *cu)
+{
+ bfd *abfd = cu->objfile->obfd;
+
+ if (struct_pdi->name == NULL)
+ struct_pdi->name = "(anonymous class)";
add_partial_symbol (struct_pdi, cu);
}
@@ -5362,7 +5408,10 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu,
if (offset >= cu->header.offset
&& offset < cu->header.offset + cu->header.length)
- return find_partial_die_in_comp_unit (offset, cu);
+ {
+ *target_cu = cu;
+ return find_partial_die_in_comp_unit (offset, cu);
+ }
per_cu = dwarf2_find_containing_comp_unit (offset, cu);
gdb_assert (per_cu != NULL);
@@ -5383,8 +5432,8 @@ static void
fixup_partial_die (struct partial_die_info *part_die,
struct dwarf2_cu *cu)
{
- /* If we found a reference attribute and the die has no name, try
- to find a name in the referred to die. */
+ /* If we found a reference attribute and the DIE has no name, try
+ to find a name in the referred to DIE. */
if (part_die->name == NULL && part_die->has_specification)
{
@@ -5404,6 +5453,19 @@ fixup_partial_die (struct partial_die_info *part_die,
part_die->is_external = spec_die->is_external;
}
}
+
+ /* Set default names for some unnamed DIEs. */
+ if (part_die->name == NULL && (part_die->tag == DW_TAG_structure_type
+ || part_die->tag == DW_TAG_class_type))
+ part_die->name = "(anonymous class)";
+
+ if (part_die->name == NULL && part_die->tag == DW_TAG_namespace)
+ part_die->name = "(anonymous namespace)";
+
+ if (part_die->tag == DW_TAG_structure_type
+ || part_die->tag == DW_TAG_structure_type
+ || part_die->tag == DW_TAG_union_type)
+ guess_structure_name (part_die, cu);
}
/* Read the die from the .debug_info section buffer. Set DIEP to