[rfc][27/37] Eliminate builtin_type_ macros: Update C++ ABI handling

uweigand
2008-08-31T17:52:38Z

[-- Attachment #1: diff-type-cpgnu --]
[-- Type: text/plain, Size: 23710 bytes --]

Hello,

gnu-v3-abi.c uses current_gdbarch and builtin_type_ macros to determine
ABI properties of the C++ class implementation. The following patch
removes the dependency on the current_gdbarch variable by using the
architecture associated with the objfile where the class type is defined.

Note that this assumes every C++ class type GDB handles is in fact
defined in an objfile, i.e. there are no GDB internal class types.
This is in fact the case (except for some Java "class" definitions,
which are not handled by gnu-v3-abi.c anyway).

Nearly all functions in gnu-v3-abi.c already operate on a class type.
The only exceptions are the cplus_method_ptr_size and cplus_make_method_ptr
callbacks; to handle those, I've updated their callers to pass in the
appropriate method (or method pointer) type.

As another C++-related change, I've removed the assumption in
cp_print_class_member that member pointer types have the same length
as a "long" on the target. If the caller simply passes in the pointer
type itself instead of only the associated domain type, that routine
can just use the actual length of the pointer type itself.

Bye,
Ulrich

* cp-abi.h (cplus_method_ptr_size): Add TO_TYPE parameter.
(cplus_make_method_ptr): Add TYPE parameter.
* cp-abi.c (cplus_method_ptr_size): Add TO_TYPE parameter. Pass it
on to current_cp_abi.method_ptr_size callback.
(cplus_make_method_ptr): Add TYPE parameter. Pass it on to
current_cp_abi.make_method_ptr callback.

* gdbtypes.c (lookup_methodptr_type): Pass target type
argument to cplus_method_ptr_size.
* valops.c (value_cast): Pass type argument to cplus_make_method_ptr.
(value_struct_elt_for_reference): Likewise.

* gnu-v3-abi.c (get_class_arch): New function.
(vtable_address_point_offset): Add GDBARCH parameter. Use it
instead of current_gdbarch. Update all callers.
(gnuv3_get_vtable): Likewise.
(gnuv3_get_virtual_fn): Likewise.
(gnuv3_rtti_type): Call get_class_arch to determine architecture.
Use it instead of current_gdbarch.
(gnuv3_virtual_fn_field): Likewise.
(gnuv3_baseclass_offset): Likewise.
(gnuv3_print_method_ptr): Likewise.
(gnuv3_method_ptr_to_value): Likewise.
(gnuv3_method_ptr_size): Add TYPE parameter. Use it to determine
class architecture. Use architecture types instead of builtin types.
(gnuv3_make_method_ptr): Likewise.

* cp-valprint.c (cp_print_class_member): Expect pointer type
instead of class type. Use its length when extracting value.
* c-valprint.c (c_val_print): Update call to cp_print_class_member.

Index: gdb-head/gdb/cp-abi.c
===================================================================
--- gdb-head.orig/gdb/cp-abi.c
+++ gdb-head/gdb/cp-abi.c
@@ -113,19 +113,20 @@ cplus_print_method_ptr (const gdb_byte *
}

int
-cplus_method_ptr_size (void)
+cplus_method_ptr_size (struct type *to_type)
{
if (current_cp_abi.method_ptr_size == NULL)
error (_("GDB does not support pointers to methods on this target"));
- return (*current_cp_abi.method_ptr_size) ();
+ return (*current_cp_abi.method_ptr_size) (to_type);
}

void
-cplus_make_method_ptr (gdb_byte *contents, CORE_ADDR value, int is_virtual)
+cplus_make_method_ptr (struct type *type, gdb_byte *contents,
+ CORE_ADDR value, int is_virtual)
{
if (current_cp_abi.make_method_ptr == NULL)
error (_("GDB does not support pointers to methods on this target"));
- (*current_cp_abi.make_method_ptr) (contents, value, is_virtual);
+ (*current_cp_abi.make_method_ptr) (type, contents, value, is_virtual);
}

CORE_ADDR
Index: gdb-head/gdb/cp-abi.h
===================================================================
--- gdb-head.orig/gdb/cp-abi.h
+++ gdb-head/gdb/cp-abi.h
@@ -151,21 +151,20 @@ extern int baseclass_offset (struct type
void cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
struct ui_file *stream);

-/* Return the size of a pointer to member function for the current
- architecture. */
-int cplus_method_ptr_size (void);
+/* Return the size of a pointer to member function of type TO_TYPE. */
+int cplus_method_ptr_size (struct type *to_type);

/* Return the method which should be called by applying METHOD_PTR
to *THIS_P, and adjust *THIS_P if necessary. */
struct value *cplus_method_ptr_to_value (struct value **this_p,
struct value *method_ptr);

-/* Create the byte pattern in CONTENTS representing a pointer to
- member function at ADDRESS (if IS_VIRTUAL is 0) or with virtual
- table offset ADDRESS (if IS_VIRTUAL is 1). This is the opposite
- of cplus_method_ptr_to_value. */
-void cplus_make_method_ptr (gdb_byte *CONTENTS, CORE_ADDR address,
- int is_virtual);
+/* Create the byte pattern in CONTENTS representing a pointer of
+ type TYPE to member function at ADDRESS (if IS_VIRTUAL is 0)
+ or with virtual table offset ADDRESS (if IS_VIRTUAL is 1).
+ This is the opposite of cplus_method_ptr_to_value. */
+void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS,
+ CORE_ADDR address, int is_virtual);

