* varobj.c (install_new_value): Only call value_get_print_value
[deliverable/binutils-gdb.git] / gdb / varobj.c
index 27c27610eb754b8fe114468db89e7be57ae12132..be0f2bcdf2680116a22a8d92a6aa780add5423ef 100644 (file)
@@ -107,14 +107,12 @@ struct varobj
   /* The type of this variable. This may NEVER be NULL. */
   struct type *type;
 
-  /* The value of this expression or subexpression.  This may be NULL. 
+  /* The value of this expression or subexpression.  A NULL value
+     indicates there was an error getting this value.
      Invariant: if varobj_value_is_changeable_p (this) is non-zero, 
      the value is either NULL, or not lazy.  */
   struct value *value;
 
-  /* Did an error occur evaluating the expression or getting its value? */
-  int error;
-
   /* The number of (immediate) children this variable has */
   int num_children;
 
@@ -178,7 +176,7 @@ static struct cleanup *make_cleanup_free_variable (struct varobj *var);
 
 static struct type *get_type (struct varobj *var);
 
-static struct type *get_type_deref (struct varobj *var);
+static struct type *get_value_type (struct varobj *var);
 
 static struct type *get_target_type (struct type *);
 
@@ -811,7 +809,7 @@ varobj_set_value (struct varobj *var, char *expression)
   struct value *value;
   int saved_input_radix = input_radix;
 
-  if (var->value != NULL && variable_editable (var) && !var->error)
+  if (var->value != NULL && variable_editable (var))
     {
       char *s = expression;
       int i;
@@ -909,7 +907,6 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   int need_to_fetch;
   int changed = 0;
 
-  var->error = 0;
   /* We need to know the varobj's type to decide if the value should
      be fetched or not.  C++ fake children (public/protected/private) don't have
      a type. */
@@ -946,20 +943,17 @@ install_new_value (struct varobj *var, struct value *value, int initial)
     {
       if (!gdb_value_fetch_lazy (value))
        {
-         var->error = 1;
          /* Set the value to NULL, so that for the next -var-update,
             we don't try to compare the new value with this value,
             that we couldn't even read.  */
          value = NULL;
        }
-      else
-       var->error = 0;
     }
 
   /* 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)
+  if (initial && changeable)
     var->print_value = value_get_print_value (value, var->format);
   else if (changeable)
     {
@@ -1078,12 +1072,6 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
   if (fi)
     select_frame (fi);
 
-  if (new == NULL)
-    {
-      (*varp)->error = 1;
-      return -1;
-    }
-
   /* If this is a "use_selected_frame" varobj, and its type has changed,
      them note that it's changed. */
   if (type_changed)
@@ -1097,6 +1085,14 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
       VEC_safe_push (varobj_p, result, *varp);
     }
 
+  if (new == NULL)
+    {
+      /* This means the varobj itself is out of scope.
+        Report it.  */
+      VEC_free (varobj_p, result);
+      return -1;
+    }
+
   VEC_safe_push (varobj_p, stack, *varp);
 
   /* Walk through the children, reconstructing them all. */
@@ -1370,9 +1366,6 @@ create_child (struct varobj *parent, int index, char *name)
                                                       child->index);
   install_new_value (child, value, 1);
 
-  if ((!CPLUS_FAKE_CHILD (child) && child->value == NULL) || parent->error)
-    child->error = 1;
-
   return child;
 }
 \f
@@ -1393,7 +1386,6 @@ new_variable (void)
   var->index = -1;
   var->type = NULL;
   var->value = NULL;
-  var->error = 0;
   var->num_children = -1;
   var->parent = NULL;
   var->children = NULL;
@@ -1467,22 +1459,33 @@ get_type (struct varobj *var)
   return type;
 }
 
-/* This returns the type of the variable, dereferencing references, pointers
-   and references to pointers, too. */
+/* Return the type of the value that's stored in VAR,
+   or that would have being stored there if the
+   value were accessible.  
+
+   This differs from VAR->type in that VAR->type is always
+   the true type of the expession in the source language.
+   The return value of this function is the type we're
+   actually storing in varobj, and using for displaying
+   the values and for comparing previous and new values.
+
+   For example, top-level references are always stripped.  */
 static struct type *
