* mips-tdep.c (mips_gdbarch_init): Use Tag_GNU_MIPS_ABI_FP to
[deliverable/binutils-gdb.git] / gdb / varobj.c
index f97c09090530d459ac720e863d92fa6cb22cb941..fb3d6962296f79dcd9a969c698dd1ab55afb5b1d 100644 (file)
@@ -71,6 +71,10 @@ struct varobj_root
      using the currently selected frame. */
   int use_selected_frame;
 
+  /* Flag that indicates validity: set to 0 when this varobj_root refers 
+     to symbols that do not exist anymore.  */
+  int is_valid;
+
   /* Language info for this variable and its children */
   struct language_specific *lang;
 
@@ -133,6 +137,16 @@ struct varobj
 
   /* Last print value.  */
   char *print_value;
+
+  /* Is this variable frozen.  Frozen variables are never implicitly
+     updated by -var-update * 
+     or -var-update <direct-or-indirect-parent>.  */
+  int frozen;
+
+  /* Is the value of this variable intentionally not fetched?  It is
+     not fetched if either the variable is frozen, or any parents is
+     frozen.  */
+  int not_fetched;
 };
 
 struct cpstack
@@ -178,8 +192,6 @@ static struct type *get_type (struct varobj *var);
 
 static struct type *get_value_type (struct varobj *var);
 
-static struct type *get_type_deref (struct varobj *var);
-
 static struct type *get_target_type (struct type *);
 
 static enum varobj_display_formats variable_default_display (struct varobj *);
@@ -431,14 +443,14 @@ varobj_create (char *objname,
     {
       char *p;
       enum varobj_languages lang;
-      struct value *value;
+      struct value *value = NULL;
 
       /* Parse and evaluate the expression, filling in as much
          of the variable's data as possible */
 
       /* Allow creator to specify context of variable */
       if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME))
-       fi = deprecated_selected_frame;
+       fi = deprecated_safe_get_selected_frame ();
       else
        /* FIXME: cagney/2002-11-23: This code should be doing a
           lookup using the frame ID and not just the frame's
@@ -485,7 +497,7 @@ varobj_create (char *objname,
       if (fi != NULL)
        {
          var->root->frame = get_frame_id (fi);
-         old_fi = deprecated_selected_frame;
+         old_fi = get_selected_frame (NULL);
          select_frame (fi);
        }
 
@@ -493,11 +505,15 @@ varobj_create (char *objname,
          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))
-       /* Error getting the value.  Try to at least get the
-          right type.  */
-       value = evaluate_type (var->root->exp);
+       {
+         /* Error getting the value.  Try to at least get the
+            right type.  */
+         struct value *type_only_value = evaluate_type (var->root->exp);
+         var->type = value_type (type_only_value);
+       }
+      else 
+       var->type = value_type (value);
 
-      var->type = value_type (value);
       install_new_value (var, value, 1 /* Initial assignment */);
 
       /* Set language info */
@@ -663,6 +679,26 @@ varobj_get_display_format (struct varobj *var)
   return var->format;
 }
 
+void
+varobj_set_frozen (struct varobj *var, int frozen)
+{
+  /* When a variable is unfrozen, we don't fetch its value.
+     The 'not_fetched' flag remains set, so next -var-update
+     won't complain.
+
+     We don't fetch the value, because for structures the client
+     should do -var-update anyway.  It would be bad to have different
+     client-size logic for structure and other types.  */
+  var->frozen = frozen;
+}
+
+int
+varobj_get_frozen (struct varobj *var)
+{
+  return var->frozen;
+}
+
+
 int
 varobj_get_num_children (struct varobj *var)
 {
@@ -744,8 +780,9 @@ varobj_get_type (struct varobj *var)
   long length;
 
   /* For the "fake" variables, do not return a type. (It's type is
-     NULL, too.) */
-  if (CPLUS_FAKE_CHILD (var))
+     NULL, too.)
+     Do not return a type for invalid variables as well.  */
+  if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
     return NULL;
 
   stb = mem_fileopen ();
