/* varobj support for Ada.

   Copyright (C) 2012-2014 Free Software Foundation, Inc.

   This file is part of GDB.

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

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

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

#include "defs.h"
#include "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);
      *type_ptr = ada_check_typedef (value_type (*value_ptr));
    }
  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.

   The result should be deallocated by xfree after use.  */

static char *
ada_varobj_scalar_image (struct type *type, LONGEST val)
{
  struct ui_file *buf = mem_fileopen ();
  struct cleanup *cleanups = make_cleanup_ui_file_delete (buf);
  char *result;

  ada_print_scalar (type, val, buf);
  result = ui_file_xstrdup (buf, NULL);
  do_cleanups (cleanups);

  return result;
}

/* 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 (value);
    }
  else
    type = TYPE_FIELD_TYPE (parent_type, fieldno);

  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 (TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF);

      /* Decode parent_type by the equivalent pointer to (decoded)
	 array.  */
      while (TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
	parent_type = TYPE_TARGET_TYPE (parent_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 (value);
    }
  else
    type = TYPE_TARGET_TYPE (parent_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 (TYPE_INDEX_TYPE (parent_type), elt_index);

      value = ada_value_subscript (parent_value, 1, &index_value);
      type = value_type (value);
    }
  else
    type = TYPE_TARGET_TYPE (parent_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) == TYPE_CODE_PTR
      && (TYPE_CODE (TYPE_TARGET_TYPE (*type)) == TYPE_CODE_STRUCT
          || TYPE_CODE (TYPE_TARGET_TYPE (*type)) == TYPE_CODE_UNION)
      && !ada_is_array_descriptor_type (TYPE_TARGET_TYPE (*type))
      && !ada_is_constrained_packed_array_type (TYPE_TARGET_TYPE (*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 (*value);
    }
}

/* 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 (!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 (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT
	      || TYPE_CODE (parent_type) == TYPE_CODE_UNION);

  for (i = 0; i < TYPE_NFIELDS (parent_type); 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 = TYPE_TARGET_TYPE (parent_type);

  /* Pointer to functions and to void do not have a child, since
     you cannot print what they point to.  */
  if (TYPE_CODE (child_type) == TYPE_CODE_FUNC
      || TYPE_CODE (child_type) == TYPE_CODE_VOID)
    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_array_descriptor_type (parent_type)
      && TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
    return 1;

  if (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY)
    return ada_varobj_get_array_number_of_children (parent_value,
						    parent_type);

  if (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT
      || TYPE_CODE (parent_type) == TYPE_CODE_UNION)
    return ada_varobj_get_struct_number_of_children (parent_value,
						     parent_type);

  if (TYPE_CODE (parent_type) == 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.  This copy must be deallocated
       with xfree after use.

     - 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.  The resulting string must be deallocated
       after use with xfree.

       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,
				       char **child_name,
				       struct value **child_value,
				       struct type **child_type,
				       char **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,
				  char **child_name,
				  struct value **child_value,
				  struct type **child_type,
				  char **child_path_expr)
{
  int fieldno;
  int childno = 0;

  gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT);

  for (fieldno = 0; fieldno < TYPE_NFIELDS (parent_type); 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 = TYPE_FIELD_NAME (parent_type, fieldno);
	      int child_name_len = ada_name_prefix_len (field_name);

	      *child_name = xstrprintf ("%.*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 = TYPE_FIELD_NAME (parent_type, fieldno);
	      int child_name_len = ada_name_prefix_len (field_name);

	      *child_path_expr =
		xstrprintf ("(%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,
			       char **child_name,
			       struct value **child_value,
			       struct type **child_type,
			       char **child_path_expr)
{
  if (child_name)
    *child_name = xstrprintf ("%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 = xstrprintf ("(%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,
					char **child_name,
					struct value **child_value,
					struct type **child_type,
					char **child_path_expr)
{
  struct type *index_type;
  int real_index;

  gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY);

  index_type = TYPE_INDEX_TYPE (parent_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)
    {
      char *index_img = ada_varobj_scalar_image (index_type, real_index);
      struct cleanup *cleanups = make_cleanup (xfree, index_img);

      /* Enumeration litterals 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 litteral "red" for instance, or even
	 the fully-qualified litteral "pck.red" cannot be resolved
	 by itself.  Type qualification is needed to determine which
	 enumeration litterals 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;

      /* If the index type is a range type, find the base type.  */
      while (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
	index_type = TYPE_TARGET_TYPE (index_type);

      if (TYPE_CODE (index_type) == TYPE_CODE_ENUM
	  || TYPE_CODE (index_type) == TYPE_CODE_BOOL)
	{
	  index_type_name = ada_type_name (index_type);
	  if (index_type_name)
	    index_type_name = ada_decode (index_type_name);
	}

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

/* 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,
			   char **child_name,
			   struct value **child_value,
			   struct type **child_type,
			   char **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 = NULL;
  if (child_value)
    *child_value = NULL;
  if (child_type)
    *child_type = NULL;
  if (child_path_expr)
    *child_path_expr = NULL;

  if (ada_is_array_descriptor_type (parent_type)
      && TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
    {
      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 (TYPE_CODE (parent_type) == 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 (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT)
    {
      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 (TYPE_CODE (parent_type) == 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 = xstrdup ("???");
}

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

   The result should be deallocated after use with xfree.  */

static char *
ada_varobj_get_name_of_child (struct value *parent_value,
			      struct type *parent_type,
			      const char *parent_name, int child_index)
{
  char *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.

   The result must be deallocated after use with xfree.  */

static char *
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)
{
  char *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.

   The resulting string must be deallocated after use with xfree.  */

static char *
ada_varobj_get_value_image (struct value *value,
			    struct value_print_options *opts)
{
  char *result;
  struct ui_file *buffer;
  struct cleanup *old_chain;

  buffer = mem_fileopen ();
  old_chain = make_cleanup_ui_file_delete (buffer);

  common_val_print (value, buffer, 0, opts, current_language);
  result = ui_file_xstrdup (buffer, NULL);

  do_cleanups (old_chain);
  return result;
}

/* 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.

   The result should be deallocated after use using xfree.  */

static char *
ada_varobj_get_value_of_array_variable (struct value *value,
					struct type *type,
					struct value_print_options *opts)
{
  char *result;
  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'))
    {
      char *str;
      struct cleanup *old_chain;

      str = ada_varobj_get_value_image (value, opts);
      old_chain = make_cleanup (xfree, str);
      result = xstrprintf ("[%d] %s", numchild, str);
      do_cleanups (old_chain);
    }
  else
    result = xstrprintf ("[%d]", numchild);

  return result;
}

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

static char *
ada_varobj_get_value_of_variable (struct value *value,
				  struct type *type,
				  struct value_print_options *opts)
{
  char *result = NULL;

  ada_varobj_decode_var (&value, &type);

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      result = xstrdup ("{...}");
      break;
    case TYPE_CODE_ARRAY:
      result = ada_varobj_get_value_of_array_variable (value, type, opts);
      break;
    default:
      if (!value)
	result = xstrdup ("");
      else
	result = ada_varobj_get_value_image (value, opts);
      break;
    }

  return result;
}

/* Ada specific callbacks for VAROBJs.  */

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

static char *
ada_name_of_variable (struct varobj *parent)
{
  return c_varobj_ops.name_of_variable (parent);
}

static char *
ada_name_of_child (struct varobj *parent, int index)
{
  return ada_varobj_get_name_of_child (parent->value, parent->type,
				       parent->name, index);
}

static char*
ada_path_expr_of_child (struct varobj *child)
{
  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,
					    parent->type,
					    parent->name,
					    parent_path_expr,
					    child->index);
}

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

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

static char *
ada_value_of_variable (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, var->type, &opts);
}

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

static int
ada_value_is_changeable_p (struct varobj *var)
{
  struct type *type = var->value ? value_type (var->value) : var->type;

  if (ada_is_array_descriptor_type (type)
      && TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
    {
      /* This is in reality a pointer to an unconstrained array.
	 its value is changeable.  */
      return 1;
    }

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

  return varobj_default_value_is_changeable_p (var);
}

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

static int
ada_value_has_mutated (struct varobj *var, struct value *new_val,
		       struct type *new_type)
{
  int i;
  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 1;

  /* 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 (i = from; i < to; i++)
    if (strcmp (ada_varobj_get_name_of_child (new_val, new_type,
					      var->name, i),
		VEC_index (varobj_p, var->children, i)->name) != 0)
      return 1;

  return 0;
}

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