* psymtab.c (PSYMTAB_TO_SYMTAB): Remove.
[deliverable/binutils-gdb.git] / gdb / varobj.c
index 6186db03c8cc5ed029153506eeb0edce4c9e2e2c..308649972108ad8a954abf511d3b7737c8b66ba3 100644 (file)
@@ -33,6 +33,8 @@
 #include "vec.h"
 #include "gdbthread.h"
 #include "inferior.h"
+#include "ada-varobj.h"
+#include "ada-lang.h"
 
 #if HAVE_PYTHON
 #include "python/python.h"
@@ -268,6 +270,9 @@ static void cppush (struct cpstack **pstack, char *name);
 
 static char *cppop (struct cpstack **pstack);
 
+static int update_type_if_necessary (struct varobj *var,
+                                    struct value *new_value);
+
 static int install_new_value (struct varobj *var, struct value *value, 
                              int initial);
 
@@ -304,6 +309,8 @@ static struct varobj *varobj_add_child (struct varobj *var,
 
 #endif /* HAVE_PYTHON */
 
+static int default_value_is_changeable_p (struct varobj *var);
+
 /* C implementation */
 
 static int c_number_of_children (struct varobj *var);
@@ -382,6 +389,11 @@ static struct type *ada_type_of_child (struct varobj *parent, int index);
 static char *ada_value_of_variable (struct varobj *var,
                                    enum varobj_display_formats format);
 
+static int ada_value_is_changeable_p (struct varobj *var);
+
+static int ada_value_has_mutated (struct varobj *var, struct value *new_val,
+                                 struct type *new_type);
+
 /* The language specific vector */
 
 struct language_specific
@@ -415,6 +427,31 @@ struct language_specific
   /* The current value of VAR.  */
   char *(*value_of_variable) (struct varobj * var,
                              enum varobj_display_formats format);
+
+  /* Return non-zero if changes in value of VAR must be detected and
+     reported by -var-update.  Return zero if -var-update should never
+     report changes of such values.  This makes sense for structures
+     (since the changes in children values will be reported separately),
+     or for artifical objects (like 'public' pseudo-field in C++).
+
+     Return value of 0 means that gdb need not call value_fetch_lazy
+     for the value of this variable object.  */
+  int (*value_is_changeable_p) (struct varobj *var);
+
+  /* Return nonzero if the type of VAR has mutated.
+
+     VAR's value is still the varobj's previous value, while NEW_VALUE
+     is VAR's new value and NEW_TYPE is the var's new type.  NEW_VALUE
+     may be NULL indicating that there is no value available (the varobj
+     may be out of scope, of may be the child of a null pointer, for
+     instance).  NEW_TYPE, on the other hand, must never be NULL.
+
+     This function should also be able to assume that var's number of
+     children is set (not < 0).
+
+     Languages where types do not mutate can set this to NULL.  */
+  int (*value_has_mutated) (struct varobj *var, struct value *new_value,
+                           struct type *new_type);
 };
 
 /* Array of known source language routines.  */
@@ -429,7 +466,9 @@ static struct language_specific languages[vlang_end] = {
    c_value_of_root,
    c_value_of_child,
    c_type_of_child,
-   c_value_of_variable}
+   c_value_of_variable,
+   default_value_is_changeable_p,
+   NULL /* value_has_mutated */}
   ,
   /* C */
   {
@@ -441,7 +480,9 @@ static struct language_specific languages[vlang_end] = {
    c_value_of_root,
    c_value_of_child,
    c_type_of_child,
-   c_value_of_variable}
+   c_value_of_variable,
+   default_value_is_changeable_p,
+   NULL /* value_has_mutated */}
   ,
   /* C++ */
   {
@@ -453,7 +494,9 @@ static struct language_specific languages[vlang_end] = {
    cplus_value_of_root,
    cplus_value_of_child,
    cplus_type_of_child,
-   cplus_value_of_variable}
+   cplus_value_of_variable,
+   default_value_is_changeable_p,
+   NULL /* value_has_mutated */}
   ,
   /* Java */
   {
@@ -465,7 +508,9 @@ static struct language_specific languages[vlang_end] = {
    java_value_of_root,
    java_value_of_child,
    java_type_of_child,
-   java_value_of_variable},
+   java_value_of_variable,
+   default_value_is_changeable_p,
+   NULL /* value_has_mutated */},
   /* Ada */
   {
    vlang_ada,
@@ -476,7 +521,9 @@ static struct language_specific languages[vlang_end] = {
    ada_value_of_root,
    ada_value_of_child,
    ada_type_of_child,
-   ada_value_of_variable}
+   ada_value_of_variable,
+   ada_value_is_changeable_p,
+   ada_value_has_mutated}
 };
 
 /* A little convenience enum for dealing with C++/Java.  */
