/* Low level packing and unpacking of values for GDB, the GNU Debugger.

   Copyright (C) 1986-2026 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "arch-utils.h"
#include "extract-store-integer.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcore.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "target.h"
#include "language.h"
#include "demangle.h"
#include "regcache.h"
#include "block.h"
#include "target-float.h"
#include "objfiles.h"
#include "valprint.h"
#include "cli/cli-decode.h"
#include "extension.h"
#include "tracepoint.h"
#include "cp-abi.h"
#include "user-regs.h"
#include <algorithm>
#include <iterator>
#include <map>
#include <utility>
#include <vector>
#include "completer.h"
#include "gdbsupport/cleanups.h"
#include "gdbsupport/selftest.h"
#include "gdbsupport/array-view.h"
#include "cli/cli-style.h"
#include "expop.h"
#include "inferior.h"
#include "varobj.h"

/* Definition of a user function.  */
struct internal_function
{
  internal_function (std::string name, internal_function_fn_noside handler,
		     void *cookie)
    : name (std::move (name)),
      handler (handler),
      cookie (cookie)
  {}

  /* The name of the function.  It is a bit odd to have this in the
     function itself -- the user might use a differently-named
     convenience variable to hold the function.  */
  std::string name;

  /* The handler.  */
  internal_function_fn_noside handler;

  /* User data for the handler.  */
  void *cookie;
};

using internal_function_up = std::unique_ptr<internal_function>;

/* Returns true if the ranges defined by [offset1, offset1+len1) and
   [offset2, offset2+len2) overlap.  */

static bool
ranges_overlap (LONGEST offset1, ULONGEST len1,
		LONGEST offset2, ULONGEST len2)
{
  LONGEST h, l;

  l = std::max (offset1, offset2);
  h = std::min (offset1 + len1, offset2 + len2);
  return (l < h);
}

/* Returns true if RANGES contains any range that overlaps [OFFSET,
   OFFSET+LENGTH).  */

static bool
ranges_contain (const std::vector<range> &ranges, LONGEST offset,
		ULONGEST length)
{
  range what;

  what.offset = offset;
  what.length = length;

  /* We keep ranges sorted by offset and coalesce overlapping and
     contiguous ranges, so to check if a range list contains a given
     range, we can do a binary search for the position the given range
     would be inserted if we only considered the starting OFFSET of
     ranges.  We call that position I.  Since we also have LENGTH to
     care for (this is a range after all), we need to check if the
     _previous_ range overlaps the I range.  E.g.,

	 R
	 |---|
       |---|    |---|  |------| ... |--|
       0        1      2            N

       I=1

     In the case above, the binary search would return `I=1', meaning,
     this OFFSET should be inserted at position 1, and the current
     position 1 should be pushed further (and before 2).  But, `0'
     overlaps with R.

     Then we need to check if the I range overlaps the I range itself.
     E.g.,

	      R
	      |---|
       |---|    |---|  |-------| ... |--|
       0        1      2             N

       I=1
  */


  auto i = std::lower_bound (ranges.begin (), ranges.end (), what);

  if (i > ranges.begin ())
    {
      const struct range &bef = *(i - 1);

      if (ranges_overlap (bef.offset, bef.length, offset, length))
	return true;
    }

  if (i < ranges.end ())
    {
      const struct range &r = *i;

      if (ranges_overlap (r.offset, r.length, offset, length))
	return true;
    }

  return false;
}

static struct cmd_list_element *functionlist;

value::~value ()
{
  if (this->lval () == lval_computed)
    {
      const struct lval_funcs *funcs = m_location.computed.funcs;

      if (funcs->free_closure)
	funcs->free_closure (this);
    }
  else if (this->lval () == lval_xcallable)
    delete m_location.xm_worker;
}

/* See value.h.  */

struct gdbarch *
value::arch () const
{
  return type ()->arch ();
}

bool
value::bits_available (LONGEST offset, ULONGEST length) const
{
  gdb_assert (!m_lazy);

  /* Don't pretend we have anything available there in the history beyond
     the boundaries of the value recorded.  It's not like inferior memory
     where there is actual stuff underneath.  */
  ULONGEST val_len = TARGET_CHAR_BIT * enclosing_type ()->length ();
  return !((m_in_history
	    && (offset < 0 || offset + length > val_len))
	   || ranges_contain (m_unavailable, offset, length));
}

bool
value::bytes_available (LONGEST offset, ULONGEST length) const
{
  ULONGEST sign = (1ULL << (sizeof (ULONGEST) * 8 - 1)) / TARGET_CHAR_BIT;
  ULONGEST mask = (sign << 1) - 1;

  if (offset != ((offset & mask) ^ sign) - sign
      || length != ((length & mask) ^ sign) - sign
      || (length > 0 && (~offset & (offset + length - 1) & sign) != 0))
    error (_("Integer overflow in data location calculation"));

  return bits_available (offset * TARGET_CHAR_BIT, length * TARGET_CHAR_BIT);
}

bool
value::bits_any_optimized_out (int bit_offset, int bit_length) const
{
  gdb_assert (!m_lazy);

  return ranges_contain (m_optimized_out, bit_offset, bit_length);
}

bool
value::entirely_available ()
{
  /* We can only tell whether the whole value is available when we try
     to read it.  */
  if (m_lazy)
    fetch_lazy ();

  if (m_unavailable.empty ())
    return true;
  return false;
}

/* See value.h.  */

bool
value::entirely_covered_by_range_vector (const std::vector<range> &ranges)
{
  /* We can only tell whether the whole value is optimized out /
     unavailable when we try to read it.  */
  if (m_lazy)
    fetch_lazy ();

  if (ranges.size () == 1)
    {
      const struct range &t = ranges[0];

      if (t.offset == 0
	  && t.length == TARGET_CHAR_BIT * enclosing_type ()->length ())
	return true;
    }

  return false;
}

/* Insert into the vector pointed to by VECTORP the bit range starting of
   OFFSET bits, and extending for the next LENGTH bits.  */

static void
insert_into_bit_range_vector (std::vector<range> *vectorp,
			      LONGEST offset, ULONGEST length)
{
  range newr;

  /* Insert the range sorted.  If there's overlap or the new range
     would be contiguous with an existing range, merge.  */

  newr.offset = offset;
  newr.length = length;

  /* Do a binary search for the position the given range would be
     inserted if we only considered the starting OFFSET of ranges.
     Call that position I.  Since we also have LENGTH to care for
     (this is a range after all), we need to check if the _previous_
     range overlaps the I range.  E.g., calling R the new range:

       #1 - overlaps with previous

	   R
	   |-...-|
	 |---|     |---|  |------| ... |--|
	 0         1      2            N

	 I=1

     In the case #1 above, the binary search would return `I=1',
     meaning, this OFFSET should be inserted at position 1, and the
     current position 1 should be pushed further (and become 2).  But,
     note that `0' overlaps with R, so we want to merge them.

     A similar consideration needs to be taken if the new range would
     be contiguous with the previous range:

       #2 - contiguous with previous

	    R
	    |-...-|
	 |--|       |---|  |------| ... |--|
	 0          1      2            N

	 I=1

     If there's no overlap with the previous range, as in:

       #3 - not overlapping and not contiguous

	       R
	       |-...-|
	  |--|         |---|  |------| ... |--|
	  0            1      2            N

	 I=1

     or if I is 0:

       #4 - R is the range with lowest offset

	  R
	 |-...-|
		 |--|       |---|  |------| ... |--|
		 0          1      2            N

	 I=0

     ... we just push the new range to I.

     All the 4 cases above need to consider that the new range may
     also overlap several of the ranges that follow, or that R may be
     contiguous with the following range, and merge.  E.g.,

       #5 - overlapping following ranges

	  R
	 |------------------------|
		 |--|       |---|  |------| ... |--|
		 0          1      2            N

	 I=0

       or:

	    R
	    |-------|
	 |--|       |---|  |------| ... |--|
	 0          1      2            N

	 I=1

  */

  auto i = std::lower_bound (vectorp->begin (), vectorp->end (), newr);
  if (i > vectorp->begin ())
    {
      struct range &bef = *(i - 1);

      if (ranges_overlap (bef.offset, bef.length, offset, length))
	{
	  /* #1 */
	  LONGEST l = std::min (bef.offset, offset);
	  LONGEST h = std::max (bef.offset + bef.length, offset + length);

	  bef.offset = l;
	  bef.length = h - l;
	  i--;
	}
      else if (offset == bef.offset + bef.length)
	{
	  /* #2 */
	  bef.length += length;
	  i--;
	}
      else
	{
	  /* #3 */
	  i = vectorp->insert (i, newr);
	}
    }
  else
    {
      /* #4 */
      i = vectorp->insert (i, newr);
    }

  /* Check whether the ranges following the one we've just added or
     touched can be folded in (#5 above).  */
  if (i != vectorp->end () && i + 1 < vectorp->end ())
    {
      int removed = 0;
      auto next = i + 1;

      /* Get the range we just touched.  */
      struct range &t = *i;
      removed = 0;

      i = next;
      for (; i < vectorp->end (); i++)
	{
	  struct range &r = *i;
	  if (r.offset <= t.offset + t.length)
	    {
	      LONGEST l, h;

	      l = std::min (t.offset, r.offset);
	      h = std::max (t.offset + t.length, r.offset + r.length);

	      t.offset = l;
	      t.length = h - l;

	      removed++;
	    }
	  else
	    {
	      /* If we couldn't merge this one, we won't be able to
		 merge following ones either, since the ranges are
		 always sorted by OFFSET.  */
	      break;
	    }
	}

      if (removed != 0)
	vectorp->erase (next, next + removed);
    }
}

void
value::mark_bits_unavailable (LONGEST offset, ULONGEST length)
{
  insert_into_bit_range_vector (&m_unavailable, offset, length);
}

void
value::mark_bytes_unavailable (LONGEST offset, ULONGEST length)
{
  mark_bits_unavailable (offset * TARGET_CHAR_BIT,
			 length * TARGET_CHAR_BIT);
}

/* Find the first range in RANGES that overlaps the range defined by
   OFFSET and LENGTH, starting at element POS in the RANGES vector,
   Returns the index into RANGES where such overlapping range was
   found, or -1 if none was found.  */

static int
find_first_range_overlap (const std::vector<range> *ranges, int pos,
			  LONGEST offset, LONGEST length)
{
  int i;

  for (i = pos; i < ranges->size (); i++)
    {
      const range &r = (*ranges)[i];
      if (ranges_overlap (r.offset, r.length, offset, length))
	return i;
    }

  return -1;
}

/* Compare LENGTH_BITS of memory at PTR1 + OFFSET1_BITS with the memory at
   PTR2 + OFFSET2_BITS.  Return 0 if the memory is the same, otherwise
   return non-zero.

   It must always be the case that:
     OFFSET1_BITS % TARGET_CHAR_BIT == OFFSET2_BITS % TARGET_CHAR_BIT

   It is assumed that memory can be accessed from:
     PTR + (OFFSET_BITS / TARGET_CHAR_BIT)
   to:
     PTR + ((OFFSET_BITS + LENGTH_BITS + TARGET_CHAR_BIT - 1)
	    / TARGET_CHAR_BIT)  */
static int
memcmp_with_bit_offsets (const gdb_byte *ptr1, size_t offset1_bits,
			 const gdb_byte *ptr2, size_t offset2_bits,
			 size_t length_bits)
{
  gdb_assert (offset1_bits % TARGET_CHAR_BIT
	      == offset2_bits % TARGET_CHAR_BIT);

  if (offset1_bits % TARGET_CHAR_BIT != 0)
    {
      size_t bits;
      gdb_byte mask, b1, b2;

      /* The offset from the base pointers PTR1 and PTR2 is not a complete
	 number of bytes.  A number of bits up to either the next exact
	 byte boundary, or LENGTH_BITS (which ever is sooner) will be
	 compared.  */
      bits = TARGET_CHAR_BIT - offset1_bits % TARGET_CHAR_BIT;
      gdb_assert (bits < sizeof (mask) * TARGET_CHAR_BIT);
      mask = (1 << bits) - 1;

      if (length_bits < bits)
	{
	  mask &= ~(gdb_byte) ((1 << (bits - length_bits)) - 1);
	  bits = length_bits;
	}

      /* Now load the two bytes and mask off the bits we care about.  */
      b1 = *(ptr1 + offset1_bits / TARGET_CHAR_BIT) & mask;
      b2 = *(ptr2 + offset2_bits / TARGET_CHAR_BIT) & mask;

      if (b1 != b2)
	return 1;

      /* Now update the length and offsets to take account of the bits
	 we've just compared.  */
      length_bits -= bits;
      offset1_bits += bits;
      offset2_bits += bits;
    }

  if (length_bits % TARGET_CHAR_BIT != 0)
    {
      size_t bits;
      size_t o1, o2;
      gdb_byte mask, b1, b2;

      /* The length is not an exact number of bytes.  After the previous
	 IF.. block then the offsets are byte aligned, or the
	 length is zero (in which case this code is not reached).  Compare
	 a number of bits at the end of the region, starting from an exact
	 byte boundary.  */
      bits = length_bits % TARGET_CHAR_BIT;
      o1 = offset1_bits + length_bits - bits;
      o2 = offset2_bits + length_bits - bits;

      gdb_assert (bits < sizeof (mask) * TARGET_CHAR_BIT);
      mask = ((1 << bits) - 1) << (TARGET_CHAR_BIT - bits);

      gdb_assert (o1 % TARGET_CHAR_BIT == 0);
      gdb_assert (o2 % TARGET_CHAR_BIT == 0);

      b1 = *(ptr1 + o1 / TARGET_CHAR_BIT) & mask;
      b2 = *(ptr2 + o2 / TARGET_CHAR_BIT) & mask;

      if (b1 != b2)
	return 1;

      length_bits -= bits;
    }

  if (length_bits > 0)
    {
      /* We've now taken care of any stray "bits" at the start, or end of
	 the region to compare, the remainder can be covered with a simple
	 memcmp.  */
      gdb_assert (offset1_bits % TARGET_CHAR_BIT == 0);
      gdb_assert (offset2_bits % TARGET_CHAR_BIT == 0);
      gdb_assert (length_bits % TARGET_CHAR_BIT == 0);

      return memcmp (ptr1 + offset1_bits / TARGET_CHAR_BIT,
		     ptr2 + offset2_bits / TARGET_CHAR_BIT,
		     length_bits / TARGET_CHAR_BIT);
    }

  /* Length is zero, regions match.  */
  return 0;
}

/* Helper struct for find_first_range_overlap_and_match and
   value_contents_bits_eq.  Keep track of which slot of a given ranges
   vector have we last looked at.  */

struct ranges_and_idx
{
  /* The ranges.  */
  const std::vector<range> *ranges;

  /* The range we've last found in RANGES.  Given ranges are sorted,
     we can start the next lookup here.  */
  int idx;
};

/* Helper function for value_contents_bits_eq.  Compare LENGTH bits of
   RP1's ranges starting at OFFSET1 bits with LENGTH bits of RP2's
   ranges starting at OFFSET2 bits.  Return true if the ranges match
   and fill in *L and *H with the overlapping window relative to
   (both) OFFSET1 or OFFSET2.  */

static int
find_first_range_overlap_and_match (struct ranges_and_idx *rp1,
				    struct ranges_and_idx *rp2,
				    LONGEST offset1, LONGEST offset2,
				    ULONGEST length, ULONGEST *l, ULONGEST *h)
{
  rp1->idx = find_first_range_overlap (rp1->ranges, rp1->idx,
				       offset1, length);
  rp2->idx = find_first_range_overlap (rp2->ranges, rp2->idx,
				       offset2, length);

  if (rp1->idx == -1 && rp2->idx == -1)
    {
      *l = length;
      *h = length;
      return 1;
    }
  else if (rp1->idx == -1 || rp2->idx == -1)
    return 0;
  else
    {
      const range *r1, *r2;
      ULONGEST l1, h1;
      ULONGEST l2, h2;

      r1 = &(*rp1->ranges)[rp1->idx];
      r2 = &(*rp2->ranges)[rp2->idx];

      /* Get the unavailable windows intersected by the incoming
	 ranges.  The first and last ranges that overlap the argument
	 range may be wider than said incoming arguments ranges.  */
      l1 = std::max (offset1, r1->offset);
      h1 = std::min (offset1 + length, r1->offset + r1->length);

      l2 = std::max (offset2, r2->offset);
      h2 = std::min (offset2 + length, offset2 + r2->length);

      /* Make them relative to the respective start offsets, so we can
	 compare them for equality.  */
      l1 -= offset1;
      h1 -= offset1;

      l2 -= offset2;
      h2 -= offset2;

      /* Different ranges, no match.  */
      if (l1 != l2 || h1 != h2)
	return 0;

      *h = h1;
      *l = l1;
      return 1;
    }
}

