mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 12:39:59 +00:00
* 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.
This commit is contained in:
parent
94202ba54e
commit
de17c821b3
@ -1,3 +1,28 @@
|
||||
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.
|
||||
|
||||
2002-09-13 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
* gdbarch.sh (SIGTRAMP_END): Change to a predicate function.
|
||||
|
@ -558,7 +558,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
|
||||
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 breakpoint.o findvar.o regcache.o \
|
||||
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_string_h) $(frame_h) $(inferior_h) \
|
||||
$(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_string_h) $(bfd_h) $(gdb_obstack_h) \
|
||||
$(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) \
|
||||
|
141
gdb/cp-support.c
Normal file
141
gdb/cp-support.c
Normal file
@ -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;
|
||||
}
|
25
gdb/cp-support.h
Normal file
25
gdb/cp-support.h
Normal file
@ -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);
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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, int method_id, int signature_id)
|
||||
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,7 +3478,6 @@ build_gdbtypes (void)
|
||||
"__bfd_vma", (struct objfile *) NULL);
|
||||
}
|
||||
|
||||
|
||||
extern void _initialize_gdbtypes (void);
|
||||
void
|
||||
_initialize_gdbtypes (void)
|
||||
|
@ -1124,7 +1124,7 @@ extern struct type *check_typedef (struct type *);
|
||||
|
||||
#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 *);
|
||||
|
||||
|
@ -620,13 +620,11 @@ pascal_object_print_class_method (char *valaddr, struct type *type,
|
||||
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 *valaddr, struct type *type,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
181
gdb/stabsread.c
181
gdb/stabsread.c
@ -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 *fip, char **pp, struct type *type,
|
||||
}
|
||||
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);
|
||||
|
18
gdb/valops.c
18
gdb/valops.c
@ -2302,12 +2302,11 @@ search_struct_method (char *name, struct value **arg1p,
|
||||
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 value **arg1p,
|
||||
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, char *method, int offset,
|
||||
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 type *domain, int offset,
|
||||
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 type *domain, int offset,
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user