-get_type_deref (struct varobj *var)
+get_value_type (struct varobj *var)
 {
   struct type *type;
 
-  type = get_type (var);
+  if (var->value)
+    type = value_type (var->value);
+  else
+    type = var->type;
 
-  if (type)
-    {
-      if (TYPE_CODE (type) == TYPE_CODE_REF)
-       type = get_target_type (type);
-      if (TYPE_CODE (type) == TYPE_CODE_PTR)
-       type = get_target_type (type);
-    }
+  type = check_typedef (type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_REF)
+    type = get_target_type (type);
+
+  type = check_typedef (type);
 
   return type;
 }
@@ -1731,7 +1734,7 @@ varobj_value_is_changeable_p (struct varobj *var)
   if (CPLUS_FAKE_CHILD (var))
     return 0;
 
-  type = get_type (var);
+  type = get_value_type (var);
 
   switch (TYPE_CODE (type))
     {
@@ -1748,17 +1751,61 @@ varobj_value_is_changeable_p (struct varobj *var)
   return r;
 }
 
+/* Given the value and the type of a variable object,
+   adjust the value and type to those necessary
+   for getting children of the variable object.
+   This includes dereferencing top-level references
+   to all types and dereferencing pointers to
+   structures.  
+
+   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.  */
+static void
+adjust_value_for_child_access (struct value **value,
+                                 struct type **type)
+{
+  gdb_assert (type && *type);
+
+  *type = check_typedef (*type);
+  
+  /* The type of value stored in varobj, that is passed
+     to us, is already supposed to be
+     reference-stripped.  */
+
+  gdb_assert (TYPE_CODE (*type) != TYPE_CODE_REF);
+
+  /* Pointers to structures are treated just like
+     structures when accessing children.  Don't
+     dererences pointers to other types.  */
+  if (TYPE_CODE (*type) == TYPE_CODE_PTR)
+    {
+      struct type *target_type = get_target_type (*type);
+      if (TYPE_CODE (target_type) == TYPE_CODE_STRUCT
+         || TYPE_CODE (target_type) == TYPE_CODE_UNION)
+       {
+         if (value && *value)
+           gdb_value_ind (*value, value);        
+         *type = target_type;
+       }
+    }
+
+  /* The 'get_target_type' function calls check_typedef on
+     result, so we can immediately check type code.  No
+     need to call check_typedef here.  */
+}
+
 /* C */
 static int
 c_number_of_children (struct varobj *var)
 {
-  struct type *type;
+  struct type *type = get_value_type (var);
+  int children = 0;
   struct type *target;
-  int children;
 
-  type = get_type (var);
+  adjust_value_for_child_access (NULL, &type);
   target = get_target_type (type);
-  children = 0;
 
   switch (TYPE_CODE (type))
     {
@@ -1778,30 +1825,19 @@ c_number_of_children (struct varobj *var)
       break;
 
     case TYPE_CODE_PTR:
-      /* This is where things get complicated. All pointers have one child.
-         Except, of course, for struct and union ptr, which we automagically
-         dereference for the user, and function ptrs which have no children.
-         We also don't dereference void* as we don't know what to show.
+      /* The type here is a pointer to non-struct. Typically, pointers
+        have one child, except for function ptrs, which have no children,
+        and except for void*, as we don't know what to show.
+
          We can show char* so we allow it to be dereferenced.  If you decide
          to test for it, please mind that a little magic is necessary to
          properly identify it: char* has TYPE_CODE == TYPE_CODE_INT and 
          TYPE_NAME == "char" */
-
-      switch (TYPE_CODE (target))
-       {
-       case TYPE_CODE_STRUCT:
-       case TYPE_CODE_UNION:
-         children = TYPE_NFIELDS (target);
-         break;
-
-       case TYPE_CODE_FUNC:
-       case TYPE_CODE_VOID:
-         children = 0;
-         break;
-
-       default:
-         children = 1;
-       }
+      if (TYPE_CODE (target) == TYPE_CODE_FUNC
+         || TYPE_CODE (target) == TYPE_CODE_VOID)
+       children = 0;
+      else
+       children = 1;
       break;
 
     default:
@@ -1867,7 +1903,7 @@ c_describe_child (struct varobj *parent, int index,
                  char **cname, struct value **cvalue, struct type **ctype)
 {
   struct value *value = parent->value;
-  struct type *type = get_type (parent);
+  struct type *type = get_value_type (parent);
 
   if (cname)
     *cname = NULL;
@@ -1876,19 +1912,7 @@ c_describe_child (struct varobj *parent, int index,
   if (ctype)
     *ctype = NULL;
 
-  /* Pointers to structures are treated just like
-     structures when accessing children.  */
-  if (TYPE_CODE (type) == TYPE_CODE_PTR)
-    {
-      struct type *target_type = get_target_type (type);
-      if (TYPE_CODE (target_type) == TYPE_CODE_STRUCT
-         || TYPE_CODE (target_type) == TYPE_CODE_UNION)
-       {
-         if (value)
-           gdb_value_ind (value, &value);        
-         type = target_type;
-       }
-    }
+  adjust_value_for_child_access (&value, &type);
       
   switch (TYPE_CODE (type))
     {
@@ -1936,8 +1960,11 @@ c_describe_child (struct varobj *parent, int index,
       if (cvalue && value)
        gdb_value_ind (value, cvalue);
 
+      /* Don't use get_target_type because it calls
+        check_typedef and here, we want to show the true
+        declared type of the variable.  */
       if (ctype)
-       *ctype = get_target_type (type);
+       *ctype = TYPE_TARGET_TYPE (type);
       
       break;
 
@@ -1972,11 +1999,10 @@ c_value_of_root (struct varobj **var_handle)
 
 
   /* Determine whether the variable is still around. */
-  if (var->root->valid_block == NULL)
+  if (var->root->valid_block == NULL || var->root->use_selected_frame)
     within_scope = 1;
   else
     {
-      reinit_frame_cache ();
       fi = frame_find_by_id (var->root->frame);
       within_scope = fi != NULL;
       /* FIXME: select_frame could fail */
@@ -1994,16 +2020,8 @@ c_value_of_root (struct varobj **var_handle)
   if (within_scope)
     {
       /* We need to catch errors here, because if evaluate
-         expression fails we just want to make val->error = 1 and
-         go on */
-      if (gdb_evaluate_expression (var->root->exp, &new_val))
-       {
-         var->error = 0;
-         release_value (new_val);
-       }
-      else
-       var->error = 1;
-
+         expression fails we want to just return NULL.  */
+      gdb_evaluate_expression (var->root->exp, &new_val);
       return new_val;
     }
 
@@ -2015,8 +2033,6 @@ c_value_of_child (struct varobj *parent, int index)
 {
   struct value *value = NULL;
   c_describe_child (parent, index, NULL, &value, NULL);
-  if (value != NULL)
-    release_value (value);
 
   return value;
 }
@@ -2032,7 +2048,7 @@ c_type_of_child (struct varobj *parent, int index)
 static int
 c_variable_editable (struct varobj *var)
 {
-  switch (TYPE_CODE (get_type (var)))
+  switch (TYPE_CODE (get_value_type (var)))
     {
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
@@ -2108,7 +2124,8 @@ cplus_number_of_children (struct varobj *var)
 
   if (!CPLUS_FAKE_CHILD (var))
     {
-      type = get_type_deref (var);
+      type = get_value_type (var);
+      adjust_value_for_child_access (NULL, &type);
 
       if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
          ((TYPE_CODE (type)) == TYPE_CODE_UNION))
@@ -2134,7 +2151,8 @@ cplus_number_of_children (struct varobj *var)
     {
       int kids[3];
 
-      type = get_type_deref (var->parent);
+      type = get_value_type (var->parent);
+      adjust_value_for_child_access (NULL, &type);
 
       cplus_class_num_children (type, kids);
       if (strcmp (var->name, "public") == 0)
@@ -2185,25 +2203,56 @@ cplus_name_of_variable (struct varobj *parent)
   return c_name_of_variable (parent);
 }
 
-static char *
-cplus_name_of_child (struct varobj *parent, int index)
+enum accessibility { private_field, protected_field, public_field };
+
+/* Check if field INDEX of TYPE has the specified accessibility.
+   Return 0 if so and 1 otherwise.  */
+static int 
+match_accessibility (struct type *type, int index, enum accessibility acc)
 {
-  char *name;
+  if (acc == private_field && TYPE_FIELD_PRIVATE (type, index))
+    return 1;
+  else if (acc == protected_field && TYPE_FIELD_PROTECTED (type, index))
+    return 1;
+  else if (acc == public_field && !TYPE_FIELD_PRIVATE (type, index)
+          && !TYPE_FIELD_PROTECTED (type, index))
+    return 1;
+  else
+    return 0;
+}
+
+static void
+cplus_describe_child (struct varobj *parent, int index,
+                     char **cname, struct value **cvalue, struct type **ctype)
+{
+  char *name = 0;
+  struct value *value;
   struct type *type;
 
+  if (cname)
+    *cname = NULL;
+  if (cvalue)
+    *cvalue = NULL;
+  if (ctype)
+    *ctype = NULL;
+
+
   if (CPLUS_FAKE_CHILD (parent))
     {
-      /* Looking for children of public, private, or protected. */
-      type = get_type_deref (parent->parent);
+      value = parent->parent->value;
+      type = get_value_type (parent->parent);
     }
   else
-    type = get_type_deref (parent);
+    {
+      value = parent->value;
+      type = get_value_type (parent);
+    }
 
-  name = NULL;
-  switch (TYPE_CODE (type))
+  adjust_value_for_child_access (&value, &type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+      || TYPE_CODE (type) == TYPE_CODE_STRUCT)
     {
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
       if (CPLUS_FAKE_CHILD (parent))
        {
          /* The fields of the class type are ordered as they
@@ -2213,56 +2262,53 @@ cplus_name_of_child (struct varobj *parent, int index)
             have the access control we are looking for to properly
             find the indexed field. */
          int type_index = TYPE_N_BASECLASSES (type);
+         enum accessibility acc = public_field;
          if (strcmp (parent->name, "private") == 0)
-           {
-             while (index >= 0)
-               {
-                 if (TYPE_VPTR_BASETYPE (type) == type
-                     && type_index == TYPE_VPTR_FIELDNO (type))
-                   ; /* ignore vptr */
-                 else if (TYPE_FIELD_PRIVATE (type, type_index))
-                   --index;
-                 ++type_index;
-               }
-             --type_index;
-           }
+           acc = private_field;
          else if (strcmp (parent->name, "protected") == 0)
+           acc = protected_field;
+
+         while (index >= 0)
            {
-             while (index >= 0)
-               {
-                 if (TYPE_VPTR_BASETYPE (type) == type
-                     && type_index == TYPE_VPTR_FIELDNO (type))
-                   ; /* ignore vptr */
-                 else if (TYPE_FIELD_PROTECTED (type, type_index))
+             if (TYPE_VPTR_BASETYPE (type) == type
+                 && type_index == TYPE_VPTR_FIELDNO (type))
+               ; /* ignore vptr */
+             else if (match_accessibility (type, type_index, acc))
                    --index;
                  ++type_index;
-               }
-             --type_index;
            }
-         else
+         --type_index;
+
+         if (cname)
+           *cname = xstrdup (TYPE_FIELD_NAME (type, type_index));
+
+         if (cvalue && value)
+           *cvalue = value_struct_element_index (value, type_index);
+
+         if (ctype)
+           *ctype = TYPE_FIELD_TYPE (type, type_index);
+       }
+      else if (index < TYPE_N_BASECLASSES (type))
+       {
+         /* This is a baseclass.  */
+         if (cname)
+           *cname = xstrdup (TYPE_FIELD_NAME (type, index));
+
+         if (cvalue && value)
            {
-             while (index >= 0)
-               {
-                 if (TYPE_VPTR_BASETYPE (type) == type
-                     && type_index == TYPE_VPTR_FIELDNO (type))
-                   ; /* ignore vptr */
-                 else if (!TYPE_FIELD_PRIVATE (type, type_index) &&
-                     !TYPE_FIELD_PROTECTED (type, type_index))
-                   --index;
-                 ++type_index;
-               }
-             --type_index;
+             *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
            }
 
-         name = TYPE_FIELD_NAME (type, type_index);
+         if (ctype)
+           {
+             *ctype = TYPE_FIELD_TYPE (type, index);
+           }
        }
-      else if (index < TYPE_N_BASECLASSES (type))
-       /* We are looking up the name of a base class */
-       name = TYPE_FIELD_NAME (type, index);
       else
        {
+         char *access = 0;
          int children[3];
-         cplus_class_num_children(type, children);
+         cplus_class_num_children (type, children);
 
          /* Everything beyond the baseclasses can
             only be "public", "private", or "protected"
@@ -2274,46 +2320,49 @@ cplus_name_of_child (struct varobj *parent, int index)
            {
            case 0:
              if (children[v_public] > 0)
-               name = "public";
+               access = "public";
              else if (children[v_private] > 0)
-               name = "private";
+               access = "private";
              else 
-               name = "protected";
+               access = "protected";
              break;
            case 1:
              if (children[v_public] > 0)
                {
                  if (children[v_private] > 0)
-                   name = "private";
+                   access = "private";
                  else
-                   name = "protected";
+                   access = "protected";
                }
              else if (children[v_private] > 0)
-               name = "protected";
+               access = "protected";
              break;
            case 2:
              /* Must be protected */
-             name = "protected";
+             access = "protected";
              break;
            default:
              /* error! */
              break;
            }
-       }
-      break;
+         
+         if (cname)
+           *cname = xstrdup (access);
 
-    default:
-      break;
+         /* Value and type are null here.  */
+       }
     }
-
-  if (name == NULL)
-    return c_name_of_child (parent, index);
   else
     {
-      if (name != NULL)
-       name = savestring (name, strlen (name));
-    }
+      c_describe_child (parent, index, cname, cvalue, ctype);
+    }  
+}
 
+static char *
+cplus_name_of_child (struct varobj *parent, int index)
+{
+  char *name = NULL;
+  cplus_describe_child (parent, index, &name, NULL, NULL);
   return name;
 }
 
@@ -2326,118 +2375,16 @@ cplus_value_of_root (struct varobj **var_handle)
 static struct value *
 cplus_value_of_child (struct varobj *parent, int index)
 {
-  struct type *type;
-  struct value *value;
-
-  if (CPLUS_FAKE_CHILD (parent))
-    type = get_type_deref (parent->parent);
-  else
-    type = get_type_deref (parent);
-
-  value = NULL;
-
-  if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) ||
-      ((TYPE_CODE (type)) == TYPE_CODE_UNION))
-    {
-      if (CPLUS_FAKE_CHILD (parent))
-       {
-         char *name;
-         struct value *temp = parent->parent->value;
-
-         if (temp == NULL)
-           return NULL;
-
-         name = name_of_child (parent, index);
-         gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL,
-                               "cplus_structure");
-         if (value != NULL)
-           release_value (value);
-
-         xfree (name);
-       }
-      else if (index >= TYPE_N_BASECLASSES (type))
-       {
-         /* public, private, or protected */
-         return NULL;
-       }
-      else
-       {
-         /* Baseclass */
-         if (parent->value != NULL)
-           {
-             struct value *temp = NULL;
-
-             /* No special processing for references is needed --
-                value_cast below handles references.  */
-             if (TYPE_CODE (value_type (parent->value)) == TYPE_CODE_PTR)
-               {
-                 if (!gdb_value_ind (parent->value, &temp))
-                   return NULL;
-               }
-             else
-               temp = parent->value;
-
-             if (temp != NULL)
-               {
-                 value = value_cast (TYPE_FIELD_TYPE (type, index), temp);
-                 release_value (value);
-               }
-             else
-               {
-                 /* We failed to evaluate the parent's value, so don't even
-                    bother trying to evaluate this child. */
-                 return NULL;
-               }
-           }
-       }
-    }
-
-  if (value == NULL)
-    return c_value_of_child (parent, index);
-
+  struct value *value = NULL;
+  cplus_describe_child (parent, index, NULL, &value, NULL);
   return value;
 }
 
 static struct type *
 cplus_type_of_child (struct varobj *parent, int index)
 {
-  struct type *type, *t;
-
-  if (CPLUS_FAKE_CHILD (parent))
-    {
-      /* Looking for the type of a child of public, private, or protected. */
-      t = get_type_deref (parent->parent);
-    }
-  else
-    t = get_type_deref (parent);
-
-  type = NULL;
-  switch (TYPE_CODE (t))
-    {
-    case TYPE_CODE_STRUCT:
-    case TYPE_CODE_UNION:
-      if (CPLUS_FAKE_CHILD (parent))
-       {
-         char *name = cplus_name_of_child (parent, index);
-         type = lookup_struct_elt_type (t, name, 0);
-         xfree (name);
-       }
-      else if (index < TYPE_N_BASECLASSES (t))
-       type = TYPE_FIELD_TYPE (t, index);
-      else
-       {
-         /* special */
-         return NULL;
-       }
-      break;
-
-    default:
-      break;
-    }
-
-  if (type == NULL)
-    return c_type_of_child (parent, index);
-
+  struct type *type = NULL;
+  cplus_describe_child (parent, index, NULL, NULL, &type);
   return type;
 }
 
This page took 0.033829 seconds and 4 git commands to generate.