/* Helper function for value_contents_eq.  The only difference is that
   this function is bit rather than byte based.

   Compare LENGTH bits of VAL1's contents starting at OFFSET1 bits
   with LENGTH bits of VAL2's contents starting at OFFSET2 bits.
   Return true if the available bits match.  */

bool
value::contents_bits_eq (int offset1, const struct value *val2, int offset2,
			 int length) const
{
  /* Each array element corresponds to a ranges source (unavailable,
     optimized out).  '1' is for VAL1, '2' for VAL2.  */
  struct ranges_and_idx rp1[2], rp2[2];

  /* See function description in value.h.  */
  gdb_assert (!m_lazy && !val2->m_lazy);

  /* We shouldn't be trying to compare past the end of the values.  */
  gdb_assert (offset1 + length
	      <= m_enclosing_type->length () * TARGET_CHAR_BIT);
  gdb_assert (offset2 + length
	      <= val2->m_enclosing_type->length () * TARGET_CHAR_BIT);

  memset (&rp1, 0, sizeof (rp1));
  memset (&rp2, 0, sizeof (rp2));
  rp1[0].ranges = &m_unavailable;
  rp2[0].ranges = &val2->m_unavailable;
  rp1[1].ranges = &m_optimized_out;
  rp2[1].ranges = &val2->m_optimized_out;

  while (length > 0)
    {
      ULONGEST l = 0, h = 0; /* init for gcc -Wall */
      int i;

      for (i = 0; i < 2; i++)
	{
	  ULONGEST l_tmp, h_tmp;

	  /* The contents only match equal if the invalid/unavailable
	     contents ranges match as well.  */
	  if (!find_first_range_overlap_and_match (&rp1[i], &rp2[i],
						   offset1, offset2, length,
						   &l_tmp, &h_tmp))
	    return false;

	  /* We're interested in the lowest/first range found.  */
	  if (i == 0 || l_tmp < l)
	    {
	      l = l_tmp;
	      h = h_tmp;
	    }
	}

      /* Compare the available/valid contents.  */
      if (memcmp_with_bit_offsets (m_contents.get (), offset1,
				   val2->m_contents.get (), offset2, l) != 0)
	return false;

      length -= h;
      offset1 += h;
      offset2 += h;
    }

  return true;
}

/* See value.h.  */

bool
value::contents_eq (LONGEST offset1,
		    const struct value *val2, LONGEST offset2,
		    LONGEST length) const
{
  return contents_bits_eq (offset1 * TARGET_CHAR_BIT,
			   val2, offset2 * TARGET_CHAR_BIT,
			   length * TARGET_CHAR_BIT);
}

/* See value.h.  */

bool
value::contents_eq (const struct value *val2) const
{
  ULONGEST len1 = check_typedef (enclosing_type ())->length ();
  ULONGEST len2 = check_typedef (val2->enclosing_type ())->length ();
  if (len1 != len2)
    return false;
  return contents_eq (0, val2, 0, len1);
}

/* The value-history records all the values printed by print commands
   during this session.  */

static std::vector<value_ref_ptr> value_history;


/* List of all value objects currently allocated
   (except for those released by calls to release_value)
   This is so they can be freed after each command.  */

static std::vector<value_ref_ptr> all_values;

/* See value.h.  */

struct value *
value::allocate_lazy (struct type *type)
{
  struct value *val;

  /* Call check_typedef on our type to make sure that, if TYPE
     is a TYPE_CODE_TYPEDEF, its length is set to the length
     of the target type instead of zero.  However, we do not
     replace the typedef type by the target type, because we want
     to keep the typedef in order to be able to set the VAL's type
     description correctly.  */
  check_typedef (type);

  val = new struct value (type);

  /* Values start out on the all_values chain.  */
  all_values.emplace_back (val);

  return val;
}

/* The maximum size, in bytes, that GDB will try to allocate for a value.
   The initial value of 64k was not selected for any specific reason, it is
   just a reasonable starting point.  */

static int max_value_size = 65536; /* 64k bytes */

/* It is critical that the MAX_VALUE_SIZE is at least as big as the size of
   LONGEST, otherwise GDB will not be able to parse integer values from the
   CLI; for example if the MAX_VALUE_SIZE could be set to 1 then GDB would
   be unable to parse "set max-value-size 2".

   As we want a consistent GDB experience across hosts with different sizes
   of LONGEST, this arbitrary minimum value was selected, so long as this
   is bigger than LONGEST on all GDB supported hosts we're fine.  */

#define MIN_VALUE_FOR_MAX_VALUE_SIZE 16
static_assert (sizeof (LONGEST) <= MIN_VALUE_FOR_MAX_VALUE_SIZE);

/* Implement the "set max-value-size" command.  */

static void
set_max_value_size (const char *args, int from_tty,
		    struct cmd_list_element *c)
{
  gdb_assert (max_value_size == -1 || max_value_size >= 0);

  if (max_value_size > -1 && max_value_size < MIN_VALUE_FOR_MAX_VALUE_SIZE)
    {
      max_value_size = MIN_VALUE_FOR_MAX_VALUE_SIZE;
      error (_("max-value-size set too low, increasing to %d bytes"),
	     max_value_size);
    }
}

/* Implement the "show max-value-size" command.  */

static void
show_max_value_size (struct ui_file *file, int from_tty,
		     struct cmd_list_element *c, const char *value)
{
  if (max_value_size == -1)
    gdb_printf (file, _("Maximum value size is unlimited.\n"));
  else
    gdb_printf (file, _("Maximum value size is %d bytes.\n"),
		max_value_size);
}

/* Called before we attempt to allocate or reallocate a buffer for the
   contents of a value.  TYPE is the type of the value for which we are
   allocating the buffer.  If the buffer is too large (based on the user
   controllable setting) then throw an error.  If this function returns
   then we should attempt to allocate the buffer.  */

static void
check_type_length_before_alloc (const struct type *type)
{
  ULONGEST length = type->length ();

  if (exceeds_max_value_size (length))
    {
      if (type->name () != NULL)
	error (_("value of type `%s' requires %s bytes, which is more "
		 "than max-value-size"), type->name (), pulongest (length));
      else
	error (_("value requires %s bytes, which is more than "
		 "max-value-size"), pulongest (length));
    }
}

/* See value.h.  */

bool
exceeds_max_value_size (ULONGEST length)
{
  return max_value_size > -1 && length > max_value_size;
}

/* When this has a value, it is used to limit the number of array elements
   of an array that are loaded into memory when an array value is made
   non-lazy.  */
static std::optional<int> array_length_limiting_element_count;

/* See value.h.  */
scoped_array_length_limiting::scoped_array_length_limiting (int elements)
{
  m_old_value = array_length_limiting_element_count;
  array_length_limiting_element_count.emplace (elements);
}

/* See value.h.  */
scoped_array_length_limiting::~scoped_array_length_limiting ()
{
  array_length_limiting_element_count = m_old_value;
}

/* Find the inner element type for ARRAY_TYPE.  */

static struct type *
find_array_element_type (struct type *array_type)
{
  array_type = check_typedef (array_type);
  gdb_assert (array_type->code () == TYPE_CODE_ARRAY);

  if (current_language->la_language == language_fortran)
    while (array_type->code () == TYPE_CODE_ARRAY)
      {
	array_type = array_type->target_type ();
	array_type = check_typedef (array_type);
      }
  else
    {
      array_type = array_type->target_type ();
      array_type = check_typedef (array_type);
    }

  return array_type;
}

/* Return the limited length of ARRAY_TYPE, which must be of
   TYPE_CODE_ARRAY.  This function can only be called when the global
   ARRAY_LENGTH_LIMITING_ELEMENT_COUNT has a value.

   The limited length of an array is the smallest of either (1) the total
   size of the array type, or (2) the array target type multiplies by the
   array_length_limiting_element_count.  */

static ULONGEST
calculate_limited_array_length (struct type *array_type)
{
  gdb_assert (array_length_limiting_element_count.has_value ());

  array_type = check_typedef (array_type);
  gdb_assert (array_type->code () == TYPE_CODE_ARRAY);

  struct type *elm_type = find_array_element_type (array_type);
  ULONGEST len = (elm_type->length ()
		  * (*array_length_limiting_element_count));
  len = std::min (len, array_type->length ());

  return len;
}

/* See value.h.  */

bool
value::set_limited_array_length ()
{
  ULONGEST limit = m_limited_length;
  ULONGEST len = type ()->length ();

  if (array_length_limiting_element_count.has_value ())
    len = calculate_limited_array_length (type ());

  if (limit != 0 && len > limit)
    len = limit;
  if (len > max_value_size)
    return false;

  m_limited_length = max_value_size;
  return true;
}

/* See value.h.  */

void
value::allocate_contents (bool check_size)
{
  if (!m_contents)
    {
      struct type *enc_type = enclosing_type ();
      ULONGEST len = enc_type->length ();

      if (check_size)
	{
	  /* If we are allocating the contents of an array, which
	     is greater in size than max_value_size, and there is
	     an element limit in effect, then we can possibly try
	     to load only a sub-set of the array contents into
	     GDB's memory.  */
	  if (type () == enc_type
	      && type ()->code () == TYPE_CODE_ARRAY
	      && len > max_value_size
	      && set_limited_array_length ())
	    len = m_limited_length;
	  else
	    check_type_length_before_alloc (enc_type);
	}

      m_contents.reset ((gdb_byte *) xzalloc (len));
    }
}

/* Allocate a value and its contents for type TYPE.  If CHECK_SIZE is true,
   then apply the usual max-value-size checks.  */

struct value *
value::allocate (struct type *type, bool check_size)
{
  struct value *val = value::allocate_lazy (type);

  val->allocate_contents (check_size);
  val->m_lazy = false;
  return val;
}

/* Allocate a value and its contents for type TYPE.  */

struct value *
value::allocate (struct type *type)
{
  return allocate (type, true);
}

/* See value.h  */

value *
value::allocate_register_lazy (const frame_info_ptr &initial_next_frame,
			       int regnum, struct type *type)
{
  if (type == nullptr)
    type = register_type (frame_unwind_arch (initial_next_frame), regnum);

  value *result = value::allocate_lazy (type);

  result->set_lval (lval_register);
  result->m_location.reg.regnum = regnum;

  /* If this register value is created during unwind (while computing a frame
     id), and NEXT_FRAME is a frame inlined in the frame being unwound, then
     NEXT_FRAME will not have a valid frame id yet.  Find the next non-inline
     frame (possibly the sentinel frame).  This is where registers are unwound
     from anyway.  */
  frame_info_ptr next_frame = initial_next_frame;
  while (get_frame_type (next_frame) == INLINE_FRAME)
    next_frame = get_next_frame_sentinel_okay (next_frame);

  result->m_location.reg.next_frame_id = get_frame_id (next_frame);

  /* We should have a next frame with a valid id.  */
  gdb_assert (frame_id_p (result->m_location.reg.next_frame_id));

  return result;
}

/* See value.h  */

value *
value::allocate_register (const frame_info_ptr &next_frame, int regnum,
			  struct type *type)
{
  value *result = value::allocate_register_lazy (next_frame, regnum, type);
  result->set_lazy (false);
  return result;
}

/* Allocate a  value  that has the correct length
   for COUNT repetitions of type TYPE.  */

struct value *
allocate_repeat_value (struct type *type, int count)
{
  /* Despite the fact that we are really creating an array of TYPE here, we
     use the string lower bound as the array lower bound.  This seems to
     work fine for now.  */
  int low_bound = current_language->string_lower_bound ();
  /* FIXME-type-allocation: need a way to free this type when we are
     done with it.  */
  struct type *array_type
    = lookup_array_range_type (type, low_bound, count + low_bound - 1);

  return value::allocate (array_type);
}

struct value *
value::allocate_computed (struct type *type,
			  const struct lval_funcs *funcs,
			  void *closure)
{
  struct value *v = value::allocate_lazy (type);

  v->set_lval (lval_computed);
  v->m_location.computed.funcs = funcs;
  v->m_location.computed.closure = closure;

  return v;
}

/* See value.h.  */

struct value *
value::allocate_optimized_out (struct type *type)
{
  struct value *retval = value::allocate_lazy (type);

  retval->mark_bytes_optimized_out (0, type->length ());
  retval->set_lazy (false);
  return retval;
}

/* Accessor methods.  */

gdb::array_view<gdb_byte>
value::contents_raw ()
{
  int unit_size = gdbarch_addressable_memory_unit_size (arch ());

  allocate_contents (true);

  ULONGEST length = type ()->length ();
  return gdb::make_array_view
    (m_contents.get () + m_embedded_offset * unit_size, length);
}

gdb::array_view<gdb_byte>
value::contents_all_raw ()
{
  allocate_contents (true);

  ULONGEST length = enclosing_type ()->length ();
  return gdb::make_array_view (m_contents.get (), length);
}

/* Look at value.h for description.  */

struct type *
value_actual_type (struct value *value, int resolve_simple_types,
		   int *real_type_found)
{
  struct value_print_options opts;
  struct type *result;

  get_user_print_options (&opts);

  if (real_type_found)
    *real_type_found = 0;
  result = value->type ();
  if (opts.objectprint)
    {
      /* If result's target type is TYPE_CODE_STRUCT, proceed to
	 fetch its rtti type.  */
      if (result->is_pointer_or_reference ()
	  && (check_typedef (result->target_type ())->code ()
	      == TYPE_CODE_STRUCT)
	  && !value->optimized_out ())
	{
	  struct type *real_type;

	  real_type = value_rtti_indirect_type (value, NULL, NULL, NULL);
	  if (real_type)
	    {
	      if (real_type_found)
		*real_type_found = 1;
	      result = real_type;
	    }
	}
      else if (resolve_simple_types)
	{
	  if (real_type_found)
	    *real_type_found = 1;
	  result = value->enclosing_type ();
	}
    }

  return result;
}

void
error_value_optimized_out (void)
{
  throw_error (OPTIMIZED_OUT_ERROR, _("value has been optimized out"));
}

void
value::require_not_optimized_out () const
{
  if (!m_optimized_out.empty ())
    {
      if (m_lval == lval_register)
	throw_error (OPTIMIZED_OUT_ERROR,
		     _("register has not been saved in frame"));
      else
	error_value_optimized_out ();
    }
}

void
value::require_available () const
{
  if (!m_unavailable.empty ())
    throw_error (NOT_AVAILABLE_ERROR, _("value is not available"));
}

gdb::array_view<const gdb_byte>
value::contents_for_printing ()
{
  if (m_lazy)
    fetch_lazy ();

  ULONGEST length = enclosing_type ()->length ();
  return gdb::make_array_view (m_contents.get (), length);
}

gdb::array_view<const gdb_byte>
value::contents_for_printing () const
{
  gdb_assert (!m_lazy);

  ULONGEST length = enclosing_type ()->length ();
  return gdb::make_array_view (m_contents.get (), length);
}

gdb::array_view<const gdb_byte>
value::contents_all ()
{
  gdb::array_view<const gdb_byte> result = contents_for_printing ();
  require_not_optimized_out ();
  require_available ();
  return result;
}

/* Copy ranges in SRC_RANGE that overlap [SRC_BIT_OFFSET,
   SRC_BIT_OFFSET+BIT_LENGTH) ranges into *DST_RANGE, adjusted.  */

