/* Python interface to values.

   Copyright (C) 2008-2025 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 "top.h"
#include "charset.h"
#include "value.h"
#include "language.h"
#include "target-float.h"
#include "valprint.h"
#include "infcall.h"
#include "expression.h"
#include "cp-abi.h"
#include "python.h"
#include "ada-lang.h"

#include "python-internal.h"

/* Even though Python scalar types directly map to host types, we use
   target types here to remain consistent with the values system in
   GDB (which uses target arithmetic).  */

/* Python's integer type corresponds to C's long type.  */
#define builtin_type_pyint \
  builtin_type (gdbpy_enter::get_gdbarch ())->builtin_long

/* Python's float type corresponds to C's double type.  */
#define builtin_type_pyfloat \
  builtin_type (gdbpy_enter::get_gdbarch ())->builtin_double

/* Python's long type corresponds to C's long long type.  */
#define builtin_type_pylong \
  builtin_type (gdbpy_enter::get_gdbarch ())->builtin_long_long

/* Python's long type corresponds to C's long long type.  Unsigned version.  */
#define builtin_type_upylong builtin_type \
  (gdbpy_enter::get_gdbarch ())->builtin_unsigned_long_long

#define builtin_type_pybool \
  language_bool_type (current_language, gdbpy_enter::get_gdbarch ())

struct value_object {
  PyObject_HEAD
  struct value_object *next;
  struct value_object *prev;
  struct value *value;
  PyObject *address;
  PyObject *dynamic_type;
  PyObject *content_bytes;
};

/* List of all values which are currently exposed to Python. It is
   maintained so that when an objfile is discarded, preserve_values
   can copy the values' types if needed.  */
/* This variable is unnecessarily initialized to NULL in order to
   work around a linker bug on MacOS.  */
static value_object *values_in_python = NULL;

/* Clear out an old GDB value stored within SELF, and reset the fields to
   nullptr.  This should be called when a gdb.Value is deallocated, and
   also if a gdb.Value is reinitialized with a new value.  */

static void
valpy_clear_value (value_object *self)
{
  /* Indicate we are no longer interested in the value object.  */
  self->value->decref ();
  self->value = nullptr;

  Py_CLEAR (self->address);
  Py_CLEAR (self->content_bytes);
}

/* Called by the Python interpreter when deallocating a value object.  */
static void
valpy_dealloc (PyObject *obj)
{
  value_object *self = (value_object *) obj;

  /* If SELF failed to initialize correctly then it may not have a value
     contained within it.  */
  if (self->value != nullptr)
    {
      /* Remove SELF from the global list of values.  */
      if (self->prev != nullptr)
	self->prev->next = self->next;
      else
	{
	  gdb_assert (values_in_python == self);
	  values_in_python = self->next;
	}
      if (self->next != nullptr)
	self->next->prev = self->prev;

      /* Release the value object and any cached Python objects.  */
      valpy_clear_value (self);
    }

  Py_TYPE (self)->tp_free (self);
}

/* Helper to push a gdb.Value object on to the global list of values.  If
   VALUE_OBJ is already on the lit then this does nothing.  */

static void
note_value (value_object *value_obj)
{
  if (value_obj->next == nullptr)
    {
      gdb_assert (value_obj->prev == nullptr);
      value_obj->next = values_in_python;
      if (value_obj->next != nullptr)
	value_obj->next->prev = value_obj;
      values_in_python = value_obj;
    }
}

/* Convert a python object OBJ with type TYPE to a gdb value.  The
   python object in question must conform to the python buffer
   protocol.  On success, return the converted value, otherwise
   nullptr.  When REQUIRE_EXACT_SIZE_P is true the buffer OBJ must be the
   exact length of TYPE.  When REQUIRE_EXACT_SIZE_P is false then the
   buffer OBJ can be longer than TYPE, in which case only the least
   significant bytes from the buffer are used.  */

static struct value *
convert_buffer_and_type_to_value (PyObject *obj, struct type *type,
				  bool require_exact_size_p)
{
  Py_buffer_up buffer_up;
  Py_buffer py_buf;

  if (PyObject_CheckBuffer (obj) 
      && PyObject_GetBuffer (obj, &py_buf, PyBUF_SIMPLE) == 0)
    {
      /* Got a buffer, py_buf, out of obj.  Cause it to be released
	 when it goes out of scope.  */
      buffer_up.reset (&py_buf);
    }
  else
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Object must support the python buffer protocol."));
      return nullptr;
    }

  if (require_exact_size_p && type->length () != py_buf.len)
    {
      PyErr_SetString (PyExc_ValueError,
		       _("Size of type is not equal to that of buffer object."));
      return nullptr;
    }
  else if (!require_exact_size_p && type->length () > py_buf.len)
    {
      PyErr_SetString (PyExc_ValueError,
		       _("Size of type is larger than that of buffer object."));
      return nullptr;
    }

  return value_from_contents (type, (const gdb_byte *) py_buf.buf);
}

/* Implement gdb.Value.__init__.  */

static int
valpy_init (PyObject *self, PyObject *args, PyObject *kwds)
{
  static const char *keywords[] = { "val", "type", NULL };
  PyObject *val_obj = nullptr;
  PyObject *type_obj = nullptr;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwds, "O|O", keywords,
					&val_obj, &type_obj))
    return -1;

  struct type *type = nullptr;
  if (type_obj != nullptr && type_obj != Py_None)
    {
      type = type_object_to_type (type_obj);
      if (type == nullptr)
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("type argument must be a gdb.Type."));
	  return -1;
	}
    }

  struct value *value;
  if (type == nullptr)
    value = convert_value_from_python (val_obj);
  else
    value = convert_buffer_and_type_to_value (val_obj, type, false);
  if (value == nullptr)
    {
      gdb_assert (PyErr_Occurred ());
      return -1;
    }

  /* There might be a previous value here.  */
  value_object *value_obj = (value_object *) self;
  if (value_obj->value != nullptr)
    valpy_clear_value (value_obj);

  /* Store the value into this Python object.  */
  value_obj->value = release_value (value).release ();

  /* Ensure that this gdb.Value is in the set of all gdb.Value objects.  If
     we are already in the set then this is call does nothing.  */
  note_value (value_obj);

  return 0;
}

/* Iterate over all the Value objects, calling preserve_one_value on
   each.  */
void
gdbpy_preserve_values (const struct extension_language_defn *extlang,
		       struct objfile *objfile,
		       copied_types_hash_t &copied_types)
{
  value_object *iter;

  for (iter = values_in_python; iter; iter = iter->next)
    iter->value->preserve (objfile, copied_types);
}

