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


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

Re: RFA: abstract C++ ABI dependencies



Here is the same patch, revised (hopefully) to address the problems
David and Anthony pointed out.  Test results on both old and new GCC's
are unchanged.

2001-04-24  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, p-valprint.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, p-valprint.o, symtab.o, linespec.o, typeprint.o,
	valops.o): Add dependency on $(cp_abi_h).

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.79
diff -c -r1.79 Makefile.in
*** gdb/Makefile.in	2001/04/17 21:20:48	1.79
--- gdb/Makefile.in	2001/04/25 00:17:54
***************
*** 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 \
! 	gnu-v2-abi.c hpacc-abi.c cp-abi.c
  
  LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
  
***************
*** 613,618 ****
--- 614,621 ----
  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,692 ****
  	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)
  
--- 689,696 ----
  	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 \
! 	gnu-v2-abi.o hpacc-abi.o cp-abi.o
  
  OBS = $(COMMON_OBS) $(ANNOTATE_OBS)
  
***************
*** 1222,1231 ****
  
  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)
  
  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
--- 1226,1235 ----
  
  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) $(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,1283 ****
--- 1282,1289 ----
  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,1293 ****
  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)
  
--- 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 $(cp_abi_h)
  
  delta68-nat.o: delta68-nat.c $(defs_h)
  
***************
*** 1317,1323 ****
  
  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
  
  event-loop.o: event-loop.c $(defs_h) $(top_h) $(event_loop_h) $(event_top_h)
  
--- 1323,1329 ----
  
  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 $(cp_abi_h)
  
  event-loop.o: event-loop.c $(defs_h) $(top_h) $(event_loop_h) $(event_top_h)
  
***************
*** 1446,1452 ****
  
  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)
--- 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 $(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,1459 ****
--- 1460,1468 ----
  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,1467 ****
--- 1471,1479 ----
  
  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,1557 ****
  
  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 \
--- 1563,1569 ----
  
  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 $(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,1968 ****
  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) \
! 	$(demangle_h) command.h
  
  tic80-tdep.o: tic80-tdep.c $(defs_h) $(regcache_h)
  
--- 1970,1980 ----
  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)
  
***************
*** 1981,1987 ****
  
  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
  
  # OBSOLETE ultra3-nat.o: ultra3-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(regcache_h)
  
--- 1993,1999 ----
  
  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 $(cp_abi.h)
  
  # OBSOLETE ultra3-nat.o: ultra3-nat.c $(defs_h) $(gdbcore_h) $(inferior_h) $(regcache_h)
  
***************
*** 1998,2004 ****
  	gdb_string.h
  
  valops.o: valops.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
! 	gdb_string.h $(regcache_h)
  
  valprint.o: valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
  	$(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \
--- 2010,2016 ----
  	gdb_string.h
  
  valops.o: valops.c $(defs_h) $(gdbcore_h) $(inferior_h) target.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: gdb/c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.9
diff -c -r1.9 c-typeprint.c
*** gdb/c-typeprint.c	2001/03/27 20:36:23	1.9
--- gdb/c-typeprint.c	2001/04/25 00:17:56
***************
*** 33,38 ****
--- 33,39 ----
  #include "demangle.h"
  #include "c-lang.h"
  #include "typeprint.h"
+ #include "cp-abi.h"
  
  #include "gdb_string.h"
  #include <errno.h>
***************
*** 900,910 ****
  		{
  		  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))
