aboutsummaryrefslogtreecommitdiff
path: root/gdb/gnu-v3-abi.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2002-07-05 16:23:13 +0000
committerDaniel Jacobowitz <drow@false.org>2002-07-05 16:23:13 +0000
commit79d5b63a4560a9be0c4bbcfc38c7615cd13b735e (patch)
tree1fe4df6c5e4211a6dd6b199ed278f8530a448656 /gdb/gnu-v3-abi.c
parent3bb912e83b95feffd211a80f5308ce32b6fcbec8 (diff)
downloadgdb-79d5b63a4560a9be0c4bbcfc38c7615cd13b735e.zip
gdb-79d5b63a4560a9be0c4bbcfc38c7615cd13b735e.tar.gz
gdb-79d5b63a4560a9be0c4bbcfc38c7615cd13b735e.tar.bz2
2002-07-05 Daniel Jacobowitz <drow@mvista.com>
Fix PR gdb/595, gdb/602 * gnu-v3-abi.c (gnuv3_baseclass_offset): Remove unused variables. Don't call value_cast, just read the vtable pointer; update comments to match.
Diffstat (limited to 'gdb/gnu-v3-abi.c')
-rw-r--r--gdb/gnu-v3-abi.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index e86af89..a9ab494 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -374,15 +374,11 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr,
{
struct type *vtable_type = gdbarch_data (current_gdbarch,
vtable_type_gdbarch_data);
- struct type *basetype = TYPE_BASECLASS (type, index);
- struct value *full_object, *vbase_object, *orig_object;
- struct value *vtable, *orig_typeinfo, *orig_base_info;
- struct type *orig_type, *vbasetype;
+ struct value *vtable;
+ struct type *vbasetype;
struct value *offset_val, *vbase_array;
CORE_ADDR vtable_address;
long int cur_base_offset, base_offset;
- int to_top;
- int baseclasses, i;
/* If it isn't a virtual base, this is easy. The offset is in the
type definition. */
@@ -405,15 +401,22 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr,
/ ((int) TYPE_LENGTH (builtin_type_void_data_ptr));
/* We're now looking for the cur_base_offset'th entry (negative index)
- in the vcall_and_vbase_offsets array. */
-
- orig_object = value_at_lazy (type, address, NULL);
- vbasetype = TYPE_VPTR_BASETYPE (VALUE_TYPE (orig_object));
- vbase_object = value_cast (vbasetype, orig_object);
-
- vtable_address
- = value_as_address (value_field (vbase_object,
- TYPE_VPTR_FIELDNO (vbasetype)));
+ in the vcall_and_vbase_offsets array. We used to cast the object to
+ its TYPE_VPTR_BASETYPE, and reference the vtable as TYPE_VPTR_FIELDNO;
+ however, that cast can not be done without calling baseclass_offset again
+ if the TYPE_VPTR_BASETYPE is a virtual base class, as described in the
+ v3 C++ ABI Section 2.4.I.2.b. Fortunately the ABI guarantees that the
+ vtable pointer will be located at the beginning of the object, so we can
+ bypass the casting. Verify that the TYPE_VPTR_FIELDNO is in fact at the
+ start of whichever baseclass it resides in, as a sanity measure. */
+
+ vbasetype = TYPE_VPTR_BASETYPE (type);
+ if (TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0)
+ error ("Illegal vptr offset in class %s",
+ TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : "<unknown>");
+
+ vtable_address = value_as_address (value_at_lazy (builtin_type_void_data_ptr,
+ address, NULL));
vtable = value_at_lazy (vtable_type,
vtable_address - vtable_address_point_offset (),
NULL);