static void
ranges_copy_adjusted (std::vector<range> *dst_range, int dst_bit_offset,
		      const std::vector<range> &src_range, int src_bit_offset,
		      unsigned int bit_length)
{
  for (const range &r : src_range)
    {
      LONGEST h, l;

      l = std::max (r.offset, (LONGEST) src_bit_offset);
      h = std::min ((LONGEST) (r.offset + r.length),
		    (LONGEST) src_bit_offset + bit_length);

      if (l < h)
	insert_into_bit_range_vector (dst_range,
				      dst_bit_offset + (l - src_bit_offset),
				      h - l);
    }
}

/* See value.h.  */

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,
			  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);
}

/* See value.h.  */

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;
  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 && !m_lazy);

  ULONGEST copy_length = length;
  ULONGEST limit = m_limited_length;
  if (limit > 0 && src_offset + length > limit)
    copy_length = src_offset > limit ? 0 : limit - src_offset;

  /* The overwritten DST range gets unavailability ORed in, not
     replaced.  Make sure to remember to implement replacing if it
     turns out actually necessary.  */
  gdb_assert (dst->bytes_available (dst_offset, length));
  gdb_assert (!dst->bits_any_optimized_out (TARGET_CHAR_BIT * dst_offset,
					    TARGET_CHAR_BIT * length));

  if ((src_offset + copy_length) * unit_size > enclosing_type ()-> length ())
    error (_("access outside bounds of object"));

  /* Copy the data.  */
  gdb::array_view<gdb_byte> dst_contents
    = dst->contents_all_raw ().slice (dst_offset * unit_size,
				      copy_length * unit_size);
  gdb::array_view<const gdb_byte> src_contents
    = contents_all_raw ().slice (src_offset * unit_size,
				 copy_length * unit_size);
  gdb::copy (src_contents, dst_contents);

  /* Copy the meta-data, adjusted.  */
  src_bit_offset = src_offset * unit_size * HOST_CHAR_BIT;
  dst_bit_offset = dst_offset * unit_size * HOST_CHAR_BIT;
  bit_length = length * unit_size * HOST_CHAR_BIT;

  ranges_copy_adjusted (dst, dst_bit_offset,
			src_bit_offset, bit_length);
}

/* See value.h.  */

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 && !m_lazy);

  ULONGEST copy_bit_length = bit_length;
  ULONGEST bit_limit = m_limited_length * TARGET_CHAR_BIT;
  if (bit_limit > 0 && src_bit_offset + bit_length > bit_limit)
    copy_bit_length = (src_bit_offset > bit_limit ? 0
		       : bit_limit - src_bit_offset);

  /* The overwritten DST range gets unavailability ORed in, not
     replaced.  Make sure to remember to implement replacing if it
     turns out actually necessary.  */
  LONGEST dst_offset = dst_bit_offset / TARGET_CHAR_BIT;
  LONGEST length = bit_length / TARGET_CHAR_BIT;
  gdb_assert (dst->bytes_available (dst_offset, length));
  gdb_assert (!dst->bits_any_optimized_out (dst_bit_offset,
					    bit_length));

  /* Copy the data.  */
  gdb::array_view<gdb_byte> dst_contents = dst->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,
		copy_bit_length,
		type_byte_order (type ()) == BFD_ENDIAN_BIG);

  /* Copy the meta-data.  */
  ranges_copy_adjusted (dst, dst_bit_offset, src_bit_offset, bit_length);
}

/* See value.h.  */

void
value::contents_copy (struct value *dst, LONGEST dst_offset,
		      LONGEST src_offset, LONGEST length)
{
  if (m_lazy)
    fetch_lazy ();

  contents_copy_raw (dst, dst_offset, src_offset, length);
}

gdb::array_view<const gdb_byte>
value::contents ()
{
  gdb::array_view<const gdb_byte> result = contents_writeable ();
  require_not_optimized_out ();
  require_available ();
  return result;
}

gdb::array_view<gdb_byte>
value::contents_writeable ()
{
  if (m_lazy)
    fetch_lazy ();
  return contents_raw ();
}

bool
value::optimized_out ()
{
  if (m_lazy)
    {
      /* See if we can compute the result without fetching the
	 value.  */
      if (this->lval () == lval_memory)
	return false;
      else if (this->lval () == lval_computed)
	{
	  const struct lval_funcs *funcs = m_location.computed.funcs;

	  if (funcs->is_optimized_out != nullptr)
	    return funcs->is_optimized_out (this);
	}

      /* Fall back to fetching.  */
      try
	{
	  fetch_lazy ();
	}
      catch (const gdb_exception_error &ex)
	{
	  switch (ex.error)
	    {
	    case MEMORY_ERROR:
	    case OPTIMIZED_OUT_ERROR:
	    case NOT_AVAILABLE_ERROR:
	      /* These can normally happen when we try to access an
		 optimized out or unavailable register, either in a
		 physical register or spilled to memory.  */
	      break;
	    default:
	      throw;
	    }
	}
    }

  return !m_optimized_out.empty ();
}

/* Mark contents of VALUE as optimized out, starting at OFFSET bytes, and
   the following LENGTH bytes.  */

void
value::mark_bytes_optimized_out (int offset, int length)
{
  mark_bits_optimized_out (offset * TARGET_CHAR_BIT,
			   length * TARGET_CHAR_BIT);
}

/* See value.h.  */

void
value::mark_bits_optimized_out (LONGEST offset, LONGEST length)
{
  insert_into_bit_range_vector (&m_optimized_out, offset, length);
}

bool
value::bits_synthetic_pointer (LONGEST offset, LONGEST length) const
{
  if (m_lval != lval_computed
      || !m_location.computed.funcs->check_synthetic_pointer)
    return false;
  return m_location.computed.funcs->check_synthetic_pointer (this, offset,
							     length);
}

const struct lval_funcs *
value::computed_funcs () const
{
  gdb_assert (m_lval == lval_computed);

  return m_location.computed.funcs;
}

void *
value::computed_closure () const
{
  gdb_assert (m_lval == lval_computed);

  return m_location.computed.closure;
}

CORE_ADDR
value::address () const
{
  if (m_lval != lval_memory)
    return 0;

  if (m_parent != NULL)
    return m_parent->address () + m_offset;

  if (dynamic_prop *dyn_prop = type ()->dyn_prop (DYN_PROP_DATA_LOCATION);
      dyn_prop != nullptr)
    {
      gdb_assert (dyn_prop->is_constant ());
      return dyn_prop->const_val ();
    }

  return m_location.address + m_offset;
}

CORE_ADDR
value::raw_address () const
{
  if (m_lval != lval_memory)
    return 0;
  return m_location.address;
}

void
value::set_address (CORE_ADDR addr)
{
  gdb_assert (m_lval == lval_memory);
  m_location.address = addr;
}

/* Return a mark in the value chain.  All values allocated after the
   mark is obtained (except for those released) are subject to being freed
   if a subsequent value_free_to_mark is passed the mark.  */
struct value *
value_mark (void)
{
  if (all_values.empty ())
    return nullptr;
  return all_values.back ().get ();
}

/* Release a reference to VAL, which was acquired with value_incref.
   This function is also called to deallocate values from the value
   chain.  */

void
value::decref ()
{
  gdb_assert (m_reference_count > 0);
  m_reference_count--;
  if (m_reference_count == 0)
    delete this;
}

/* Free all values allocated since MARK was obtained by value_mark
   (except for those released).  */
void
value_free_to_mark (const struct value *mark)
{
  auto iter = std::find (all_values.begin (), all_values.end (), mark);
  if (iter == all_values.end ())
    all_values.clear ();
  else
    all_values.erase (iter + 1, all_values.end ());
}

/* Remove VAL from the chain all_values
   so it will not be freed automatically.  */

value_ref_ptr
release_value (struct value *val)
{
  if (val == nullptr)
    return value_ref_ptr ();

  std::vector<value_ref_ptr>::reverse_iterator iter;
  for (iter = all_values.rbegin (); iter != all_values.rend (); ++iter)
    {
      if (*iter == val)
	{
	  value_ref_ptr result = *iter;
	  all_values.erase (iter.base () - 1);
	  return result;
	}
    }

  /* We must always return an owned reference.  Normally this happens
     because we transfer the reference from the value chain, but in
     this case the value was not on the chain.  */
  return value_ref_ptr::new_reference (val);
}

/* See value.h.  */

std::vector<value_ref_ptr>
value_release_to_mark (const struct value *mark)
{
  std::vector<value_ref_ptr> result;

  auto iter = std::find (all_values.begin (), all_values.end (), mark);
  if (iter == all_values.end ())
    std::swap (result, all_values);
  else
    {
      std::move (iter + 1, all_values.end (), std::back_inserter (result));
      all_values.erase (iter + 1, all_values.end ());
    }
  std::reverse (result.begin (), result.end ());
  return result;
}

/* See value.h.  */

struct value *
value::copy () const
{
  struct type *encl_type = enclosing_type ();
  struct value *val;

  val = value::allocate_lazy (encl_type);
  val->m_type = m_type;
  val->set_lval (m_lval);
  val->m_location = m_location;
  val->m_offset = m_offset;
  val->m_bitpos = m_bitpos;
  val->m_bitsize = m_bitsize;
  val->m_lazy = m_lazy;
  val->m_embedded_offset = embedded_offset ();
  val->m_pointed_to_offset = m_pointed_to_offset;
  val->m_modifiable = m_modifiable;
  val->m_stack = m_stack;
  val->m_is_zero = m_is_zero;
  val->m_in_history = m_in_history;
  val->m_initialized = m_initialized;
  val->m_unavailable = m_unavailable;
  val->m_optimized_out = m_optimized_out;
  val->m_parent = m_parent;
  val->m_limited_length = m_limited_length;

  if (!val->lazy ()
      && !(val->entirely_optimized_out ()
	   || val->entirely_unavailable ()))
    {
      ULONGEST length = val->m_limited_length;
      if (length == 0)
	length = val->enclosing_type ()->length ();

      gdb_assert (m_contents != nullptr);
      const auto &arg_view
	= gdb::make_array_view (m_contents.get (), length);

      val->allocate_contents (false);
      gdb::array_view<gdb_byte> val_contents
	= val->contents_all_raw ().slice (0, length);

      gdb::copy (arg_view, val_contents);
    }

  if (val->lval () == lval_computed)
    {
      const struct lval_funcs *funcs = val->m_location.computed.funcs;

      if (funcs->copy_closure)
	val->m_location.computed.closure = funcs->copy_closure (val);
    }
  return val;
}

/* Return a "const" and/or "volatile" qualified version of the value V.
   If CNST is true, then the returned value will be qualified with
   "const".
   if VOLTL is true, then the returned value will be qualified with
   "volatile".  */

struct value *
make_cv_value (int cnst, int voltl, struct value *v)
{
  struct type *val_type = v->type ();
  struct type *m_enclosing_type = v->enclosing_type ();
  struct value *cv_val = v->copy ();

  cv_val->deprecated_set_type (make_cv_type (cnst, voltl, val_type));
  cv_val->set_enclosing_type (make_cv_type (cnst, voltl, m_enclosing_type));

  return cv_val;
}

/* See value.h.  */

struct value *
value::non_lval ()
{
  if (this->lval () != not_lval)
    {
      struct type *enc_type = enclosing_type ();
      struct value *val = value::allocate (enc_type);

      gdb::copy (contents_all (), val->contents_all_raw ());
      val->m_type = m_type;
      val->set_embedded_offset (embedded_offset ());
      val->set_pointed_to_offset (pointed_to_offset ());
      return val;
    }
  return this;
}

/* See value.h.  */

void
value::force_lval (CORE_ADDR addr)
{
  gdb_assert (this->lval () == not_lval);

  write_memory (addr, contents_raw ().data (), type ()->length ());
  m_lval = lval_memory;
  m_location.address = addr;
}

void
value::set_component_location (const struct value *whole)
{
  struct type *type;

  gdb_assert (whole->m_lval != lval_xcallable);

  if (whole->m_lval == lval_internalvar)
    m_lval = lval_internalvar_component;
  else
    m_lval = whole->m_lval;

  m_location = whole->m_location;
  if (whole->m_lval == lval_computed)
    {
      const struct lval_funcs *funcs = whole->m_location.computed.funcs;

      if (funcs->copy_closure)
	m_location.computed.closure = funcs->copy_closure (whole);
    }

  /* If the WHOLE value has a dynamically resolved location property then
     update the address of the COMPONENT.  */
  type = whole->type ();
  if (dynamic_prop *dyn_prop = type->dyn_prop (DYN_PROP_DATA_LOCATION);
      dyn_prop != nullptr && dyn_prop->is_constant ())
    set_address (dyn_prop->const_val ());

  /* Similarly, if the COMPONENT value has a dynamically resolved location
     property then update its address.  */
  type = this->type ();
  if (dynamic_prop *dyn_prop = type->dyn_prop (DYN_PROP_DATA_LOCATION);
      dyn_prop != nullptr && dyn_prop->is_constant ())
    {
      /* If the COMPONENT has a dynamic location, force it to have lval_memory.

	 The data location, obtained by evaluating the DYN_PROP_DATA_LOCATION
	 property (typically a DWARF DW_AT_data_location attribute), isn't
	 related to the location of the object.  Even if the object is, let's
	 say, a register, evaluating DYN_PROP_DATA_LOCATION yields a different
	 location.  At the moment, we assume that it yields a memory location.
	 But in theory, a DW_AT_data_location attribute could yield any kind of
	 location.

	 Even in the case of internalvars, only the content of the object itself
	 is copied to the internalvar.  If the object has a DYN_PROP_DATA_LOCATION
	 property pointing outside the object, that data isn't captured in the
	 internalvar.  */
      gdb_assert (lazy ());
      m_lval = lval_memory;
      set_address (dyn_prop->const_val ());
    }
}

/* Access to the value history.  */

/* Record a new value in the value history.
   Returns the absolute history index of the entry.  */

int
value::record_latest ()
{
  /* We don't want this value to have anything to do with the inferior anymore.
     In particular, "set $1 = 50" should not affect the variable from which
     the value was taken, and fast watchpoints should be able to assume that
     a value on the value history never changes.  */
  if (lazy ())
    fetch_lazy ();

  /* Mark the value as recorded in the history for the availability check.  */
  m_in_history = true;

  /* We preserve VALUE_LVAL so that the user can find out where it was fetched
     from.  This is a bit dubious, because then *&$1 does not just return $1
     but the current contents of that location.  c'est la vie...  */
  set_modifiable (false);

  value_history.push_back (release_value (this));

  return value_history.size ();
}

/* Return a copy of the value in the history with sequence number NUM.  */

struct value *
access_value_history (int num)
{
  int absnum = num;

  if (absnum <= 0)
    absnum += value_history.size ();

  if (absnum <= 0)
    {
      if (num == 0)
	error (_("The history is empty."));
      else if (num == 1)
	error (_("There is only one value in the history."));
      else
	error (_("History does not go back to $$%d."), -num);
    }
  if (absnum > value_history.size ())
    error (_("History has not yet reached $%d."), absnum);

  absnum--;

  return value_history[absnum]->copy ();
}

/* See value.h.  */

ULONGEST
value_history_count ()
{
  return value_history.size ();
}

static void
show_values (const char *num_exp, int from_tty)
{
  int i;
  struct value *val;
  static int num = 1;

  if (num_exp)
    {
      /* "show values +" should print from the stored position.
	 "show values <exp>" should print around value number <exp>.  */
      if (num_exp[0] != '+' || num_exp[1] != '\0')
	num = parse_and_eval_long (num_exp) - 5;
    }
  else
    {
      /* "show values" means print the last 10 values.  */
      num = value_history.size () - 9;
    }

  if (num <= 0)
    num = 1;

  for (i = num; i < num + 10 && i <= value_history.size (); i++)
    {
      struct value_print_options opts;

      val = access_value_history (i);
      gdb_printf (("$%d = "), i);
      get_user_print_options (&opts);
      value_print (val, gdb_stdout, &opts);
      gdb_printf (("\n"));
    }

  /* The next "show values +" should start after what we just printed.  */
  num += 10;

  /* Hitting just return after this command should do the same thing as
     "show values +".  If num_exp is null, this is unnecessary, since
     "show values +" is not useful after "show values".  */
  if (from_tty && num_exp)
    set_repeat_arguments ("+");
}

enum internalvar_kind
{
  /* The internal variable is empty.  */
  INTERNALVAR_VOID,

