* gdb.ada/taft_type/pck.ads, gdb.ada/taft_type/pck.adb,
[deliverable/binutils-gdb.git] / gdb / varobj.c
index c19bd20c13fb0d71705f1b011b39b9173d29057c..d078bef5074e3a0c59a7bad0d22cd30e872afe95 100644 (file)
@@ -1,11 +1,11 @@
 /* Implementation of the GDB variable objects API.
 
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   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,
@@ -14,9 +14,7 @@
    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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "exceptions.h"
@@ -101,6 +99,10 @@ struct varobj
   /* NOTE: This is the "expression" */
   char *name;
 
+  /* Alloc'd expression for this child.  Can be used to create a
+     root variable corresponding to this child.  */
+  char *path_expr;
+
   /* The alloc'd name for this variable's object. This is here for
      convenience when constructing this object's children. */
   char *obj_name;
@@ -108,7 +110,9 @@ struct varobj
   /* Index of this variable in its parent or -1 */
   int index;
 
-  /* The type of this variable. This may NEVER be NULL. */
+  /* The type of this variable.  This can be NULL
+     for artifial variable objects -- currently, the "accessibility" 
+     variable objects in C++.  */
   struct type *type;
 
   /* The value of this expression or subexpression.  A NULL value
@@ -217,8 +221,6 @@ static struct value *value_of_root (struct varobj **var_handle, int *);
 
 static struct value *value_of_child (struct varobj *parent, int index);
 
-static int variable_editable (struct varobj *var);
-
 static char *my_value_of_variable (struct varobj *var);
 
 static char *value_get_print_value (struct value *value,
@@ -236,14 +238,14 @@ static char *c_name_of_variable (struct varobj *parent);
 
 static char *c_name_of_child (struct varobj *parent, int index);
 
+static char *c_path_expr_of_child (struct varobj *child);
+
 static struct value *c_value_of_root (struct varobj **var_handle);
 
 static struct value *c_value_of_child (struct varobj *parent, int index);
 
 static struct type *c_type_of_child (struct varobj *parent, int index);
 
-static int c_variable_editable (struct varobj *var);
-
 static char *c_value_of_variable (struct varobj *var);
 
 /* C++ implementation */
@@ -256,14 +258,14 @@ static char *cplus_name_of_variable (struct varobj *parent);
 
 static char *cplus_name_of_child (struct varobj *parent, int index);
 
+static char *cplus_path_expr_of_child (struct varobj *child);
+
 static struct value *cplus_value_of_root (struct varobj **var_handle);
 
 static struct value *cplus_value_of_child (struct varobj *parent, int index);
 
 static struct type *cplus_type_of_child (struct varobj *parent, int index);
 
-static int cplus_variable_editable (struct varobj *var);
-
 static char *cplus_value_of_variable (struct varobj *var);
 
 /* Java implementation */
@@ -274,14 +276,14 @@ static char *java_name_of_variable (struct varobj *parent);
 
 static char *java_name_of_child (struct varobj *parent, int index);
 
+static char *java_path_expr_of_child (struct varobj *child);
+
 static struct value *java_value_of_root (struct varobj **var_handle);
 
 static struct value *java_value_of_child (struct varobj *parent, int index);
 
 static struct type *java_type_of_child (struct varobj *parent, int index);
 
-static int java_variable_editable (struct varobj *var);
-
 static char *java_value_of_variable (struct varobj *var);
 
 /* The language specific vector */
@@ -301,6 +303,10 @@ struct language_specific
   /* The name of the INDEX'th child of PARENT. */
   char *(*name_of_child) (struct varobj * parent, int index);
 
+  /* Returns the rooted expression of CHILD, which is a variable
+     obtain that has some parent.  */
+  char *(*path_expr_of_child) (struct varobj * child);
+
   /* The ``struct value *'' of the root variable ROOT. */
   struct value *(*value_of_root) (struct varobj ** root_handle);
 
@@ -310,9 +316,6 @@ struct language_specific
   /* The type of the INDEX'th child of PARENT. */
   struct type *(*type_of_child) (struct varobj * parent, int index);
 
