This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [rfa+6.1]: Revised patch for PR c++/1553
- From: David Carlton <carlton at kealia dot com>
- To: Elena Zannoni <ezannoni at redhat dot com>
- Cc: gdb-patches at sources dot redhat dot com, Jim Blandy <jimb at redhat dot com>,Daniel Jacobowitz <drow at mvista dot com>
- Date: Mon, 15 Mar 2004 14:45:49 -0800
- Subject: Re: [rfa+6.1]: Revised patch for PR c++/1553
- References: <m3k71vnt7j.fsf@coconut.kealia.com><16470.493.253043.158843@localhost.redhat.com>
On Mon, 15 Mar 2004 14:20:13 -0500, Elena Zannoni <ezannoni@redhat.com> said:
> seems ok, however I wasn't able to apply it cleanly.
I guess it overlapped a bit with some of Daniel's patches;
fortunately, the problems are only cosmetic. Unfortunately, the
cosmetic changes are different for mainline and 6.1; I'll include both
versions of the revised patch below.
> Also, there are a couple of C++ style comments that should go.
Whoops, sorry! I was so worried about making sure that I wrote
function calls like "func (arg)" instead of "func( arg )" that I
forgot all about that. Sigh.
Here's what I actually committed.
David Carlton
carlton@kealia.com
2004-03-15 David Carlton <carlton@kealia.com>
Fix for PR c++/1553:
* dwarf2read.c (read_structure_type): Determine type name by
calling determine_class_name.
(determine_class_name): New.
(determine_prefix): Look at TYPE_TAG_NAME and call
determine_class_name when appropriate.
(determine_prefix_aux, class_name): Delete.
The patch for mainline:
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.139
diff -u -p -r1.139 dwarf2read.c
--- dwarf2read.c 14 Mar 2004 21:08:24 -0000 1.139
+++ dwarf2read.c 15 Mar 2004 22:32:05 -0000
@@ -782,12 +782,8 @@ static void read_type_die (struct die_in
static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
-static char *determine_prefix_aux (struct die_info *die, struct dwarf2_cu *);
-
static char *typename_concat (const char *prefix, const char *suffix);
-static char *class_name (struct die_info *die, struct dwarf2_cu *);
-
static void read_typedef (struct die_info *, struct dwarf2_cu *);
static void read_base_type (struct die_info *, struct dwarf2_cu *);
@@ -824,6 +820,8 @@ static void read_structure_type (struct
static void process_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 *);
@@ -3167,13 +3165,8 @@ read_structure_type (struct die_info *di
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
- 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;
if (die->type)
return;
@@ -3184,41 +3177,20 @@ read_structure_type (struct die_info *di
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
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_TAG_NAME (type) = name;
- need_to_update_name = (cu->language == language_cplus);
+ TYPE_TAG_NAME (type) = DW_STRING (attr);
}
}
@@ -3279,41 +3251,6 @@ read_structure_type (struct die_info *di
/* C++ member function. */
read_type_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)
{
@@ -3474,6 +3411,62 @@ read_enumeration_type (struct die_info *
die->type = type;
}
+/* 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)
+ {
+ const char *name = dwarf2_name (die, cu);
+ new_prefix = typename_concat (processing_current_prefix,
+ name ? name : "<<anonymous>>");
+ }
+
+ if (back_to != NULL)
+ do_cleanups (back_to);
+
+ return new_prefix;
+}
+
/* Given a pointer to a die which begins an enumeration, process all
the dies that define the members of the enumeration, and create the
symbol for the enumeration type.
@@ -3724,6 +3717,7 @@ read_namespace (struct die_info *die, st
TYPE_TAG_NAME (type) = TYPE_NAME (type);
new_symbol (die, type, cu);
+ die->type = type;
if (is_anonymous)
cp_add_using_directive (processing_current_prefix,
@@ -6298,18 +6292,6 @@ read_type_die (struct die_info *die, str
static char *
determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
- char *prefix = determine_prefix_aux (die, cu);
-
- return prefix ? prefix : xstrdup ("");
-}
-
-/* Return the name of the namespace/class that DIE is defined
- within, or NULL if we can't tell. The caller should xfree the
- result. */
-
-static char *
-determine_prefix_aux (struct die_info *die, struct dwarf2_cu *cu)
-{
struct die_info *parent;
if (cu->language != language_cplus)
@@ -6319,49 +6301,55 @@ determine_prefix_aux (struct die_info *d
if (parent == NULL)
{
- return (processing_has_namespace_info ? xstrdup ("") : NULL);
+ return xstrdup ("");
}
else
{
- char *parent_prefix = determine_prefix_aux (parent, cu);
- char *retval;
-
switch (parent->tag) {
case DW_TAG_namespace:
{
- int dummy;
-
- retval = typename_concat (parent_prefix,
- namespace_name (parent, &dummy, cu));
+ /* FIXME: carlton/2004-03-05: Should I follow extension dies
+ before doing this check? */
+ if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
+ {
+ return xstrdup (TYPE_TAG_NAME (parent->type));
+ }
+ else
+ {
+ int dummy;
+ char *parent_prefix = determine_prefix (parent, cu);
+ char *retval = typename_concat (parent_prefix,
+ namespace_name (parent, &dummy,
+ cu));
+ xfree (parent_prefix);
+ return retval;
+ }
}
break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
{
- if (parent_prefix != NULL)
+ if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
{
- const char *parent_name = dwarf2_name (parent, cu);
-
- if (parent_name != NULL)
- retval = typename_concat (parent_prefix, dwarf2_name (parent, cu));
- else
- /* FIXME: carlton/2003-11-10: I'm not sure what the
- best thing to do here is. */
- retval = typename_concat (parent_prefix,
- "<<anonymous class>>");
+ return xstrdup (TYPE_TAG_NAME (parent->type));
}
else
- retval = class_name (parent, cu);
+ {
+ const char *old_prefix = processing_current_prefix;
+ char *new_prefix = determine_prefix (parent, cu);
+ char *retval;
+
+ processing_current_prefix = new_prefix;
+ retval = determine_class_name (parent, cu);
+ processing_current_prefix = old_prefix;
+
+ xfree (new_prefix);
+ return retval;
+ }
}
- break;
default:
- retval = parent_prefix;
- break;
+ return determine_prefix (parent, cu);
}
-
- if (retval != parent_prefix)
- xfree (parent_prefix);
- return retval;
}
}
@@ -6384,28 +6372,6 @@ typename_concat (const char *prefix, con
return retval;
}
-}
-
-/* Return a newly-allocated string giving the name of the class given
- by DIE. */
-
-static char *
-class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
- struct die_info *child;
- const char *name;
-
- for (child = die->child; child != NULL; child = sibling_die (child))
- {
- if (child->tag == DW_TAG_subprogram)
- return class_name_from_physname (dwarf2_linkage_name (child, cu));
- }
-
- name = dwarf2_name (die, cu);
- if (name != NULL)
- return xstrdup (name);
- else
- return xstrdup ("");
}
static struct type *
The patch for 6.1:
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.135.4.1
diff -u -p -r1.135.4.1 dwarf2read.c
--- dwarf2read.c 14 Mar 2004 21:08:37 -0000 1.135.4.1
+++ dwarf2read.c 15 Mar 2004 22:43:54 -0000
@@ -766,12 +766,8 @@ static void read_type_die (struct die_in
static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
-static char *determine_prefix_aux (struct die_info *die, struct dwarf2_cu *);
-
static char *typename_concat (const char *prefix, const char *suffix);
-static char *class_name (struct die_info *die, struct dwarf2_cu *);
-
static void read_typedef (struct die_info *, struct dwarf2_cu *);
static void read_base_type (struct die_info *, struct dwarf2_cu *);
@@ -808,6 +804,8 @@ static void read_structure_type (struct
static void process_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 *);
@@ -3008,13 +3006,8 @@ read_structure_type (struct die_info *di
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;
if (die->type)
return;
@@ -3025,40 +3018,18 @@ read_structure_type (struct die_info *di
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
{
- TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
- &objfile->objfile_obstack);
- need_to_update_name = (cu->language == language_cplus);
+ TYPE_TAG_NAME (type) = DW_STRING (attr);
}
}
@@ -3119,41 +3090,6 @@ read_structure_type (struct die_info *di
/* C++ member function. */
read_type_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)
{
@@ -3313,6 +3249,62 @@ read_enumeration_type (struct die_info *
die->type = type;
}
+/* 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)
+ {
+ const char *name = dwarf2_name (die, cu);
+ new_prefix = typename_concat (processing_current_prefix,
+ name ? name : "<<anonymous>>");
+ }
+
+ if (back_to != NULL)
+ do_cleanups (back_to);
+
+ return new_prefix;
+}
+
/* Given a pointer to a die which begins an enumeration, process all
the dies that define the members of the enumeration, and create the
symbol for the enumeration type.
@@ -3563,6 +3555,7 @@ read_namespace (struct die_info *die, st
TYPE_TAG_NAME (type) = TYPE_NAME (type);
new_symbol (die, type, cu);
+ die->type = type;
if (is_anonymous)
cp_add_using_directive (processing_current_prefix,
@@ -6120,18 +6113,6 @@ read_type_die (struct die_info *die, str
static char *
determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
- char *prefix = determine_prefix_aux (die, cu);
-
- return prefix ? prefix : xstrdup ("");
-}
-
-/* Return the name of the namespace/class that DIE is defined
- within, or NULL if we can't tell. The caller should xfree the
- result. */
-
-static char *
-determine_prefix_aux (struct die_info *die, struct dwarf2_cu *cu)
-{
struct die_info *parent;
if (cu->language != language_cplus)
@@ -6141,49 +6122,55 @@ determine_prefix_aux (struct die_info *d
if (parent == NULL)
{
- return (processing_has_namespace_info ? xstrdup ("") : NULL);
+ return xstrdup ("");
}
else
{
- char *parent_prefix = determine_prefix_aux (parent, cu);
- char *retval;
-
switch (parent->tag) {
case DW_TAG_namespace:
{
- int dummy;
-
- retval = typename_concat (parent_prefix,
- namespace_name (parent, &dummy, cu));
+ /* FIXME: carlton/2004-03-05: Should I follow extension dies
+ before doing this check? */
+ if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
+ {
+ return xstrdup (TYPE_TAG_NAME (parent->type));
+ }
+ else
+ {
+ int dummy;
+ char *parent_prefix = determine_prefix (parent, cu);
+ char *retval = typename_concat (parent_prefix,
+ namespace_name (parent, &dummy,
+ cu));
+ xfree (parent_prefix);
+ return retval;
+ }
}
break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
{
- if (parent_prefix != NULL)
+ if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
{
- const char *parent_name = dwarf2_name (parent, cu);
-
- if (parent_name != NULL)
- retval = typename_concat (parent_prefix, dwarf2_name (parent, cu));
- else
- /* FIXME: carlton/2003-11-10: I'm not sure what the
- best thing to do here is. */
- retval = typename_concat (parent_prefix,
- "<<anonymous class>>");
+ return xstrdup (TYPE_TAG_NAME (parent->type));
}
else
- retval = class_name (parent, cu);
+ {
+ const char *old_prefix = processing_current_prefix;
+ char *new_prefix = determine_prefix (parent, cu);
+ char *retval;
+
+ processing_current_prefix = new_prefix;
+ retval = determine_class_name (parent, cu);
+ processing_current_prefix = old_prefix;
+
+ xfree (new_prefix);
+ return retval;
+ }
}
- break;
default:
- retval = parent_prefix;
- break;
+ return determine_prefix (parent, cu);
}
-
- if (retval != parent_prefix)
- xfree (parent_prefix);
- return retval;
}
}
@@ -6206,28 +6193,6 @@ typename_concat (const char *prefix, con
return retval;
}
-}
-
-/* Return a newly-allocated string giving the name of the class given
- by DIE. */
-
-static char *
-class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
- struct die_info *child;
- const char *name;
-
- for (child = die->child; child != NULL; child = sibling_die (child))
- {
- if (child->tag == DW_TAG_subprogram)
- return class_name_from_physname (dwarf2_linkage_name (child, cu));
- }
-
- name = dwarf2_name (die, cu);
- if (name != NULL)
- return xstrdup (name);
- else
- return xstrdup ("");
}
static struct type *