/* Implementation of the GDB variable objects API.

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

   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 "value.h"
#include "expression.h"
#include "frame.h"
#include "language.h"
#include "cli/cli-cmds.h"
#include "block.h"
#include "valprint.h"
#include "gdbsupport/gdb_regex.h"

#include "varobj.h"
#include "gdbthread.h"
#include "inferior.h"
#include "varobj-iter.h"
#include "parser-defs.h"
#include "gdbarch.h"
#include <algorithm>
#include "observable.h"

#if HAVE_PYTHON
#include "python/python.h"
#include "python/python-internal.h"
#else
typedef int PyObject;
#endif

/* See varobj.h.  */

unsigned int varobjdebug = 0;
static void
show_varobjdebug (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Varobj debugging is %s.\n"), value);
}

/* String representations of gdb's format codes.  */
const char *varobj_format_string[] =
  { "natural", "binary", "decimal", "hexadecimal", "octal", "zero-hexadecimal" };

/* True if we want to allow Python-based pretty-printing.  */
static bool pretty_printing = false;

void
varobj_enable_pretty_printing (void)
{
  pretty_printing = true;
}

/* Data structures */

/* Every root variable has one of these structures saved in its
   varobj.  */
struct varobj_root
{
  /* The expression for this parent.  */
  expression_up exp;

  /* Cached arch from exp, for use in case exp gets invalidated.  */
  struct gdbarch *gdbarch = nullptr;

  /* Cached language from exp, for use in case exp gets invalidated.  */
  const struct language_defn *language_defn = nullptr;

  /* Block for which this expression is valid.  */
  const struct block *valid_block = NULL;

  /* The frame for this expression.  This field is set iff valid_block is
     not NULL.  */
  struct frame_id frame = null_frame_id;

  /* The global thread ID that this varobj_root belongs to.  This field
     is only valid if valid_block is not NULL.
     When not 0, indicates which thread 'frame' belongs to.
     When 0, indicates that the thread list was empty when the varobj_root
     was created.  */
  int thread_id = 0;

  /* If true, the -var-update always recomputes the value in the
     current thread and frame.  Otherwise, variable object is
     always updated in the specific scope/thread/frame.  */
  bool floating = false;

  /* Flag that indicates validity: set to false when this varobj_root refers
     to symbols that do not exist anymore.  */
  bool is_valid = true;

  /* Set to true if the varobj was created as tracking a global.  */
  bool global = false;

  /* Language-related operations for this variable and its
     children.  */
  const struct lang_varobj_ops *lang_ops = NULL;

  /* The varobj for this root node.  */
  struct varobj *rootvar = NULL;
};

/* Dynamic part of varobj.  */

struct varobj_dynamic
{
  /* Whether the children of this varobj were requested.  This field is
     used to decide if dynamic varobj should recompute their children.
     In the event that the frontend never asked for the children, we
     can avoid that.  */
  bool children_requested = false;

  /* The pretty-printer constructor.  If NULL, then the default
     pretty-printer will be looked up.  If None, then no
     pretty-printer will be installed.  */
  PyObject *constructor = NULL;

  /* The pretty-printer that has been constructed.  If NULL, then a
     new printer object is needed, and one will be constructed.  */
  PyObject *pretty_printer = NULL;

  /* The iterator returned by the printer's 'children' method, or NULL
     if not available.  */
  std::unique_ptr<varobj_iter> child_iter;

  /* We request one extra item from the iterator, so that we can
     report to the caller whether there are more items than we have
     already reported.  However, we don't want to install this value
     when we read it, because that will mess up future updates.  So,
     we stash it here instead.  */
  std::unique_ptr<varobj_item> saved_item;
};

/* Private function prototypes */

/* Helper functions for the above subcommands.  */

static int delete_variable (struct varobj *, bool);

static void delete_variable_1 (int *, struct varobj *, bool, bool);

static void install_variable (struct varobj *);

static void uninstall_variable (struct varobj *);

static struct varobj *create_child (struct varobj *, int, std::string &);

static struct varobj *
create_child_with_value (struct varobj *parent, int index,
			 struct varobj_item *item);

/* Utility routines */

static bool update_type_if_necessary (struct varobj *var,
				      struct value *new_value);

static bool install_new_value (struct varobj *var, struct value *value,
			       bool initial);

/* Language-specific routines.  */

static int number_of_children (const struct varobj *);

static std::string name_of_variable (const struct varobj *);

static std::string name_of_child (struct varobj *, int);

static struct value *value_of_root (struct varobj **var_handle, bool *);

static struct value *value_of_child (const struct varobj *parent, int index);

static std::string my_value_of_variable (struct varobj *var,
					 enum varobj_display_formats format);

static bool is_root_p (const struct varobj *var);

static struct varobj *varobj_add_child (struct varobj *var,
					struct varobj_item *item);

/* Private data */

/* Mappings of varobj_display_formats enums to gdb's format codes.  */
static int format_code[] = { 0, 't', 'd', 'x', 'o', 'z' };

/* List of root variable objects.  */
static std::list<struct varobj_root *> rootlist;

/* Pointer to the varobj hash table (built at run time).  */
static htab_t varobj_table;



/* API Implementation */
static bool
is_root_p (const struct varobj *var)
{
  return (var->root->rootvar == var);
}

#ifdef HAVE_PYTHON

/* See python-internal.h.  */
gdbpy_enter_varobj::gdbpy_enter_varobj (const struct varobj *var)
: gdbpy_enter (var->root->gdbarch, var->root->language_defn)
{
}

#endif

/* Return the full FRAME which corresponds to the given CORE_ADDR
   or NULL if no FRAME on the chain corresponds to CORE_ADDR.  */

static frame_info_ptr
find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
{
  frame_info_ptr frame = NULL;

  if (frame_addr == (CORE_ADDR) 0)
    return NULL;

  for (frame = get_current_frame ();
       frame != NULL;
       frame = get_prev_frame (frame))
    {
      /* The CORE_ADDR we get as argument was parsed from a string GDB
	 output as $fp.  This output got truncated to gdbarch_addr_bit.
	 Truncate the frame base address in the same manner before
	 comparing it against our argument.  */
      CORE_ADDR frame_base = get_frame_base_address (frame);
      int addr_bit = gdbarch_addr_bit (get_frame_arch (frame));

      if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
	frame_base &= ((CORE_ADDR) 1 << addr_bit) - 1;

      if (frame_base == frame_addr)
	return frame;
    }

  return NULL;
}

/* Creates a varobj (not its children).  */

