(Changes from Daniel Berlin, with revisions by Jim Blandy.)
authorJim Blandy <jimb@codesourcery.com>
Fri, 27 Apr 2001 00:19:09 +0000 (00:19 +0000)
committerJim Blandy <jimb@codesourcery.com>
Fri, 27 Apr 2001 00:19:09 +0000 (00:19 +0000)
Abstract out operations specific to particular C++ ABI's, and
invoke them through a function table.  This removes the C++ ABI
dependencies scattered throughout the code, and allows us to
cleanly add support for new C++ ABI's.
* cp-abi.h, cp-abi.h, gnu-v2-abi.c, hpacc-abi.c: New files.
* c-typeprint.c, c-valprint.c, dbxread.c, eval.c, gdbtypes.c,
jv-typeprint.c, linespec.c, symtab.c, typeprint.c, valops.c:
#include "cp-abi.h".  These files all use functions now declared
there.
* symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P):
Deleted.  These services are now provided by functions declared in
cp-abi.h.
* value.h (value_rtti_type, value_virtual_fn_field): Same.
* values.c (value_virtual_fn_field): Same, for this definition.
* valops.c (value_rtti_type): Same.
* c-typeprint.c (c_type_print_base): Use the functions from
"cp-abi.h", instead of the old macros, or hard-coded ABI-specific
tests.
* dbxread.c (record_minimal_symbol): Same.
* gdbtypes.c (get_destructor_fn_field, virtual_base_index,
virtual_base_index_skip_primaries): Same.
* jv-typeprint.c (java_type_print_base): Same.
* linespec.c (find_methods, decode_line_1): Same.
* symtab.c (gdb_mangle_name): Same.
* Makefile.in (SFILES): Add the new .c files mentioned above.
(cp_abi_h): New variable.
(COMMON_OBS): Add gnu-v2-abi.o, hpacc-abi.o, and cp-abi.o.
(cp-abi.o, gnu-v2-abi.o, hpacc-abi.o): New targets.
(c-typeprint.o, c-valprint.o, dbxread.o, eval.o, gdbtypes.o,
jv-typeprint.o, symtab.o, linespec.o, typeprint.o, valops.o): Add
dependency on $(cp_abi_h).

19 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/c-typeprint.c
gdb/c-valprint.c
gdb/cp-abi.c [new file with mode: 0644]
gdb/cp-abi.h [new file with mode: 0644]
gdb/dbxread.c
gdb/eval.c
gdb/gdbtypes.c
gdb/gnu-v2-abi.c [new file with mode: 0644]
gdb/hpacc-abi.c [new file with mode: 0644]
gdb/jv-typeprint.c
gdb/linespec.c
gdb/symtab.c
gdb/symtab.h
gdb/typeprint.c
gdb/valops.c
gdb/value.h
gdb/values.c

index 7f1161f..69fdc41 100644 (file)
@@ -1,3 +1,39 @@
+2001-04-26  Jim Blandy  <jimb@redhat.com>
+
+       (Changes from Daniel Berlin, with revisions by Jim Blandy.)
+       
+       Abstract out operations specific to particular C++ ABI's, and
+       invoke them through a function table.  This removes the C++ ABI
+       dependencies scattered throughout the code, and allows us to
+       cleanly add support for new C++ ABI's.
+       * cp-abi.h, cp-abi.h, gnu-v2-abi.c, hpacc-abi.c: New files.
+       * c-typeprint.c, c-valprint.c, dbxread.c, eval.c, gdbtypes.c,
+       jv-typeprint.c, linespec.c, symtab.c, typeprint.c, valops.c:
+       #include "cp-abi.h".  These files all use functions now declared
+       there.
+       * symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P):
+       Deleted.  These services are now provided by functions declared in
+       cp-abi.h.
+       * value.h (value_rtti_type, value_virtual_fn_field): Same.
+       * values.c (value_virtual_fn_field): Same, for this definition.
+       * valops.c (value_rtti_type): Same.     
+       * c-typeprint.c (c_type_print_base): Use the functions from
+       "cp-abi.h", instead of the old macros, or hard-coded ABI-specific
+       tests.
+       * dbxread.c (record_minimal_symbol): Same.
+       * gdbtypes.c (get_destructor_fn_field, virtual_base_index,
+       virtual_base_index_skip_primaries): Same.
+       * jv-typeprint.c (java_type_print_base): Same.
+       * linespec.c (find_methods, decode_line_1): Same.
+       * symtab.c (gdb_mangle_name): Same.
+       * Makefile.in (SFILES): Add the new .c files mentioned above.
+       (cp_abi_h): New variable.
+       (COMMON_OBS): Add gnu-v2-abi.o, hpacc-abi.o, and cp-abi.o.
+       (cp-abi.o, gnu-v2-abi.o, hpacc-abi.o): New targets.
+       (c-typeprint.o, c-valprint.o, dbxread.o, eval.o, gdbtypes.o,
+       jv-typeprint.o, symtab.o, linespec.o, typeprint.o, valops.o): Add
+       dependency on $(cp_abi_h).
+
 2001-04-26  Michael Snyder  <msnyder@redhat.com>
 
        * thread-db.c (_initialize_thread_db): Add set/show command
index 6874561..ecc5b32 100644 (file)
@@ -539,7 +539,8 @@ SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
        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
+       frame.c \
+       gnu-v2-abi.c hpacc-abi.c cp-abi.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -613,6 +614,8 @@ cli_script_h =      $(srcdir)/cli/cli-script.h
 cli_setshow_h =        $(srcdir)/cli/cli-setshow.h
 cli_utils_h =  $(srcdir)/cli/cli-utils.h
 
+cp_abi_h = cp-abi.h
+
 # Header files that need to have srcdir added.  Note that in the cases
 # where we use a macro like $(gdbcmd_h), things are carefully arranged
 # so that each .h file is listed exactly once (M-x tags-search works
@@ -686,7 +689,8 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
        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
+       frame.o \
+       gnu-v2-abi.o hpacc-abi.o cp-abi.o
 
 OBS = $(COMMON_OBS) $(ANNOTATE_OBS)
 
@@ -1222,10 +1226,10 @@ c-lang.o: c-lang.c c-lang.h $(defs_h) $(expression_h) $(gdbtypes_h) \
 
 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
+       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)
+       language.h $(symtab_h) valprint.h $(value_h) $(cp_abi_h)
 
 f-lang.o: f-lang.c f-lang.h $(defs_h) $(expression_h) $(gdbtypes_h) \
        language.h parser-defs.h $(symtab_h) gdb_string.h
@@ -1278,6 +1282,8 @@ corefile.o: corefile.c $(dis-asm_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
 corelow.o: corelow.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
        target.h gdbthread.h gdb_string.h $(regcache_h)
 
+cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h)
+
 cp-valprint.o: cp-valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
        $(gdbtypes_h) $(symtab_h) $(value_h) gdb_string.h
 
@@ -1287,7 +1293,7 @@ dcache.o: dcache.c $(dcache_h) $(defs_h) $(gdbcmd_h) gdb_string.h \
 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
+       symfile.h $(symtab_h) target.h gdb_string.h $(cp_abi_h)
 
 delta68-nat.o: delta68-nat.c $(defs_h)
 
@@ -1317,7 +1323,7 @@ environ.o: environ.c $(defs_h) environ.h $(gdbcore_h) gdb_string.h
 
 eval.o: eval.c $(bfd_h) $(defs_h) $(expression_h) $(frame_h) \
        $(gdbtypes_h) language.h $(symtab_h) target.h $(value_h) \