  /* The value of the internal variable is provided directly as
     a GDB value object.  */
  INTERNALVAR_VALUE,

  /* A fresh value is computed via a call-back routine on every
     access to the internal variable.  */
  INTERNALVAR_MAKE_VALUE,

  /* The internal variable holds a GDB internal convenience function.  */
  INTERNALVAR_FUNCTION,

  /* The variable holds an integer value.  */
  INTERNALVAR_INTEGER,

  /* The variable holds a GDB-provided string.  */
  INTERNALVAR_STRING,
};

union internalvar_data
{
  /* A value object used with INTERNALVAR_VALUE.  */
  struct value *value;

  /* The call-back routine used with INTERNALVAR_MAKE_VALUE.  */
  struct
  {
    /* The functions to call.  */
    const struct internalvar_funcs *functions;

    /* The function's user-data.  */
    void *data;
  } make_value;

  /* The internal function used with INTERNALVAR_FUNCTION.  */
  struct
  {
    struct internal_function *function;
    /* True if this is the canonical name for the function.  */
    int canonical;
  } fn;

  /* An integer value used with INTERNALVAR_INTEGER.  */
  struct
  {
    /* If type is non-NULL, it will be used as the type to generate
       a value for this internal variable.  If type is NULL, a default
       integer type for the architecture is used.  */
    struct type *type;
    LONGEST val;
  } integer;

  /* A string value used with INTERNALVAR_STRING.  */
  char *string;
};

/* Internal variables.  These are variables within the debugger
   that hold values assigned by debugger commands.
   The user refers to them with a '$' prefix
   that does not appear in the variable names stored internally.  */

struct internalvar
{
  internalvar (std::string name)
    : name (std::move (name))
  {}

  internalvar (internalvar &&other)
    : name (std::move(other.name)),
      kind (other.kind),
      u (other.u)
  {
    other.kind = INTERNALVAR_VOID;
  }

  ~internalvar ()
  {
    clear_internalvar (this);
  }

  std::string name;

  /* We support various different kinds of content of an internal variable.
     enum internalvar_kind specifies the kind, and union internalvar_data
     provides the data associated with this particular kind.  */

  enum internalvar_kind kind = INTERNALVAR_VOID;

  union internalvar_data u {};
};

/* Use std::map, a sorted container, to make the order of iteration (and
   therefore the output of "show convenience") stable.  */

static std::map<std::string, internalvar> internalvars;

/* If the variable does not already exist create it and give it the
   value given.  If no value is given then the default is zero.  */
static void
init_if_undefined_command (const char* args, int from_tty)
{
  struct internalvar *intvar = nullptr;

  /* Parse the expression - this is taken from set_command().  */
  expression_up expr = parse_expression (args);

  /* Validate the expression.
     Was the expression an assignment?
     Or even an expression at all?  */
  if (expr->first_opcode () != BINOP_ASSIGN)
    error (_("Init-if-undefined requires an assignment expression."));

  /* Extract the variable from the parsed expression.  */
  expr::assign_operation *assign
    = dynamic_cast<expr::assign_operation *> (expr->op.get ());
  if (assign != nullptr)
    {
      expr::operation *lhs = assign->get_lhs ();
      expr::internalvar_operation *ivarop
	= dynamic_cast<expr::internalvar_operation *> (lhs);
      if (ivarop != nullptr)
	intvar = ivarop->get_internalvar ();
    }

  if (intvar == nullptr)
    error (_("The first parameter to init-if-undefined "
	     "should be a GDB variable."));

  /* Only evaluate the expression if the lvalue is void.
     This may still fail if the expression is invalid.  */
  if (intvar->kind == INTERNALVAR_VOID)
    expr->evaluate ();
}


/* Look up an internal variable with name NAME.  NAME should not
   normally include a dollar sign.

   If the specified internal variable does not exist,
   the return value is NULL.  */

struct internalvar *
lookup_only_internalvar (const char *name)
{
  auto it = internalvars.find (name);
  if (it == internalvars.end ())
    return nullptr;

  return &it->second;
}

/* Complete NAME by comparing it to the names of internal
   variables.  */

void
complete_internalvar (completion_tracker &tracker, const char *name)
{
  int len = strlen (name);

  for (auto &pair : internalvars)
    {
      const internalvar &var = pair.second;

      if (var.name.compare (0, len, name) == 0)
	tracker.add_completion (make_unique_xstrdup (var.name.c_str ()));
    }
}

/* Create an internal variable with name NAME and with a void value.
   NAME should not normally include a dollar sign.

   An internal variable with that name must not exist already.  */

struct internalvar *
create_internalvar (const char *name)
{
  auto pair = internalvars.emplace (std::make_pair (name, internalvar (name)));
  gdb_assert (pair.second);

  return &pair.first->second;
}

/* Create an internal variable with name NAME and register FUN as the
   function that value_of_internalvar uses to create a value whenever
   this variable is referenced.  NAME should not normally include a
   dollar sign.  DATA is passed uninterpreted to FUN when it is
   called.  CLEANUP, if not NULL, is called when the internal variable
   is destroyed.  It is passed DATA as its only argument.  */

struct internalvar *
create_internalvar_type_lazy (const char *name,
			      const struct internalvar_funcs *funcs,
			      void *data)
{
  struct internalvar *var = create_internalvar (name);

  var->kind = INTERNALVAR_MAKE_VALUE;
  var->u.make_value.functions = funcs;
  var->u.make_value.data = data;
  return var;
}

/* See documentation in value.h.  */

int
compile_internalvar_to_ax (struct internalvar *var,
			   struct agent_expr *expr,
			   struct axs_value *value)
{
  if (var->kind != INTERNALVAR_MAKE_VALUE
      || var->u.make_value.functions->compile_to_ax == NULL)
    return 0;

  var->u.make_value.functions->compile_to_ax (var, expr, value,
					      var->u.make_value.data);
  return 1;
}

/* Look up an internal variable with name NAME.  NAME should not
   normally include a dollar sign.

   If the specified internal variable does not exist,
   one is created, with a void value.  */

struct internalvar *
lookup_internalvar (const char *name)
{
  struct internalvar *var;

  var = lookup_only_internalvar (name);
  if (var)
    return var;

  return create_internalvar (name);
}

/* Return current value of internal variable VAR.  For variables that
   are not inherently typed, use a value type appropriate for GDBARCH.  */

struct value *
value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var)
{
  struct value *val;
  struct trace_state_variable *tsv;

  /* If there is a trace state variable of the same name, assume that
     is what we really want to see.  */
  tsv = find_trace_state_variable (var->name.c_str ());
  if (tsv)
    {
      tsv->value_known = target_get_trace_state_variable_value (tsv->number,
								&(tsv->value));
      if (tsv->value_known)
	val = value_from_longest (builtin_type (gdbarch)->builtin_int64,
				  tsv->value);
      else
	val = value::allocate (builtin_type (gdbarch)->builtin_void);
      return val;
    }

  switch (var->kind)
    {
    case INTERNALVAR_VOID:
      val = value::allocate (builtin_type (gdbarch)->builtin_void);
      break;

    case INTERNALVAR_FUNCTION:
      val = value::allocate (builtin_type (gdbarch)->internal_fn);
      break;

    case INTERNALVAR_INTEGER:
      if (!var->u.integer.type)
	val = value_from_longest (builtin_type (gdbarch)->builtin_int,
				  var->u.integer.val);
      else
	val = value_from_longest (var->u.integer.type, var->u.integer.val);
      break;

    case INTERNALVAR_STRING:
      val = current_language->value_string (gdbarch,
					    var->u.string,
					    strlen (var->u.string));
      break;

    case INTERNALVAR_VALUE:
      val = var->u.value->copy ();
      if (val->lazy ())
	val->fetch_lazy ();
      break;

    case INTERNALVAR_MAKE_VALUE:
      val = (*var->u.make_value.functions->make_value) (gdbarch, var,
							var->u.make_value.data);
      break;

    default:
      internal_error (_("bad kind"));
    }

  /* Change the VALUE_LVAL to lval_internalvar so that future operations
     on this value go back to affect the original internal variable.

     Do not do this for INTERNALVAR_MAKE_VALUE variables, as those have
     no underlying modifiable state in the internal variable.

     Likewise, if the variable's value is a computed lvalue, we want
     references to it to produce another computed lvalue, where
     references and assignments actually operate through the
     computed value's functions.

     This means that internal variables with computed values
     behave a little differently from other internal variables:
     assignments to them don't just replace the previous value
     altogether.  At the moment, this seems like the behavior we
     want.  */

  if (var->kind != INTERNALVAR_MAKE_VALUE
      && val->lval () != lval_computed)
    {
      val->set_lval (lval_internalvar);
      VALUE_INTERNALVAR (val) = var;
    }

  return val;
}

int
get_internalvar_integer (struct internalvar *var, LONGEST *result)
{
  if (var->kind == INTERNALVAR_INTEGER)
    {
      *result = var->u.integer.val;
      return 1;
    }

  if (var->kind == INTERNALVAR_VALUE)
    {
      struct type *type = check_typedef (var->u.value->type ());

      if (type->code () == TYPE_CODE_INT)
	{
	  *result = value_as_long (var->u.value);
	  return 1;
	}
    }

  if (var->kind == INTERNALVAR_MAKE_VALUE)
    {
      struct gdbarch *gdbarch = get_current_arch ();
      struct value *val
	= (*var->u.make_value.functions->make_value) (gdbarch, var,
						      var->u.make_value.data);
      struct type *type = check_typedef (val->type ());

      if (type->code () == TYPE_CODE_INT)
	{
	  *result = value_as_long (val);
	  return 1;
	}
    }

  return 0;
}

static int
get_internalvar_function (struct internalvar *var,
			  struct internal_function **result)
{
  switch (var->kind)
    {
    case INTERNALVAR_FUNCTION:
      *result = var->u.fn.function;
      return 1;

    default:
      return 0;
    }
}

void
set_internalvar_component (struct internalvar *var,
			   LONGEST offset, LONGEST bitpos,
			   LONGEST bitsize, struct value *newval)
{
  gdb_byte *addr;
  struct gdbarch *gdbarch;
  int unit_size;

  switch (var->kind)
    {
    case INTERNALVAR_VALUE:
      addr = var->u.value->contents_writeable ().data ();
      gdbarch = var->u.value->arch ();
      unit_size = gdbarch_addressable_memory_unit_size (gdbarch);

      if (bitsize)
	modify_field (var->u.value->type (), addr + offset,
		      value_as_long (newval), bitpos, bitsize);
      else
	memcpy (addr + offset * unit_size, newval->contents ().data (),
		newval->type ()->length ());
      break;

    default:
      /* We can never get a component of any other kind.  */
      internal_error (_("set_internalvar_component"));
    }
}

void
set_internalvar (struct internalvar *var, struct value *val)
{
  enum internalvar_kind new_kind;
  union internalvar_data new_data = { 0 };

  if (var->kind == INTERNALVAR_FUNCTION && var->u.fn.canonical)
    error (_("Cannot overwrite convenience function %s"), var->name.c_str ());

  /* Prepare new contents.  */
  switch (check_typedef (val->type ())->code ())
    {
    case TYPE_CODE_VOID:
      new_kind = INTERNALVAR_VOID;
      break;

    case TYPE_CODE_INTERNAL_FUNCTION:
      gdb_assert (val->lval () == lval_internalvar);
      new_kind = INTERNALVAR_FUNCTION;
      get_internalvar_function (VALUE_INTERNALVAR (val),
				&new_data.fn.function);
      /* Copies created here are never canonical.  */
      break;

    default:
      new_kind = INTERNALVAR_VALUE;
      struct value *copy = val->copy ();
      copy->set_modifiable (true);

      /* Force the value to be fetched from the target now, to avoid problems
	 later when this internalvar is referenced and the target is gone or
	 has changed.  */
      if (copy->lazy ())
	copy->fetch_lazy ();

      /* Release the value from the value chain to prevent it from being
	 deleted by free_all_values.  From here on this function should not
	 call error () until new_data is installed into the var->u to avoid
	 leaking memory.  */
      new_data.value = release_value (copy).release ();

      /* Internal variables which are created from values with a dynamic
	 location don't need the location property of the origin anymore.
	 The resolved dynamic location is used prior then any other address
	 when accessing the value.
	 If we keep it, we would still refer to the origin value.
	 Remove the location property in case it exist.  */
      new_data.value->type ()->remove_dyn_prop (DYN_PROP_DATA_LOCATION);

      break;
    }

  /* Clean up old contents.  */
  clear_internalvar (var);

  /* Switch over.  */
  var->kind = new_kind;
  var->u = new_data;
  /* End code which must not call error().  */
}

void
set_internalvar_integer (struct internalvar *var, LONGEST l)
{
  /* Clean up old contents.  */
  clear_internalvar (var);

  var->kind = INTERNALVAR_INTEGER;
  var->u.integer.type = NULL;
  var->u.integer.val = l;
}

void
set_internalvar_string (struct internalvar *var, const char *string)
{
  /* Clean up old contents.  */
  clear_internalvar (var);

  var->kind = INTERNALVAR_STRING;
  var->u.string = xstrdup (string);
}

static void
set_internalvar_function (internalvar *var, internal_function_up f)
{
  /* Clean up old contents.  */
  clear_internalvar (var);

  var->kind = INTERNALVAR_FUNCTION;
  var->u.fn.function = f.release ();
  var->u.fn.canonical = 1;
  /* Variables installed here are always the canonical version.  */
}

void
clear_internalvar (struct internalvar *var)
{
  /* Clean up old contents.  */
  switch (var->kind)
    {
    case INTERNALVAR_VALUE:
      var->u.value->decref ();
      break;

    case INTERNALVAR_STRING:
      xfree (var->u.string);
      break;

    case INTERNALVAR_FUNCTION:
      delete var->u.fn.function;
      break;

    default:
      break;
    }

  /* Reset to void kind.  */
  var->kind = INTERNALVAR_VOID;
}

const char *
internalvar_name (const struct internalvar *var)
{
  return var->name.c_str ();
}

const char *
value_internal_function_name (struct value *val)
{
  struct internal_function *ifn;
  int result;

  gdb_assert (val->lval () == lval_internalvar);
  result = get_internalvar_function (VALUE_INTERNALVAR (val), &ifn);
  gdb_assert (result);

  return ifn->name.c_str ();
}

struct value *
call_internal_function (struct gdbarch *gdbarch,
			const struct language_defn *language,
			struct value *func, int argc, struct value **argv,
			enum noside noside)
{
  struct internal_function *ifn;
  int result;

  gdb_assert (func->lval () == lval_internalvar);
  result = get_internalvar_function (VALUE_INTERNALVAR (func), &ifn);
  gdb_assert (result);

  return ifn->handler (gdbarch, language, ifn->cookie, argc, argv, noside);
}

/* The 'function' command.  This does nothing -- it is just a
   placeholder to let "help function NAME" work.  This is also used as
   the implementation of the sub-command that is created when
   registering an internal function.  */
static void
function_command (const char *command, int from_tty)
{
  /* Do nothing.  */
}

/* Helper function that does the work for add_internal_function.  */

static struct cmd_list_element *
do_add_internal_function (const char *name, const char *doc,
			  internal_function_fn_noside handler, void *cookie)
{
  set_internalvar_function (lookup_internalvar (name),
			    std::make_unique<internal_function> (name, handler,
								 cookie));

  return add_cmd (name, no_class, function_command, doc, &functionlist);
}

/* See value.h.  */

void
add_internal_function (const char *name, const char *doc,
		       internal_function_fn_noside handler, void *cookie)
{
  do_add_internal_function (name, doc, handler, cookie);
}

/* By default, internal functions are assumed to return int.  Return a value
   with that type to reflect this.  If this is not correct for a specific
   internal function, it should use an internal_function_fn_noside handler to
   bypass this default.  */

static struct value *
internal_function_default_return_type (struct gdbarch *gdbarch)
{
  return value::zero (builtin_type (gdbarch)->builtin_int, not_lval);
}

/* See value.h.  */

