/* varobj support for Ada.

   Copyright (C) 2012-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 "ada-lang.h"
#include "varobj.h"
#include "language.h"
#include "valprint.h"

/* Implementation principle used in this unit:

   For our purposes, the meat of the varobj object is made of two
   elements: The varobj's (struct) value, and the varobj's (struct)
   type.  In most situations, the varobj has a non-NULL value, and
   the type becomes redundant, as it can be directly derived from
   the value.  In the initial implementation of this unit, most
   routines would only take a value, and return a value.

   But there are many situations where it is possible for a varobj
   to have a NULL value.  For instance, if the varobj becomes out of
   scope.  Or better yet, when the varobj is the child of another
   NULL pointer varobj.  In that situation, we must rely on the type
   instead of the value to create the child varobj.

   That's why most functions below work with a (value, type) pair.
   The value may or may not be NULL.  But the type is always expected
   to be set.  When the value is NULL, then we work with the type
   alone, and keep the value NULL.  But when the value is not NULL,
   then we work using the value, because it provides more information.
   But we still always set the type as well, even if that type could
   easily be derived from the value.  The reason behind this is that
   it allows the code to use the type without having to worry about
   it being set or not.  It makes the code clearer.  */

static int ada_varobj_get_number_of_children (struct value *parent_value,
					      struct type *parent_type);

/* A convenience function that decodes the VALUE_PTR/TYPE_PTR couple:
   If there is a value (*VALUE_PTR not NULL), then perform the decoding
   using it, and compute the associated type from the resulting value.
   Otherwise, compute a static approximation of *TYPE_PTR, leaving
   *VALUE_PTR unchanged.

   The results are written in place.  */

static void
ada_varobj_decode_var (struct value **value_ptr, struct type **type_ptr)
{
  if (*value_ptr)
    *value_ptr = ada_get_decoded_value (*value_ptr);

  if (*value_ptr != nullptr)
    *type_ptr = ada_check_typedef ((*value_ptr)->type ());
  else
    *type_ptr = ada_get_decoded_type (*type_ptr);
}

/* Return a string containing an image of the given scalar value.
   VAL is the numeric value, while TYPE is the value's type.
   This is useful for plain integers, of course, but even more
   so for enumerated types.  */

static std::string
ada_varobj_scalar_image (struct type *type, LONGEST val)
{
  string_file buf;

  ada_print_scalar (type, val, &buf);
  return buf.release ();
}

/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair designates
   a struct or union, compute the (CHILD_VALUE, CHILD_TYPE) couple
   corresponding to the field number FIELDNO.  */

static void
ada_varobj_struct_elt (struct value *parent_value,
		       struct type *parent_type,
		       int fieldno,
		       struct value **child_value,
		       struct type **child_type)
{
  struct value *value = NULL;
  struct type *type = NULL;

  if (parent_value)
    {
      value = value_field (parent_value, fieldno);
      type = value->type ();
    }
  else
    type = parent_type->field (fieldno).type ();

  if (child_value)
    *child_value = value;
  if (child_type)
    *child_type = type;
}

/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is a pointer or
   reference, return a (CHILD_VALUE, CHILD_TYPE) couple corresponding
   to the dereferenced value.  */

static void
ada_varobj_ind (struct value *parent_value,
		struct type *parent_type,
		struct value **child_value,
		struct type **child_type)
{
  struct value *value = NULL;
  struct type *type = NULL;

  if (ada_is_array_descriptor_type (parent_type))
    {
      /* This can only happen when PARENT_VALUE is NULL.  Otherwise,
	 ada_get_decoded_value would have transformed our parent_type
	 into a simple array pointer type.  */
      gdb_assert (parent_value == NULL);
      gdb_assert (parent_type->code () == TYPE_CODE_TYPEDEF);

      /* Decode parent_type by the equivalent pointer to (decoded)
	 array.  */
      while (parent_type->code () == TYPE_CODE_TYPEDEF)
	parent_type = parent_type->target_type ();
      parent_type = ada_coerce_to_simple_array_type (parent_type);
      parent_type = lookup_pointer_type (parent_type);
    }

  /* If parent_value is a null pointer, then only perform static
     dereferencing.  We cannot dereference null pointers.  */
  if (parent_value && value_as_address (parent_value) == 0)
    parent_value = NULL;