struct varobj *
varobj_create (const char *objname,
	       const char *expression, CORE_ADDR frame, enum varobj_type type)
{
  /* Fill out a varobj structure for the (root) variable being constructed.  */
  auto var = std::make_unique<varobj> (new varobj_root);

  if (expression != NULL)
    {
      frame_info_ptr fi;
      struct frame_id old_id = null_frame_id;
      const struct block *block;
      const char *p;
      struct value *value = NULL;
      CORE_ADDR pc;

      /* Parse and evaluate the expression, filling in as much of the
	 variable's data as possible.  */

      if (has_stack_frames ())
	{
	  /* Allow creator to specify context of variable.  */
	  if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME))
	    fi = get_selected_frame (NULL);
	  else
	    /* FIXME: cagney/2002-11-23: This code should be doing a
	       lookup using the frame ID and not just the frame's
	       ``address''.  This, of course, means an interface
	       change.  However, with out that interface change ISAs,
	       such as the ia64 with its two stacks, won't work.
	       Similar goes for the case where there is a frameless
	       function.  */
	    fi = find_frame_addr_in_frame_chain (frame);
	}
      else
	fi = NULL;

      if (type == USE_SELECTED_FRAME)
	var->root->floating = true;

      pc = 0;
      block = NULL;
      if (fi != NULL)
	{
	  block = get_frame_block (fi, 0);
	  pc = get_frame_pc (fi);
	}

      p = expression;

      innermost_block_tracker tracker (INNERMOST_BLOCK_FOR_SYMBOLS
				       | INNERMOST_BLOCK_FOR_REGISTERS);
      /* Wrap the call to parse expression, so we can
	 return a sensible error.  */
      try
	{
	  var->root->exp = parse_exp_1 (&p, pc, block, 0, &tracker);

	  /* Cache gdbarch and language_defn as they might be used even
	     after var is invalidated and var->root->exp cleared.  */
	  var->root->gdbarch = var->root->exp->gdbarch;
	  var->root->language_defn = var->root->exp->language_defn;
	}

      catch (const gdb_exception_error &except)
	{
	  return NULL;
	}

      /* Don't allow variables to be created for types.  */
      if (var->root->exp->type_p ())
	{
	  gdb_printf (gdb_stderr, "Attempt to use a type name"
		      " as an expression.\n");
	  return NULL;
	}

      var->format = FORMAT_NATURAL;
      var->root->valid_block =
	var->root->floating ? NULL : tracker.block ();
      var->root->global
	= var->root->floating ? false : var->root->valid_block == nullptr;
      var->name = expression;
      /* For a root var, the name and the expr are the same.  */
      var->path_expr = expression;

      /* When the frame is different from the current frame,
	 we must select the appropriate frame before parsing
	 the expression, otherwise the value will not be current.
	 Since select_frame is so benign, just call it for all cases.  */
      if (var->root->valid_block)
	{
	  /* User could specify explicit FRAME-ADDR which was not found but
	     EXPRESSION is frame specific and we would not be able to evaluate
	     it correctly next time.  With VALID_BLOCK set we must also set
	     FRAME and THREAD_ID.  */
	  if (fi == NULL)
	    error (_("Failed to find the specified frame"));

	  var->root->frame = get_frame_id (fi);
	  var->root->thread_id = inferior_thread ()->global_num;
	  old_id = get_frame_id (get_selected_frame (NULL));
	  select_frame (fi);
	}

      /* We definitely need to catch errors here.  If evaluation of
	 the expression succeeds, we got the value we wanted.  But if
	 it fails, we still go on with a call to evaluate_type().  */
      try
	{
	  value = var->root->exp->evaluate ();
	}
      catch (const gdb_exception_error &except)
	{
	  /* Error getting the value.  Try to at least get the
	     right type.  */
	  struct value *type_only_value = var->root->exp->evaluate_type ();

	  var->type = type_only_value->type ();
	}

      if (value != NULL)
	{
	  int real_type_found = 0;

	  var->type = value_actual_type (value, 0, &real_type_found);
	  if (real_type_found)
	    value = value_cast (var->type, value);
	}

      /* Set language info */
      var->root->lang_ops = var->root->exp->language_defn->varobj_ops ();

      install_new_value (var.get (), value, 1 /* Initial assignment */);

      /* Set ourselves as our root.  */
      var->root->rootvar = var.get ();

      /* Reset the selected frame.  */
      if (frame_id_p (old_id))
	select_frame (frame_find_by_id (old_id));
    }

  /* If the variable object name is null, that means this
     is a temporary variable, so don't install it.  */

  if ((var != NULL) && (objname != NULL))
    {
      var->obj_name = objname;
      install_variable (var.get ());
    }

  return var.release ();
}

/* Generates an unique name that can be used for a varobj.  */

std::string
varobj_gen_name (void)
{
  static int id = 0;

  /* Generate a name for this object.  */
  id++;
  return string_printf ("var%d", id);
}

/* Given an OBJNAME, returns the pointer to the corresponding varobj.  Call
   error if OBJNAME cannot be found.  */

struct varobj *
varobj_get_handle (const char *objname)
{
  varobj *var = (varobj *) htab_find_with_hash (varobj_table, objname,
						htab_hash_string (objname));

  if (var == NULL)
    error (_("Variable object not found"));

  return var;
}

/* Given the handle, return the name of the object.  */

const char *
varobj_get_objname (const struct varobj *var)
{
  return var->obj_name.c_str ();
}

/* Given the handle, return the expression represented by the
   object.  */

std::string
varobj_get_expression (const struct varobj *var)
{
  return name_of_variable (var);
}

/* See varobj.h.  */

int
varobj_delete (struct varobj *var, bool only_children)
{
  return delete_variable (var, only_children);
}

#if HAVE_PYTHON

/* Convenience function for varobj_set_visualizer.  Instantiate a
   pretty-printer for a given value.  */
static PyObject *
instantiate_pretty_printer (PyObject *constructor, struct value *value)
{
  gdbpy_ref<> val_obj (value_to_value_object (value));
  if (val_obj == nullptr)
    return NULL;

  return PyObject_CallFunctionObjArgs (constructor, val_obj.get (), NULL);
}

#endif

/* Set/Get variable object display format.  */

enum varobj_display_formats
varobj_set_display_format (struct varobj *var,
			   enum varobj_display_formats format)
{
  var->format = format;

  if (varobj_value_is_changeable_p (var)
      && var->value != nullptr && !var->value->lazy ())
    {
      var->print_value = varobj_value_get_print_value (var->value.get (),
						       var->format, var);
    }

  return var->format;
}

enum varobj_display_formats
varobj_get_display_format (const struct varobj *var)
{
  return var->format;
}

gdb::unique_xmalloc_ptr<char>
varobj_get_display_hint (const struct varobj *var)
{
  gdb::unique_xmalloc_ptr<char> result;

#if HAVE_PYTHON
  if (!gdb_python_initialized)
    return NULL;

  gdbpy_enter_varobj enter_py (var);

  if (var->dynamic->pretty_printer != NULL)
    result = gdbpy_get_display_hint (var->dynamic->pretty_printer);
#endif

  return result;
}

/* Return true if the varobj has items after TO, false otherwise.  */

bool
varobj_has_more (const struct varobj *var, int to)
{
  if (var->children.size () > to)
    return true;

  return ((to == -1 || var->children.size () == to)
	  && (var->dynamic->saved_item != NULL));
}

/* If the variable object is bound to a specific thread, that
   is its evaluation can always be done in context of a frame
   inside that thread, returns GDB id of the thread -- which
   is always positive.  Otherwise, returns -1.  */
int
varobj_get_thread_id (const struct varobj *var)
{
  if (var->root->valid_block && var->root->thread_id > 0)
    return var->root->thread_id;
  else
    return -1;
}

void
varobj_set_frozen (struct varobj *var, bool frozen)
{
  /* When a variable is unfrozen, we don't fetch its value.
     The 'not_fetched' flag remains set, so next -var-update
     won't complain.

     We don't fetch the value, because for structures the client
     should do -var-update anyway.  It would be bad to have different
     client-size logic for structure and other types.  */
  var->frozen = frozen;
}

bool
varobj_get_frozen (const struct varobj *var)
{
  return var->frozen;
}

/* A helper function that updates the contents of FROM and TO based on the
   size of the vector CHILDREN.  If the contents of either FROM or TO are
   negative the entire range is used.  */

void
varobj_restrict_range (const std::vector<varobj *> &children,
		       int *from, int *to)
{
  int len = children.size ();

  if (*from < 0 || *to < 0)
    {
      *from = 0;
      *to = len;
    }
  else
    {
      if (*from > len)
	*from = len;
      if (*to > len)
	*to = len;
      if (*from > *to)
	*from = *to;
    }
}

/* A helper for update_dynamic_varobj_children that installs a new
   child when needed.  */

static void
install_dynamic_child (struct varobj *var,
		       std::vector<varobj *> *changed,
		       std::vector<varobj *> *type_changed,
		       std::vector<varobj *> *newobj,
		       std::vector<varobj *> *unchanged,
		       bool *cchanged,
		       int index,
		       struct varobj_item *item)
{
  if (var->children.size () < index + 1)
    {
      /* There's no child yet.  */
      struct varobj *child = varobj_add_child (var, item);

      if (newobj != NULL)
	{
	  newobj->push_back (child);
	  *cchanged = true;
	}
    }
  else
    {
      varobj *existing = var->children[index];
      bool type_updated = update_type_if_necessary (existing,
						    item->value.get ());

      if (type_updated)
	{
	  if (type_changed != NULL)
	    type_changed->push_back (existing);
	}
      if (install_new_value (existing, item->value.get (), 0))
	{
	  if (!type_updated && changed != NULL)
	    changed->push_back (existing);
	}
      else if (!type_updated && unchanged != NULL)
	unchanged->push_back (existing);
    }
}