void
add_internal_function (const char *name, const char *doc,
		       internal_function_fn handler, void *cookie)
{
  internal_function_fn_noside fn
    = [=] (struct gdbarch *gdbarch,
	   const struct language_defn *language,
	   void *_cookie,
	   int argc,
	   struct value **argv,
	   enum noside noside)
    {
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	return internal_function_default_return_type (gdbarch);
      return handler (gdbarch, language, _cookie, argc, argv);
    };

  do_add_internal_function (name, doc, fn, cookie);
}

/* See value.h.  */

void
add_internal_function (gdb::unique_xmalloc_ptr<char> &&name,
		       gdb::unique_xmalloc_ptr<char> &&doc,
		       internal_function_fn_noside handler, void *cookie)
{
  struct cmd_list_element *cmd
    = do_add_internal_function (name.get (), doc.get (), handler, cookie);

  /* Manually transfer the ownership of the doc and name strings to CMD by
     setting the appropriate flags.  */
  (void) doc.release ();
  cmd->doc_allocated = 1;
  (void) name.release ();
  cmd->name_allocated = 1;
}

/* See value.h.  */

void
add_internal_function (gdb::unique_xmalloc_ptr<char> &&name,
		       gdb::unique_xmalloc_ptr<char> &&doc,
		       internal_function_fn handler, void *cookie)
{
  internal_function_fn_noside fn
    = [=] (struct gdbarch *gdbarch,
	   const struct language_defn *language,
	   void *_cookie,
	   int argc,
	   struct value **argv,
	   enum noside noside)
    {
      if (noside == EVAL_AVOID_SIDE_EFFECTS)
	return internal_function_default_return_type (gdbarch);
      return handler (gdbarch, language, _cookie, argc, argv);
    };

  add_internal_function (std::forward<gdb::unique_xmalloc_ptr<char>>(name),
			 std::forward<gdb::unique_xmalloc_ptr<char>>(doc),
			 fn, cookie);
}

void
value::preserve (struct objfile *objfile, copied_types_hash_t &copied_types)
{
  if (m_type->objfile_owner () == objfile)
    m_type = copy_type_recursive (m_type, copied_types);

  if (m_enclosing_type->objfile_owner () == objfile)
    m_enclosing_type = copy_type_recursive (m_enclosing_type, copied_types);
}

/* Likewise for internal variable VAR.  */

static void
preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
			  copied_types_hash_t &copied_types)
{
  switch (var->kind)
    {
    case INTERNALVAR_INTEGER:
      if (var->u.integer.type
	  && var->u.integer.type->objfile_owner () == objfile)
	var->u.integer.type
	  = copy_type_recursive (var->u.integer.type, copied_types);
      break;

    case INTERNALVAR_VALUE:
      var->u.value->preserve (objfile, copied_types);
      break;
    }
}

/* Make sure that all types and values referenced by VAROBJ are updated before
   OBJFILE is discarded.  COPIED_TYPES is used to prevent cycles and
   duplicates.  */

static void
preserve_one_varobj (struct varobj *varobj, struct objfile *objfile,
		     copied_types_hash_t &copied_types)
{
  if (varobj->type->is_objfile_owned ()
      && varobj->type->objfile_owner () == objfile)
    {
      varobj->type
	= copy_type_recursive (varobj->type, copied_types);
    }

  if (varobj->value != nullptr)
    varobj->value->preserve (objfile, copied_types);
}

/* Update the internal variables and value history when OBJFILE is
   discarded; we must copy the types out of the objfile.  New global types
   will be created for every convenience variable which currently points to
   this objfile's types, and the convenience variables will be adjusted to
   use the new global types.  */

void
preserve_values (struct objfile *objfile)
{
  /* Create the hash table.  We allocate on the objfile's obstack, since
     it is soon to be deleted.  */
  copied_types_hash_t copied_types;

  for (const value_ref_ptr &item : value_history)
    item->preserve (objfile, copied_types);

  for (auto &pair : internalvars)
    preserve_one_internalvar (&pair.second, objfile, copied_types);

  /* For the remaining varobj, check that none has type owned by OBJFILE.  */
  all_root_varobjs ([&copied_types, objfile] (struct varobj *varobj)
    {
      preserve_one_varobj (varobj, objfile, copied_types);
    });

  preserve_ext_lang_values (objfile, copied_types);
}

static void
show_convenience (const char *ignore, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();
  int varseen = 0;
  struct value_print_options opts;

  get_user_print_options (&opts);
  for (auto &pair : internalvars)
    {
      internalvar &var = pair.second;

      if (!varseen)
	{
	  varseen = 1;
	}
      gdb_printf (("$%s = "), var.name.c_str ());

      try
	{
	  struct value *val;

	  val = value_of_internalvar (gdbarch, &var);
	  value_print (val, gdb_stdout, &opts);
	}
      catch (const gdb_exception_error &ex)
	{
	  fprintf_styled (gdb_stdout, metadata_style.style (),
			  _("<error: %s>"), ex.what ());
	}

      gdb_printf (("\n"));
    }
  if (!varseen)
    {
      /* This text does not mention convenience functions on purpose.
	 The user can't create them except via Python, and if Python support
	 is installed this message will never be printed ($_streq will
	 exist).  */
      gdb_printf (_("No debugger convenience variables now defined.\n"
		    "Convenience variables have "
		    "names starting with \"$\";\n"
		    "use \"%ps\" as in \"%ps\" to define them.\n"),
		  styled_string (command_style.style (), "set"),
		  styled_string (command_style.style (), "set $foo = 5"));
    }
}


/* See value.h.  */

struct value *
value::from_xmethod (xmethod_worker_up &&worker)
{
  struct value *v;

  v = value::allocate (builtin_type (current_inferior ()->arch ())->xmethod);
  v->m_lval = lval_xcallable;
  v->m_location.xm_worker = worker.release ();
  v->m_modifiable = false;

  return v;
}

/* See value.h.  */

struct type *
value::result_type_of_xmethod (gdb::array_view<value *> argv)
{
  gdb_assert (type ()->code () == TYPE_CODE_XMETHOD
	      && m_lval == lval_xcallable && !argv.empty ());

  return m_location.xm_worker->get_result_type (argv[0], argv.slice (1));
}

/* See value.h.  */

struct value *
value::call_xmethod (gdb::array_view<value *> argv)
{
  gdb_assert (type ()->code () == TYPE_CODE_XMETHOD
	      && m_lval == lval_xcallable && !argv.empty ());

  return m_location.xm_worker->invoke (argv[0], argv.slice (1));
}

/* Extract a value as a C number (either long or double).
   Knows how to convert fixed values to double, or
   floating values to long.
   Does not deallocate the value.  */

LONGEST
value_as_long (struct value *val)
{
  /* This coerces arrays and functions, which is necessary (e.g.
     in disassemble_command).  It also dereferences references, which
     I suspect is the most logical thing to do.  */
  val = coerce_array (val);
  return unpack_long (val->type (), val->contents ().data ());
}

/* See value.h.  */

gdb_mpz
value_as_mpz (struct value *val)
{
  val = coerce_array (val);
  struct type *type = check_typedef (val->type ());

  switch (type->code ())
    {
    case TYPE_CODE_ENUM:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
      break;

    default:
      return gdb_mpz (value_as_long (val));
    }

  gdb_mpz result;

  gdb::array_view<const gdb_byte> valbytes = val->contents ();
  enum bfd_endian byte_order = type_byte_order (type);

  /* Handle integers that are either not a multiple of the word size,
     or that are stored at some bit offset.  */
  unsigned bit_off = 0, bit_size = 0;
  if (type->bit_size_differs_p ())
    {
      bit_size = type->bit_size ();
      if (bit_size == 0)
	{
	  /* We can just handle this immediately.  */
	  return result;
	}

      bit_off = type->bit_offset ();

      unsigned n_bytes = ((bit_off % 8) + bit_size + 7) / 8;
      valbytes = valbytes.slice (bit_off / 8, n_bytes);

      if (byte_order == BFD_ENDIAN_BIG)
	bit_off = (n_bytes * 8 - bit_off % 8 - bit_size);
      else
	bit_off %= 8;
    }

  result.read (val->contents (), byte_order, type->is_unsigned ());

  /* Shift off any low bits, if needed.  */
  if (bit_off != 0)
    result >>= bit_off;

  /* Mask off any high bits, if needed.  */
  if (bit_size)
    result.mask (bit_size);

  /* Now handle any range bias.  */
  if (type->code () == TYPE_CODE_RANGE && type->bounds ()->bias != 0)
    {
      /* Unfortunately we have to box here, because LONGEST is
	 probably wider than long.  */
      result += gdb_mpz (type->bounds ()->bias);
    }

  return result;
}

/* Extract a value as a C pointer.  */

CORE_ADDR
value_as_address (struct value *val)
{
  struct gdbarch *gdbarch = val->type ()->arch ();

  /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
     whether we want this to be true eventually.  */
#if 0
  /* gdbarch_addr_bits_remove is wrong if we are being called for a
     non-address (e.g. argument to "signal", "info break", etc.), or
     for pointers to char, in which the low bits *are* significant.  */
  return gdbarch_addr_bits_remove (gdbarch, value_as_long (val));
#else

  /* There are several targets (IA-64, PowerPC, and others) which
     don't represent pointers to functions as simply the address of
     the function's entry point.  For example, on the IA-64, a
     function pointer points to a two-word descriptor, generated by
     the linker, which contains the function's entry point, and the
     value the IA-64 "global pointer" register should have --- to
     support position-independent code.  The linker generates
     descriptors only for those functions whose addresses are taken.

     On such targets, it's difficult for GDB to convert an arbitrary
     function address into a function pointer; it has to either find
     an existing descriptor for that function, or call malloc and
     build its own.  On some targets, it is impossible for GDB to
     build a descriptor at all: the descriptor must contain a jump
     instruction; data memory cannot be executed; and code memory
     cannot be modified.

     Upon entry to this function, if VAL is a value of type `function'
     (that is, TYPE_CODE (val->type ()) == TYPE_CODE_FUNC), then
     val->address () is the address of the function.  This is what
     you'll get if you evaluate an expression like `main'.  The call
     to COERCE_ARRAY below actually does all the usual unary
     conversions, which includes converting values of type `function'
     to `pointer to function'.  This is the challenging conversion
     discussed above.  Then, `unpack_pointer' will convert that pointer
     back into an address.

     So, suppose the user types `disassemble foo' on an architecture
     with a strange function pointer representation, on which GDB
     cannot build its own descriptors, and suppose further that `foo'
     has no linker-built descriptor.  The address->pointer conversion
     will signal an error and prevent the command from running, even
     though the next step would have been to convert the pointer
     directly back into the same address.

     The following shortcut avoids this whole mess.  If VAL is a
     function, just return its address directly.  */
  if (val->type ()->code () == TYPE_CODE_FUNC
      || val->type ()->code () == TYPE_CODE_METHOD)
    return val->address ();

  val = coerce_array (val);

  /* Some architectures (e.g. Harvard), map instruction and data
     addresses onto a single large unified address space.  For
     instance: An architecture may consider a large integer in the
     range 0x10000000 .. 0x1000ffff to already represent a data
     addresses (hence not need a pointer to address conversion) while
     a small integer would still need to be converted integer to
     pointer to address.  Just assume such architectures handle all
     integer conversions in a single function.  */

  /* JimB writes:

     I think INTEGER_TO_ADDRESS is a good idea as proposed --- but we
     must admonish GDB hackers to make sure its behavior matches the
     compiler's, whenever possible.

     In general, I think GDB should evaluate expressions the same way
     the compiler does.  When the user copies an expression out of
     their source code and hands it to a `print' command, they should
     get the same value the compiler would have computed.  Any
     deviation from this rule can cause major confusion and annoyance,
     and needs to be justified carefully.  In other words, GDB doesn't
     really have the freedom to do these conversions in clever and
     useful ways.

     AndrewC pointed out that users aren't complaining about how GDB
     casts integers to pointers; they are complaining that they can't
     take an address from a disassembly listing and give it to `x/i'.
     This is certainly important.

     Adding an architecture method like integer_to_address() certainly
     makes it possible for GDB to "get it right" in all circumstances
     --- the target has complete control over how things get done, so
     people can Do The Right Thing for their target without breaking
     anyone else.  The standard doesn't specify how integers get
     converted to pointers; usually, the ABI doesn't either, but
     ABI-specific code is a more reasonable place to handle it.  */

  if (!val->type ()->is_pointer_or_reference ()
      && gdbarch_integer_to_address_p (gdbarch))
    return gdbarch_integer_to_address (gdbarch, val->type (),
				       val->contents ().data ());

  return unpack_pointer (val->type (), val->contents ().data ());
#endif
}

/* Unpack raw data (copied from debuggee, target byte order) at VALADDR
   as a long, or as a double, assuming the raw data is described
   by type TYPE.  Knows how to convert different sizes of values
   and can convert between fixed and floating point.  We don't assume
   any alignment for the raw data.  Return value is in host byte order.

   If you want functions and arrays to be coerced to pointers, and
   references to be dereferenced, call value_as_long() instead.

   C++: It is assumed that the front-end has taken care of
   all matters concerning pointers to members.  A pointer
   to member which reaches here is considered to be equivalent
   to an INT (or some size).  After all, it is only an offset.  */

LONGEST
unpack_long (struct type *type, const gdb_byte *valaddr)
{
  if (is_fixed_point_type (type))
    type = type->fixed_point_type_base_type ();

  enum bfd_endian byte_order = type_byte_order (type);
  enum type_code code = type->code ();
  int len = type->length ();
  int nosign = type->is_unsigned ();

  switch (code)
    {
    case TYPE_CODE_TYPEDEF:
      return unpack_long (check_typedef (type), valaddr);
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_MEMBERPTR:
      {
	LONGEST result;

	if (type->bit_size_differs_p ())
	  {
	    unsigned bit_off = type->bit_offset ();
	    unsigned bit_size = type->bit_size ();
	    if (bit_size == 0)
	      {
		/* unpack_bits_as_long doesn't handle this case the
		   way we'd like, so handle it here.  */
		result = 0;
	      }
	    else
	      result = unpack_bits_as_long (type, valaddr, bit_off, bit_size);
	  }
	else
	  {
	    if (nosign)
	      result = extract_unsigned_integer (valaddr, len, byte_order);
	    else
	      result = extract_signed_integer (valaddr, len, byte_order);
	  }
	if (code == TYPE_CODE_RANGE)
	  result += type->bounds ()->bias;
	return result;
      }

    case TYPE_CODE_FLT:
    case TYPE_CODE_DECFLOAT:
      return target_float_to_longest (valaddr, type);

    case TYPE_CODE_FIXED_POINT:
      {
	gdb_mpq vq;
	vq.read_fixed_point (gdb::make_array_view (valaddr, len),
			     byte_order, nosign,
			     type->fixed_point_scaling_factor ());

	gdb_mpz vz = vq.as_integer ();
	return vz.as_integer<LONGEST> ();
      }

    case TYPE_CODE_PTR:
    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
      /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
	 whether we want this to be true eventually.  */
      return extract_typed_address (valaddr, type);

    default:
      error (_("Value can't be converted to integer."));
    }
}

/* Unpack raw data (copied from debuggee, target byte order) at VALADDR
   as a CORE_ADDR, assuming the raw data is described by type TYPE.
   We don't assume any alignment for the raw data.  Return value is in
   host byte order.

   If you want functions and arrays to be coerced to pointers, and
   references to be dereferenced, call value_as_address() instead.

   C++: It is assumed that the front-end has taken care of
   all matters concerning pointers to members.  A pointer
   to member which reaches here is considered to be equivalent
   to an INT (or some size).  After all, it is only an offset.  */

CORE_ADDR
unpack_pointer (struct type *type, const gdb_byte *valaddr)
{
  /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
     whether we want this to be true eventually.  */
  return unpack_long (type, valaddr);
}

bool
is_floating_value (struct value *val)
{
  struct type *type = check_typedef (val->type ());

  if (is_floating_type (type))
    {
      if (!target_float_is_valid (val->contents ().data (), type))
	error (_("Invalid floating value found in program."));
      return true;
    }

  return false;
}


/* Get the value of the FIELDNO'th field (which must be static) of
   TYPE.  */