  if (parent_value)
    {
      value = ada_value_ind (parent_value);
      type = value->type ();
    }
  else
    type = parent_type->target_type ();

  if (child_value)
    *child_value = value;
  if (child_type)
    *child_type = type;
}

/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is a simple
   array (TYPE_CODE_ARRAY), return the (CHILD_VALUE, CHILD_TYPE)
   pair corresponding to the element at ELT_INDEX.  */

static void
ada_varobj_simple_array_elt (struct value *parent_value,
			     struct type *parent_type,
			     int elt_index,
			     struct value **child_value,
			     struct type **child_type)
{
  struct value *value = NULL;
  struct type *type = NULL;

  if (parent_value)
    {
      struct value *index_value =
	value_from_longest (parent_type->index_type (), elt_index);

      value = ada_value_subscript (parent_value, 1, &index_value);
      type = value->type ();
    }
  else
    type = parent_type->target_type ();

  if (child_value)
    *child_value = value;
  if (child_type)
    *child_type = type;
}

/* Given the decoded value and decoded type of a variable object,
   adjust the value and type to those necessary for getting children
   of the variable object.

   The replacement is performed in place.  */

static void
ada_varobj_adjust_for_child_access (struct value **value,
				    struct type **type)
{
   /* Pointers to struct/union types are special: Instead of having
      one child (the struct), their children are the components of
      the struct/union type.  We handle this situation by dereferencing
      the (value, type) couple.  */
  if ((*type)->code () == TYPE_CODE_PTR
      && ((*type)->target_type ()->code () == TYPE_CODE_STRUCT
	  || (*type)->target_type ()->code () == TYPE_CODE_UNION)
      && *value != nullptr
      && value_as_address (*value) != 0
      && !ada_is_array_descriptor_type ((*type)->target_type ())
      && !ada_is_constrained_packed_array_type ((*type)->target_type ()))
    ada_varobj_ind (*value, *type, value, type);

  /* If this is a tagged type, we need to transform it a bit in order
     to be able to fetch its full view.  As always with tagged types,
     we can only do that if we have a value.  */
  if (*value != NULL && ada_is_tagged_type (*type, 1))
    {
      *value = ada_tag_value_at_base_address (*value);
      *type = (*value)->type ();
    }
}

/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is an array
   (any type of array, "simple" or not), return the number of children
   that this array contains.  */

static int
ada_varobj_get_array_number_of_children (struct value *parent_value,
					 struct type *parent_type)
{
  LONGEST lo, hi;

  if (parent_value == NULL
      && is_dynamic_type (parent_type->index_type ()))
    {
      /* This happens when listing the children of an object
	 which does not exist in memory (Eg: when requesting
	 the children of a null pointer, which is allowed by
	 varobj).  The array index type being dynamic, we cannot
	 determine how many elements this array has.  Just assume
	 it has none.  */
      return 0;
    }

  if (!get_array_bounds (parent_type, &lo, &hi))
    {
      /* Could not get the array bounds.  Pretend this is an empty array.  */
      warning (_("unable to get bounds of array, assuming null array"));
      return 0;
    }

  /* Ada allows the upper bound to be less than the lower bound,
     in order to specify empty arrays...  */
  if (hi < lo)
    return 0;

  return hi - lo + 1;
}

/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is a struct or
   union, return the number of children this struct contains.  */

static int
ada_varobj_get_struct_number_of_children (struct value *parent_value,
					  struct type *parent_type)
{
  int n_children = 0;
  int i;

  gdb_assert (parent_type->code () == TYPE_CODE_STRUCT
	      || parent_type->code () == TYPE_CODE_UNION);

  for (i = 0; i < parent_type->num_fields (); i++)
    {
      if (ada_is_ignored_field (parent_type, i))
	continue;

      if (ada_is_wrapper_field (parent_type, i))
	{
	  struct value *elt_value;
	  struct type *elt_type;

	  ada_varobj_struct_elt (parent_value, parent_type, i,
				 &elt_value, &elt_type);
	  if (ada_is_tagged_type (elt_type, 0))
	    {
	      /* We must not use ada_varobj_get_number_of_children
		 to determine is element's number of children, because
		 this function first calls ada_varobj_decode_var,
		 which "fixes" the element.  For tagged types, this
		 includes reading the object's tag to determine its
		 real type, which happens to be the parent_type, and
		 leads to an infinite loop (because the element gets
		 fixed back into the parent).  */
	      n_children += ada_varobj_get_struct_number_of_children
		(elt_value, elt_type);
	    }
	  else
	    n_children += ada_varobj_get_number_of_children (elt_value, elt_type);
	}
      else if (ada_is_variant_part (parent_type, i))
	{
	  /* In normal situations, the variant part of the record should
	     have been "fixed". Or, in other words, it should have been
	     replaced by the branch of the variant part that is relevant
	     for our value.  But there are still situations where this
	     can happen, however (Eg. when our parent is a NULL pointer).
	     We do not support showing this part of the record for now,
	     so just pretend this field does not exist.  */
	}
      else
	n_children++;
    }

