This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[dictionary] follow DW_AT_specification in structure names
- From: David Carlton <carlton at kealia dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 12 Jun 2003 12:02:40 -0700
- Subject: [dictionary] follow DW_AT_specification in structure names
Here's part of the DW_AT_specification mess dealt with. There are
many more things to deal with in this area, but this fixes a bug that
some users were reporting to me, which boiled down to names of nested
classes getting set incorrectly in the symtab.
David Carlton
carlton@kealia.com
2003-06-12 David Carlton <carlton@kealia.com>
* dwarf2read.c (die_specification): New.
(determine_prefix): Fix memory management.
(read_structure_scope): Set prefix correctly if getting type via
specification.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.66.4.29
diff -u -p -r1.66.4.29 dwarf2read.c
--- dwarf2read.c 29 May 2003 00:01:36 -0000 1.66.4.29
+++ dwarf2read.c 12 Jun 2003 18:44:45 -0000
@@ -776,6 +776,8 @@ static struct attribute *dwarf_attr (str
static int die_is_declaration (struct die_info *);
+static struct die_info *die_specification (struct die_info *die);
+
static void free_line_header (struct line_header *lh);
static struct line_header *(dwarf_decode_line_header
@@ -3003,6 +3005,7 @@ read_structure_scope (struct die_info *d
struct attribute *attr;
const char *name;
const char *previous_prefix = processing_current_prefix;
+ struct cleanup *back_to = NULL;
/* This says whether or not we want to try to update the structure's
name to include enclosing namespace/class information, if
any. */
@@ -3014,6 +3017,18 @@ read_structure_scope (struct die_info *d
name = dwarf2_name (die);
if (name != NULL)
{
+ if (cu_language == language_cplus)
+ {
+ struct die_info *spec_die = die_specification (die);
+
+ if (spec_die != NULL)
+ {
+ char *specification_prefix = determine_prefix (spec_die);
+ processing_current_prefix = specification_prefix;
+ back_to = make_cleanup (xfree, specification_prefix);
+ }
+ }
+
if (processing_has_namespace_info)
{
/* FIXME: carlton/2002-11-26: This variable exists only for
@@ -3022,8 +3037,8 @@ read_structure_scope (struct die_info *d
of changes which would have forced decode_line_1 to take
a const char **. */
char *new_prefix = obconcat (&objfile->type_obstack,
- previous_prefix,
- previous_prefix[0] == '\0'
+ processing_current_prefix,
+ processing_current_prefix[0] == '\0'
? "" : "::",
name);
TYPE_TAG_NAME (type) = new_prefix;
@@ -3200,6 +3215,8 @@ read_structure_scope (struct die_info *d
}
processing_current_prefix = previous_prefix;
+ if (back_to != NULL)
+ do_cleanups (back_to);
}
/* Given a pointer to a die which begins an enumeration, process all
@@ -4950,6 +4967,19 @@ die_is_declaration (struct die_info *die
&& ! dwarf_attr (die, DW_AT_specification));
}
+/* Returns the die giving the specification for this one, or NULL if
+ none. */
+
+static struct die_info *
+die_specification (struct die_info *die)
+{
+ struct attribute *spec_attr = dwarf_attr (die, DW_AT_specification);
+
+ if (spec_attr == NULL)
+ return NULL;
+ else
+ return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr));
+}
/* Free the line_header structure *LH, and any arrays and strings it
refers to. */
@@ -6023,15 +6053,17 @@ determine_prefix (struct die_info *die)
else
{
char *parent_prefix = determine_prefix (parent);
+ char *retval;
switch (parent->tag) {
case DW_TAG_namespace:
{
int dummy;
- return typename_concat (parent_prefix,
- namespace_name (parent, &dummy));
+ retval = typename_concat (parent_prefix,
+ namespace_name (parent, &dummy));
}
+ break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
{
@@ -6040,19 +6072,25 @@ determine_prefix (struct die_info *die)
const char *parent_name = dwarf2_name (parent);
if (parent_name != NULL)
- return typename_concat (parent_prefix, dwarf2_name (parent));
+ retval = typename_concat (parent_prefix, dwarf2_name (parent));
else
/* FIXME: carlton/2003-05-28: I'm not sure what the
best thing to do here is. */
- return typename_concat (parent_prefix,
- "<<anonymous class>>");
+ retval = typename_concat (parent_prefix,
+ "<<anonymous class>>");
}
else
- return class_name (parent);
+ retval = class_name (parent);
}
+ break;
default:
- return parent_prefix;
+ retval = parent_prefix;
+ break;
}
+
+ if (retval != parent_prefix)
+ xfree (parent_prefix);
+ return retval;
}
}