@@ -515,7 +562,7 @@ is_root_p (struct varobj *var)
 #ifdef HAVE_PYTHON
 /* Helper function to install a Python environment suitable for
    use during operations on VAR.  */
-struct cleanup *
+static struct cleanup *
 varobj_ensure_python_env (struct varobj *var)
 {
   return ensure_python_env (var->root->exp->gdbarch,
@@ -672,15 +719,21 @@ varobj_create (char *objname,
 
          var->type = value_type (type_only_value);
        }
-      else 
-       var->type = value_type (value);
+       else
+         {
+           int real_type_found = 0;
 
-      install_new_value (var, value, 1 /* Initial assignment */);
+           var->type = value_actual_type (value, 0, &real_type_found);
+           if (real_type_found)
+             value = value_cast (var->type, value);
+         }
 
       /* Set language info */
       lang = variable_language (var);
       var->root->lang = &languages[lang];
 
+      install_new_value (var, value, 1 /* Initial assignment */);
+
       /* Set ourselves as our root.  */
       var->root->rootvar = var;
 
@@ -961,6 +1014,7 @@ restrict_range (VEC (varobj_p) *children, int *from, int *to)
 static void
 install_dynamic_child (struct varobj *var,
                       VEC (varobj_p) **changed,
+                      VEC (varobj_p) **type_changed,
                       VEC (varobj_p) **new,
                       VEC (varobj_p) **unchanged,
                       int *cchanged,
@@ -983,12 +1037,18 @@ install_dynamic_child (struct varobj *var,
     {
       varobj_p existing = VEC_index (varobj_p, var->children, index);
 
+      int type_updated = update_type_if_necessary (existing, value);
+      if (type_updated)
+       {
+         if (type_changed)
+           VEC_safe_push (varobj_p, *type_changed, existing);
+       }
       if (install_new_value (existing, value, 0))
        {
-         if (changed)
+         if (!type_updated && changed)
            VEC_safe_push (varobj_p, *changed, existing);
        }
-      else if (unchanged)
+      else if (!type_updated && unchanged)
        VEC_safe_push (varobj_p, *unchanged, existing);
     }
 }
@@ -1011,6 +1071,7 @@ dynamic_varobj_has_child_method (struct varobj *var)
 static int
 update_dynamic_varobj_children (struct varobj *var,
                                VEC (varobj_p) **changed,
+                               VEC (varobj_p) **type_changed,
                                VEC (varobj_p) **new,
                                VEC (varobj_p) **unchanged,
                                int *cchanged,
@@ -1146,6 +1207,7 @@ update_dynamic_varobj_children (struct varobj *var,
          if (v == NULL)
            gdbpy_print_stack ();
          install_dynamic_child (var, can_mention ? changed : NULL,
+                                can_mention ? type_changed : NULL,
                                 can_mention ? new : NULL,
                                 can_mention ? unchanged : NULL,
                                 can_mention ? cchanged : NULL, i, name, v);
@@ -1201,7 +1263,7 @@ varobj_get_num_children (struct varobj *var)
 
          /* 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, &dummy,
+         update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL, &dummy,
                                          0, 0, 0);
        }
       else
@@ -1227,8 +1289,8 @@ varobj_list_children (struct varobj *var, int *from, int *to)
       /* 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, &children_changed,
-                                     0, 0, *to);
+      update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL,
+                                     &children_changed, 0, 0, *to);
       restrict_range (var->children, from, to);
       return var->children;
     }
@@ -1575,6 +1637,43 @@ install_new_value_visualizer (struct varobj *var)
 #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 int
+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;
+         char *curr_type_str, *new_type_str;
+
+         new_type = value_actual_type (new_value, 0, 0);
+         new_type_str = type_to_string (new_type);
+         curr_type_str = varobj_get_type (var);
+         if (strcmp (curr_type_str, new_type_str) != 0)
+           {
+             var->type = new_type;
+
+             /* This information may be not valid for a new type.  */
+             varobj_delete (var, NULL, 1);
+             VEC_free (varobj_p, var->children);
+             var->num_children = -1;
+             return 1;
+           }
+       }
+    }
+
+  return 0;
+}
+
 /* Assign a new value to a variable object.  If INITIAL is non-zero,
    this is the first assignement after the variable object was just
    created, or changed type.  In that case, just assign the value 
@@ -1824,6 +1923,30 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
 #endif
 }
 
+/* If NEW_VALUE is the new value of the given varobj (var), return
+   non-zero 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 int
+varobj_value_has_mutated (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 0;
+
+  if (var->root->lang->value_has_mutated)
+    return var->root->lang->value_has_mutated (var, new_value, new_type);
+  else
+    return 0;
+}
+
 /* 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
@@ -1880,8 +2003,9 @@ varobj_update (struct varobj **varp, int explicit)
         value_of_root variable dispose of the varobj if the type
         has changed.  */
       new = value_of_root (varp, &type_changed);
+      if (update_type_if_necessary(*varp, new))
+         type_changed = 1;
       r.varobj = *varp;
-
       r.type_changed = type_changed;
       if (install_new_value ((*varp), new, type_changed))
        r.changed = 1;
@@ -1918,9 +2042,30 @@ varobj_update (struct varobj **varp, int explicit)
       /* Update this variable, unless it's a root, which is already
         updated.  */
       if (!r.value_installed)
-       {         
+       {
+         struct type *new_type;
+
          new = value_of_child (v->parent, v->index);
-         if (install_new_value (v, new, 0 /* type not changed */))
+         if (update_type_if_necessary(v, new))
+           r.type_changed = 1;
+         if (new)
+           new_type = value_type (new);
+         else
+           new_type = v->root->lang->type_of_child (v->parent, v->index);
+
+         if (varobj_value_has_mutated (v, new, new_type))
+           {
+             /* The children are no longer valid; delete them now.
+                Report the fact that its type changed as well.  */
+             varobj_delete (v, NULL, 1 /* only_children */);
+             v->num_children = -1;
+             v->to = -1;
+             v->from = -1;
+             v->type = new_type;
+             r.type_changed = 1;
+           }
+
+         if (install_new_value (v, new, r.type_changed))
            {
              r.changed = 1;
              v->updated = 0;
@@ -1932,7 +2077,8 @@ varobj_update (struct varobj **varp, int explicit)
         invoked.  */
       if (v->pretty_printer)
        {
-         VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0;
+         VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0;
+         VEC (varobj_p) *new = 0;
          int i, children_changed = 0;
 
          if (v->frozen)
@@ -1950,7 +2096,7 @@ varobj_update (struct varobj **varp, int explicit)
                 it.  */
              if (!varobj_has_more (v, 0))
                {
-                 update_dynamic_varobj_children (v, NULL, NULL, NULL,
+                 update_dynamic_varobj_children (v, NULL, NULL, NULL, NULL,
                                                  &dummy, 0, 0, 0);
                  if (varobj_has_more (v, 0))
                    r.changed = 1;
@@ -1964,8 +2110,8 @@ varobj_update (struct varobj **varp, int explicit)
 
          /* If update_dynamic_varobj_children returns 0, then we have
             a non-conforming pretty-printer, so we skip it.  */
-         if (update_dynamic_varobj_children (v, &changed, &new, &unchanged,
-                                             &children_changed, 1,
+         if (update_dynamic_varobj_children (v, &changed, &type_changed, &new,
+                                             &unchanged, &children_changed, 1,
                                              v->from, v->to))
            {
              if (children_changed || new)
@@ -1977,6 +2123,18 @@ varobj_update (struct varobj **varp, int explicit)
                 popped from the work stack first, and so will be
                 added to result first.  This does not affect
                 correctness, just "nicer".  */
+             for (i = VEC_length (varobj_p, type_changed) - 1; i >= 0; --i)
+               {
+                 varobj_p tmp = VEC_index (varobj_p, type_changed, i);
+                 varobj_update_result r = {0};
+
+                 /* Type may change only if value was changed.  */
+                 r.varobj = tmp;
+                 r.changed = 1;
+                 r.type_changed = 1;
+                 r.value_installed = 1;
+                 VEC_safe_push (varobj_update_result, stack, &r);
+               }
              for (i = VEC_length (varobj_p, changed) - 1; i >= 0; --i)
                {
                  varobj_p tmp = VEC_index (varobj_p, changed, i);
@@ -2003,9 +2161,10 @@ varobj_update (struct varobj **varp, int explicit)
              if (r.changed || r.children_changed)
                VEC_safe_push (varobj_update_result, result, &r);
 
-             /* Free CHANGED and UNCHANGED, but not NEW, because NEW
-                has been put into the result vector.  */
+             /* Free CHANGED, TYPE_CHANGED and UNCHANGED, but not NEW,
+                because NEW has been put into the result vector.  */
              VEC_free (varobj_p, changed);
+             VEC_free (varobj_p, type_changed);
              VEC_free (varobj_p, unchanged);
 
              continue;
@@ -2280,7 +2439,7 @@ create_child_with_value (struct varobj *parent, int index, const char *name,
   if (value != NULL)
     /* If the child had no evaluation errors, var->value
        will be non-NULL and contain a valid type.  */
-    child->type = value_type (value);
+    child->type = value_actual_type (value, 0, NULL);
   else
     /* Otherwise, we must compute the type.  */
     child->type = (*child->root->lang->type_of_child) (child->parent, 
@@ -2627,7 +2786,28 @@ value_of_root (struct varobj **var_handle, int *type_changed)
       *type_changed = 0;
     }
 
-  return (*var->root->lang->value_of_root) (var_handle);
+  {
+    struct value *value;
+
+    value = (*var->root->lang->value_of_root) (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 (value)))
+      {
+       /* 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, NULL, 1 /* only_children */);
+       var->num_children = -1;
+       var->to = -1;
+       var->from = -1;
+       *type_changed = 1;
+      }
+    return value;
+  }
 }
 
 /* What is the ``struct value *'' for the INDEX'th child of PARENT?  */
@@ -2816,39 +2996,12 @@ varobj_editable_p (struct varobj *var)
     }
 }
 
-/* Return non-zero if changes in value of VAR
-   must be detected and reported by -var-update.
-   Return zero is -var-update should never report
-   changes of such values.  This makes sense for structures
-   (since the changes in children values will be reported separately),
-   or for artifical objects (like 'public' pseudo-field in C++).
+/* Call VAR's value_is_changeable_p language-specific callback.  */
 
-   Return value of 0 means that gdb need not call value_fetch_lazy
-   for the value of this variable object.  */
 static int
 varobj_value_is_changeable_p (struct varobj *var)
 {
-  int r;
-  struct type *type;
-
-  if (CPLUS_FAKE_CHILD (var))
-    return 0;
-
-  type = get_value_type (var);
-
-  switch (TYPE_CODE (type))
-    {
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-    case TYPE_CODE_ARRAY:
-      r = 0;
-      break;
-
-    default:
-      r = 1;
-    }
-
-  return r;
+  return var->root->lang->value_is_changeable_p (var);
 }
 
 /* Return 1 if that varobj is floating, that is is always evaluated in the
@@ -2867,6 +3020,10 @@ varobj_floating_p (struct varobj *var)
    to all types and dereferencing pointers to
    structures.
 
+   If LOOKUP_ACTUAL_TYPE is set the enclosing type of the
+   value will be fetched and if it differs from static type
+   the value will be casted to it.
+
    Both TYPE and *TYPE should be non-null.  VALUE
    can be null if we want to only translate type.
    *VALUE can be null as well -- if the parent
@@ -2878,7 +3035,8 @@ varobj_floating_p (struct varobj *var)
 static void
 adjust_value_for_child_access (struct value **value,
                                  struct type **type,
-                                 int *was_ptr)
+                                 int *was_ptr,
+                                 int lookup_actual_type)
 {
   gdb_assert (type && *type);
 
@@ -2923,9 +3081,53 @@ adjust_value_for_child_access (struct value **value,
   /* The 'get_target_type' function calls check_typedef on
      result, so we can immediately check type code.  No
      need to call check_typedef here.  */
+
+  /* Access a real type of the value (if necessary and possible).  */
+  if (value && *value && lookup_actual_type)
+    {
+      struct type *enclosing_type;
+      int real_type_found = 0;
+
+      enclosing_type = value_actual_type (*value, 1, &real_type_found);
+      if (real_type_found)
+        {
+          *type = enclosing_type;
+          *value = value_cast (enclosing_type, *value);
+        }
+    }
+}
+
+/* Implement the "value_is_changeable_p" varobj callback for most
+   languages.  */
+
+static int
+default_value_is_changeable_p (struct varobj *var)
+{
+  int r;
+  struct type *type;
+
+  if (CPLUS_FAKE_CHILD (var))
+    return 0;
+
+  type = get_value_type (var);
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+    case TYPE_CODE_ARRAY:
+      r = 0;
+      break;
+
+    default:
+      r = 1;
+    }
+
+  return r;
 }
 
 /* C */
+
 static int
 c_number_of_children (struct varobj *var)
 {
@@ -2933,7 +3135,7 @@ c_number_of_children (struct varobj *var)
   int children = 0;
   struct type *target;
 
-  adjust_value_for_child_access (NULL, &type, NULL);
+  adjust_value_for_child_access (NULL, &type, NULL, 0);
   target = get_target_type (type);
 
   switch (TYPE_CODE (type))
@@ -3049,7 +3251,7 @@ c_describe_child (struct varobj *parent, int index,
       *cfull_expression = NULL;
       parent_expression = varobj_get_path_expr (get_path_expr_parent (parent));
     }
-  adjust_value_for_child_access (&value, &type, &was_ptr);
+  adjust_value_for_child_access (&value, &type, &was_ptr, 0);
       
   switch (TYPE_CODE (type))
     {
@@ -3345,16 +3547,29 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format)
 static int
 cplus_number_of_children (struct varobj *var)
 {
+  struct value *value = NULL;
   struct type *type;
   int children, dont_know;
+  int lookup_actual_type = 0;
+  struct value_print_options opts;
 
   dont_know = 1;
   children = 0;
 
+  get_user_print_options (&opts);
+
   if (!CPLUS_FAKE_CHILD (var))
     {
       type = get_value_type (var);
-      adjust_value_for_child_access (NULL, &type, NULL);
+
+      /* It is necessary to access a real type (via RTTI).  */
+      if (opts.objectprint)
+        {
+          value = var->value;
+          lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+                               || TYPE_CODE (var->type) == TYPE_CODE_PTR);
+        }
+      adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
 
       if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
          ((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -3381,7 +3596,17 @@ cplus_number_of_children (struct varobj *var)
       int kids[3];
 
       type = get_value_type (var->parent);
-      adjust_value_for_child_access (NULL, &type, NULL);
+
+      /* It is necessary to access a real type (via RTTI).  */
+      if (opts.objectprint)
+        {
+         struct varobj *parent = var->parent;
+
+         value = parent->value;
+         lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF
+                               || TYPE_CODE (parent->type) == TYPE_CODE_PTR);
+        }
+      adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
 
       cplus_class_num_children (type, kids);
       if (strcmp (var->name, "public") == 0)
@@ -3463,7 +3688,10 @@ cplus_describe_child (struct varobj *parent, int index,
   struct value *value;
   struct type *type;
   int was_ptr;
+  int lookup_actual_type = 0;
   char *parent_expression = NULL;
+  struct varobj *var;
+  struct value_print_options opts;
 
   if (cname)
     *cname = NULL;
@@ -3474,24 +3702,18 @@ cplus_describe_child (struct varobj *parent, int index,
   if (cfull_expression)
     *cfull_expression = NULL;
 
-  if (CPLUS_FAKE_CHILD (parent))
-    {
-      value = parent->parent->value;
-      type = get_value_type (parent->parent);
-      if (cfull_expression)
-       parent_expression
-         = varobj_get_path_expr (get_path_expr_parent (parent->parent));
-    }
-  else
-    {
-      value = parent->value;
-      type = get_value_type (parent);
-      if (cfull_expression)
-       parent_expression
-         = varobj_get_path_expr (get_path_expr_parent (parent));
-    }
+  get_user_print_options (&opts);
 
-  adjust_value_for_child_access (&value, &type, &was_ptr);
+  var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent;
+  if (opts.objectprint)
+    lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF
+                         || TYPE_CODE (var->type) == TYPE_CODE_PTR);
+  value = var->value;
+  type = get_value_type (var);
+  if (cfull_expression)
+    parent_expression = varobj_get_path_expr (get_path_expr_parent (var));
+
+  adjust_value_for_child_access (&value, &type, &was_ptr, lookup_actual_type);
 
   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
       || TYPE_CODE (type) == TYPE_CODE_UNION)
@@ -3794,7 +4016,7 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
 static int
 ada_number_of_children (struct varobj *var)
 {
-  return c_number_of_children (var);
+  return ada_varobj_get_number_of_children (var->value, var->type);
 }
 
 static char *
@@ -3806,13 +4028,21 @@ ada_name_of_variable (struct varobj *parent)
 static char *
 ada_name_of_child (struct varobj *parent, int index)
 {
-  return c_name_of_child (parent, 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)
 {
-  return c_path_expr_of_child (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 *
@@ -3824,19 +4054,92 @@ ada_value_of_root (struct varobj **var_handle)
 static struct value *
 ada_value_of_child (struct varobj *parent, int index)
 {
-  return c_value_of_child (parent, 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 c_type_of_child (parent, 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)
 {
-  return c_value_of_variable (var, format);
+  struct value_print_options opts;
+
+  get_formatted_print_options (&opts, format_code[(int) format]);
+  opts.deref_ref = 0;
+  opts.raw = 1;
+
+  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 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.  */
+
+  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;
 }
 
 /* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
This page took 0.051366 seconds and 4 git commands to generate.