int offset;
struct type *void_ptr_type
- = lookup_pointer_type (builtin_type_void);
+ = builtin_type (arch)->builtin_data_ptr;
struct type *ptr_to_void_fn_type
- = lookup_pointer_type (lookup_function_type (builtin_type_void));
+ = builtin_type (arch)->builtin_func_ptr;
/* ARCH can't give us the true ptrdiff_t type, so we guess. */
struct type *ptrdiff_type
FIELD_NAME (*field) = "vcall_and_vbase_offsets";
FIELD_TYPE (*field)
= create_array_type (0, ptrdiff_type,
- create_range_type (0, builtin_type_int, 0, -1));
+ create_range_type (0, builtin_type_int32, 0, -1));
FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
offset += TYPE_LENGTH (FIELD_TYPE (*field));
field++;
FIELD_NAME (*field) = "virtual_functions";
FIELD_TYPE (*field)
= create_array_type (0, ptr_to_void_fn_type,
- create_range_type (0, builtin_type_int, 0, -1));
+ create_range_type (0, builtin_type_int32, 0, -1));
FIELD_BITPOS (*field) = offset * TARGET_CHAR_BIT;
offset += TYPE_LENGTH (FIELD_TYPE (*field));
field++;
struct type *run_time_type;
struct type *base_type;
LONGEST offset_to_top;
+ struct type *values_type_vptr_basetype;
+ int values_type_vptr_fieldno;
/* We only have RTTI for class objects. */
if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
/* If we can't find the virtual table pointer for values_type, we
can't find the RTTI. */
- fill_in_vptr_fieldno (values_type);
- if (TYPE_VPTR_FIELDNO (values_type) == -1)
+ values_type_vptr_fieldno = get_vptr_fieldno (values_type,
+ &values_type_vptr_basetype);
+ if (values_type_vptr_fieldno == -1)
return NULL;
if (using_enc_p)
/* Fetch VALUE's virtual table pointer, and tweak it to point at
an instance of our imaginary gdb_gnu_v3_abi_vtable structure. */
- base_type = check_typedef (TYPE_VPTR_BASETYPE (values_type));
+ base_type = check_typedef (values_type_vptr_basetype);
if (values_type != base_type)
{
value = value_cast (base_type, value);
*using_enc_p = 1;
}
vtable_address
- = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (values_type)));
+ = value_as_address (value_field (value, values_type_vptr_fieldno));
vtable = value_at_lazy (vtable_type,
vtable_address - vtable_address_point_offset ());
/* Fetch the appropriate function pointer from the vtable. */
vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions),
- value_from_longest (builtin_type_int, vtable_index));
+ value_from_longest (builtin_type_int32, vtable_index));
/* If this architecture uses function descriptors directly in the vtable,
then the address of the vtable entry is actually a "function pointer"
struct value *offset_val, *vbase_array;
CORE_ADDR vtable_address;
long int cur_base_offset, base_offset;
+ int vbasetype_vptr_fieldno;
/* If it isn't a virtual base, this is easy. The offset is in the
type definition. */
we have debugging information for that baseclass. */
vbasetype = TYPE_VPTR_BASETYPE (type);
- if (TYPE_VPTR_FIELDNO (vbasetype) < 0)
- fill_in_vptr_fieldno (vbasetype);
+ vbasetype_vptr_fieldno = get_vptr_fieldno (vbasetype, NULL);
- if (TYPE_VPTR_FIELDNO (vbasetype) >= 0
- && TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0)
+ if (vbasetype_vptr_fieldno >= 0
+ && TYPE_FIELD_BITPOS (vbasetype, vbasetype_vptr_fieldno) != 0)
error (_("Illegal vptr offset in class %s"),
TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : "<unknown>");
address));
vtable = value_at_lazy (vtable_type,
vtable_address - vtable_address_point_offset ());
- offset_val = value_from_longest(builtin_type_int, cur_base_offset);
+ offset_val = value_from_longest(builtin_type_int32, cur_base_offset);
vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets);
base_offset = value_as_long (value_subscript (vbase_array, offset_val));
return base_offset;
return NULL;
}
+/* Decode GNU v3 method pointer. */
+
+static int
+gnuv3_decode_method_ptr (const gdb_byte *contents,
+ CORE_ADDR *value_p,
+ LONGEST *adjustment_p)
+{
+ struct type *funcptr_type = builtin_type_void_func_ptr;
+ struct type *offset_type = builtin_type_long;
+ CORE_ADDR ptr_value;
+ LONGEST voffset, adjustment;
+ int vbit;
+
+ /* Extract the pointer to member. The first element is either a pointer
+ or a vtable offset. For pointers, we need to use extract_typed_address
+ to allow the back-end to convert the pointer to a GDB address -- but
+ vtable offsets we must handle as integers. At this point, we do not
+ yet know which case we have, so we extract the value under both
+ interpretations and choose the right one later on. */
+ ptr_value = extract_typed_address (contents, funcptr_type);
+ voffset = extract_signed_integer (contents, TYPE_LENGTH (funcptr_type));
+ contents += TYPE_LENGTH (funcptr_type);
+ adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type));
+
+ if (!gdbarch_vbit_in_delta (current_gdbarch))
+ {
+ vbit = voffset & 1;
+ voffset = voffset ^ vbit;
+ }
+ else
+ {
+ vbit = adjustment & 1;
+ adjustment = adjustment >> 1;
+ }
+
+ *value_p = vbit? voffset : ptr_value;
+ *adjustment_p = adjustment;
+ return vbit;
+}
+
/* GNU v3 implementation of cplus_print_method_ptr. */
static void
domain = TYPE_DOMAIN_TYPE (type);
/* Extract the pointer to member. */
- ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
- contents += TYPE_LENGTH (builtin_type_void_func_ptr);
- adjustment = extract_signed_integer (contents,
- TYPE_LENGTH (builtin_type_long));
-
- if (!gdbarch_vbit_in_delta (current_gdbarch))
- {
- vbit = ptr_value & 1;
- ptr_value = ptr_value ^ vbit;
- }
- else
- {
- vbit = adjustment & 1;
- adjustment = adjustment >> 1;
- }
+ vbit = gnuv3_decode_method_ptr (contents, &ptr_value, &adjustment);
/* Check for NULL. */
if (ptr_value == 0 && vbit == 0)
method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
- ptr_value = extract_typed_address (contents, builtin_type_void_func_ptr);
- contents += TYPE_LENGTH (builtin_type_void_func_ptr);
- adjustment = extract_signed_integer (contents,
- TYPE_LENGTH (builtin_type_long));
-
- if (!gdbarch_vbit_in_delta (current_gdbarch))
- {
- vbit = ptr_value & 1;
- ptr_value = ptr_value ^ vbit;
- }
- else
- {
- vbit = adjustment & 1;
- adjustment = adjustment >> 1;
- }
+ /* Extract the pointer to member. */
+ vbit = gnuv3_decode_method_ptr (contents, &ptr_value, &adjustment);
/* First convert THIS to match the containing type of the pointer to
member. This cast may adjust the value of THIS. */
instance. */
*this_p = value_cast (builtin_type_void_data_ptr, *this_p);
adjval = value_from_longest (builtin_type_long, adjustment);
- *this_p = value_add (*this_p, adjval);
+ *this_p = value_ptradd (*this_p, adjval);
*this_p = value_cast (final_type, *this_p);
if (vbit)