  return n_children;
}

/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair designates
   a pointer, return the number of children this pointer has.  */

static int
ada_varobj_get_ptr_number_of_children (struct value *parent_value,
				       struct type *parent_type)
{
  struct type *child_type = parent_type->target_type ();

  /* Pointer to functions and to void do not have a child, since
     you cannot print what they point to.  */
  if (child_type->code () == TYPE_CODE_FUNC
      || child_type->code () == TYPE_CODE_VOID)
    return 0;

  /* Only show children for non-null pointers.  */
  if (parent_value == nullptr || value_as_address (parent_value) == 0)
    return 0;

  /* All other types have 1 child.  */
  return 1;
}

/* Return the number of children for the (PARENT_VALUE, PARENT_TYPE)
   pair.  */

static int
ada_varobj_get_number_of_children (struct value *parent_value,
				   struct type *parent_type)
{
  ada_varobj_decode_var (&parent_value, &parent_type);
  ada_varobj_adjust_for_child_access (&parent_value, &parent_type);

  /* A typedef to an array descriptor in fact represents a pointer
     to an unconstrained array.  These types always have one child
     (the unconstrained array).  */
  if (ada_is_access_to_unconstrained_array (parent_type))
    return 1;

  if (parent_type->code () == TYPE_CODE_ARRAY)
    return ada_varobj_get_array_number_of_children (parent_value,
						    parent_type);

  if (parent_type->code () == TYPE_CODE_STRUCT
      || parent_type->code () == TYPE_CODE_UNION)
    return ada_varobj_get_struct_number_of_children (parent_value,
						     parent_type);

  if (parent_type->code () == TYPE_CODE_PTR)
    return ada_varobj_get_ptr_number_of_children (parent_value,
						  parent_type);

  /* All other types have no child.  */
  return 0;
}

/* Describe the child of the (PARENT_VALUE, PARENT_TYPE) pair
   whose index is CHILD_INDEX:

     - If CHILD_NAME is not NULL, then a copy of the child's name
       is saved in *CHILD_NAME.

     - If CHILD_VALUE is not NULL, then save the child's value
       in *CHILD_VALUE. Same thing for the child's type with
       CHILD_TYPE if not NULL.

     - If CHILD_PATH_EXPR is not NULL, then compute the child's
       path expression.

       Computing the child's path expression requires the PARENT_PATH_EXPR
       to be non-NULL.  Otherwise, PARENT_PATH_EXPR may be null if
       CHILD_PATH_EXPR is NULL.

  PARENT_NAME is the name of the parent, and should never be NULL.  */

static void ada_varobj_describe_child (struct value *parent_value,
				       struct type *parent_type,
				       const char *parent_name,
				       const char *parent_path_expr,
				       int child_index,
				       std::string *child_name,
				       struct value **child_value,
				       struct type **child_type,
				       std::string *child_path_expr);

/* Same as ada_varobj_describe_child, but limited to struct/union
   objects.  */

