* emultempl/mmixelf.em: Remove incorrect '#line' directive.
[deliverable/binutils-gdb.git] / gdb / varobj.c
index ccca0511a2ca7880174913e4bed390ce28d058a7..7b2bfb838d2f6bf9a4e4a04cb0607e58caff40a9 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;
 
@@ -436,7 +440,7 @@ varobj_create (char *objname,
 
       /* 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 +487,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);
        }
 
@@ -742,8 +746,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 +783,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 */
 
@@ -953,7 +958,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)
     {
@@ -1018,22 +1023,20 @@ 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... 
 
    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)
 {
   int changed = 0;
-  int error = 0;
   int type_changed;
   int i;
   int vleft;
@@ -1046,34 +1049,34 @@ 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;
+    error (_("Only root variables can be updated"));
+
+  if (!(*varp)->root->is_valid)
+    return INVALID;
 
   /* 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);
+     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. */
+     has changed.  */
   type_changed = 1;
   new = value_of_root (varp, &type_changed);
 
-  /* Restore selected frame */
+  /* 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. */
+     them note that it's changed.  */
   if (type_changed)
     VEC_safe_push (varobj_p, result, *varp);
 
@@ -1090,12 +1093,12 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
       /* This means the varobj itself is out of scope.
         Report it.  */
       VEC_free (varobj_p, result);
-      return -1;
+      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);
@@ -1126,7 +1129,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 +1142,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;
 }
@@ -1409,6 +1415,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 +1699,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 *
@@ -2020,13 +2030,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;
     }
 
@@ -2038,8 +2043,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;
 }
@@ -2304,7 +2307,6 @@ 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)
@@ -2512,3 +2514,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.027086 seconds and 4 git commands to generate.