diff options
author | Jim Blandy <jimb@codesourcery.com> | 2001-04-27 00:19:09 +0000 |
---|---|---|
committer | Jim Blandy <jimb@codesourcery.com> | 2001-04-27 00:19:09 +0000 |
commit | f0f81458ce15d0fa455ffb80ac5bfb665f88bb8b (patch) | |
tree | 9a8c497f061b1321dabc1a8a0fce768f2008b037 /gdb/valops.c | |
parent | 1eb93c8be3f2118012ee08b80f9160bb8d13b917 (diff) | |
download | gdb-f0f81458ce15d0fa455ffb80ac5bfb665f88bb8b.tar.gz |
(Changes from Daniel Berlin, with revisions by Jim Blandy.)
Abstract out operations specific to particular C++ ABI's, and
invoke them through a function table. This removes the C++ ABI
dependencies scattered throughout the code, and allows us to
cleanly add support for new C++ ABI's.
* cp-abi.h, cp-abi.h, gnu-v2-abi.c, hpacc-abi.c: New files.
* c-typeprint.c, c-valprint.c, dbxread.c, eval.c, gdbtypes.c,
jv-typeprint.c, linespec.c, symtab.c, typeprint.c, valops.c:
#include "cp-abi.h". These files all use functions now declared
there.
* symtab.h (OPNAME_PREFIX_P, VTBL_PREFIX_P, DESTRUCTOR_PREFIX_P):
Deleted. These services are now provided by functions declared in
cp-abi.h.
* value.h (value_rtti_type, value_virtual_fn_field): Same.
* values.c (value_virtual_fn_field): Same, for this definition.
* valops.c (value_rtti_type): Same.
* c-typeprint.c (c_type_print_base): Use the functions from
"cp-abi.h", instead of the old macros, or hard-coded ABI-specific
tests.
* dbxread.c (record_minimal_symbol): Same.
* gdbtypes.c (get_destructor_fn_field, virtual_base_index,
virtual_base_index_skip_primaries): Same.
* jv-typeprint.c (java_type_print_base): Same.
* linespec.c (find_methods, decode_line_1): Same.
* symtab.c (gdb_mangle_name): Same.
* Makefile.in (SFILES): Add the new .c files mentioned above.
(cp_abi_h): New variable.
(COMMON_OBS): Add gnu-v2-abi.o, hpacc-abi.o, and cp-abi.o.
(cp-abi.o, gnu-v2-abi.o, hpacc-abi.o): New targets.
(c-typeprint.o, c-valprint.o, dbxread.o, eval.o, gdbtypes.o,
jv-typeprint.o, symtab.o, linespec.o, typeprint.o, valops.o): Add
dependency on $(cp_abi_h).
Diffstat (limited to 'gdb/valops.c')
-rw-r--r-- | gdb/valops.c | 221 |
1 files changed, 1 insertions, 220 deletions
diff --git a/gdb/valops.c b/gdb/valops.c index 0ab0ae6e916..0e7e7e14056 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -31,6 +31,7 @@ #include "language.h" #include "gdbcmd.h" #include "regcache.h" +#include "cp-abi.h" #include <errno.h> #include "gdb_string.h" @@ -3111,226 +3112,6 @@ value_struct_elt_for_reference (struct type *domain, int offset, } -/* Find the real run-time type of a value using RTTI. - * V is a pointer to the value. - * A pointer to the struct type entry of the run-time type - * is returneed. - * FULL is a flag that is set only if the value V includes - * the entire contents of an object of the RTTI type. - * TOP is the offset to the top of the enclosing object of - * the real run-time type. This offset may be for the embedded - * object, or for the enclosing object of V. - * USING_ENC is the flag that distinguishes the two cases. - * If it is 1, then the offset is for the enclosing object, - * otherwise for the embedded object. - * - */ - -struct type * -value_rtti_type (value_ptr v, int *full, int *top, int *using_enc) -{ - struct type *known_type; - struct type *rtti_type; - CORE_ADDR coreptr; - value_ptr vp; - int using_enclosing = 0; - long top_offset = 0; - char rtti_type_name[256]; - - if (full) - *full = 0; - if (top) - *top = -1; - if (using_enc) - *using_enc = 0; - - /* Get declared type */ - known_type = VALUE_TYPE (v); - CHECK_TYPEDEF (known_type); - /* RTTI works only or class objects */ - if (TYPE_CODE (known_type) != TYPE_CODE_CLASS) - return NULL; - if (TYPE_HAS_VTABLE(known_type)) - { - /* If neither the declared type nor the enclosing type of the - * value structure has a HP ANSI C++ style virtual table, - * we can't do anything. */ - if (!TYPE_HAS_VTABLE (known_type)) - { - known_type = VALUE_ENCLOSING_TYPE (v); - CHECK_TYPEDEF (known_type); - if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) || - !TYPE_HAS_VTABLE (known_type)) - return NULL; /* No RTTI, or not HP-compiled types */ - CHECK_TYPEDEF (known_type); - using_enclosing = 1; - } - - if (using_enclosing && using_enc) - *using_enc = 1; - - /* First get the virtual table address */ - coreptr = *(CORE_ADDR *) ((VALUE_CONTENTS_ALL (v)) - + VALUE_OFFSET (v) - + (using_enclosing ? 0 : VALUE_EMBEDDED_OFFSET (v))); - if (coreptr == 0) - return NULL; /* return silently -- maybe called on gdb-generated value */ - - /* Fetch the top offset of the object */ - /* FIXME possible 32x64 problem with pointer size & arithmetic */ - vp = value_at (builtin_type_int, - coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET, - VALUE_BFD_SECTION (v)); - top_offset = value_as_long (vp); - if (top) - *top = top_offset; - - /* Fetch the typeinfo pointer */ - /* FIXME possible 32x64 problem with pointer size & arithmetic */ - vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET, VALUE_BFD_SECTION (v)); - /* Indirect through the typeinfo pointer and retrieve the pointer - * to the string name */ - coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)); - if (!coreptr) - error ("Retrieved null typeinfo pointer in trying to determine run-time type"); - vp = value_at (builtin_type_int, coreptr + 4, VALUE_BFD_SECTION (v)); /* 4 -> offset of name field */ - /* FIXME possible 32x64 problem */ - - coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)); - - read_memory_string (coreptr, rtti_type_name, 256); - - if (strlen (rtti_type_name) == 0) - error ("Retrieved null type name from typeinfo"); - - /* search for type */ - rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1); - - if (!rtti_type) - error ("Could not find run-time type: invalid type name %s in typeinfo??", rtti_type_name); - CHECK_TYPEDEF (rtti_type); -#if 0 - printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type), TYPE_TAG_NAME (rtti_type), full ? *full : -1); -#endif - /* Check whether we have the entire object */ - if (full /* Non-null pointer passed */ - && - /* Either we checked on the whole object in hand and found the - top offset to be zero */ - (((top_offset == 0) && - using_enclosing && - TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type)) - || - /* Or we checked on the embedded object and top offset was the - same as the embedded offset */ - ((top_offset == VALUE_EMBEDDED_OFFSET (v)) && - !using_enclosing && - TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type)))) - - *full = 1; - } - else - /* - Right now this is G++ RTTI. Plan on this changing in the - future as i get around to setting the vtables properly for G++ - compiled stuff. Also, i'll be using the type info functions, - which are always right. Deal with it until then. - */ - { - CORE_ADDR vtbl; - struct minimal_symbol *minsym; - struct symbol *sym; - char *demangled_name; - struct type *btype; - /* If the type has no vptr fieldno, try to get it filled in */ - if (TYPE_VPTR_FIELDNO(known_type) < 0) - fill_in_vptr_fieldno(known_type); - - /* If we still can't find one, give up */ - if (TYPE_VPTR_FIELDNO(known_type) < 0) - return NULL; - - /* Make sure our basetype and known type match, otherwise, cast - so we can get at the vtable properly. - */ - btype = TYPE_VPTR_BASETYPE (known_type); - CHECK_TYPEDEF (btype); - if (btype != known_type ) - { - v = value_cast (btype, v); - if (using_enc) - *using_enc=1; - } - /* - We can't use value_ind here, because it would want to use RTTI, and - we'd waste a bunch of time figuring out we already know the type. - Besides, we don't care about the type, just the actual pointer - */ - if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0) - return NULL; - - /* - If we are enclosed by something that isn't us, adjust the - address properly and set using_enclosing. - */ - if (VALUE_ENCLOSING_TYPE(v) != VALUE_TYPE(v)) - { - value_ptr tempval; - tempval=value_field(v,TYPE_VPTR_FIELDNO(known_type)); - VALUE_ADDRESS(tempval)+=(TYPE_BASECLASS_BITPOS(known_type,TYPE_VPTR_FIELDNO(known_type))/8); - vtbl=value_as_pointer(tempval); - using_enclosing=1; - } - else - { - vtbl=value_as_pointer(value_field(v,TYPE_VPTR_FIELDNO(known_type))); - using_enclosing=0; - } - - /* Try to find a symbol that is the vtable */ - minsym=lookup_minimal_symbol_by_pc(vtbl); - if (minsym==NULL || (demangled_name=SYMBOL_NAME(minsym))==NULL || !VTBL_PREFIX_P(demangled_name)) - return NULL; - - /* If we just skip the prefix, we get screwed by namespaces */ - demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI); - *(strchr(demangled_name,' '))=0; - - /* Lookup the type for the name */ - rtti_type=lookup_typename(demangled_name, (struct block *)0,1); - - if (rtti_type==NULL) - return NULL; - - if (TYPE_N_BASECLASSES(rtti_type) > 1 && full && (*full) != 1) - { - if (top) - *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8; - if (top && ((*top) >0)) - { - if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type)) - { - if (full) - *full=0; - } - else - { - if (full) - *full=1; - } - } - } - else - { - if (full) - *full=1; - } - if (using_enc) - *using_enc=using_enclosing; - } - return rtti_type; -} - /* Given a pointer value V, find the real (RTTI) type of the object it points to. Other parameters FULL, TOP, USING_ENC as with value_rtti_type() |