static void
ada_varobj_describe_struct_child (struct value *parent_value,
				  struct type *parent_type,
				  const char *parent_name,
				  const char *parent_path_expr,
				  int child_index,
				  std::string *child_name,
				  struct value **child_value,
				  struct type **child_type,
				  std::string *child_path_expr)
{
  int fieldno;
  int childno = 0;

  gdb_assert (parent_type->code () == TYPE_CODE_STRUCT
	      || parent_type->code () == TYPE_CODE_UNION);

  for (fieldno = 0; fieldno < parent_type->num_fields (); fieldno++)
    {
      if (ada_is_ignored_field (parent_type, fieldno))
	continue;

      if (ada_is_wrapper_field (parent_type, fieldno))
	{
	  struct value *elt_value;
	  struct type *elt_type;
	  int elt_n_children;

	  ada_varobj_struct_elt (parent_value, parent_type, fieldno,
				 &elt_value, &elt_type);
	  if (ada_is_tagged_type (elt_type, 0))
	    {
	      /* Same as in ada_varobj_get_struct_number_of_children:
		 For tagged types, we must be careful to not call
		 ada_varobj_get_number_of_children, to prevent our
		 element from being fixed back into the parent.  */
	      elt_n_children = ada_varobj_get_struct_number_of_children
		(elt_value, elt_type);
	    }
	  else
	    elt_n_children =
	      ada_varobj_get_number_of_children (elt_value, elt_type);

	  /* Is the child we're looking for one of the children
	     of this wrapper field?  */
	  if (child_index - childno < elt_n_children)
	    {
	      if (ada_is_tagged_type (elt_type, 0))
		{
		  /* Same as in ada_varobj_get_struct_number_of_children:
		     For tagged types, we must be careful to not call
		     ada_varobj_describe_child, to prevent our element
		     from being fixed back into the parent.  */
		  ada_varobj_describe_struct_child
		    (elt_value, elt_type, parent_name, parent_path_expr,
		     child_index - childno, child_name, child_value,
		     child_type, child_path_expr);
		}
	      else
		ada_varobj_describe_child (elt_value, elt_type,
					   parent_name, parent_path_expr,
					   child_index - childno,
					   child_name, child_value,
					   child_type, child_path_expr);
	      return;
	    }

	  /* The child we're looking for is beyond this wrapper
	     field, so skip all its children.  */
	  childno += elt_n_children;
	  continue;
	}
      else if (ada_is_variant_part (parent_type, fieldno))
	{
	  /* In normal situations, the variant part of the record should
	     have been "fixed". Or, in other words, it should have been
	     replaced by the branch of the variant part that is relevant
	     for our value.  But there are still situations where this
	     can happen, however (Eg. when our parent is a NULL pointer).
	     We do not support showing this part of the record for now,
	     so just pretend this field does not exist.  */
	  continue;
	}

      if (childno == child_index)
	{
	  if (child_name)
	    {
	      /* The name of the child is none other than the field's
		 name, except that we need to strip suffixes from it.
		 For instance, fields with alignment constraints will
		 have an __XVA suffix added to them.  */
	      const char *field_name = parent_type->field (fieldno).name ();
	      int child_name_len = ada_name_prefix_len (field_name);

	      *child_name = string_printf ("%.*s", child_name_len, field_name);
	    }

	  if (child_value && parent_value)
	    ada_varobj_struct_elt (parent_value, parent_type, fieldno,
				   child_value, NULL);

	  if (child_type)
	    ada_varobj_struct_elt (parent_value, parent_type, fieldno,
				   NULL, child_type);

	  if (child_path_expr)
	    {
	      /* The name of the child is none other than the field's
		 name, except that we need to strip suffixes from it.
		 For instance, fields with alignment constraints will
		 have an __XVA suffix added to them.  */
	      const char *field_name = parent_type->field (fieldno).name ();
	      int child_name_len = ada_name_prefix_len (field_name);

	      *child_path_expr =
		string_printf ("(%s).%.*s", parent_path_expr,
			       child_name_len, field_name);
	    }

	  return;
	}

      childno++;
    }

  /* Something went wrong.  Either we miscounted the number of
     children, or CHILD_INDEX was too high.  But we should never
     reach here.  We don't have enough information to recover
     nicely, so just raise an assertion failure.  */
  gdb_assert_not_reached ("unexpected code path");
}

/* Same as ada_varobj_describe_child, but limited to pointer objects.

   Note that CHILD_INDEX is unused in this situation, but still provided
   for consistency of interface with other routines describing an object's
   child.  */

static void
ada_varobj_describe_ptr_child (struct value *parent_value,
			       struct type *parent_type,
			       const char *parent_name,
			       const char *parent_path_expr,
			       int child_index,
			       std::string *child_name,
			       struct value **child_value,
			       struct type **child_type,
			       std::string *child_path_expr)
{
  if (child_name)
    *child_name = string_printf ("%s.all", parent_name);

  if (child_value && parent_value)
    ada_varobj_ind (parent_value, parent_type, child_value, NULL);

  if (child_type)
    ada_varobj_ind (parent_value, parent_type, NULL, child_type);

  if (child_path_expr)
    *child_path_expr = string_printf ("(%s).all", parent_path_expr);
}