@@ -780,7 +817,7 @@ varobj_get_attributes (struct varobj *var)
 {
   int attributes = 0;
 
-  if (variable_editable (var))
+  if (var->root->is_valid && variable_editable (var))
     /* FIXME: define masks for attributes */
     attributes |= 0x00000001;  /* Editable */
 
@@ -908,6 +945,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   int changeable;
   int need_to_fetch;
   int changed = 0;
+  int intentionally_not_fetched = 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
@@ -943,7 +981,20 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      will be lazy, which means we've lost that old value.  */
   if (need_to_fetch && value && value_lazy (value))
     {
-      if (!gdb_value_fetch_lazy (value))
+      struct varobj *parent = var->parent;
+      int frozen = var->frozen;
+      for (; !frozen && parent; parent = parent->parent)
+       frozen |= parent->frozen;
+
+      if (frozen && initial)
+       {
+         /* For variables that are frozen, or are children of frozen
+            variables, we don't do fetch on initial assignment.
+            For non-initial assignemnt we do the fetch, since it means we're
+            explicitly asked to compare the new value with the old one.  */
+         intentionally_not_fetched = 1;
+       }
+      else if (!gdb_value_fetch_lazy (value))
        {
          /* Set the value to NULL, so that for the next -var-update,
             we don't try to compare the new value with this value,
@@ -955,7 +1006,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   /* 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)
     {
@@ -973,9 +1024,16 @@ install_new_value (struct varobj *var, struct value *value, int initial)
        {
          /* Try to compare the values.  That requires that both
             values are non-lazy.  */
-         
-         /* Quick comparison of NULL values.  */
-         if (var->value == NULL && value == NULL)
+         if (var->not_fetched && value_lazy (var->value))
+           {
+             /* This is a frozen varobj and the value was never read.
+                Presumably, UI shows some "never read" indicator.
+                Now that we've fetched the real value, we need to report
+                this varobj as changed so that UI can show the real
+                value.  */
+             changed = 1;
+           }
+          else  if (var->value == NULL && value == NULL)
            /* Equal. */
            ;
          else if (var->value == NULL || value == NULL)
@@ -1005,9 +1063,13 @@ install_new_value (struct varobj *var, struct value *value, int initial)
     }
 
   /* We must always keep the new value, since children depend on it.  */
-  if (var->value != NULL)
+  if (var->value != NULL && var->value != value)
     value_free (var->value);
   var->value = value;
+  if (value && value_lazy (value) && intentionally_not_fetched)
+    var->not_fetched = 1;
+  else
+    var->not_fetched = 0;
   var->updated = 0;
 
   gdb_assert (!var->value || value_type (var->value));
@@ -1020,23 +1082,25 @@ install_new_value (struct varobj *var, struct value *value, int initial)
    expression to see if it's changed.  Then go all the way
    through its children, reconstructing them and noting if they've
    changed.
-   Return value:
-    -1 if there was an error updating the varobj
-    -2 if the type changed
-    Otherwise it is the number of children + parent changed
+   Return value: 
+    < 0 for error values, see varobj.h.
+    Otherwise it is the number of children + parent changed.
 
-   Only root variables can be updated... 
+   The EXPLICIT parameter specifies if this call is result
+   of MI request to update this specific variable, or 
+   result of implicit -var-update *. For implicit request, we don't
+   update frozen variables.
 
    NOTE: This function may delete the caller's varobj. If it
-   returns -2, then it has done this and VARP will be modified
-   to point to the new varobj. */
+   returns TYPE_CHANGED, then it has done this and VARP will be modified
+   to point to the new varobj.  */
 
 int
-varobj_update (struct varobj **varp, struct varobj ***changelist)
+varobj_update (struct varobj **varp, struct varobj ***changelist,
+              int explicit)
 {
   int changed = 0;
-  int error = 0;
-  int type_changed;
+  int type_changed = 0;
   int i;
   int vleft;
   struct varobj *v;
@@ -1048,56 +1112,64 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
   struct frame_id old_fid;
   struct frame_info *fi;
 
-  /* sanity check: have we been passed a pointer? */
-  if (changelist == NULL)
-    return -1;
+  /* sanity check: have we been passed a pointer?  */
+  gdb_assert (changelist);
 
-  /*  Only root variables can be updated... */
-  if (!is_root_p (*varp))
-    /* Not a root var */
-    return -1;
+  /* Frozen means frozen -- we don't check for any change in
+     this varobj, including its going out of scope, or
+     changing type.  One use case for frozen varobjs is
+     retaining previously evaluated expressions, and we don't
+     want them to be reevaluated at all.  */
+  if (!explicit && (*varp)->frozen)
+    return 0;
 
-  /* Save the selected stack frame, since we will need to change it
-     in order to evaluate expressions. */
-  old_fid = get_frame_id (deprecated_selected_frame);
-
-  /* Update the root variable. value_of_root can return NULL
-     if the variable is no longer around, i.e. we stepped out of
-     the frame in which a local existed. We are letting the 
-     value_of_root variable dispose of the varobj if the type
-     has changed. */
-  type_changed = 1;
-  new = value_of_root (varp, &type_changed);
-
-  /* Restore selected frame */
-  fi = frame_find_by_id (old_fid);
-  if (fi)
-    select_frame (fi);
-
-  /* If this is a "use_selected_frame" varobj, and its type has changed,
-     them note that it's changed. */
-  if (type_changed)
-    VEC_safe_push (varobj_p, result, *varp);
+  if (!(*varp)->root->is_valid)
+    return INVALID;
 
-  if (install_new_value ((*varp), new, type_changed))
+  if ((*varp)->root->rootvar == *varp)
     {
-      /* If type_changed is 1, install_new_value will never return
-        non-zero, so we'll never report the same variable twice.  */
-      gdb_assert (!type_changed);
-      VEC_safe_push (varobj_p, result, *varp);
-    }
+      /* Save the selected stack frame, since we will need to change it
+        in order to evaluate expressions.  */
+      old_fid = get_frame_id (deprecated_safe_get_selected_frame ());
+      
+      /* Update the root variable. value_of_root can return NULL
+        if the variable is no longer around, i.e. we stepped out of
+        the frame in which a local existed. We are letting the 
+        value_of_root variable dispose of the varobj if the type
+        has changed.  */
+      type_changed = 1;
+      new = value_of_root (varp, &type_changed);
+
+      /* Restore selected frame.  */
+      fi = frame_find_by_id (old_fid);
+      if (fi)
+       select_frame (fi);
+      
+      /* If this is a "use_selected_frame" varobj, and its type has changed,
+        them note that it's changed.  */
+      if (type_changed)
+       VEC_safe_push (varobj_p, result, *varp);
+      
+        if (install_new_value ((*varp), new, type_changed))
+         {
+           /* If type_changed is 1, install_new_value will never return
+              non-zero, so we'll never report the same variable twice.  */
+           gdb_assert (!type_changed);
+           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;
+      if (new == NULL)
+       {
+         /* This means the varobj itself is out of scope.
+            Report it.  */
+         VEC_free (varobj_p, result);
+         return NOT_IN_SCOPE;
+       }
     }
 
   VEC_safe_push (varobj_p, stack, *varp);
 
-  /* Walk through the children, reconstructing them all. */
+  /* Walk through the children, reconstructing them all.  */
   while (!VEC_empty (varobj_p, stack))
     {
       v = VEC_pop (varobj_p, stack);
@@ -1110,13 +1182,13 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
        {
          varobj_p c = VEC_index (varobj_p, v->children, i);
          /* Child may be NULL if explicitly deleted by -var-delete.  */
-         if (c != NULL)
+         if (c != NULL && !c->frozen)
            VEC_safe_push (varobj_p, stack, c);
        }
 
       /* Update this variable, unless it's a root, which is already
         updated.  */
-      if (v != *varp)
+      if (v->root->rootvar != v)
        {         
          new = value_of_child (v->parent, v->index);
          if (install_new_value (v, new, 0 /* type not changed */))
@@ -1128,7 +1200,7 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
        }
     }
 
-  /* Alloc (changed + 1) list entries */
+  /* Alloc (changed + 1) list entries */
   changed = VEC_length (varobj_p, result);
   *changelist = xmalloc ((changed + 1) * sizeof (struct varobj *));
   cv = *changelist;
@@ -1141,8 +1213,11 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
     }
   *cv = 0;
 
+  VEC_free (varobj_p, stack);
+  VEC_free (varobj_p, result);
+
   if (type_changed)
-    return -2;
+    return TYPE_CHANGED;
   else
     return changed;
 }
@@ -1395,6 +1470,8 @@ new_variable (void)
   var->root = NULL;
   var->updated = 0;
   var->print_value = NULL;
+  var->frozen = 0;
+  var->not_fetched = 0;
 
   return var;
 }