-       gdb_string.h
+       gdb_string.h $(cp_abi_h)
 
 event-loop.o: event-loop.c $(defs_h) $(top_h) $(event_loop_h) $(event_top_h)
 
@@ -1446,7 +1452,7 @@ arch-utils.o: arch-utils.c $(defs_h) $(bfd_h) $(gdbcmd_h) \
 
 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
+       $(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)
@@ -1454,6 +1460,9 @@ go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) gdb_wait.h $(gdbcore_h) \
 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
 
+gnu-v2-abi.o: gnu-v2-abi.c $(defs_h) $(cp_abi_h) gdb_string.h $(symtab_h) \
+       $(gdbtypes_h) $(value_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) \
@@ -1462,6 +1471,9 @@ h8500-tdep.o: h8500-tdep.c $(bfd_h) $(dis-asm_h) $(defs_h) \
 
 hp300ux-nat.o: hp300ux-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(regcache_h)
 
+hpacc-abi.o: hpacc-abi.c $(defs_h) $(cp_abi_h) gdb_string.h $(gdbtypes_h) \
+       $(value_h) $(gdbcore_h)
+
 hppa-tdep.o: hppa-tdep.c gdb_wait.h $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
        $(inferior_h) objfiles.h symfile.h target.h $(regcache_h)
 
@@ -1551,7 +1563,7 @@ jv-lang.o: jv-lang.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_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
+       typeprint.h c-lang.h $(cp_abi_h)
 
 jv-valprint.o: jv-valprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
        $(expression_h) $(value_h) $(demangle_h) valprint.h \
@@ -1958,11 +1970,11 @@ symmisc.o: symmisc.c $(bfd_h) $(breakpoint_h) $(command_h) $(defs_h) \
 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
+       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
+       $(demangle_h) command.h $(cp_abi_h)
 
 tic80-tdep.o: tic80-tdep.c $(defs_h) $(regcache_h)
 
