From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25381 invoked by alias); 13 Sep 2002 18:30:41 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 25371 invoked from network); 13 Sep 2002 18:30:39 -0000 Received: from unknown (HELO localhost.redhat.com) (66.30.197.194) by sources.redhat.com with SMTP; 13 Sep 2002 18:30:39 -0000 Received: by localhost.redhat.com (Postfix, from userid 469) id 0EDF9106CC; Fri, 13 Sep 2002 14:28:46 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15746.11870.93370.310471@localhost.redhat.com> Date: Fri, 13 Sep 2002 11:30:00 -0000 To: Daniel Jacobowitz Cc: Elena Zannoni , gdb-patches@sources.redhat.com Subject: Re: RFA: Correct field names for class methods In-Reply-To: <20020910222022.GA5819@nevyn.them.org> References: <20020827031346.GA16591@nevyn.them.org> <15741.12051.396773.949592@localhost.redhat.com> <20020910163610.GA10920@nevyn.them.org> <15742.28309.864077.222180@localhost.redhat.com> <20020910222022.GA5819@nevyn.them.org> X-SW-Source: 2002-09/txt/msg00256.txt.bz2 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. Elena > > > > > > > -- > > > Daniel Jacobowitz > > > MontaVista Software Debian GNU/Linux Developer > > > > > > 2002-09-10 Daniel Jacobowitz > > > > > > * gdbtypes.c (check_stub_method): Make static. > > > (check_stub_method_group, find_last_component) > > > (class_name_from_physname, method_name_from_physname): New functions. > > > * gdbtypes.h: Update prototypes. > > > > > > * stabsread.c: Include "cp-abi.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. > > > > > > * 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 10 Sep 2002 16:35:15 -0000 > > > @@ -2174,7 +2174,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) > > > 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-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 10 Sep 2002 16:35:15 -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 10 Sep 2002 16:35:16 -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 > > > @@ -3435,6 +3478,120 @@ build_gdbtypes (void) > > > "__bfd_vma", (struct objfile *) NULL); > > > } > > > > > > +/* 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; > > > +} > > > > > > 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 10 Sep 2002 16:35:16 -0000 > > > @@ -1124,11 +1124,15 @@ 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 *); > > > > > > extern char *gdb_mangle_name (struct type *, int, int); > > > + > > > +extern char *class_name_from_physname (const char *physname); > > > + > > > +extern char *method_name_from_physname (const char *physname); > > > > > > extern struct type *builtin_type (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 10 Sep 2002 16:35:16 -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 10 Sep 2002 16:35:17 -0000 > > > @@ -44,6 +44,7 @@ > > > #include "demangle.h" > > > #include "language.h" > > > #include "doublest.h" > > > +#include "cp-abi.h" > > > > > > #include > > > > > > @@ -3080,6 +3081,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 +3399,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.69 > > > diff -u -p -r1.69 valops.c > > > --- valops.c 21 Aug 2002 17:24:31 -0000 1.69 > > > +++ valops.c 10 Sep 2002 16:35:18 -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 > > > > -- > Daniel Jacobowitz > MontaVista Software Debian GNU/Linux Developer