/* Same as ada_varobj_describe_child, limited to simple array objects
   (TYPE_CODE_ARRAY only).

   Assumes that the (PARENT_VALUE, PARENT_TYPE) pair is properly decoded.
   This is done by ada_varobj_describe_child before calling us.  */

static void
ada_varobj_describe_simple_array_child (struct value *parent_value,
					struct type *parent_type,
					const char *parent_name,
					const char *parent_path_expr,
					int child_index,
					std::string *child_name,
					struct value **child_value,
					struct type **child_type,
					std::string *child_path_expr)
{
  struct type *index_type;
  int real_index;

  gdb_assert (parent_type->code () == TYPE_CODE_ARRAY);

  index_type = parent_type->index_type ();
  real_index = child_index + ada_discrete_type_low_bound (index_type);

  if (child_name)
    *child_name = ada_varobj_scalar_image (index_type, real_index);

  if (child_value && parent_value)
    ada_varobj_simple_array_elt (parent_value, parent_type, real_index,
				 child_value, NULL);

  if (child_type)
    ada_varobj_simple_array_elt (parent_value, parent_type, real_index,
				 NULL, child_type);

  if (child_path_expr)
    {
      std::string index_img = ada_varobj_scalar_image (index_type, real_index);

      /* Enumeration literals by themselves are potentially ambiguous.
	 For instance, consider the following package spec:

	    package Pck is
	       type Color is (Red, Green, Blue, White);
	       type Blood_Cells is (White, Red);
	    end Pck;

	 In this case, the literal "red" for instance, or even
	 the fully-qualified literal "pck.red" cannot be resolved
	 by itself.  Type qualification is needed to determine which
	 enumeration literals should be used.

	 The following variable will be used to contain the name
	 of the array index type when such type qualification is
	 needed.  */
      const char *index_type_name = NULL;
      std::string decoded;

      /* If the index type is a range type, find the base type.  */
      while (index_type->code () == TYPE_CODE_RANGE)
	index_type = index_type->target_type ();

      if (index_type->code () == TYPE_CODE_ENUM
	  || index_type->code () == TYPE_CODE_BOOL)
	{
	  index_type_name = ada_type_name (index_type);
	  if (index_type_name)
	    {
	      decoded = ada_decode (index_type_name);
	      index_type_name = decoded.c_str ();
	    }
	}

      if (index_type_name != NULL)
	*child_path_expr =
	  string_printf ("(%s)(%.*s'(%s))", parent_path_expr,
			 ada_name_prefix_len (index_type_name),
			 index_type_name, index_img.c_str ());
      else
	*child_path_expr =
	  string_printf ("(%s)(%s)", parent_path_expr, index_img.c_str ());
    }
}

/* See description at declaration above.  */

static void
ada_varobj_describe_child (struct value *parent_value,
			   struct type *parent_type,
			   const char *parent_name,
			   const char *parent_path_expr,
			   int child_index,
			   std::string *child_name,
			   struct value **child_value,
			   struct type **child_type,
			   std::string *child_path_expr)
{
  /* We cannot compute the child's path expression without
     the parent's path expression.  This is a pre-condition
     for calling this function.  */
  if (child_path_expr)
    gdb_assert (parent_path_expr != NULL);

  ada_varobj_decode_var (&parent_value, &parent_type);
  ada_varobj_adjust_for_child_access (&parent_value, &parent_type);

  if (child_name)
    *child_name = std::string ();
  if (child_value)
    *child_value = NULL;
  if (child_type)
    *child_type = NULL;
  if (child_path_expr)
    *child_path_expr = std::string ();

  if (ada_is_access_to_unconstrained_array (parent_type))
    {
      ada_varobj_describe_ptr_child (parent_value, parent_type,
				     parent_name, parent_path_expr,
				     child_index, child_name,
				     child_value, child_type,
				     child_path_expr);
      return;
    }

  if (parent_type->code () == TYPE_CODE_ARRAY)
    {
      ada_varobj_describe_simple_array_child
	(parent_value, parent_type, parent_name, parent_path_expr,
	 child_index, child_name, child_value, child_type,
	 child_path_expr);
      return;
    }

  if (parent_type->code () == TYPE_CODE_STRUCT
      || parent_type->code () == TYPE_CODE_UNION)
    {
      ada_varobj_describe_struct_child (parent_value, parent_type,
					parent_name, parent_path_expr,
					child_index, child_name,
					child_value, child_type,
					child_path_expr);
      return;
    }

  if (parent_type->code () == TYPE_CODE_PTR)
    {
      ada_varobj_describe_ptr_child (parent_value, parent_type,
				     parent_name, parent_path_expr,
				     child_index, child_name,
				     child_value, child_type,
				     child_path_expr);
      return;
    }

  /* It should never happen.  But rather than crash, report dummy names
     and return a NULL child_value.  */
  if (child_name)
    *child_name = "???";
}

