Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: RFA: abstract C++ ABI dependencies
@ 2001-04-25  6:40 David Taylor
  2001-04-26 17:23 ` Jim Blandy
  0 siblings, 1 reply; 14+ messages in thread
From: David Taylor @ 2001-04-25  6:40 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches, Anthony Green

    From: Jim Blandy <jimb@zwingli.cygnus.com>
    Date: 24 Apr 2001 19:42:19 -0500


    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.

For my part, this is approved.

Thanks.

    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).


^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
@ 2001-04-24 12:27 David Taylor
  2001-04-24 15:33 ` Jim Blandy
  2001-04-24 17:42 ` Jim Blandy
  0 siblings, 2 replies; 14+ messages in thread
From: David Taylor @ 2001-04-24 12:27 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches, Anthony Green

    From: Jim Blandy <jimb@zwingli.cygnus.com>
    Date: Tue, 24 Apr 2001 12:30:19 -0500 (EST)

    I'd like approval for these changes from the following people:

    - David Taylor (c-typeprint.c, c-valprint.c, eval.c, gdbtypes.c,
      typeprint.c, valops.c, value.h, values.c, valops.c)

    - Anthony Green (jv-typeprint.c)

cp-abi.h -- includes defs.h and value.h; this is contrary to the value
of the macro definition of cp_abi_h in Makefile.in.

While I dislike having include files include other include files and I
don't wish to reopen that debate, I must ask -- why does cp-abi.h
include defs.h?

Every .c file linked in to gdb includes defs.h already (usually as
it's first include) or includes none of the gdb include files (e.g.,
gnu-regex.c).

So, why does cp-abi.h need to include defs.h explicitly?  Any *.c that
needs it should already be including it.

    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.

*NONE* of these files initialize the rtti_type field within the
cp_abi_ops structure; they all let it default to 0.

	    * 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".

For c-valprint.c, eval.c, typeprint.c, and valops.c, it is unclear to
me why you are including cp-abi.h.

	    * 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.

Your definition of cp_abi_h is simply cp-abi.h -- however, cp-abi.h
includes other header files -- OOPS!

	    (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).


^ permalink raw reply	[flat|nested] 14+ messages in thread
* RFA: abstract C++ ABI dependencies
@ 2001-04-24 10:30 Jim Blandy
  0 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2001-04-24 10:30 UTC (permalink / raw)
  To: gdb-patches, Anthony Green

I'd like approval for these changes from the following people:

- David Taylor (c-typeprint.c, c-valprint.c, eval.c, gdbtypes.c,
  typeprint.c, valops.c, value.h, values.c, valops.c)
- Anthony Green (jv-typeprint.c)

Daniel Berlin, the C++ maintainer, has already approved these changes
(as far as they go).

Running against an older GCC (egcs-2.91.66), these changes have no
real effect on the test suite results.  However, they provide some
infrastructure essential to supporting multiple C++ and Java ABI's in
a clean way.

Before:

		=== gdb Summary ===

# of expected passes		6677
# of unexpected failures	17
# of unexpected successes	27
# of expected failures		161
# of untested testcases		19
# of unsupported tests		1
/umbra/jimb/cygnus/pentium3/sourceware/gdb/main/native/build/gdb/testsuite/../../gdb/gdb version  5.0 -nx

After:

		=== gdb Summary ===

# of expected passes		6677
# of unexpected failures	17
# of unexpected successes	33
# of expected failures		166
# of untested testcases		19
# of unsupported tests		1
/umbra/jimb/cygnus/pentium3/sourceware/gdb/main/native/build/gdb/testsuite/../../gdb/gdb version  5.0 -nx

When run against a compiler built recently from the GCC 3 branch,
which uses the V3 C++ ABI, these patches have no effect on the test
results whatsoever.


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, symtab.c, typeprint.c, valops.c:
	#include "cp-abi.h".

	* 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).

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/24 16:42:52
***************
*** 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 $(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/24 16:42:53
***************
*** 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/24 16:42:53
***************
*** 28,33 ****
--- 28,34 ----
  #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,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 09:42:53 2001
***************
*** 0 ****
--- 1,77 ----
+ #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 09:42:53 2001
***************
*** 0 ****
--- 1,133 ----
+ /* 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
+ #include "defs.h"
+ #include "value.h"
+ 
+ /* 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/24 16:42:55
***************
*** 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/24 16:42:56
***************
*** 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/24 16:42:57
***************
*** 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 09:42:57 2001
***************
*** 0 ****
--- 1,199 ----
+ /* Abstraction of GNU v2 abi.
+    Contributed by Daniel Berlin <dberlin@redhat.com>
+    Copyright 2001 Free Software Foundation, Inc.
+ 
+    This file is part of GDB.
+ 
+    This program is free software; you can redistribute it and/or
+    modify
+    it under the terms of the GNU General Public License as published
+    by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+ 
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include "defs.h"
+ #include "cp-abi.h"
+ #include "gdb_regex.h"
+ #include "gdb_string.h"
+ #include "symtab.h"
+ #include "gdbtypes.h"
+ #include "value.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;
+ }
+ 
+ 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;
+ }
+ 
+ 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 09:42:58 2001
***************
*** 0 ****
--- 1,203 ----
+ /* 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 "cp-abi.h"
+ #include "gdb_regex.h"
+ #include "gdb_string.h"
+ #include "gdbtypes.h"
+ #include "value.h"
+ #include "gdbcore.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 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;
+ }
+ 
+ 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/24 16:42:58
***************
*** 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,231 ----
  
  		  physname = TYPE_FN_FIELD_PHYSNAME (f, j);
  
! 		  is_full_physname_constructor = is_constructor_name (physname) != 0 || is_destructor_name (physname) != 0;
  
  		  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/24 16:42:58
***************
*** 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/24 16:43:00
***************
*** 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/24 16:43:01
***************
*** 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] == '_')
- \f
- 
  /* 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/24 16:43:02
***************
*** 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/24 16:43:04
***************
*** 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/24 16:43:04
***************
*** 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/24 16:43:05
***************
*** 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 ----


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2001-04-26 17:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-25  6:40 RFA: abstract C++ ABI dependencies David Taylor
2001-04-26 17:23 ` Jim Blandy
  -- strict thread matches above, loose matches on Subject: below --
2001-04-24 12:27 David Taylor
2001-04-24 15:33 ` Jim Blandy
2001-04-24 16:23   ` Daniel Berlin
2001-04-24 18:27     ` Jim Blandy
2001-04-24 23:21   ` Eli Zaretskii
2001-04-24 23:35     ` Daniel Berlin
2001-04-24 23:52       ` Eli Zaretskii
2001-04-25  0:07         ` Daniel Berlin
2001-04-25  0:24           ` Eli Zaretskii
2001-04-24 17:42 ` Jim Blandy
2001-04-25  5:04   ` Anthony Green
2001-04-24 10:30 Jim Blandy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox