[v3,43/50] Turn various value copying-related functions into methods

Message ID 20230209-submit-value-fixups-2023-v3-43-45e91a20c742@tromey.com
State Committed
Commit 6c49729e593cd1577080b082be81fe113f8d7943
Headers
Series Use methods for struct value |

Commit Message

Tom Tromey Feb. 13, 2023, 3:15 a.m. UTC
  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>
---
 gdb/aarch64-tdep.c |   2 +-
 gdb/ada-lang.c     |   4 +-
 gdb/breakpoint.c   |  11 ++-
 gdb/c-varobj.c     |   2 +-
 gdb/cp-valprint.c  |   6 +-
 gdb/dwarf2/expr.c  |   4 +-
 gdb/eval.c         |   2 +-
 gdb/f-lang.c       |   8 +-
 gdb/findvar.c      |   2 +-
 gdb/gnu-v2-abi.c   |   2 +-
 gdb/p-valprint.c   |   6 +-
 gdb/rust-lang.c    |   6 +-
 gdb/valops.c       |  15 ++--
 gdb/valprint.c     |  12 +--
 gdb/value.c        | 213 ++++++++++++++++++++++-------------------------------
 gdb/value.h        |  95 ++++++++++++++++--------
 16 files changed, 193 insertions(+), 197 deletions(-)
  

Patch

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index a4f71f246c6..fa8db9c788d 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1799,7 +1799,7 @@  pass_in_v_vfp_candidate (struct gdbarch *gdbarch, struct regcache *regcache,
 	  if (field_is_static (&arg_type->field (i)))
 	    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 ());
 
 	  if (!pass_in_v_vfp_candidate (gdbarch, regcache, info, field_type,
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 37aea44b8d5..cc69281075e 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -565,7 +565,7 @@  coerce_unspec_val_to_type (struct value *val, struct type *type)
       else
 	{
 	  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_bitsize (val->bitsize ());
@@ -6929,7 +6929,7 @@  ada_value_primitive_field (struct value *arg1, int offset, int fieldno,
 					     bit_pos % 8, bit_size, type);
     }
   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, 
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 4653dbfbd74..62ef31049fa 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1866,12 +1866,11 @@  extract_bitfield_from_watchpoint_value (struct watchpoint *w, struct value *val)
 
   bit_val = value::allocate (val->type ());
 
-  unpack_value_bitfield (bit_val,
-			 w->val_bitpos,
-			 w->val_bitsize,
-			 val->contents_for_printing ().data (),
-			 val->offset (),
-			 val);
+  val->unpack_bitfield (bit_val,
+			w->val_bitpos,
+			w->val_bitsize,
+			val->contents_for_printing ().data (),
+			val->offset ());
 
   return bit_val;
 }
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index 00094244ff1..3e3919a65c0 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -257,7 +257,7 @@  value_struct_element_index (struct value *value, int type_index)
       if (field_is_static (&type->field (type_index)))
 	result = value_static_field (type, type_index);
       else
-	result = value_primitive_field (value, 0, type_index, type);
+	result = value->primitive_field (0, type_index, type);
     }
   catch (const gdb_exception_error &e)
     {
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 37147749619..167cf0314af 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -330,7 +330,7 @@  cp_print_value_fields (struct value *val, struct ui_file *stream,
 		}
 	      else
 		{
-		  struct value *v = value_primitive_field (val, 0, i, type);
+		  struct value *v = val->primitive_field (0, i, type);
 		  opts->deref_ref = false;
 		  common_val_print (v, stream, recurse + 1, opts,
 				    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,
 					  current_language))
 	    {
-	      struct value *baseclass_val = value_primitive_field (val, 0,
-								   i, type);
+	      struct value *baseclass_val = val->primitive_field (0,
+								  i, type);
 
 	      /* Attempt to run an extension language pretty-printer on the
 		 baseclass if possible.  */
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 45bdb007420..60d9bf5f1f9 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -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
 		   <optimized out> instead of <not saved>.  */
 		value *tmp = value::allocate (subobj_type);
-		value_contents_copy (tmp, 0, retval, 0,
-				     subobj_type->length ());
+		retval->contents_copy (tmp, 0, 0,
+				       subobj_type->length ());
 		retval = tmp;
 	      }
 	  }
diff --git a/gdb/eval.c b/gdb/eval.c
index b263dc998d6..2bff97227dd 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2570,7 +2570,7 @@  unop_extract_operation::evaluate (struct type *expect_type,
     error (_("length type is larger than the value 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;
 }
 
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index f883b08e2ae..d935f59088f 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -159,7 +159,7 @@  fortran_bounds_all_dims (bool lbound_p,
       gdb_assert (dst_offset + v->type ()->length ()
 		  <= result->type ()->length ());
       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.  */
       array_type = array_type->target_type ();
@@ -282,8 +282,8 @@  class fortran_array_repacker_base_impl
      available offset.  */
   void copy_element_to_dest (struct value *elt)
   {
-    value_contents_copy (m_dest, m_dest_offset, elt, 0,
-			 elt->type ()->length ());
+    elt->contents_copy (m_dest, m_dest_offset, 0,
+			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 ()
 		  <= result->type ()->length ());
       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.  */
       val_type = val_type->target_type ();
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 2a2c3eb2ab4..a82cf8c0afa 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -866,7 +866,7 @@  read_frame_register_value (struct value *value, frame_info_ptr frame)
       if (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;
       len -= reg_len;
diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c
index e8202667e24..fa46d474914 100644
--- a/gdb/gnu-v2-abi.c
+++ b/gdb/gnu-v2-abi.c
@@ -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
      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);
 
   /* With older versions of g++, the vtbl field pointed to an array
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index f13f0ef6625..d74c738bc22 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -654,8 +654,8 @@  pascal_object_print_value_fields (struct value *val, struct ui_file *stream,
 
 		  opts.deref_ref = false;
 
-		  struct value *v = value_primitive_field (val, 0, i,
-							   val->type ());
+		  struct value *v = val->primitive_field (0, i,
+							  val->type ());
 		  common_val_print (v, stream, recurse + 1, &opts,
 				    current_language);
 		}
@@ -729,7 +729,7 @@  pascal_object_print_value (struct value *val, struct ui_file *stream,
       struct value *base_value;
       try
 	{
-	  base_value = value_primitive_field (val, 0, i, type);
+	  base_value = val->primitive_field (0, i, type);
 	}
       catch (const gdb_exception_error &ex)
 	{
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index a5be110a33b..013b8a4c0d2 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -1382,7 +1382,7 @@  rust_struct_anon::evaluate (struct type *expect_type,
 		   field_number, type->name ());
 
 	  int fieldno = rust_enum_variant (type);
-	  lhs = value_primitive_field (lhs, 0, fieldno, type);
+	  lhs = lhs->primitive_field (0, fieldno, type);
 	  outer_type = type;
 	  type = lhs->type ();
 	}
@@ -1418,7 +1418,7 @@  rust_struct_anon::evaluate (struct type *expect_type,
 		  field_number, type->name ());
 	}
 
-      return value_primitive_field (lhs, 0, field_number, type);
+      return lhs->primitive_field (0, field_number, type);
     }
   else
     error(_("Anonymous field access is only allowed on tuples, \
@@ -1445,7 +1445,7 @@  rust_structop::evaluate (struct type *expect_type,
 	       field_name, type->name ());
 
       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;
       type = lhs->type ();
diff --git a/gdb/valops.c b/gdb/valops.c
index 89bd5c95a2c..7197348950b 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1726,8 +1726,7 @@  value_array (int lowbound, int highbound, struct value **elemvec)
     {
       val = value::allocate (arraytype);
       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;
     }
 
@@ -1736,7 +1735,7 @@  value_array (int lowbound, int highbound, struct value **elemvec)
 
   val = value::allocate (arraytype);
   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;
 }
 
@@ -2022,7 +2021,7 @@  struct_field_searcher::search (struct value *arg1, LONGEST offset,
 	    if (field_is_static (&type->field (i)))
 	      v = value_static_field (type, i);
 	    else
-	      v = value_primitive_field (arg1, offset, i, type);
+	      v = arg1->primitive_field (offset, i, type);
 
 	    update_result (v, offset);
 	    return;
@@ -2118,7 +2117,7 @@  struct_field_searcher::search (struct value *arg1, LONGEST offset,
 	    search (v2, 0, TYPE_BASECLASS (type, i));
 	}
       else if (found_baseclass)
-	v = value_primitive_field (arg1, offset, i, type);
+	v = arg1->primitive_field (offset, i, type);
       else
 	{
 	  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))
 	  && bitpos == t->field (i).loc_bitpos ()
 	  && 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."));
@@ -4083,8 +4082,8 @@  value_slice (struct value *array, int lowbound, int length)
     else
       {
 	slice = value::allocate (slice_type);
-	value_contents_copy (slice, 0, array, offset,
-			     type_length_units (slice_type));
+	array->contents_copy (slice, 0, offset,
+			      type_length_units (slice_type));
       }
 
     slice->set_component_location (array);
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 46d0aee1417..8c067693492 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -2007,9 +2007,9 @@  value_print_array_elements (struct value *val, struct ui_file *stream,
       maybe_print_array_index (index_type, i + low_bound,
 			       stream, options);
 
-      struct value *element = value_from_component_bitsize (val, elttype,
-							    bit_stride * i,
-							    bit_stride);
+      struct value *element = val->from_component_bitsize (elttype,
+							   bit_stride * i,
+							   bit_stride);
       rep1 = i + 1;
       reps = 1;
       /* 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)
 	    {
 	      struct value *rep_elt
-		= value_from_component_bitsize (val, elttype,
-						rep1 * bit_stride,
-						bit_stride);
+		= val->from_component_bitsize (elttype,
+					       rep1 * bit_stride,
+					       bit_stride);
 	      bool repeated = ((available
 				&& rep_elt->entirely_available ()
 				&& element->contents_eq (rep_elt))
diff --git a/gdb/value.c b/gdb/value.c
index 3aac084a864..1921aecdbc1 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -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,
-   SRC_BIT_OFFSET+BIT_LENGTH) into DST, adjusted.  */
+/* See value.h.  */
 
-static void
-value_ranges_copy_adjusted (struct value *dst, int dst_bit_offset,
-			    const struct value *src, int src_bit_offset,
-			    int bit_length)
+void
+value::ranges_copy_adjusted (struct value *dst, int dst_bit_offset,
+			     int src_bit_offset, int bit_length) const
 {
-  ranges_copy_adjusted (&dst->m_unavailable, dst_bit_offset,
-			src->m_unavailable, src_bit_offset,
-			bit_length);
-  ranges_copy_adjusted (&dst->m_optimized_out, dst_bit_offset,
-			src->m_optimized_out, src_bit_offset,
-			bit_length);
+  ::ranges_copy_adjusted (&dst->m_unavailable, dst_bit_offset,
+			  m_unavailable, src_bit_offset,
+			  bit_length);
+  ::ranges_copy_adjusted (&dst->m_optimized_out, dst_bit_offset,
+			  m_optimized_out, src_bit_offset,
+			  bit_length);
 }
 
-/* Copy LENGTH target addressable memory units of SRC 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 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,
-   DST_OFFSET+LENGTH) range are wholly available.  */
+/* See value.h.  */
 
-static void
-value_contents_copy_raw (struct value *dst, LONGEST dst_offset,
-			 struct value *src, LONGEST src_offset, LONGEST length)
+void
+value::contents_copy_raw (struct value *dst, LONGEST dst_offset,
+			  LONGEST src_offset, LONGEST 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
      soon as DST's contents were un-lazied (by a later value_contents
      call, say), the contents would be overwritten.  A lazy SRC would
      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
      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,
 					  length * unit_size);
   gdb::array_view<const gdb_byte> src_contents
-    = src->contents_all_raw ().slice (src_offset * unit_size,
-					  length * unit_size);
+    = contents_all_raw ().slice (src_offset * unit_size,
+				 length * unit_size);
   gdb::copy (src_contents, dst_contents);
 
   /* 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;
   bit_length = length * unit_size * HOST_CHAR_BIT;
 
-  value_ranges_copy_adjusted (dst, dst_bit_offset,
-			      src, src_bit_offset,
-			      bit_length);
+  ranges_copy_adjusted (dst, dst_bit_offset,
+			src_bit_offset, bit_length);
 }
 
-/* A helper for value_from_component_bitsize that copies bits from SRC
-   to DEST.  */
+/* See value.h.  */
 
-static void
-value_contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset,
-				 struct value *src, LONGEST src_bit_offset,
-				 LONGEST bit_length)
+void
+value::contents_copy_raw_bitwise (struct value *dst, LONGEST dst_bit_offset,
+				  LONGEST src_bit_offset,
+				  LONGEST bit_length)
 {
   /* 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
      call, say), the contents would be overwritten.  A lazy SRC would
      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
      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.  */
   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,
 		src_contents.data (), src_bit_offset,
 		bit_length,
-		type_byte_order (src->type ()) == BFD_ENDIAN_BIG);
+		type_byte_order (type ()) == BFD_ENDIAN_BIG);
 
   /* Copy the meta-data.  */
-  value_ranges_copy_adjusted (dst, dst_bit_offset,
-			      src, src_bit_offset,
-			      bit_length);
+  ranges_copy_adjusted (dst, dst_bit_offset, src_bit_offset, bit_length);
 }
 
-/* Copy LENGTH bytes of SRC 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 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.  */
+/* See value.h.  */
 
 void
-value_contents_copy (struct value *dst, LONGEST dst_offset,
-		     struct value *src, LONGEST src_offset, LONGEST length)
+value::contents_copy (struct value *dst, LONGEST dst_offset,
+		      LONGEST src_offset, LONGEST length)
 {
-  if (src->m_lazy)
-    src->fetch_lazy ();
+  if (m_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>
@@ -2859,19 +2836,14 @@  value::set_enclosing_type (struct type *new_encl_type)
   m_enclosing_type = new_encl_type;
 }
 
-/* Given a value ARG1 (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.  */
+/* See value.h.  */
 
 struct value *
-value_primitive_field (struct value *arg1, LONGEST offset,
-		       int fieldno, struct type *arg_type)
+value::primitive_field (LONGEST offset, int fieldno, struct type *arg_type)
 {
   struct value *v;
   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);
   type = arg_type->field (fieldno).type ();
@@ -2905,11 +2877,11 @@  value_primitive_field (struct value *arg1, LONGEST offset,
 	v->set_bitpos (bitpos % container_bitsize);
       else
 	v->set_bitpos (bitpos % 8);
-      v->set_offset ((arg1->embedded_offset ()
+      v->set_offset ((embedded_offset ()
 		      + offset
 		      + (bitpos - v->bitpos ()) / 8));
-      v->set_parent (arg1);
-      if (!arg1->lazy ())
+      v->set_parent (this);
+      if (!lazy ())
 	v->fetch_lazy ();
     }
   else if (fieldno < TYPE_N_BASECLASSES (arg_type))
@@ -2920,32 +2892,31 @@  value_primitive_field (struct value *arg1, LONGEST offset,
       LONGEST boffset;
 
       /* Lazy register values with offsets are not supported.  */
-      if (VALUE_LVAL (arg1) == lval_register && arg1->lazy ())
-	arg1->fetch_lazy ();
+      if (VALUE_LVAL (this) == lval_register && lazy ())
+	fetch_lazy ();
 
       /* We special case virtual inheritance here because this
 	 requires access to the contents, which we would rather avoid
 	 for references to ordinary fields of unavailable values.  */
       if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno))
 	boffset = baseclass_offset (arg_type, fieldno,
-				    arg1->contents ().data (),
-				    arg1->embedded_offset (),
-				    arg1->address (),
-				    arg1);
+				    contents ().data (),
+				    embedded_offset (),
+				    address (),
+				    this);
       else
 	boffset = arg_type->field (fieldno).loc_bitpos () / 8;
 
-      if (arg1->lazy ())
-	v = value::allocate_lazy (arg1->enclosing_type ());
+      if (lazy ())
+	v = value::allocate_lazy (enclosing_type ());
       else
 	{
-	  v = value::allocate (arg1->enclosing_type ());
-	  value_contents_copy_raw (v, 0, arg1, 0,
-				   arg1->enclosing_type ()->length ());
+	  v = value::allocate (enclosing_type ());
+	  contents_copy_raw (v, 0, 0, enclosing_type ()->length ());
 	}
       v->deprecated_set_type (type);
-      v->set_offset (arg1->offset ());
-      v->set_embedded_offset (offset + arg1->embedded_offset () + boffset);
+      v->set_offset (this->offset ());
+      v->set_embedded_offset (offset + embedded_offset () + boffset);
     }
   else if (NULL != TYPE_DATA_LOCATION (type))
     {
@@ -2965,22 +2936,21 @@  value_primitive_field (struct value *arg1, LONGEST offset,
 		 / (HOST_CHAR_BIT * unit_size));
 
       /* Lazy register values with offsets are not supported.  */
-      if (VALUE_LVAL (arg1) == lval_register && arg1->lazy ())
-	arg1->fetch_lazy ();
+      if (VALUE_LVAL (this) == lval_register && lazy ())
+	fetch_lazy ();
 
-      if (arg1->lazy ())
+      if (lazy ())
 	v = value::allocate_lazy (type);
       else
 	{
 	  v = value::allocate (type);
-	  value_contents_copy_raw (v, v->embedded_offset (),
-				   arg1, arg1->embedded_offset () + offset,
-				   type_length_units (type));
+	  contents_copy_raw (v, v->embedded_offset (),
+			     embedded_offset () + offset,
+			     type_length_units (type));
 	}
-      v->set_offset ((arg1->offset () + offset
-		      + arg1->embedded_offset ()));
+      v->set_offset (this->offset () + offset + embedded_offset ());
     }
-  v->set_component_location (arg1);
+  v->set_component_location (this);
   return v;
 }
 
@@ -2991,7 +2961,7 @@  value_primitive_field (struct value *arg1, LONGEST offset,
 struct value *
 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.
@@ -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);
 }
 
-/* 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
-   VAL.  If the VAL's contents required to extract the bitfield from
-   are unavailable/optimized out, DEST_VAL is correspondingly
-   marked unavailable/optimized out.  */
+/* See value.h.  */
 
 void
-unpack_value_bitfield (struct value *dest_val,
-		       LONGEST bitpos, LONGEST bitsize,
-		       const gdb_byte *valaddr, LONGEST embedded_offset,
-		       const struct value *val)
+value::unpack_bitfield (struct value *dest_val,
+			LONGEST bitpos, LONGEST bitsize,
+			const gdb_byte *valaddr, LONGEST embedded_offset)
+  const
 {
   enum bfd_endian byte_order;
   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;
   else
     dst_bit_offset = 0;
-  value_ranges_copy_adjusted (dest_val, dst_bit_offset,
-			      val, src_bit_offset, bitsize);
+  ranges_copy_adjusted (dest_val, dst_bit_offset, src_bit_offset, bitsize);
 }
 
 /* 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);
   struct value *res_val = value::allocate (type->field (fieldno).type ());
 
-  unpack_value_bitfield (res_val, bitpos, bitsize,
-			 valaddr, embedded_offset, val);
+  val->unpack_bitfield (res_val, bitpos, bitsize, valaddr, embedded_offset);
 
   return res_val;
 }
@@ -3573,9 +3535,9 @@  value_from_component (struct value *whole, struct type *type, LONGEST offset)
   else
     {
       v = value::allocate (type);
-      value_contents_copy (v, v->embedded_offset (),
-			   whole, whole->embedded_offset () + offset,
-			   type_length_units (type));
+      whole->contents_copy (v, v->embedded_offset (),
+			    whole->embedded_offset () + offset,
+			    type_length_units (type));
     }
   v->set_offset (whole->offset () + offset + whole->embedded_offset ());
   v->set_component_location (whole);
@@ -3586,10 +3548,10 @@  value_from_component (struct value *whole, struct type *type, LONGEST offset)
 /* See value.h.  */
 
 struct value *
