This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: Correct field names for class methods


On Fri, Sep 13, 2002 at 02:28:46PM -0400, Elena Zannoni wrote:
> Daniel Jacobowitz writes:
>  > On Tue, Sep 10, 2002 at 06:13:41PM -0400, Elena Zannoni wrote:
>  > > Approved, except for moving the functions to stabsread.c.
>  > > 
>  > > Elena
>  > 
>  > Well, that ulterior motive is showing again.
>  > 
>  > - I can't move method_name_from_physname unless I move the existing
>  >   check_stub_method routine.  I could do this, and it might even be a
>  >   good idea, since it's so patently stabs-only.
> 
> OK I like the idea.
> 
>  > 
>  > - I'm going to need class_name_from_physname in other parts of GDB; at
>  >   least in the DWARF-2 reader.
>  > 
> 
> Ah.
> 
>  > I'd feel a little silly moving method_name_from_physname and leaving
>  > class_name_from_physname.  What do you think?  I should probably
>  > (separate patch) move check_stub_method and check_stub_method_group,
>  > but the _from_physname functions seem like gdbtypes.c material to me.
>  > 
> 
> As you mentioned in a [private] e-mail maybe now the time has come to
> start separating the c++ support into its own file. I think we could
> move a few other things into such a file. I recall this being proposed
> before, but I cannot do a successful search in the archives. All the
> words I try to match are too common and the search only returns the
> first N matches.

OK.  I've checked the patch in as attached; the new functions go in
cp-support.c.  When I get a chance I'll move some associated gunk out
of gdbtypes.c; offhand this means check_stub_method{,_group}.

Onwards!  Method names were first; method printing from type
information is probably next; and then I'll tackle class names, and
we'll really start to get namespace support.  Then we can pick up the
DWARF-2 (DWARF-3) bits to handle it, which means the associated GCC
patches can finally go in.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-09-13  Daniel Jacobowitz  <drow@mvista.com>

	* gdbtypes.c (check_stub_method): Make static.
	(check_stub_method_group): New function.
	* gdbtypes.h: Update prototypes.
	* cp-support.c: New file.
	* cp-support.h: New file.

	* stabsread.c: Include "cp-abi.h" and "cp-support.h".
	(update_method_name_from_physname): New function.
	(read_member_functions): Correct method names for operators
	and v3 constructors/destructors.  Separate v2 constructors and
	destructors.
	* Makefile.in (stabsread.o): Update dependencies.
	(SFILES): Add cp-support.c.
	(COMMON_OBS): Add cp-support.o.
	(cp_support_h, cp-support.o): Add.

	* cp-valprint.c (cp_print_class_method): Call
	check_stub_method_group instead of check_stub_method.  Remove
	extraneous QUITs.
	* p-valprint.c (pascal_object_print_class_method): Likewise.
	* valops.c (search_struct_method): Likewise.
	(find_method_list, value_struct_elt_for_reference): Likewise.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.257
diff -u -p -r1.257 Makefile.in
--- Makefile.in	2 Sep 2002 18:09:06 -0000	1.257
+++ Makefile.in	14 Sep 2002 02:01:35 -0000
@@ -558,7 +558,7 @@ SFILES = ada-exp.y ada-lang.c ada-typepr
 	ui-file.h ui-file.c \
 	frame.c doublest.c \
 	builtin-regs.c std-regs.c \
-	gnu-v2-abi.c gnu-v3-abi.c hpacc-abi.c cp-abi.c
+	gnu-v2-abi.c gnu-v3-abi.c hpacc-abi.c cp-abi.c cp-support.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -626,6 +626,7 @@ command_h = command.h
 complaints_h = complaints.h
 completer_h = completer.h
 cp_abi_h = cp-abi.h
+cp_support_h = cp-support.h
 dcache_h = dcache.h
 defs_h = defs.h $(config_h) $(gdb_locale_h) $(gdb_signals_h) $(ansidecl_h) \
 	$(libiberty_h) $(progress_h) $(bfd_h) $(tui_h) $(ui_file_h) $(xm_h) \
@@ -842,7 +843,7 @@ COMMON_OBS = version.o blockframe.o brea
 	nlmread.o serial.o mdebugread.o top.o utils.o \
 	ui-file.o \
 	frame.o doublest.o \
