Turn various value copying-related functions into methods

This patch turns a grab bag of value functions to methods of value.
These are done together because their implementations are
interrelated.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit is contained in:
Tom Tromey
2023-02-01 07:27:50 -07:00
parent e3fb3c4772
commit 6c49729e59
16 changed files with 193 additions and 197 deletions

View File

@ -1799,7 +1799,7 @@ pass_in_v_vfp_candidate (struct gdbarch *gdbarch, struct regcache *regcache,
if (field_is_static (&arg_type->field (i))) if (field_is_static (&arg_type->field (i)))
continue; continue;
struct value *field = value_primitive_field (arg, 0, i, arg_type); struct value *field = arg->primitive_field (0, i, arg_type);
struct type *field_type = check_typedef (field->type ()); struct type *field_type = check_typedef (field->type ());
if (!pass_in_v_vfp_candidate (gdbarch, regcache, info, field_type, if (!pass_in_v_vfp_candidate (gdbarch, regcache, info, field_type,

View File

@ -565,7 +565,7 @@ coerce_unspec_val_to_type (struct value *val, struct type *type)
else else
{ {
result = value::allocate (type); result = value::allocate (type);
value_contents_copy (result, 0, val, 0, type->length ()); val->contents_copy (result, 0, 0, type->length ());
} }
result->set_component_location (val); result->set_component_location (val);
result->set_bitsize (val->bitsize ()); result->set_bitsize (val->bitsize ());
@ -6929,7 +6929,7 @@ ada_value_primitive_field (struct value *arg1, int offset, int fieldno,
bit_pos % 8, bit_size, type); bit_pos % 8, bit_size, type);
} }
else else
return value_primitive_field (arg1, offset, fieldno, arg_type); return arg1->primitive_field (offset, fieldno, arg_type);
} }
/* Find field with name NAME in object of type TYPE. If found, /* Find field with name NAME in object of type TYPE. If found,

View File

@ -1866,12 +1866,11 @@ extract_bitfield_from_watchpoint_value (struct watchpoint *w, struct value *val)
bit_val = value::allocate (val->type ()); bit_val = value::allocate (val->type ());
unpack_value_bitfield (bit_val, val->unpack_bitfield (bit_val,
w->val_bitpos, w->val_bitpos,
w->val_bitsize, w->val_bitsize,
val->contents_for_printing ().data (), val->contents_for_printing ().data (),
val->offset (), val->offset ());
val);
return bit_val; return bit_val;
} }

View File

@ -257,7 +257,7 @@ value_struct_element_index (struct value *value, int type_index)
if (field_is_static (&type->field (type_index))) if (field_is_static (&type->field (type_index)))
result = value_static_field (type, type_index); result = value_static_field (type, type_index);
else else
result = value_primitive_field (value, 0, type_index, type); result = value->primitive_field (0, type_index, type);
} }
catch (const gdb_exception_error &e) catch (const gdb_exception_error &e)
{ {

View File

@ -330,7 +330,7 @@ cp_print_value_fields (struct value *val, struct ui_file *stream,
} }
else else
{ {
struct value *v = value_primitive_field (val, 0, i, type); struct value *v = val->primitive_field (0, i, type);
opts->deref_ref = false; opts->deref_ref = false;
common_val_print (v, stream, recurse + 1, opts, common_val_print (v, stream, recurse + 1, opts,
current_language); current_language);
@ -498,8 +498,8 @@ cp_print_value (struct value *val, struct ui_file *stream,
if (!val_print_check_max_depth (stream, recurse, options, if (!val_print_check_max_depth (stream, recurse, options,
current_language)) current_language))
{ {
struct value *baseclass_val = value_primitive_field (val, 0, struct value *baseclass_val = val->primitive_field (0,
i, type); i, type);
/* Attempt to run an extension language pretty-printer on the /* Attempt to run an extension language pretty-printer on the
baseclass if possible. */ baseclass if possible. */

View File

@ -969,8 +969,8 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
generic optimized out value instead, so that we show generic optimized out value instead, so that we show
<optimized out> instead of <not saved>. */ <optimized out> instead of <not saved>. */
value *tmp = value::allocate (subobj_type); value *tmp = value::allocate (subobj_type);
value_contents_copy (tmp, 0, retval, 0, retval->contents_copy (tmp, 0, 0,
subobj_type->length ()); subobj_type->length ());
retval = tmp; retval = tmp;
} }
} }

View File

@ -2570,7 +2570,7 @@ unop_extract_operation::evaluate (struct type *expect_type,
error (_("length type is larger than the value type")); error (_("length type is larger than the value type"));
struct value *result = value::allocate (type); struct value *result = value::allocate (type);
value_contents_copy (result, 0, old_value, 0, type->length ()); old_value->contents_copy (result, 0, 0, type->length ());
return result; return result;
} }

View File

