[RFA] Revised C++ ABI abstraction patches

Jim Blandy
2001-03-15T01:50:00Z

I've gone through the set of patches Dan posted back in February,
incorporated the suggestions people made, and made some further
cleanups myself. These patches depend on the demangler patches I just
posted to gcc-patches (and CC'd here).

They're not fit to be applied yet, since we don't yet automatically
detect whether the executable uses the V3 or V2 ABI. Nonetheless, I'm
posting them here looking for comments, and so people can try them
out.

Certainly, if you are a maintainer, and you have objections to
something you see here, I'm all ears.

2001-03-15 Jim Blandy <jimb@redhat.com>

* cp-abi-gnu-v2.c (gnu_v2_destructor_prefix_p,
gnu_v2_constructor_prefix_p, gnu_v2_vtable_prefix_p,
init_gnu_v2_ops): Renamed from gnuv2_destructor_prefix_p,
gnuv2_constructor_prefix_p, gnuv2_vtable_prefix_p,
init_gnuv2_ops, to match general conventions used in GDB
(words are separated by underscores). Make these all static.
Reformat definitions according to GNU coding standards.
* cp-abi-gnu-v3.c (gnu_v3_destructor_prefix_p,
gnu_v3_constructor_prefix_p, gnu_v3_vtable_prefix_p,
init_gnu_v3_ops): Renamed from gnuv3_destructor_prefix_p,
gnuv3_constructor_prefix_p, gnuv3_vtable_prefix_p,
init_gnuv3_ops, to match general conventions used in GDB.
Make these all static. Reformat definitions according to GNU
coding standards.

* cp-abi-gnu-v2.c (gnuv2_vtable_prefix_p): Neaten up,
following suggestion from Michael Chastain.

* cp-abi-gnu-v3.c: Don't #include "gdb_regex.h" any more.
Do #include "demangle.h".
(gnuv3_destructor_prefix_p, gnuv3_constructor_prefix_p):
Use new functions exported by demangler to correctly recognize
mangled names of constructors and destructors.
* Makefile.in (cp-abi-gnu-v3.o): Remove gdb_regex.h from
list of dependencies; add $(demangle_h).

* cp-abi-gnu-v3.c (gnuv3_vtable_prefix_p): Fix sense of test
of strncmp's return value. (Thanks to Michael Chastain.)

* cp-abi-gnu-v2.c, cp-abi-gnu-v3.c: Renamed from gnu-v2-abi.c
and gnu-v3-abi.c, to show more clearly that they are
implementations of cp-abi.h.
* Makefile.in: Adjusted accordingly.

2001-02-20 Daniel Berlin <dberlin@redhat.com>

* Makefile.in (SFILES): Add gnu-v2-abi.c, gnu-v3-abi.c
(COMMON_OBJS): Add gnu-v2-abi.o, gnu-v3-abi.o
(gnu-v3-abi.o): Add.
(gnu-v2-abi.o): Add.
(symtab.o): Add cp-abi.h.
(linespec.o): Add cp-abi.h.
(dbxread.o): Add cp-abi.h.
(c-typeprint.o): Add cp-abi.h.

* cp-abi.h: New file. C++ abi abstraction

* gnu-v2-abi.c: New file. C++ abi abstraction implementation for
v2 abi.

* gnu-v3-abi.c New file. C++ abi abstraction implementation for v3
abi.

* valops.c (value_rtti_type): VTBL_PREFIX_P -> vtbl_prefix_p.
Add cp-abi.h to the include list.

* symtab.c (gdb_mangle_name): DESTRUCTOR_PREFIX_P ->
destructor_prefix_p.
Replace hardcoded g++ v2 constructor name test with
constructor_prefix_p.
Add cp-abi.h to the include list.

* linespec.c (find_methods): Change SYMBOL_TYPE (sym_class) to
CHECK_TYPEDEF (t), remove FIXME.
Change method name comparison from STREQ to strcmp_iw.
DESTRUCTOR_PREFIX_P -> destructor_prefix_p, fix test so it works
(it was broken before, it was doing the reverse of what it
should).
Add cp-abi.h to include list.

* dbxread.c (record_minimal_symbol): VTBL_PREFIX_P ->
vtbl_prefix_p.
Add cp-abi.h to include list.

* c-typeprint.c (c_type_print_base): Remove hardcoded g++ v2
destructor/constructor name test, replace with
destructor_prefix_p, constructor_prefix_p.
Change STREQN (method_name, "~", 1) to method_name[0] == '~'.
Add cp-abi.h to include list

* jv-typeprint.c (java_type_print_base): Remove hardcoded g++ v2
destructor/constructor name test, replace with
destructor_prefix_p, constructor_prefix_p.

* symtab.h: Remove VTBL_PREFIX_P macro.
Remove DESTRUCTOR_PREFIX_P macro.

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.72
diff -c -c -3 -p -r1.72 Makefile.in
*** gdb/Makefile.in 2001/03/10 06:17:20 1.72
--- gdb/Makefile.in 2001/03/15 09:40:05
*************** SFILES = ax-general.c ax-gdb.c bcache.c
*** 539,545 ****
tui/tuiStack.c tui/tuiStack.h tui/tuiWin.c tui/tuiWin.h \
tui/tui-file.h tui/tui-file.c \
ui-file.h ui-file.c \
! frame.c

LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c

--- 539,546 ----
tui/tuiStack.c tui/tuiStack.h tui/tuiWin.c tui/tuiWin.h \
tui/tui-file.h tui/tui-file.c \
ui-file.h ui-file.c \
! frame.c \
! cp-abi-gnu-v2.c cp-abi-gnu-v3.c

LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c

*************** floatformat_h = $(INCLUDE_DIR)/floatform
*** 553,558 ****
--- 554,560 ----
bfd_h = $(BFD_DIR)/bfd.h
dis-asm_h = $(INCLUDE_DIR)/dis-asm.h
remote-sim_h = $(INCLUDE_DIR)/remote-sim.h
+ demangle_h = $(INCLUDE_DIR)/demangle.h

dcache_h = dcache.h
remote_utils_h = $(dcache_h) serial.h target.h remote-utils.h $(remote-sim_h)
*************** value_h = value.h $(symtab_h) $(gdbtypes
*** 584,589 ****
--- 586,592 ----
breakpoint_h = breakpoint.h $(frame_h) $(value_h)

command_h = command.h
+ cp_abi_h = cp-abi.h
gdbcmd_h = gdbcmd.h $(command_h)
call_cmds_h = call-cmds.h
regcache_h = regcache.h
*************** COMMON_OBS = version.o blockframe.o brea
*** 685,691 ****
c-valprint.o cp-valprint.o ch-valprint.o f-valprint.o m2-valprint.o \
nlmread.o serial.o mdebugread.o os9kread.o top.o utils.o \
ui-file.o tui-file.o \
! frame.o

OBS = $(COMMON_OBS) $(ANNOTATE_OBS)

--- 688,695 ----
c-valprint.o cp-valprint.o ch-valprint.o f-valprint.o m2-valprint.o \
nlmread.o serial.o mdebugread.o os9kread.o top.o utils.o \
ui-file.o tui-file.o \
! frame.o \
! cp-abi-gnu-v2.o cp-abi-gnu-v3.o

OBS = $(COMMON_OBS) $(ANNOTATE_OBS)

*************** c-lang.o: c-lang.c c-lang.h $(defs_h) $(
*** 1228,1234 ****

c-typeprint.o: c-typeprint.c c-lang.h $(defs_h) $(expression_h) \
$(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) \
! target.h typeprint.h $(value_h) gdb_string.h

c-valprint.o: c-valprint.c $(defs_h) $(expression_h) $(gdbtypes_h) \
language.h $(symtab_h) valprint.h $(value_h)
--- 1232,1238 ----

c-typeprint.o: c-typeprint.c c-lang.h $(defs_h) $(expression_h) \
$(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) \
! target.h typeprint.h $(value_h) gdb_string.h $(cp_abi_h)

c-valprint.o: c-valprint.c $(defs_h) $(expression_h) $(gdbtypes_h) \
language.h $(symtab_h) valprint.h $(value_h)
*************** dcache.o: dcache.c $(dcache_h) $(defs_h)
*** 1293,1299 ****
dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
$(gdbtypes_h) language.h objfiles.h partial-stab.h stabsread.h \
! symfile.h $(symtab_h) target.h gdb_string.h

delta68-nat.o: delta68-nat.c $(defs_h)

--- 1297,1303 ----
dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
$(gdbtypes_h) language.h objfiles.h partial-stab.h stabsread.h \
! symfile.h $(symtab_h) target.h gdb_string.h $(cp_abi_h)

delta68-nat.o: delta68-nat.c $(defs_h)

*************** arch-utils.o: arch-utils.c $(defs_h) $(b
*** 1452,1458 ****

gdbtypes.o: gdbtypes.c $(bfd_h) complaints.h $(defs_h) $(expression_h) \
$(gdbtypes_h) language.h objfiles.h symfile.h $(symtab_h) target.h \
! $(value_h) gdb_string.h wrapper.h

go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) gdb_wait.h $(gdbcore_h) \
$(command_h) $(floatformat_h) target.h i387-nat.h $(regcache_h)
--- 1456,1462 ----

gdbtypes.o: gdbtypes.c $(bfd_h) complaints.h $(defs_h) $(expression_h) \
$(gdbtypes_h) language.h objfiles.h symfile.h $(symtab_h) target.h \
! $(value_h) gdb_string.h wrapper.h $(cp_abi_h)

go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) gdb_wait.h $(gdbcore_h) \
$(command_h) $(floatformat_h) target.h i387-nat.h $(regcache_h)
*************** go32-nat.o: go32-nat.c $(defs_h) $(infer
*** 1460,1465 ****
--- 1464,1474 ----
gnu-nat.o: process_reply_S.h exc_request_S.h notify_S.h msg_reply_S.h \
exc_request_U.h msg_U.h gnu-nat.h

+ cp-abi-gnu-v3.o: cp-abi-gnu-v3.c $(cp_abi_h) $(defs) gdb_string.h \
+ $(demangle_h)
+
+ cp-abi-gnu-v2.o: cp-abi-gnu-v2.c $(cp_abi_h) $(defs) gdb_regex.h gdb_string.h
+
h8300-tdep.o: h8300-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(regcache_h)

h8500-tdep.o: h8500-tdep.c $(bfd_h) $(dis-asm_h) $(defs_h) \
*************** jv-lang.o: jv-lang.c $(bfd_h) $(defs_h)
*** 1554,1564 ****
gdb_string.h $(value_h) c-lang.h jv-lang.h $(gdbcore_h)

jv-typeprint.o: jv-typeprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
! $(value_h) $(INCLUDE_DIR)/demangle.h jv-lang.h gdb_string.h \
typeprint.h c-lang.h

jv-valprint.o: jv-valprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
! $(expression_h) $(value_h) $(INCLUDE_DIR)/demangle.h valprint.h \
language.h jv-lang.h c-lang.h gdbcore.h annotate.h

kod.o: kod.c $(defs_h) $(command_h) $(gdbcmd_h) target.h gdb_string.h kod.h
--- 1563,1573 ----
gdb_string.h $(value_h) c-lang.h jv-lang.h $(gdbcore_h)

jv-typeprint.o: jv-typeprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
! $(value_h) $(demangle_h) jv-lang.h gdb_string.h \
typeprint.h c-lang.h

jv-valprint.o: jv-valprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
! $(expression_h) $(value_h) $(demangle_h) valprint.h \
language.h jv-lang.h c-lang.h gdbcore.h annotate.h

kod.o: kod.c $(defs_h) $(command_h) $(gdbcmd_h) target.h gdb_string.h kod.h
*************** symmisc.o: symmisc.c $(bfd_h) $(breakpoi
*** 1962,1972 ****
symtab.o: symtab.c call-cmds.h $(defs_h) $(expression_h) $(frame_h) \
$(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h objfiles.h \
gnu-regex.h symfile.h $(symtab_h) target.h $(value_h) \
! gdb_string.h linespec.h

linespec.o: linespec.c linespec.h $(defs_h) $(frame_h) $(value_h) \
objfiles.h symfile.h completer.h $(symtab_h) \
! $(INCLUDE_DIR)/demangle.h command.h

tic80-tdep.o: tic80-tdep.c $(defs_h) $(regcache_h)

--- 1971,1981 ----
symtab.o: symtab.c call-cmds.h $(defs_h) $(expression_h) $(frame_h) \
$(gdbcmd_h) $(gdbcore_h) $(gdbtypes_h) language.h objfiles.h \
gnu-regex.h symfile.h $(symtab_h) target.h $(value_h) \
! gdb_string.h linespec.h $(cp_abi_h)

linespec.o: linespec.c linespec.h $(defs_h) $(frame_h) $(value_h) \
objfiles.h symfile.h completer.h $(symtab_h) \
! $(demangle_h) command.h $(cp_abi_h)

tic80-tdep.o: tic80-tdep.c $(defs_h) $(regcache_h)

Index: gdb/c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.6
diff -c -c -3 -p -r1.6 c-typeprint.c
*** gdb/c-typeprint.c 2001/03/07 02:57:08 1.6
--- gdb/c-typeprint.c 2001/03/15 09:40:06
***************
*** 38,43 ****
--- 38,44 ----

#include "gdb_string.h"
#include <errno.h>
+ #include "cp-abi.h"

/* Flag indicating target was compiled by HP compiler */
extern int hp_som_som_object_present;
*************** c_type_print_base (struct type *type, st
*** 902,912 ****
{
char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
int is_full_physname_constructor =
! ((physname[0] == '_' && physname[1] == '_'
! && strchr ("0123456789Qt", physname[2]))
! || STREQN (physname, "__ct__", 6)
! || DESTRUCTOR_PREFIX_P (physname)
! || STREQN (physname, "__dt__", 6));

QUIT;
if (TYPE_FN_FIELD_PROTECTED (f, j))
--- 903,912 ----
{
char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
int is_full_physname_constructor =
! constructor_prefix_p (physname)
! || destructor_prefix_p (physname)
! || method_name[0] == '~';
!

QUIT;
if (TYPE_FN_FIELD_PROTECTED (f, j))
Index: gdb/cp-abi-gnu-v2.c
===================================================================
RCS file: cp-abi-gnu-v2.c
diff -N cp-abi-gnu-v2.c
*** gdb/cp-abi-gnu-v2.c Tue May 5 13:32:27 1998
--- gdb/cp-abi-gnu-v2.c Thu Mar 15 01:40:06 2001
***************
*** 0 ****
--- 1,74 ----
+ /* Abstraction of GNU v2 abi.
+ Contributed by Daniel Berlin <dberlin@redhat.com>
+ Copyright 2001 Free Software Foundation, Inc.
+
+ 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-abi.h"
+ #include "gdb_regex.h"
+ #include "gdb_string.h"
+ #include <ctype.h>
+
+ struct cp_abi_ops gnu_v2_abi_ops;
+
+ static int
+ gnu_v2_destructor_prefix_p (const char * name)
+ {
+ return ((name[0] == '_' && is_cplus_marker (name[1]) && name[2] == '_')
+ || strncmp(name, "__dt__", 6) == 0);
+ }
+
+ static int
+ gnu_v2_constructor_prefix_p (const char * name)
+ {
+ return ((name[0] == '_' && name[1] == '_'
+ && (isdigit (name[2]) || strchr ("Qt", name[2])))
+ || strncmp(name, "__ct__", 6) == 0);
+ }
+
+ static int
+ gnu_v2_vtable_prefix_p (const char * name)
+ {
+ return ((strncmp (name, "_VT", 3) == 0 && is_cplus_marker (name[3]))
+ || (strncmp (name, "_vt", 3) == 0 && is_cplus_marker (name[3]))
+ || (strncmp (name, "__vt_", 5) == 0));
+ }
+
+ static void
+ init_gnu_v2_ops (void)
+ {
+ gnu_v2_abi_ops.cpo_shortname = "gnu-v2";
+ gnu_v2_abi_ops.cpo_longname = "GNU G++ Version 2 ABI";
+ gnu_v2_abi_ops.cpo_doc = "G++ Version 2 ABI";
+ gnu_v2_abi_ops.cpo_destructor_prefix_p = gnu_v2_destructor_prefix_p;
+ gnu_v2_abi_ops.cpo_constructor_prefix_p = gnu_v2_constructor_prefix_p;
+ gnu_v2_abi_ops.cpo_vtable_prefix_p = gnu_v2_vtable_prefix_p;
+ }
+
+
+ /* struct cp_abi_ops current_cp_abi; */
+ void
+ _initialize_gnu_v2_abi (void)
+ {
+ init_gnu_v2_ops();
+ /* current_cp_abi = gnu_v2_abi_ops; */
+ }
+
Index: gdb/cp-abi-gnu-v3.c
===================================================================
RCS file: cp-abi-gnu-v3.c
diff -N cp-abi-gnu-v3.c
*** gdb/cp-abi-gnu-v3.c Tue May 5 13:32:27 1998
--- gdb/cp-abi-gnu-v3.c Thu Mar 15 01:40:06 2001
***************
*** 0 ****
--- 1,98 ----
+ /* Abstraction of GNU v3 abi.
+ Contributed by Daniel Berlin <dberlin@redhat.com>
+ Copyright 2001 Free Software Foundation, Inc.
+
+ 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-abi.h"
+ #include "gdb_string.h"
+ #include "demangle.h"
+
+ struct cp_abi_ops gnu_v3_abi_ops;
+
+
+ static int
+ gnu_v3_destructor_prefix_p (const char * name)
+ {
+ /* A quick false positive test: all destructors should start with
+ "_Z", and end with "D[012]Ev". */
+ if (! strncmp (name, "_Z", 2))
+ {
+ int length = strlen (name);
+
+ if (! strcmp (name + length - 2, "Ev")
+ && ('0' <= name[length - 3] && name[length - 3] <= '2')
+ && name[length - 4] == 'D')
+ return is_gnu_v3_mangled_destructor (name) != 0;
+ }
+
+ return 0;
+ }
+
+
+ static int
+ gnu_v3_constructor_prefix_p (const char * name)
+ {
+ /* A quick false positive test: all constructors should start with _Z,
+ and contain a match for "C[123]". */
+ if (! strncmp (name, "_Z", 2))
+ {
+ const char *scan = name;
+
+ while ((scan = strchr (scan, 'C')) != 0)
+ {
+ if ('1' <= scan[1] && scan[1] <= '3')
+ return is_gnu_v3_mangled_constructor (name) != 0;
+
+ scan++;
+ }
+ }
+
+ return 0;
+ }
+
+
+ static int
+ gnu_v3_vtable_prefix_p (const char * name)
+ {
+ return strncmp (name, "_ZTV", 4) == 0;
+ }
+
+
+ void
+ init_gnu_v3_ops (void)
+ {
+ gnu_v3_abi_ops.cpo_shortname = "gnu-v3";
+ gnu_v3_abi_ops.cpo_longname = "GNU G++ Version 3 ABI";
+ gnu_v3_abi_ops.cpo_doc = "G++ Version 3 ABI";
+ gnu_v3_abi_ops.cpo_destructor_prefix_p = gnu_v3_destructor_prefix_p;
+ gnu_v3_abi_ops.cpo_constructor_prefix_p = gnu_v3_constructor_prefix_p;
+ gnu_v3_abi_ops.cpo_vtable_prefix_p = gnu_v3_vtable_prefix_p;
+
+ }
+ struct cp_abi_ops current_cp_abi;
+ void
+ _initialize_gnu_v3_abi (void)
+ {
+ init_gnu_v3_ops();
+ current_cp_abi = gnu_v3_abi_ops;
+ }
+
Index: gdb/cp-abi.h
===================================================================
RCS file: cp-abi.h
diff -N cp-abi.h
*** gdb/cp-abi.h Tue May 5 13:32:27 1998
--- gdb/cp-abi.h Thu Mar 15 01:40:06 2001
***************
*** 0 ****
--- 1,75 ----
+ /* Abstraction of various C++ ABI's we support, and the info we need
+ to get from them.
+ Contributed by Daniel Berlin <dberlin@redhat.com>
+ Copyright 2001 Free Software Foundation, Inc.
+
+ 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. */
+
+ #ifndef CP_ABI_H_
+ #define CP_ABI_H_ 1
+
+ /* Following the target ops as a reference */
+ struct cp_abi_ops
+ {
+ const char *cpo_shortname;
+ const char *cpo_longname;
+ const char *cpo_doc;
+
+
+ /* FIXME: prefix is a misnomer, because not all ABI's do
+ constructors by prefix. However, we don't want these names to be
+ not understandable, and ca_mangled_name_is_constructor_p is a
+ little long. Ideas?
+ */
+ /* Determine if the given *mangled* name is a destructor. Might
+ change to demangled name in the future, but not without warning. It
+ depends on whether or not this ends up being completely used in the
+ old GNU abi, or if it was really needed somewhere else */
+
+ int (*cpo_destructor_prefix_p) (const char *name);
+
+ /* Determine if a given *mangled* name is a constructor. Same
+ warning as for destructor functions.*/
+ int (*cpo_constructor_prefix_p) (const char *name);
+
+ /* Determine if a given *mangled* name is a vtable. Same warning as
+ for constructors and destructor functions. */
+ int (*cpo_vtable_prefix_p) (const char *name);
+
+ /* Determine if a given *mangled* name is an operator. Same warning
+ as all of the others */
+ int (*cpo_operator_prefix_p) (const char *name);
+ };
+
+ extern struct cp_abi_ops current_cp_abi;
+
+ #define constructor_prefix_p(NAME) \
+ (*current_cp_abi.cpo_constructor_prefix_p)(NAME)
+
+ #define destructor_prefix_p(NAME) \
+ (*current_cp_abi.cpo_destructor_prefix_p)(NAME)
+
+ #define vtbl_prefix_p(NAME) \
+ (*current_cp_abi.cpo_vtable_prefix_p)(NAME)
+
+ #define operator_prefix_p(NAME) \
+ (*current_cp_abi.cpo_operator_prefix_p)(NAME)
+ #endif
+
Index: gdb/dbxread.c
===================================================================
RCS file: /cvs/src/src/gdb/dbxread.c,v
retrieving revision 1.15
diff -c -c -3 -p -r1.15 dbxread.c
*** gdb/dbxread.c 2001/03/07 02:57:08 1.15
--- gdb/dbxread.c 2001/03/15 09:40:08
***************
*** 58,63 ****
--- 58,64 ----
#include "demangle.h"
#include "language.h" /* Needed inside partial-stab.h */
#include "complaints.h"
+ #include "cp-abi.h"

#include "aout/aout64.h"
#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */
*************** record_minimal_symbol (char *name, CORE_
*** 514,520 ****
char *tempstring = name;
if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
++tempstring;
! if (VTBL_PREFIX_P ((tempstring)))
ms_type = mst_data;
}
section = SECT_OFF_DATA (objfile);
--- 515,521 ----
char *tempstring = name;
if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
++tempstring;
! if (vtbl_prefix_p (tempstring))
ms_type = mst_data;
}
section = SECT_OFF_DATA (objfile);
Index: gdb/gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.18
diff -c -c -3 -p -r1.18 gdbtypes.c
*** gdb/gdbtypes.c 2001/03/07 02:57:08 1.18
--- gdb/gdbtypes.c 2001/03/15 09:40:09
***************
*** 35,40 ****
--- 35,41 ----
#include "complaints.h"
#include "gdbcmd.h"
#include "wrapper.h"
+ #include "cp-abi.h"

/* These variables point to the objects
representing the predefined C data types. */
*************** get_destructor_fn_field (struct type *t,
*** 1027,1033 ****

for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
{
! if (DESTRUCTOR_PREFIX_P (TYPE_FN_FIELD_PHYSNAME (f, j)))
{
*method_indexp = i;
*field_indexp = j;
--- 1028,1034 ----

for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
{
! if (destructor_prefix_p (TYPE_FN_FIELD_PHYSNAME (f, j)) != 0)
{
*method_indexp = i;
*field_indexp = j;
Index: gdb/jv-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/jv-typeprint.c,v
retrieving revision 1.4
diff -c -c -3 -p -r1.4 jv-typeprint.c
*** gdb/jv-typeprint.c 2001/03/06 08:21:09 1.4
--- gdb/jv-typeprint.c 2001/03/15 09:40:09
***************
*** 28,34 ****
#include "gdb_string.h"
#include "typeprint.h"
#include "c-lang.h"
!
/* Local functions */

static void java_type_print_base (struct type * type,
--- 28,34 ----
#include "gdb_string.h"
#include "typeprint.h"
#include "c-lang.h"
! #include "cp-abi.h"
/* Local functions */

static void java_type_print_base (struct type * type,
*************** java_type_print_base (struct type *type,
*** 224,235 ****

physname = TYPE_FN_FIELD_PHYSNAME (f, j);

! is_full_physname_constructor =
! ((physname[0] == '_' && physname[1] == '_'
! && strchr ("0123456789Qt", physname[2]))
! || STREQN (physname, "__ct__", 6)
! || DESTRUCTOR_PREFIX_P (physname)
! || STREQN (physname, "__dt__", 6));

QUIT;

--- 224,230 ----

physname = TYPE_FN_FIELD_PHYSNAME (f, j);

! is_full_physname_constructor = constructor_prefix_p (physname) != 0 || destructor_prefix_p (physname) != 0;

QUIT;

Index: gdb/linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.6
diff -c -c -3 -p -r1.6 linespec.c
*** gdb/linespec.c 2001/03/14 18:36:45 1.6
--- gdb/linespec.c 2001/03/15 09:40:10
***************
*** 29,34 ****
--- 29,35 ----
#include "demangle.h"
#include "value.h"
#include "completer.h"
+ #include "cp-abi.h"

/* Prototype for one function in parser-defs.h,
instead of including that entire file. */
*************** find_methods (struct type *t, char *name
*** 119,127 ****
{
int method_counter;

! /* FIXME: Shouldn't this just be CHECK_TYPEDEF (t)? */
! t = SYMBOL_TYPE (sym_class);
!
/* Loop over each method name. At this level, all overloads of a name
are counted as a single name. There is an inner loop which loops over
each overload. */
--- 120,126 ----
{
int method_counter;

! CHECK_TYPEDEF (t);
/* Loop over each method name. At this level, all overloads of a name
are counted as a single name. There is an inner loop which loops over
each overload. */
*************** find_methods (struct type *t, char *name
*** 144,150 ****
method_name = dem_opname;
}

! if (STREQ (name, method_name))
/* Find all the overloaded methods with that name. */
for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
field_counter >= 0;
--- 143,149 ----
method_name = dem_opname;
}

! if (strcmp_iw (name, method_name) == 0)
/* Find all the overloaded methods with that name. */
for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
field_counter >= 0;
*************** find_methods (struct type *t, char *name
*** 168,176 ****
}
else
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
!
/* Destructor is handled by caller, dont add it to the list */
! if (DESTRUCTOR_PREFIX_P (phys_name))
continue;

sym_arr[i1] = lookup_symbol (phys_name,
--- 167,175 ----
}
else
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
!
/* Destructor is handled by caller, dont add it to the list */
! if (destructor_prefix_p (phys_name) != 0)
continue;

sym_arr[i1] = lookup_symbol (phys_name,
Index: gdb/symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.32
diff -c -c -3 -p -r1.32 symtab.c
*** gdb/symtab.c 2001/03/06 08:21:17 1.32
--- gdb/symtab.c 2001/03/15 09:40:12
***************
*** 45,51 ****
#include "gdb_string.h"
#include "gdb_stat.h"
#include <ctype.h>
!
/* Prototype for one function in parser-defs.h,
instead of including that entire file. */

--- 45,51 ----
#include "gdb_string.h"
#include "gdb_stat.h"
#include <ctype.h>
! #include "cp-abi.h"
/* Prototype for one function in parser-defs.h,
instead of including that entire file. */

*************** gdb_mangle_name (struct type *type, int
*** 288,294 ****
int is_full_physname_constructor;

int is_constructor;
! int is_destructor = DESTRUCTOR_PREFIX_P (physname);
/* Need a new type prefix. */
char *const_prefix = method->is_const ? "C" : "";
char *volatile_prefix = method->is_volatile ? "V" : "";
--- 288,294 ----
int is_full_physname_constructor;

int is_constructor;
! int is_destructor = destructor_prefix_p (physname);
/* Need a new type prefix. */
char *const_prefix = method->is_const ? "C" : "";
char *volatile_prefix = method->is_volatile ? "V" : "";
*************** gdb_mangle_name (struct type *type, int
*** 298,307 ****
if (OPNAME_PREFIX_P (field_name))
return xstrdup (physname);

! is_full_physname_constructor =
! ((physname[0] == '_' && physname[1] == '_' &&
! (isdigit (physname[2]) || physname[2] == 'Q' || physname[2] == 't'))
! || (strncmp (physname, "__ct", 4) == 0));

is_constructor =
is_full_physname_constructor || (newname && STREQ (field_name, newname));
--- 298,304 ----
if (OPNAME_PREFIX_P (field_name))
return xstrdup (physname);

! is_full_physname_constructor = constructor_prefix_p (physname);

is_constructor =
is_full_physname_constructor || (newname && STREQ (field_name, newname));
Index: gdb/symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.20
diff -c -c -3 -p -r1.20 symtab.h
*** gdb/symtab.h 2001/03/07 02:57:08 1.20
--- gdb/symtab.h 2001/03/15 09:40:13
*************** struct partial_symtab
*** 1051,1075 ****
#define OPNAME_PREFIX_P(NAME) \
(!strncmp (NAME, "operator", 8))

- /* Macro that yields non-zero value iff NAME is the prefix for C++ vtbl
- names. Note that this macro is g++ specific (FIXME).
- '_vt$' is the old cfront-style vtables; '_VT$' is the new
- style, using thunks (where '$' is really CPLUS_MARKER). */
-
- #define VTBL_PREFIX_P(NAME) \
- (((NAME)[0] == '_' \
- && (((NAME)[1] == 'V' && (NAME)[2] == 'T') \
- || ((NAME)[1] == 'v' && (NAME)[2] == 't')) \
- && is_cplus_marker ((NAME)[3])) || ((NAME)[0]=='_' && (NAME)[1]=='_' \
- && (NAME)[2]=='v' && (NAME)[3]=='t' && (NAME)[4]=='_'))
-
- /* Macro that yields non-zero value iff NAME is the prefix for C++ destructor
- names. Note that this macro is g++ specific (FIXME). */
-
- #define DESTRUCTOR_PREFIX_P(NAME) \
- ((NAME)[0] == '_' && is_cplus_marker ((NAME)[1]) && (NAME)[2] == '_')
\f
-
/* External variables and functions for the objects described above. */

/* This symtab variable specifies the current file for printing source lines */
--- 1051,1057 ----
Index: gdb/valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.33
diff -c -c -3 -p -r1.33 valops.c
*** gdb/valops.c 2001/03/06 08:21:18 1.33
--- gdb/valops.c 2001/03/15 09:40:15
***************
*** 31,36 ****
--- 31,37 ----
#include "language.h"
#include "gdbcmd.h"
#include "regcache.h"
+ #include "cp-abi.h"

#include <errno.h>
#include "gdb_string.h"
*************** value_rtti_type (value_ptr v, int *full,
*** 3296,3302 ****

/* Try to find a symbol that is the vtable */
minsym=lookup_minimal_symbol_by_pc(vtbl);
! if (minsym==NULL || (demangled_name=SYMBOL_NAME(minsym))==NULL || !VTBL_PREFIX_P(demangled_name))
return NULL;

/* If we just skip the prefix, we get screwed by namespaces */
--- 3297,3303 ----

/* Try to find a symbol that is the vtable */
minsym=lookup_minimal_symbol_by_pc(vtbl);
! if (minsym==NULL || (demangled_name=SYMBOL_NAME(minsym))==NULL || !vtbl_prefix_p(demangled_name))
return NULL;

/* If we just skip the prefix, we get screwed by namespaces */