/* A factory for creating dynamic varobj's iterators.  Returns an
   iterator object suitable for iterating over VAR's children.  */

static std::unique_ptr<varobj_iter>
varobj_get_iterator (struct varobj *var)
{
#if HAVE_PYTHON
  if (var->dynamic->pretty_printer)
    {
      value_print_options opts;
      varobj_formatted_print_options (&opts, var->format);
      return py_varobj_get_iterator (var, var->dynamic->pretty_printer, &opts);
    }
#endif

  gdb_assert_not_reached ("requested an iterator from a non-dynamic varobj");
}

static bool
update_dynamic_varobj_children (struct varobj *var,
				std::vector<varobj *> *changed,
				std::vector<varobj *> *type_changed,
				std::vector<varobj *> *newobj,
				std::vector<varobj *> *unchanged,
				bool *cchanged,
				bool update_children,
				int from,
				int to)
{
  int i;

  *cchanged = false;

  if (update_children || var->dynamic->child_iter == NULL)
    {
      var->dynamic->child_iter = varobj_get_iterator (var);
      var->dynamic->saved_item.reset (nullptr);

      i = 0;

      if (var->dynamic->child_iter == NULL)
	return false;
    }
  else
    i = var->children.size ();

  /* We ask for one extra child, so that MI can report whether there
     are more children.  */
  for (; to < 0 || i < to + 1; ++i)
    {
      std::unique_ptr<varobj_item> item;

      /* See if there was a leftover from last time.  */
      if (var->dynamic->saved_item != NULL)
	item = std::move (var->dynamic->saved_item);
      else
	item = var->dynamic->child_iter->next ();

      if (item == NULL)
	{
	  /* Iteration is done.  Remove iterator from VAR.  */
	  var->dynamic->child_iter.reset (nullptr);
	  break;
	}
      /* We don't want to push the extra child on any report list.  */
      if (to < 0 || i < to)
	{
	  bool can_mention = from < 0 || i >= from;

	  install_dynamic_child (var, can_mention ? changed : NULL,
				 can_mention ? type_changed : NULL,
				 can_mention ? newobj : NULL,
				 can_mention ? unchanged : NULL,
				 can_mention ? cchanged : NULL, i,
				 item.get ());
	}
      else
	{
	  var->dynamic->saved_item = std::move (item);

	  /* We want to truncate the child list just before this
	     element.  */
	  break;
	}
    }

  if (i < var->children.size ())
    {
      *cchanged = true;
      for (int j = i; j < var->children.size (); ++j)
	varobj_delete (var->children[j], 0);

      var->children.resize (i);
    }

  /* If there are fewer children than requested, note that the list of
     children changed.  */
  if (to >= 0 && var->children.size () < to)
    *cchanged = true;

  var->num_children = var->children.size ();

  return true;
}

int
varobj_get_num_children (struct varobj *var)
{
  if (var->num_children == -1)
    {
      if (varobj_is_dynamic_p (var))
	{
	  bool dummy;

	  /* If we have a dynamic varobj, don't report -1 children.
	     So, try to fetch some children first.  */
	  update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL, &dummy,
					  false, 0, 0);
	}
      else
	var->num_children = number_of_children (var);
    }

  return var->num_children >= 0 ? var->num_children : 0;
}

/* Creates a list of the immediate children of a variable object;
   the return code is the number of such children or -1 on error.  */

const std::vector<varobj *> &
varobj_list_children (struct varobj *var, int *from, int *to)
{
  var->dynamic->children_requested = true;

  if (varobj_is_dynamic_p (var))
    {
      bool children_changed;

      /* This, in theory, can result in the number of children changing without
	 frontend noticing.  But well, calling -var-list-children on the same
	 varobj twice is not something a sane frontend would do.  */
      update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL,
				      &children_changed, false, 0, *to);
      varobj_restrict_range (var->children, from, to);
      return var->children;
    }

  if (var->num_children == -1)
    var->num_children = number_of_children (var);

  /* If that failed, give up.  */
  if (var->num_children == -1)
    return var->children;

  /* If we're called when the list of children is not yet initialized,
     allocate enough elements in it.  */
  while (var->children.size () < var->num_children)
    var->children.push_back (NULL);

  for (int i = 0; i < var->num_children; i++)
    {
      if (var->children[i] == NULL)
	{
	  /* Either it's the first call to varobj_list_children for
	     this variable object, and the child was never created,
	     or it was explicitly deleted by the client.  */
	  std::string name = name_of_child (var, i);
	  var->children[i] = create_child (var, i, name);
	}
    }

  varobj_restrict_range (var->children, from, to);
  return var->children;
}

static struct varobj *
varobj_add_child (struct varobj *var, struct varobj_item *item)
{
  varobj *v = create_child_with_value (var, var->children.size (), item);

  var->children.push_back (v);

  return v;
}

/* Obtain the type of an object Variable as a string similar to the one gdb
   prints on the console.  The caller is responsible for freeing the string.
   */

std::string
varobj_get_type (struct varobj *var)
{
  /* For the "fake" variables, do not return a type.  (Its type is
     NULL, too.)
     Do not return a type for invalid variables as well.  */
  if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
    return std::string ();

  return type_to_string (var->type);
}

/* Obtain the type of an object variable.  */

struct type *
varobj_get_gdb_type (const struct varobj *var)
{
  return var->type;
}

/* Is VAR a path expression parent, i.e., can it be used to construct
   a valid path expression?  */

static bool
is_path_expr_parent (const struct varobj *var)
{
  gdb_assert (var->root->lang_ops->is_path_expr_parent != NULL);
  return var->root->lang_ops->is_path_expr_parent (var);
}

/* Is VAR a path expression parent, i.e., can it be used to construct
   a valid path expression?  By default we assume any VAR can be a path
   parent.  */

bool
varobj_default_is_path_expr_parent (const struct varobj *var)
{
  return true;
}

/* Return the path expression parent for VAR.  */

const struct varobj *
varobj_get_path_expr_parent (const struct varobj *var)
{
  const struct varobj *parent = var;

  while (!is_root_p (parent) && !is_path_expr_parent (parent))
    parent = parent->parent;

  /* Computation of full rooted expression for children of dynamic
     varobjs is not supported.  */
  if (varobj_is_dynamic_p (parent))
    error (_("Invalid variable object (child of a dynamic varobj)"));

  return parent;
}

/* Return a pointer to the full rooted expression of varobj VAR.
   If it has not been computed yet, compute it.  */

const char *
varobj_get_path_expr (const struct varobj *var)
{
  if (var->path_expr.empty ())
    {
      /* For root varobjs, we initialize path_expr
	 when creating varobj, so here it should be
	 child varobj.  */
      struct varobj *mutable_var = (struct varobj *) var;
      gdb_assert (!is_root_p (var));

      mutable_var->path_expr = (*var->root->lang_ops->path_expr_of_child) (var);
    }

  return var->path_expr.c_str ();
}

const struct language_defn *
varobj_get_language (const struct varobj *var)
{
  return var->root->exp->language_defn;
}

int
varobj_get_attributes (const struct varobj *var)
{
  int attributes = 0;

  if (varobj_editable_p (var))
    /* FIXME: define masks for attributes.  */
    attributes |= 0x00000001;	/* Editable */

  return attributes;
}

/* Return true if VAR is a dynamic varobj.  */

bool
varobj_is_dynamic_p (const struct varobj *var)
{
  return var->dynamic->pretty_printer != NULL;
}

std::string
varobj_get_formatted_value (struct varobj *var,
			    enum varobj_display_formats format)
{
  return my_value_of_variable (var, format);
}

std::string
varobj_get_value (struct varobj *var)
{
  return my_value_of_variable (var, var->format);
}

/* Set the value of an object variable (if it is editable) to the
   value of the given expression.  */
/* Note: Invokes functions that can call error().  */