@@ -1411,6 +1488,7 @@ new_root_variable (void)
   var->root->frame = null_frame_id;
   var->root->use_selected_frame = 0;
   var->root->rootvar = NULL;
+  var->root->is_valid = 1;
 
   return var;
 }
@@ -1492,26 +1570,6 @@ get_value_type (struct varobj *var)
   return type;
 }
 
-/* This returns the type of the variable, dereferencing references, pointers
-   and references to pointers, too. */
-static struct type *
-get_type_deref (struct varobj *var)
-{
-  struct type *type;
-
-  type = get_type (var);
-
-  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);
-    }
-
-  return type;
-}
-
 /* This returns the target type (or NULL) of TYPE, also skipping
    past typedefs, just like get_type ().
 
@@ -1652,13 +1710,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)
        {
@@ -1682,6 +1741,8 @@ value_of_root (struct varobj **var_handle, int *type_changed)
          var = *var_handle;
          *type_changed = 1;
        }
+      xfree (old_type);
+      xfree (new_type);
     }
   else
     {
@@ -1714,7 +1775,10 @@ variable_editable (struct varobj *var)
 static char *
 my_value_of_variable (struct varobj *var)
 {
-  return (*var->root->lang->value_of_variable) (var);
+  if (var->root->is_valid)
+    return (*var->root->lang->value_of_variable) (var);
+  else
+    return NULL;
 }
 
 static char *
@@ -1773,17 +1837,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))
     {
@@ -1803,30 +1911,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:
@@ -1892,7 +1989,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;
@@ -1901,19 +1998,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))
     {
@@ -1961,8 +2046,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;
 
@@ -2018,13 +2106,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))
-       {
-         release_value (new_val);
-       }
-
+         expression fails we want to just return NULL.  */
+      gdb_evaluate_expression (var->root->exp, &new_val);
       return new_val;
     }
 