-	gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o
+	gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o
 
 OBS = $(COMMON_OBS) $(ANNOTATE_OBS)
 
@@ -1588,6 +1589,7 @@ corelow.o: corelow.c $(defs_h) $(gdb_str
 	$(symtab_h) $(command_h) $(bfd_h) $(target_h) $(gdbcore_h) \
 	$(gdbthread_h) $(regcache_h) $(symfile_h)
 cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(gdb_string_h)
+cp-support.o: cp-support.c $(defs_h) $(cp_support_h)
 cp-valprint.o: cp-valprint.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \
 	$(gdbtypes_h) $(expression_h) $(value_h) $(command_h) $(gdbcmd_h) \
 	$(demangle_h) $(annotate_h) $(gdb_string_h) $(c_lang_h) $(target_h) \
@@ -2174,7 +2176,7 @@ stabsread.o: stabsread.c $(defs_h) $(gdb
 	$(symtab_h) $(gdbtypes_h) $(expression_h) $(symfile_h) $(objfiles_h) \
 	$(aout_stab_gnu_h) $(libaout_h) $(aout_aout64_h) $(gdb_stabs_h) \
 	$(buildsym_h) $(complaints_h) $(demangle_h) $(language_h) \
-	$(doublest_h) $(stabsread_h)
+	$(doublest_h) $(stabsread_h) $(cp_abi_h) $(cp_support_h)
 stack.o: stack.c $(defs_h) $(gdb_string_h) $(value_h) $(symtab_h) \
 	$(gdbtypes_h) $(expression_h) $(language_h) $(frame_h) $(gdbcmd_h) \
 	$(gdbcore_h) $(target_h) $(breakpoint_h) $(demangle_h) $(inferior_h) \
Index: cp-support.c
===================================================================
RCS file: cp-support.c
diff -N cp-support.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cp-support.c	14 Sep 2002 02:01:35 -0000
@@ -0,0 +1,141 @@
+/* Helper routines for C++ support in GDB.
+   Copyright 2002 Free Software Foundation, Inc.
+
+   Contributed by MontaVista Software.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "cp-support.h"
+#include "gdb_string.h"
+#include "demangle.h"
+
+/* Find the last component of the demangled C++ name NAME.  NAME
+   must be a method name including arguments, in order to correctly
+   locate the last component.
+
+   This function return a pointer to the first colon before the
+   last component, or NULL if the name had only one component.  */
+
+static const char *
+find_last_component (const char *name)
+{
+  const char *p;
+  int depth;
+
+  /* Functions can have local classes, so we need to find the
+     beginning of the last argument list, not the end of the first
+     one.  */
+  p = name + strlen (name) - 1;
+  while (p > name && *p != ')')
+    p--;
+
+  if (p == name)
+    return NULL;
+
+  /* P now points at the `)' at the end of the argument list.  Walk
+     back to the beginning.  */
+  p--;
+  depth = 1;
+  while (p > name && depth > 0)
+    {
+      if (*p == '<' || *p == '(')
+	depth--;
+      else if (*p == '>' || *p == ')')
+	depth++;
+      p--;
+    }
+
+  if (p == name)
+    return NULL;
+
+  while (p > name && *p != ':')
+    p--;
+
+  if (p == name || p == name + 1 || p[-1] != ':')
+    return NULL;
+
+  return p - 1;
+}
+
+/* Return the name of the class containing method PHYSNAME.  */
+
+char *
+class_name_from_physname (const char *physname)
+{
+  char *ret = NULL;
+  const char *end;
+  int depth = 0;
+  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
+
+  if (demangled_name == NULL)
+    return NULL;
+
+  end = find_last_component (demangled_name);
+  if (end != NULL)
+    {
+      ret = xmalloc (end - demangled_name + 1);
+      memcpy (ret, demangled_name, end - demangled_name);
+      ret[end - demangled_name] = '\0';
+    }
+
+  xfree (demangled_name);
+  return ret;
+}
+
+/* Return the name of the method whose linkage name is PHYSNAME.  */
+
+char *
+method_name_from_physname (const char *physname)
+{
+  char *ret = NULL;
+  const char *end;
+  int depth = 0;
+  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
+
+  if (demangled_name == NULL)
+    return NULL;
+
+  end = find_last_component (demangled_name);
+  if (end != NULL)
+    {
+      char *args;
+      int len;
+
+      /* Skip "::".  */
+      end = end + 2;
+
+      /* Find the argument list, if any.  */
+      args = strchr (end, '(');
+      if (args == NULL)
+	len = strlen (end + 2);
+      else
+	{
+	  args --;
+	  while (*args == ' ')
+	    args --;
+	  len = args - end + 1;
+	}
+      ret = xmalloc (len + 1);
+      memcpy (ret, end, len);
+      ret[len] = 0;
+    }
+
+  xfree (demangled_name);
+  return ret;
+}
Index: cp-support.h
===================================================================
RCS file: cp-support.h
diff -N cp-support.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cp-support.h	14 Sep 2002 02:01:35 -0000
@@ -0,0 +1,25 @@
+/* Helper routines for C++ support in GDB.
+   Copyright 2002 Free Software Foundation, Inc.
+
+   Contributed by MontaVista Software.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+extern char *class_name_from_physname (const char *physname);
+
+extern char *method_name_from_physname (const char *physname);
Index: cp-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-valprint.c,v
retrieving revision 1.13
diff -u -p -r1.13 cp-valprint.c
--- cp-valprint.c	29 Jul 2002 22:55:26 -0000	1.13
+++ cp-valprint.c	14 Sep 2002 02:01:35 -0000
@@ -97,13 +97,11 @@ cp_print_class_method (char *valaddr,
 	  f = TYPE_FN_FIELDLIST1 (domain, i);
 	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
 
+	  check_stub_method_group (domain, i);
 	  for (j = 0; j < len2; j++)
 	    {
-	      QUIT;
 	      if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
 		{
-		  if (TYPE_FN_FIELD_STUB (f, j))
-		    check_stub_method (domain, i, j);
 		  kind = "virtual ";
 		  goto common;
 		}
@@ -129,15 +127,11 @@ cp_print_class_method (char *valaddr,
 	  f = TYPE_FN_FIELDLIST1 (domain, i);
 	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
 
+	  check_stub_method_group (f, j);
 	  for (j = 0; j < len2; j++)
 	    {
-	      QUIT;
-	      if (TYPE_FN_FIELD_STUB (f, j))
-		check_stub_method (domain, i, j);
 	      if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
-		{
-		  goto common;
-		}
+		goto common;
 	    }
 	}
     }
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.56
diff -u -p -r1.56 gdbtypes.c
--- gdbtypes.c	20 Aug 2002 19:57:32 -0000	1.56
+++ gdbtypes.c	14 Sep 2002 02:01:36 -0000
@@ -1672,7 +1672,7 @@ safe_parse_type (char *p, int length)
    which info used to be in the stab's but was removed to hack back
    the space required for them.  */
 
-void
+static void
 check_stub_method (struct type *type, int method_id, int signature_id)
 {
   struct fn_field *f;
@@ -1781,6 +1781,49 @@ check_stub_method (struct type *type, in
   xfree (demangled_name);
 }
 
+/* This is the external interface to check_stub_method, above.  This function
+   unstubs all of the signatures for TYPE's METHOD_ID method name.  After
+   calling this function TYPE_FN_FIELD_STUB will be cleared for each signature
+   and TYPE_FN_FIELDLIST_NAME will be correct.
+
+   This function unfortunately can not die until stabs do.  */
+
+void
+check_stub_method_group (struct type *type, int method_id)
+{
+  int len = TYPE_FN_FIELDLIST_LENGTH (type, method_id);
+  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
+  int j, found_stub;
+
+  for (j = 0; j < len; j++)
+    if (TYPE_FN_FIELD_STUB (f, j))
+      {
+	found_stub = 1;
+	check_stub_method (type, method_id, j);
+      }
+
+  /* GNU v3 methods with incorrect names were corrected when we read in
+     type information, because it was cheaper to do it then.  The only GNU v2
+     methods with incorrect method names are operators and destructors;
+     destructors were also corrected when we read in type information.
+
+     Therefore the only thing we need to handle here are v2 operator
+     names.  */
+  if (found_stub && strncmp (TYPE_FN_FIELD_PHYSNAME (f, 0), "_Z", 2) != 0)
+    {
+      int ret;
+      char dem_opname[256];
+
+      ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, method_id),
+				   dem_opname, DMGL_ANSI);
+      if (!ret)
+	ret = cplus_demangle_opname (TYPE_FN_FIELDLIST_NAME (type, method_id),
+				     dem_opname, 0);
+      if (ret)
+	TYPE_FN_FIELDLIST_NAME (type, method_id) = xstrdup (dem_opname);
+    }
+}
+
 const struct cplus_struct_type cplus_struct_default;
 
 void
@@ -3434,7 +3477,6 @@ build_gdbtypes (void)
 	       TYPE_FLAG_UNSIGNED,
 	       "__bfd_vma", (struct objfile *) NULL);
 }