bool
varobj_set_value (struct varobj *var, const char *expression)
{
  struct value *val = NULL; /* Initialize to keep gcc happy.  */
  /* The argument "expression" contains the variable's new value.
     We need to first construct a legal expression for this -- ugh!  */
  /* Does this cover all the bases?  */
  struct value *value = NULL; /* Initialize to keep gcc happy.  */
  const char *s = expression;

  gdb_assert (varobj_editable_p (var));

  /* ALWAYS reset to decimal temporarily.  */
  auto save_input_radix = make_scoped_restore (&input_radix, 10);
  expression_up exp = parse_exp_1 (&s, 0, 0, 0);
  try
    {
      value = exp->evaluate ();
    }

  catch (const gdb_exception_error &except)
    {
      /* We cannot proceed without a valid expression.  */
      return false;
    }

  /* All types that are editable must also be changeable.  */
  gdb_assert (varobj_value_is_changeable_p (var));

  /* The value of a changeable variable object must not be lazy.  */
  gdb_assert (!var->value->lazy ());

  /* Need to coerce the input.  We want to check if the
     value of the variable object will be different
     after assignment, and the first thing value_assign
     does is coerce the input.
     For example, if we are assigning an array to a pointer variable we
     should compare the pointer with the array's address, not with the
     array's content.  */
  value = coerce_array (value);

  /* The new value may be lazy.  value_assign, or
     rather value_contents, will take care of this.  */
  try
    {
      val = value_assign (var->value.get (), value);
    }

  catch (const gdb_exception_error &except)
    {
      return false;
    }

  /* If the value has changed, record it, so that next -var-update can
     report this change.  If a variable had a value of '1', we've set it
     to '333' and then set again to '1', when -var-update will report this
     variable as changed -- because the first assignment has set the
     'updated' flag.  There's no need to optimize that, because return value
     of -var-update should be considered an approximation.  */
  var->updated = install_new_value (var, val, false /* Compare values.  */);
  return true;
}

#if HAVE_PYTHON

/* A helper function to install a constructor function and visualizer
   in a varobj_dynamic.  */

static void
install_visualizer (struct varobj_dynamic *var, PyObject *constructor,
		    PyObject *visualizer)
{
  Py_XDECREF (var->constructor);
  var->constructor = constructor;

  Py_XDECREF (var->pretty_printer);
  var->pretty_printer = visualizer;

  var->child_iter.reset (nullptr);
}

/* Install the default visualizer for VAR.  */

static void
install_default_visualizer (struct varobj *var)
{
  /* Do not install a visualizer on a CPLUS_FAKE_CHILD.  */
  if (CPLUS_FAKE_CHILD (var))
    return;

  if (pretty_printing)
    {
      gdbpy_ref<> pretty_printer;

      if (var->value != nullptr)
	{
	  pretty_printer = gdbpy_get_varobj_pretty_printer (var->value.get ());
	  if (pretty_printer == nullptr)
	    {
	      gdbpy_print_stack ();
	      error (_("Cannot instantiate printer for default visualizer"));
	    }
	}

      if (pretty_printer == Py_None)
	pretty_printer.reset (nullptr);

      install_visualizer (var->dynamic, NULL, pretty_printer.release ());
    }
}

/* Instantiate and install a visualizer for VAR using CONSTRUCTOR to
   make a new object.  */

static void
construct_visualizer (struct varobj *var, PyObject *constructor)
{
  PyObject *pretty_printer;

  /* Do not install a visualizer on a CPLUS_FAKE_CHILD.  */
  if (CPLUS_FAKE_CHILD (var))
    return;

  Py_INCREF (constructor);
  if (constructor == Py_None)
    pretty_printer = NULL;
  else
    {
      pretty_printer = instantiate_pretty_printer (constructor,
						   var->value.get ());
      if (! pretty_printer)
	{
	  gdbpy_print_stack ();
	  Py_DECREF (constructor);
	  constructor = Py_None;
	  Py_INCREF (constructor);
	}

      if (pretty_printer == Py_None)
	{
	  Py_DECREF (pretty_printer);
	  pretty_printer = NULL;
	}
    }

  install_visualizer (var->dynamic, constructor, pretty_printer);
}

#endif /* HAVE_PYTHON */

/* A helper function for install_new_value.  This creates and installs
   a visualizer for VAR, if appropriate.  */

static void
install_new_value_visualizer (struct varobj *var)
{
#if HAVE_PYTHON
  /* If the constructor is None, then we want the raw value.  If VAR
     does not have a value, just skip this.  */
  if (!gdb_python_initialized)
    return;

  if (var->dynamic->constructor != Py_None && var->value != NULL)
    {
      gdbpy_enter_varobj enter_py (var);

      if (var->dynamic->constructor == NULL)
	install_default_visualizer (var);
      else
	construct_visualizer (var, var->dynamic->constructor);
    }
#else
  /* Do nothing.  */
#endif
}

/* When using RTTI to determine variable type it may be changed in runtime when
   the variable value is changed.  This function checks whether type of varobj
   VAR will change when a new value NEW_VALUE is assigned and if it is so
   updates the type of VAR.  */

static bool
update_type_if_necessary (struct varobj *var, struct value *new_value)
{
  if (new_value)
    {
      struct value_print_options opts;

      get_user_print_options (&opts);
      if (opts.objectprint)
	{
	  struct type *new_type = value_actual_type (new_value, 0, 0);
	  std::string new_type_str = type_to_string (new_type);
	  std::string curr_type_str = varobj_get_type (var);

	  /* Did the type name change?  */
	  if (curr_type_str != new_type_str)
	    {
	      var->type = new_type;

	      /* This information may be not valid for a new type.  */
	      varobj_delete (var, 1);
	      var->children.clear ();
	      var->num_children = -1;
	      return true;
	    }
	}
    }

  return false;
}

/* Assign a new value to a variable object.  If INITIAL is true,
   this is the first assignment after the variable object was just
   created, or changed type.  In that case, just assign the value
   and return false.
   Otherwise, assign the new value, and return true if the value is
   different from the current one, false otherwise.  The comparison is
   done on textual representation of value.  Therefore, some types
   need not be compared.  E.g.  for structures the reported value is
   always "{...}", so no comparison is necessary here.  If the old
   value was NULL and new one is not, or vice versa, we always return true.

   The VALUE parameter should not be released -- the function will
   take care of releasing it when needed.  */