@ -159,7 +159,7 @@ fortran_bounds_all_dims (bool lbound_p,
gdb_assert (dst_offset + v->type ()->length () gdb_assert (dst_offset + v->type ()->length ()
<= result->type ()->length ()); <= result->type ()->length ());
gdb_assert (v->type ()->length () == elm_len); gdb_assert (v->type ()->length () == elm_len);
value_contents_copy (result, dst_offset, v, 0, elm_len); v->contents_copy (result, dst_offset, 0, elm_len);
/* Peel another dimension of the array. */ /* Peel another dimension of the array. */
array_type = array_type->target_type (); array_type = array_type->target_type ();
@ -282,8 +282,8 @@ protected:
available offset. */ available offset. */
void copy_element_to_dest (struct value *elt) void copy_element_to_dest (struct value *elt)
{ {
value_contents_copy (m_dest, m_dest_offset, elt, 0, elt->contents_copy (m_dest, m_dest_offset, 0,
elt->type ()->length ()); elt->type ()->length ());
m_dest_offset += elt->type ()->length (); m_dest_offset += elt->type ()->length ();
} }
@ -744,7 +744,7 @@ fortran_array_shape (struct gdbarch *gdbarch, const language_defn *lang,
gdb_assert (dst_offset + v->type ()->length () gdb_assert (dst_offset + v->type ()->length ()
<= result->type ()->length ()); <= result->type ()->length ());
gdb_assert (v->type ()->length () == elm_len); gdb_assert (v->type ()->length () == elm_len);
value_contents_copy (result, dst_offset, v, 0, elm_len); v->contents_copy (result, dst_offset, 0, elm_len);
/* Peel another dimension of the array. */ /* Peel another dimension of the array. */
val_type = val_type->target_type (); val_type = val_type->target_type ();

View File

@ -866,7 +866,7 @@ read_frame_register_value (struct value *value, frame_info_ptr frame)
if (reg_len > len) if (reg_len > len)
reg_len = len; reg_len = len;
value_contents_copy (value, offset, regval, reg_offset, reg_len); regval->contents_copy (value, offset, reg_offset, reg_len);
offset += reg_len; offset += reg_len;
len -= reg_len; len -= reg_len;

View File

@ -127,7 +127,7 @@ gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
/* The virtual function table is now an array of structures /* The virtual function table is now an array of structures
which have the form { int16 offset, delta; void *pfn; }. */ which have the form { int16 offset, delta; void *pfn; }. */
vtbl = value_primitive_field (arg1, 0, context_vptr_fieldno, vtbl = arg1->primitive_field (0, context_vptr_fieldno,
context_vptr_basetype); context_vptr_basetype);
/* With older versions of g++, the vtbl field pointed to an array /* With older versions of g++, the vtbl field pointed to an array

View File

@ -654,8 +654,8 @@ pascal_object_print_value_fields (struct value *val, struct ui_file *stream,
opts.deref_ref = false; opts.deref_ref = false;
struct value *v = value_primitive_field (val, 0, i, struct value *v = val->primitive_field (0, i,
val->type ()); val->type ());
common_val_print (v, stream, recurse + 1, &opts, common_val_print (v, stream, recurse + 1, &opts,
current_language); current_language);
} }
@ -729,7 +729,7 @@ pascal_object_print_value (struct value *val, struct ui_file *stream,
struct value *base_value; struct value *base_value;
try try
{ {
base_value = value_primitive_field (val, 0, i, type); base_value = val->primitive_field (0, i, type);
} }
catch (const gdb_exception_error &ex) catch (const gdb_exception_error &ex)
{ {

View File

@ -1382,7 +1382,7 @@ rust_struct_anon::evaluate (struct type *expect_type,
field_number, type->name ()); field_number, type->name ());
int fieldno = rust_enum_variant (type); int fieldno = rust_enum_variant (type);
lhs = value_primitive_field (lhs, 0, fieldno, type); lhs = lhs->primitive_field (0, fieldno, type);
outer_type = type; outer_type = type;
type = lhs->type (); type = lhs->type ();
} }
@ -1418,7 +1418,7 @@ rust_struct_anon::evaluate (struct type *expect_type,
field_number, type->name ()); field_number, type->name ());
} }
return value_primitive_field (lhs, 0, field_number, type); return lhs->primitive_field (0, field_number, type);
} }
else else
error(_("Anonymous field access is only allowed on tuples, \ error(_("Anonymous field access is only allowed on tuples, \
@ -1445,7 +1445,7 @@ rust_structop::evaluate (struct type *expect_type,
field_name, type->name ()); field_name, type->name ());
int fieldno = rust_enum_variant (type); int fieldno = rust_enum_variant (type);
lhs = value_primitive_field (lhs, 0, fieldno, type); lhs = lhs->primitive_field (0, fieldno, type);
struct type *outer_type = type; struct type *outer_type = type;
type = lhs->type (); type = lhs->type ();

View File

@ -1726,8 +1726,7 @@ value_array (int lowbound, int highbound, struct value **elemvec)
{ {
val = value::allocate (arraytype); val = value::allocate (arraytype);
for (idx = 0; idx < nelem; idx++) for (idx = 0; idx < nelem; idx++)
value_contents_copy (val, idx * typelength, elemvec[idx], 0, elemvec[idx]->contents_copy (val, idx * typelength, 0, typelength);
typelength);
return val; return val;
} }
@ -1736,7 +1735,7 @@ value_array (int lowbound, int highbound, struct value **elemvec)
val = value::allocate (arraytype); val = value::allocate (arraytype);
for (idx = 0; idx < nelem; idx++) for (idx = 0; idx < nelem; idx++)
value_contents_copy (val, idx * typelength, elemvec[idx], 0, typelength); elemvec[idx]->contents_copy (val, idx * typelength, 0, typelength);
return val; return val;
} }
@ -2022,7 +2021,7 @@ struct_field_searcher::search (struct value *arg1, LONGEST offset,
if (field_is_static (&type->field (i))) if (field_is_static (&type->field (i)))
v = value_static_field (type, i); v = value_static_field (type, i);
else else
v = value_primitive_field (arg1, offset, i, type); v = arg1->primitive_field (offset, i, type);
update_result (v, offset); update_result (v, offset);
return; return;
@ -2118,7 +2117,7 @@ struct_field_searcher::search (struct value *arg1, LONGEST offset,
search (v2, 0, TYPE_BASECLASS (type, i)); search (v2, 0, TYPE_BASECLASS (type, i));
} }
else if (found_baseclass) else if (found_baseclass)
v = value_primitive_field (arg1, offset, i, type); v = arg1->primitive_field (offset, i, type);
else else
{ {
search (arg1, offset + TYPE_BASECLASS_BITPOS (type, i) / 8, search (arg1, offset + TYPE_BASECLASS_BITPOS (type, i) / 8,
@ -2467,7 +2466,7 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
if (!field_is_static (&t->field (i)) if (!field_is_static (&t->field (i))
&& bitpos == t->field (i).loc_bitpos () && bitpos == t->field (i).loc_bitpos ()
&& types_equal (ftype, t->field (i).type ())) && types_equal (ftype, t->field (i).type ()))
return value_primitive_field (*argp, 0, i, t); return (*argp)->primitive_field (0, i, t);
} }
error (_("No field with matching bitpos and type.")); error (_("No field with matching bitpos and type."));
@ -4083,8 +4082,8 @@ value_slice (struct value *array, int lowbound, int length)
else else
{ {
slice = value::allocate (slice_type); slice = value::allocate (slice_type);
value_contents_copy (slice, 0, array, offset, array->contents_copy (slice, 0, offset,
type_length_units (slice_type)); type_length_units (slice_type));
} }
slice->set_component_location (array); slice->set_component_location (array);

View File

@ -2007,9 +2007,9 @@ value_print_array_elements (struct value *val, struct ui_file *stream,
maybe_print_array_index (index_type, i + low_bound, maybe_print_array_index (index_type, i + low_bound,
stream, options); stream, options);
struct value *element = value_from_component_bitsize (val, elttype, struct value *element = val->from_component_bitsize (elttype,
bit_stride * i, bit_stride * i,
bit_stride); bit_stride);
rep1 = i + 1; rep1 = i + 1;
reps = 1; reps = 1;
/* Only check for reps if repeat_count_threshold is not set to /* Only check for reps if repeat_count_threshold is not set to
@ -2022,9 +2022,9 @@ value_print_array_elements (struct value *val, struct ui_file *stream,
while (rep1 < len) while (rep1 < len)
{ {
struct value *rep_elt struct value *rep_elt
= value_from_component_bitsize (val, elttype, = val->from_component_bitsize (elttype,
rep1 * bit_stride, rep1 * bit_stride,
bit_stride); bit_stride);
bool repeated = ((available bool repeated = ((available
&& rep_elt->entirely_available () && rep_elt->entirely_available ()
&& element->contents_eq (rep_elt)) && element->contents_eq (rep_elt))

View File

@ -1138,45 +1138,34 @@ ranges_copy_adjusted (std::vector<range> *dst_range, int dst_bit_offset,
} }
} }
/* Copy the ranges metadata in SRC that overlaps [SRC_BIT_OFFSET, /* See value.h. */
SRC_BIT_OFFSET+BIT_LENGTH) into DST, adjusted. */
static void void
value_ranges_copy_adjusted (struct value *dst, int dst_bit_offset, value::ranges_copy_adjusted (struct value *dst, int dst_bit_offset,
const struct value *src, int src_bit_offset, int src_bit_offset, int bit_length) const
int bit_length)
{ {
ranges_copy_adjusted (&dst->m_unavailable, dst_bit_offset, ::ranges_copy_adjusted (&dst->m_unavailable, dst_bit_offset,
src->m_unavailable, src_bit_offset, m_unavailable, src_bit_offset,
bit_length); bit_length);
ranges_copy_adjusted (&dst->m_optimized_out, dst_bit_offset, ::ranges_copy_adjusted (&dst->m_optimized_out, dst_bit_offset,
src->m_optimized_out, src_bit_offset, m_optimized_out, src_bit_offset,
bit_length); bit_length);
} }
/* Copy LENGTH target addressable memory units of SRC value's (all) contents /* See value.h. */
(value_contents_all) starting at SRC_OFFSET, into DST value's (all)
contents, starting at DST_OFFSET. If unavailable contents are
being copied from SRC, the corresponding DST contents are marked
unavailable accordingly. Neither DST nor SRC may be lazy
values.
It is assumed the contents of DST in the [DST_OFFSET, void
DST_OFFSET+LENGTH) range are wholly available. */ value::contents_copy_raw (struct value *dst, LONGEST dst_offset,
LONGEST src_offset, LONGEST length)
static void
value_contents_copy_raw (struct value *dst, LONGEST dst_offset,
struct value *src, LONGEST src_offset, LONGEST length)
{ {
LONGEST src_bit_offset, dst_bit_offset, bit_length; LONGEST src_bit_offset, dst_bit_offset, bit_length;
struct gdbarch *arch = src->arch (); int unit_size = gdbarch_addressable_memory_unit_size (arch ());
int unit_size = gdbarch_addressable_memory_unit_size (arch);
/* A lazy DST would make that this copy operation useless, since as /* A lazy DST would make that this copy operation useless, since as
soon as DST's contents were un-lazied (by a later value_contents soon as DST's contents were un-lazied (by a later value_contents
call, say), the contents would be overwritten. A lazy SRC would call, say), the contents would be overwritten. A lazy SRC would
mean we'd be copying garbage. */ mean we'd be copying garbage. */
gdb_assert (!dst->m_lazy && !src->m_lazy); gdb_assert (!dst->m_lazy && !m_lazy);
/* The overwritten DST range gets unavailability ORed in, not /* The overwritten DST range gets unavailability ORed in, not
replaced. Make sure to remember to implement replacing if it replaced. Make sure to remember to implement replacing if it
@ -1190,8 +1179,8 @@ value_contents_copy_raw (struct value *dst, LONGEST dst_offset,
= dst->contents_all_raw ().slice (dst_offset * unit_size, = dst->contents_all_raw ().slice (dst_offset * unit_size,
length * unit_size); length * unit_size);
gdb::array_view<const gdb_byte> src_contents gdb::array_view<const gdb_byte> src_contents
= src->contents_all_raw ().slice (src_offset * unit_size, = contents_all_raw ().slice (src_offset * unit_size,
length * unit_size); length * unit_size);
gdb::copy (src_contents, dst_contents); gdb::copy (src_contents, dst_contents);
/* Copy the meta-data, adjusted. */ /* Copy the meta-data, adjusted. */
@ -1199,24 +1188,22 @@ value_contents_copy_raw (struct value *dst, LONGEST dst_offset,
dst_bit_offset = dst_offset * unit_size * HOST_CHAR_BIT; dst_bit_offset = dst_offset * unit_size * HOST_CHAR_BIT;
bit_length = length * unit_size * HOST_CHAR_BIT; bit_length = length * unit_size * HOST_CHAR_BIT;
value_ranges_copy_adjusted (dst, dst_bit_offset, ranges_copy_adjusted (dst, dst_bit_offset,
src, src_bit_offset, src_bit_offset, bit_length);
bit_length);
} }
/* A helper for value_from_component_bitsize that copies bits from SRC /* See value.h. */
to DEST. */
static void void
value_contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset, value::contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset,
struct value *src, LONGEST src_bit_offset, LONGEST src_bit_offset,
LONGEST bit_length) LONGEST bit_length)
{ {
/* A lazy DST would make that this copy operation useless, since as /* A lazy DST would make that this copy operation useless, since as
soon as DST's contents were un-lazied (by a later value_contents soon as DST's contents were un-lazied (by a later value_contents
call, say), the contents would be overwritten. A lazy SRC would call, say), the contents would be overwritten. A lazy SRC would
mean we'd be copying garbage. */ mean we'd be copying garbage. */
gdb_assert (!dst->m_lazy && !src->m_lazy); gdb_assert (!dst->m_lazy && !m_lazy);
/* The overwritten DST range gets unavailability ORed in, not /* The overwritten DST range gets unavailability ORed in, not
replaced. Make sure to remember to implement replacing if it replaced. Make sure to remember to implement replacing if it
@ -1229,36 +1216,26 @@ value_contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset,
/* Copy the data. */ /* Copy the data. */
gdb::array_view<gdb_byte> dst_contents = dst->contents_all_raw (); gdb::array_view<gdb_byte> dst_contents = dst->contents_all_raw ();
gdb::array_view<const gdb_byte> src_contents = src->contents_all_raw (); gdb::array_view<const gdb_byte> src_contents = contents_all_raw ();
copy_bitwise (dst_contents.data (), dst_bit_offset, copy_bitwise (dst_contents.data (), dst_bit_offset,
src_contents.data (), src_bit_offset, src_contents.data (), src_bit_offset,
bit_length, bit_length,
type_byte_order (src->type ()) == BFD_ENDIAN_BIG); type_byte_order (type ()) == BFD_ENDIAN_BIG);
/* Copy the meta-data. */ /* Copy the meta-data. */
value_ranges_copy_adjusted (dst, dst_bit_offset, ranges_copy_adjusted (dst, dst_bit_offset, src_bit_offset, bit_length);
src, src_bit_offset,
bit_length);
} }
/* Copy LENGTH bytes of SRC value's (all) contents /* See value.h. */
(value_contents_all) starting at SRC_OFFSET byte, into DST value's
(all) contents, starting at DST_OFFSET. If unavailable contents
are being copied from SRC, the corresponding DST contents are
marked unavailable accordingly. DST must not be lazy. If SRC is
lazy, it will be fetched now.
It is assumed the contents of DST in the [DST_OFFSET,
DST_OFFSET+LENGTH) range are wholly available. */
void void
value_contents_copy (struct value *dst, LONGEST dst_offset, value::contents_copy (struct value *dst, LONGEST dst_offset,
struct value *src, LONGEST src_offset, LONGEST length) LONGEST src_offset, LONGEST length)
{ {
if (src->m_lazy) if (m_lazy)
src->fetch_lazy (); fetch_lazy ();
value_contents_copy_raw (dst, dst_offset, src, src_offset, length); contents_copy_raw (dst, dst_offset, src_offset, length);
} }
gdb::array_view<const gdb_byte> gdb::array_view<const gdb_byte>
@ -2859,19 +2836,14 @@ value::set_enclosing_type (struct type *new_encl_type)
m_enclosing_type = new_encl_type; m_enclosing_type = new_encl_type;
} }
/* Given a value ARG1 (offset by OFFSET bytes) /* See value.h. */
of a struct or union type ARG_TYPE,
extract and return the value of one of its (non-static) fields.
FIELDNO says which field. */
struct value * struct value *
value_primitive_field (struct value *arg1, LONGEST offset, value::primitive_field (LONGEST offset, int fieldno, struct type *arg_type)
int fieldno, struct type *arg_type)
{ {
struct value *v; struct value *v;
struct type *type; struct type *type;
struct gdbarch *arch = arg1->arch (); int unit_size = gdbarch_addressable_memory_unit_size (arch ());
int unit_size = gdbarch_addressable_memory_unit_size (arch);
arg_type = check_typedef (arg_type); arg_type = check_typedef (arg_type);
type = arg_type->field (fieldno).type (); type = arg_type->field (fieldno).type ();
@ -2905,11 +2877,11 @@ value_primitive_field (struct value *arg1, LONGEST offset,
v->set_bitpos (bitpos % container_bitsize); v->set_bitpos (bitpos % container_bitsize);
else else
v->set_bitpos (bitpos % 8); v->set_bitpos (bitpos % 8);
v->set_offset ((arg1->embedded_offset () v->set_offset ((embedded_offset ()
+ offset + offset
+ (bitpos - v->bitpos ()) / 8)); + (bitpos - v->bitpos ()) / 8));
v->set_parent (arg1); v->set_parent (this);
if (!arg1->lazy ()) if (!lazy ())
v->fetch_lazy (); v->fetch_lazy ();
} }
else if (fieldno < TYPE_N_BASECLASSES (arg_type)) else if (fieldno < TYPE_N_BASECLASSES (arg_type))
@ -2920,32 +2892,31 @@ value_primitive_field (struct value *arg1, LONGEST offset,
LONGEST boffset; LONGEST boffset;
/* Lazy register values with offsets are not supported. */ /* Lazy register values with offsets are not supported. */
if (VALUE_LVAL (arg1) == lval_register && arg1->lazy ()) if (VALUE_LVAL (this) == lval_register && lazy ())
arg1->fetch_lazy (); fetch_lazy ();
/* We special case virtual inheritance here because this /* We special case virtual inheritance here because this
requires access to the contents, which we would rather avoid requires access to the contents, which we would rather avoid
for references to ordinary fields of unavailable values. */ for references to ordinary fields of unavailable values. */
if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno)) if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno))
boffset = baseclass_offset (arg_type, fieldno, boffset = baseclass_offset (arg_type, fieldno,
arg1->contents ().data (), contents ().data (),
arg1->embedded_offset (), embedded_offset (),
arg1->address (), address (),
arg1); this);
else else
boffset = arg_type->field (fieldno).loc_bitpos () / 8; boffset = arg_type->field (fieldno).loc_bitpos () / 8;
if (arg1->lazy ()) if (lazy ())
v = value::allocate_lazy (arg1->enclosing_type ()); v = value::allocate_lazy (enclosing_type ());
else else
{ {
v = value::allocate (arg1->enclosing_type ()); v = value::allocate (enclosing_type ());
value_contents_copy_raw (v, 0, arg1, 0, contents_copy_raw (v, 0, 0, enclosing_type ()->length ());
arg1->enclosing_type ()->length ());
} }
v->deprecated_set_type (type); v->deprecated_set_type (type);
v->set_offset (arg1->offset ()); v->set_offset (this->offset ());
v->set_embedded_offset (offset + arg1->embedded_offset () + boffset); v->set_embedded_offset (offset + embedded_offset () + boffset);
} }
else if (NULL != TYPE_DATA_LOCATION (type)) else if (NULL != TYPE_DATA_LOCATION (type))
{ {
@ -2965,22 +2936,21 @@ value_primitive_field (struct value *arg1, LONGEST offset,
/ (HOST_CHAR_BIT * unit_size)); / (HOST_CHAR_BIT * unit_size));
/* Lazy register values with offsets are not supported. */ /* Lazy register values with offsets are not supported. */
if (VALUE_LVAL (arg1) == lval_register && arg1->lazy ()) if (VALUE_LVAL (this) == lval_register && lazy ())
arg1->fetch_lazy (); fetch_lazy ();
if (arg1->lazy ()) if (lazy ())
v = value::allocate_lazy (type); v = value::allocate_lazy (type);
else else
{ {
v = value::allocate (type); v = value::allocate (type);
value_contents_copy_raw (v, v->embedded_offset (), contents_copy_raw (v, v->embedded_offset (),
arg1, arg1->embedded_offset () + offset, embedded_offset () + offset,
type_length_units (type)); type_length_units (type));
} }
v->set_offset ((arg1->offset () + offset v->set_offset (this->offset () + offset + embedded_offset ());
+ arg1->embedded_offset ()));
} }
v->set_component_location (arg1); v->set_component_location (this);
return v; return v;
} }
@ -2991,7 +2961,7 @@ value_primitive_field (struct value *arg1, LONGEST offset,
struct value * struct value *
value_field (struct value *arg1, int fieldno) value_field (struct value *arg1, int fieldno)
{ {
return value_primitive_field (arg1, 0, fieldno, arg1->type ()); return arg1->primitive_field (0, fieldno, arg1->type ());
} }
/* Return a non-virtual function as a value. /* Return a non-virtual function as a value.
@ -3149,19 +3119,13 @@ unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize); return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize);
} }
/* Unpack a bitfield of BITSIZE bits found at BITPOS in the object at /* See value.h. */
VALADDR + EMBEDDEDOFFSET that has the type of DEST_VAL and store
the contents in DEST_VAL, zero or sign extending if the type of
DEST_VAL is wider than BITSIZE. VALADDR points to the contents of
VAL. If the VAL's contents required to extract the bitfield from
are unavailable/optimized out, DEST_VAL is correspondingly
marked unavailable/optimized out. */
void void
unpack_value_bitfield (struct value *dest_val, value::unpack_bitfield (struct value *dest_val,
LONGEST bitpos, LONGEST bitsize, LONGEST bitpos, LONGEST bitsize,
const gdb_byte *valaddr, LONGEST embedded_offset, const gdb_byte *valaddr, LONGEST embedded_offset)
const struct value *val) const
{ {
enum bfd_endian byte_order; enum bfd_endian byte_order;
int src_bit_offset; int src_bit_offset;
@ -3192,8 +3156,7 @@ unpack_value_bitfield (struct value *dest_val,
dst_bit_offset = field_type->length () * TARGET_CHAR_BIT - bitsize; dst_bit_offset = field_type->length () * TARGET_CHAR_BIT - bitsize;
else else
dst_bit_offset = 0; dst_bit_offset = 0;
value_ranges_copy_adjusted (dest_val, dst_bit_offset, ranges_copy_adjusted (dest_val, dst_bit_offset, src_bit_offset, bitsize);
val, src_bit_offset, bitsize);
} }
/* Return a new value with type TYPE, which is FIELDNO field of the /* Return a new value with type TYPE, which is FIELDNO field of the
@ -3211,8 +3174,7 @@ value_field_bitfield (struct type *type, int fieldno,
int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
struct value *res_val = value::allocate (type->field (fieldno).type ()); struct value *res_val = value::allocate (type->field (fieldno).type ());
unpack_value_bitfield (res_val, bitpos, bitsize, val->unpack_bitfield (res_val, bitpos, bitsize, valaddr, embedded_offset);
valaddr, embedded_offset, val);
return res_val; return res_val;
} }
@ -3573,9 +3535,9 @@ value_from_component (struct value *whole, struct type *type, LONGEST offset)
else else
{ {
v = value::allocate (type); v = value::allocate (type);
value_contents_copy (v, v->embedded_offset (), whole->contents_copy (v, v->embedded_offset (),
whole, whole->embedded_offset () + offset, whole->embedded_offset () + offset,
type_length_units (type)); type_length_units (type));
} }
v->set_offset (whole->offset () + offset + whole->embedded_offset ()); v->set_offset (whole->offset () + offset + whole->embedded_offset ());
v->set_component_location (whole); v->set_component_location (whole);
@ -3586,10 +3548,10 @@ value_from_component (struct value *whole, struct type *type, LONGEST offset)
/* See value.h. */ /* See value.h. */
struct value * struct value *
value_from_component_bitsize (struct value *whole, struct type *type, value::from_component_bitsize (struct type *type,
LONGEST bit_offset, LONGEST bit_length) LONGEST bit_offset, LONGEST bit_length)
{ {
gdb_assert (!whole->lazy ()); gdb_assert (!lazy ());
/* Preserve lvalue-ness if possible. This is needed to avoid /* Preserve lvalue-ness if possible. This is needed to avoid
array-printing failures (including crashes) when printing Ada array-printing failures (including crashes) when printing Ada
@ -3597,7 +3559,7 @@ value_from_component_bitsize (struct value *whole, struct type *type,
if ((bit_offset % TARGET_CHAR_BIT) == 0 if ((bit_offset % TARGET_CHAR_BIT) == 0
&& (bit_length % TARGET_CHAR_BIT) == 0 && (bit_length % TARGET_CHAR_BIT) == 0
&& bit_length == TARGET_CHAR_BIT * type->length ()) && bit_length == TARGET_CHAR_BIT * type->length ())
return value_from_component (whole, type, bit_offset / TARGET_CHAR_BIT); return value_from_component (this, type, bit_offset / TARGET_CHAR_BIT);
struct value *v = value::allocate (type); struct value *v = value::allocate (type);
@ -3605,12 +3567,11 @@ value_from_component_bitsize (struct value *whole, struct type *type,
if (is_scalar_type (type) && type_byte_order (type) == BFD_ENDIAN_BIG) if (is_scalar_type (type) && type_byte_order (type) == BFD_ENDIAN_BIG)
dst_offset += TARGET_CHAR_BIT * type->length () - bit_length; dst_offset += TARGET_CHAR_BIT * type->length () - bit_length;
value_contents_copy_raw_bitwise (v, dst_offset, contents_copy_raw_bitwise (v, dst_offset,
whole, TARGET_CHAR_BIT
TARGET_CHAR_BIT * embedded_offset ()
* whole->embedded_offset () + bit_offset,
+ bit_offset, bit_length);
bit_length);
return v; return v;
} }
@ -3756,9 +3717,9 @@ value::fetch_lazy_bitfield ()
if (parent->lazy ()) if (parent->lazy ())
parent->fetch_lazy (); parent->fetch_lazy ();
unpack_value_bitfield (this, bitpos (), bitsize (), parent->unpack_bitfield (this, bitpos (), bitsize (),
parent->contents_for_printing ().data (), parent->contents_for_printing ().data (),
offset (), parent); offset ());
} }
/* See value.h. */ /* See value.h. */
@ -3853,9 +3814,9 @@ value::fetch_lazy_register ()
/* Copy the contents and the unavailability/optimized-out /* Copy the contents and the unavailability/optimized-out
meta-data from NEW_VAL to VAL. */ meta-data from NEW_VAL to VAL. */
set_lazy (0); set_lazy (0);
value_contents_copy (this, embedded_offset (), new_val->contents_copy (this, embedded_offset (),
new_val, new_val->embedded_offset (), new_val->embedded_offset (),
type_length_units (type)); type_length_units (type));
if (frame_debug) if (frame_debug)
{ {

View File

@ -558,6 +558,49 @@ public:
used to prevent cycles / duplicates. */ used to prevent cycles / duplicates. */
void preserve (struct objfile *objfile, htab_t copied_types); void preserve (struct objfile *objfile, htab_t copied_types);
/* Unpack a bitfield of BITSIZE bits found at BITPOS in the object
at VALADDR + EMBEDDEDOFFSET that has the type of DEST_VAL and
store the contents in DEST_VAL, zero or sign extending if the
type of DEST_VAL is wider than BITSIZE. VALADDR points to the
contents of this value. If this value's contents required to
extract the bitfield from are unavailable/optimized out, DEST_VAL
is correspondingly marked unavailable/optimized out. */
void unpack_bitfield (struct value *dest_val,
LONGEST bitpos, LONGEST bitsize,
const gdb_byte *valaddr, LONGEST embedded_offset)
const;
/* Copy LENGTH bytes of this value's (all) contents
(value_contents_all) starting at SRC_OFFSET byte, into DST
value's (all) contents, starting at DST_OFFSET. If unavailable
contents are being copied from this value, the corresponding DST
contents are marked unavailable accordingly. DST must not be
lazy. If this value is lazy, it will be fetched now.
It is assumed the contents of DST in the [DST_OFFSET,
DST_OFFSET+LENGTH) range are wholly available. */
void contents_copy (struct value *dst, LONGEST dst_offset,
LONGEST src_offset, LONGEST length);
/* Given a value (offset by OFFSET bytes)
of a struct or union type ARG_TYPE,
extract and return the value of one of its (non-static) fields.
FIELDNO says which field. */
struct value *primitive_field (LONGEST offset, int fieldno,
struct type *arg_type);
/* Create a new value by extracting it from this value. TYPE is the
type of the new value. BIT_OFFSET and BIT_LENGTH describe the
offset and field width of the value to extract from this value --
BIT_LENGTH may differ from TYPE's length in the case where this
value's type is packed.
When the value does come from a non-byte-aligned offset or field
width, it will be marked non_lval. */
struct value *from_component_bitsize (struct type *type,
LONGEST bit_offset,
LONGEST bit_length);
/* Type of value; either not an lval, or one of the various /* Type of value; either not an lval, or one of the various
different possible kinds of lval. */ different possible kinds of lval. */
@ -781,6 +824,29 @@ private:
value is lazy, it'll be read now. Note that RANGE is a pointer value is lazy, it'll be read now. Note that RANGE is a pointer
to pointer because reading the value might change *RANGE. */ to pointer because reading the value might change *RANGE. */
int entirely_covered_by_range_vector (const std::vector<range> &ranges); int entirely_covered_by_range_vector (const std::vector<range> &ranges);
/* Copy the ranges metadata from this value that overlaps
[SRC_BIT_OFFSET, SRC_BIT_OFFSET+BIT_LENGTH) into DST,
adjusted. */
void ranges_copy_adjusted (struct value *dst, int dst_bit_offset,
int src_bit_offset, int bit_length) const;
/* Copy LENGTH target addressable memory units of this value's (all)
contents (value_contents_all) starting at SRC_OFFSET, into DST
value's (all) contents, starting at DST_OFFSET. If unavailable
contents are being copied from this, the corresponding DST
contents are marked unavailable accordingly. Neither DST nor
this value may be lazy values.
It is assumed the contents of DST in the [DST_OFFSET,
DST_OFFSET+LENGTH) range are wholly available. */
void contents_copy_raw (struct value *dst, LONGEST dst_offset,
LONGEST src_offset, LONGEST length);
/* A helper for value_from_component_bitsize that copies bits from
this value to DEST. */
void contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset,
LONGEST src_bit_offset, LONGEST bit_length);
}; };
inline void inline void
@ -995,12 +1061,6 @@ extern int unpack_value_field_as_long (struct type *type, const gdb_byte *valadd
LONGEST embedded_offset, int fieldno, LONGEST embedded_offset, int fieldno,
const struct value *val, LONGEST *result); const struct value *val, LONGEST *result);
extern void unpack_value_bitfield (struct value *dest_val,
LONGEST bitpos, LONGEST bitsize,
const gdb_byte *valaddr,
LONGEST embedded_offset,
const struct value *val);
extern struct value *value_field_bitfield (struct type *type, int fieldno, extern struct value *value_field_bitfield (struct type *type, int fieldno,
const gdb_byte *valaddr, const gdb_byte *valaddr,
LONGEST embedded_offset, LONGEST embedded_offset,
@ -1017,20 +1077,6 @@ extern struct value *value_from_component (struct value *, struct type *,
LONGEST); LONGEST);
/* Create a new value by extracting it from WHOLE. TYPE is the type
of the new value. BIT_OFFSET and BIT_LENGTH describe the offset
and field width of the value to extract from WHOLE -- BIT_LENGTH
may differ from TYPE's length in the case where WHOLE's type is
packed.
When the value does come from a non-byte-aligned offset or field
width, it will be marked non_lval. */
extern struct value *value_from_component_bitsize (struct value *whole,
struct type *type,
LONGEST bit_offset,
LONGEST bit_length);
extern struct value *value_at (struct type *type, CORE_ADDR addr); extern struct value *value_at (struct type *type, CORE_ADDR addr);
extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr); extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
@ -1082,10 +1128,6 @@ extern struct value *read_var_value (struct symbol *var,
const struct block *var_block, const struct block *var_block,
frame_info_ptr frame); frame_info_ptr frame);
extern void value_contents_copy (struct value *dst, LONGEST dst_offset,
struct value *src, LONGEST src_offset,
LONGEST length);
extern struct value *allocate_repeat_value (struct type *type, int count); extern struct value *allocate_repeat_value (struct type *type, int count);
extern struct value *value_mark (void); extern struct value *value_mark (void);
@ -1201,11 +1243,6 @@ extern int find_overload_match (gdb::array_view<value *> args,
extern struct value *value_field (struct value *arg1, int fieldno); extern struct value *value_field (struct value *arg1, int fieldno);
extern struct value *value_primitive_field (struct value *arg1, LONGEST offset,
int fieldno,
struct type *arg_type);
extern struct type *value_rtti_indirect_type (struct value *, int *, LONGEST *, extern struct type *value_rtti_indirect_type (struct value *, int *, LONGEST *,
int *); int *);