[PATCH] Start abstraction of C++ abi's

Daniel Berlin
2001-02-18T12:51:00Z

[-- Attachment #1: Type: text/plain, Size: 1376 bytes --]

This patch, plus the attached files, start the abstraction of the C++
ABI's.

I've started by replacing the simple things, and will incrementally
replace the more complex things, and the things that require real code
changes, as time goes on.

The cp-abi directory, and it's files, are attached in a gzipped tar file.

This fixes some problems with the new-abi already, like not being able
to set breakpoints on destructors (if you try it, you'll get:

(gdb) b foo::~foo
the class `foo' does not have destructor defined
Hint: try 'foo::~foo<TAB> or 'foo::~foo<ESC-?>
(Note leading single quote.)
(gdb)
)

I haven't added the method for detecting which C++ abi we are using,
so it simply defaults to the gnu v2 abi.

However, I have verified the gnu v3 abi parts work fine too (that's how i
know it fixed breakpoints on destructors).

This stuff touches a lot of files, but it's only removing code, or
changing a macro call to a function call (IE VTBL_PREFIX_P ->
vtbl_prefix_p, DESTRUCTOR_PREFIX_P -> destructor_prefix_p).

Who exactly do i need approval from to check this stuff in?

As I said, this is an incremental process. This is the minimum number
of changes necessary to start abstracting the simple things. There is
no way to make this patch smaller, without breaking gdb.

I need someone to look at the configure.in change, i'm not positive I
did it right.

--Dan

[-- Attachment #2: cp-abi.tar.gz --]
[-- Type: application/x-gzip, Size: 2023 bytes --]

[-- Attachment #3: cpabidiffs --]
[-- Type: text/x-c, Size: 15584 bytes --]

Index: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.4
diff -c -3 -p -r1.4 c-typeprint.c
*** c-typeprint.c 2000/12/15 01:01:46 1.4
--- c-typeprint.c 2001/02/18 20:42:41
***************
*** 38,43 ****
--- 38,44 ----
#include "gdb_string.h"
#include <errno.h>
#include <ctype.h>
+ #include "cp-abi.h"

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

QUIT;
if (TYPE_FN_FIELD_PROTECTED (f, j))
--- 903,912 ----
{
char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
int is_full_physname_constructor =
! constructor_prefix_p (physname)
! || destructor_prefix_p (physname)
! || STREQN (method_name, "~", 1);
!

QUIT;
if (TYPE_FN_FIELD_PROTECTED (f, j))
*************** c_type_print_base (struct type *type, st
*** 963,969 ****

demangled_name =
cplus_demangle (mangled_name,
! DMGL_ANSI | DMGL_PARAMS);
if (demangled_name == NULL)
{
/* in some cases (for instance with the HP demangling),
--- 963,969 ----

demangled_name =
cplus_demangle (mangled_name,
! DMGL_ANSI | DMGL_PARAMS | DMGL_VERBOSE);
if (demangled_name == NULL)
{
/* in some cases (for instance with the HP demangling),
Index: dbxread.c
===================================================================
RCS file: /cvs/src/src/gdb/dbxread.c,v
retrieving revision 1.12
diff -c -3 -p -r1.12 dbxread.c
*** dbxread.c 2001/01/19 14:53:44 1.12
--- dbxread.c 2001/02/18 20:42:42
***************
*** 58,63 ****
--- 58,64 ----
#include "demangle.h"
#include "language.h" /* Needed inside partial-stab.h */
#include "complaints.h"
+ #include "cp-abi.h"

#include "aout/aout64.h"
#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */
*************** record_minimal_symbol (char *name, CORE_
*** 514,520 ****
char *tempstring = name;
if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
++tempstring;
! if (VTBL_PREFIX_P ((tempstring)))
ms_type = mst_data;
}
section = SECT_OFF_DATA (objfile);
--- 515,521 ----
char *tempstring = name;
if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
++tempstring;
! if (vtbl_prefix_p ((tempstring)))
ms_type = mst_data;
}
section = SECT_OFF_DATA (objfile);
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.16
diff -c -3 -p -r1.16 gdbtypes.c
*** gdbtypes.c 2000/12/15 01:01:47 1.16
--- gdbtypes.c 2001/02/18 20:42:42
***************
*** 33,39 ****
--- 33,41 ----
#include "demangle.h"
#include "complaints.h"
#include "gdbcmd.h"
+ #include "gdb_regex.h"
#include "wrapper.h"
+ #include "cp-abi.h"

/* These variables point to the objects
representing the predefined C data types. */
*************** int
*** 1018,1024 ****
get_destructor_fn_field (struct type *t, int *method_indexp, int *field_indexp)
{
int i;
-
for (i = 0; i < TYPE_NFN_FIELDS (t); i++)
{
int j;
--- 1020,1025 ----
*************** get_destructor_fn_field (struct type *t,
*** 1026,1032 ****

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;
--- 1027,1033 ----

for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
{
! if (destructor_prefix_p (TYPE_FN_FIELD_PHYSNAME (f, j)) != 0)
{
*method_indexp = i;
*field_indexp = j;
Index: jv-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/jv-typeprint.c,v
retrieving revision 1.3
diff -c -3 -p -r1.3 jv-typeprint.c
*** jv-typeprint.c 2000/12/15 01:01:47 1.3
--- jv-typeprint.c 2001/02/18 20:42:42
***************
*** 28,34 ****
#include "gdb_string.h"
#include "typeprint.h"
#include "c-lang.h"
!
/* Local functions */

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

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

physname = TYPE_FN_FIELD_PHYSNAME (f, j);

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

QUIT;

--- 224,230 ----

physname = TYPE_FN_FIELD_PHYSNAME (f, j);

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

QUIT;

Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.4
diff -c -3 -p -r1.4 linespec.c
*** linespec.c 2000/12/15 01:01:48 1.4
--- linespec.c 2001/02/18 20:42:42
***************
*** 28,34 ****
#include "demangle.h"
#include "value.h"
#include "completer.h"
!
/* Prototype for one function in parser-defs.h,
instead of including that entire file. */

--- 28,35 ----
#include "demangle.h"
#include "value.h"
#include "completer.h"
! #include "gdb_regex.h"
! #include "cp-abi.h"
/* Prototype for one function in parser-defs.h,
instead of including that entire file. */

*************** find_methods (struct type *t, char *name
*** 119,126 ****
int method_counter;

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

/* FIXME: Shouldn't this just be CHECK_TYPEDEF (t)? */
! CHECK_TYPEDEF (t);
/* Loop over each method name. At this level, all overloads of a name
are counted as a single name. There is an inner loop which loops over
each overload. */
*************** find_methods (struct type *t, char *name
*** 143,149 ****
method_name = dem_opname;
}

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

! if (strcmp_iw (name, method_name) == 0)
/* Find all the overloaded methods with that name. */
for (field_counter = TYPE_FN_FIELDLIST_LENGTH (t, method_counter) - 1;
field_counter >= 0;
*************** find_methods (struct type *t, char *name
*** 167,177 ****
}
else
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
!
/* Destructor is handled by caller, dont add it to the list */
! if (DESTRUCTOR_PREFIX_P (phys_name))
continue;
-
sym_arr[i1] = lookup_symbol (phys_name,
NULL, VAR_NAMESPACE,
(int *) NULL,
--- 167,176 ----
}
else
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
!
/* Destructor is handled by caller, dont add it to the list */
! if (destructor_prefix_p (phys_name) != 0)
continue;
sym_arr[i1] = lookup_symbol (phys_name,
NULL, VAR_NAMESPACE,
(int *) NULL,
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.28
diff -c -3 -p -r1.28 symtab.c
*** symtab.c 2001/01/30 02:49:36 1.28
--- symtab.c 2001/02/18 20:42:43
***************
*** 44,50 ****
#include "gdb_string.h"
#include "gdb_stat.h"
#include <ctype.h>
!
/* Prototype for one function in parser-defs.h,
instead of including that entire file. */

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

*************** gdb_mangle_name (struct type *type, int
*** 287,293 ****
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" : "";
--- 287,293 ----
int is_full_physname_constructor;

int is_constructor;
! int is_destructor = destructor_prefix_p (physname);
/* Need a new type prefix. */
char *const_prefix = method->is_const ? "C" : "";
char *volatile_prefix = method->is_volatile ? "V" : "";
*************** gdb_mangle_name (struct type *type, int
*** 297,306 ****
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));
--- 297,303 ----
if (OPNAME_PREFIX_P (field_name))
return xstrdup (physname);

! is_full_physname_constructor = constructor_prefix_p (physname);

is_constructor =
is_full_physname_constructor || (newname && STREQ (field_name, newname));
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.18
diff -c -3 -p -r1.18 symtab.h
*** symtab.h 2001/02/08 06:03:54 1.18
--- symtab.h 2001/02/18 20:42:43
*************** struct partial_symtab
*** 1055,1074 ****
'_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 */
--- 1055,1061 ----
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.31
diff -c -3 -p -r1.31 valops.c
*** valops.c 2001/02/06 20:05:41 1.31
--- valops.c 2001/02/18 20:42:44
***************
*** 30,35 ****
--- 30,36 ----
#include "demangle.h"
#include "language.h"
#include "gdbcmd.h"
+ #include "cp-abi.h"

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

/* 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 */
--- 3296,3302 ----

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

/* If we just skip the prefix, we get screwed by namespaces */
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.62
diff -c -3 -p -r1.62 Makefile.in
*** Makefile.in 2001/02/18 07:22:16 1.62
--- Makefile.in 2001/02/18 20:42:44
*************** INTL_DEPS = @INTLDEPS@
*** 137,143 ****
--- 137,158 ----
INTL_SRC = $(srcdir)/$(INTL_DIR)
INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC)

+ #
+ # CP-ABI sub directory definitions
#
+
+ SUBDIR_CPABI_OBS = \
+ cp-abi.o gnu-v3-abi.o gnu-v2-abi.o
+ SUBDIR_CPABI_SRCS = \
+ cp-abi/cp-abi.c cp-abi/gnu-v3-abi.c cp-abi/gnu-v2-abi.c
+ SUBDIR_CPABI_DEPS =
+ SUBDIR_CPABI_INITS = cp-abi/cp-abi.c cp-abi/gnu-v3-abi.c cp-abi/gnu-v2-abi.c
+ SUBDIR_CPABI_CFLAGS =
+ SUBDIR_CPABI_ALL =
+ SUBDIR_CPABI_CLEAN =
+ SUBDIR_CPABI_INSTALL =
+ SUBDIR_CPABI_UNINSTALL =
+ #
# CLI sub directory definitons
#
SUBDIR_CLI_OBS = \
*************** varobj.o: varobj.c $(defs_h) $(frame_h)
*** 2057,2062 ****
--- 2072,2088 ----
$(language_h) valprint.h varobj.h wrapper.h

wrapper.o: wrapper.c $(defs_h) $(frame_h) $(value_h) wrapper.h
+
+ # CPABI dependencies
+ # Need to explicitly specify the compile rule as make will do nothing
+ # or try to compile the object file into the cp-abi directory.
+
+ cp-abi.o: $(srcdir)/cp-abi/cp-abi.c cp-abi.h
+ $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cp-abi/cp-abi.c
+ gnu-v3-abi.o: $(srcdir)/cp-abi/gnu-v3-abi.c cp-abi.h
+ $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cp-abi/gnu-v3-abi.c
+ gnu-v2-abi.o: $(srcdir)/cp-abi/gnu-v2-abi.c cp-abi.h
+ $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cp-abi/gnu-v2-abi.c

#
# CLI dependencies
Index: configure.in
===================================================================
RCS file: /cvs/src/src/gdb/configure.in,v
retrieving revision 1.56
diff -c -3 -p -r1.56 configure.in
*** configure.in 2001/02/14 18:48:40 1.56
--- configure.in 2001/02/18 20:42:44
*************** esac
*** 499,504 ****
--- 499,527 ----

dnl Handle optional features that can be enabled.

+ dnl Handle cp-abi sub-directory configury.
+ AC_ARG_ENABLE(cp-abi,
+ [ --enable-cp-abi Enable C++ ABI abstraction],
+ [
+ case "${enable_cp_abi}" in
+ "yes" | "no") ;;
+ "") enable_cp_abi=yes ;;
+ *)
+ AC_MSG_ERROR(Bad value for --enable-cp-abi: ${enableval})
+ ;;
+ esac
+ ], [enable_cp_abi=yes])
+ case ${enable_cp_abi} in
+ "yes" )
+ if test -d "${srcdir}/cp-abi" ; then
+ CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_CPABI_OBS)"
+ CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_CPABI_DEPS)"
+ CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_CPABI_SRCS)"
+ CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_CPABI_INITS)"
+ ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_CPABI_CFLAGS)"
+ fi
+ ;;
+ esac
dnl Handle MI sub-directory configury.
AC_ARG_ENABLE(gdbmi,
[ --enable-gdbmi Enable GDB-MI interface],
*************** case ${enable_gdbmi} in
*** 526,531 ****
--- 549,555 ----
fi
;;
esac
+

# Configure UI_OUT by default (before 5.2 it can be disabled)
# It must be configured if gdbmi is configured