-  /* Is VAR editable? */
-  int (*variable_editable) (struct varobj * var);
-
   /* The current value of VAR. */
   char *(*value_of_variable) (struct varobj * var);
 };
@@ -325,10 +328,10 @@ static struct language_specific languages[vlang_end] = {
    c_number_of_children,
    c_name_of_variable,
    c_name_of_child,
+   c_path_expr_of_child,
    c_value_of_root,
    c_value_of_child,
    c_type_of_child,
-   c_variable_editable,
    c_value_of_variable}
   ,
   /* C */
@@ -337,10 +340,10 @@ static struct language_specific languages[vlang_end] = {
    c_number_of_children,
    c_name_of_variable,
    c_name_of_child,
+   c_path_expr_of_child,
    c_value_of_root,
    c_value_of_child,
    c_type_of_child,
-   c_variable_editable,
    c_value_of_variable}
   ,
   /* C++ */
@@ -349,10 +352,10 @@ static struct language_specific languages[vlang_end] = {
    cplus_number_of_children,
    cplus_name_of_variable,
    cplus_name_of_child,
+   cplus_path_expr_of_child,
    cplus_value_of_root,
    cplus_value_of_child,
    cplus_type_of_child,
-   cplus_variable_editable,
    cplus_value_of_variable}
   ,
   /* Java */
@@ -361,10 +364,10 @@ static struct language_specific languages[vlang_end] = {
    java_number_of_children,
    java_name_of_variable,
    java_name_of_child,
+   java_path_expr_of_child,
    java_value_of_root,
    java_value_of_child,
    java_type_of_child,
-   java_variable_editable,
    java_value_of_variable}
 };
 
