register struct type *type = VALUE_TYPE (toval);
register value val;
char raw_buffer[MAX_REGISTER_RAW_SIZE];
- char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
int use_buffer = 0;
COERCE_ARRAY (fromval);
convert FROMVAL's contents now, with result in `raw_buffer',
and set USE_BUFFER to the number of bytes to write. */
+#ifdef REGISTER_CONVERTIBLE
if (VALUE_REGNO (toval) >= 0
&& REGISTER_CONVERTIBLE (VALUE_REGNO (toval)))
{
int regno = VALUE_REGNO (toval);
- if (VALUE_TYPE (fromval) != REGISTER_VIRTUAL_TYPE (regno))
- fromval = value_cast (REGISTER_VIRTUAL_TYPE (regno), fromval);
- memcpy (virtual_buffer, VALUE_CONTENTS (fromval),
- REGISTER_VIRTUAL_SIZE (regno));
- REGISTER_CONVERT_TO_RAW (regno, virtual_buffer, raw_buffer);
- use_buffer = REGISTER_RAW_SIZE (regno);
+ if (REGISTER_CONVERTIBLE (regno))
+ {
+ REGISTER_CONVERT_TO_RAW (VALUE_TYPE (fromval), regno,
+ VALUE_CONTENTS (fromval), raw_buffer);
+ use_buffer = REGISTER_RAW_SIZE (regno);
+ }
}
+#endif
switch (VALUE_LVAL (toval))
{
case lval_memory:
if (VALUE_BITSIZE (toval))
{
- int v; /* FIXME, this won't work for large bitfields */
+ char buffer[sizeof (LONGEST)];
+ /* We assume that the argument to read_memory is in units of
+ host chars. FIXME: Is that correct? */
+ int len = (VALUE_BITPOS (toval)
+ + VALUE_BITSIZE (toval)
+ + HOST_CHAR_BIT - 1)
+ / HOST_CHAR_BIT;
+
+ if (len > sizeof (LONGEST))
+ error ("Can't handle bitfields which don't fit in a %d bit word.",
+ sizeof (LONGEST) * HOST_CHAR_BIT);
+
read_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- (char *) &v, sizeof v);
- modify_field ((char *) &v, value_as_long (fromval),
+ buffer, len);
+ modify_field (buffer, value_as_long (fromval),
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- (char *)&v, sizeof v);
+ buffer, len);
}
else if (use_buffer)
write_memory (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
case lval_register:
if (VALUE_BITSIZE (toval))
{
- int v;
-
- read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- (char *) &v, sizeof v);
- modify_field ((char *) &v, value_as_long (fromval),
- VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
- write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
- (char *) &v, sizeof v);
+ char buffer[sizeof (LONGEST)];
+ int len = REGISTER_RAW_SIZE (VALUE_REGNO (toval));
+
+ if (len > sizeof (LONGEST))
+ error ("Can't handle bitfields in registers larger than %d bits.",
+ sizeof (LONGEST) * HOST_CHAR_BIT);
+
+ if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval)
+ > len * HOST_CHAR_BIT)
+ /* Getting this right would involve being very careful about
+ byte order. */
+ error ("\
+Can't handle bitfield which doesn't fit in a single register.");
+
+ read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ buffer, len);
+ modify_field (buffer, value_as_long (fromval),
+ VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+ write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ buffer, len);
}
else if (use_buffer)
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
#endif
}
+ /* Assigning to the stack pointer, frame pointer, and other
+ (architecture and calling convention specific) registers may
+ cause the frame cache to be out of date. We just do this
+ on all assignments to registers for simplicity; I doubt the slowdown
+ matters. */
+ reinit_frame_cache ();
break;
case lval_reg_frame_relative:
int byte_offset = VALUE_OFFSET (toval) % reg_size;
int reg_offset = VALUE_OFFSET (toval) / reg_size;
int amount_copied;
- char *buffer = (char *) alloca (amount_to_copy);
+
+ /* Make the buffer large enough in all cases. */
+ char *buffer = (char *) alloca (amount_to_copy
+ + sizeof (LONGEST)
+ + MAX_REGISTER_RAW_SIZE);
+
int regno;
FRAME frame;
if (t1[!staticp] == 0) return 0;
for (i = !staticp; t1[i] && TYPE_CODE (t1[i]) != TYPE_CODE_VOID; i++)
{
+ struct type *tt1, *tt2;
if (! t2[i])
return i+1;
- if (TYPE_CODE (t1[i]) == TYPE_CODE_REF
+ tt1 = t1[i];
+ tt2 = VALUE_TYPE(t2[i]);
+ if (TYPE_CODE (tt1) == TYPE_CODE_REF
/* We should be doing hairy argument matching, as below. */
- && (TYPE_CODE (TYPE_TARGET_TYPE (t1[i]))
- == TYPE_CODE (VALUE_TYPE (t2[i]))))
+ && (TYPE_CODE (TYPE_TARGET_TYPE (tt1)) == TYPE_CODE (tt2)))
{
t2[i] = value_addr (t2[i]);
continue;
}
- if (TYPE_CODE (t1[i]) == TYPE_CODE_PTR
- && TYPE_CODE (VALUE_TYPE (t2[i])) == TYPE_CODE_ARRAY)
- /* Array to pointer is a `trivial conversion' according to the ARM. */
- continue;
+ while (TYPE_CODE (tt1) == TYPE_CODE_PTR
+ && (TYPE_CODE(tt2)==TYPE_CODE_ARRAY || TYPE_CODE(tt2)==TYPE_CODE_PTR))
+ {
+ tt1 = TYPE_TARGET_TYPE(tt1);
+ tt2 = TYPE_TARGET_TYPE(tt2);
+ }
+ if (TYPE_CODE(tt1) == TYPE_CODE(tt2)) continue;
+ /* Array to pointer is a `trivial conversion' according to the ARM. */
/* We should be doing much hairier argument matching (see section 13.2
of the ARM), but as a quick kludge, just check for the same type
register struct type *type;
{
int i;
+ value v;
static int name_matched = 0;
+ char dem_opname[64];
check_stub_type (type);
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
{
char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ if (strncmp(t_field_name, "__", 2)==0 ||
+ strncmp(t_field_name, "op", 2)==0 ||
+ strncmp(t_field_name, "type", 4)==0 )
+ {
+ if (cplus_demangle_opname(t_field_name, dem_opname, DMGL_ANSI))
+ t_field_name = dem_opname;
+ else if (cplus_demangle_opname(t_field_name, dem_opname, 0))
+ t_field_name = dem_opname;
+ }
if (t_field_name && STREQ (t_field_name, name))
{
int j = TYPE_FN_FIELDLIST_LENGTH (type, i) - 1;
return (value)value_virtual_fn_field (arg1p, f, j, type, offset);
if (TYPE_FN_FIELD_STATIC_P (f, j) && static_memfuncp)
*static_memfuncp = 1;
- return (value)value_fn_field (arg1p, f, j, type, offset);
+ v = (value)value_fn_field (arg1p, f, j, type, offset);
+ if (v != (value)NULL) return v;
}
j--;
}
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
- value v;
int base_offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
if (!args[1])
{
/* destructors are a special case. */
- return (value)value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0),
- TYPE_FN_FIELDLIST_LENGTH (t, 0),
- 0, 0);
+ v = (value)value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0),
+ TYPE_FN_FIELDLIST_LENGTH (t, 0), 0, 0);
+ if (!v) error("could not find destructor function named %s.", name);
+ else return v;
}
else
{