@@ -1981,7 +1993,7 @@ top.o: top.c top.h $(bfd_h) $(getopt_h) $(readline_headers) call-cmds.h \
 
 typeprint.o: typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
        $(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \
-       $(value_h) gdb_string.h
+       $(value_h) gdb_string.h $(cp_abi.h)
 
 # OBSOLETE ultra3-nat.o: ultra3-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(regcache_h)
 
@@ -1998,7 +2010,7 @@ valarith.o: valarith.c $(bfd_h) $(defs_h) $(expression_h) \
        gdb_string.h
 
 valops.o: valops.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
-       gdb_string.h $(regcache_h)
+       gdb_string.h $(regcache_h) $(cp_abi_h)
 
 valprint.o: valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
        $(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \
index ab9abc7..789d5f0 100644 (file)
@@ -33,6 +33,7 @@
 #include "demangle.h"
 #include "c-lang.h"
 #include "typeprint.h"
+#include "cp-abi.h"
 
 #include "gdb_string.h"
 #include <errno.h>
@@ -904,11 +905,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
                {
                  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));
+                  is_constructor_name (physname) 
+                  || is_destructor_name (physname)
+                  || method_name[0] == '~';
+
 
                  QUIT;
                  if (TYPE_FN_FIELD_PROTECTED (f, j))
index a4bcfb4..e1e8b82 100644 (file)
@@ -28,6 +28,7 @@
 #include "valprint.h"
 #include "language.h"
 #include "c-lang.h"
+#include "cp-abi.h"
 \f
 
 /* Print function pointer with inferior address ADDRESS onto stdio
@@ -303,6 +304,7 @@ c_val_print (struct type *type, char *valaddr, int embedded_offset,
        }
       /* Fall through.  */
     case TYPE_CODE_STRUCT:
+      /*FIXME: Abstract this away */
       if (vtblprint && cp_is_vtbl_ptr_type (type))
        {
          /* Print the unmangled name if desired.  */
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
new file mode 100644 (file)
index 0000000..eb31270
--- /dev/null
@@ -0,0 +1,99 @@
+/* Generic code for supporting multiple C++ ABI's
+   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 "value.h"
+#include "cp-abi.h"
+
+struct cp_abi_ops current_cp_abi;
+
+struct cp_abi_ops *cp_abis;
+
+int num_cp_abis = 0;
+
+enum ctor_kinds
+is_constructor_name (const char *name)
+{
+  if ((current_cp_abi.is_constructor_name) == NULL)
+    error ("ABI doesn't define required function is_constructor_name");
+  return (*current_cp_abi.is_constructor_name) (name);
+}
+
+enum dtor_kinds
+is_destructor_name (const char *name)
+{
+  if ((current_cp_abi.is_destructor_name) == NULL)
+    error ("ABI doesn't define required function is_destructor_name");
+  return (*current_cp_abi.is_destructor_name) (name);
+}
+
+int
+is_vtable_name (const char *name)
+{
+  if ((current_cp_abi.is_vtable_name) == NULL)
+    error ("ABI doesn't define required function is_vtable_name");
+  return (*current_cp_abi.is_vtable_name) (name);
+}
+
+int
+is_operator_name (const char *name)
+{
+  if ((current_cp_abi.is_operator_name) == NULL)
+    error ("ABI doesn't define required function is_operator_name");
+  return (*current_cp_abi.is_operator_name) (name);
+}
+
+value_ptr
+value_virtual_fn_field (value_ptr * arg1p, struct fn_field * f, int j,
+                       struct type * type, int offset)
+{
+  if ((current_cp_abi.virtual_fn_field) == NULL)
+    return NULL;
+  return (*current_cp_abi.virtual_fn_field) (arg1p, f, j, type, offset);
+}
+struct type *
+value_rtti_type (value_ptr v, int *full, int *top, int *using_enc)
+{
+  if ((current_cp_abi.rtti_type) == NULL)
+    return NULL;
+  return (*current_cp_abi.rtti_type) (v, full, top, using_enc);
+}
+
+int
+register_cp_abi (struct cp_abi_ops abi)
+{
+  cp_abis =
+    xrealloc (cp_abis, (num_cp_abis + 1) * sizeof (struct cp_abi_ops));
+  cp_abis[num_cp_abis++] = abi;
+
+  return 1;
+
+}
+
+int
+switch_to_cp_abi (const char *short_name)
+{
+  int i;
+  for (i = 0; i < num_cp_abis; i++)
+    if (strcmp (cp_abis[i].shortname, short_name) == 0)
+      current_cp_abi = cp_abis[i];
+  return 1;
+}
+
diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h
new file mode 100644 (file)
index 0000000..059816a
--- /dev/null
@@ -0,0 +1,131 @@
+/* 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
+
+/* Kinds of constructors.  All these values are guaranteed to be
+   non-zero.  */
+enum ctor_kinds {
+
+  /* Initialize a complete object, including virtual bases, using
+     memory provided by caller.  */
+  complete_object_ctor = 1,
+
+  /* Initialize a base object of some larger object.  */
+  base_object_ctor,
+
+  /* An allocating complete-object constructor.  */
+  complete_object_allocating_ctor
+};
+
+
+/* Kinds of destructors.  All these values are guaranteed to be
+   non-zero.  */
+enum dtor_kinds {
+
+  /* A destructor which finalizes the entire object, and then calls
+     `delete' on its storage.  */
+  deleting_dtor = 1,
+
+  /* A destructor which finalizes the entire object, but does not call
+     `delete'.  */
+  complete_object_dtor,
+
+  /* A destructor which finalizes a subobject of some larger object.  */
+  base_object_dtor
+};
+  
+
+struct cp_abi_ops
+{
+  const char *shortname;
+  const char *longname;
+  const char *doc;
+
+  /* The functions here that attempt to determine what sort of thing a
+     mangled name refers to may well be revised in the future.  It
+     would certainly be cleaner to carry this information explicitly
+     in GDB's data structures than to derive it from the mangled name.  */
+
+  /* Return non-zero iff NAME is the mangled name of a constructor.
+     Actually, return an `enum ctor_kind' value describing what *kind*
+     of constructor it is.  */
+  enum ctor_kinds (*is_constructor_name) (const char *name);
+
+  /* Return non-zero iff NAME is the mangled name of a destructor.
+     Actually, return an `enum dtor_kind' value describing what *kind*
+     of destructor it is.  */
+  enum dtor_kinds (*is_destructor_name) (const char *name);
+
+  /* Return non-zero iff NAME is the mangled name of a vtable.  */
+  int (*is_vtable_name) (const char *name);
+
+  /* Return non-zero iff NAME is the un-mangled name of an operator,
+     perhaps scoped within some class.  */
+  int (*is_operator_name) (const char *name);
+
+  value_ptr (*virtual_fn_field) (value_ptr * arg1p, struct fn_field * f,
+                                int j, struct type * type, int offset);
+
+  /* Find the real run-time type of a value using RTTI.
+   * V is a pointer to the value.
+   * A pointer to the struct type entry of the run-time type
+   * is returneed.
+   * FULL is a flag that is set only if the value V includes
+   * the entire contents of an object of the RTTI type.
+   * TOP is the offset to the top of the enclosing object of
+   * the real run-time type.  This offset may be for the embedded
+   * object, or for the enclosing object of V.
+   * USING_ENC is the flag that distinguishes the two cases.
+   * If it is 1, then the offset is for the enclosing object,
+   * otherwise for the embedded object.
+   *
+   */
+
+  struct type *(*rtti_type) (value_ptr v, int *full, int *top,
+                            int *using_enc);
+};
+
+
+extern struct cp_abi_ops *cp_abis;
+
+extern int num_cp_abis;
+
+extern struct cp_abi_ops current_cp_abi;
+
+extern enum ctor_kinds is_constructor_name (const char *name);
+extern enum dtor_kinds is_destructor_name (const char *name);
+extern int is_vtable_name (const char *name);
+extern int is_operator_name (const char *name);
+extern value_ptr value_virtual_fn_field (value_ptr * arg1p,
+                                        struct fn_field *f, int j,
+                                        struct type *type, int offset);
+extern struct type *value_rtti_type (value_ptr v, int *full, int *top,
+                                    int *using_enc);
+extern int register_cp_abi (struct cp_abi_ops abi);
+extern int switch_to_cp_abi (const char *short_name);
+
+#endif
+
index cdb1657..d3a1489 100644 (file)
@@ -57,6 +57,7 @@
 #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 */
@@ -514,7 +515,7 @@ record_minimal_symbol (char *name, CORE_ADDR address, int type,
        char *tempstring = name;
        if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
          ++tempstring;
-       if (VTBL_PREFIX_P ((tempstring)))
+       if (is_vtable_name (tempstring))
          ms_type = mst_data;
       }
       section = SECT_OFF_DATA (objfile);
index ceed262..fad995e 100644 (file)
@@ -30,6 +30,7 @@
 #include "frame.h"
 #include "language.h"          /* For CAST_IS_CONVERSION */
 #include "f-lang.h"            /* for array bound stuff */
+#include "cp-abi.h"
 
 /* Defined in symtab.c */
 extern int hp_som_som_object_present;
index 86499e2..f3cff63 100644 (file)
@@ -35,6 +35,7 @@
 #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.  */
@@ -1027,7 +1028,7 @@ get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp)
 
       for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
        {
-         if (DESTRUCTOR_PREFIX_P (TYPE_FN_FIELD_PHYSNAME (f, j)))
+         if (is_destructor_name (TYPE_FN_FIELD_PHYSNAME (f, j)) != 0)
            {
              *method_indexp = i;
              *field_indexp = j;
@@ -1902,12 +1903,12 @@ virtual_base_index (struct type *base, struct type *dclass)
     return -1;
 
   i = 0;
-  vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[0];
+  vbase = virtual_base_list (dclass)[0];
   while (vbase)
     {
       if (vbase == base)
        break;
-      vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[++i];
+      vbase = virtual_base_list (dclass)[++i];
     }
 
   return vbase ? i : -1;
@@ -1936,14 +1937,14 @@ virtual_base_index_skip_primaries (struct type *base, struct type *dclass)
 
   j = -1;
   i = 0;
-  vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[0];
+  vbase = virtual_base_list (dclass)[0];
   while (vbase)
     {
       if (!primary || (virtual_base_index_skip_primaries (vbase, primary) < 0))
        j++;
       if (vbase == base)
        break;
-      vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[++i];
+      vbase = virtual_base_list (dclass)[++i];
     }
 
   return vbase ? j : -1;
diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c
new file mode 100644 (file)
index 0000000..ad73165
--- /dev/null
@@ -0,0 +1,332 @@
+/* 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 "gdb_regex.h"
+#include "gdb_string.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "value.h"
+#include "demangle.h"
+#include "cp-abi.h"
+
+#include <ctype.h>
+
+struct cp_abi_ops gnu_v2_abi_ops;
+
+static int vb_match (struct type *, int, struct type *);
+
+static enum dtor_kinds
+gnuv2_is_destructor_name (const char *name)
+{
+  if ((name[0] == '_' && is_cplus_marker (name[1]) && name[2] == '_')
+      || strncmp (name, "__dt__", 6) == 0)
+    return complete_object_dtor;
+  else
+    return 0;
+}
+
+static enum ctor_kinds
+gnuv2_is_constructor_name (const char *name)
+{
+  if ((name[0] == '_' && name[1] == '_'
+       && (isdigit (name[2]) || strchr ("Qt", name[2])))
+      || strncmp (name, "__ct__", 6) == 0)
+    return complete_object_ctor;
+  else
+    return 0;
+}
+
+static int
+gnuv2_is_vtable_name (const char *name)
+{
+  return (((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] == '_'));
+}
+
+static int
+gnuv2_is_operator_name (const char *name)
+{
+  return strncmp (name, "operator", 8) == 0;
+}
+
+\f
+/* Return a virtual function as a value.
+   ARG1 is the object which provides the virtual function
+   table pointer.  *ARG1P is side-effected in calling this function.
+   F is the list of member functions which contains the desired virtual
+   function.
+   J is an index into F which provides the desired virtual function.
+
+   TYPE is the type in which F is located.  */
+static value_ptr
+gnuv2_virtual_fn_field (value_ptr * arg1p, struct fn_field * f, int j,
+                       struct type * type, int offset)
+{
+  value_ptr arg1 = *arg1p;
+  struct type *type1 = check_typedef (VALUE_TYPE (arg1));
+
+
+  struct type *entry_type;
+  /* First, get the virtual function table pointer.  That comes
+     with a strange type, so cast it to type `pointer to long' (which
+     should serve just fine as a function type).  Then, index into
+     the table, and convert final value to appropriate function type.  */
+  value_ptr entry, vfn, vtbl;
+  value_ptr vi = value_from_longest (builtin_type_int,
+                                    (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
+  struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
+  struct type *context;
+  if (fcontext == NULL)
+    /* We don't have an fcontext (e.g. the program was compiled with
+       g++ version 1).  Try to get the vtbl from the TYPE_VPTR_BASETYPE.
+       This won't work right for multiple inheritance, but at least we
+       should do as well as GDB 3.x did.  */
+    fcontext = TYPE_VPTR_BASETYPE (type);
+  context = lookup_pointer_type (fcontext);
+  /* Now context is a pointer to the basetype containing the vtbl.  */
+  if (TYPE_TARGET_TYPE (context) != type1)
+    {
+      value_ptr tmp = value_cast (context, value_addr (arg1));
+      VALUE_POINTED_TO_OFFSET (tmp) = 0;
+      arg1 = value_ind (tmp);
+      type1 = check_typedef (VALUE_TYPE (arg1));
+    }
+
+  context = type1;
+  /* Now context is the basetype containing the vtbl.  */
+
+  /* This type may have been defined before its virtual function table
+     was.  If so, fill in the virtual function table entry for the
+     type now.  */
+  if (TYPE_VPTR_FIELDNO (context) < 0)
+    fill_in_vptr_fieldno (context);
+
+  /* The virtual function table is now an array of structures
+     which have the form { int16 offset, delta; void *pfn; }.  */
+  vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
+                               TYPE_VPTR_BASETYPE (context));
+
+  /* With older versions of g++, the vtbl field pointed to an array
+     of structures.  Nowadays it points directly to the structure. */
+  if (TYPE_CODE (VALUE_TYPE (vtbl)) == TYPE_CODE_PTR
+      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (vtbl))) == TYPE_CODE_ARRAY)
+    {
+      /* Handle the case where the vtbl field points to an
+         array of structures. */
+      vtbl = value_ind (vtbl);
+
+      /* Index into the virtual function table.  This is hard-coded because
+         looking up a field is not cheap, and it may be important to save
+         time, e.g. if the user has set a conditional breakpoint calling
+         a virtual function.  */
+      entry = value_subscript (vtbl, vi);
+    }
+  else
+    {
+      /* Handle the case where the vtbl field points directly to a structure. */
+      vtbl = value_add (vtbl, vi);
+      entry = value_ind (vtbl);
+    }
+
+  entry_type = check_typedef (VALUE_TYPE (entry));
+
+  if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
+    {
+      /* Move the `this' pointer according to the virtual function table. */
+      VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
+
+      if (!VALUE_LAZY (arg1))
+       {
+         VALUE_LAZY (arg1) = 1;
+         value_fetch_lazy (arg1);
+       }
+
+      vfn = value_field (entry, 2);
+    }
+  else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
+    vfn = entry;
+  else
+    error ("I'm confused:  virtual function table has bad type");
+  /* Reinstantiate the function pointer with the correct type.  */
+  VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
+
+  *arg1p = arg1;
+  return vfn;
+}
+
+
+struct type *
+gnuv2_value_rtti_type (value_ptr v, int *full, int *top, int *using_enc)
+{
+  struct type *known_type;
+  struct type *rtti_type;
+  CORE_ADDR coreptr;
+  value_ptr vp;
+  int using_enclosing = 0;
+  long top_offset = 0;
+  char rtti_type_name[256];
+  CORE_ADDR vtbl;
+  struct minimal_symbol *minsym;
+  struct symbol *sym;
+  char *demangled_name;
+  struct type *btype;
+
+  if (full)
+    *full = 0;
+  if (top)
+    *top = -1;
+  if (using_enc)
+    *using_enc = 0;
+
+  /* Get declared type */
+  known_type = VALUE_TYPE (v);
+  CHECK_TYPEDEF (known_type);
+  /* RTTI works only or class objects */
+  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
+    return NULL;
+
+  /* Plan on this changing in the future as i get around to setting
+     the vtables properly for G++ compiled stuff.  Also, I'll be using
+     the type info functions, which are always right.  Deal with it
+     until then.  */
+
+  /* If the type has no vptr fieldno, try to get it filled in */
+  if (TYPE_VPTR_FIELDNO(known_type) < 0)
+    fill_in_vptr_fieldno(known_type);
+
+  /* If we still can't find one, give up */
+  if (TYPE_VPTR_FIELDNO(known_type) < 0)
+    return NULL;
+
+  /* Make sure our basetype and known type match, otherwise, cast
+     so we can get at the vtable properly.
+  */
+  btype = TYPE_VPTR_BASETYPE (known_type);
+  CHECK_TYPEDEF (btype);
+  if (btype != known_type )
+    {
+      v = value_cast (btype, v);
+      if (using_enc)
+        *using_enc=1;
+    }
+  /*
+    We can't use value_ind here, because it would want to use RTTI, and
+    we'd waste a bunch of time figuring out we already know the type.
+    Besides, we don't care about the type, just the actual pointer
+  */
+  if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
+    return NULL;
+
+  /*
+    If we are enclosed by something that isn't us, adjust the
+    address properly and set using_enclosing.
+  */
+  if (VALUE_ENCLOSING_TYPE(v) != VALUE_TYPE(v))
+    {
+      value_ptr tempval;
+      int bitpos = TYPE_BASECLASS_BITPOS (known_type,
+                                          TYPE_VPTR_FIELDNO (known_type));
+      tempval=value_field (v, TYPE_VPTR_FIELDNO(known_type));
+      VALUE_ADDRESS(tempval) += bitpos / 8;
+      vtbl=value_as_pointer (tempval);
+      using_enclosing=1;
+    }
+  else
+    {
+      vtbl=value_as_pointer(value_field(v,TYPE_VPTR_FIELDNO(known_type)));
+      using_enclosing=0;
+    }
+
+  /* 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
+      || !is_vtable_name (demangled_name))
+    return NULL;
+
+  /* If we just skip the prefix, we get screwed by namespaces */
+  demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
+  *(strchr(demangled_name,' '))=0;
+
+  /* Lookup the type for the name */
+  rtti_type=lookup_typename(demangled_name, (struct block *)0,1);
+
+  if (rtti_type==NULL)
+    return NULL;
+
+  if (TYPE_N_BASECLASSES(rtti_type) > 1 &&  full && (*full) != 1)
+    {
+      if (top)
+        *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
+      if (top && ((*top) >0))
+        {
+          if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
+            {
+              if (full)
+                *full=0;
+            }
+          else
+            {
+              if (full)
+                *full=1;
+            }
+        }
+    }
+  else
+    {
+      if (full)
+        *full=1;
+    }
+  if (using_enc)
+    *using_enc=using_enclosing;
+
+  return rtti_type;
+}
+
+
+static void
+init_gnuv2_ops (void)
+{
+  gnu_v2_abi_ops.shortname = "gnu-v2";
+  gnu_v2_abi_ops.longname = "GNU G++ Version 2 ABI";
+  gnu_v2_abi_ops.doc = "G++ Version 2 ABI";
+  gnu_v2_abi_ops.is_destructor_name = gnuv2_is_destructor_name;
+  gnu_v2_abi_ops.is_constructor_name = gnuv2_is_constructor_name;
+  gnu_v2_abi_ops.is_vtable_name = gnuv2_is_vtable_name;
+  gnu_v2_abi_ops.is_operator_name = gnuv2_is_operator_name;
+  gnu_v2_abi_ops.virtual_fn_field = gnuv2_virtual_fn_field;
+  gnu_v2_abi_ops.rtti_type = gnuv2_value_rtti_type;
+}
+
+void
+_initialize_gnu_v2_abi (void)
+{
+  init_gnuv2_ops ();
+  register_cp_abi (gnu_v2_abi_ops);
+  switch_to_cp_abi ("gnu-v2");
+}
diff --git a/gdb/hpacc-abi.c b/gdb/hpacc-abi.c
new file mode 100644 (file)
index 0000000..f9ec317
--- /dev/null
@@ -0,0 +1,321 @@
+/* Abstraction of HP aCC ABI.
+   Contributed by Daniel Berlin <dberlin@redhat.com>
+   Most of the real code is from HP, i've just fiddled it to fit in
+   the C++ ABI abstraction framework.
+
+   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 "value.h"
+#include "gdb_regex.h"
+#include "gdb_string.h"
+#include "gdbtypes.h"
+#include "gdbcore.h"
+#include "cp-abi.h"
+
+struct cp_abi_ops hpacc_abi_ops;
+
+/* It appears the is_*_name stuff is never used when we try the hpACC
+ * ABI. As such, I have no clue what the real answers are. Shouldn't
+ * have any more effect than it does now.  */
+static regex_t constructor_pattern;
+static regex_t destructor_pattern;
+static regex_t operator_pattern;
+
+static enum dtor_kinds
+hpacc_is_destructor_name (const char *name)
+{
+  if (regexec (&destructor_pattern, name, 0, 0, 0) == 0)
+    return complete_object_dtor;
+  else
+    return 0;
+}
+
+static enum ctor_kinds
+hpacc_is_constructor_name (const char *name)
+{
+  if (regexec (&constructor_pattern, name, 0, 0, 0) == 0)
+    return complete_object_ctor;
+  else
+    return 0;
+}
+
+static int
+hpacc_is_operator_name (const char *name)
+{
+  return regexec (&operator_pattern, name, 0, 0, 0) == 0;
+}
+
+static int
+hpacc_is_vtable_name (const char *name)
+{
+  return strcmp (name,
+                "This will never match anything, please fill it in") == 0;
+}
+
+/* Return a virtual function as a value.
+   ARG1 is the object which provides the virtual function
+   table pointer.  *ARG1P is side-effected in calling this function.
+   F is the list of member functions which contains the desired virtual
+   function.
+   J is an index into F which provides the desired virtual function.
+
+   TYPE is the type in which F is located.  */
+static value_ptr
+hpacc_virtual_fn_field (value_ptr * arg1p, struct fn_field * f, int j,
+                       struct type * type, int offset)
+{
+  value_ptr arg1 = *arg1p;
+  struct type *type1 = check_typedef (VALUE_TYPE (arg1));
+
+  /* Deal with HP/Taligent runtime model for virtual functions */
+  value_ptr vp;
+  value_ptr argp;              /* arg1 cast to base */
+  CORE_ADDR coreptr;           /* pointer to target address */
+  int class_index;             /* which class segment pointer to use */
+  struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);      /* method type */
+
+  argp = value_cast (type, *arg1p);
+
+  if (VALUE_ADDRESS (argp) == 0)
+    error ("Address of object is null; object may not have been created.");
+
+  /* pai: FIXME -- 32x64 possible problem? */
+  /* First word (4 bytes) in object layout is the vtable pointer */
+  coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (argp));    /* pai: (temp)  */
+  /* + offset + VALUE_EMBEDDED_OFFSET (argp)); */
+
+  if (!coreptr)
+    error
+      ("Virtual table pointer is null for object; object may not have been created.");
+
+  /* pai/1997-05-09
+   * FIXME: The code here currently handles only
+   * the non-RRBC case of the Taligent/HP runtime spec; when RRBC
+   * is introduced, the condition for the "if" below will have to
+   * be changed to be a test for the RRBC case.  */
+
+  if (1)
+    {
+      /* Non-RRBC case; the virtual function pointers are stored at fixed
+       * offsets in the virtual table. */
+
+      /* Retrieve the offset in the virtual table from the debug
+       * info.  The offset of the vfunc's entry is in words from
+       * the beginning of the vtable; but first we have to adjust
+       * by HP_ACC_VFUNC_START to account for other entries */
+
+      /* pai: FIXME: 32x64 problem here, a word may be 8 bytes in
+       * which case the multiplier should be 8 and values should be long */
+      vp = value_at (builtin_type_int,
+                    coreptr + 4 * (TYPE_FN_FIELD_VOFFSET (f, j) +
+                                   HP_ACC_VFUNC_START), NULL);
+
+      coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+      /* coreptr now contains the address of the virtual function */
+      /* (Actually, it contains the pointer to the plabel for the function. */
+    }
+  else
+    {
+      /* RRBC case; the virtual function pointers are found by double
+       * indirection through the class segment tables. */
+
+      /* Choose class segment depending on type we were passed */
+      class_index = class_index_in_primary_list (type);
+
+      /* Find class segment pointer.  These are in the vtable slots after
+       * some other entries, so adjust by HP_ACC_VFUNC_START for that. */
+      /* pai: FIXME 32x64 problem here, if words are 8 bytes long
+       * the multiplier below has to be 8 and value should be long. */
+      vp = value_at (builtin_type_int,
+                    coreptr + 4 * (HP_ACC_VFUNC_START + class_index), NULL);
+      /* Indirect once more, offset by function index */
+      /* pai: FIXME 32x64 problem here, again multiplier could be 8 and value long */
+      coreptr =
+       *(CORE_ADDR *) (VALUE_CONTENTS (vp) +
+                       4 * TYPE_FN_FIELD_VOFFSET (f, j));
+      vp = value_at (builtin_type_int, coreptr, NULL);
+      coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+
+      /* coreptr now contains the address of the virtual function */
+      /* (Actually, it contains the pointer to the plabel for the function.) */
+
+    }
+
+  if (!coreptr)
+    error ("Address of virtual function is null; error in virtual table?");
+
+  /* Wrap this addr in a value and return pointer */
+  vp = allocate_value (ftype);
+  VALUE_TYPE (vp) = ftype;
+  VALUE_ADDRESS (vp) = coreptr;
+
+  /* pai: (temp) do we need the value_ind stuff in value_fn_field? */
+  return vp;
+}
+
+
+static struct type *
+hpacc_value_rtti_type (value_ptr v, int *full, int *top, int *using_enc)
+{
+  struct type *known_type;
+  struct type *rtti_type;
+  CORE_ADDR coreptr;
+  value_ptr vp;
+  int using_enclosing = 0;
+  long top_offset = 0;
+  char rtti_type_name[256];
+
+  if (full)
+    *full = 0;
+  if (top)
+    *top = -1;
+  if (using_enc)
+    *using_enc = 0;
+
+  /* Get declared type */
+  known_type = VALUE_TYPE (v);
+  CHECK_TYPEDEF (known_type);
+  /* RTTI works only or class objects */
+  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
+    return NULL;
+
+  /* If neither the declared type nor the enclosing type of the
+   * value structure has a HP ANSI C++ style virtual table,
+   * we can't do anything. */
+  if (!TYPE_HAS_VTABLE (known_type))
+    {
+      known_type = VALUE_ENCLOSING_TYPE (v);
+      CHECK_TYPEDEF (known_type);
+      if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) ||
+          !TYPE_HAS_VTABLE (known_type))
+        return NULL;           /* No RTTI, or not HP-compiled types */
+      CHECK_TYPEDEF (known_type);
+      using_enclosing = 1;
+    }
+
+  if (using_enclosing && using_enc)
+    *using_enc = 1;
+
+  /* First get the virtual table address */
+  coreptr = *(CORE_ADDR *) ((VALUE_CONTENTS_ALL (v))
+                            + VALUE_OFFSET (v)
+                            + (using_enclosing
+                               ? 0
+                               : VALUE_EMBEDDED_OFFSET (v)));
+  if (coreptr == 0)
+    /* return silently -- maybe called on gdb-generated value */
+    return NULL;
+  
+  /* Fetch the top offset of the object */
+  /* FIXME possible 32x64 problem with pointer size & arithmetic */
+  vp = value_at (builtin_type_int,
+                 coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET,
+                 VALUE_BFD_SECTION (v));
+  top_offset = value_as_long (vp);
+  if (top)
+    *top = top_offset;
+
+  /* Fetch the typeinfo pointer */
+  /* FIXME possible 32x64 problem with pointer size & arithmetic */
+  vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET,
+                 VALUE_BFD_SECTION (v));
+  /* Indirect through the typeinfo pointer and retrieve the pointer
+   * to the string name */
+  coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+  if (!coreptr)
+    error ("Retrieved null typeinfo pointer in trying to determine "
+           "run-time type");
+  /* 4 -> offset of name field */
+  vp = value_at (builtin_type_int, coreptr + 4, VALUE_BFD_SECTION (v));
+  /* FIXME possible 32x64 problem */
+
+  coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
+
+  read_memory_string (coreptr, rtti_type_name, 256);
+
+  if (strlen (rtti_type_name) == 0)
+    error ("Retrieved null type name from typeinfo");
+
+  /* search for type */
+  rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1);
+
+  if (!rtti_type)
+    error ("Could not find run-time type: invalid type name %s in typeinfo??",
+           rtti_type_name);
+  CHECK_TYPEDEF (rtti_type);
+#if 0
+  printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type),
+          TYPE_TAG_NAME (rtti_type), full ? *full : -1);
+#endif
+  /* Check whether we have the entire object */
+  if (full                     /* Non-null pointer passed */
+      &&
+      /* Either we checked on the whole object in hand and found the
+         top offset to be zero */
+      (((top_offset == 0) &&
+        using_enclosing &&
+        TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type))
+       ||
+       /* Or we checked on the embedded object and top offset was the
+          same as the embedded offset */
+       ((top_offset == VALUE_EMBEDDED_OFFSET (v)) &&
+        !using_enclosing &&
+        TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type))))
+
+    *full = 1;
+
+  return rtti_type;
+}
+
+
+static void
+init_hpacc_ops (void)
+{
+  hpacc_abi_ops.shortname = "hpaCC";
+  hpacc_abi_ops.longname = "HP aCC ABI";
+  hpacc_abi_ops.doc = "HP aCC ABI";
+  hpacc_abi_ops.is_destructor_name = hpacc_is_destructor_name;
+  hpacc_abi_ops.is_constructor_name = hpacc_is_constructor_name;
+  hpacc_abi_ops.is_vtable_name = hpacc_is_vtable_name;
+  hpacc_abi_ops.is_operator_name = hpacc_is_operator_name;
+  hpacc_abi_ops.virtual_fn_field = hpacc_virtual_fn_field;
+  hpacc_abi_ops.rtti_type = hpacc_value_rtti_type;
+}
+
+
+void
+_initialize_hpacc_abi (void)
+{
+  init_hpacc_ops ();
+
+  regcomp (&constructor_pattern,
+          "^This will never match anything, please fill it in$", REG_NOSUB);
+
+  regcomp (&destructor_pattern,
+          "^This will never match anything, please fill it in$", REG_NOSUB);
+
+  regcomp (&operator_pattern,
+          "^This will never match anything, please fill it in$", REG_NOSUB);
+
+  register_cp_abi (hpacc_abi_ops);
+}
index 4fdd84c..c0d9ec9 100644 (file)
@@ -28,6 +28,7 @@
 #include "gdb_string.h"
 #include "typeprint.h"
 #include "c-lang.h"