static bool
install_new_value (struct varobj *var, struct value *value, bool initial)
{
  bool changeable;
  bool need_to_fetch;
  bool changed = false;
  bool intentionally_not_fetched = false;

  /* We need to know the varobj's type to decide if the value should
     be fetched or not.  C++ fake children (public/protected/private)
     don't have a type.  */
  gdb_assert (var->type || CPLUS_FAKE_CHILD (var));
  changeable = varobj_value_is_changeable_p (var);

  /* If the type has custom visualizer, we consider it to be always
     changeable.  FIXME: need to make sure this behavior will not
     mess up read-sensitive values.  */
  if (var->dynamic->pretty_printer != NULL)
    changeable = true;

  need_to_fetch = changeable;

  /* We are not interested in the address of references, and given
     that in C++ a reference is not rebindable, it cannot
     meaningfully change.  So, get hold of the real value.  */
  if (value)
    value = coerce_ref (value);

  if (var->type && var->type->code () == TYPE_CODE_UNION)
    /* For unions, we need to fetch the value implicitly because
       of implementation of union member fetch.  When gdb
       creates a value for a field and the value of the enclosing
       structure is not lazy,  it immediately copies the necessary
       bytes from the enclosing values.  If the enclosing value is
       lazy, the call to value_fetch_lazy on the field will read
       the data from memory.  For unions, that means we'll read the
       same memory more than once, which is not desirable.  So
       fetch now.  */
    need_to_fetch = true;

  /* The new value might be lazy.  If the type is changeable,
     that is we'll be comparing values of this type, fetch the
     value now.  Otherwise, on the next update the old value
     will be lazy, which means we've lost that old value.  */
  if (need_to_fetch && value && value->lazy ())
    {
      const struct varobj *parent = var->parent;
      bool frozen = var->frozen;

      for (; !frozen && parent; parent = parent->parent)
	frozen |= parent->frozen;

      if (frozen && initial)
	{
	  /* For variables that are frozen, or are children of frozen
	     variables, we don't do fetch on initial assignment.
	     For non-initial assignment we do the fetch, since it means we're
	     explicitly asked to compare the new value with the old one.  */
	  intentionally_not_fetched = true;
	}
      else
	{

	  try
	    {
	      value->fetch_lazy ();
	    }

	  catch (const gdb_exception_error &except)
	    {
	      /* Set the value to NULL, so that for the next -var-update,
		 we don't try to compare the new value with this value,
		 that we couldn't even read.  */
	      value = NULL;
	    }
	}
    }

  /* Get a reference now, before possibly passing it to any Python
     code that might release it.  */
  value_ref_ptr value_holder;
  if (value != NULL)
    value_holder = value_ref_ptr::new_reference (value);

  /* Below, we'll be comparing string rendering of old and new
     values.  Don't get string rendering if the value is
     lazy -- if it is, the code above has decided that the value
     should not be fetched.  */
  std::string print_value;
  if (value != NULL && !value->lazy ()
      && var->dynamic->pretty_printer == NULL)
    print_value = varobj_value_get_print_value (value, var->format, var);

  /* If the type is changeable, compare the old and the new values.
     If this is the initial assignment, we don't have any old value
     to compare with.  */
  if (!initial && changeable)
    {
      /* If the value of the varobj was changed by -var-set-value,
	 then the value in the varobj and in the target is the same.
	 However, that value is different from the value that the
	 varobj had after the previous -var-update.  So need to the
	 varobj as changed.  */
      if (var->updated)
	changed = true;
      else if (var->dynamic->pretty_printer == NULL)
	{
	  /* Try to compare the values.  That requires that both
	     values are non-lazy.  */
	  if (var->not_fetched && var->value->lazy ())
	    {
	      /* This is a frozen varobj and the value was never read.
		 Presumably, UI shows some "never read" indicator.
		 Now that we've fetched the real value, we need to report
		 this varobj as changed so that UI can show the real
		 value.  */
	      changed = true;
	    }
	  else  if (var->value == NULL && value == NULL)
	    /* Equal.  */
	    ;
	  else if (var->value == NULL || value == NULL)
	    {
	      changed = true;
	    }
	  else
	    {
	      gdb_assert (!var->value->lazy ());
	      gdb_assert (!value->lazy ());

	      gdb_assert (!var->print_value.empty () && !print_value.empty ());
	      if (var->print_value != print_value)
		changed = true;
	    }
	}
    }

  if (!initial && !changeable)
    {
      /* For values that are not changeable, we don't compare the values.
	 However, we want to notice if a value was not NULL and now is NULL,
	 or vice versa, so that we report when top-level varobjs come in scope
	 and leave the scope.  */
      changed = (var->value != NULL) != (value != NULL);
    }

  /* We must always keep the new value, since children depend on it.  */
  var->value = value_holder;
  if (value && value->lazy () && intentionally_not_fetched)
    var->not_fetched = true;
  else
    var->not_fetched = false;
  var->updated = false;

  install_new_value_visualizer (var);

  /* If we installed a pretty-printer, re-compare the printed version
     to see if the variable changed.  */
  if (var->dynamic->pretty_printer != NULL)
    {
      print_value = varobj_value_get_print_value (var->value.get (),
						  var->format, var);
      if (var->print_value != print_value)
	changed = true;
    }
  var->print_value = print_value;

  gdb_assert (var->value == nullptr || var->value->type ());

  return changed;
}

/* Return the requested range for a varobj.  VAR is the varobj.  FROM
   and TO are out parameters; *FROM and *TO will be set to the
   selected sub-range of VAR.  If no range was selected using
   -var-set-update-range, then both will be -1.  */
void
varobj_get_child_range (const struct varobj *var, int *from, int *to)
{
  *from = var->from;
  *to = var->to;
}

/* Set the selected sub-range of children of VAR to start at index
   FROM and end at index TO.  If either FROM or TO is less than zero,
   this is interpreted as a request for all children.  */
void
varobj_set_child_range (struct varobj *var, int from, int to)
{
  var->from = from;
  var->to = to;
}

void
varobj_set_visualizer (struct varobj *var, const char *visualizer)
{
#if HAVE_PYTHON
  PyObject *mainmod;

  if (!gdb_python_initialized)
    return;

  gdbpy_enter_varobj enter_py (var);

  mainmod = PyImport_AddModule ("__main__");
  gdbpy_ref<> globals
    = gdbpy_ref<>::new_reference (PyModule_GetDict (mainmod));
  gdbpy_ref<> constructor (PyRun_String (visualizer, Py_eval_input,
					 globals.get (), globals.get ()));

  if (constructor == NULL)
    {
      gdbpy_print_stack ();
      error (_("Could not evaluate visualizer expression: %s"), visualizer);
    }

  construct_visualizer (var, constructor.get ());

  /* If there are any children now, wipe them.  */
  varobj_delete (var, 1 /* children only */);
  var->num_children = -1;

  /* Also be sure to reset the print value.  */
  varobj_set_display_format (var, var->format);
#else
  error (_("Python support required"));
#endif
}

/* If NEW_VALUE is the new value of the given varobj (var), return
   true if var has mutated.  In other words, if the type of
   the new value is different from the type of the varobj's old
   value.

   NEW_VALUE may be NULL, if the varobj is now out of scope.  */

static bool
varobj_value_has_mutated (const struct varobj *var, struct value *new_value,
			  struct type *new_type)
{
  /* If we haven't previously computed the number of children in var,
     it does not matter from the front-end's perspective whether
     the type has mutated or not.  For all intents and purposes,
     it has not mutated.  */
  if (var->num_children < 0)
    return false;

  if (var->root->lang_ops->value_has_mutated != NULL)
    {
      /* The varobj module, when installing new values, explicitly strips
	 references, saying that we're not interested in those addresses.
	 But detection of mutation happens before installing the new
	 value, so our value may be a reference that we need to strip
	 in order to remain consistent.  */
      if (new_value != NULL)
	new_value = coerce_ref (new_value);
      return var->root->lang_ops->value_has_mutated (var, new_value, new_type);
    }
  else
    return false;
}

/* Update the values for a variable and its children.  This is a
   two-pronged attack.  First, re-parse the value for the root's
   expression to see if it's changed.  Then go all the way
   through its children, reconstructing them and noting if they've
   changed.

   The IS_EXPLICIT parameter specifies if this call is result
   of MI request to update this specific variable, or
   result of implicit -var-update *.  For implicit request, we don't
   update frozen variables.

   NOTE: This function may delete the caller's varobj.  If it
   returns TYPE_CHANGED, then it has done this and VARP will be modified
   to point to the new varobj.  */

