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

   Copyright (C) 1986-2023 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 "defs.h"
#include "arch-utils.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcore.h"
#include "command.h"
#include "gdbcmd.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 <ctype.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/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
{
  /* 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.  */
  char *name;

  /* The handler.  */
  internal_function_fn handler;

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

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

static int
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 int
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 afterall), 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 1;
    }

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

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

  return 0;
}

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

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

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

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

int
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 1;
  return 0;
}

/* See value.h.  */

int
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 1;
    }

  return 0;
}

/* 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 afterall), 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
gdb_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 (max_value_size > -1 && length > max_value_size)
    {
      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));
    }
}

/* 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 gdb::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 = 0;
  return val;
}

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

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

/* 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 (0);
  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);

  /* 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));

  /* Copy the data.  */
  gdb::array_view<gdb_byte> dst_contents
    = dst->contents_all_raw ().slice (dst_offset * unit_size,
					  length * unit_size);
  gdb::array_view<const gdb_byte> src_contents
    = contents_all_raw ().slice (src_offset * unit_size,
				 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);

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

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

int
value::bits_synthetic_pointer (LONGEST offset, LONGEST length) const
{
  if (m_lval != lval_computed
      || !m_location.computed.funcs->check_synthetic_pointer)
    return 0;
  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 (NULL != TYPE_DATA_LOCATION (type ()))
    {
      gdb_assert (PROP_CONST == TYPE_DATA_LOCATION_KIND (type ()));
      return TYPE_DATA_LOCATION_ADDR (type ());
    }

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

struct frame_id *
value::deprecated_next_frame_id_hack ()
{
  gdb_assert (m_lval == lval_register);
  return &m_location.reg.next_frame_id;
}

int *
value::deprecated_regnum_hack ()
{
  gdb_assert (m_lval == lval_register);
  return &m_location.reg.regnum;
}


/* 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, NULL));
  cv_val->set_enclosing_type (make_cv_type (cnst, voltl, m_enclosing_type, NULL));

  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 (NULL != TYPE_DATA_LOCATION (type)
      && TYPE_DATA_LOCATION_KIND (type) == PROP_CONST)
    set_address (TYPE_DATA_LOCATION_ADDR (type));

  /* Similarly, if the COMPONENT value has a dynamically resolved location
     property then update its address.  */
  type = this->type ();
  if (NULL != TYPE_DATA_LOCATION (type)
      && TYPE_DATA_LOCATION_KIND (type) == PROP_CONST)
    {
      /* If the COMPONENT has a dynamic location, and is an
	 lval_internalvar_component, then we change it to a lval_memory.

	 Usually a component of an internalvar is created non-lazy, and has
	 its content immediately copied from the parent internalvar.
	 However, for components with a dynamic location, the content of
	 the component is not contained within the parent, but is instead
	 accessed indirectly.  Further, the component will be created as a
	 lazy value.

	 By changing the type of the component to lval_memory we ensure
	 that value_fetch_lazy can successfully load the component.

         This solution isn't ideal, but a real fix would require values to
         carry around both the parent value contents, and the contents of
         any dynamic fields within the parent.  This is a substantial
         change to how values work in GDB.  */
      if (this->lval () == lval_internalvar_component)
	{
	  gdb_assert (lazy ());
	  m_lval = lval_memory;
	}
      else
	gdb_assert (this->lval () == lval_memory);
      set_address (TYPE_DATA_LOCATION_ADDR (type));
    }
}

/* 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 ())
    {
      /* We know that this is a _huge_ array, any attempt to fetch this
	 is going to cause GDB to throw an error.  However, to allow
	 the array to still be displayed we fetch its contents up to
	 `max_value_size' and mark anything beyond "unavailable" in
	 the history.  */
      if (m_type->code () == TYPE_CODE_ARRAY
	  && m_type->length () > max_value_size
	  && array_length_limiting_element_count.has_value ()
	  && m_enclosing_type == m_type
	  && calculate_limited_array_length (m_type) <= max_value_size)
	m_limited_length = max_value_size;

      fetch_lazy ();
    }

  ULONGEST limit = m_limited_length;
  if (limit != 0)
    mark_bytes_unavailable (limit, m_enclosing_type->length () - limit);

  /* 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 (0);

  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))
  {}

  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)
    evaluate_expression (expr.get ());
}


/* 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 = value_cstring (var->u.string, strlen (var->u.string),
			   builtin_type (gdbarch)->builtin_char);
      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;
	}
    }

  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 (1);

      /* 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 (struct internalvar *var, struct internal_function *f)
{
  /* Clean up old contents.  */
  clear_internalvar (var);

  var->kind = INTERNALVAR_FUNCTION;
  var->u.fn.function = f;
  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;

    default:
      break;
    }

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

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

static struct internal_function *
create_internal_function (const char *name,
			  internal_function_fn handler, void *cookie)
{
  struct internal_function *ifn = XNEW (struct internal_function);

  ifn->name = xstrdup (name);
  ifn->handler = handler;
  ifn->cookie = cookie;
  return ifn;
}

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

struct value *
call_internal_function (struct gdbarch *gdbarch,
			const struct language_defn *language,
			struct value *func, int argc, struct value **argv)
{
  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);
}