+#include "cp-abi.h"
 
 /* Local functions */
 
@@ -224,12 +225,9 @@ java_type_print_base (struct type *type, struct ui_file *stream, int show,
 
                  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));
+                 is_full_physname_constructor
+                    = (is_constructor_name (physname)
+                       || is_destructor_name (physname));
 
                  QUIT;
 
index 35f225c..e234790 100644 (file)
@@ -29,6 +29,7 @@
 #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. */
@@ -166,7 +167,7 @@ find_methods (struct type *t, char *name, struct symbol **sym_arr)
                  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))
+               if (is_destructor_name (phys_name) != 0)
                  continue;
 
                sym_arr[i1] = lookup_symbol (phys_name,
@@ -801,7 +802,7 @@ decode_line_1 (char **argptr, int funfirstline, struct symtab *default_symtab,
                    {
                      char *tmp;
 
-                     if (OPNAME_PREFIX_P (copy))
+                     if (is_operator_name (copy))
                        {
                          tmp = (char *) alloca (strlen (copy + 3) + 9);
                          strcpy (tmp, "operator ");
index 6cb8e96..aecf362 100644 (file)
@@ -45,6 +45,7 @@
 #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. */
@@ -288,20 +289,17 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   int is_full_physname_constructor;
 
   int is_constructor;
-  int is_destructor = DESTRUCTOR_PREFIX_P (physname);
+  int is_destructor = is_destructor_name (physname);
   /* Need a new type prefix.  */
   char *const_prefix = method->is_const ? "C" : "";
   char *volatile_prefix = method->is_volatile ? "V" : "";
   char buf[20];
   int len = (newname == NULL ? 0 : strlen (newname));
 
-  if (OPNAME_PREFIX_P (field_name))
+  if (is_operator_name (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_full_physname_constructor = is_constructor_name (physname);
 
   is_constructor =
     is_full_physname_constructor || (newname && STREQ (field_name, newname));
index a4f224d..bbde658 100644 (file)
@@ -1046,30 +1046,6 @@ struct partial_symtab
 
 #define VTBL_FNADDR_OFFSET 2
 
-/* Macro that yields non-zero value iff NAME is the prefix for C++ operator
-   names.  If you leave out the parenthesis here you will lose!  */
-#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 */
index 444c78b..7ea7098 100644 (file)
@@ -31,6 +31,7 @@
 #include "gdbcmd.h"
 #include "target.h"
 #include "language.h"
+#include "cp-abi.h"
 
 #include "gdb_string.h"
 #include <errno.h>
index 0ab0ae6..0e7e7e1 100644 (file)
@@ -31,6 +31,7 @@
 #include "language.h"
 #include "gdbcmd.h"
 #include "regcache.h"
+#include "cp-abi.h"
 
 #include <errno.h>
 #include "gdb_string.h"
@@ -3111,226 +3112,6 @@ value_struct_elt_for_reference (struct type *domain, int offset,
 }
 
 
-/* Find the real run-time type of a value using RTTI.
- * V is a pointer to the value.
- * A pointer to the struct type entry of the run-time type
- * is returneed.
- * FULL is a flag that is set only if the value V includes
- * the entire contents of an object of the RTTI type.
- * TOP is the offset to the top of the enclosing object of
- * the real run-time type.  This offset may be for the embedded
- * object, or for the enclosing object of V.
- * USING_ENC is the flag that distinguishes the two cases.
- * If it is 1, then the offset is for the enclosing object,
- * otherwise for the embedded object.
- *
- */
-
-struct type *
-value_rtti_type (value_ptr v, int *full, int *top, int *using_enc)
-{
-  struct type *known_type;
-  struct type *rtti_type;
-  CORE_ADDR coreptr;
-  value_ptr vp;
-  int using_enclosing = 0;
-  long top_offset = 0;
-  char rtti_type_name[256];
-
-  if (full)
-    *full = 0;
-  if (top)
-    *top = -1;
-  if (using_enc)
-    *using_enc = 0;
-
-  /* Get declared type */
-  known_type = VALUE_TYPE (v);
-  CHECK_TYPEDEF (known_type);
-  /* RTTI works only or class objects */
-  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
-    return NULL;
-  if (TYPE_HAS_VTABLE(known_type))
-    {
-      /* If neither the declared type nor the enclosing type of the
-       * value structure has a HP ANSI C++ style virtual table,
-       * we can't do anything. */
-      if (!TYPE_HAS_VTABLE (known_type))
-       {
-         known_type = VALUE_ENCLOSING_TYPE (v);
-         CHECK_TYPEDEF (known_type);
-         if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) ||
-             !TYPE_HAS_VTABLE (known_type))
-           return NULL;                /* No RTTI, or not HP-compiled types */
-         CHECK_TYPEDEF (known_type);
-         using_enclosing = 1;
-       }
-
-      if (using_enclosing && using_enc)
-       *using_enc = 1;
-
-      /* First get the virtual table address */
-      coreptr = *(CORE_ADDR *) ((VALUE_CONTENTS_ALL (v))
-                               + VALUE_OFFSET (v)
-                               + (using_enclosing ? 0 : VALUE_EMBEDDED_OFFSET (v)));
-      if (coreptr == 0)
-       return NULL;            /* return silently -- maybe called on gdb-generated value */
-
-      /* Fetch the top offset of the object */
-      /* FIXME possible 32x64 problem with pointer size & arithmetic */
-      vp = value_at (builtin_type_int,
-                    coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET,
-                    VALUE_BFD_SECTION (v));
-      top_offset = value_as_long (vp);
-      if (top)
-       *top = top_offset;
-
-      /* Fetch the typeinfo pointer */
-      /* FIXME possible 32x64 problem with pointer size & arithmetic */
-      vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET, VALUE_BFD_SECTION (v));
-      /* Indirect through the typeinfo pointer and retrieve the pointer
-       * to the string name */
-      coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
-      if (!coreptr)
-       error ("Retrieved null typeinfo pointer in trying to determine run-time type");
-      vp = value_at (builtin_type_int, coreptr + 4, VALUE_BFD_SECTION (v));            /* 4 -> offset of name field */
-      /* FIXME possible 32x64 problem */
-
-      coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
-
-      read_memory_string (coreptr, rtti_type_name, 256);
-
-      if (strlen (rtti_type_name) == 0)
-       error ("Retrieved null type name from typeinfo");
-
-      /* search for type */
-      rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1);
-
-      if (!rtti_type)
-       error ("Could not find run-time type: invalid type name %s in typeinfo??", rtti_type_name);
-      CHECK_TYPEDEF (rtti_type);
-#if 0
-      printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type), TYPE_TAG_NAME (rtti_type), full ? *full : -1);
-#endif
-      /* Check whether we have the entire object */
-      if (full                 /* Non-null pointer passed */
-         &&
-         /* Either we checked on the whole object in hand and found the
-            top offset to be zero */
-         (((top_offset == 0) &&
-           using_enclosing &&
-           TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type))
-          ||
-          /* Or we checked on the embedded object and top offset was the
-             same as the embedded offset */
-          ((top_offset == VALUE_EMBEDDED_OFFSET (v)) &&
-           !using_enclosing &&
-           TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type))))
-
-       *full = 1;
-    }
-  else
-    /*
-      Right now this is G++ RTTI. Plan on this changing in the
-      future as i get around to setting the vtables properly for G++
-      compiled stuff. Also, i'll be using the type info functions,
-      which are always right. Deal with it until then.
-    */
-    {
-      CORE_ADDR vtbl;
-      struct minimal_symbol *minsym;
-      struct symbol *sym;
-      char *demangled_name;
-      struct type *btype;
-      /* If the type has no vptr fieldno, try to get it filled in */
-      if (TYPE_VPTR_FIELDNO(known_type) < 0)
-       fill_in_vptr_fieldno(known_type);
-
-      /* If we still can't find one, give up */
-      if (TYPE_VPTR_FIELDNO(known_type) < 0)
-       return NULL;
-
-      /* Make sure our basetype and known type match, otherwise, cast
-        so we can get at the vtable properly.
-      */
-      btype = TYPE_VPTR_BASETYPE (known_type);
-      CHECK_TYPEDEF (btype);
-      if (btype != known_type )
-       {
-         v = value_cast (btype, v);
-         if (using_enc)
-           *using_enc=1;
-       }
-      /*
-       We can't use value_ind here, because it would want to use RTTI, and
-       we'd waste a bunch of time figuring out we already know the type.
-        Besides, we don't care about the type, just the actual pointer
-      */
-      if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
-       return NULL;
-
-      /*
-        If we are enclosed by something that isn't us, adjust the
-        address properly and set using_enclosing.
-      */
-      if (VALUE_ENCLOSING_TYPE(v) != VALUE_TYPE(v))
-       {
-         value_ptr tempval;
-         tempval=value_field(v,TYPE_VPTR_FIELDNO(known_type));
-         VALUE_ADDRESS(tempval)+=(TYPE_BASECLASS_BITPOS(known_type,TYPE_VPTR_FIELDNO(known_type))/8);
-         vtbl=value_as_pointer(tempval);
-         using_enclosing=1;
-       }
-      else
-       {
-         vtbl=value_as_pointer(value_field(v,TYPE_VPTR_FIELDNO(known_type)));
-         using_enclosing=0;
-       }
-
-      /* 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 */
-      demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
-      *(strchr(demangled_name,' '))=0;
-
-      /* Lookup the type for the name */
-      rtti_type=lookup_typename(demangled_name, (struct block *)0,1);
-
-      if (rtti_type==NULL)
-       return NULL;
-
-      if (TYPE_N_BASECLASSES(rtti_type) > 1 &&  full && (*full) != 1)
-       {
-         if (top)
-           *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
-         if (top && ((*top) >0))
-           {
-             if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
-               {
-                 if (full)
-                   *full=0;
-               }
-             else
-               {
-                 if (full)
-                   *full=1;
-               }
-           }
-       }
-      else
-       {
-         if (full)
-           *full=1;
-       }
-      if (using_enc)
-       *using_enc=using_enclosing;
-    }
-  return rtti_type;
-}
-
 /* Given a pointer value V, find the real (RTTI) type
    of the object it points to.
    Other parameters FULL, TOP, USING_ENC as with value_rtti_type()
index 064a261..50abe0e 100644 (file)
@@ -367,7 +367,6 @@ extern value_ptr value_field (value_ptr arg1, int fieldno);
 extern value_ptr value_primitive_field (value_ptr arg1, int offset,
                                        int fieldno, struct type *arg_type);
 
-extern struct type *value_rtti_type (value_ptr, int *, int *, int *);
 
 extern struct type *value_rtti_target_type (value_ptr, int *, int *, int *);
 
@@ -447,10 +446,6 @@ extern value_ptr value_x_unop (value_ptr arg1, enum exp_opcode op,
 extern value_ptr value_fn_field (value_ptr * arg1p, struct fn_field *f,
                                 int j, struct type *type, int offset);
 
-extern value_ptr value_virtual_fn_field (value_ptr * arg1p,
-                                        struct fn_field *f, int j,
-                                        struct type *type, int offset);
-
 extern int binop_user_defined_p (enum exp_opcode op,
                                 value_ptr arg1, value_ptr arg2);
 
index eec1178..8a93be9 100644 (file)
@@ -45,7 +45,6 @@ static void show_values (char *, int);
 
 static void show_convenience (char *, int);
 
-static int vb_match (struct type *, int, struct type *);
 
 /* The value-history records all the values printed
    by print commands during this session.  Each chunk
@@ -890,197 +889,6 @@ value_fn_field (value_ptr *arg1p, struct fn_field *f, int j, struct type *type,
   return v;
 }
 
-/* Return a virtual function as a value.
-   ARG1 is the object which provides the virtual function
-   table pointer.  *ARG1P is side-effected in calling this function.
-   F is the list of member functions which contains the desired virtual
-   function.
-   J is an index into F which provides the desired virtual function.
-
-   TYPE is the type in which F is located.  */
-value_ptr
-value_virtual_fn_field (value_ptr *arg1p, struct fn_field *f, int j,
-                       struct type *type, int offset)
-{
-  value_ptr arg1 = *arg1p;
-  struct type *type1 = check_typedef (VALUE_TYPE (arg1));
-
-  if (TYPE_HAS_VTABLE (type))
-    {
-      /* Deal with HP/Taligent runtime model for virtual functions */
-      value_ptr vp;
-      value_ptr argp;          /* arg1 cast to base */
-      CORE_ADDR coreptr;       /* pointer to target address */
-      int class_index;         /* which class segment pointer to use */
-      struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);  /* method type */
-
-      argp = value_cast (type, *arg1p);
-
-      if (VALUE_ADDRESS (argp) == 0)
-       error ("Address of object is null; object may not have been created.");
-
-      /* pai: FIXME -- 32x64 possible problem? */
-      /* First word (4 bytes) in object layout is the vtable pointer */
-      coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (argp));                /* pai: (temp)  */
-      /* + offset + VALUE_EMBEDDED_OFFSET (argp)); */
-
-      if (!coreptr)
-       error ("Virtual table pointer is null for object; object may not have been created.");
-
-      /* pai/1997-05-09
-       * FIXME: The code here currently handles only
-       * the non-RRBC case of the Taligent/HP runtime spec; when RRBC
-       * is introduced, the condition for the "if" below will have to
-       * be changed to be a test for the RRBC case.  */
-
-      if (1)
-       {
-         /* Non-RRBC case; the virtual function pointers are stored at fixed
-          * offsets in the virtual table. */
-
-         /* Retrieve the offset in the virtual table from the debug
-          * info.  The offset of the vfunc's entry is in words from
-          * the beginning of the vtable; but first we have to adjust
-          * by HP_ACC_VFUNC_START to account for other entries */
-
-         /* pai: FIXME: 32x64 problem here, a word may be 8 bytes in
-          * which case the multiplier should be 8 and values should be long */
-         vp = value_at (builtin_type_int,
-                        coreptr + 4 * (TYPE_FN_FIELD_VOFFSET (f, j) + HP_ACC_VFUNC_START), NULL);
-
-         coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
-         /* coreptr now contains the address of the virtual function */
-         /* (Actually, it contains the pointer to the plabel for the function. */
-       }
-      else
-       {
-         /* RRBC case; the virtual function pointers are found by double
-          * indirection through the class segment tables. */
-
-         /* Choose class segment depending on type we were passed */
-         class_index = class_index_in_primary_list (type);
-
-         /* Find class segment pointer.  These are in the vtable slots after
-          * some other entries, so adjust by HP_ACC_VFUNC_START for that. */
-         /* pai: FIXME 32x64 problem here, if words are 8 bytes long
-          * the multiplier below has to be 8 and value should be long. */
-         vp = value_at (builtin_type_int,
-                   coreptr + 4 * (HP_ACC_VFUNC_START + class_index), NULL);
-         /* Indirect once more, offset by function index */
-         /* pai: FIXME 32x64 problem here, again multiplier could be 8 and value long */
-         coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp) + 4 * TYPE_FN_FIELD_VOFFSET (f, j));
-         vp = value_at (builtin_type_int, coreptr, NULL);
-         coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
-
-         /* coreptr now contains the address of the virtual function */
-         /* (Actually, it contains the pointer to the plabel for the function.) */
-
-       }
-
-      if (!coreptr)
-       error ("Address of virtual function is null; error in virtual table?");
-
-      /* Wrap this addr in a value and return pointer */
-      vp = allocate_value (ftype);
-      VALUE_TYPE (vp) = ftype;
-      VALUE_ADDRESS (vp) = coreptr;
-
-      /* pai: (temp) do we need the value_ind stuff in value_fn_field? */
-      return vp;
-    }
-  else
-    {                          /* Not using HP/Taligent runtime conventions; so try to
-                                * use g++ conventions for virtual table */
-
-      struct type *entry_type;
-      /* First, get the virtual function table pointer.  That comes
-         with a strange type, so cast it to type `pointer to long' (which
-         should serve just fine as a function type).  Then, index into
-         the table, and convert final value to appropriate function type.  */
-      value_ptr entry, vfn, vtbl;
-      value_ptr vi = value_from_longest (builtin_type_int,
-                                   (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
-      struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
-      struct type *context;
-      if (fcontext == NULL)
-       /* We don't have an fcontext (e.g. the program was compiled with
-          g++ version 1).  Try to get the vtbl from the TYPE_VPTR_BASETYPE.
-          This won't work right for multiple inheritance, but at least we
-          should do as well as GDB 3.x did.  */
-       fcontext = TYPE_VPTR_BASETYPE (type);
-      context = lookup_pointer_type (fcontext);
-      /* Now context is a pointer to the basetype containing the vtbl.  */
-      if (TYPE_TARGET_TYPE (context) != type1)
-       {
-         value_ptr tmp = value_cast (context, value_addr (arg1));
-         VALUE_POINTED_TO_OFFSET (tmp) = 0;
-         arg1 = value_ind (tmp);
-         type1 = check_typedef (VALUE_TYPE (arg1));
-       }
-
-      context = type1;
-      /* Now context is the basetype containing the vtbl.  */
-
-      /* This type may have been defined before its virtual function table
-         was.  If so, fill in the virtual function table entry for the
-         type now.  */
-      if (TYPE_VPTR_FIELDNO (context) < 0)
-       fill_in_vptr_fieldno (context);
-
-      /* The virtual function table is now an array of structures
-         which have the form { int16 offset, delta; void *pfn; }.  */
-      vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
-                                   TYPE_VPTR_BASETYPE (context));
-
-      /* With older versions of g++, the vtbl field pointed to an array
-         of structures.  Nowadays it points directly to the structure. */
-      if (TYPE_CODE (VALUE_TYPE (vtbl)) == TYPE_CODE_PTR
-      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (vtbl))) == TYPE_CODE_ARRAY)
-       {
-         /* Handle the case where the vtbl field points to an
-            array of structures. */
-         vtbl = value_ind (vtbl);
-
-         /* Index into the virtual function table.  This is hard-coded because
-            looking up a field is not cheap, and it may be important to save
-            time, e.g. if the user has set a conditional breakpoint calling
-            a virtual function.  */
-         entry = value_subscript (vtbl, vi);
-       }
-      else
-       {
-         /* Handle the case where the vtbl field points directly to a structure. */
-         vtbl = value_add (vtbl, vi);
-         entry = value_ind (vtbl);
-       }
-
-      entry_type = check_typedef (VALUE_TYPE (entry));
-
-      if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
-       {
-         /* Move the `this' pointer according to the virtual function table. */
-         VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
-
-         if (!VALUE_LAZY (arg1))
-           {
-             VALUE_LAZY (arg1) = 1;
-             value_fetch_lazy (arg1);
-           }
-
-         vfn = value_field (entry, 2);
-       }
-      else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
-       vfn = entry;
-      else
-       error ("I'm confused:  virtual function table has bad type");
-      /* Reinstantiate the function pointer with the correct type.  */
-      VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
-
-      *arg1p = arg1;
-      return vfn;
-    }
-}
-
 /* ARG is a pointer to an object we know to be at least
    a DTYPE.  BTYPE is the most derived basetype that has
    already been searched (and need not be searched again).