/* Determine if we are currently in a C++ thunk. If so, get the address
of the routine we are thunking to and continue to there instead. */
@@ -195,8 +194,8 @@ struct cp_abi_ops
const bfd_byte *valaddr, CORE_ADDR address);
void (*print_method_ptr) (const gdb_byte *contents, struct type *type,
struct ui_file *stream);
- int (*method_ptr_size) (void);
- void (*make_method_ptr) (gdb_byte *, CORE_ADDR, int);
+ int (*method_ptr_size) (struct type *);
+ void (*make_method_ptr) (struct type *, gdb_byte *, CORE_ADDR, int);
struct value * (*method_ptr_to_value) (struct value **, struct value *);
CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
int (*pass_by_reference) (struct type *type);
Index: gdb-head/gdb/cp-valprint.c
===================================================================
--- gdb-head.orig/gdb/cp-valprint.c
+++ gdb-head/gdb/cp-valprint.c
@@ -538,16 +538,16 @@ cp_find_class_member (struct type **doma
}

void
-cp_print_class_member (const gdb_byte *valaddr, struct type *domain,
+cp_print_class_member (const gdb_byte *valaddr, struct type *type,
struct ui_file *stream, char *prefix)
{
/* VAL is a byte offset into the structure type DOMAIN.
Find the name of the field for that offset and
print it. */
+ struct type *domain = TYPE_DOMAIN_TYPE (type);
+ LONGEST val = extract_signed_integer (valaddr, TYPE_LENGTH (type));
unsigned int fieldno;

- LONGEST val = unpack_long (builtin_type_long, valaddr);
-
/* Pointers to data members are usually byte offsets into an object.
Because a data member can have offset zero, and a NULL pointer to
member must be distinct from any valid non-NULL pointer to
Index: gdb-head/gdb/c-valprint.c
===================================================================
--- gdb-head.orig/gdb/c-valprint.c
+++ gdb-head/gdb/c-valprint.c
@@ -189,9 +189,7 @@ c_val_print (struct type *type, const gd
print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
break;
}
- cp_print_class_member (valaddr + embedded_offset,
- TYPE_DOMAIN_TYPE (type),
- stream, "&");
+ cp_print_class_member (valaddr + embedded_offset, type, stream, "&");
break;

case TYPE_CODE_METHODPTR:
Index: gdb-head/gdb/gdbtypes.c
===================================================================
--- gdb-head.orig/gdb/gdbtypes.c
+++ gdb-head/gdb/gdbtypes.c
@@ -666,7 +666,7 @@ lookup_methodptr_type (struct type *to_t
mtype = alloc_type (TYPE_OBJFILE (to_type));
TYPE_TARGET_TYPE (mtype) = to_type;
TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type);
- TYPE_LENGTH (mtype) = cplus_method_ptr_size ();
+ TYPE_LENGTH (mtype) = cplus_method_ptr_size (to_type);
TYPE_CODE (mtype) = TYPE_CODE_METHODPTR;
return mtype;
}
Index: gdb-head/gdb/gnu-v3-abi.c
===================================================================
--- gdb-head.orig/gdb/gnu-v3-abi.c
+++ gdb-head/gdb/gnu-v3-abi.c
@@ -45,6 +45,21 @@ gnuv3_is_operator_name (const char *name
}

+/* Determine architecture of class DOMAIN. This architecture is used
+ to query C++ ABI details (types, method pointer layout, etc.).
+
+ Note that we assume DOMAIN must have been allocated with an OBJFILE;
+ GDB does not provide any built-in class types. Thus we use the
+ architecture of that OBJFILE to define the C++ ABI. */
+
+static struct gdbarch *
+get_class_arch (struct type *domain)
+{
+ gdb_assert (TYPE_CODE (domain) == TYPE_CODE_CLASS);
+ gdb_assert (TYPE_OBJFILE (domain) != NULL);
+ return get_objfile_arch (TYPE_OBJFILE (domain));
+}
+
/* To help us find the components of a vtable, we build ourselves a
GDB type object representing the vtable structure. Following the
V3 ABI, it goes something like this:
@@ -176,10 +191,9 @@ build_gdb_vtable_type (struct gdbarch *a
gdb_gnu_v3_abi_vtable' object to the vtable's "address point"
(i.e., where objects' virtual table pointers point). */
static int
-vtable_address_point_offset (void)
+vtable_address_point_offset (struct gdbarch *gdbarch)
{
- struct type *vtable_type = gdbarch_data (current_gdbarch,
- vtable_type_gdbarch_data);
+ struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);

return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions)
/ TARGET_CHAR_BIT);
@@ -190,8 +204,8 @@ static struct type *
gnuv3_rtti_type (struct value *value,
int *full_p, int *top_p, int *using_enc_p)
{
- struct type *vtable_type = gdbarch_data (current_gdbarch,
- vtable_type_gdbarch_data);
+ struct gdbarch *gdbarch;
+ struct type *vtable_type;
struct type *values_type = check_typedef (value_type (value));
CORE_ADDR vtable_address;
struct value *vtable;
@@ -208,6 +222,16 @@ gnuv3_rtti_type (struct value *value,
if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
return NULL;

+ /* This routine may be called for Java types that do not have
+ a proper objfile. Just return NULL for those. */
+ if (!TYPE_OBJFILE (values_type)
+ || !TYPE_OBJFILE (values_type)->obfd)
+ return NULL;
+
+ /* Determine architecture. */
+ gdbarch = get_class_arch (values_type);
+ vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
+
/* If we can't find the virtual table pointer for values_type, we
can't find the RTTI. */
values_type_vptr_fieldno = get_vptr_fieldno (values_type,
@@ -229,8 +253,9 @@ gnuv3_rtti_type (struct value *value,
}
vtable_address
= value_as_address (value_field (value, values_type_vptr_fieldno));
- vtable = value_at_lazy (vtable_type,
- vtable_address - vtable_address_point_offset ());
+ vtable
+ = value_at_lazy (vtable_type,
+ vtable_address - vtable_address_point_offset (gdbarch));

/* Find the linker symbol for this vtable. */
vtable_symbol
@@ -282,10 +307,9 @@ gnuv3_rtti_type (struct value *value,
vtable type for this architecture. */

static struct value *
-gnuv3_get_vtable (struct value *container)
+gnuv3_get_vtable (struct gdbarch *gdbarch, struct value *container)
{
- struct type *vtable_type = gdbarch_data (current_gdbarch,
- vtable_type_gdbarch_data);
+ struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
struct type *vtable_pointer_type;
struct value *vtable_pointer;
CORE_ADDR vtable_pointer_address, vtable_address;
@@ -311,17 +335,17 @@ gnuv3_get_vtable (struct value *containe
/* Correct it to point at the start of the virtual table, rather
than the address point. */
return value_at_lazy (vtable_type,
- vtable_address - vtable_address_point_offset ());
+ vtable_address - vtable_address_point_offset (gdbarch));
}

/* Return a function pointer for CONTAINER's VTABLE_INDEX'th virtual
function, of type FNTYPE. */

static struct value *
-gnuv3_get_virtual_fn (struct value *container, struct type *fntype,
- int vtable_index)
+gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container,
+ struct type *fntype, int vtable_index)
{
- struct value *vtable = gnuv3_get_vtable (container);
+ struct value *vtable = gnuv3_get_vtable (gdbarch, container);
struct value *vfn;

/* Fetch the appropriate function pointer from the vtable. */
@@ -333,7 +357,7 @@ gnuv3_get_virtual_fn (struct value *cont
(i.e. points to the descriptor). We don't need to scale the index
by the size of a function descriptor; GCC does that before outputing
debug information. */
- if (gdbarch_vtable_function_descriptors (current_gdbarch))
+ if (gdbarch_vtable_function_descriptors (gdbarch))
vfn = value_addr (vfn);

/* Cast the function pointer to the appropriate type. */
@@ -351,18 +375,22 @@ gnuv3_virtual_fn_field (struct value **v
struct type *vfn_base, int offset)
{
struct type *values_type = check_typedef (value_type (*value_p));
+ struct gdbarch *gdbarch;

/* Some simple sanity checks. */
if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
error (_("Only classes can have virtual functions."));

+ /* Determine architecture. */
+ gdbarch = get_class_arch (values_type);
+
/* Cast our value to the base class which defines this virtual
function. This takes care of any necessary `this'
adjustments. */
if (vfn_base != values_type)
*value_p = value_cast (vfn_base, *value_p);

- return gnuv3_get_virtual_fn (*value_p, TYPE_FN_FIELD_TYPE (f, j),
+ return gnuv3_get_virtual_fn (gdbarch, *value_p, TYPE_FN_FIELD_TYPE (f, j),
TYPE_FN_FIELD_VOFFSET (f, j));
}

@@ -377,8 +405,9 @@ static int
gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
CORE_ADDR address)
{
- struct type *vtable_type = gdbarch_data (current_gdbarch,
- vtable_type_gdbarch_data);
+ struct gdbarch *gdbarch;
+ struct type *vtable_type;
+ struct type *ptr_type;
struct value *vtable;
struct type *vbasetype;
struct value *offset_val, *vbase_array;
@@ -386,6 +415,11 @@ gnuv3_baseclass_offset (struct type *typ
long int cur_base_offset, base_offset;
int vbasetype_vptr_fieldno;

+ /* Determine architecture. */
+ gdbarch = get_class_arch (type);
+ vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
+ ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+
/* If it isn't a virtual base, this is easy. The offset is in the
type definition. */
if (!BASETYPE_VIA_VIRTUAL (type, index))
@@ -397,14 +431,13 @@ gnuv3_baseclass_offset (struct type *typ
complete inheritance graph based on the debug info. Neither is
worthwhile. */
cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8;
- if (cur_base_offset >= - vtable_address_point_offset ())
+ if (cur_base_offset >= - vtable_address_point_offset (gdbarch))
error (_("Expected a negative vbase offset (old compiler?)"));

- cur_base_offset = cur_base_offset + vtable_address_point_offset ();
- if ((- cur_base_offset) % TYPE_LENGTH (builtin_type_void_data_ptr) != 0)
+ cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch);
+ if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0)
error (_("Misaligned vbase offset."));
- cur_base_offset = cur_base_offset
- / ((int) TYPE_LENGTH (builtin_type_void_data_ptr));
+ cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type));

/* We're now looking for the cur_base_offset'th entry (negative index)
in the vcall_and_vbase_offsets array. We used to cast the object to
@@ -425,11 +458,11 @@ gnuv3_baseclass_offset (struct type *typ
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));
- vtable = value_at_lazy (vtable_type,
- vtable_address - vtable_address_point_offset ());
- offset_val = value_from_longest(builtin_type_int32, cur_base_offset);
+ vtable_address = value_as_address (value_at_lazy (ptr_type, address));
+ vtable
+ = value_at_lazy (vtable_type,
+ vtable_address - vtable_address_point_offset (gdbarch));
+ 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;
@@ -496,6 +529,9 @@ gnuv3_print_method_ptr (const gdb_byte *
struct type *type,
struct ui_file *stream)
{
+ struct gdbarch *gdbarch;
+ struct type *funcptr_type;
+ struct type *offset_type;
CORE_ADDR ptr_value;
LONGEST adjustment;
struct type *domain;
@@ -503,13 +539,17 @@ gnuv3_print_method_ptr (const gdb_byte *

domain = TYPE_DOMAIN_TYPE (type);

+ /* Determine architecture. */
+ gdbarch = get_class_arch (domain);
+ funcptr_type = builtin_type (gdbarch)->builtin_func_ptr;
+ offset_type = builtin_type (gdbarch)->builtin_long;
+
/* 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));
+ ptr_value = extract_typed_address (contents, funcptr_type);
+ contents += TYPE_LENGTH (funcptr_type);
+ adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type));

- if (!gdbarch_vbit_in_delta (current_gdbarch))
+ if (!gdbarch_vbit_in_delta (gdbarch))
{
vbit = ptr_value & 1;
ptr_value = ptr_value ^ vbit;
@@ -536,7 +576,7 @@ gnuv3_print_method_ptr (const gdb_byte *
/* It's a virtual table offset, maybe in this class. Search
for a field with the correct vtable offset. First convert it
to an index, as used in TYPE_FN_FIELD_VOFFSET. */
- voffset = ptr_value / TYPE_LENGTH (builtin_type_long);
+ voffset = ptr_value / TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);

physname = gnuv3_find_method_in (domain, voffset, adjustment);

@@ -575,17 +615,22 @@ gnuv3_print_method_ptr (const gdb_byte *
/* GNU v3 implementation of cplus_method_ptr_size. */

static int
-gnuv3_method_ptr_size (void)
+gnuv3_method_ptr_size (struct type *type)
{
- return 2 * TYPE_LENGTH (builtin_type_void_data_ptr);
+ struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
+ struct gdbarch *gdbarch = get_class_arch (domain_type);
+ return 2 * TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
}

/* GNU v3 implementation of cplus_make_method_ptr. */

static void
-gnuv3_make_method_ptr (gdb_byte *contents, CORE_ADDR value, int is_virtual)
+gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
+ CORE_ADDR value, int is_virtual)
{
- int size = TYPE_LENGTH (builtin_type_void_data_ptr);
+ struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
+ struct gdbarch *gdbarch = get_class_arch (domain_type);
+ int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);

/* FIXME drow/2006-12-24: The adjustment of "this" is currently
always zero, since the method pointer is of the correct type.
@@ -596,7 +641,7 @@ gnuv3_make_method_ptr (gdb_byte *content
support for adjusting pointers to members when casting them -
not currently supported by GDB. */

- if (!gdbarch_vbit_in_delta (current_gdbarch))
+ if (!gdbarch_vbit_in_delta (gdbarch))
{
store_unsigned_integer (contents, size, value | is_virtual);
store_unsigned_integer (contents + size, size, 0);
@@ -613,24 +658,30 @@ gnuv3_make_method_ptr (gdb_byte *content
static struct value *
gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
{
+ struct gdbarch *gdbarch;
const gdb_byte *contents = value_contents (method_ptr);
CORE_ADDR ptr_value;
- struct type *final_type, *method_type;
+ struct type *domain_type, *final_type, *method_type;
+ struct type *funcptr_type, *offset_type;
LONGEST adjustment;
struct value *adjval;
int vbit;

- final_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr)));
- final_type = lookup_pointer_type (final_type);
+ domain_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr)));
+ final_type = lookup_pointer_type (domain_type);

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));
+ /* Determine architecture. */
+ gdbarch = get_class_arch (domain_type);
+ funcptr_type = builtin_type (gdbarch)->builtin_func_ptr;
+ offset_type = builtin_type (gdbarch)->builtin_long;
+
+ ptr_value = extract_typed_address (contents, funcptr_type);
+ contents += TYPE_LENGTH (funcptr_type);
+ adjustment = extract_signed_integer (contents, TYPE_LENGTH (offset_type));