-value_from_component_bitsize (struct value *whole, struct type *type,
-			      LONGEST bit_offset, LONGEST bit_length)
+value::from_component_bitsize (struct type *type,
+			       LONGEST bit_offset, LONGEST bit_length)
 {
-  gdb_assert (!whole->lazy ());
+  gdb_assert (!lazy ());
 
   /* Preserve lvalue-ness if possible.  This is needed to avoid
      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
       && (bit_length % TARGET_CHAR_BIT) == 0
       && 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);
 
@@ -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)
     dst_offset += TARGET_CHAR_BIT * type->length () - bit_length;
 
-  value_contents_copy_raw_bitwise (v, dst_offset,
-				   whole,
-				   TARGET_CHAR_BIT
-				   * whole->embedded_offset ()
-				   + bit_offset,
-				   bit_length);
+  contents_copy_raw_bitwise (v, dst_offset,
+			     TARGET_CHAR_BIT
+			     * embedded_offset ()
+			     + bit_offset,
+			     bit_length);
   return v;
 }
 
@@ -3756,9 +3717,9 @@  value::fetch_lazy_bitfield ()
   if (parent->lazy ())
     parent->fetch_lazy ();
 
-  unpack_value_bitfield (this, bitpos (), bitsize (),
-			 parent->contents_for_printing ().data (),
-			 offset (), parent);
+  parent->unpack_bitfield (this, bitpos (), bitsize (),
+			   parent->contents_for_printing ().data (),
+			   offset ());
 }
 
 /* See value.h.  */
@@ -3853,9 +3814,9 @@  value::fetch_lazy_register ()
   /* Copy the contents and the unavailability/optimized-out
      meta-data from NEW_VAL to VAL.  */
   set_lazy (0);
-  value_contents_copy (this, embedded_offset (),
-		       new_val, new_val->embedded_offset (),
-		       type_length_units (type));
+  new_val->contents_copy (this, embedded_offset (),
+			  new_val->embedded_offset (),
+			  type_length_units (type));
 
   if (frame_debug)
     {
diff --git a/gdb/value.h b/gdb/value.h
index ccba2208e88..7e232f378ed 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -558,6 +558,49 @@  struct value
      used to prevent cycles / duplicates.  */
   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
      different possible kinds of lval.  */
@@ -781,6 +824,29 @@  struct value
      value is lazy, it'll be read now.  Note that RANGE is a pointer
      to pointer because reading the value might change *RANGE.  */
   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
@@ -995,12 +1061,6 @@  extern int unpack_value_field_as_long (struct type *type, const gdb_byte *valadd
 				LONGEST embedded_offset, int fieldno,
 				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,
 					   const gdb_byte *valaddr,
 					   LONGEST embedded_offset,
@@ -1017,20 +1077,6 @@  extern struct value *value_from_component (struct value *, struct type *,
 					   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_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,
 				     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 *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_primitive_field (struct value *arg1, LONGEST offset,
-					    int fieldno,
-					    struct type *arg_type);
-
-
 extern struct type *value_rtti_indirect_type (struct value *, int *, LONGEST *,
 					      int *);