struct value *
value_static_field (struct type *type, int fieldno)
{
  struct value *retval;

  switch (type->field (fieldno).loc_kind ())
    {
    case FIELD_LOC_KIND_PHYSADDR:
      retval = value_at_lazy (type->field (fieldno).type (),
			      type->field (fieldno).loc_physaddr ());
      break;
    case FIELD_LOC_KIND_PHYSNAME:
    {
      const char *phys_name = type->field (fieldno).loc_physname ();
      /* type->field (fieldno).name (); */
      struct block_symbol sym = lookup_symbol (phys_name, nullptr,
					       SEARCH_VAR_DOMAIN, nullptr);

      if (sym.symbol == NULL)
	{
	  /* With some compilers, e.g. HP aCC, static data members are
	     reported as non-debuggable symbols.  */
	  bound_minimal_symbol msym
	    = lookup_minimal_symbol (current_program_space, phys_name);
	  struct type *field_type = type->field (fieldno).type ();

	  if (!msym.minsym)
	    retval = value::allocate_optimized_out (field_type);
	  else
	    retval = value_at_lazy (field_type, msym.value_address ());
	}
      else
	retval = value_of_variable (sym.symbol, sym.block);
      break;
    }
    default:
      gdb_assert_not_reached ("unexpected field location kind");
    }

  return retval;
}

/* Change the enclosing type of a value object VAL to NEW_ENCL_TYPE.
   You have to be careful here, since the size of the data area for the value
   is set by the length of the enclosing type.  So if NEW_ENCL_TYPE is bigger
   than the old enclosing type, you have to allocate more space for the
   data.  */

void
value::set_enclosing_type (struct type *new_encl_type)
{
  if (new_encl_type->length () > enclosing_type ()->length ())
    {
      check_type_length_before_alloc (new_encl_type);
      m_contents.reset ((gdb_byte *) xrealloc (m_contents.release (),
					       new_encl_type->length ()));
    }

  m_enclosing_type = new_encl_type;
}

/* See value.h.  */

struct value *
value::primitive_field (LONGEST offset, int fieldno, struct type *arg_type)
{
  struct value *v;
  struct type *type;
  int unit_size = gdbarch_addressable_memory_unit_size (arch ());

  arg_type = check_typedef (arg_type);
  type = arg_type->field (fieldno).type ();

  /* Call check_typedef on our type to make sure that, if TYPE
     is a TYPE_CODE_TYPEDEF, its length is set to the length
     of the target type instead of zero.  However, we do not
     replace the typedef type by the target type, because we want
     to keep the typedef in order to be able to print the type
     description correctly.  */
  check_typedef (type);

  if (arg_type->field (fieldno).bitsize ())
    {
      /* Handle packed fields.

	 Create a new value for the bitfield, with bitpos and bitsize
	 set.  If possible, arrange offset and bitpos so that we can
	 do a single aligned read of the size of the containing type.
	 Otherwise, adjust offset to the byte containing the first
	 bit.  Assume that the address, offset, and embedded offset
	 are sufficiently aligned.  */

      LONGEST bitpos = arg_type->field (fieldno).loc_bitpos ();
      LONGEST container_bitsize = type->length () * 8;

      v = value::allocate_lazy (type);
      v->set_bitsize (arg_type->field (fieldno).bitsize ());
      if ((bitpos % container_bitsize) + v->bitsize () <= container_bitsize
	  && type->length () <= (int) sizeof (LONGEST))
	v->set_bitpos (bitpos % container_bitsize);
      else
	v->set_bitpos (bitpos % 8);
      v->set_offset ((embedded_offset ()
		      + offset
		      + (bitpos - v->bitpos ()) / 8));
      v->set_parent (this);
      if (!lazy ())
	v->fetch_lazy ();
    }
  else if (fieldno < TYPE_N_BASECLASSES (arg_type))
    {
      /* This field is actually a base subobject, so preserve the
	 entire object's contents for later references to virtual
	 bases, etc.  */
      LONGEST boffset;

      /* Lazy register values with offsets are not supported.  */
      if (this->lval () == 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,
				    contents ().data (),
				    embedded_offset (),
				    address (),
				    this);
      else
	boffset = arg_type->field (fieldno).loc_bitpos () / 8;

      if (lazy ())
	v = value::allocate_lazy (enclosing_type ());
      else
	{
	  v = value::allocate (enclosing_type ());
	  contents_copy_raw (v, 0, 0, enclosing_type ()->length ());
	}
      v->deprecated_set_type (type);
      v->set_offset (this->offset ());
      v->set_embedded_offset (offset + embedded_offset () + boffset);
    }
  else if (NULL != type->dyn_prop (DYN_PROP_DATA_LOCATION))
    {
      /* Field is a dynamic data member.  */

      gdb_assert (0 == offset);
      /* We expect an already resolved data location.  */
      gdb_assert (type->dyn_prop (DYN_PROP_DATA_LOCATION)->is_constant ());
      /* For dynamic data types defer memory allocation
	 until we actual access the value.  */
      v = value::allocate_lazy (type);
    }
  else
    {
      /* Plain old data member */
      offset += (arg_type->field (fieldno).loc_bitpos ()
		 / (HOST_CHAR_BIT * unit_size));

      /* Lazy register values with offsets are not supported.  */
      if (this->lval () == lval_register && lazy ())
	fetch_lazy ();

      if (lazy ())
	v = value::allocate_lazy (type);
      else
	{
	  v = value::allocate (type);
	  contents_copy_raw (v, v->embedded_offset (),
			     embedded_offset () + offset,
			     type_length_units (type));
	}
      v->set_offset (this->offset () + offset + embedded_offset ());
    }
  v->set_component_location (this);
  return v;
}

/* Return a non-virtual function as a value.
   F is the list of member functions which contains the desired method.
   J is an index into F which provides the desired method.

   We only use the symbol for its address, so be happy with either a
   full symbol or a minimal symbol.  */

struct value *
value_fn_field (struct value **arg1p, struct fn_field *f,
		int j, struct type *type,
		LONGEST offset)
{
  struct value *v;
  struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
  const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
  struct symbol *sym;
  bound_minimal_symbol msym;

  sym = lookup_symbol (physname, nullptr, SEARCH_FUNCTION_DOMAIN,
		       nullptr).symbol;
  if (sym == nullptr)
    {
      msym = lookup_minimal_symbol (current_program_space, physname);
      if (msym.minsym == NULL)
	return NULL;
    }

  v = value::allocate (ftype);
  v->set_lval (lval_memory);
  if (sym)
    {
      v->set_address (sym->value_block ()->entry_pc ());
    }
  else
    {
      /* The minimal symbol might point to a function descriptor;
	 resolve it to the actual code address instead.  */
      struct objfile *objfile = msym.objfile;
      struct gdbarch *gdbarch = objfile->arch ();

      v->set_address (gdbarch_convert_from_func_ptr_addr
		      (gdbarch, msym.value_address (),
		       current_inferior ()->top_target ()));
    }

  if (arg1p)
    {
      if (type != (*arg1p)->type ())
	*arg1p = value_ind (value_cast (lookup_pointer_type (type),
					value_addr (*arg1p)));

      /* Move the `this' pointer according to the offset.
	 (*arg1p)->offset () += offset; */
    }

  return v;
}



/* See value.h.  */

LONGEST
unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
		     LONGEST bitpos, LONGEST bitsize)
{
  enum bfd_endian byte_order = type_byte_order (field_type);
  ULONGEST val;
  ULONGEST valmask;
  int lsbcount;
  LONGEST bytes_read;
  LONGEST read_offset;

  /* Read the minimum number of bytes required; there may not be
     enough bytes to read an entire ULONGEST.  */
  field_type = check_typedef (field_type);
  if (bitsize)
    bytes_read = ((bitpos % 8) + bitsize + 7) / 8;
  else
    {
      bytes_read = field_type->length ();
      bitsize = 8 * bytes_read;
    }

  read_offset = bitpos / 8;

  val = extract_unsigned_integer (valaddr + read_offset,
				  bytes_read, byte_order);

  /* Extract bits.  See comment above.  */

  if (byte_order == BFD_ENDIAN_BIG)
    lsbcount = (bytes_read * 8 - bitpos % 8 - bitsize);
  else
    lsbcount = (bitpos % 8);
  val >>= lsbcount;

  /* If the field does not entirely fill a LONGEST, then zero the sign bits.
     If the field is signed, and is negative, then sign extend.  */

  if (bitsize < 8 * (int) sizeof (val))
    {
      valmask = (((ULONGEST) 1) << bitsize) - 1;
      val &= valmask;
      if (!field_type->is_unsigned ())
	{
	  if (val & (valmask ^ (valmask >> 1)))
	    {
	      val |= ~valmask;
	    }
	}
    }

  if (field_type->code () == TYPE_CODE_RANGE)
    val += field_type->bounds ()->bias;

  return val;
}

/* Unpack a field FIELDNO of the specified TYPE, from the object at
   VALADDR + EMBEDDED_OFFSET.  VALADDR points to the contents of
   ORIGINAL_VALUE, which must not be NULL.  See
   unpack_value_bits_as_long for more details.  */

int
unpack_value_field_as_long (struct type *type, const gdb_byte *valaddr,
			    LONGEST embedded_offset, int fieldno,
			    const struct value *val, LONGEST *result)
{
  int bitpos = type->field (fieldno).loc_bitpos ();
  int bitsize = type->field (fieldno).bitsize ();
  struct type *field_type = type->field (fieldno).type ();
  int bit_offset;

  gdb_assert (val != NULL);

  bit_offset = embedded_offset * TARGET_CHAR_BIT + bitpos;
  if (val->bits_any_optimized_out (bit_offset, bitsize)
      || !val->bits_available (bit_offset, bitsize))
    return 0;

  *result = unpack_bits_as_long (field_type, valaddr + embedded_offset,
				 bitpos, bitsize);
  return 1;
}

/* See value.h.  */

LONGEST
unpack_field_as_long (const gdb_byte *valaddr, struct field *field)
{
  int bitpos = field->loc_bitpos ();
  int bitsize = field->bitsize ();
  struct type *field_type = field->type ();

  return unpack_bits_as_long (field_type, valaddr, bitpos, bitsize);
}

/* See value.h.  */

LONGEST
unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
{
  return unpack_field_as_long (valaddr, &type->field (fieldno));
}

/* See value.h.  */

void
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;
  int dst_bit_offset;
  struct type *field_type = dest_val->type ();

  byte_order = type_byte_order (field_type);

  /* First, unpack and sign extend the bitfield as if it was wholly
     valid.  Optimized out/unavailable bits are read as zero, but
     that's OK, as they'll end up marked below.  If the VAL is
     wholly-invalid we may have skipped allocating its contents,
     though.  See value::allocate_optimized_out.  */
  if (valaddr != NULL)
    {
      LONGEST num;

      num = unpack_bits_as_long (field_type, valaddr + embedded_offset,
				 bitpos, bitsize);
      store_signed_integer (dest_val->contents_raw ().data (),
			    field_type->length (), byte_order, num);
    }

  /* Now copy the optimized out / unavailability ranges to the right
     bits.  */
  src_bit_offset = embedded_offset * TARGET_CHAR_BIT + bitpos;
  if (byte_order == BFD_ENDIAN_BIG)
    dst_bit_offset = field_type->length () * TARGET_CHAR_BIT - bitsize;
  else
    dst_bit_offset = 0;
  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
   object at VALADDR + EMBEDDEDOFFSET.  VALADDR points to the contents
   of VAL.  If the VAL's contents required to extract the bitfield
   from are unavailable/optimized out, the new value is
   correspondingly marked unavailable/optimized out.  */

struct value *
value_field_bitfield (struct type *type, int fieldno,
		      const gdb_byte *valaddr,
		      LONGEST embedded_offset, const struct value *val)
{
  int bitpos = type->field (fieldno).loc_bitpos ();
  int bitsize = type->field (fieldno).bitsize ();
  struct value *res_val = value::allocate (type->field (fieldno).type ());

  val->unpack_bitfield (res_val, bitpos, bitsize, valaddr, embedded_offset);

  return res_val;
}

/* Modify the value of a bitfield.  ADDR points to a block of memory in
   target byte order; the bitfield starts in the byte pointed to.  FIELDVAL
   is the desired value of the field, in host byte order.  BITPOS and BITSIZE
   indicate which bits (in target bit order) comprise the bitfield.
   Requires 0 < BITSIZE <= lbits, 0 <= BITPOS % 8 + BITSIZE <= lbits, and
   0 <= BITPOS, where lbits is the size of a LONGEST in bits.  */

void
modify_field (struct type *type, gdb_byte *addr,
	      LONGEST fieldval, LONGEST bitpos, LONGEST bitsize)
{
  enum bfd_endian byte_order = type_byte_order (type);
  ULONGEST oword;
  ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize);
  LONGEST bytesize;

  /* Normalize BITPOS.  */
  addr += bitpos / 8;
  bitpos %= 8;

  /* If a negative fieldval fits in the field in question, chop
     off the sign extension bits.  */
  if ((~fieldval & ~(mask >> 1)) == 0)
    fieldval &= mask;

  /* Warn if value is too big to fit in the field in question.  */
  if (0 != (fieldval & ~mask))
    {
      /* FIXME: would like to include fieldval in the message, but
	 we don't have a sprintf_longest.  */
      warning (_("Value does not fit in %s bits."), plongest (bitsize));

      /* Truncate it, otherwise adjoining fields may be corrupted.  */
      fieldval &= mask;
    }

  /* Ensure no bytes outside of the modified ones get accessed as it may cause
     false valgrind reports.  */

  bytesize = (bitpos + bitsize + 7) / 8;
  oword = extract_unsigned_integer (addr, bytesize, byte_order);

  /* Shifting for bit field depends on endianness of the target machine.  */
  if (byte_order == BFD_ENDIAN_BIG)
    bitpos = bytesize * 8 - bitpos - bitsize;

  oword &= ~(mask << bitpos);
  oword |= fieldval << bitpos;

  store_unsigned_integer (addr, bytesize, byte_order, oword);
}

/* Pack NUM into BUF using a target format of TYPE.  */

void
pack_long (gdb_byte *buf, struct type *type, LONGEST num)
{
  enum bfd_endian byte_order = type_byte_order (type);
  LONGEST len;

  type = check_typedef (type);
  len = type->length ();

  switch (type->code ())
    {
    case TYPE_CODE_RANGE:
      num -= type->bounds ()->bias;
      [[fallthrough]];
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_MEMBERPTR:
      if (type->bit_size_differs_p ())
	{
	  unsigned bit_off = type->bit_offset ();
	  unsigned bit_size = type->bit_size ();
	  num &= ((ULONGEST) 1 << bit_size) - 1;
	  num <<= bit_off;
	}
      store_signed_integer (buf, len, byte_order, num);
      break;

    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
    case TYPE_CODE_PTR:
      store_typed_address (buf, type, (CORE_ADDR) num);
      break;

    case TYPE_CODE_FLT:
    case TYPE_CODE_DECFLOAT:
      target_float_from_longest (buf, type, num);
      break;

    default:
      error (_("Unexpected type (%d) encountered for integer constant."),
	     type->code ());
    }
}


/* Pack NUM into BUF using a target format of TYPE.  */

static void
pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
{
  LONGEST len;
  enum bfd_endian byte_order;

  type = check_typedef (type);
  len = type->length ();
  byte_order = type_byte_order (type);

  switch (type->code ())
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLAGS:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_MEMBERPTR:
      if (type->bit_size_differs_p ())
	{
	  unsigned bit_off = type->bit_offset ();
	  unsigned bit_size = type->bit_size ();
	  num &= ((ULONGEST) 1 << bit_size) - 1;
	  num <<= bit_off;
	}
      store_unsigned_integer (buf, len, byte_order, num);
      break;

    case TYPE_CODE_REF:
    case TYPE_CODE_RVALUE_REF:
    case TYPE_CODE_PTR:
      store_typed_address (buf, type, (CORE_ADDR) num);
      break;

    case TYPE_CODE_FLT:
    case TYPE_CODE_DECFLOAT:
      target_float_from_ulongest (buf, type, num);
      break;

    default:
      error (_("Unexpected type (%d) encountered "
	       "for unsigned integer constant."),
	     type->code ());
    }
}