- if (!gdbarch_vbit_in_delta (current_gdbarch))
+ if (!gdbarch_vbit_in_delta (gdbarch))
{
vbit = ptr_value & 1;
ptr_value = ptr_value ^ vbit;
@@ -660,15 +711,17 @@ gnuv3_method_ptr_to_value (struct value

You can provoke this case by casting a Base::* to a Derived::*, for
instance. */
- *this_p = value_cast (builtin_type_void_data_ptr, *this_p);
- adjval = value_from_longest (builtin_type_long, adjustment);
+ *this_p = value_cast (builtin_type (gdbarch)->builtin_data_ptr, *this_p);
+ adjval = value_from_longest (offset_type, adjustment);
*this_p = value_ptradd (*this_p, adjval);
*this_p = value_cast (final_type, *this_p);

if (vbit)
{
- LONGEST voffset = ptr_value / TYPE_LENGTH (builtin_type_long);
- return gnuv3_get_virtual_fn (value_ind (*this_p), method_type, voffset);
+ LONGEST voffset;
+ voffset = ptr_value / TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
+ return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
+ method_type, voffset);
}
else
return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
Index: gdb-head/gdb/valops.c
===================================================================
--- gdb-head.orig/gdb/valops.c
+++ gdb-head/gdb/valops.c
@@ -466,7 +466,7 @@ value_cast (struct type *type, struct va
&& value_as_long (arg2) == 0)
{
struct value *result = allocate_value (type);
- cplus_make_method_ptr (value_contents_writeable (result), 0, 0);
+ cplus_make_method_ptr (type, value_contents_writeable (result), 0, 0);
return result;
}
else if (code1 == TYPE_CODE_MEMBERPTR && code2 == TYPE_CODE_INT
@@ -2612,7 +2612,8 @@ value_struct_elt_for_reference (struct t
{
result = allocate_value
(lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j)));
- cplus_make_method_ptr (value_contents_writeable (result),
+ cplus_make_method_ptr (value_type (result),
+ value_contents_writeable (result),
TYPE_FN_FIELD_VOFFSET (f, j), 1);
}
else if (noside == EVAL_AVOID_SIDE_EFFECTS)
@@ -2635,7 +2636,8 @@ value_struct_elt_for_reference (struct t
else
{
result = allocate_value (lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j)));
- cplus_make_method_ptr (value_contents_writeable (result),
+ cplus_make_method_ptr (value_type (result),
+ value_contents_writeable (result),
VALUE_ADDRESS (v), 0);
}
}