--- 901,910 ----
  		{
  		  char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
  		  int is_full_physname_constructor =
! 		   is_constructor_name (physname) 
! 		   || is_destructor_name (physname)
! 		   || method_name[0] == '~';
! 
  
  		  QUIT;
  		  if (TYPE_FN_FIELD_PROTECTED (f, j))
Index: gdb/c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.8
diff -c -r1.8 c-valprint.c
*** gdb/c-valprint.c	2001/03/07 02:57:08	1.8
--- gdb/c-valprint.c	2001/04/25 00:17:56
***************
*** 28,33 ****
--- 28,34 ----
  #include "valprint.h"
  #include "language.h"
  #include "c-lang.h"
+ #include "cp-abi.h"
  
  
  /* Print function pointer with inferior address ADDRESS onto stdio
***************
*** 303,308 ****
--- 304,310 ----
  	}
        /* Fall through.  */
      case TYPE_CODE_STRUCT:
+       /*FIXME: Abstract this away */
        if (vtblprint && cp_is_vtbl_ptr_type (type))
  	{
  	  /* Print the unmangled name if desired.  */
Index: gdb/cp-abi.c
===================================================================
RCS file: cp-abi.c
diff -N cp-abi.c
*** gdb/cp-abi.c	Tue May  5 13:32:27 1998
--- gdb/cp-abi.c	Tue Apr 24 17:17:56 2001
***************
*** 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;
+ }
+ 
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	Tue Apr 24 17:17:57 2001
***************
*** 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: gdb/dbxread.c
===================================================================
RCS file: /cvs/src/src/gdb/dbxread.c,v
retrieving revision 1.17
diff -c -r1.17 dbxread.c
*** gdb/dbxread.c	2001/03/27 20:36:23	1.17
--- gdb/dbxread.c	2001/04/25 00:18:00
***************
*** 57,62 ****
--- 57,63 ----
  #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,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 (is_vtable_name (tempstring))
  	  ms_type = mst_data;
        }
        section = SECT_OFF_DATA (objfile);
Index: gdb/eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.12
diff -c -r1.12 eval.c
*** gdb/eval.c	2001/03/19 23:31:41	1.12
--- gdb/eval.c	2001/04/25 00:18:02
***************
*** 30,35 ****
--- 30,36 ----
  #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: gdb/gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.19
diff -c -r1.19 gdbtypes.c
*** gdb/gdbtypes.c	2001/03/20 01:37:09	1.19
--- gdb/gdbtypes.c	2001/04/25 00:18:05
***************
*** 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.  */
***************
*** 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 (is_destructor_name (TYPE_FN_FIELD_PHYSNAME (f, j)) != 0)
  	    {
  	      *method_indexp = i;
  	      *field_indexp = j;
***************
*** 1902,1913 ****
      return -1;
  
    i = 0;
!   vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[0];
    while (vbase)
      {
        if (vbase == base)
  	break;
!       vbase = TYPE_VIRTUAL_BASE_LIST (dclass)[++i];
      }
  
    return vbase ? i : -1;
--- 1903,1914 ----
      return -1;
  
    i = 0;
!   vbase = virtual_base_list (dclass)[0];
    while (vbase)
      {
        if (vbase == base)
  	break;
!       vbase = virtual_base_list (dclass)[++i];
      }
  
    return vbase ? i : -1;
***************
*** 1936,1949 ****
  
    j = -1;
    i = 0;
!   vbase = TYPE_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];
      }
  
    return vbase ? j : -1;
--- 1937,1950 ----
  
    j = -1;
    i = 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 = virtual_base_list (dclass)[++i];
      }
  
    return vbase ? j : -1;
Index: gdb/gnu-v2-abi.c
===================================================================
RCS file: gnu-v2-abi.c
diff -N gnu-v2-abi.c
*** gdb/gnu-v2-abi.c	Tue May  5 13:32:27 1998
--- gdb/gnu-v2-abi.c	Tue Apr 24 17:18:07 2001
***************
*** 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;
+ }
+ 
+ 
+ /* 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");
+ }
Index: gdb/hpacc-abi.c
===================================================================
RCS file: hpacc-abi.c
diff -N hpacc-abi.c
*** gdb/hpacc-abi.c	Tue May  5 13:32:27 1998
--- gdb/hpacc-abi.c	Tue Apr 24 17:18:07 2001
***************
*** 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: gdb/jv-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/jv-typeprint.c,v
retrieving revision 1.4
diff -c -r1.4 jv-typeprint.c
*** gdb/jv-typeprint.c	2001/03/06 08:21:09	1.4
--- gdb/jv-typeprint.c	2001/04/25 00:18:07
***************
*** 28,33 ****
--- 28,34 ----
  #include "gdb_string.h"
  #include "typeprint.h"
  #include "c-lang.h"
+ #include "cp-abi.h"
  
  /* Local functions */
  