/* See value.h.  */

struct value *
value::zero (struct type *type, enum lval_type lv)
{
  struct value *val = value::allocate_lazy (type);

  val->set_lval (lv == lval_computed ? not_lval : lv);
  val->m_is_zero = true;
  return val;
}

/* Convert C numbers into newly allocated values.  */

struct value *
value_from_longest (struct type *type, LONGEST num)
{
  struct value *val = value::allocate (type);

  pack_long (val->contents_raw ().data (), type, num);
  return val;
}


/* Convert C unsigned numbers into newly allocated values.  */

struct value *
value_from_ulongest (struct type *type, ULONGEST num)
{
  struct value *val = value::allocate (type);

  pack_unsigned_long (val->contents_raw ().data (), type, num);

  return val;
}

/* See value.h.  */

struct value *
value_from_mpz (struct type *type, const gdb_mpz &v)
{
  struct type *real_type = check_typedef (type);

  const gdb_mpz *val = &v;
  gdb_mpz storage;
  if (real_type->code () == TYPE_CODE_RANGE && type->bounds ()->bias != 0)
    {
      storage = *val;
      val = &storage;
      storage -= type->bounds ()->bias;
    }

  if (type->bit_size_differs_p ())
    {
      unsigned bit_off = type->bit_offset ();
      unsigned bit_size = type->bit_size ();

      if (val != &storage)
	{
	  storage = *val;
	  val = &storage;
	}

      storage.mask (bit_size);
      storage <<= bit_off;
    }

  struct value *result = value::allocate (type);
  val->truncate (result->contents_raw (), type_byte_order (type),
		 type->is_unsigned ());
  return result;
}

/* Create a value representing a pointer of type TYPE to the address
   ADDR.  */

struct value *
value_from_pointer (struct type *type, CORE_ADDR addr)
{
  struct value *val = value::allocate (type);

  store_typed_address (val->contents_raw ().data (),
		       check_typedef (type), addr);
  return val;
}

/* Create and return a value object of TYPE containing the value D.  The
   TYPE must be of TYPE_CODE_FLT, and must be large enough to hold D once
   it is converted to target format.  */

struct value *
value_from_host_double (struct type *type, double d)
{
  struct value *value = value::allocate (type);
  gdb_assert (type->code () == TYPE_CODE_FLT);
  target_float_from_host_double (value->contents_raw ().data (),
				 value->type (), d);
  return value;
}

/* Create a value of type TYPE whose contents come from VALADDR, if it
   is non-null, and whose memory address (in the inferior) is
   ADDRESS.  The type of the created value may differ from the passed
   type TYPE.  Make sure to retrieve values new type after this call.
   Note that TYPE is not passed through resolve_dynamic_type; this is
   a special API intended for use only by Ada.  */

struct value *
value_from_contents_and_address_unresolved (struct type *type,
					    const gdb_byte *valaddr,
					    CORE_ADDR address)
{
  struct value *v;

  if (valaddr == NULL)
    v = value::allocate_lazy (type);
  else
    v = value_from_contents (type, valaddr);
  v->set_lval (lval_memory);
  v->set_address (address);
  return v;
}

/* Create a value of type TYPE whose contents come from VALADDR, if it
   is non-null, and whose memory address (in the inferior) is
   ADDRESS.  The type of the created value may differ from the passed
   type TYPE.  Make sure to retrieve values new type after this call.  */

struct value *
value_from_contents_and_address (struct type *type,
				 const gdb_byte *valaddr,
				 CORE_ADDR address,
				 const frame_info_ptr &frame)
{
  gdb::array_view<const gdb_byte> view;
  if (valaddr != nullptr)
    view = gdb::make_array_view (valaddr, type->length ());
  struct type *resolved_type = resolve_dynamic_type (type, view, address,
						     &frame);
  struct type *resolved_type_no_typedef = check_typedef (resolved_type);

  struct value *v;
  if (resolved_type_no_typedef->code () == TYPE_CODE_ARRAY
      && resolved_type_no_typedef->bound_optimized_out ())
    {
      /* Resolution found that the bounds are optimized out.  In this
	 case, mark the array itself as optimized-out.  */
      v = value::allocate_optimized_out (resolved_type);
    }
  else if (valaddr == nullptr)
    v = value::allocate_lazy (resolved_type);
  else
    v = value_from_contents (resolved_type, valaddr);

  if (dynamic_prop *dyn_prop
	= resolved_type_no_typedef->dyn_prop (DYN_PROP_DATA_LOCATION);
      dyn_prop != nullptr && dyn_prop->is_constant ())
    address = dyn_prop->const_val ();

  v->set_lval (lval_memory);
  v->set_address (address);
  return v;
}

/* Create a value of type TYPE holding the contents CONTENTS.
   The new value is `not_lval'.  */

struct value *
value_from_contents (struct type *type, const gdb_byte *contents)
{
  struct value *result;

  result = value::allocate (type);
  memcpy (result->contents_raw ().data (), contents, type->length ());
  return result;
}

/* Extract a value from the history file.  Input will be of the form
   $digits or $$digits.  See block comment above 'write_dollar_variable'
   for details.  */

struct value *
value_from_history_ref (const char *h, const char **endp)
{
  int index, len;

  if (h[0] == '$')
    len = 1;
  else
    return NULL;

  if (h[1] == '$')
    len = 2;

  /* Find length of numeral string.  */
  for (; c_isdigit (h[len]); len++)
    ;

  /* Make sure numeral string is not part of an identifier.  */
  if (h[len] == '_' || c_isalpha (h[len]))
    return NULL;

  /* Now collect the index value.  */
  if (h[1] == '$')
    {
      if (len == 2)
	{
	  /* For some bizarre reason, "$$" is equivalent to "$$1",
	     rather than to "$$0" as it ought to be!  */
	  index = -1;
	  *endp += len;
	}
      else
	{
	  char *local_end;

	  index = -strtol (&h[2], &local_end, 10);
	  *endp = local_end;
	}
    }
  else
    {
      if (len == 1)
	{
	  /* "$" is equivalent to "$0".  */
	  index = 0;
	  *endp += len;
	}
      else
	{
	  char *local_end;

	  index = strtol (&h[1], &local_end, 10);
	  *endp = local_end;
	}
    }

  return access_value_history (index);
}

/* Get the component value (offset by OFFSET bytes) of a struct or
   union WHOLE.  Component's type is TYPE.  */