std::vector<varobj_update_result>
varobj_update (struct varobj **varp, bool is_explicit)
{
  bool type_changed = false;
  struct value *newobj;
  std::vector<varobj_update_result> stack;
  std::vector<varobj_update_result> result;

  /* Frozen means frozen -- we don't check for any change in
     this varobj, including its going out of scope, or
     changing type.  One use case for frozen varobjs is
     retaining previously evaluated expressions, and we don't
     want them to be reevaluated at all.  */
  if (!is_explicit && (*varp)->frozen)
    return result;

  if (!(*varp)->root->is_valid)
    {
      result.emplace_back (*varp, VAROBJ_INVALID);
      return result;
    }

  if ((*varp)->root->rootvar == *varp)
    {
      varobj_update_result r (*varp);

      /* Update the root variable.  value_of_root can return NULL
	 if the variable is no longer around, i.e. we stepped out of
	 the frame in which a local existed.  We are letting the
	 value_of_root variable dispose of the varobj if the type
	 has changed.  */
      newobj = value_of_root (varp, &type_changed);
      if (update_type_if_necessary (*varp, newobj))
	  type_changed = true;
      r.varobj = *varp;
      r.type_changed = type_changed;
      if (install_new_value ((*varp), newobj, type_changed))
	r.changed = true;

      if (newobj == NULL)
	r.status = VAROBJ_NOT_IN_SCOPE;
      r.value_installed = true;

      if (r.status == VAROBJ_NOT_IN_SCOPE)
	{
	  if (r.type_changed || r.changed)
	    result.push_back (std::move (r));

	  return result;
	}

      stack.push_back (std::move (r));
    }
  else
    stack.emplace_back (*varp);

  /* Walk through the children, reconstructing them all.  */
  while (!stack.empty ())
    {
      varobj_update_result r = std::move (stack.back ());
      stack.pop_back ();
      struct varobj *v = r.varobj;

      /* Update this variable, unless it's a root, which is already
	 updated.  */
      if (!r.value_installed)
	{
	  struct type *new_type;

	  newobj = value_of_child (v->parent, v->index);
	  if (update_type_if_necessary (v, newobj))
	    r.type_changed = true;
	  if (newobj)
	    new_type = newobj->type ();
	  else
	    new_type = v->root->lang_ops->type_of_child (v->parent, v->index);

	  if (varobj_value_has_mutated (v, newobj, new_type))
	    {
	      /* The children are no longer valid; delete them now.
		 Report the fact that its type changed as well.  */
	      varobj_delete (v, 1 /* only_children */);
	      v->num_children = -1;
	      v->to = -1;
	      v->from = -1;
	      v->type = new_type;
	      r.type_changed = true;
	    }

	  if (install_new_value (v, newobj, r.type_changed))
	    {
	      r.changed = true;
	      v->updated = false;
	    }
	}

      /* We probably should not get children of a dynamic varobj, but
	 for which -var-list-children was never invoked.  */
      if (varobj_is_dynamic_p (v))
	{
	  std::vector<varobj *> changed, type_changed_vec, unchanged, newobj_vec;
	  bool children_changed = false;

	  if (v->frozen)
	    continue;

	  if (!v->dynamic->children_requested)
	    {
	      bool dummy;

	      /* If we initially did not have potential children, but
		 now we do, consider the varobj as changed.
		 Otherwise, if children were never requested, consider
		 it as unchanged -- presumably, such varobj is not yet
		 expanded in the UI, so we need not bother getting
		 it.  */
	      if (!varobj_has_more (v, 0))
		{
		  update_dynamic_varobj_children (v, NULL, NULL, NULL, NULL,
						  &dummy, false, 0, 0);
		  if (varobj_has_more (v, 0))
		    r.changed = true;
		}

	      if (r.changed)
		result.push_back (std::move (r));

	      continue;
	    }

	  /* If update_dynamic_varobj_children returns false, then we have
	     a non-conforming pretty-printer, so we skip it.  */
	  if (update_dynamic_varobj_children (v, &changed, &type_changed_vec,
					      &newobj_vec,
					      &unchanged, &children_changed,
					      true, v->from, v->to))
	    {
	      if (children_changed || !newobj_vec.empty ())
		{
		  r.children_changed = true;
		  r.newobj = std::move (newobj_vec);
		}
	      /* Push in reverse order so that the first child is
		 popped from the work stack first, and so will be
		 added to result first.  This does not affect
		 correctness, just "nicer".  */
	      for (int i = type_changed_vec.size () - 1; i >= 0; --i)
		{
		  varobj_update_result item (type_changed_vec[i]);

		  /* Type may change only if value was changed.  */
		  item.changed = true;
		  item.type_changed = true;
		  item.value_installed = true;

		  stack.push_back (std::move (item));
		}
	      for (int i = changed.size () - 1; i >= 0; --i)
		{
		  varobj_update_result item (changed[i]);

		  item.changed = true;
		  item.value_installed = true;

		  stack.push_back (std::move (item));
		}
	      for (int i = unchanged.size () - 1; i >= 0; --i)
		{
		  if (!unchanged[i]->frozen)
		    {
		      varobj_update_result item (unchanged[i]);

		      item.value_installed = true;

		      stack.push_back (std::move (item));
		    }
		}
	      if (r.changed || r.children_changed)
		result.push_back (std::move (r));

	      continue;
	    }
	}

      /* Push any children.  Use reverse order so that the first
	 child is popped from the work stack first, and so
	 will be added to result first.  This does not
	 affect correctness, just "nicer".  */
      for (int i = v->children.size () - 1; i >= 0; --i)
	{
	  varobj *c = v->children[i];

	  /* Child may be NULL if explicitly deleted by -var-delete.  */
	  if (c != NULL && !c->frozen)
	    stack.emplace_back (c);
	}

      if (r.changed || r.type_changed)
	result.push_back (std::move (r));
    }

  return result;
}

/* Helper functions */

/*
 * Variable object construction/destruction
 */

static int
delete_variable (struct varobj *var, bool only_children_p)
{
  int delcount = 0;

  delete_variable_1 (&delcount, var, only_children_p,
		     true /* remove_from_parent_p */ );

  return delcount;
}

/* Delete the variable object VAR and its children.  */
/* IMPORTANT NOTE: If we delete a variable which is a child
   and the parent is not removed we dump core.  It must be always
   initially called with remove_from_parent_p set.  */
static void
delete_variable_1 (int *delcountp, struct varobj *var, bool only_children_p,
		   bool remove_from_parent_p)
{
  /* Delete any children of this variable, too.  */
  for (varobj *child : var->children)
    {
      if (!child)
	continue;

      if (!remove_from_parent_p)
	child->parent = NULL;

      delete_variable_1 (delcountp, child, false, only_children_p);
    }
  var->children.clear ();

  /* if we were called to delete only the children we are done here.  */
  if (only_children_p)
    return;

  /* Otherwise, add it to the list of deleted ones and proceed to do so.  */
  /* If the name is empty, this is a temporary variable, that has not
     yet been installed, don't report it, it belongs to the caller...  */
  if (!var->obj_name.empty ())
    {
      *delcountp = *delcountp + 1;
    }

  /* If this variable has a parent, remove it from its parent's list.  */
  /* OPTIMIZATION: if the parent of this variable is also being deleted,
     (as indicated by remove_from_parent_p) we don't bother doing an
     expensive list search to find the element to remove when we are
     discarding the list afterwards.  */
  if ((remove_from_parent_p) && (var->parent != NULL))
    var->parent->children[var->index] = NULL;

  if (!var->obj_name.empty ())
    uninstall_variable (var);

  /* Free memory associated with this variable.  */
  delete var;
}

/* Install the given variable VAR with the object name VAR->OBJ_NAME.  */
static void
install_variable (struct varobj *var)
{
  hashval_t hash = htab_hash_string (var->obj_name.c_str ());
  void **slot = htab_find_slot_with_hash (varobj_table,
					  var->obj_name.c_str (),
					  hash, INSERT);
  if (*slot != nullptr)
    error (_("Duplicate variable object name"));

  /* Add varobj to hash table.  */
  *slot = var;

  /* If root, add varobj to root list.  */
  if (is_root_p (var))
    rootlist.push_front (var->root);
}

/* Uninstall the object VAR.  */
static void
uninstall_variable (struct varobj *var)
{
  hashval_t hash = htab_hash_string (var->obj_name.c_str ());
  htab_remove_elt_with_hash (varobj_table, var->obj_name.c_str (), hash);

  if (varobjdebug)
    gdb_printf (gdb_stdlog, "Deleting %s\n", var->obj_name.c_str ());

  /* If root, remove varobj from root list.  */
  if (is_root_p (var))
    {
      auto iter = std::find (rootlist.begin (), rootlist.end (), var->root);
      rootlist.erase (iter);
    }
}

/* Create and install a child of the parent of the given name.

   The created VAROBJ takes ownership of the allocated NAME.  */

static struct varobj *
create_child (struct varobj *parent, int index, std::string &name)
{
  struct varobj_item item;

  std::swap (item.name, name);
  item.value = release_value (value_of_child (parent, index));

  return create_child_with_value (parent, index, &item);
}

static struct varobj *
create_child_with_value (struct varobj *parent, int index,
			 struct varobj_item *item)
{
  varobj *child = new varobj (parent->root);

  /* NAME is allocated by caller.  */
  std::swap (child->name, item->name);
  child->index = index;
  child->parent = parent;

  if (varobj_is_anonymous_child (child))
    child->obj_name = string_printf ("%s.%d_anonymous",
				     parent->obj_name.c_str (), index);
  else
    child->obj_name = string_printf ("%s.%s",
				     parent->obj_name.c_str (),
				     child->name.c_str ());

  install_variable (child);

