* 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-25 6:40 RFA: abstract C++ ABI dependencies David Taylor
@ 2001-04-26 17:23 ` Jim Blandy
0 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2001-04-26 17:23 UTC (permalink / raw)
To: David Taylor; +Cc: gdb-patches, Anthony Green
David Taylor <taylor@candd.org> writes:
> From: Jim Blandy <jimb@zwingli.cygnus.com>
> 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.
I have committed this. Thank you!
^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: RFA: abstract C++ ABI dependencies
2001-04-24 17:42 ` Jim Blandy
@ 2001-04-25 5:04 ` Anthony Green
0 siblings, 0 replies; 14+ messages in thread
From: Anthony Green @ 2001-04-25 5:04 UTC (permalink / raw)
To: Jim Blandy, David Taylor; +Cc: gdb-patches
Jim wrote:
> 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.
Looks great to me.
Thanks,
AG
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
2001-04-25 0:07 ` Daniel Berlin
@ 2001-04-25 0:24 ` Eli Zaretskii
0 siblings, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2001-04-25 0:24 UTC (permalink / raw)
To: Daniel Berlin; +Cc: Jim Blandy, David Taylor, gdb-patches, Anthony Green
On 25 Apr 2001, Daniel Berlin wrote:
> and IMHO, saying
>
> #include <cp-abi.h> /* Include C++ ABI stuff */
>
> is like saying
>
> i++; /* Increment i */
That's not what I suggested to say in the comment.
> > In other words, if there were no reason to have an explanation, why would
> > Jim feel he should provide one on the ChangeLog?
>
> Because nobody else realized those macros were spread out across 2 (or
> was it 3) header files, and had nothing to do with what the header
> file purported to be, except me, because nobody had touched the hard
> core C++ ABI stuff in at least year or so, except me?
Just tell the above in the comment, or put there what Jim suggested to
put in the ChangeLog:
#include "cp-abi.h". These files all use functions now declared there.
> 1. A message explaining why it was done, on the mailing list (done at
> some point in the past), so others understand.
> 2. A short reminder in the ChangeLog, saying why it was done.
I think the comments in the code should explain anything that isn't
obvious from reading the code itself. Mail messages and ChangeLog
entries are not the right place for such information, IMHO.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
2001-04-24 23:52 ` Eli Zaretskii
@ 2001-04-25 0:07 ` Daniel Berlin
2001-04-25 0:24 ` Eli Zaretskii
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Berlin @ 2001-04-25 0:07 UTC (permalink / raw)
To: Eli Zaretskii
Cc: Daniel Berlin, Jim Blandy, David Taylor, gdb-patches, Anthony Green
Eli Zaretskii <eliz@is.elta.co.il> writes:
> On 25 Apr 2001, Daniel Berlin wrote:
>
> > Eli Zaretskii <eliz@is.elta.co.il> writes:
> >
> > > On 24 Apr 2001, Jim Blandy wrote:
> > >
> > > > > * 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.
> > > >
> > > > Because they use functions which used to be declared elsewhere, but
> > > > are now declared in cp-abi.h. I've clarified the ChangeLog entry.
> > >
> > > Isn't it better to put such explanations in the files which include
> > > cp-abi.h, rather than in a ChangeLog?
> >
> > Errr, i don't see any other comments on header includes.
>
> I see _lots_ of them. Two examples (you can see them all with
> "grep '#include..*/\*' *.c"):
>
> utils.c:#include "inferior.h" /* for signed_pointer_to_address */
> linux-thread.c:#include "gdb_wait.h" /* for WUNTRACED and __WCLONE flags */
>
> But even if these comments were not present, that doesn't mean they
> shouldn't be there.
>
> > Why would you list the reasons for including a given header?
>
> Because people who read the code afterwards might ask themselves why
> was that header included, if the name of the header doesn't make that
> obvious.
In this case, the header filename is pretty obvious, IMHO.
cp-abi.h includes C++ ABI related definitions.
>
> This seems especially important since lately some of the maintainers are
> actively terying to remove unneeded headers in order to minimize
> dependencies and slash the build time.
>
> > If you want to know what's in the header, and you can't tell from the
> > top of the header itself, or the filename of the header, well, then,
> > there's probably something else wrong.
>
> Maybe something _is_ wrong. If so, the code should be reworked
> accordingly.
This was done in this case. This is the result of the rework.
>
> However, if, after all the deliberations, it is decided to leave the
> header inclusion, and that header's name does not explain why it is
> needed, like in the case in point (see David's question), then I think
> the explanation should be in the code, not in the ChangeLog.
This is not the case in what you are referring to.
The reality is that some things that didn't belong in other headers
and files, related to C++ ABI stuff, were moved into new headers and
files, and abstracted so that the old function *implementations* and
macros no longer existed or were no longer "public" (like the macros
related specifically to virtual function start offsets in the HP C++
ABI implementation, which are now in hpacc-abi.h).
This necessitated the inclusion of that new header. In other words,
this is the case of comments should have been there before about
including gdbtypes.h and symtab.h for some C++ ABI stuff as well, and
we should now be able to remove them.
Since there are no comments there, there is nothing to remove.
and IMHO, saying
#include <cp-abi.h> /* Include C++ ABI stuff */
is like saying
i++; /* Increment i */
If it's not immediately obvious what cp-abi.h does, the first line of
the file will give it to you.
So, basically, i'm saying that before, we should have had
#include <symtab.h> /* ... Get some C++ ABI related junk */
#include <gdbtypes.h> /* ... Get some other C++ ABI related junk */
#include <value.h> /* ... Get yet some more C++ ABI related junk */
or something, and been able to just replace all three lines with
#include <cp-abi.h>
with no comment.
>
> In other words, if there were no reason to have an explanation, why would
> Jim feel he should provide one on the ChangeLog?
Because nobody else realized those macros were spread out across 2 (or
was it 3) header files, and had nothing to do with what the header
file purported to be, except me, because nobody had touched the hard
core C++ ABI stuff in at least year or so, except me?
And the functions were removed from the old headers, since they didn't
really fit in with what the rest of the functions were doing, and made
much more sense in the context of other functions (specifically,
functions that are used to implement support for a given C++ ABI).
Since this requires a lot of domain specific gdb knowledge to realize
this, in order for others to understand why it's done, you basically
need two things:
1. A message explaining why it was done, on the mailing list (done at
some point in the past), so others understand.
2. A short reminder in the ChangeLog, saying why it was done.
Jim did #2, I think I did #1, IIRC.
--
"It's a small world, but I wouldn't want to have to paint it.
"-Steven Wright
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
2001-04-24 23:35 ` Daniel Berlin
@ 2001-04-24 23:52 ` Eli Zaretskii
2001-04-25 0:07 ` Daniel Berlin
0 siblings, 1 reply; 14+ messages in thread
From: Eli Zaretskii @ 2001-04-24 23:52 UTC (permalink / raw)
To: Daniel Berlin; +Cc: Jim Blandy, David Taylor, gdb-patches, Anthony Green
On 25 Apr 2001, Daniel Berlin wrote:
> Eli Zaretskii <eliz@is.elta.co.il> writes:
>
> > On 24 Apr 2001, Jim Blandy wrote:
> >
> > > > * 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.
> > >
> > > Because they use functions which used to be declared elsewhere, but
> > > are now declared in cp-abi.h. I've clarified the ChangeLog entry.
> >
> > Isn't it better to put such explanations in the files which include
> > cp-abi.h, rather than in a ChangeLog?
>
> Errr, i don't see any other comments on header includes.
I see _lots_ of them. Two examples (you can see them all with
"grep '#include..*/\*' *.c"):
utils.c:#include "inferior.h" /* for signed_pointer_to_address */
linux-thread.c:#include "gdb_wait.h" /* for WUNTRACED and __WCLONE flags */
But even if these comments were not present, that doesn't mean they
shouldn't be there.
> Why would you list the reasons for including a given header?
Because people who read the code afterwards might ask themselves why
was that header included, if the name of the header doesn't make that
obvious.
This seems especially important since lately some of the maintainers are
actively terying to remove unneeded headers in order to minimize
dependencies and slash the build time.
> If you want to know what's in the header, and you can't tell from the
> top of the header itself, or the filename of the header, well, then,
> there's probably something else wrong.
Maybe something _is_ wrong. If so, the code should be reworked
accordingly.
However, if, after all the deliberations, it is decided to leave the
header inclusion, and that header's name does not explain why it is
needed, like in the case in point (see David's question), then I think
the explanation should be in the code, not in the ChangeLog.
In other words, if there were no reason to have an explanation, why would
Jim feel he should provide one on the ChangeLog?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
2001-04-24 23:21 ` Eli Zaretskii
@ 2001-04-24 23:35 ` Daniel Berlin
2001-04-24 23:52 ` Eli Zaretskii
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Berlin @ 2001-04-24 23:35 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Jim Blandy, David Taylor, gdb-patches, Anthony Green
Eli Zaretskii <eliz@is.elta.co.il> writes:
> On 24 Apr 2001, Jim Blandy wrote:
>
> > > * 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.
> >
> > Because they use functions which used to be declared elsewhere, but
> > are now declared in cp-abi.h. I've clarified the ChangeLog entry.
>
> Isn't it better to put such explanations in the files which include
> cp-abi.h, rather than in a ChangeLog?
>
> ChangeLog entries are not supposed to explain the reasons for the changes,
> just the changes themselves; see standards.texi. Beyond the Word of The
> Law in standards.texi, I find it much easier to read comments right where
> I might ask myself ``why the heck did they include this header?'' than to
> grep through lots of ChangeLog entries.
Errr, i don't see any other comments on header includes.
It doesn't make sense to me, on so many levels.
Why would you list the reasons for including a given header?
If you want to know what's in the header, and you can't tell from the
top of the header itself, or the filename of the header, well, then,
there's probably something else wrong.
If, for example, I have to tell you that it included symtab.h because
that's where some of the C++ ABI related macros it uses are
located, and it doesn't seem to be clear to the user of the header
file, then maybe they shouldn't be in symtab.h. Maybe they should be
in, for example, cp-abi.h.
Especially when symtab.h might say at the top "Symbol table stuff".
You wouldn't really expect C++ ABI macros related to all kinds of
stuff, but strangely, not at all to symbol tables, to be in there,
would you?
If we have to document something like this in each file that includes
it, it means something was counter-intuitive. It means there should
have been comments before (or none, ever), and we should be able to
remove them now.
--
"I busted a mirror and got seven years bad luck, but my lawyer
thinks he can get me five.
"-Steven Wright
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
2001-04-24 15:33 ` Jim Blandy
2001-04-24 16:23 ` Daniel Berlin
@ 2001-04-24 23:21 ` Eli Zaretskii
2001-04-24 23:35 ` Daniel Berlin
1 sibling, 1 reply; 14+ messages in thread
From: Eli Zaretskii @ 2001-04-24 23:21 UTC (permalink / raw)
To: Jim Blandy; +Cc: David Taylor, gdb-patches, Anthony Green
On 24 Apr 2001, Jim Blandy wrote:
> > * 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.
>
> Because they use functions which used to be declared elsewhere, but
> are now declared in cp-abi.h. I've clarified the ChangeLog entry.
Isn't it better to put such explanations in the files which include
cp-abi.h, rather than in a ChangeLog?
ChangeLog entries are not supposed to explain the reasons for the changes,
just the changes themselves; see standards.texi. Beyond the Word of The
Law in standards.texi, I find it much easier to read comments right where
I might ask myself ``why the heck did they include this header?'' than to
grep through lots of ChangeLog entries.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
2001-04-24 16:23 ` Daniel Berlin
@ 2001-04-24 18:27 ` Jim Blandy
0 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2001-04-24 18:27 UTC (permalink / raw)
To: Daniel Berlin; +Cc: Jim Blandy, David Taylor, gdb-patches, Anthony Green
Daniel Berlin <dan@www.cgsoftware.com> writes:
> > > *NONE* of these files initialize the rtti_type field within the
> > > cp_abi_ops structure; they all let it default to 0.
>
> This is normal, actually.
> gnuv-2's rtti type is broken
> Until the HP stuff is verified to work, it avoids problems.
Right, but I'm trying to post a patch which changes the behavior of
GDB as little as possible. Further changes, even good ones, should be
posted as separate patches.
^ 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
2001-04-25 5:04 ` Anthony Green
1 sibling, 1 reply; 14+ messages in thread
From: Jim Blandy @ 2001-04-24 17:42 UTC (permalink / raw)
To: David Taylor, Anthony Green; +Cc: gdb-patches
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"
\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 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;
+ }
+
+ \f
+ /* Return a virtual function as a value.
+ ARG1 is the object which provides the virtual function
+ table pointer. *ARG1P is side-effected in calling this function.
+ F is the list of member functions which contains the desired virtual
+ function.
+ J is an index into F which provides the desired virtual function.
+
+ TYPE is the type in which F is located. */
+ static value_ptr
+ gnuv2_virtual_fn_field (value_ptr * arg1p, struct fn_field * f, int j,
+ struct type * type, int offset)
+ {
+ value_ptr arg1 = *arg1p;
+ struct type *type1 = check_typedef (VALUE_TYPE (arg1));
+
+
+ struct type *entry_type;
+ /* First, get the virtual function table pointer. That comes
+ with a strange type, so cast it to type `pointer to long' (which
+ should serve just fine as a function type). Then, index into
+ the table, and convert final value to appropriate function type. */
+ value_ptr entry, vfn, vtbl;
+ value_ptr vi = value_from_longest (builtin_type_int,
+ (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
+ struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
+ struct type *context;
+ if (fcontext == NULL)
+ /* We don't have an fcontext (e.g. the program was compiled with
+ g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE.
+ This won't work right for multiple inheritance, but at least we
+ should do as well as GDB 3.x did. */
+ fcontext = TYPE_VPTR_BASETYPE (type);
+ context = lookup_pointer_type (fcontext);
+ /* Now context is a pointer to the basetype containing the vtbl. */
+ if (TYPE_TARGET_TYPE (context) != type1)
+ {
+ value_ptr tmp = value_cast (context, value_addr (arg1));
+ VALUE_POINTED_TO_OFFSET (tmp) = 0;
+ arg1 = value_ind (tmp);
+ type1 = check_typedef (VALUE_TYPE (arg1));
+ }
+
+ context = type1;
+ /* Now context is the basetype containing the vtbl. */
+
+ /* This type may have been defined before its virtual function table
+ was. If so, fill in the virtual function table entry for the
+ type now. */
+ if (TYPE_VPTR_FIELDNO (context) < 0)
+ fill_in_vptr_fieldno (context);
+
+ /* The virtual function table is now an array of structures
+ which have the form { int16 offset, delta; void *pfn; }. */
+ vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
+ TYPE_VPTR_BASETYPE (context));
+
+ /* With older versions of g++, the vtbl field pointed to an array
+ of structures. Nowadays it points directly to the structure. */
+ if (TYPE_CODE (VALUE_TYPE (vtbl)) == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (vtbl))) == TYPE_CODE_ARRAY)
+ {
+ /* Handle the case where the vtbl field points to an
+ array of structures. */
+ vtbl = value_ind (vtbl);
+
+ /* Index into the virtual function table. This is hard-coded because
+ looking up a field is not cheap, and it may be important to save
+ time, e.g. if the user has set a conditional breakpoint calling
+ a virtual function. */
+ entry = value_subscript (vtbl, vi);
+ }
+ else
+ {
+ /* Handle the case where the vtbl field points directly to a structure. */
+ vtbl = value_add (vtbl, vi);
+ entry = value_ind (vtbl);
+ }
+
+ entry_type = check_typedef (VALUE_TYPE (entry));
+
+ if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
+ {
+ /* Move the `this' pointer according to the virtual function table. */
+ VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
+
+ if (!VALUE_LAZY (arg1))
+ {
+ VALUE_LAZY (arg1) = 1;
+ value_fetch_lazy (arg1);
+ }
+
+ vfn = value_field (entry, 2);
+ }
+ else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
+ vfn = entry;
+ else
+ error ("I'm confused: virtual function table has bad type");
+ /* Reinstantiate the function pointer with the correct type. */
+ VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
+
+ *arg1p = arg1;
+ return vfn;
+ }
+
+
+ struct type *
+ gnuv2_value_rtti_type (value_ptr v, int *full, int *top, int *using_enc)
+ {
+ struct type *known_type;
+ struct type *rtti_type;
+ CORE_ADDR coreptr;
+ value_ptr vp;
+ int using_enclosing = 0;
+ long top_offset = 0;
+ char rtti_type_name[256];
+ CORE_ADDR vtbl;
+ struct minimal_symbol *minsym;
+ struct symbol *sym;
+ char *demangled_name;
+ struct type *btype;
+
+ if (full)
+ *full = 0;
+ if (top)
+ *top = -1;
+ if (using_enc)
+ *using_enc = 0;
+
+ /* Get declared type */
+ known_type = VALUE_TYPE (v);
+ CHECK_TYPEDEF (known_type);
+ /* RTTI works only or class objects */
+ if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
+ return NULL;
+
+ /* Plan on this changing in the future as i get around to setting
+ the vtables properly for G++ compiled stuff. Also, I'll be using
+ the type info functions, which are always right. Deal with it
+ until then. */
+
+ /* If the type has no vptr fieldno, try to get it filled in */
+ if (TYPE_VPTR_FIELDNO(known_type) < 0)
+ fill_in_vptr_fieldno(known_type);
+
+ /* If we still can't find one, give up */
+ if (TYPE_VPTR_FIELDNO(known_type) < 0)
+ return NULL;
+
+ /* Make sure our basetype and known type match, otherwise, cast
+ so we can get at the vtable properly.
+ */
+ btype = TYPE_VPTR_BASETYPE (known_type);
+ CHECK_TYPEDEF (btype);
+ if (btype != known_type )
+ {
+ v = value_cast (btype, v);
+ if (using_enc)
+ *using_enc=1;
+ }
+ /*
+ We can't use value_ind here, because it would want to use RTTI, and
+ we'd waste a bunch of time figuring out we already know the type.
+ Besides, we don't care about the type, just the actual pointer
+ */
+ if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
+ return NULL;
+
+ /*
+ If we are enclosed by something that isn't us, adjust the
+ address properly and set using_enclosing.
+ */
+ if (VALUE_ENCLOSING_TYPE(v) != VALUE_TYPE(v))
+ {
+ value_ptr tempval;
+ int bitpos = TYPE_BASECLASS_BITPOS (known_type,
+ TYPE_VPTR_FIELDNO (known_type));
+ tempval=value_field (v, TYPE_VPTR_FIELDNO(known_type));
+ VALUE_ADDRESS(tempval) += bitpos / 8;
+ vtbl=value_as_pointer (tempval);
+ using_enclosing=1;
+ }
+ else
+ {
+ vtbl=value_as_pointer(value_field(v,TYPE_VPTR_FIELDNO(known_type)));
+ using_enclosing=0;
+ }
+
+ /* Try to find a symbol that is the vtable */
+ minsym=lookup_minimal_symbol_by_pc(vtbl);
+ if (minsym==NULL
+ || (demangled_name=SYMBOL_NAME(minsym))==NULL
+ || !is_vtable_name (demangled_name))
+ return NULL;
+
+ /* If we just skip the prefix, we get screwed by namespaces */
+ demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
+ *(strchr(demangled_name,' '))=0;
+
+ /* Lookup the type for the name */
+ rtti_type=lookup_typename(demangled_name, (struct block *)0,1);
+
+ if (rtti_type==NULL)
+ return NULL;
+
+ if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1)
+ {
+ if (top)
+ *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
+ if (top && ((*top) >0))
+ {
+ if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
+ {
+ if (full)
+ *full=0;
+ }
+ else
+ {
+ if (full)
+ *full=1;
+ }
+ }
+ }
+ else
+ {
+ if (full)
+ *full=1;
+ }
+ if (using_enc)
+ *using_enc=using_enclosing;
+
+ return rtti_type;
+ }
+
+
+ static void
+ init_gnuv2_ops (void)
+ {
+ gnu_v2_abi_ops.shortname = "gnu-v2";
+ gnu_v2_abi_ops.longname = "GNU G++ Version 2 ABI";
+ gnu_v2_abi_ops.doc = "G++ Version 2 ABI";
+ gnu_v2_abi_ops.is_destructor_name = gnuv2_is_destructor_name;
+ gnu_v2_abi_ops.is_constructor_name = gnuv2_is_constructor_name;
+ gnu_v2_abi_ops.is_vtable_name = gnuv2_is_vtable_name;
+ gnu_v2_abi_ops.is_operator_name = gnuv2_is_operator_name;
+ gnu_v2_abi_ops.virtual_fn_field = gnuv2_virtual_fn_field;
+ gnu_v2_abi_ops.rtti_type = gnuv2_value_rtti_type;
+ }
+
+ void
+ _initialize_gnu_v2_abi (void)
+ {
+ init_gnuv2_ops ();
+ register_cp_abi (gnu_v2_abi_ops);
+ switch_to_cp_abi ("gnu-v2");
+ }
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] == '_')
- \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/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 ----
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: abstract C++ ABI dependencies
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
1 sibling, 1 reply; 14+ messages in thread
From: Daniel Berlin @ 2001-04-24 16:23 UTC (permalink / raw)
To: Jim Blandy; +Cc: David Taylor, gdb-patches, Anthony Green
On 24 Apr 2001, Jim Blandy wrote:
>
> Thanks for reading so carefully (and promptly!). I thought I'd been
> careful, but clearly there's a bunch of stuff botched. I'll post a
> revision in a bit.
>
> I've answered your questions below.
>
> David Taylor <taylor@candd.org> writes:
> > 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?
> >
> > Your definition of cp_abi_h is simply cp-abi.h -- however, cp-abi.h
> > includes other header files -- OOPS!
>
> I share your preference. In the next rev of this patch, cp-abi.h will
> no longer #include any other files.
>
> > 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.
This is normal, actually.
gnuv-2's rtti type is broken
Until the HP stuff is verified to work, it avoids problems.
the v3 abi stuff defines an rtti_type that works okay.
> >
> > * 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.
>
> Because they use functions which used to be declared elsewhere, but
> are now declared in cp-abi.h. I've clarified the ChangeLog entry.
>
^ 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 16:23 ` Daniel Berlin
2001-04-24 23:21 ` Eli Zaretskii
2001-04-24 17:42 ` Jim Blandy
1 sibling, 2 replies; 14+ messages in thread
From: Jim Blandy @ 2001-04-24 15:33 UTC (permalink / raw)
To: David Taylor; +Cc: gdb-patches, Anthony Green
Thanks for reading so carefully (and promptly!). I thought I'd been
careful, but clearly there's a bunch of stuff botched. I'll post a
revision in a bit.
I've answered your questions below.
David Taylor <taylor@candd.org> writes:
> 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?
>
> Your definition of cp_abi_h is simply cp-abi.h -- however, cp-abi.h
> includes other header files -- OOPS!
I share your preference. In the next rev of this patch, cp-abi.h will
no longer #include any other files.
> 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.
Because they use functions which used to be declared elsewhere, but
are now declared in cp-abi.h. I've clarified the ChangeLog entry.
^ 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