This is the mail archive of the
gdb-prs@sources.redhat.com
mailing list for the GDB project.
Re: c++/1553: gdb confused in namespace / subclass
- From: David Carlton <carlton at kealia dot com>
- To: carlton at sources dot redhat dot com
- Cc: gdb-prs at sources dot redhat dot com,
- Date: 24 Feb 2004 01:38:01 -0000
- Subject: Re: c++/1553: gdb confused in namespace / subclass
- Reply-to: David Carlton <carlton at kealia dot com>
The following reply was made to PR c++/1553; it has been noted by GNATS.
From: David Carlton <carlton@kealia.com>
To: Dirk-Jan Jongeneel <dirkjjn@cobalt.et.tudelft.nl>
Cc: gdb-gnats@sources.redhat.com
Subject: Re: c++/1553: gdb confused in namespace / subclass
Date: Mon, 23 Feb 2004 17:31:01 -0800
Thanks for the excellent test cases. This patch seems to work for
those cases; can you see if it helps in the other places where you're
having problems?
David Carlton
carlton@kealia.com
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.135
diff -u -p -r1.135 dwarf2read.c
--- dwarf2read.c 21 Feb 2004 02:13:35 -0000 1.135
+++ dwarf2read.c 24 Feb 2004 01:29:22 -0000
@@ -806,6 +806,8 @@ static void dwarf2_attach_fn_fields_to_t
static void read_structure_scope (struct die_info *, struct dwarf2_cu *);
+static char *determine_class_name (struct die_info *die, struct dwarf2_cu *cu);
+
static void read_common_block (struct die_info *, struct dwarf2_cu *);
static void read_namespace (struct die_info *die, struct dwarf2_cu *);
@@ -3000,13 +3002,8 @@ read_structure_scope (struct die_info *d
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
- const char *name = NULL;
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. */
- int need_to_update_name = 0;
type = alloc_type (objfile);
@@ -3014,40 +3011,21 @@ read_structure_scope (struct die_info *d
attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
{
- name = DW_STRING (attr);
-
if (cu->language == language_cplus)
{
- struct die_info *spec_die = die_specification (die, cu);
-
- if (spec_die != NULL)
- {
- char *specification_prefix = determine_prefix (spec_die, cu);
- processing_current_prefix = specification_prefix;
- back_to = make_cleanup (xfree, specification_prefix);
- }
- }
-
- if (processing_has_namespace_info)
- {
- /* FIXME: carlton/2003-11-10: This variable exists only for
- const-correctness reasons. When I tried to change
- TYPE_TAG_NAME to be a const char *, I ran into a cascade
- of changes which would have forced decode_line_1 to take
- a const char **. */
- char *new_prefix = obconcat (&objfile->objfile_obstack,
- processing_current_prefix,
- processing_current_prefix[0] == '\0'
- ? "" : "::",
- name);
- TYPE_TAG_NAME (type) = new_prefix;
+ char *new_prefix = determine_class_name (die, cu);
+ TYPE_TAG_NAME (type) = obsavestring (new_prefix,
+ strlen (new_prefix),
+ &objfile->objfile_obstack);
+ back_to = make_cleanup (xfree, new_prefix);
processing_current_prefix = new_prefix;
}
else
{
+ const char *name = DW_STRING (attr);
+
TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
&objfile->objfile_obstack);
- need_to_update_name = (cu->language == language_cplus);
}
}
@@ -3108,41 +3086,6 @@ read_structure_scope (struct die_info *d
/* C++ member function. */
process_die (child_die, cu);
dwarf2_add_member_fn (&fi, child_die, type, cu);
- if (need_to_update_name)
- {
- /* The demangled names of member functions contain
- information about enclosing namespaces/classes,
- if any. */
-
- /* FIXME: carlton/2003-11-10: The excessive
- demangling here is a bit wasteful, as is the
- memory usage for names. */
-
- /* NOTE: carlton/2003-11-10: As commented in
- add_partial_structure, the demangler sometimes
- prints the type info in a different form from the
- debug info. We could solve this by using the
- demangled name to get the prefix; if doing so,
- however, we'd need to be careful when reading a
- class that's nested inside a template class.
- That would also cause problems when trying to
- determine RTTI information, since we use the
- demangler to determine the appropriate class
- name. */
- char *actual_class_name
- = class_name_from_physname (dwarf2_linkage_name
- (child_die, cu));
- if (actual_class_name != NULL
- && strcmp (actual_class_name, name) != 0)
- {
- TYPE_TAG_NAME (type)
- = obsavestring (actual_class_name,
- strlen (actual_class_name),
- &objfile->objfile_obstack);
- }
- xfree (actual_class_name);
- need_to_update_name = 0;
- }
}
else if (child_die->tag == DW_TAG_inheritance)
{
@@ -3222,6 +3165,59 @@ read_structure_scope (struct die_info *d
processing_current_prefix = previous_prefix;
if (back_to != NULL)
do_cleanups (back_to);
+}
+
+/* Determine the name of the type represented by DIE, which should be
+ a named C++ compound type. Return the name in question; the caller
+ is responsible for xfree()'ing it. */
+
+static char *
+determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct cleanup *back_to = NULL;
+ struct die_info *spec_die = die_specification (die, cu);
+ char *new_prefix = NULL;
+
+ /* If this is the definition of a class that is declared by another
+ die, then processing_current_prefix may not be accurate; see
+ read_func_scope for a similar example. */
+ if (spec_die != NULL)
+ {
+ char *specification_prefix = determine_prefix (spec_die, cu);
+ processing_current_prefix = specification_prefix;
+ back_to = make_cleanup (xfree, specification_prefix);
+ }
+
+ /* If we don't have namespace debug info, guess the name by trying
+ to demangle the names of members, just like we did in
+ add_partial_structure. */
+ if (!processing_has_namespace_info)
+ {
+ struct die_info *child;
+
+ for (child = die->child;
+ child != NULL && child->tag != 0;
+ child = sibling_die (child))
+ {
+ if (child->tag == DW_TAG_subprogram)
+ {
+ new_prefix = class_name_from_physname (dwarf2_linkage_name
+ (child, cu));
+
+ if (new_prefix != NULL)
+ break;
+ }
+ }
+ }
+
+ if (new_prefix == NULL)
+ new_prefix = typename_concat (processing_current_prefix,
+ dwarf2_name (die, cu));
+
+ if (back_to != NULL)
+ do_cleanups (back_to);
+
+ return new_prefix;
}
/* Given a pointer to a die which begins an enumeration, process all