/* Return the name of the child number CHILD_INDEX of the (PARENT_VALUE,
   PARENT_TYPE) pair.  PARENT_NAME is the name of the PARENT.  */

static std::string
ada_varobj_get_name_of_child (struct value *parent_value,
			      struct type *parent_type,
			      const char *parent_name, int child_index)
{
  std::string child_name;

  ada_varobj_describe_child (parent_value, parent_type, parent_name,
			     NULL, child_index, &child_name, NULL,
			     NULL, NULL);
  return child_name;
}

/* Return the path expression of the child number CHILD_INDEX of
   the (PARENT_VALUE, PARENT_TYPE) pair.  PARENT_NAME is the name
   of the parent, and PARENT_PATH_EXPR is the parent's path expression.
   Both must be non-NULL.  */

static std::string
ada_varobj_get_path_expr_of_child (struct value *parent_value,
				   struct type *parent_type,
				   const char *parent_name,
				   const char *parent_path_expr,
				   int child_index)
{
  std::string child_path_expr;

  ada_varobj_describe_child (parent_value, parent_type, parent_name,
			     parent_path_expr, child_index, NULL,
			     NULL, NULL, &child_path_expr);

  return child_path_expr;
}

/* Return the value of child number CHILD_INDEX of the (PARENT_VALUE,
   PARENT_TYPE) pair.  PARENT_NAME is the name of the parent.  */

static struct value *
ada_varobj_get_value_of_child (struct value *parent_value,
			       struct type *parent_type,
			       const char *parent_name, int child_index)
{
  struct value *child_value;

  ada_varobj_describe_child (parent_value, parent_type, parent_name,
			     NULL, child_index, NULL, &child_value,
			     NULL, NULL);

  return child_value;
}

/* Return the type of child number CHILD_INDEX of the (PARENT_VALUE,
   PARENT_TYPE) pair.  */

static struct type *
ada_varobj_get_type_of_child (struct value *parent_value,
			      struct type *parent_type,
			      int child_index)
{
  struct type *child_type;

  ada_varobj_describe_child (parent_value, parent_type, NULL, NULL,
			     child_index, NULL, NULL, &child_type, NULL);

  return child_type;
}

/* Return a string that contains the image of the given VALUE, using
   the print options OPTS as the options for formatting the result.  */

static std::string
ada_varobj_get_value_image (struct value *value,
			    struct value_print_options *opts)
{
  string_file buffer;

  common_val_print (value, &buffer, 0, opts, current_language);
  return buffer.release ();
}

/* Assuming that the (VALUE, TYPE) pair designates an array varobj,
   return a string that is suitable for use in the "value" field of
   the varobj output.  Most of the time, this is the number of elements
   in the array inside square brackets, but there are situations where
   it's useful to add more info.

   OPTS are the print options used when formatting the result.  */

static std::string
ada_varobj_get_value_of_array_variable (struct value *value,
					struct type *type,
					struct value_print_options *opts)
{
  const int numchild = ada_varobj_get_array_number_of_children (value, type);

  /* If we have a string, provide its contents in the "value" field.
     Otherwise, the only other way to inspect the contents of the string
     is by looking at the value of each element, as in any other array,
     which is not very convenient...  */
  if (value
      && ada_is_string_type (type)
      && (opts->format == 0 || opts->format == 's'))
    {
      std::string str = ada_varobj_get_value_image (value, opts);
      return string_printf ("[%d] %s", numchild, str.c_str ());
    }
  else
    return string_printf ("[%d]", numchild);
}

/* Return a string representation of the (VALUE, TYPE) pair, using
   the given print options OPTS as our formatting options.  */

