*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / varobj.c
index be0f2bcdf2680116a22a8d92a6aa780add5423ef..c19bd20c13fb0d71705f1b011b39b9173d29057c 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
@@ -429,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
@@ -483,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);
        }
 
@@ -491,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 */
@@ -661,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)
 {
@@ -742,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 ();
@@ -778,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 */
 
@@ -906,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
@@ -941,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,
@@ -971,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)
@@ -1003,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));
@@ -1018,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;
@@ -1046,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);
@@ -1108,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 */))
@@ -1126,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;
@@ -1139,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;
 }
@@ -1393,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;
 }
@@ -1409,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;
 }
@@ -1692,7 +1772,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 *
@@ -2102,6 +2185,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);
@@ -2504,3 +2593,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.028229 seconds and 4 git commands to generate.