struct value *
value_from_component (struct value *whole, struct type *type, LONGEST offset)
{
  struct value *v;

  if (whole->lval () == lval_memory && whole->lazy ())
    v = value::allocate_lazy (type);
  else
    {
      v = value::allocate (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);

  return v;
}

/* See value.h.  */

struct value *
value::from_component_bitsize (struct type *type,
			       LONGEST bit_offset, LONGEST bit_length)
{
  gdb_assert (!lazy ());

  /* Preserve lvalue-ness if possible.  This is needed to avoid
     array-printing failures (including crashes) when printing Ada
     arrays in programs compiled with -fgnat-encodings=all.  */
  if ((bit_offset % TARGET_CHAR_BIT) == 0
      && (bit_length % TARGET_CHAR_BIT) == 0
      && bit_length == TARGET_CHAR_BIT * type->length ())
    return value_from_component (this, type, bit_offset / TARGET_CHAR_BIT);

  struct value *v = value::allocate (type);

  LONGEST dst_offset = TARGET_CHAR_BIT * v->embedded_offset ();
  if (is_scalar_type (type) && type_byte_order (type) == BFD_ENDIAN_BIG)
    dst_offset += TARGET_CHAR_BIT * type->length () - bit_length;

  contents_copy_raw_bitwise (v, dst_offset,
			     TARGET_CHAR_BIT
			     * embedded_offset ()
			     + bit_offset,
			     bit_length);
  return v;
}

struct value *
coerce_ref_if_computed (const struct value *arg)
{
  const struct lval_funcs *funcs;

  if (!TYPE_IS_REFERENCE (check_typedef (arg->type ())))
    return NULL;

  if (arg->lval () != lval_computed)
    return NULL;

  funcs = arg->computed_funcs ();
  if (funcs->coerce_ref == NULL)
    return NULL;

  return funcs->coerce_ref (arg);
}

/* Look at value.h for description.  */

struct value *
readjust_indirect_value_type (struct value *value, struct type *enc_type,
			      const struct type *original_type,
			      struct value *original_value,
			      CORE_ADDR original_value_address)
{
  gdb_assert (original_type->is_pointer_or_reference ());

  struct type *original_target_type = original_type->target_type ();
  gdb::array_view<const gdb_byte> view;
  struct type *resolved_original_target_type
    = resolve_dynamic_type (original_target_type, view,
			    original_value_address);

  /* Re-adjust type.  */
  value->deprecated_set_type (resolved_original_target_type);

  /* Add embedding info.  */
  value->set_enclosing_type (enc_type);
  value->set_embedded_offset (original_value->pointed_to_offset ());

  /* We may be pointing to an object of some derived type.  */
  return value_full_object (value, NULL, 0, 0, 0);
}

struct value *
coerce_ref (struct value *arg)
{
  struct type *value_type_arg_tmp = check_typedef (arg->type ());
  struct value *retval;
  struct type *enc_type;

  retval = coerce_ref_if_computed (arg);
  if (retval)
    return retval;

  if (!TYPE_IS_REFERENCE (value_type_arg_tmp))
    return arg;

  enc_type = check_typedef (arg->enclosing_type ());
  enc_type = enc_type->target_type ();

  CORE_ADDR addr = unpack_pointer (arg->type (), arg->contents ().data ());
  retval = value_at_lazy (enc_type, addr);
  enc_type = retval->type ();
  return readjust_indirect_value_type (retval, enc_type, value_type_arg_tmp,
				       arg, addr);
}

struct value *
coerce_array (struct value *arg)
{
  struct type *type;

  arg = coerce_ref (arg);
  type = check_typedef (arg->type ());

  switch (type->code ())
    {
    case TYPE_CODE_ARRAY:
      if (!type->is_vector () && current_language->c_style_arrays_p ())
	arg = value_coerce_array (arg);
      break;
    case TYPE_CODE_FUNC:
      arg = value_coerce_function (arg);
      break;
    }
  return arg;
}


/* Return the return value convention that will be used for the
   specified type.  */

enum return_value_convention
struct_return_convention (struct gdbarch *gdbarch,
			  struct value *function, struct type *value_type)
{
  enum type_code code = value_type->code ();

  if (code == TYPE_CODE_ERROR)
    error (_("Function return type unknown."));

  /* Probe the architecture for the return-value convention.  */
  return gdbarch_return_value_as_value (gdbarch, function, value_type,
					NULL, NULL, NULL);
}

/* Return true if the function returning the specified type is using
   the convention of returning structures in memory (passing in the
   address as a hidden first parameter).  */

int
using_struct_return (struct gdbarch *gdbarch,
		     struct value *function, struct type *value_type)
{
  if (value_type->code () == TYPE_CODE_VOID)
    /* A void return value is never in memory.  See also corresponding
       code in "print_return_value".  */
    return 0;

  return (struct_return_convention (gdbarch, function, value_type)
	  != RETURN_VALUE_REGISTER_CONVENTION);
}

/* See value.h.  */

void
value::fetch_lazy_bitfield ()
{
  gdb_assert (bitsize () != 0);

  /* To read a lazy bitfield, read the entire enclosing value.  This
     prevents reading the same block of (possibly volatile) memory once
     per bitfield.  It would be even better to read only the containing
     word, but we have no way to record that just specific bits of a
     value have been fetched.  */
  struct value *parent = this->parent ();

  if (parent->lazy ())
    parent->fetch_lazy ();

  parent->unpack_bitfield (this, bitpos (), bitsize (),
			   parent->contents_for_printing ().data (),
			   offset ());
}

/* See value.h.  */

void
value::fetch_lazy_memory ()
{
  gdb_assert (m_lval == lval_memory);

  CORE_ADDR addr = address ();
  struct type *type = check_typedef (enclosing_type ());

  /* Figure out how much we should copy from memory.  Usually, this is just
     the size of the type, but, for arrays, we might only be loading a
     small part of the array (this is only done for very large arrays).  */
  int len = 0;
  if (m_limited_length > 0)
    {
      gdb_assert (this->type ()->code () == TYPE_CODE_ARRAY);
      len = m_limited_length;
    }
  else if (type->length () > 0)
    len = type_length_units (type);

  gdb_assert (len >= 0);

  if (len > 0)
    read_value_memory (this, 0, stack (), addr,
		       contents_all_raw ().data (), len);

  /* If only part of an array was loaded, mark the rest as unavailable.  */
  if (m_limited_length > 0)
    mark_bytes_unavailable (m_limited_length,
			    m_enclosing_type->length () - m_limited_length);
}

/* See value.h.  */

void
value::fetch_lazy_register ()
{
  struct type *type = check_typedef (this->type ());
  struct value *new_val = this;

  scoped_value_mark mark;

  /* Offsets are not supported here; lazy register values must
     refer to the entire register.  */
  gdb_assert (offset () == 0);

  while (new_val->lval () == lval_register && new_val->lazy ())
    {
      frame_id next_frame_id = new_val->next_frame_id ();
      frame_info_ptr next_frame = frame_find_by_id (next_frame_id);
      gdb_assert (next_frame != NULL);

      int regnum = new_val->regnum ();

      /* Convertible register routines are used for multi-register
	 values and for interpretation in different types
	 (e.g. float or int from a double register).  Lazy
	 register values should have the register's natural type,
	 so they do not apply.  */
      gdb_assert (!gdbarch_convert_register_p (get_frame_arch (next_frame),
					       regnum, type));

      new_val = frame_unwind_register_value (next_frame, regnum);

      /* If we get another lazy lval_register value, it means the
	 register is found by reading it from NEXT_FRAME's next frame.
	 frame_unwind_register_value should never return a value with
	 the frame id pointing to NEXT_FRAME.  If it does, it means we
	 either have two consecutive frames with the same frame id
	 in the frame chain, or some code is trying to unwind
	 behind get_prev_frame's back (e.g., a frame unwind
	 sniffer trying to unwind), bypassing its validations.  In
	 any case, it should always be an internal error to end up
	 in this situation.  */
      if (new_val->lval () == lval_register
	  && new_val->lazy ()
	  && new_val->next_frame_id () == next_frame_id)
	internal_error (_("infinite loop while fetching a register"));
    }

  /* If it's still lazy (for instance, a saved register on the
     stack), fetch it.  */
  if (new_val->lazy ())
    new_val->fetch_lazy ();

  /* Copy the contents and the unavailability/optimized-out
     meta-data from NEW_VAL to VAL.  */
  set_lazy (false);
  new_val->contents_copy (this, embedded_offset (),
			  new_val->embedded_offset (),
			  type_length_units (type));

  if (frame_debug)
    {
      frame_info_ptr frame = frame_find_by_id (this->next_frame_id ());
      frame = get_prev_frame_always (frame);
      int regnum = this->regnum ();
      gdbarch *gdbarch = get_frame_arch (frame);

      string_file debug_file;
      gdb_printf (&debug_file,
		  "(frame=%d, regnum=%d(%s), ...) ",
		  frame_relative_level (frame), regnum,
		  user_reg_map_regnum_to_name (gdbarch, regnum));

      gdb_printf (&debug_file, "->");
      if (new_val->optimized_out ())
	{
	  gdb_printf (&debug_file, " ");
	  val_print_optimized_out (new_val, &debug_file);
	}
      else
	{
	  if (new_val->lval () == lval_register)
	    gdb_printf (&debug_file, " register=%d", new_val->regnum ());
	  else if (new_val->lval () == lval_memory)
	    gdb_printf (&debug_file, " address=%s",
			paddress (gdbarch,
				  new_val->address ()));
	  else
	    gdb_printf (&debug_file, " computed");

	  if (new_val->entirely_available ())
	    {
	      int i;
	      gdb::array_view<const gdb_byte> buf = new_val->contents ();

	      gdb_printf (&debug_file, " bytes=");
	      gdb_printf (&debug_file, "[");
	      for (i = 0; i < register_size (gdbarch, regnum); i++)
		gdb_printf (&debug_file, "%02x", buf[i]);
	      gdb_printf (&debug_file, "]");
	    }
	  else if (new_val->entirely_unavailable ())
	    gdb_printf (&debug_file, " unavailable");
	  else
	    gdb_printf (&debug_file, " partly unavailable");
	}

      frame_debug_printf ("%s", debug_file.c_str ());
    }
}

/* See value.h.  */

void
value::fetch_lazy ()
{
  gdb_assert (lazy ());
  allocate_contents (true);
  /* A value is either lazy, or fully fetched.  The
     availability/validity is only established as we try to fetch a
     value.  */
  gdb_assert (m_optimized_out.empty ());
  gdb_assert (m_unavailable.empty ());
  if (m_is_zero)
    {
      /* Nothing.  */
    }
  else if (bitsize ())
    fetch_lazy_bitfield ();
  else if (this->lval () == lval_memory)
    fetch_lazy_memory ();
  else if (this->lval () == lval_register)
    fetch_lazy_register ();
  else if (this->lval () == lval_computed
	   && computed_funcs ()->read != NULL)
    computed_funcs ()->read (this);
  else
    internal_error (_("Unexpected lazy value type."));

  set_lazy (false);
}

/* See value.h.  */

value *
pseudo_from_raw_part (const frame_info_ptr &next_frame, int pseudo_reg_num,
		      int raw_reg_num, int raw_offset)
{
  value *pseudo_reg_val
    = value::allocate_register (next_frame, pseudo_reg_num);
  value *raw_reg_val = value_of_register (raw_reg_num, next_frame);
  raw_reg_val->contents_copy (pseudo_reg_val, 0, raw_offset,
			      pseudo_reg_val->type ()->length ());
  return pseudo_reg_val;
}

/* See value.h.  */

void
pseudo_to_raw_part (const frame_info_ptr &next_frame,
		    gdb::array_view<const gdb_byte> pseudo_buf,
		    int raw_reg_num, int raw_offset)
{
  int raw_reg_size
    = register_size (frame_unwind_arch (next_frame), raw_reg_num);

  /* When overflowing a register, put_frame_register_bytes writes to the
     subsequent registers.  We don't want that behavior here, so make sure
     the write is wholly within register RAW_REG_NUM.  */
  gdb_assert (raw_offset + pseudo_buf.size () <= raw_reg_size);
  put_frame_register_bytes (next_frame, raw_reg_num, raw_offset, pseudo_buf);
}

/* See value.h.  */

value *
pseudo_from_concat_raw (const frame_info_ptr &next_frame, int pseudo_reg_num,
			int raw_reg_1_num, int raw_reg_2_num)
{
  value *pseudo_reg_val
    = value::allocate_register (next_frame, pseudo_reg_num);
  int dst_offset = 0;

  value *raw_reg_1_val = value_of_register (raw_reg_1_num, next_frame);
  raw_reg_1_val->contents_copy (pseudo_reg_val, dst_offset, 0,
				raw_reg_1_val->type ()->length ());
  dst_offset += raw_reg_1_val->type ()->length ();

  value *raw_reg_2_val = value_of_register (raw_reg_2_num, next_frame);
  raw_reg_2_val->contents_copy (pseudo_reg_val, dst_offset, 0,
				raw_reg_2_val->type ()->length ());
  dst_offset += raw_reg_2_val->type ()->length ();

  gdb_assert (dst_offset == pseudo_reg_val->type ()->length ());

  return pseudo_reg_val;
}

/* See value.h. */

void
pseudo_to_concat_raw (const frame_info_ptr &next_frame,
		      gdb::array_view<const gdb_byte> pseudo_buf,
		      int raw_reg_1_num, int raw_reg_2_num)
{
  int src_offset = 0;
  gdbarch *arch = frame_unwind_arch (next_frame);

  int raw_reg_1_size = register_size (arch, raw_reg_1_num);
  put_frame_register (next_frame, raw_reg_1_num,
		      pseudo_buf.slice (src_offset, raw_reg_1_size));
  src_offset += raw_reg_1_size;

  int raw_reg_2_size = register_size (arch, raw_reg_2_num);
  put_frame_register (next_frame, raw_reg_2_num,
		      pseudo_buf.slice (src_offset, raw_reg_2_size));
  src_offset += raw_reg_2_size;

  gdb_assert (src_offset == pseudo_buf.size ());
}

/* See value.h.  */

value *
pseudo_from_concat_raw (const frame_info_ptr &next_frame, int pseudo_reg_num,
			int raw_reg_1_num, int raw_reg_2_num,
			int raw_reg_3_num)
{
  value *pseudo_reg_val
    = value::allocate_register (next_frame, pseudo_reg_num);
  int dst_offset = 0;

  value *raw_reg_1_val = value_of_register (raw_reg_1_num, next_frame);
  raw_reg_1_val->contents_copy (pseudo_reg_val, dst_offset, 0,
				raw_reg_1_val->type ()->length ());
  dst_offset += raw_reg_1_val->type ()->length ();

  value *raw_reg_2_val = value_of_register (raw_reg_2_num, next_frame);
  raw_reg_2_val->contents_copy (pseudo_reg_val, dst_offset, 0,
				raw_reg_2_val->type ()->length ());
  dst_offset += raw_reg_2_val->type ()->length ();

  value *raw_reg_3_val = value_of_register (raw_reg_3_num, next_frame);
  raw_reg_3_val->contents_copy (pseudo_reg_val, dst_offset, 0,
				raw_reg_3_val->type ()->length ());
  dst_offset += raw_reg_3_val->type ()->length ();

  gdb_assert (dst_offset == pseudo_reg_val->type ()->length ());

  return pseudo_reg_val;
}

/* See value.h. */

void
pseudo_to_concat_raw (const frame_info_ptr &next_frame,
		      gdb::array_view<const gdb_byte> pseudo_buf,
		      int raw_reg_1_num, int raw_reg_2_num, int raw_reg_3_num)
{
  int src_offset = 0;
  gdbarch *arch = frame_unwind_arch (next_frame);

  int raw_reg_1_size = register_size (arch, raw_reg_1_num);
  put_frame_register (next_frame, raw_reg_1_num,
		      pseudo_buf.slice (src_offset, raw_reg_1_size));
  src_offset += raw_reg_1_size;

  int raw_reg_2_size = register_size (arch, raw_reg_2_num);
  put_frame_register (next_frame, raw_reg_2_num,
		      pseudo_buf.slice (src_offset, raw_reg_2_size));
  src_offset += raw_reg_2_size;

  int raw_reg_3_size = register_size (arch, raw_reg_3_num);
  put_frame_register (next_frame, raw_reg_3_num,
		      pseudo_buf.slice (src_offset, raw_reg_3_size));
  src_offset += raw_reg_3_size;

  gdb_assert (src_offset == pseudo_buf.size ());
}

/* Implementation of the convenience function $_isvoid.  */

static struct value *
isvoid_internal_fn (struct gdbarch *gdbarch,
		    const struct language_defn *language,
		    void *cookie, int argc, struct value **argv)
{
  int ret;

  if (argc != 1)
    error (_("You must provide one argument for $_isvoid."));

  ret = argv[0]->type ()->code () == TYPE_CODE_VOID;

  return value_from_longest (builtin_type (gdbarch)->builtin_int, ret);
}

/* Implementation of the convenience function $_creal.  Extracts the
   real part from a complex number.  */

static struct value *
creal_internal_fn (struct gdbarch *gdbarch,
		   const struct language_defn *language,
		   void *cookie, int argc, struct value **argv,
		   enum noside noside)
{
  if (argc != 1)
    error (_("You must provide one argument for $_creal."));

  value *cval = argv[0];
  type *ctype = check_typedef (cval->type ());
  if (ctype->code () != TYPE_CODE_COMPLEX)
    error (_("expected a complex number"));
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value::zero (ctype->target_type (), not_lval);
  return value_real_part (cval);
}

/* Implementation of the convenience function $_cimag.  Extracts the
   imaginary part from a complex number.  */

static struct value *
cimag_internal_fn (struct gdbarch *gdbarch,
		   const struct language_defn *language,
		   void *cookie, int argc,
		   struct value **argv, enum noside noside)
{
  if (argc != 1)
    error (_("You must provide one argument for $_cimag."));

  value *cval = argv[0];
  type *ctype = check_typedef (cval->type ());
  if (ctype->code () != TYPE_CODE_COMPLEX)
    error (_("expected a complex number"));
  if (noside == EVAL_AVOID_SIDE_EFFECTS)
    return value::zero (ctype->target_type (), not_lval);
  return value_imaginary_part (cval);
}

#if GDB_SELF_TEST
namespace selftests
{

/* Test the ranges_contain function.  */

static void
test_ranges_contain ()
{
  std::vector<range> ranges;
  range r;

  /* [10, 14] */
  r.offset = 10;
  r.length = 5;
  ranges.push_back (r);

  /* [20, 24] */
  r.offset = 20;
  r.length = 5;
  ranges.push_back (r);

  /* [2, 6] */
  SELF_CHECK (!ranges_contain (ranges, 2, 5));
  /* [9, 13] */
  SELF_CHECK (ranges_contain (ranges, 9, 5));
  /* [10, 11] */
  SELF_CHECK (ranges_contain (ranges, 10, 2));
  /* [10, 14] */
  SELF_CHECK (ranges_contain (ranges, 10, 5));
  /* [13, 18] */
  SELF_CHECK (ranges_contain (ranges, 13, 6));
  /* [14, 18] */
  SELF_CHECK (ranges_contain (ranges, 14, 5));
  /* [15, 18] */
  SELF_CHECK (!ranges_contain (ranges, 15, 4));
  /* [16, 19] */
  SELF_CHECK (!ranges_contain (ranges, 16, 4));
  /* [16, 21] */
  SELF_CHECK (ranges_contain (ranges, 16, 6));
  /* [21, 21] */
  SELF_CHECK (ranges_contain (ranges, 21, 1));
  /* [21, 25] */
  SELF_CHECK (ranges_contain (ranges, 21, 5));
  /* [26, 28] */
  SELF_CHECK (!ranges_contain (ranges, 26, 3));
}

/* Check that RANGES contains the same ranges as EXPECTED.  */

static bool
check_ranges_vector (gdb::array_view<const range> ranges,
		     gdb::array_view<const range> expected)
{
  return ranges == expected;
}

/* Test the insert_into_bit_range_vector function.  */

static void
test_insert_into_bit_range_vector ()
{
  std::vector<range> ranges;

  /* [10, 14] */
  {
    insert_into_bit_range_vector (&ranges, 10, 5);
    static const range expected[] = {
      {10, 5}
    };
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }

  /* [10, 14] */
  {
    insert_into_bit_range_vector (&ranges, 11, 4);
    static const range expected = {10, 5};
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }

  /* [10, 14] [20, 24] */
  {
    insert_into_bit_range_vector (&ranges, 20, 5);
    static const range expected[] = {
      {10, 5},
      {20, 5},
    };
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }

  /* [10, 14] [17, 24] */
  {
    insert_into_bit_range_vector (&ranges, 17, 5);
    static const range expected[] = {
      {10, 5},
      {17, 8},
    };
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }

  /* [2, 8] [10, 14] [17, 24] */
  {
    insert_into_bit_range_vector (&ranges, 2, 7);
    static const range expected[] = {
      {2, 7},
      {10, 5},
      {17, 8},
    };
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }

  /* [2, 14] [17, 24] */
  {
    insert_into_bit_range_vector (&ranges, 9, 1);
    static const range expected[] = {
      {2, 13},
      {17, 8},
    };
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }

  /* [2, 14] [17, 24] */
  {
    insert_into_bit_range_vector (&ranges, 9, 1);
    static const range expected[] = {
      {2, 13},
      {17, 8},
    };
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }

  /* [2, 33] */
  {
    insert_into_bit_range_vector (&ranges, 4, 30);
    static const range expected = {2, 32};
    SELF_CHECK (check_ranges_vector (ranges, expected));
  }
}

static void
test_value_copy ()
{
  type *type = builtin_type (current_inferior ()->arch ())->builtin_int;

  /* Verify that we can copy an entirely optimized out value, that may not have
     its contents allocated.  */
  value_ref_ptr val = release_value (value::allocate_optimized_out (type));
  value_ref_ptr copy = release_value (val->copy ());

  SELF_CHECK (val->entirely_optimized_out ());
  SELF_CHECK (copy->entirely_optimized_out ());
}

} /* namespace selftests */
#endif /* GDB_SELF_TEST */

INIT_GDB_FILE (values)
{
  cmd_list_element *show_convenience_cmd
    = add_cmd ("convenience", no_class, show_convenience, _("\
Debugger convenience (\"$foo\") variables and functions.\n\
Convenience variables are created when you assign them values;\n\
thus, \"set $foo=1\" gives \"$foo\" the value 1.  Values may be any type.\n\
\n\
A few convenience variables are given values automatically:\n\
\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
\"$__\" holds the contents of the last address examined with \"x\"."
#ifdef HAVE_PYTHON
"\n\n\
Convenience functions are defined via the Python API."
#endif
	   ), &showlist);
  add_alias_cmd ("conv", show_convenience_cmd, no_class, 1, &showlist);

  add_cmd ("values", no_set_class, show_values, _("\
Elements of value history around item number IDX (or last ten)."),
	   &showlist);

  add_com ("init-if-undefined", class_vars, init_if_undefined_command, _("\
Initialize a convenience variable if necessary.\n\
init-if-undefined VARIABLE = EXPRESSION\n\
Set an internal VARIABLE to the result of the EXPRESSION if it does not\n\
exist or does not contain a value.  The EXPRESSION is not evaluated if the\n\
VARIABLE is already initialized."));

  add_prefix_cmd ("function", no_class, function_command, _("\
Placeholder command for showing help on convenience functions."),
		  &functionlist, 0, &cmdlist);

  add_internal_function ("_isvoid", _("\
Check whether an expression is void.\n\
Usage: $_isvoid (expression)\n\
Return 1 if the expression is void, zero otherwise."),
			 isvoid_internal_fn, NULL);

  add_internal_function ("_creal", _("\
Extract the real part of a complex number.\n\
Usage: $_creal (expression)\n\
Return the real part of a complex number, the type depends on the\n\
type of a complex number."),
			 creal_internal_fn, NULL);

  add_internal_function ("_cimag", _("\
Extract the imaginary part of a complex number.\n\
Usage: $_cimag (expression)\n\
Return the imaginary part of a complex number, the type depends on the\n\
type of a complex number."),
			 cimag_internal_fn, NULL);

  add_setshow_zuinteger_unlimited_cmd ("max-value-size",
				       class_support, &max_value_size, _("\
Set maximum sized value gdb will load from the inferior."), _("\
Show maximum sized value gdb will load from the inferior."), _("\
Use this to control the maximum size, in bytes, of a value that gdb\n\
will load from the inferior.  Setting this value to 'unlimited'\n\
disables checking.\n\
Setting this does not invalidate already allocated values, it only\n\
prevents future values, larger than this size, from being allocated."),
			    set_max_value_size,
			    show_max_value_size,
			    &setlist, &showlist);
  set_show_commands vsize_limit
    = add_setshow_zuinteger_unlimited_cmd ("varsize-limit", class_support,
					   &max_value_size, _("\
Set the maximum number of bytes allowed in a variable-size object."), _("\
Show the maximum number of bytes allowed in a variable-size object."), _("\
Attempts to access an object whose size is not a compile-time constant\n\
and exceeds this limit will cause an error."),
					   NULL, NULL, &setlist, &showlist);
  deprecate_cmd (vsize_limit.set, "set max-value-size");

#if GDB_SELF_TEST
  selftests::register_test ("ranges_contain", selftests::test_ranges_contain);
  selftests::register_test ("insert_into_bit_range_vector",
			    selftests::test_insert_into_bit_range_vector);
  selftests::register_test ("value_copy", selftests::test_value_copy);
#endif

  /* Destroy any values currently allocated in a final cleanup instead
     of leaving it to global destructors, because that may be too
     late.  For example, the destructors of xmethod values call into
     the Python runtime.  */
  add_final_cleanup ([] ()
    {
      all_values.clear ();
    });
}