/* Given a value of a pointer type, apply the C unary * operator to it.  */
static PyObject *
valpy_dereference (PyObject *self, PyObject *args)
{
  PyObject *result = NULL;

  try
    {
      struct value *res_val;
      scoped_value_mark free_values;

      res_val = value_ind (((value_object *) self)->value);
      result = value_to_value_object (res_val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Given a value of a pointer type or a reference type, return the value
   referenced. The difference between this function and valpy_dereference is
   that the latter applies * unary operator to a value, which need not always
   result in the value referenced. For example, for a value which is a reference
   to an 'int' pointer ('int *'), valpy_dereference will result in a value of
   type 'int' while valpy_referenced_value will result in a value of type
   'int *'.  */

static PyObject *
valpy_referenced_value (PyObject *self, PyObject *args)
{
  PyObject *result = NULL;

  try
    {
      struct value *self_val, *res_val;
      scoped_value_mark free_values;

      self_val = ((value_object *) self)->value;
      switch (check_typedef (self_val->type ())->code ())
	{
	case TYPE_CODE_PTR:
	  res_val = value_ind (self_val);
	  break;
	case TYPE_CODE_REF:
	case TYPE_CODE_RVALUE_REF:
	  res_val = coerce_ref (self_val);
	  break;
	default:
	  error(_("Trying to get the referenced value from a value which is "
		  "neither a pointer nor a reference."));
	}

      result = value_to_value_object (res_val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Return a value which is a reference to the value.  */

static PyObject *
valpy_reference_value (PyObject *self, PyObject *args, enum type_code refcode)
{
  PyObject *result = NULL;

  try
    {
      struct value *self_val;
      scoped_value_mark free_values;

      self_val = ((value_object *) self)->value;
      result = value_to_value_object (value_ref (self_val, refcode));
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

static PyObject *
valpy_lvalue_reference_value (PyObject *self, PyObject *args)
{
  return valpy_reference_value (self, args, TYPE_CODE_REF);
}

static PyObject *
valpy_rvalue_reference_value (PyObject *self, PyObject *args)
{
  return valpy_reference_value (self, args, TYPE_CODE_RVALUE_REF);
}

/* Implement Value.to_array.  */

static PyObject *
valpy_to_array (PyObject *self, PyObject *args)
{
  PyObject *result = nullptr;

  try
    {
      struct value *val = ((value_object *) self)->value;
      struct type *type = check_typedef (val->type ());

      if (type->code () == TYPE_CODE_ARRAY)
	{
	  result = self;
	  Py_INCREF (result);
	}
      else
	{
	  val = value_to_array (val);
	  if (val == nullptr)
	    PyErr_SetString (PyExc_TypeError, _("Value is not array-like."));
	  else
	    result = value_to_value_object (val);
	}
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Return a "const" qualified version of the value.  */

static PyObject *
valpy_const_value (PyObject *self, PyObject *args)
{
  PyObject *result = NULL;

  try
    {
      struct value *self_val, *res_val;
      scoped_value_mark free_values;

      self_val = ((value_object *) self)->value;
      res_val = make_cv_value (1, 0, self_val);
      result = value_to_value_object (res_val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Return "&value".  */
static PyObject *
valpy_get_address (PyObject *self, void *closure)
{
  value_object *val_obj = (value_object *) self;

  if (!val_obj->address)
    {
      try
	{
	  struct value *res_val;
	  scoped_value_mark free_values;

	  res_val = value_addr (val_obj->value);
	  val_obj->address = value_to_value_object (res_val);
	}
      catch (const gdb_exception_forced_quit &except)
	{
	  quit_force (NULL, 0);
	}
      catch (const gdb_exception &except)
	{
	  val_obj->address = Py_None;
	  Py_INCREF (Py_None);
	}
    }

  Py_XINCREF (val_obj->address);

  return val_obj->address;
}

/* Return type of the value.  */
static PyObject *
valpy_get_type (PyObject *self, void *closure)
{
  value_object *obj = (value_object *) self;

  return type_to_type_object (obj->value->type ());
}

/* Return dynamic type of the value.  */

static PyObject *
valpy_get_dynamic_type (PyObject *self, void *closure)
{
  value_object *obj = (value_object *) self;
  struct type *type = nullptr;

  try
    {
      struct value *val = obj->value;
      scoped_value_mark free_values;

      type = val->type ();
      type = check_typedef (type);

      if (type->is_pointer_or_reference ()
	  && (type->target_type ()->code () == TYPE_CODE_STRUCT))
	{
	  struct value *target;
	  int was_pointer = type->code () == TYPE_CODE_PTR;

	  if (was_pointer)
	    target = value_ind (val);
	  else
	    target = coerce_ref (val);
	  type = value_rtti_type (target, NULL, NULL, NULL);

	  if (type)
	    {
	      if (was_pointer)
		type = lookup_pointer_type (type);
	      else
		type = lookup_lvalue_reference_type (type);
	    }
	}
      else if (type->code () == TYPE_CODE_STRUCT)
	type = value_rtti_type (val, NULL, NULL, NULL);
      else
	type = val->type ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return type_to_type_object (type);
}

/* Implementation of gdb.Value.lazy_string ([encoding] [, length]) ->
   string.  Return a PyObject representing a lazy_string_object type.
   A lazy string is a pointer to a string with an optional encoding and
   length.  If ENCODING is not given, encoding is set to None.  If an
   ENCODING is provided the encoding parameter is set to ENCODING, but
   the string is not encoded.
   If LENGTH is provided then the length parameter is set to LENGTH.
   Otherwise if the value is an array of known length then the array's length
   is used.  Otherwise the length will be set to -1 (meaning first null of
   appropriate with).  */

static PyObject *
valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
{
  gdb_py_longest length = -1;
  struct value *value = ((value_object *) self)->value;
  const char *user_encoding = NULL;
  static const char *keywords[] = { "encoding", "length", NULL };
  PyObject *str_obj = NULL;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG,
					keywords, &user_encoding, &length))
    return NULL;

  if (length < -1)
    {
      PyErr_SetString (PyExc_ValueError, _("Invalid length."));
      return NULL;
    }

  try
    {
      scoped_value_mark free_values;
      struct type *type, *realtype;
      CORE_ADDR addr;

      type = value->type ();
      realtype = check_typedef (type);

      switch (realtype->code ())
	{
	case TYPE_CODE_ARRAY:
	  {
	    LONGEST array_length = -1;
	    LONGEST low_bound, high_bound;

	    /* PR 20786: There's no way to specify an array of length zero.
	       Record a length of [0,-1] which is how Ada does it.  Anything
	       we do is broken, but this one possible solution.  */
	    if (get_array_bounds (realtype, &low_bound, &high_bound))
	      array_length = high_bound - low_bound + 1;
	    if (length == -1)
	      length = array_length;
	    else if (array_length == -1)
	      {
		type = lookup_array_range_type (realtype->target_type (),
						0, length - 1);
	      }
	    else if (length != array_length)
	      {
		/* We need to create a new array type with the
		   specified length.  */
		if (length > array_length)
		  error (_("Length is larger than array size."));
		type = lookup_array_range_type (realtype->target_type (),
						low_bound,
						low_bound + length - 1);
	      }
	    addr = value->address ();
	    break;
	  }
	case TYPE_CODE_PTR:
	  /* If a length is specified we defer creating an array of the
	     specified width until we need to.  */
	  addr = value_as_address (value);
	  break;
	default:
	  error (_("Cannot make lazy string from this object"));
	}

      str_obj = gdbpy_create_lazy_string_object (addr, length, user_encoding,
						 type);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return str_obj;
}

/* Implementation of gdb.Value.string ([encoding] [, errors]
   [, length]) -> string.  Return Unicode string with value contents.
   If ENCODING is not given, the string is assumed to be encoded in
   the target's charset.  If LENGTH is provided, only fetch string to
   the length provided.  */

static PyObject *
valpy_string (PyObject *self, PyObject *args, PyObject *kw)
{
  int length = -1;
  gdb::unique_xmalloc_ptr<gdb_byte> buffer;
  struct value *value = ((value_object *) self)->value;
  const char *encoding = NULL;
  const char *errors = NULL;
  const char *user_encoding = NULL;
  const char *la_encoding = NULL;
  struct type *char_type;
  static const char *keywords[] = { "encoding", "errors", "length", NULL };

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords,
					&user_encoding, &errors, &length))
    return NULL;

  try
    {
      c_get_string (value, &buffer, &length, &char_type, &la_encoding);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
  return PyUnicode_Decode ((const char *) buffer.get (),
			   length * char_type->length (),
			   encoding, errors);
}

/* Given a Python object, copy its truth value to a C bool (the value
   pointed by dest).
   If src_obj is NULL, then *dest is not modified.

   Return true in case of success (including src_obj being NULL), false
   in case of error.  */

static bool
copy_py_bool_obj (bool *dest, PyObject *src_obj)
{
  if (src_obj)
    {
      int cmp = PyObject_IsTrue (src_obj);
      if (cmp < 0)
	return false;
      *dest = cmp;
    }

  return true;
}

/* Implementation of gdb.Value.format_string (...) -> string.
   Return Unicode string with value contents formatted using the
   keyword-only arguments.  */

static PyObject *
valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
{
  static const char *keywords[] =
    {
      /* Basic C/C++ options.  */
      "raw",			/* See the /r option to print.  */
      "pretty_arrays",		/* See set print array on|off.  */
      "pretty_structs",		/* See set print pretty on|off.  */
      "array_indexes",		/* See set print array-indexes on|off.  */
      "symbols",		/* See set print symbol on|off.  */
      "unions",			/* See set print union on|off.  */
      "address",		/* See set print address on|off.  */
      "styling",		/* Should we apply styling.  */
      "nibbles",		/* See set print nibbles on|off.  */
      "summary",		/* Summary mode for non-scalars.  */
      /* C++ options.  */
      "deref_refs",		/* No corresponding setting.  */
      "actual_objects",		/* See set print object on|off.  */
      "static_members",		/* See set print static-members on|off.  */
      /* C non-bool options.  */
      "max_characters", 	/* See set print characters N.  */
      "max_elements", 		/* See set print elements N.  */
      "max_depth",		/* See set print max-depth N.  */
      "repeat_threshold",	/* See set print repeats.  */
      "format",			/* The format passed to the print command.  */
      NULL
    };

  /* This function has too many arguments to be useful as positionals, so
     the user should specify them all as keyword arguments.
     Python 3.3 and later have a way to specify it (both in C and Python
     itself), but we could be compiled with older versions, so we just
     check that the args tuple is empty.  */
  Py_ssize_t positional_count = PyObject_Length (args);
  if (positional_count < 0)
    return NULL;
  else if (positional_count > 0)
    {
      /* This matches the error message that Python 3.3 raises when
	 passing positionals to functions expecting keyword-only
	 arguments.  */
      PyErr_Format (PyExc_TypeError,
		    "format_string() takes 0 positional arguments but %zu were given",
		    positional_count);
      return NULL;
    }

  struct value_print_options opts;
  gdbpy_get_print_options (&opts);
  opts.deref_ref = false;

  /* We need objects for booleans as the "p" flag for bools is new in
     Python 3.3.  */
  PyObject *raw_obj = NULL;
  PyObject *pretty_arrays_obj = NULL;
  PyObject *pretty_structs_obj = NULL;
  PyObject *array_indexes_obj = NULL;
  PyObject *symbols_obj = NULL;
  PyObject *unions_obj = NULL;
  PyObject *address_obj = NULL;
  PyObject *styling_obj = Py_False;
  PyObject *nibbles_obj = NULL;
  PyObject *deref_refs_obj = NULL;
  PyObject *actual_objects_obj = NULL;
  PyObject *static_members_obj = NULL;
  PyObject *summary_obj = NULL;
  char *format = NULL;
  if (!gdb_PyArg_ParseTupleAndKeywords (args,
					kw,
					"|O!O!O!O!O!O!O!O!O!O!O!O!O!IIIIs",
					keywords,
					&PyBool_Type, &raw_obj,
					&PyBool_Type, &pretty_arrays_obj,
					&PyBool_Type, &pretty_structs_obj,
					&PyBool_Type, &array_indexes_obj,
					&PyBool_Type, &symbols_obj,
					&PyBool_Type, &unions_obj,
					&PyBool_Type, &address_obj,
					&PyBool_Type, &styling_obj,
					&PyBool_Type, &nibbles_obj,
					&PyBool_Type, &summary_obj,
					&PyBool_Type, &deref_refs_obj,
					&PyBool_Type, &actual_objects_obj,
					&PyBool_Type, &static_members_obj,
					&opts.print_max_chars,
					&opts.print_max,
					&opts.max_depth,
					&opts.repeat_count_threshold,
					&format))
    return NULL;

  /* Set boolean arguments.  */
  if (!copy_py_bool_obj (&opts.raw, raw_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.prettyformat_arrays, pretty_arrays_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.prettyformat_structs, pretty_structs_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.print_array_indexes, array_indexes_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.symbol_print, symbols_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.unionprint, unions_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.addressprint, address_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.nibblesprint, nibbles_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.deref_ref, deref_refs_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.objectprint, actual_objects_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.static_field_print, static_members_obj))
    return NULL;
  if (!copy_py_bool_obj (&opts.summary, summary_obj))
    return nullptr;

  /* Numeric arguments for which 0 means unlimited (which we represent as
     UINT_MAX).  Note that the max-depth numeric argument uses -1 as
     unlimited, and 0 is a valid choice.  */
  if (opts.print_max == 0)
    opts.print_max = UINT_MAX;
  if (opts.repeat_count_threshold == 0)
    opts.repeat_count_threshold = UINT_MAX;

  /* Other arguments.  */
  if (format != NULL)
    {
      if (strlen (format) == 1)
	opts.format = format[0];
      else
	{
	  /* Mimic the message on standard Python ones for similar
	     errors.  */
	  PyErr_SetString (PyExc_ValueError,
			   "a single character is required");
	  return NULL;
	}
    }

  /* We force styling_obj to be a 'bool' when we parse the args above.  */
  gdb_assert (PyBool_Check (styling_obj));
  string_file stb (styling_obj == Py_True);

  try
    {
      common_val_print (((value_object *) self)->value, &stb, 0,
			&opts, current_language);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return PyUnicode_Decode (stb.c_str (), stb.size (), host_charset (), NULL);
}

/* A helper function that implements the various cast operators.  */

static PyObject *
valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
{
  PyObject *type_obj, *result = NULL;
  struct type *type;

  if (! PyArg_ParseTuple (args, "O", &type_obj))
    return NULL;

  type = type_object_to_type (type_obj);
  if (! type)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Argument must be a type."));
      return NULL;
    }

  try
    {
      struct value *val = ((value_object *) self)->value;
      struct value *res_val;
      scoped_value_mark free_values;

      if (op == UNOP_DYNAMIC_CAST)
	res_val = value_dynamic_cast (type, val);
      else if (op == UNOP_REINTERPRET_CAST)
	res_val = value_reinterpret_cast (type, val);
      else
	{
	  gdb_assert (op == UNOP_CAST);
	  res_val = value_cast (type, val);
	}

      result = value_to_value_object (res_val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Implementation of the "cast" method.  */

static PyObject *
valpy_cast (PyObject *self, PyObject *args)
{
  return valpy_do_cast (self, args, UNOP_CAST);
}

/* Implementation of the "dynamic_cast" method.  */

static PyObject *
valpy_dynamic_cast (PyObject *self, PyObject *args)
{
  return valpy_do_cast (self, args, UNOP_DYNAMIC_CAST);
}

/* Implementation of the "reinterpret_cast" method.  */

static PyObject *
valpy_reinterpret_cast (PyObject *self, PyObject *args)
{
  return valpy_do_cast (self, args, UNOP_REINTERPRET_CAST);
}

/* Assign NEW_VALUE into SELF, handles 'struct value' reference counting,
   and also clearing the bytes data cached within SELF.  Return true if
   the assignment was successful, otherwise return false, in which case a
   Python exception will be set.  */

static bool
valpy_assign_core (value_object *self, struct value *new_value)
{
  try
    {
      new_value = value_assign (self->value, new_value);

      /* value_as_address returns a new value with the same location
	 as the old one.  Ensure that this gdb.Value is updated to
	 reflect the new value.  */
      new_value->incref ();
      self->value->decref ();
      Py_CLEAR (self->content_bytes);
      self->value = new_value;
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (false, except);
    }

  return true;
}

/* Implementation of the "assign" method.  */

static PyObject *
valpy_assign (PyObject *self_obj, PyObject *args)
{
  PyObject *val_obj;

  if (! PyArg_ParseTuple (args, "O", &val_obj))
    return nullptr;

  struct value *val = convert_value_from_python (val_obj);
  if (val == nullptr)
    return nullptr;

  value_object *self = (value_object *) self_obj;
  if (!valpy_assign_core (self, val))
    return nullptr;

  Py_RETURN_NONE;
}

static Py_ssize_t
valpy_length (PyObject *self)
{
  /* We don't support getting the number of elements in a struct / class.  */
  PyErr_SetString (PyExc_NotImplementedError,
		   _("Invalid operation on gdb.Value."));
  return -1;
}

/* Return 1 if the gdb.Field object FIELD is present in the value V.
   Returns 0 otherwise.  If any Python error occurs, -1 is returned.  */

static int
value_has_field (struct value *v, PyObject *field)
{
  struct type *parent_type, *val_type;
  enum type_code type_code;
  gdbpy_ref<> type_object (PyObject_GetAttrString (field, "parent_type"));
  int has_field = 0;

  if (type_object == NULL)
    return -1;

  parent_type = type_object_to_type (type_object.get ());
  if (parent_type == NULL)
    {
      PyErr_SetString (PyExc_TypeError,
		       _("'parent_type' attribute of gdb.Field object is not a"
			 "gdb.Type object."));
      return -1;
    }

  try
    {
      val_type = v->type ();
      val_type = check_typedef (val_type);
      if (val_type->is_pointer_or_reference ())
	val_type = check_typedef (val_type->target_type ());

      type_code = val_type->code ();
      if ((type_code == TYPE_CODE_STRUCT || type_code == TYPE_CODE_UNION)
	  && types_equal (val_type, parent_type))
	has_field = 1;
      else
	has_field = 0;
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (-1, except);
    }

  return has_field;
}

/* Return the value of a flag FLAG_NAME in a gdb.Field object FIELD.
   Returns 1 if the flag value is true, 0 if it is false, and -1 if
   a Python error occurs.  */

static int
get_field_flag (PyObject *field, const char *flag_name)
{
  gdbpy_ref<> flag_object (PyObject_GetAttrString (field, flag_name));

  if (flag_object == NULL)
    return -1;

  return PyObject_IsTrue (flag_object.get ());
}

/* Return the "type" attribute of a gdb.Field object.
   Returns NULL on error, with a Python exception set.  */

static struct type *
get_field_type (PyObject *field)
{
  gdbpy_ref<> ftype_obj (PyObject_GetAttrString (field, "type"));
  struct type *ftype;

  if (ftype_obj == NULL)
    return NULL;
  ftype = type_object_to_type (ftype_obj.get ());
  if (ftype == NULL)
    PyErr_SetString (PyExc_TypeError,
		     _("'type' attribute of gdb.Field object is not a "
		       "gdb.Type object."));

  return ftype;
}

/* Given string name or a gdb.Field object corresponding to an element inside
   a structure, return its value object.  Returns NULL on error, with a python
   exception set.  */

static PyObject *
valpy_getitem (PyObject *self, PyObject *key)
{
  value_object *self_value = (value_object *) self;
  gdb::unique_xmalloc_ptr<char> field;
  struct type *base_class_type = NULL, *field_type = NULL;
  long bitpos = -1;
  PyObject *result = NULL;

  if (gdbpy_is_string (key))
    {
      field = python_string_to_host_string (key);
      if (field == NULL)
	return NULL;
    }
  else if (gdbpy_is_field (key))
    {
      int is_base_class, valid_field;

      valid_field = value_has_field (self_value->value, key);
      if (valid_field < 0)
	return NULL;
      else if (valid_field == 0)
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("Invalid lookup for a field not contained in "
			     "the value."));

	  return NULL;
	}

      is_base_class = get_field_flag (key, "is_base_class");
      if (is_base_class < 0)
	return NULL;
      else if (is_base_class > 0)
	{
	  base_class_type = get_field_type (key);
	  if (base_class_type == NULL)
	    return NULL;
	}
      else
	{
	  gdbpy_ref<> name_obj (PyObject_GetAttrString (key, "name"));

	  if (name_obj == NULL)
	    return NULL;

	  if (name_obj != Py_None)
	    {
	      field = python_string_to_host_string (name_obj.get ());
	      if (field == NULL)
		return NULL;
	    }
	  else
	    {
	      if (!PyObject_HasAttrString (key, "bitpos"))
		{
		  PyErr_SetString (PyExc_AttributeError,
				   _("gdb.Field object has no name and no "
				     "'bitpos' attribute."));

		  return NULL;
		}
	      gdbpy_ref<> bitpos_obj (PyObject_GetAttrString (key, "bitpos"));
	      if (bitpos_obj == NULL)
		return NULL;
	      if (!gdb_py_int_as_long (bitpos_obj.get (), &bitpos))
		return NULL;

	      field_type = get_field_type (key);
	      if (field_type == NULL)
		return NULL;
	    }
	}
    }

  try
    {
      struct value *tmp = self_value->value;
      struct value *res_val = NULL;
      scoped_value_mark free_values;

      if (field)
	res_val = value_struct_elt (&tmp, {}, field.get (), NULL,
				    "struct/class/union");
      else if (bitpos >= 0)
	res_val = value_struct_elt_bitpos (tmp, bitpos, field_type);
      else if (base_class_type != NULL)
	{
	  struct type *val_type;

	  val_type = check_typedef (tmp->type ());
	  if (val_type->code () == TYPE_CODE_PTR)
	    res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
	  else if (val_type->code () == TYPE_CODE_REF)
	    res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
				  tmp);
	  else if (val_type->code () == TYPE_CODE_RVALUE_REF)
	    res_val = value_cast (lookup_rvalue_reference_type (base_class_type),
				  tmp);
	  else
	    res_val = value_cast (base_class_type, tmp);
	}
      else
	{
	  /* Assume we are attempting an array access, and let the
	     value code throw an exception if the index has an invalid
	     type.  */
	  struct value *idx = convert_value_from_python (key);

	  if (idx != NULL
	      && binop_user_defined_p (BINOP_SUBSCRIPT, tmp, idx))
	    res_val = value_x_binop (tmp, idx, BINOP_SUBSCRIPT,
				     OP_NULL, EVAL_NORMAL);
	  else if (idx != NULL)
	    {
	      /* Check the value's type is something that can be accessed via
		 a subscript.  */
	      struct type *type;

	      tmp = coerce_ref (tmp);
	      type = check_typedef (tmp->type ());
	      if (type->code () != TYPE_CODE_ARRAY
		  && type->code () != TYPE_CODE_PTR)
		  error (_("Cannot subscript requested type."));
	      else if (ADA_TYPE_P (type))
		res_val = ada_value_subscript (tmp, 1, &idx);
	      else
		res_val = value_subscript (tmp, value_as_long (idx));
	    }
	}

      if (res_val)
	result = value_to_value_object (res_val);
    }
  catch (const gdb_exception &ex)
    {
      return gdbpy_handle_gdb_exception (nullptr, ex);
    }

  return result;
}

static int
valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
{
  PyErr_Format (PyExc_NotImplementedError,
		_("Setting of struct elements is not currently supported."));
  return -1;
}

/* Called by the Python interpreter to perform an inferior function
   call on the value.  Returns NULL on error, with a python exception set.  */
static PyObject *
valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
{
  Py_ssize_t args_count;
  struct value *function = ((value_object *) self)->value;
  struct value **vargs = NULL;
  struct type *ftype = NULL;
  PyObject *result = NULL;

  try
    {
      ftype = check_typedef (function->type ());
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (ftype->code () != TYPE_CODE_FUNC && ftype->code () != TYPE_CODE_METHOD
      && ftype->code () != TYPE_CODE_INTERNAL_FUNCTION)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Value is not callable (not TYPE_CODE_FUNC"
			 " or TYPE_CODE_METHOD"
			 " or TYPE_CODE_INTERNAL_FUNCTION)."));
      return NULL;
    }

  if (! PyTuple_Check (args))
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Inferior arguments must be provided in a tuple."));
      return NULL;
    }

  args_count = PyTuple_Size (args);
  if (args_count > 0)
    {
      int i;

      vargs = XALLOCAVEC (struct value *, args_count);
      for (i = 0; i < args_count; i++)
	{
	  PyObject *item = PyTuple_GetItem (args, i);

	  if (item == NULL)
	    return NULL;

	  vargs[i] = convert_value_from_python (item);
	  if (vargs[i] == NULL)
	    return NULL;
	}
    }

  try
    {
      scoped_value_mark free_values;

      value *return_value;
      if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION)
	return_value = call_internal_function (gdbpy_enter::get_gdbarch (),
					       current_language,
					       function, args_count, vargs,
					       EVAL_NORMAL);
      else
	return_value
	  = call_function_by_hand (function, NULL,
				   gdb::make_array_view (vargs, args_count));
      result = value_to_value_object (return_value);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Called by the Python interpreter to obtain string representation
   of the object.  */
static PyObject *
valpy_str (PyObject *self)
{
  struct value_print_options opts;

  gdbpy_get_print_options (&opts);
  opts.deref_ref = false;

  string_file stb;

  try
    {
      common_val_print (((value_object *) self)->value, &stb, 0,
			&opts, current_language);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return PyUnicode_Decode (stb.c_str (), stb.size (), host_charset (), NULL);
}

/* Implements gdb.Value.is_optimized_out.  */
static PyObject *
valpy_get_is_optimized_out (PyObject *self, void *closure)
{
  struct value *value = ((value_object *) self)->value;
  int opt = 0;

  try
    {
      opt = value->optimized_out ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (opt)
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* Implements gdb.Value.is_lazy.  */
static PyObject *
valpy_get_is_lazy (PyObject *self, void *closure)
{
  struct value *value = ((value_object *) self)->value;
  int opt = 0;

  try
    {
      opt = value->lazy ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (opt)
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* Get gdb.Value.bytes attribute.  */

static PyObject *
valpy_get_bytes (PyObject *self, void *closure)
{
  value_object *value_obj = (value_object *) self;
  struct value *value = value_obj->value;

  if (value_obj->content_bytes != nullptr)
    {
      Py_INCREF (value_obj->content_bytes);
      return value_obj->content_bytes;
    }

  gdb::array_view<const gdb_byte> contents;
  try
    {
      contents = value->contents ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  value_obj->content_bytes
    =  PyBytes_FromStringAndSize ((const char *) contents.data (),
				  contents.size ());
  Py_XINCREF (value_obj->content_bytes);
  return value_obj->content_bytes;
}

/* Set gdb.Value.bytes attribute.  */

static int
valpy_set_bytes (PyObject *self_obj, PyObject *new_value_obj, void *closure)
{
  value_object *self = (value_object *) self_obj;

  /* Create a new value from the buffer NEW_VALUE_OBJ.  We pass true here
     to indicate that NEW_VALUE_OBJ must match exactly the type length.  */
  struct value *new_value
    = convert_buffer_and_type_to_value (new_value_obj, self->value->type (),
					true);
  if (new_value == nullptr)
    return -1;

  if (!valpy_assign_core (self, new_value))
    return -1;

  return 0;
}

/* Implements gdb.Value.fetch_lazy ().  */
static PyObject *
valpy_fetch_lazy (PyObject *self, PyObject *args)
{
  struct value *value = ((value_object *) self)->value;

  try
    {
      if (value->lazy ())
	value->fetch_lazy ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  Py_RETURN_NONE;
}

/* Calculate and return the address of the PyObject as the value of
   the builtin __hash__ call.  */
static Py_hash_t
valpy_hash (PyObject *self)
{
  return (intptr_t) self;
}

enum valpy_opcode
{
  VALPY_ADD,
  VALPY_SUB,
  VALPY_MUL,
  VALPY_DIV,
  VALPY_REM,
  VALPY_POW,
  VALPY_LSH,
  VALPY_RSH,
  VALPY_BITAND,
  VALPY_BITOR,
  VALPY_BITXOR
};

/* If TYPE is a reference, return the target; otherwise return TYPE.  */
#define STRIP_REFERENCE(TYPE) \
  (TYPE_IS_REFERENCE (TYPE) ? ((TYPE)->target_type ()) : (TYPE))

/* Helper for valpy_binop.  Returns a value object which is the result
   of applying the operation specified by OPCODE to the given
   arguments.  Throws a GDB exception on error.  */

static PyObject *
valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
{
  PyObject *result = NULL;

  struct value *arg1, *arg2;
  struct value *res_val = NULL;
  enum exp_opcode op = OP_NULL;
  int handled = 0;

  scoped_value_mark free_values;

  /* If the gdb.Value object is the second operand, then it will be
     passed to us as the OTHER argument, and SELF will be an entirely
     different kind of object, altogether.  Because of this, we can't
     assume self is a gdb.Value object and need to convert it from
     python as well.  */
  arg1 = convert_value_from_python (self);
  if (arg1 == NULL)
    return NULL;

  arg2 = convert_value_from_python (other);
  if (arg2 == NULL)
    return NULL;

  switch (opcode)
    {
    case VALPY_ADD:
      {
	struct type *ltype = arg1->type ();
	struct type *rtype = arg2->type ();

	ltype = check_typedef (ltype);
	ltype = STRIP_REFERENCE (ltype);
	rtype = check_typedef (rtype);
	rtype = STRIP_REFERENCE (rtype);

	handled = 1;
	if (ltype->code () == TYPE_CODE_PTR
	    && is_integral_type (rtype))
	  res_val = value_ptradd (arg1, value_as_long (arg2));
	else if (rtype->code () == TYPE_CODE_PTR
		 && is_integral_type (ltype))
	  res_val = value_ptradd (arg2, value_as_long (arg1));
	else
	  {
	    handled = 0;
	    op = BINOP_ADD;
	  }
      }
      break;
    case VALPY_SUB:
      {
	struct type *ltype = arg1->type ();
	struct type *rtype = arg2->type ();

	ltype = check_typedef (ltype);
	ltype = STRIP_REFERENCE (ltype);
	rtype = check_typedef (rtype);
	rtype = STRIP_REFERENCE (rtype);

	handled = 1;
	if (ltype->code () == TYPE_CODE_PTR
	    && rtype->code () == TYPE_CODE_PTR)
	  /* A ptrdiff_t for the target would be preferable here.  */
	  res_val = value_from_longest (builtin_type_pyint,
					value_ptrdiff (arg1, arg2));
	else if (ltype->code () == TYPE_CODE_PTR
		 && is_integral_type (rtype))
	  res_val = value_ptradd (arg1, - value_as_long (arg2));
	else
	  {
	    handled = 0;
	    op = BINOP_SUB;
	  }
      }
      break;
    case VALPY_MUL:
      op = BINOP_MUL;
      break;
    case VALPY_DIV:
      op = BINOP_DIV;
      break;
    case VALPY_REM:
      op = BINOP_REM;
      break;
    case VALPY_POW:
      op = BINOP_EXP;
      break;
    case VALPY_LSH:
      op = BINOP_LSH;
      break;
    case VALPY_RSH:
      op = BINOP_RSH;
      break;
    case VALPY_BITAND:
      op = BINOP_BITWISE_AND;
      break;
    case VALPY_BITOR:
      op = BINOP_BITWISE_IOR;
      break;
    case VALPY_BITXOR:
      op = BINOP_BITWISE_XOR;
      break;
    }

  if (!handled)
    {
      if (binop_user_defined_p (op, arg1, arg2))
	res_val = value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
      else
	res_val = value_binop (arg1, arg2, op);
    }

  if (res_val)
    result = value_to_value_object (res_val);

  return result;
}

/* Returns a value object which is the result of applying the operation
   specified by OPCODE to the given arguments.  Returns NULL on error, with
   a python exception set.  */
static PyObject *
valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
{
  PyObject *result = NULL;

  try
    {
      result = valpy_binop_throw (opcode, self, other);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

static PyObject *
valpy_add (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_ADD, self, other);
}

static PyObject *
valpy_subtract (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_SUB, self, other);
}

static PyObject *
valpy_multiply (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_MUL, self, other);
}

static PyObject *
valpy_divide (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_DIV, self, other);
}

static PyObject *
valpy_remainder (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_REM, self, other);
}

static PyObject *
valpy_power (PyObject *self, PyObject *other, PyObject *unused)
{
  /* We don't support the ternary form of pow.  I don't know how to express
     that, so let's just throw NotImplementedError to at least do something
     about it.  */
  if (unused != Py_None)
    {
      PyErr_SetString (PyExc_NotImplementedError,
		       "Invalid operation on gdb.Value.");
      return NULL;
    }

  return valpy_binop (VALPY_POW, self, other);
}

static PyObject *
valpy_negative (PyObject *self)
{
  PyObject *result = NULL;

  try
    {
      /* Perhaps overkill, but consistency has some virtue.  */
      scoped_value_mark free_values;
      struct value *val;

      val = value_neg (((value_object *) self)->value);
      result = value_to_value_object (val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

static PyObject *
valpy_positive (PyObject *self)
{
  return value_to_value_object (((value_object *) self)->value);
}

static PyObject *
valpy_absolute (PyObject *self)
{
  struct value *value = ((value_object *) self)->value;
  int isabs = 1;

  try
    {
      scoped_value_mark free_values;

      if (value_less (value, value::zero (value->type (), not_lval)))
	isabs = 0;
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (isabs)
    return valpy_positive (self);
  else
    return valpy_negative (self);
}

/* Implements boolean evaluation of gdb.Value.  */
static int
valpy_nonzero (PyObject *self)
{
  value_object *self_value = (value_object *) self;
  struct type *type;
  int nonzero = 0; /* Appease GCC warning.  */

  try
    {
      type = check_typedef (self_value->value->type ());

      if (is_integral_type (type) || type->code () == TYPE_CODE_PTR)
	nonzero = !!value_as_long (self_value->value);
      else if (is_floating_value (self_value->value))
	nonzero = !target_float_is_zero
	  (self_value->value->contents ().data (), type);
      else
	/* All other values are True.  */
	nonzero = 1;
    }
  catch (const gdb_exception &ex)
    {
      /* This is not documented in the Python documentation, but if
	 this function fails, return -1 as slot_nb_nonzero does (the
	 default Python nonzero function).  */
      return gdbpy_handle_gdb_exception (-1, ex);
    }

  return nonzero;
}

/* Implements ~ for value objects.  */
static PyObject *
valpy_invert (PyObject *self)
{
  PyObject *result = nullptr;

  try
    {
      scoped_value_mark free_values;
      struct value *val = value_complement (((value_object *) self)->value);
      result = value_to_value_object (val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Implements left shift for value objects.  */
static PyObject *
valpy_lsh (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_LSH, self, other);
}

/* Implements right shift for value objects.  */
static PyObject *
valpy_rsh (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_RSH, self, other);
}

/* Implements bitwise and for value objects.  */
static PyObject *
valpy_and (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_BITAND, self, other);
}

/* Implements bitwise or for value objects.  */
static PyObject *
valpy_or (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_BITOR, self, other);
}

/* Implements bitwise xor for value objects.  */
static PyObject *
valpy_xor (PyObject *self, PyObject *other)
{
  return valpy_binop (VALPY_BITXOR, self, other);
}

/* Helper for valpy_richcompare.  Implements comparison operations for
   value objects.  Returns true/false on success.  Returns -1 with a
   Python exception set if a Python error is detected.  Throws a GDB
   exception on other errors (memory error, etc.).  */

static int
valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
{
  int result;
  struct value *value_other;
  struct value *value_self;

  scoped_value_mark free_values;

  value_other = convert_value_from_python (other);
  if (value_other == NULL)
    return -1;

  value_self = ((value_object *) self)->value;

  switch (op)
    {
    case Py_LT:
      result = value_less (value_self, value_other);
      break;
    case Py_LE:
      result = value_less (value_self, value_other)
	|| value_equal (value_self, value_other);
      break;
    case Py_EQ:
      result = value_equal (value_self, value_other);
      break;
    case Py_NE:
      result = !value_equal (value_self, value_other);
      break;
    case Py_GT:
      result = value_less (value_other, value_self);
      break;
    case Py_GE:
      result = (value_less (value_other, value_self)
		|| value_equal (value_self, value_other));
      break;
    default:
      /* Can't happen.  */
      PyErr_SetString (PyExc_NotImplementedError,
		       _("Invalid operation on gdb.Value."));
      result = -1;
      break;
    }

  return result;
}


/* Implements comparison operations for value objects.  Returns NULL on error,
   with a python exception set.  */
static PyObject *
valpy_richcompare (PyObject *self, PyObject *other, int op)
{
  int result = 0;

  if (other == Py_None)
    /* Comparing with None is special.  From what I can tell, in Python
       None is smaller than anything else.  */
    switch (op) {
      case Py_LT:
      case Py_LE:
      case Py_EQ:
	Py_RETURN_FALSE;
      case Py_NE:
      case Py_GT:
      case Py_GE:
	Py_RETURN_TRUE;
      default:
	/* Can't happen.  */
	PyErr_SetString (PyExc_NotImplementedError,
			 _("Invalid operation on gdb.Value."));
	return NULL;
    }

  try
    {
      result = valpy_richcompare_throw (self, other, op);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  /* In this case, the Python exception has already been set.  */
  if (result < 0)
    return NULL;

  if (result == 1)
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* Implements conversion to long.  */
static PyObject *
valpy_long (PyObject *self)
{
  struct value *value = ((value_object *) self)->value;
  struct type *type = value->type ();
  LONGEST l = 0;

  try
    {
      if (is_floating_value (value))
	{
	  type = builtin_type_pylong;
	  value = value_cast (type, value);
	}

      type = check_typedef (type);

      if (!is_integral_type (type)
	  && type->code () != TYPE_CODE_PTR)
	error (_("Cannot convert value to long."));

      l = value_as_long (value);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (type->is_unsigned ())
    return gdb_py_object_from_ulongest (l).release ();
  else
    return gdb_py_object_from_longest (l).release ();
}

/* Implements conversion to float.  */
static PyObject *
valpy_float (PyObject *self)
{
  struct value *value = ((value_object *) self)->value;
  struct type *type = value->type ();
  double d = 0;

  try
    {
      type = check_typedef (type);

      if (type->code () == TYPE_CODE_FLT && is_floating_value (value))
	d = target_float_to_host_double (value->contents ().data (), type);
      else if (type->code () == TYPE_CODE_INT)
	{
	  /* Note that valpy_long accepts TYPE_CODE_PTR and some
	     others here here -- but casting a pointer or bool to a
	     float seems wrong.  */
	  d = value_as_long (value);
	}
      else
	error (_("Cannot convert value to float."));
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return PyFloat_FromDouble (d);
}

/* Returns an object for a value, without releasing it from the
   all_values chain.  */
PyObject *
value_to_value_object (struct value *val)
{
  value_object *val_obj;

  val_obj = PyObject_New (value_object, &value_object_type);
  if (val_obj != nullptr)
    {
      val->incref ();
      val_obj->value = val;
      val_obj->next = nullptr;
      val_obj->prev = nullptr;
      val_obj->address = nullptr;
      val_obj->dynamic_type = nullptr;
      val_obj->content_bytes = nullptr;
      note_value (val_obj);
    }

  return (PyObject *) val_obj;
}

/* Returns a borrowed reference to the struct value corresponding to
   the given value object.  */
struct value *
value_object_to_value (PyObject *self)
{
  value_object *real;

  if (! PyObject_TypeCheck (self, &value_object_type))
    return NULL;
  real = (value_object *) self;
  return real->value;
}

/* Try to convert a Python value to a gdb value.  If the value cannot
   be converted, set a Python exception and return NULL.  Returns a
   reference to a new value on the all_values chain.  */

struct value *
convert_value_from_python (PyObject *obj)
{
  struct value *value = NULL; /* -Wall */
  int cmp;

  gdb_assert (obj != NULL);

  try
    {
      if (PyBool_Check (obj))
	{
	  cmp = obj == Py_True ? 1 : 0;
	  value = value_from_longest (builtin_type_pybool, cmp);
	}
      else if (PyLong_Check (obj))
	{
	  LONGEST l = PyLong_AsLongLong (obj);

	  if (PyErr_Occurred ())
	    {
	      /* If the error was an overflow, we can try converting to
		 ULONGEST instead.  */
	      if (PyErr_ExceptionMatches (PyExc_OverflowError))
		{
		  gdbpy_err_fetch fetched_error;
		  gdbpy_ref<> zero = gdb_py_object_from_longest (0);

		  /* Check whether obj is positive.  */
		  if (PyObject_RichCompareBool (obj, zero.get (), Py_GT) > 0)
		    {
		      ULONGEST ul;

		      ul = PyLong_AsUnsignedLongLong (obj);
		      if (! PyErr_Occurred ())
			value = value_from_ulongest (builtin_type_upylong, ul);
		    }
		  else
		    {
		      /* There's nothing we can do.  */
		      fetched_error.restore ();
		    }
		}
	    }
	  else
	    value = value_from_longest (builtin_type_pylong, l);
	}
      else if (PyFloat_Check (obj))
	{
	  double d = PyFloat_AsDouble (obj);

	  if (! PyErr_Occurred ())
	    value = value_from_host_double (builtin_type_pyfloat, d);
	}
      else if (gdbpy_is_string (obj))
	{
	  gdb::unique_xmalloc_ptr<char> s
	    = python_string_to_target_string (obj);
	  if (s != NULL)
	    value
	      = current_language->value_string (gdbpy_enter::get_gdbarch (),
						s.get (), strlen (s.get ()));
	}
      else if (PyObject_TypeCheck (obj, &value_object_type))
	value = ((value_object *) obj)->value->copy ();
      else if (gdbpy_is_lazy_string (obj))
	{
	  PyObject *result;

	  result = PyObject_CallMethodObjArgs (obj, gdbpy_value_cst,  NULL);
	  value = ((value_object *) result)->value->copy ();
	}
      else
	PyErr_Format (PyExc_TypeError,
		      _("Could not convert Python object: %S."), obj);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return value;
}

/* Returns value object in the ARGth position in GDB's history.  */
PyObject *
gdbpy_history (PyObject *self, PyObject *args)
{
  int i;

  if (!PyArg_ParseTuple (args, "i", &i))
    return NULL;

  PyObject *result = nullptr;
  try
    {
      scoped_value_mark free_values;
      struct value *res_val = access_value_history (i);
      result = value_to_value_object (res_val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Add a gdb.Value into GDB's history, and return (as an integer) the
   position of the newly added value.  */
PyObject *
gdbpy_add_history (PyObject *self, PyObject *args)
{
  PyObject *value_obj;

  if (!PyArg_ParseTuple (args, "O", &value_obj))
    return nullptr;

  struct value *value = convert_value_from_python (value_obj);
  if (value == nullptr)
    return nullptr;

  try
    {
      int idx = value->record_latest ();
      return gdb_py_object_from_longest (idx).release ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return nullptr;
}

/* Return an integer, the number of items in GDB's history.  */

PyObject *
gdbpy_history_count (PyObject *self, PyObject *args)
{
  return gdb_py_object_from_ulongest (value_history_count ()).release ();
}

/* Return the value of a convenience variable.  */
PyObject *
gdbpy_convenience_variable (PyObject *self, PyObject *args)
{
  const char *varname;
  struct value *res_val = NULL;

  if (!PyArg_ParseTuple (args, "s", &varname))
    return NULL;

  PyObject *result = nullptr;
  bool found = false;
  try
    {
      struct internalvar *var = lookup_only_internalvar (varname);

      if (var != NULL)
	{
	  scoped_value_mark free_values;
	  res_val = value_of_internalvar (gdbpy_enter::get_gdbarch (), var);
	  if (res_val->type ()->code () == TYPE_CODE_VOID)
	    res_val = NULL;
	  else
	    {
	      found = true;
	      result = value_to_value_object (res_val);
	    }
	}
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (result == nullptr && !found)
    Py_RETURN_NONE;

  return result;
}

/* Set the value of a convenience variable.  */
PyObject *
gdbpy_set_convenience_variable (PyObject *self, PyObject *args)
{
  const char *varname;
  PyObject *value_obj;
  struct value *value = NULL;

  if (!PyArg_ParseTuple (args, "sO", &varname, &value_obj))
    return NULL;

  /* None means to clear the variable.  */
  if (value_obj != Py_None)
    {
      value = convert_value_from_python (value_obj);
      if (value == NULL)
	return NULL;
    }

  try
    {
      if (value == NULL)
	{
	  struct internalvar *var = lookup_only_internalvar (varname);

	  if (var != NULL)
	    clear_internalvar (var);
	}
      else
	{
	  struct internalvar *var = lookup_internalvar (varname);

	  set_internalvar (var, value);
	}
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  Py_RETURN_NONE;
}

/* Returns 1 in OBJ is a gdb.Value object, 0 otherwise.  */

int
gdbpy_is_value_object (PyObject *obj)
{
  return PyObject_TypeCheck (obj, &value_object_type);
}

static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_values (void)
{
  return gdbpy_type_ready (&value_object_type);
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_values);



static gdb_PyGetSetDef value_object_getset[] = {
  { "address", valpy_get_address, NULL, "The address of the value.",
    NULL },
  { "is_optimized_out", valpy_get_is_optimized_out, NULL,
    "Boolean telling whether the value is optimized "
    "out (i.e., not available).",
    NULL },
  { "type", valpy_get_type, NULL, "Type of the value.", NULL },
  { "dynamic_type", valpy_get_dynamic_type, NULL,
    "Dynamic type of the value.", NULL },
  { "is_lazy", valpy_get_is_lazy, NULL,
    "Boolean telling whether the value is lazy (not fetched yet\n\
from the inferior).  A lazy value is fetched when needed, or when\n\
the \"fetch_lazy()\" method is called.", NULL },
  { "bytes", valpy_get_bytes, valpy_set_bytes,
    "Return a bytearray containing the bytes of this value.", nullptr },
  {NULL}  /* Sentinel */
};

static PyMethodDef value_object_methods[] = {
  { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." },
  { "dynamic_cast", valpy_dynamic_cast, METH_VARARGS,
    "dynamic_cast (gdb.Type) -> gdb.Value\n\
Cast the value to the supplied type, as if by the C++ dynamic_cast operator."
  },
  { "reinterpret_cast", valpy_reinterpret_cast, METH_VARARGS,
    "reinterpret_cast (gdb.Type) -> gdb.Value\n\
Cast the value to the supplied type, as if by the C++\n\
reinterpret_cast operator."
  },
  { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
  { "referenced_value", valpy_referenced_value, METH_NOARGS,
    "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
  { "reference_value", valpy_lvalue_reference_value, METH_NOARGS,
    "Return a value of type TYPE_CODE_REF referencing this value." },
  { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
    "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
  { "const_value", valpy_const_value, METH_NOARGS,
    "Return a 'const' qualified version of the same value." },
  { "lazy_string", (PyCFunction) valpy_lazy_string,
    METH_VARARGS | METH_KEYWORDS,
    "lazy_string ([encoding]  [, length]) -> lazy_string\n\
Return a lazy string representation of the value." },
  { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
    "string ([encoding] [, errors] [, length]) -> string\n\
Return Unicode string representation of the value." },
  { "fetch_lazy", valpy_fetch_lazy, METH_NOARGS,
    "Fetches the value from the inferior, if it was lazy." },
  { "format_string", (PyCFunction) valpy_format_string,
    METH_VARARGS | METH_KEYWORDS,
    "format_string (...) -> string\n\
Return a string representation of the value using the specified\n\
formatting options" },
  { "assign", (PyCFunction) valpy_assign, METH_VARARGS,
    "assign (VAL) -> None\n\
Assign VAL to this value." },
  { "to_array", valpy_to_array, METH_NOARGS,
    "to_array () -> Value\n\
Return value as an array, if possible." },
  {NULL}  /* Sentinel */
};

static PyNumberMethods value_object_as_number = {
  valpy_add,
  valpy_subtract,
  valpy_multiply,
  valpy_remainder,
  NULL,			      /* nb_divmod */
  valpy_power,		      /* nb_power */
  valpy_negative,	      /* nb_negative */
  valpy_positive,	      /* nb_positive */
  valpy_absolute,	      /* nb_absolute */
  valpy_nonzero,	      /* nb_nonzero */
  valpy_invert,		      /* nb_invert */
  valpy_lsh,		      /* nb_lshift */
  valpy_rsh,		      /* nb_rshift */
  valpy_and,		      /* nb_and */
  valpy_xor,		      /* nb_xor */
  valpy_or,		      /* nb_or */
  valpy_long,		      /* nb_int */
  NULL,			      /* reserved */
  valpy_float,		      /* nb_float */
  NULL,                       /* nb_inplace_add */
  NULL,                       /* nb_inplace_subtract */
  NULL,                       /* nb_inplace_multiply */
  NULL,                       /* nb_inplace_remainder */
  NULL,                       /* nb_inplace_power */
  NULL,                       /* nb_inplace_lshift */
  NULL,                       /* nb_inplace_rshift */
  NULL,                       /* nb_inplace_and */
  NULL,                       /* nb_inplace_xor */
  NULL,                       /* nb_inplace_or */
  NULL,                       /* nb_floor_divide */
  valpy_divide,               /* nb_true_divide */
  NULL,			      /* nb_inplace_floor_divide */
  NULL,			      /* nb_inplace_true_divide */
  valpy_long,		      /* nb_index */
};

static PyMappingMethods value_object_as_mapping = {
  valpy_length,
  valpy_getitem,
  valpy_setitem
};

PyTypeObject value_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.Value",			  /*tp_name*/
  sizeof (value_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  valpy_dealloc,		  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  0,				  /*tp_repr*/
  &value_object_as_number,	  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  &value_object_as_mapping,	  /*tp_as_mapping*/
  valpy_hash,		          /*tp_hash*/
  valpy_call,	                  /*tp_call*/
  valpy_str,			  /*tp_str*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES
  | Py_TPFLAGS_BASETYPE,	  /*tp_flags*/
  "GDB value object",		  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  valpy_richcompare,		  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  value_object_methods,		  /* tp_methods */
  0,				  /* tp_members */
  value_object_getset,		  /* tp_getset */
  0,				  /* tp_base */
  0,				  /* tp_dict */
  0,				  /* tp_descr_get */
  0,				  /* tp_descr_set */
  0,				  /* tp_dictoffset */
  valpy_init,			  /* tp_init */
  0,				  /* tp_alloc */
  PyType_GenericNew,		  /* tp_new */
};