***************
*** 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;
  
--- 225,233 ----
  
  		  physname = TYPE_FN_FIELD_PHYSNAME (f, j);
  
! 		  is_full_physname_constructor
!                     = (is_constructor_name (physname)
!                        || is_destructor_name (physname));
  
  		  QUIT;
  
Index: gdb/linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.10
diff -c -r1.10 linespec.c
*** gdb/linespec.c	2001/03/23 00:41:01	1.10
--- gdb/linespec.c	2001/04/25 00:18:09
***************
*** 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. */
***************
*** 166,172 ****
  		  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,173 ----
  		  phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
  		
  		/* Destructor is handled by caller, dont add it to the list */
! 		if (is_destructor_name (phys_name) != 0)
  		  continue;
  
  		sym_arr[i1] = lookup_symbol (phys_name,
***************
*** 801,807 ****
  		    {
  		      char *tmp;
  
! 		      if (OPNAME_PREFIX_P (copy))
  			{
  			  tmp = (char *) alloca (strlen (copy + 3) + 9);
  			  strcpy (tmp, "operator ");
--- 802,808 ----
  		    {
  		      char *tmp;
  
! 		      if (is_operator_name (copy))
  			{
  			  tmp = (char *) alloca (strlen (copy + 3) + 9);
  			  strcpy (tmp, "operator ");
Index: gdb/symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.34
diff -c -r1.34 symtab.c
*** gdb/symtab.c	2001/04/01 19:50:50	1.34
--- gdb/symtab.c	2001/04/25 00:18:13
***************
*** 45,50 ****
--- 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. */
***************
*** 288,307 ****
    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" : "";
    char buf[20];
    int len = (newname == NULL ? 0 : strlen (newname));
  
!   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));
--- 289,305 ----
    int is_full_physname_constructor;
  
    int is_constructor;
!   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 (is_operator_name (field_name))
      return xstrdup (physname);
  
!   is_full_physname_constructor = is_constructor_name (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 -r1.20 symtab.h
*** gdb/symtab.h	2001/03/07 02:57:08	1.20
--- gdb/symtab.h	2001/04/25 00:18:15
***************
*** 1046,1075 ****
  
  #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] == '_')
- 
- 
  /* External variables and functions for the objects described above. */
  
  /* This symtab variable specifies the current file for printing source lines */
--- 1046,1051 ----
Index: gdb/typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/typeprint.c,v
retrieving revision 1.8
diff -c -r1.8 typeprint.c
*** gdb/typeprint.c	2001/03/07 02:57:08	1.8
--- gdb/typeprint.c	2001/04/25 00:18:15
***************
*** 31,36 ****
--- 31,37 ----
  #include "gdbcmd.h"
  #include "target.h"
  #include "language.h"
+ #include "cp-abi.h"
  
  #include "gdb_string.h"
  #include <errno.h>
Index: gdb/valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.34
diff -c -r1.34 valops.c
*** gdb/valops.c	2001/03/19 20:08:16	1.34
--- gdb/valops.c	2001/04/25 00:18:19
***************
*** 31,36 ****
--- 31,37 ----
  #include "language.h"
  #include "gdbcmd.h"
  #include "regcache.h"
+ #include "cp-abi.h"
  
  #include <errno.h>
  #include "gdb_string.h"
***************
*** 3110,3335 ****
    return 0;
  }
  
- 
- /* 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.
--- 3111,3116 ----
Index: gdb/value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.17
diff -c -r1.17 value.h
*** gdb/value.h	2001/03/06 08:21:18	1.17
--- gdb/value.h	2001/04/25 00:18:20
***************
*** 367,373 ****
  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 *);
  
--- 367,372 ----
***************
*** 446,455 ****
  
  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);
--- 445,450 ----
Index: gdb/values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.14
diff -c -r1.14 values.c
*** gdb/values.c	2001/03/27 20:36:24	1.14
--- gdb/values.c	2001/04/25 00:18:21
***************
*** 45,51 ****
  
  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
--- 45,50 ----
***************
*** 888,1084 ****
      }
  
    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
--- 887,892 ----


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