  /* Compute the type of the child.  Must do this before
     calling install_new_value.  */
  if (item->value != NULL)
    /* If the child had no evaluation errors, var->value
       will be non-NULL and contain a valid type.  */
    child->type = value_actual_type (item->value.get (), 0, NULL);
  else
    /* Otherwise, we must compute the type.  */
    child->type = (*child->root->lang_ops->type_of_child) (child->parent,
							   child->index);
  install_new_value (child, item->value.get (), 1);

  return child;
}


/*
 * Miscellaneous utility functions.
 */

/* Allocate memory and initialize a new variable.  */
varobj::varobj (varobj_root *root_)
: root (root_), dynamic (new varobj_dynamic)
{
}

/* Free any allocated memory associated with VAR.  */

varobj::~varobj ()
{
  varobj *var = this;

#if HAVE_PYTHON
  if (var->dynamic->pretty_printer != NULL)
    {
      gdbpy_enter_varobj enter_py (var);

      Py_XDECREF (var->dynamic->constructor);
      Py_XDECREF (var->dynamic->pretty_printer);
    }
#endif

  /* This must be deleted before the root object, because Python-based
     destructors need access to some components.  */
  delete var->dynamic;

  if (is_root_p (var))
    delete var->root;
}

/* Return the type of the value that's stored in VAR,
   or that would have being stored there if the
   value were accessible.

   This differs from VAR->type in that VAR->type is always
   the true type of the expression in the source language.
   The return value of this function is the type we're
   actually storing in varobj, and using for displaying
   the values and for comparing previous and new values.

   For example, top-level references are always stripped.  */
struct type *
varobj_get_value_type (const struct varobj *var)
{
  struct type *type;

  if (var->value != nullptr)
    type = var->value->type ();
  else
    type = var->type;

  type = check_typedef (type);

  if (TYPE_IS_REFERENCE (type))
    type = get_target_type (type);

  type = check_typedef (type);

  return type;
}

/*
 * Language-dependencies
 */

/* Common entry points */

/* Return the number of children for a given variable.
   The result of this function is defined by the language
   implementation.  The number of children returned by this function
   is the number of children that the user will see in the variable
   display.  */
static int
number_of_children (const struct varobj *var)
{
  return (*var->root->lang_ops->number_of_children) (var);
}

/* What is the expression for the root varobj VAR? */

static std::string
name_of_variable (const struct varobj *var)
{
  return (*var->root->lang_ops->name_of_variable) (var);
}

/* What is the name of the INDEX'th child of VAR?  */

static std::string
name_of_child (struct varobj *var, int index)
{
  return (*var->root->lang_ops->name_of_child) (var, index);
}

/* If frame associated with VAR can be found, switch
   to it and return true.  Otherwise, return false.  */

static bool
check_scope (const struct varobj *var)
{
  frame_info_ptr fi;
  bool scope;

  fi = frame_find_by_id (var->root->frame);
  scope = fi != NULL;

  if (fi)
    {
      CORE_ADDR pc = get_frame_pc (fi);

      if (pc <  var->root->valid_block->start () ||
	  pc >= var->root->valid_block->end ())
	scope = false;
      else
	select_frame (fi);
    }
  return scope;
}

/* Helper function to value_of_root.  */

static struct value *
value_of_root_1 (struct varobj **var_handle)
{
  struct value *new_val = NULL;
  struct varobj *var = *var_handle;
  bool within_scope = false;

  /*  Only root variables can be updated...  */
  if (!is_root_p (var))
    /* Not a root var.  */
    return NULL;

  scoped_restore_current_thread restore_thread;

  /* Determine whether the variable is still around.  */
  if (var->root->valid_block == NULL || var->root->floating)
    within_scope = true;
  else if (var->root->thread_id == 0)
    {
      /* The program was single-threaded when the variable object was
	 created.  Technically, it's possible that the program became
	 multi-threaded since then, but we don't support such
	 scenario yet.  */
      within_scope = check_scope (var);
    }
  else
    {
      thread_info *thread = find_thread_global_id (var->root->thread_id);

      if (thread != NULL)
	{
	  switch_to_thread (thread);
	  within_scope = check_scope (var);
	}
    }

  if (within_scope)
    {

      /* We need to catch errors here, because if evaluate
	 expression fails we want to just return NULL.  */
      try
	{
	  new_val = var->root->exp->evaluate ();
	}
      catch (const gdb_exception_error &except)
	{
	}
    }

  return new_val;
}

/* What is the ``struct value *'' of the root variable VAR?
   For floating variable object, evaluation can get us a value
   of different type from what is stored in varobj already.  In
   that case:
   - *type_changed will be set to 1
   - old varobj will be freed, and new one will be
   created, with the same name.
   - *var_handle will be set to the new varobj
   Otherwise, *type_changed will be set to 0.  */
static struct value *
value_of_root (struct varobj **var_handle, bool *type_changed)
{
  struct varobj *var;

  if (var_handle == NULL)
    return NULL;

  var = *var_handle;

  /* This should really be an exception, since this should
     only get called with a root variable.  */

  if (!is_root_p (var))
    return NULL;

  if (var->root->floating)
    {
      struct varobj *tmp_var;

      tmp_var = varobj_create (NULL, var->name.c_str (), (CORE_ADDR) 0,
			       USE_SELECTED_FRAME);
      if (tmp_var == NULL)
	{
	  return NULL;
	}
      std::string old_type = varobj_get_type (var);
      std::string new_type = varobj_get_type (tmp_var);
      if (old_type == new_type)
	{
	  /* The expression presently stored inside var->root->exp
	     remembers the locations of local variables relatively to
	     the frame where the expression was created (in DWARF location
	     button, for example).  Naturally, those locations are not
	     correct in other frames, so update the expression.  */

	  std::swap (var->root->exp, tmp_var->root->exp);

	  varobj_delete (tmp_var, 0);
	  *type_changed = 0;
	}
      else
	{
	  tmp_var->obj_name = var->obj_name;
	  tmp_var->from = var->from;
	  tmp_var->to = var->to;
	  varobj_delete (var, 0);

	  install_variable (tmp_var);
	  *var_handle = tmp_var;
	  var = *var_handle;
	  *type_changed = true;
	}
    }
  else
    {
      *type_changed = 0;
    }

  {
    struct value *value;

    value = value_of_root_1 (var_handle);
    if (var->value == NULL || value == NULL)
      {
	/* For root varobj-s, a NULL value indicates a scoping issue.
	   So, nothing to do in terms of checking for mutations.  */
      }
    else if (varobj_value_has_mutated (var, value, value->type ()))
      {
	/* The type has mutated, so the children are no longer valid.
	   Just delete them, and tell our caller that the type has
	   changed.  */
	varobj_delete (var, 1 /* only_children */);
	var->num_children = -1;
	var->to = -1;
	var->from = -1;
	*type_changed = true;
      }
    return value;
  }
}

/* What is the ``struct value *'' for the INDEX'th child of PARENT?  */
static struct value *
value_of_child (const struct varobj *parent, int index)
{
  struct value *value;

  value = (*parent->root->lang_ops->value_of_child) (parent, index);

  return value;
}

/* GDB already has a command called "value_of_variable".  Sigh.  */
static std::string
my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
  if (var->root->is_valid)
    {
      if (var->dynamic->pretty_printer != NULL)
	return varobj_value_get_print_value (var->value.get (), var->format,
					     var);
      else if (var->parent != nullptr && varobj_is_dynamic_p (var->parent))
	return var->print_value;

      return (*var->root->lang_ops->value_of_variable) (var, format);
    }
  else
    return std::string ();
}

void
varobj_formatted_print_options (struct value_print_options *opts,
				enum varobj_display_formats format)
{
  get_formatted_print_options (opts, format_code[(int) format]);
  opts->deref_ref = false;
  opts->raw = !pretty_printing;
}