-
 
 extern void _initialize_gdbtypes (void);
 void
Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.35
diff -u -p -r1.35 gdbtypes.h
--- gdbtypes.h	10 Aug 2002 05:12:40 -0000	1.35
+++ gdbtypes.h	14 Sep 2002 02:01:36 -0000
@@ -1124,7 +1124,7 @@ extern struct type *check_typedef (struc
 
 #define CHECK_TYPEDEF(TYPE) (TYPE) = check_typedef (TYPE)
 
-extern void check_stub_method (struct type *, int, int);
+extern void check_stub_method_group (struct type *, int);
 
 extern struct type *lookup_primitive_typename (char *);
 
Index: p-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/p-valprint.c,v
retrieving revision 1.13
diff -u -p -r1.13 p-valprint.c
--- p-valprint.c	19 Aug 2002 13:12:09 -0000	1.13
+++ p-valprint.c	14 Sep 2002 02:01:36 -0000
@@ -620,13 +620,11 @@ pascal_object_print_class_method (char *
 	  f = TYPE_FN_FIELDLIST1 (domain, i);
 	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
 
+	  check_stub_method_group (domain, i);
 	  for (j = 0; j < len2; j++)
 	    {
-	      QUIT;
 	      if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
 		{
-		  if (TYPE_FN_FIELD_STUB (f, j))
-		    check_stub_method (domain, i, j);
 		  kind = "virtual ";
 		  goto common;
 		}
@@ -646,15 +644,11 @@ pascal_object_print_class_method (char *
 	  f = TYPE_FN_FIELDLIST1 (domain, i);
 	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
 
+	  check_stub_method_group (domain, i);
 	  for (j = 0; j < len2; j++)
 	    {
-	      QUIT;
-	      if (TYPE_FN_FIELD_STUB (f, j))
-		check_stub_method (domain, i, j);
 	      if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
-		{
-		  goto common;
-		}
+		goto common;
 	    }
 	}
     }
Index: stabsread.c
===================================================================
RCS file: /cvs/src/src/gdb/stabsread.c,v
retrieving revision 1.38
diff -u -p -r1.38 stabsread.c
--- stabsread.c	1 Aug 2002 17:18:32 -0000	1.38
+++ stabsread.c	14 Sep 2002 02:01:37 -0000
@@ -44,6 +44,8 @@
 #include "demangle.h"
 #include "language.h"
 #include "doublest.h"
+#include "cp-abi.h"
+#include "cp-support.h"
 
 #include <ctype.h>
 
@@ -3080,6 +3082,27 @@ rs6000_builtin_type (int typenum)
 
 /* This page contains subroutines of read_type.  */
 
+/* Replace *OLD_NAME with the method name portion of PHYSNAME.  */
+
+static void
+update_method_name_from_physname (char **old_name, char *physname)
+{
+  char *method_name;
+
+  method_name = method_name_from_physname (physname);
+
+  if (method_name == NULL)
+    error ("bad physname %s\n", physname);
+
+  if (strcmp (*old_name, method_name) != 0)
+    {
+      xfree (*old_name);
+      *old_name = method_name;
+    }
+  else
+    xfree (method_name);
+}
+
 /* Read member function stabs info for C++ classes.  The form of each member
    function data is:
 
@@ -3377,6 +3400,164 @@ read_member_functions (struct field_info
 	}
       else
 	{
+	  int has_stub = 0;
+	  int has_destructor = 0, has_other = 0;
+	  int is_v3 = 0;
+	  struct next_fnfield *tmp_sublist;
+
+	  /* Various versions of GCC emit various mostly-useless
+	     strings in the name field for special member functions.
+
+	     For stub methods, we need to defer correcting the name
+	     until we are ready to unstub the method, because the current
+	     name string is used by gdb_mangle_name.  The only stub methods
+	     of concern here are GNU v2 operators; other methods have their
+	     names correct (see caveat below).
+
+	     For non-stub methods, in GNU v3, we have a complete physname.
+	     Therefore we can safely correct the name now.  This primarily
+	     affects constructors and destructors, whose name will be
+	     __comp_ctor or __comp_dtor instead of Foo or ~Foo.  Cast
+	     operators will also have incorrect names; for instance,
+	     "operator int" will be named "operator i" (i.e. the type is
+	     mangled).
+
+	     For non-stub methods in GNU v2, we have no easy way to
+	     know if we have a complete physname or not.  For most
+	     methods the result depends on the platform (if CPLUS_MARKER
+	     can be `$' or `.', it will use minimal debug information, or
+	     otherwise the full physname will be included).
+
+	     Rather than dealing with this, we take a different approach.
+	     For v3 mangled names, we can use the full physname; for v2,
+	     we use cplus_demangle_opname (which is actually v2 specific),
+	     because the only interesting names are all operators - once again
+	     barring the caveat below.  Skip this process if any method in the
+	     group is a stub, to prevent our fouling up the workings of
+	     gdb_mangle_name.
+
+	     The caveat: GCC 2.95.x (and earlier?) put constructors and
+	     destructors in the same method group.  We need to split this
+	     into two groups, because they should have different names.
+	     So for each method group we check whether it contains both
+	     routines whose physname appears to be a destructor (the physnames
+	     for and destructors are always provided, due to quirks in v2
+	     mangling) and routines whose physname does not appear to be a
+	     destructor.  If so then we break up the list into two halves.
+	     Even if the constructors and destructors aren't in the same group
+	     the destructor will still lack the leading tilde, so that also
+	     needs to be fixed.
+
+	     So, to summarize what we expect and handle here:
+
+	        Given         Given          Real         Real       Action
+	     method name     physname      physname   method name
+
+	     __opi            [none]     __opi__3Foo  operator int    opname
+	                                                           [now or later]
+	     Foo              _._3Foo       _._3Foo      ~Foo       separate and
+	                                                               rename
+	     operator i     _ZN3FoocviEv _ZN3FoocviEv operator int    demangle
+	     __comp_ctor  _ZN3FooC1ERKS_ _ZN3FooC1ERKS_   Foo         demangle
+	  */
+
+	  tmp_sublist = sublist;
+	  while (tmp_sublist != NULL)
+	    {
+	      if (tmp_sublist->fn_field.is_stub)
+		has_stub = 1;
+	      if (tmp_sublist->fn_field.physname[0] == '_'
+		  && tmp_sublist->fn_field.physname[1] == 'Z')
+		is_v3 = 1;
+
+	      if (is_destructor_name (tmp_sublist->fn_field.physname))
+		has_destructor++;
+	      else
+		has_other++;
+
+	      tmp_sublist = tmp_sublist->next;
+	    }
+
+	  if (has_destructor && has_other)
+	    {
+	      struct next_fnfieldlist *destr_fnlist;
+	      struct next_fnfield *last_sublist;
+
+	      /* Create a new fn_fieldlist for the destructors.  */
+
+	      destr_fnlist = (struct next_fnfieldlist *)
+		xmalloc (sizeof (struct next_fnfieldlist));
+	      make_cleanup (xfree, destr_fnlist);
+	      memset (destr_fnlist, 0, sizeof (struct next_fnfieldlist));
+	      destr_fnlist->fn_fieldlist.name
+		= obconcat (&objfile->type_obstack, "", "~",
+			    new_fnlist->fn_fieldlist.name);
+
+	      destr_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
+		obstack_alloc (&objfile->type_obstack,
+			       sizeof (struct fn_field) * has_destructor);
+	      memset (destr_fnlist->fn_fieldlist.fn_fields, 0,
+		  sizeof (struct fn_field) * has_destructor);
+	      tmp_sublist = sublist;
+	      last_sublist = NULL;
+	      i = 0;
+	      while (tmp_sublist != NULL)
+		{
+		  if (!is_destructor_name (tmp_sublist->fn_field.physname))
+		    {
+		      tmp_sublist = tmp_sublist->next;
+		      continue;
+		    }
+		  
+		  destr_fnlist->fn_fieldlist.fn_fields[i++]
+		    = tmp_sublist->fn_field;
+		  if (last_sublist)
+		    last_sublist->next = tmp_sublist->next;
+		  else
+		    sublist = tmp_sublist->next;
+		  last_sublist = tmp_sublist;
+		  tmp_sublist = tmp_sublist->next;
+		}
+
+	      destr_fnlist->fn_fieldlist.length = has_destructor;
+	      destr_fnlist->next = fip->fnlist;
+	      fip->fnlist = destr_fnlist;
+	      nfn_fields++;
+	      total_length += has_destructor;
+	      length -= has_destructor;
+	    }
+	  else if (is_v3)
+	    {
+	      /* v3 mangling prevents the use of abbreviated physnames,
+		 so we can do this here.  There are stubbed methods in v3
+		 only:
+		 - in -gstabs instead of -gstabs+
+		 - or for static methods, which are output as a function type
+		   instead of a method type.  */
+
+	      update_method_name_from_physname (&new_fnlist->fn_fieldlist.name,
+						sublist->fn_field.physname);
+	    }
+	  else if (has_destructor && new_fnlist->fn_fieldlist.name[0] != '~')
+	    {
+	      new_fnlist->fn_fieldlist.name = concat ("~", main_fn_name, NULL);
+	      xfree (main_fn_name);
+	    }
+	  else if (!has_stub)
+	    {
+	      char dem_opname[256];
+	      int ret;
+	      ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name,
+					      dem_opname, DMGL_ANSI);
+	      if (!ret)
+		ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name,
+					     dem_opname, 0);
+	      if (ret)
+		new_fnlist->fn_fieldlist.name
+		  = obsavestring (dem_opname, strlen (dem_opname),
+				  &objfile->type_obstack);
+	    }
+
 	  new_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
 	    obstack_alloc (&objfile->type_obstack,
 			   sizeof (struct fn_field) * length);
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.71
diff -u -p -r1.71 valops.c
--- valops.c	13 Sep 2002 00:38:48 -0000	1.71
+++ valops.c	14 Sep 2002 02:01:38 -0000
@@ -2302,12 +2302,11 @@ search_struct_method (char *name, struct
 	  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
 	  name_matched = 1;
 
+	  check_stub_method_group (type, i);
 	  if (j > 0 && args == 0)
 	    error ("cannot resolve overloaded method `%s': no arguments supplied", name);
 	  else if (j == 0 && args == 0)
 	    {
-	      if (TYPE_FN_FIELD_STUB (f, j))
-		check_stub_method (type, i, j);
 	      v = value_fn_field (arg1p, f, j, type, offset);
 	      if (v != NULL)
 		return v;
@@ -2315,8 +2314,6 @@ search_struct_method (char *name, struct
 	  else
 	    while (j >= 0)
 	      {
-		if (TYPE_FN_FIELD_STUB (f, j))
-		  check_stub_method (type, i, j);
 		if (!typecmp (TYPE_FN_FIELD_STATIC_P (f, j),
 			      TYPE_VARARGS (TYPE_FN_FIELD_TYPE (f, j)),
 			      TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (f, j)),
@@ -2555,20 +2552,15 @@ find_method_list (struct value **argp, c
       char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
       if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0))
 	{
-	  /* Resolve any stub methods.  */
 	  int len = TYPE_FN_FIELDLIST_LENGTH (type, i);
 	  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
-	  int j;
 
 	  *num_fns = len;
 	  *basetype = type;
 	  *boffset = offset;
 
-	  for (j = 0; j < len; j++)
-	    {
-	      if (TYPE_FN_FIELD_STUB (f, j))
-		check_stub_method (type, i, j);
-	    }
+	  /* Resolve any stub methods.  */
+	  check_stub_method_group (type, i);
 
 	  return f;
 	}
@@ -3094,6 +3086,8 @@ value_struct_elt_for_reference (struct t
 	  int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
 	  struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
 
+	  check_stub_method_group (t, i);
+
 	  if (intype == 0 && j > 1)
 	    error ("non-unique member `%s' requires type instantiation", name);
 	  if (intype)
@@ -3107,8 +3101,6 @@ value_struct_elt_for_reference (struct t
 	  else
 	    j = 0;
 
-	  if (TYPE_FN_FIELD_STUB (f, j))
-	    check_stub_method (t, i, j);
 	  if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
 	    {
 	      return value_from_longest


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]