@@ -2036,8 +2119,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;
 }
@@ -2107,6 +2188,12 @@ c_value_of_variable (struct varobj *var)
          }
        else
          {
+           if (var->not_fetched && value_lazy (var->value))
+             /* Frozen variable and no value yet.  We don't
+                implicitly fetch the value.  MI response will
+                use empty string for the value, which is OK.  */
+             return NULL;
+
            gdb_assert (varobj_value_is_changeable_p (var));
            gdb_assert (!value_lazy (var->value));
            return value_get_print_value (var->value, var->format);
@@ -2129,7 +2216,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))
@@ -2155,7 +2243,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)
@@ -2206,25 +2295,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 = NULL;
+  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
@@ -2234,56 +2354,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 = NULL;
          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"
@@ -2295,46 +2412,50 @@ 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;
 
-    default:
-      break;
-    }
+         gdb_assert (access);
+         if (cname)
+           *cname = xstrdup (access);
 
-  if (name == NULL)
-    return c_name_of_child (parent, index);
+         /* Value and type are null here.  */
+       }
+    }
   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;
 }
 
@@ -2347,118 +2468,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;
 }
 
@@ -2578,3 +2597,44 @@ When non-zero, varobj debugging is enabled."),
                            show_varobjdebug,
                            &setlist, &showlist);
 }
+
+/* Invalidate the varobjs that are tied to locals and re-create the ones that
+   are defined on globals.
+   Invalidated varobjs will be always printed in_scope="invalid".  */
+void 
+varobj_invalidate (void)
+{
+  struct varobj **all_rootvarobj;
+  struct varobj **varp;
+
+  if (varobj_list (&all_rootvarobj) > 0)
+  {
+    varp = all_rootvarobj;
+    while (*varp != NULL)
+      {
+        /* global var must be re-evaluated.  */     
+        if ((*varp)->root->valid_block == NULL)
+        {
+          struct varobj *tmp_var;
+
+          /* Try to create a varobj with same expression.  If we succeed replace
+             the old varobj, otherwise invalidate it.  */
+          tmp_var = varobj_create (NULL, (*varp)->name, (CORE_ADDR) 0, USE_CURRENT_FRAME);
+          if (tmp_var != NULL) 
+            { 
+             tmp_var->obj_name = xstrdup ((*varp)->obj_name);
+              varobj_delete (*varp, NULL, 0);
+              install_variable (tmp_var);
+            }
+          else
+              (*varp)->root->is_valid = 0;
+        }
+        else /* locals must be invalidated.  */
+          (*varp)->root->is_valid = 0;
+
+        varp++;
+      }
+    xfree (all_rootvarobj);
+  }
+  return;
+}
This page took 0.036179 seconds and 4 git commands to generate.