std::string
varobj_value_get_print_value (struct value *value,
			      enum varobj_display_formats format,
			      const struct varobj *var)
{
  struct value_print_options opts;
  struct type *type = NULL;
  long len = 0;
  gdb::unique_xmalloc_ptr<char> encoding;
  /* Initialize it just to avoid a GCC false warning.  */
  CORE_ADDR str_addr = 0;
  bool string_print = false;

  if (value == NULL)
    return std::string ();

  string_file stb;
  std::string thevalue;

  varobj_formatted_print_options (&opts, format);

#if HAVE_PYTHON
  if (gdb_python_initialized)
    {
      PyObject *value_formatter =  var->dynamic->pretty_printer;

      gdbpy_enter_varobj enter_py (var);

      if (value_formatter)
	{
	  if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst))
	    {
	      struct value *replacement;

	      gdbpy_ref<> output = apply_varobj_pretty_printer (value_formatter,
								&replacement,
								&stb,
								&opts);

	      /* If we have string like output ...  */
	      if (output != nullptr && output != Py_None)
		{
		  /* If this is a lazy string, extract it.  For lazy
		     strings we always print as a string, so set
		     string_print.  */
		  if (gdbpy_is_lazy_string (output.get ()))
		    {
		      gdbpy_extract_lazy_string (output.get (), &str_addr,
						 &type, &len, &encoding);
		      string_print = true;
		    }
		  else
		    {
		      /* If it is a regular (non-lazy) string, extract
			 it and copy the contents into THEVALUE.  If the
			 hint says to print it as a string, set
			 string_print.  Otherwise just return the extracted
			 string as a value.  */

		      gdb::unique_xmalloc_ptr<char> s
			= python_string_to_target_string (output.get ());

		      if (s)
			{
			  struct gdbarch *gdbarch;

			  gdb::unique_xmalloc_ptr<char> hint
			    = gdbpy_get_display_hint (value_formatter);
			  if (hint)
			    {
			      if (streq (hint.get (), "string"))
				string_print = true;
			    }

			  thevalue = std::string (s.get ());
			  len = thevalue.size ();
			  gdbarch = value->type ()->arch ();
			  type = builtin_type (gdbarch)->builtin_char;

			  if (!string_print)
			    return thevalue;
			}
		      else
			gdbpy_print_stack ();
		    }
		}
	      /* If the printer returned a replacement value, set VALUE
		 to REPLACEMENT.  If there is not a replacement value,
		 just use the value passed to this function.  */
	      if (replacement)
		value = replacement;
	    }
	  else
	    {
	      /* No to_string method, so if there is a 'children'
		 method, return the default.  */
	      if (PyObject_HasAttr (value_formatter, gdbpy_children_cst))
		return "{...}";
	    }
	}
      else
	{
	  /* If we've made it here, we don't want a pretty-printer --
	     if we had one, it would already have been used.  */
	  opts.raw = true;
	}
    }
#endif

  /* If the THEVALUE has contents, it is a regular string.  */
  if (!thevalue.empty ())
    current_language->printstr (&stb, type, (gdb_byte *) thevalue.c_str (),
				len, encoding.get (), 0, &opts);
  else if (string_print)
    /* Otherwise, if string_print is set, and it is not a regular
       string, it is a lazy string.  */
    val_print_string (type, encoding.get (), str_addr, len, &stb, &opts);
  else
    /* All other cases.  */
    common_val_print (value, &stb, 0, &opts, current_language);

  return stb.release ();
}

bool
varobj_editable_p (const struct varobj *var)
{
  struct type *type;

  if (!(var->root->is_valid && var->value != nullptr
	&& var->value->lval ()))
    return false;

  type = varobj_get_value_type (var);

  switch (type->code ())
    {
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_ARRAY:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_METHOD:
      return false;
      break;

    default:
      return true;
      break;
    }
}

/* Call VAR's value_is_changeable_p language-specific callback.  */

bool
varobj_value_is_changeable_p (const struct varobj *var)
{
  return var->root->lang_ops->value_is_changeable_p (var);
}

/* Return true if that varobj is floating, that is is always evaluated in the
   selected frame, and not bound to thread/frame.  Such variable objects
   are created using '@' as frame specifier to -var-create.  */
bool
varobj_floating_p (const struct varobj *var)
{
  return var->root->floating;
}

/* Implement the "value_is_changeable_p" varobj callback for most
   languages.  */

bool
varobj_default_value_is_changeable_p (const struct varobj *var)
{
  bool r;
  struct type *type;

  if (CPLUS_FAKE_CHILD (var))
    return false;

  type = varobj_get_value_type (var);

  switch (type->code ())
    {
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_ARRAY:
      r = false;
      break;

    default:
      r = true;
    }

  return r;
}

/* Iterate all the existing _root_ VAROBJs and call the FUNC callback
   for each one.  */

void
all_root_varobjs (gdb::function_view<void (struct varobj *var)> func)
{
  /* Iterate "safely" - handle if the callee deletes its passed VAROBJ.  */
  auto iter = rootlist.begin ();
  auto end = rootlist.end ();
  while (iter != end)
    {
      auto self = iter++;
      func ((*self)->rootvar);
    }
}

/* Try to recreate the varobj VAR if it is a global or floating.  This is a
   helper function for varobj_re_set.  */

static void
varobj_re_set_iter (struct varobj *var)
{
  /* Invalidated global varobjs must be re-evaluated.  */
  if (!var->root->is_valid && var->root->global)
    {
      struct varobj *tmp_var;

      /* Try to create a varobj with same expression.  If we succeed
	 and have a global replace the old varobj.  */
      tmp_var = varobj_create (nullptr, var->name.c_str (), (CORE_ADDR) 0,
			       USE_CURRENT_FRAME);
      if (tmp_var != nullptr && tmp_var->root->global)
	{
	  tmp_var->obj_name = var->obj_name;
	  varobj_delete (var, 0);
	  install_variable (tmp_var);
	}
    }
}

/* See varobj.h.  */

void
varobj_re_set (void)
{
  all_root_varobjs (varobj_re_set_iter);
}

/* Ensure that no varobj keep references to OBJFILE.  */

static void
varobj_invalidate_if_uses_objfile (struct objfile *objfile)
{
  if (objfile->separate_debug_objfile_backlink != nullptr)
    objfile = objfile->separate_debug_objfile_backlink;

  all_root_varobjs ([objfile] (struct varobj *var)
    {
      if (var->root->valid_block != nullptr)
	{
	  struct objfile *bl_objfile = var->root->valid_block->objfile ();
	  if (bl_objfile->separate_debug_objfile_backlink != nullptr)
	    bl_objfile = bl_objfile->separate_debug_objfile_backlink;

	  if (bl_objfile == objfile)
	    {
	      /* The varobj is tied to a block which is going away.  There is
		 no way to reconstruct something later, so invalidate the
		 varobj completely and drop the reference to the block which is
		 being freed.  */
	      var->root->is_valid = false;
	      var->root->valid_block = nullptr;
	    }
	}

      if (var->root->exp != nullptr && var->root->exp->uses_objfile (objfile))
	{
	  /* The varobj's current expression references the objfile.  For
	     globals and floating, it is possible that when we try to
	     re-evaluate the expression later it is still valid with
	     whatever is in scope at that moment.  Just invalidate the
	     expression for now.  */
	  var->root->exp.reset ();

	  /* It only makes sense to keep a floating varobj around.  */
	  if (!var->root->floating)
	    var->root->is_valid = false;
	}

      /* var->value->type and var->type might also reference the objfile.
	 This is taken care of in value.c:preserve_values which deals with
	 making sure that objfile-owned types are replaced with
	 gdbarch-owned equivalents.  */
    });
}

/* A hash function for a varobj.  */

static hashval_t
hash_varobj (const void *a)
{
  const varobj *obj = (const varobj *) a;
  return htab_hash_string (obj->obj_name.c_str ());
}

/* A hash table equality function for varobjs.  */

static int
eq_varobj_and_string (const void *a, const void *b)
{
  const varobj *obj = (const varobj *) a;
  const char *name = (const char *) b;

  return obj->obj_name == name;
}

INIT_GDB_FILE (varobj)
{
  varobj_table = htab_create_alloc (5, hash_varobj, eq_varobj_and_string,
				    nullptr, xcalloc, xfree);

  add_setshow_zuinteger_cmd ("varobj", class_maintenance,
			     &varobjdebug,
			     _("Set varobj debugging."),
			     _("Show varobj debugging."),
			     _("When non-zero, varobj debugging is enabled."),
			     NULL, show_varobjdebug,
			     &setdebuglist, &showdebuglist);

  gdb::observers::free_objfile.attach (varobj_invalidate_if_uses_objfile,
				       "varobj");
}