@@ -444,6 +447,7 @@ varobj_create (char *objname,
       char *p;
       enum varobj_languages lang;
       struct value *value = NULL;
+      int expr_len;
 
       /* Parse and evaluate the expression, filling in as much
          of the variable's data as possible */
@@ -488,7 +492,10 @@ varobj_create (char *objname,
 
       var->format = variable_default_display (var);
       var->root->valid_block = innermost_block;
-      var->name = savestring (expression, strlen (expression));
+      expr_len = strlen (expression);
+      var->name = savestring (expression, expr_len);
+      /* For a root var, the name and the expr are the same.  */
+      var->path_expr = savestring (expression, expr_len);
 
       /* When the frame is different from the current frame, 
          we must select the appropriate frame before parsing
@@ -501,7 +508,7 @@ varobj_create (char *objname,
          select_frame (fi);
        }
 
-      /* We definitively need to catch errors here.
+      /* We definitely need to catch errors here.
          If evaluate_expression succeeds we got the value we wanted.
          But if it fails, we still go on with a call to evaluate_type()  */
       if (!gdb_evaluate_expression (var->root->exp, &value))
@@ -806,6 +813,23 @@ varobj_get_gdb_type (struct varobj *var)
   return var->type;
 }
 
+/* Return a pointer to the full rooted expression of varobj VAR.
+   If it has not been computed yet, compute it.  */
+char *
+varobj_get_path_expr (struct varobj *var)
+{
+  if (var->path_expr != NULL)
+    return var->path_expr;
+  else 
+    {
+      /* For root varobjs, we initialize path_expr
+        when creating varobj, so here it should be
+        child varobj.  */
+      gdb_assert (!is_root_p (var));
+      return (*var->root->lang->path_expr_of_child) (var);
+    }
+}
+
 enum varobj_languages
 varobj_get_language (struct varobj *var)
 {
@@ -817,7 +841,7 @@ varobj_get_attributes (struct varobj *var)
 {
   int attributes = 0;
 
-  if (var->root->is_valid && variable_editable (var))
+  if (varobj_editable_p (var))
     /* FIXME: define masks for attributes */
     attributes |= 0x00000001;  /* Editable */
 
@@ -847,55 +871,51 @@ varobj_set_value (struct varobj *var, char *expression)
   struct expression *exp;
   struct value *value;
   int saved_input_radix = input_radix;
+  char *s = expression;
+  int i;
 
-  if (var->value != NULL && variable_editable (var))
-    {
-      char *s = expression;
-      int i;
-
-      input_radix = 10;                /* ALWAYS reset to decimal temporarily */
-      exp = parse_exp_1 (&s, 0, 0);
-      if (!gdb_evaluate_expression (exp, &value))
-       {
-         /* We cannot proceed without a valid expression. */
-         xfree (exp);
-         return 0;
-       }
+  gdb_assert (varobj_editable_p (var));
 
-      /* All types that are editable must also be changeable.  */
-      gdb_assert (varobj_value_is_changeable_p (var));
-
-      /* The value of a changeable variable object must not be lazy.  */
-      gdb_assert (!value_lazy (var->value));
-
-      /* Need to coerce the input.  We want to check if the
-        value of the variable object will be different
-        after assignment, and the first thing value_assign
-        does is coerce the input.
-        For example, if we are assigning an array to a pointer variable we
-        should compare the pointer with the the array's address, not with the
-        array's content.  */
-      value = coerce_array (value);
-
-      /* The new value may be lazy.  gdb_value_assign, or 
-        rather value_contents, will take care of this.
-        If fetching of the new value will fail, gdb_value_assign
-        with catch the exception.  */
-      if (!gdb_value_assign (var->value, value, &val))
-       return 0;
-     
-      /* If the value has changed, record it, so that next -var-update can
-        report this change.  If a variable had a value of '1', we've set it
-        to '333' and then set again to '1', when -var-update will report this
-        variable as changed -- because the first assignment has set the
-        'updated' flag.  There's no need to optimize that, because return value
-        of -var-update should be considered an approximation.  */
-      var->updated = install_new_value (var, val, 0 /* Compare values. */);
-      input_radix = saved_input_radix;
-      return 1;
+  input_radix = 10;            /* ALWAYS reset to decimal temporarily */
+  exp = parse_exp_1 (&s, 0, 0);
+  if (!gdb_evaluate_expression (exp, &value))
+    {
+      /* We cannot proceed without a valid expression. */
+      xfree (exp);
+      return 0;
     }
 
-  return 0;
+  /* All types that are editable must also be changeable.  */
+  gdb_assert (varobj_value_is_changeable_p (var));
+
+  /* The value of a changeable variable object must not be lazy.  */
+  gdb_assert (!value_lazy (var->value));
+
+  /* Need to coerce the input.  We want to check if the
+     value of the variable object will be different
+     after assignment, and the first thing value_assign
+     does is coerce the input.
+     For example, if we are assigning an array to a pointer variable we
+     should compare the pointer with the the array's address, not with the
+     array's content.  */
+  value = coerce_array (value);
+
+  /* The new value may be lazy.  gdb_value_assign, or 
+     rather value_contents, will take care of this.
+     If fetching of the new value will fail, gdb_value_assign
+     with catch the exception.  */
+  if (!gdb_value_assign (var->value, value, &val))
+    return 0;
+     
+  /* If the value has changed, record it, so that next -var-update can
+     report this change.  If a variable had a value of '1', we've set it
+     to '333' and then set again to '1', when -var-update will report this
+     variable as changed -- because the first assignment has set the
+     'updated' flag.  There's no need to optimize that, because return value
+     of -var-update should be considered an approximation.  */
+  var->updated = install_new_value (var, val, 0 /* Compare values. */);
+  input_radix = saved_input_radix;
+  return 1;
 }
 
 /* Returns a malloc'ed list with all root variable objects */
@@ -946,6 +966,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   int need_to_fetch;
   int changed = 0;
   int intentionally_not_fetched = 0;
+  char *print_value = NULL;
 
   /* We need to know the varobj's type to decide if the value should
      be fetched or not.  C++ fake children (public/protected/private) don't have
@@ -1003,12 +1024,17 @@ install_new_value (struct varobj *var, struct value *value, int initial)
        }
     }
 
+  /* Below, we'll be comparing string rendering of old and new
+     values.  Don't get string rendering if the value is
+     lazy -- if it is, the code above has decided that the value
+     should not be fetched.  */
+  if (value && !value_lazy (value))
+      print_value = value_get_print_value (value, var->format);
+
   /* If the type is changeable, compare the old and the new values.
      If this is the initial assignment, we don't have any old value
      to compare with.  */
-  if (initial && changeable)
-    var->print_value = value_get_print_value (value, var->format);
-  else if (changeable)
+  if (!initial && changeable)
     {
       /* If the value of the varobj was changed by -var-set-value, then the 
         value in the varobj and in the target is the same.  However, that value
@@ -1016,8 +1042,6 @@ install_new_value (struct varobj *var, struct value *value, int initial)
         -var-update. So need to the varobj as changed.  */
       if (var->updated)
        {
-         xfree (var->print_value);
-         var->print_value = value_get_print_value (value, var->format);
          changed = 1;
        }
       else 
@@ -1038,26 +1062,16 @@ install_new_value (struct varobj *var, struct value *value, int initial)
            ;
          else if (var->value == NULL || value == NULL)
            {
-             xfree (var->print_value);
-             var->print_value = value_get_print_value (value, var->format);
              changed = 1;
            }
          else
            {
-             char *print_value;
              gdb_assert (!value_lazy (var->value));
              gdb_assert (!value_lazy (value));
-             print_value = value_get_print_value (value, var->format);
 
              gdb_assert (var->print_value != NULL && print_value != NULL);
              if (strcmp (var->print_value, print_value) != 0)
-               {
-                 xfree (var->print_value);
-                 var->print_value = print_value;
-                 changed = 1;
-               }
-             else
-               xfree (print_value);
+               changed = 1;
            }
        }
     }
@@ -1066,6 +1080,9 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   if (var->value != NULL && var->value != value)
     value_free (var->value);
   var->value = value;
+  if (var->print_value)
+    xfree (var->print_value);
+  var->print_value = print_value;
   if (value && value_lazy (value) && intentionally_not_fetched)
     var->not_fetched = 1;
   else
@@ -1256,6 +1273,8 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp,
   for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
     {   
       varobj_p child = VEC_index (varobj_p, var->children, i);
+      if (!child)
+       continue;
       if (!remove_from_parent_p)
        child->parent = NULL;
       delete_variable_1 (resultp, delcountp, child, 0, only_children_p);
@@ -1459,6 +1478,7 @@ new_variable (void)
 
   var = (struct varobj *) xmalloc (sizeof (struct varobj));
   var->name = NULL;
+  var->path_expr = NULL;
   var->obj_name = NULL;
   var->index = -1;
   var->type = NULL;
@@ -1507,6 +1527,7 @@ free_variable (struct varobj *var)
   xfree (var->name);
   xfree (var->obj_name);
   xfree (var->print_value);
+  xfree (var->path_expr);
   xfree (var);
 }
 
@@ -1710,13 +1731,14 @@ value_of_root (struct varobj **var_handle, int *type_changed)
     {
       struct varobj *tmp_var;
       char *old_type, *new_type;
-      old_type = varobj_get_type (var);
+
       tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0,
                               USE_SELECTED_FRAME);
       if (tmp_var == NULL)
        {
          return NULL;
        }
+      old_type = varobj_get_type (var);
       new_type = varobj_get_type (tmp_var);
       if (strcmp (old_type, new_type) == 0)
        {
@@ -1740,6 +1762,8 @@ value_of_root (struct varobj **var_handle, int *type_changed)
          var = *var_handle;
          *type_changed = 1;
        }
+      xfree (old_type);
+      xfree (new_type);
     }
   else
     {
@@ -1760,14 +1784,6 @@ value_of_child (struct varobj *parent, int index)
   return value;
 }
 
-/* Is this variable editable? Use the variable's type to make
-   this determination. */
-static int
-variable_editable (struct varobj *var)
-{
-  return (*var->root->lang->variable_editable) (var);
-}
-
 /* GDB already has a command called "value_of_variable". Sigh. */
 static char *
 my_value_of_variable (struct varobj *var)
@@ -1799,6 +1815,33 @@ value_get_print_value (struct value *value, enum varobj_display_formats format)
   return thevalue;
 }
 