static std::string
ada_varobj_get_value_of_variable (struct value *value,
				  struct type *type,
				  struct value_print_options *opts)
{
  ada_varobj_decode_var (&value, &type);

  switch (type->code ())
    {
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      return "{...}";
    case TYPE_CODE_ARRAY:
      return ada_varobj_get_value_of_array_variable (value, type, opts);
    default:
      if (!value)
	return "";
      else
	return ada_varobj_get_value_image (value, opts);
    }
}

/* Ada specific callbacks for VAROBJs.  */

static int
ada_number_of_children (const struct varobj *var)
{
  return ada_varobj_get_number_of_children (var->value.get (), var->type);
}

static std::string
ada_name_of_variable (const struct varobj *parent)
{
  return c_varobj_ops.name_of_variable (parent);
}

static std::string
ada_name_of_child (const struct varobj *parent, int index)
{
  return ada_varobj_get_name_of_child (parent->value.get (), parent->type,
				       parent->name.c_str (), index);
}

static std::string
ada_path_expr_of_child (const struct varobj *child)
{
  const struct varobj *parent = child->parent;
  const char *parent_path_expr = varobj_get_path_expr (parent);

  return ada_varobj_get_path_expr_of_child (parent->value.get (),
					    parent->type,
					    parent->name.c_str (),
					    parent_path_expr,
					    child->index);
}

static struct value *
ada_value_of_child (const struct varobj *parent, int index)
{
  return ada_varobj_get_value_of_child (parent->value.get (), parent->type,
					parent->name.c_str (), index);
}

static struct type *
ada_type_of_child (const struct varobj *parent, int index)
{
  return ada_varobj_get_type_of_child (parent->value.get (), parent->type,
				       index);
}

static std::string
ada_value_of_variable (const struct varobj *var,
		       enum varobj_display_formats format)
{
  struct value_print_options opts;

  varobj_formatted_print_options (&opts, format);

  return ada_varobj_get_value_of_variable (var->value.get (), var->type,
					   &opts);
}

/* Implement the "value_is_changeable_p" routine for Ada.  */

static bool
ada_value_is_changeable_p (const struct varobj *var)
{
  struct type *type = (var->value != nullptr
		       ? var->value->type () : var->type);

  if (type->code () == TYPE_CODE_REF)
    type = type->target_type ();

  if (ada_is_access_to_unconstrained_array (type))
    {
      /* This is in reality a pointer to an unconstrained array.
	 its value is changeable.  */
      return true;
    }

  if (ada_is_string_type (type))
    {
      /* We display the contents of the string in the array's
	 "value" field.  The contents can change, so consider
	 that the array is changeable.  */
      return true;
    }

  return varobj_default_value_is_changeable_p (var);
}

/* Implement the "value_has_mutated" routine for Ada.  */

static bool
ada_value_has_mutated (const struct varobj *var, struct value *new_val,
		       struct type *new_type)
{
  int from = -1;
  int to = -1;

  /* If the number of fields have changed, then for sure the type
     has mutated.  */
  if (ada_varobj_get_number_of_children (new_val, new_type)
      != var->num_children)
    return true;

  /* If the number of fields have remained the same, then we need
     to check the name of each field.  If they remain the same,
     then chances are the type hasn't mutated.  This is technically
     an incomplete test, as the child's type might have changed
     despite the fact that the name remains the same.  But we'll
     handle this situation by saying that the child has mutated,
     not this value.

     If only part (or none!) of the children have been fetched,
     then only check the ones we fetched.  It does not matter
     to the frontend whether a child that it has not fetched yet
     has mutated or not. So just assume it hasn't.  */

  varobj_restrict_range (var->children, &from, &to);
  for (int i = from; i < to; i++)
    if (ada_varobj_get_name_of_child (new_val, new_type,
				      var->name.c_str (), i)
	!= var->children[i]->name)
      return true;

  return false;
}

/* varobj operations for ada.  */

const struct lang_varobj_ops ada_varobj_ops =
{
  ada_number_of_children,
  ada_name_of_variable,
  ada_name_of_child,
  ada_path_expr_of_child,
  ada_value_of_child,
  ada_type_of_child,
  ada_value_of_variable,
  ada_value_is_changeable_p,
  ada_value_has_mutated,
  varobj_default_is_path_expr_parent
};