/* 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 handler, void *cookie)
{
  struct internal_function *ifn;
  struct internalvar *var = lookup_internalvar (name);

  ifn = create_internal_function (name, handler, cookie);
  set_internalvar_function (var, ifn);

  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 handler, void *cookie)
{
  do_add_internal_function (name, doc, handler, cookie);
}

/* 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)
{
  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;
}

void
value::preserve (struct objfile *objfile, htab_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,
			  htab_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,
		     htab_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.  */
  htab_up copied_types = create_copied_types_hash ();

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

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

  /* 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.get ());
    });

  preserve_ext_lang_values (objfile, copied_types.get ());
}

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 \"set\" as in \"set "
		    "$foo = 5\" to define them.\n"));
    }
}


/* See value.h.  */

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

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

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

/* Extract a value as a C pointer.  Does not deallocate the value.
   Note that val's type may not actually be a pointer; value_as_long
   handles all the cases.  */
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_long' 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_long (val->type (), val->contents ().data ());
#endif
}

/* Unpack raw data (copied from debugee, 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;
	mpz_tdiv_q (vz.val, mpq_numref (vq.val), mpq_denref (vq.val));
	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 debugee, 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, 0, VAR_DOMAIN, 0);

      if (sym.symbol == NULL)
	{
	  /* With some compilers, e.g. HP aCC, static data members are
	     reported as non-debuggable symbols.  */
	  struct bound_minimal_symbol msym
	    = lookup_minimal_symbol (phys_name, NULL, NULL);
	  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 (TYPE_FIELD_BITSIZE (arg_type, fieldno))
    {
      /* 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 (TYPE_FIELD_BITSIZE (arg_type, fieldno));
      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_DATA_LOCATION (type))
    {
      /* Field is a dynamic data member.  */

      gdb_assert (0 == offset);
      /* We expect an already resolved data location.  */
      gdb_assert (PROP_CONST == TYPE_DATA_LOCATION_KIND (type));
      /* 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;
}

/* Given a value ARG1 of a struct or union type,
   extract and return the value of one of its (non-static) fields.
   FIELDNO says which field.  */

struct value *
value_field (struct value *arg1, int fieldno)
{
  return arg1->primitive_field (0, fieldno, arg1->type ());
}

/* 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;
  struct bound_minimal_symbol msym;

  sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0).symbol;
  if (sym == nullptr)
    {
      msym = lookup_bound_minimal_symbol (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;
	    }
	}
    }

  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_BITSIZE (type, fieldno);
  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;
}

/* Unpack a field FIELDNO of the specified TYPE, from the anonymous
   object at VALADDR.  See unpack_bits_as_long for more details.  */

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

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

/* 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_BITSIZE (type, fieldno);
  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;
      /* Fall through.  */
    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;
}


/* 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)
{
  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);
  struct type *resolved_type_no_typedef = check_typedef (resolved_type);
  struct value *v;

  if (valaddr == NULL)
    v = value::allocate_lazy (resolved_type);
  else
    v = value_from_contents (resolved_type, valaddr);
  if (TYPE_DATA_LOCATION (resolved_type_no_typedef) != NULL
      && TYPE_DATA_LOCATION_KIND (resolved_type_no_typedef) == PROP_CONST)
    address = TYPE_DATA_LOCATION_ADDR (resolved_type_no_typedef);
  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 (; isdigit (h[len]); len++)
    ;

  /* Make sure numeral string is not part of an identifier.  */
  if (h[len] == '_' || 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);
}

/* See value.h.  */

void
value::fetch_lazy_register ()
{
  frame_info_ptr next_frame;
  int regnum;
  struct type *type = check_typedef (this->type ());
  struct value *new_val = this, *mark = value_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 ())
    {
      struct frame_id next_frame_id = VALUE_NEXT_FRAME_ID (new_val);

      next_frame = frame_find_by_id (next_frame_id);
      regnum = VALUE_REGNUM (new_val);

      gdb_assert (next_frame != NULL);

      /* 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));

      /* FRAME was obtained, above, via VALUE_NEXT_FRAME_ID.
	 Since a "->next" operation was performed when setting
	 this field, we do not need to perform a "next" operation
	 again when unwinding the register.  That's why
	 frame_unwind_register_value() is called here instead of
	 get_frame_register_value().  */
      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 ()
	  && VALUE_NEXT_FRAME_ID (new_val) == 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 (0);
  new_val->contents_copy (this, embedded_offset (),
			  new_val->embedded_offset (),
			  type_length_units (type));

  if (frame_debug)
    {
      struct gdbarch *gdbarch;
      frame_info_ptr frame;
      frame = frame_find_by_id (VALUE_NEXT_FRAME_ID (this));
      frame = get_prev_frame_always (frame);
      regnum = VALUE_REGNUM (this);
      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
	{
	  int i;
	  gdb::array_view<const gdb_byte> buf = new_val->contents ();

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

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

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

  /* Dispose of the intermediate values.  This prevents
     watchpoints from trying to watch the saved frame pointer.  */
  value_free_to_mark (mark);
}

/* 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 (0);
}

/* 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)
{
  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"));
  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)
{
  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"));
  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 ()->gdbarch)->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 */

void _initialize_values ();
void
_initialize_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
}

/* See value.h.  */

void
finalize_values ()
{
  all_values.clear ();
}
