/* Cast one pointer or reference type to another. Both TYPE and
the type of ARG2 should be pointer types, or else both should be
- reference types. Returns the new pointer or reference. */
+ reference types. If SUBCLASS_CHECK is non-zero, this will force a
+ check to see whether TYPE is a superclass of ARG2's type. If
+ SUBCLASS_CHECK is zero, then the subclass check is done only when
+ ARG2 is itself non-zero. Returns the new pointer or reference. */
struct value *
-value_cast_pointers (struct type *type, struct value *arg2)
+value_cast_pointers (struct type *type, struct value *arg2,
+ int subclass_check)
{
struct type *type1 = check_typedef (type);
struct type *type2 = check_typedef (value_type (arg2));
if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
&& TYPE_CODE (t2) == TYPE_CODE_STRUCT
- && !value_logical_not (arg2))
+ && (subclass_check || !value_logical_not (arg2)))
{
struct value *v2;
else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
{
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
- return value_cast_pointers (type, arg2);
+ return value_cast_pointers (type, arg2, 0);
arg2 = value_copy (arg2);
deprecated_set_value_type (arg2, type);
dest_buffer = value_contents (fromval);
}
- write_memory (changed_addr, dest_buffer, changed_len);
- observer_notify_memory_changed (changed_addr, changed_len,
- dest_buffer);
+ write_memory_with_notification (changed_addr, dest_buffer, changed_len);
}
break;
(value_as_address (arg1)
- value_pointed_to_offset (arg1)));
- /* Re-adjust type. */
- deprecated_set_value_type (arg2, TYPE_TARGET_TYPE (base_type));
- /* Add embedding info. */
- set_value_enclosing_type (arg2, enc_type);
- set_value_embedded_offset (arg2, value_pointed_to_offset (arg1));
-
- /* We may be pointing to an object of some derived type. */
- arg2 = value_full_object (arg2, NULL, 0, 0, 0);
- return arg2;
+ return readjust_indirect_value_type (arg2, enc_type, base_type, arg1);
}
error (_("Attempt to take contents of a non-pointer value."));
return i + 1;
}
-/* Helper function used by value_struct_elt to recurse through
- baseclasses. Look for a field NAME in ARG1. Adjust the address of
- ARG1 by OFFSET bytes, and search in it assuming it has (class) type
- TYPE. If found, return value, else return NULL.
+/* Helper class for do_search_struct_field that updates *RESULT_PTR
+ and *LAST_BOFFSET, and possibly throws an exception if the field
+ search has yielded ambiguous results. */
- If LOOKING_FOR_BASECLASS, then instead of looking for struct
- fields, look for a baseclass named NAME. */
+static void
+update_search_result (struct value **result_ptr, struct value *v,
+ int *last_boffset, int boffset,
+ const char *name, struct type *type)
+{
+ if (v != NULL)
+ {
+ if (*result_ptr != NULL
+ /* The result is not ambiguous if all the classes that are
+ found occupy the same space. */
+ && *last_boffset != boffset)
+ error (_("base class '%s' is ambiguous in type '%s'"),
+ name, TYPE_SAFE_NAME (type));
+ *result_ptr = v;
+ *last_boffset = boffset;
+ }
+}
-static struct value *
-search_struct_field (const char *name, struct value *arg1, int offset,
- struct type *type, int looking_for_baseclass)
+/* A helper for search_struct_field. This does all the work; most
+ arguments are as passed to search_struct_field. The result is
+ stored in *RESULT_PTR, which must be initialized to NULL.
+ OUTERMOST_TYPE is the type of the initial type passed to
+ search_struct_field; this is used for error reporting when the
+ lookup is ambiguous. */
+
+static void
+do_search_struct_field (const char *name, struct value *arg1, int offset,
+ struct type *type, int looking_for_baseclass,
+ struct value **result_ptr,
+ int *last_boffset,
+ struct type *outermost_type)
{
int i;
int nbases;
name);
}
else
- {
- v = value_primitive_field (arg1, offset, i, type);
- if (v == 0)
- error (_("there is no field named %s"), name);
- }
- return v;
+ v = value_primitive_field (arg1, offset, i, type);
+ *result_ptr = v;
+ return;
}
if (t_field_name
represented as a struct, with a member for each
<variant field>. */
- struct value *v;
+ struct value *v = NULL;
int new_offset = offset;
/* This is pretty gross. In G++, the offset in an
&& TYPE_FIELD_BITPOS (field_type, 0) == 0))
new_offset += TYPE_FIELD_BITPOS (type, i) / 8;
- v = search_struct_field (name, arg1, new_offset,
- field_type,
- looking_for_baseclass);
+ do_search_struct_field (name, arg1, new_offset,
+ field_type,
+ looking_for_baseclass, &v,
+ last_boffset,
+ outermost_type);
if (v)
- return v;
+ {
+ *result_ptr = v;
+ return;
+ }
}
}
}
for (i = 0; i < nbases; i++)
{
- struct value *v;
+ struct value *v = NULL;
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
/* If we are looking for baseclasses, this is what we get when
we hit them. But it could happen that the base part's member
&& (strcmp_iw (name,
TYPE_BASECLASS_NAME (type,
i)) == 0));
+ int boffset = value_embedded_offset (arg1) + offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
- int boffset;
struct value *v2;
boffset = baseclass_offset (type, i,
}
if (found_baseclass)
- return v2;
- v = search_struct_field (name, v2, 0,
- TYPE_BASECLASS (type, i),
- looking_for_baseclass);
+ v = v2;
+ else
+ {
+ do_search_struct_field (name, v2, 0,
+ TYPE_BASECLASS (type, i),
+ looking_for_baseclass,
+ result_ptr, last_boffset,
+ outermost_type);
+ }
}
else if (found_baseclass)
v = value_primitive_field (arg1, offset, i, type);
else
- v = search_struct_field (name, arg1,
- offset + TYPE_BASECLASS_BITPOS (type,
- i) / 8,
- basetype, looking_for_baseclass);
- if (v)
- return v;
+ {
+ do_search_struct_field (name, arg1,
+ offset + TYPE_BASECLASS_BITPOS (type,
+ i) / 8,
+ basetype, looking_for_baseclass,
+ result_ptr, last_boffset,
+ outermost_type);
+ }
+
+ update_search_result (result_ptr, v, last_boffset,
+ boffset, name, outermost_type);
}
- return NULL;
+}
+
+/* Helper function used by value_struct_elt to recurse through
+ baseclasses. Look for a field NAME in ARG1. Adjust the address of
+ ARG1 by OFFSET bytes, and search in it assuming it has (class) type
+ TYPE. If found, return value, else return NULL.
+
+ If LOOKING_FOR_BASECLASS, then instead of looking for struct
+ fields, look for a baseclass named NAME. */
+
+static struct value *
+search_struct_field (const char *name, struct value *arg1, int offset,
+ struct type *type, int looking_for_baseclass)
+{
+ struct value *result = NULL;
+ int boffset = 0;
+
+ do_search_struct_field (name, arg1, offset, type, looking_for_baseclass,
+ &result, &boffset, type);
+ return result;
}
/* Helper function used by value_struct_elt to recurse through
method.
BOFFSET is the offset of the base subobject which defines the method. */
-struct fn_field *
+static struct fn_field *
value_find_oload_method_list (struct value **argp, const char *method,
int offset, int *num_fns,
struct type **basetype, int *boffset)
and non member function, the first argument must now be
dereferenced. */
if (method == BOTH)
- deprecated_set_value_type (args[0],
- TYPE_TARGET_TYPE (value_type (args[0])));
+ args[0] = value_ind (args[0]);
if (fsym)
{
return result;
}
-/* Given a pointer value V, find the real (RTTI) type of the object it
- points to.
+/* Given a pointer or a reference value V, find its real (RTTI) type.
Other parameters FULL, TOP, USING_ENC as with value_rtti_type()
and refer to the values computed for the object pointed to. */
struct type *
-value_rtti_target_type (struct value *v, int *full,
- int *top, int *using_enc)
+value_rtti_indirect_type (struct value *v, int *full,
+ int *top, int *using_enc)
{
struct value *target;
+ struct type *type, *real_type, *target_type;
- target = value_ind (v);
+ type = value_type (v);
+ type = check_typedef (type);
+ if (TYPE_CODE (type) == TYPE_CODE_REF)
+ target = coerce_ref (v);
+ else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ target = value_ind (v);
+ else
+ return NULL;
+
+ real_type = value_rtti_type (target, full, top, using_enc);
+
+ if (real_type)
+ {
+ /* Copy qualifiers to the referenced object. */
+ target_type = value_type (target);
+ real_type = make_cv_type (TYPE_CONST (target_type),
+ TYPE_VOLATILE (target_type), real_type, NULL);
+ if (TYPE_CODE (type) == TYPE_CODE_REF)
+ real_type = lookup_reference_type (real_type);
+ else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ real_type = lookup_pointer_type (real_type);
+ else
+ internal_error (__FILE__, __LINE__, _("Unexpected value type."));
+
+ /* Copy qualifiers to the pointer/reference. */
+ real_type = make_cv_type (TYPE_CONST (type), TYPE_VOLATILE (type),
+ real_type, NULL);
+ }
- return value_rtti_type (target, full, top, using_enc);
+ return real_type;
}
/* Given a value pointed to by ARGP, check its real run-time type, and