+int
+varobj_editable_p (struct varobj *var)
+{
+  struct type *type;
+  struct value *value;
+
+  if (!(var->root->is_valid && var->value && VALUE_LVAL (var->value)))
+    return 0;
+
+  type = get_value_type (var);
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+    case TYPE_CODE_ARRAY:
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_METHOD:
+      return 0;
+      break;
+
+    default:
+      return 1;
+      break;
+    }
+}
+
 /* 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
@@ -1844,13 +1887,21 @@ varobj_value_is_changeable_p (struct varobj *var)
    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
-   value is not known.  */
+   value is not known.  
+
+   If WAS_PTR is not NULL, set *WAS_PTR to 0 or 1
+   depending on whether pointer was deferenced
+   in this function.  */
 static void
 adjust_value_for_child_access (struct value **value,
-                                 struct type **type)
+                                 struct type **type,
+                                 int *was_ptr)
 {
   gdb_assert (type && *type);
 
+  if (was_ptr)
+    *was_ptr = 0;
+
   *type = check_typedef (*type);
   
   /* The type of value stored in varobj, that is passed
@@ -1871,6 +1922,8 @@ adjust_value_for_child_access (struct value **value,
          if (value && *value)
            gdb_value_ind (*value, value);        
          *type = target_type;
+         if (was_ptr)
+           *was_ptr = 1;
        }
     }
 
@@ -1887,7 +1940,7 @@ c_number_of_children (struct varobj *var)
   int children = 0;
   struct type *target;
 
-  adjust_value_for_child_access (NULL, &type);
+  adjust_value_for_child_access (NULL, &type, NULL);
   target = get_target_type (type);
 
   switch (TYPE_CODE (type))
@@ -1983,10 +2036,13 @@ value_struct_element_index (struct value *value, int type_index)
    to NULL.  */
 static void 
 c_describe_child (struct varobj *parent, int index,
-                 char **cname, struct value **cvalue, struct type **ctype)
+                 char **cname, struct value **cvalue, struct type **ctype,
+                 char **cfull_expression)
 {
   struct value *value = parent->value;
   struct type *type = get_value_type (parent);
+  char *parent_expression = NULL;
+  int was_ptr;
 
   if (cname)
     *cname = NULL;
@@ -1994,8 +2050,12 @@ c_describe_child (struct varobj *parent, int index,
     *cvalue = NULL;
   if (ctype)
     *ctype = NULL;
-
-  adjust_value_for_child_access (&value, &type);
+  if (cfull_expression)
+    {
+      *cfull_expression = NULL;
+      parent_expression = varobj_get_path_expr (parent);
+    }
+  adjust_value_for_child_access (&value, &type, &was_ptr);
       
   switch (TYPE_CODE (type))
     {
@@ -2015,6 +2075,12 @@ c_describe_child (struct varobj *parent, int index,
       if (ctype)
        *ctype = get_target_type (type);
 
+      if (cfull_expression)
+       *cfull_expression = xstrprintf ("(%s)[%d]", parent_expression, 
+                                       index
+                                       + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)));
+
+
       break;
 
     case TYPE_CODE_STRUCT:
@@ -2034,6 +2100,13 @@ c_describe_child (struct varobj *parent, int index,
       if (ctype)
        *ctype = TYPE_FIELD_TYPE (type, index);
 
+      if (cfull_expression)
+       {
+         char *join = was_ptr ? "->" : ".";
+         *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression, join,
+                                         TYPE_FIELD_NAME (type, index));
+       }
+
       break;
 
     case TYPE_CODE_PTR:
@@ -2048,6 +2121,9 @@ c_describe_child (struct varobj *parent, int index,
         declared type of the variable.  */
       if (ctype)
        *ctype = TYPE_TARGET_TYPE (type);
+
+      if (cfull_expression)
+       *cfull_expression = xstrprintf ("*(%s)", parent_expression);
       
       break;
 
@@ -2055,6 +2131,8 @@ c_describe_child (struct varobj *parent, int index,
       /* This should not happen */
       if (cname)
        *cname = xstrdup ("???");
+      if (cfull_expression)
+       *cfull_expression = xstrdup ("???");
       /* Don't set value and type, we don't know then. */
     }
 }
@@ -2063,10 +2141,18 @@ static char *
 c_name_of_child (struct varobj *parent, int index)
 {
   char *name;
-  c_describe_child (parent, index, &name, NULL, NULL);
+  c_describe_child (parent, index, &name, NULL, NULL, NULL);
   return name;
 }
 
+static char *
+c_path_expr_of_child (struct varobj *child)
+{
+  c_describe_child (child->parent, child->index, NULL, NULL, NULL, 
+                   &child->path_expr);
+  return child->path_expr;
+}
+
 static struct value *
 c_value_of_root (struct varobj **var_handle)
 {
@@ -2115,7 +2201,7 @@ static struct value *
 c_value_of_child (struct varobj *parent, int index)
 {
   struct value *value = NULL;
-  c_describe_child (parent, index, NULL, &value, NULL);
+  c_describe_child (parent, index, NULL, &value, NULL, NULL);
 
   return value;
 }
@@ -2124,29 +2210,10 @@ static struct type *
 c_type_of_child (struct varobj *parent, int index)
 {
   struct type *type = NULL;
-  c_describe_child (parent, index, NULL, NULL, &type);
+  c_describe_child (parent, index, NULL, NULL, &type, NULL);
   return type;
 }
 
-static int
-c_variable_editable (struct varobj *var)
-{
-  switch (TYPE_CODE (get_value_type (var)))
-    {
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-    case TYPE_CODE_ARRAY:
-    case TYPE_CODE_FUNC:
-    case TYPE_CODE_METHOD:
-      return 0;
-      break;
-
-    default:
-      return 1;
-      break;
-    }
-}
-
 static char *
 c_value_of_variable (struct varobj *var)
 {
@@ -2214,7 +2281,7 @@ cplus_number_of_children (struct varobj *var)
   if (!CPLUS_FAKE_CHILD (var))
     {
       type = get_value_type (var);
-      adjust_value_for_child_access (NULL, &type);
+      adjust_value_for_child_access (NULL, &type, NULL);
 
       if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
          ((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2241,7 +2308,7 @@ cplus_number_of_children (struct varobj *var)
       int kids[3];
 
       type = get_value_type (var->parent);
-      adjust_value_for_child_access (NULL, &type);
+      adjust_value_for_child_access (NULL, &type, NULL);
 
       cplus_class_num_children (type, kids);
       if (strcmp (var->name, "public") == 0)
@@ -2312,11 +2379,14 @@ match_accessibility (struct type *type, int index, enum accessibility acc)
 
 static void
 cplus_describe_child (struct varobj *parent, int index,
-                     char **cname, struct value **cvalue, struct type **ctype)
+                     char **cname, struct value **cvalue, struct type **ctype,
+                     char **cfull_expression)
 {
-  char *name = 0;
+  char *name = NULL;
   struct value *value;
   struct type *type;
+  int was_ptr;
+  char *parent_expression = NULL;
 
   if (cname)
     *cname = NULL;
@@ -2324,24 +2394,30 @@ cplus_describe_child (struct varobj *parent, int index,
     *cvalue = NULL;
   if (ctype)
     *ctype = NULL;
-
+  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 (parent->parent);
     }
   else
     {
       value = parent->value;
       type = get_value_type (parent);
+      if (cfull_expression)
+       parent_expression = varobj_get_path_expr (parent);
     }
 
-  adjust_value_for_child_access (&value, &type);
+  adjust_value_for_child_access (&value, &type, &was_ptr);
 
   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
       || TYPE_CODE (type) == TYPE_CODE_STRUCT)
     {
+      char *join = was_ptr ? "->" : ".";
       if (CPLUS_FAKE_CHILD (parent))
        {
          /* The fields of the class type are ordered as they
@@ -2376,6 +2452,11 @@ cplus_describe_child (struct varobj *parent, int index,
 
          if (ctype)
            *ctype = TYPE_FIELD_TYPE (type, type_index);
+
+         if (cfull_expression)
+           *cfull_expression = xstrprintf ("((%s)%s%s)", parent_expression,
+                                           join, 
+                                           TYPE_FIELD_NAME (type, type_index));
        }
       else if (index < TYPE_N_BASECLASSES (type))
        {
@@ -2386,16 +2467,34 @@ cplus_describe_child (struct varobj *parent, int index,
          if (cvalue && value)
            {
              *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
+             release_value (*cvalue);
            }
 
          if (ctype)
            {
              *ctype = TYPE_FIELD_TYPE (type, index);
            }
+
+         if (cfull_expression)
+           {
+             char *ptr = was_ptr ? "*" : "";
+             /* Cast the parent to the base' type. Note that in gdb,
+                expression like 
+                        (Base1)d
+                will create an lvalue, for all appearences, so we don't
+                need to use more fancy:
+                        *(Base1*)(&d)
+                construct.  */
+             *cfull_expression = xstrprintf ("(%s(%s%s) %s)", 
+                                             ptr, 
+                                             TYPE_FIELD_NAME (type, index),
+                                             ptr,
+                                             parent_expression);
+           }
        }
       else
        {
-         char *access = 0;
+         char *access = NULL;
          int children[3];
          cplus_class_num_children (type, children);
 
@@ -2434,16 +2533,17 @@ cplus_describe_child (struct varobj *parent, int index,
              /* error! */
              break;
            }
-         
+
+         gdb_assert (access);
          if (cname)
            *cname = xstrdup (access);
 
-         /* Value and type are null here.  */
+         /* Value and type and full expression are null here.  */
        }
     }
   else
     {
-      c_describe_child (parent, index, cname, cvalue, ctype);
+      c_describe_child (parent, index, cname, cvalue, ctype, cfull_expression);
     }  
 }
 
@@ -2451,10 +2551,18 @@ static char *
 cplus_name_of_child (struct varobj *parent, int index)
 {
   char *name = NULL;
-  cplus_describe_child (parent, index, &name, NULL, NULL);
+  cplus_describe_child (parent, index, &name, NULL, NULL, NULL);
   return name;
 }
 
+static char *
+cplus_path_expr_of_child (struct varobj *child)
+{
+  cplus_describe_child (child->parent, child->index, NULL, NULL, NULL, 
+                       &child->path_expr);
+  return child->path_expr;
+}
+
 static struct value *
 cplus_value_of_root (struct varobj **var_handle)
 {
@@ -2465,7 +2573,7 @@ static struct value *
 cplus_value_of_child (struct varobj *parent, int index)
 {
   struct value *value = NULL;
-  cplus_describe_child (parent, index, NULL, &value, NULL);
+  cplus_describe_child (parent, index, NULL, &value, NULL, NULL);
   return value;
 }
 
@@ -2473,19 +2581,10 @@ static struct type *
 cplus_type_of_child (struct varobj *parent, int index)
 {
   struct type *type = NULL;
-  cplus_describe_child (parent, index, NULL, NULL, &type);
+  cplus_describe_child (parent, index, NULL, NULL, &type, NULL);
   return type;
 }
 
-static int
-cplus_variable_editable (struct varobj *var)
-{
-  if (CPLUS_FAKE_CHILD (var))
-    return 0;
-
-  return c_variable_editable (var);
-}
-
 static char *
 cplus_value_of_variable (struct varobj *var)
 {
@@ -2545,6 +2644,12 @@ java_name_of_child (struct varobj *parent, int index)
   return name;
 }
 
+static char *
+java_path_expr_of_child (struct varobj *child)
+{
+  return NULL;
+}
+
 static struct value *
 java_value_of_root (struct varobj **var_handle)
 {
@@ -2563,12 +2668,6 @@ java_type_of_child (struct varobj *parent, int index)
   return cplus_type_of_child (parent, index);
 }
 
-static int
-java_variable_editable (struct varobj *var)
-{
-  return cplus_variable_editable (var);
-}
-
 static char *
 java_value_of_variable (struct varobj *var)
 {
This page took 0.033421 seconds and 4 git commands to generate.