2007-02-13 Denis Pilat <denis.pilat@st.com>

* varobj.h (enum varobj_update_error): New enum.
	* varobj.c (struct varobj_root): Add is_valid member.
	(varobj_get_type): Check for invalid varobj.
	(varobj_get_attributes): Likewise.
	(variable_editable):Likewise.
	(varobj_update): Likewise.  Use varobj_update_error.
	(new_root_variable): Set root varobj as valid by default.
	(varobj_invalidate): New function.
	* symfile.c (clear_symtab_users): Use varobj_invalidate.
	* mi/mi-cmd-var.c (varobj_update_one): Change return type to void.
	Use varobj_update_error.
This commit is contained in:
Denis Pilat 2007-02-13 08:15:49 +00:00
parent b1e374737b
commit 8756216bc7
5 changed files with 132 additions and 52 deletions

View file

@ -1,3 +1,17 @@
2007-02-13 Denis Pilat <denis.pilat@st.com>
* varobj.h (enum varobj_update_error): New enum.
* varobj.c (struct varobj_root): Add is_valid member.
(varobj_get_type): Check for invalid varobj.
(varobj_get_attributes): Likewise.
(variable_editable):Likewise.
(varobj_update): Likewise. Use varobj_update_error.
(new_root_variable): Set root varobj as valid by default.
(varobj_invalidate): New function.
* symfile.c (clear_symtab_users): Use varobj_invalidate.
* mi/mi-cmd-var.c (varobj_update_one): Change return type to void.
Use varobj_update_error.
2007-02-12 Pierre Muller <muller@ics.u-strasbg.fr> 2007-02-12 Pierre Muller <muller@ics.u-strasbg.fr>
Fix PR pascal/2223. Fix PR pascal/2223.

View file

@ -34,9 +34,9 @@ const char mi_no_values[] = "--no-values";
const char mi_simple_values[] = "--simple-values"; const char mi_simple_values[] = "--simple-values";
const char mi_all_values[] = "--all-values"; const char mi_all_values[] = "--all-values";
extern int varobjdebug; /* defined in varobj.c */ extern int varobjdebug; /* defined in varobj.c. */
static int varobj_update_one (struct varobj *var, static void varobj_update_one (struct varobj *var,
enum print_values print_values); enum print_values print_values);
static int mi_print_value_p (struct type *type, enum print_values print_values); static int mi_print_value_p (struct type *type, enum print_values print_values);
@ -535,11 +535,9 @@ mi_cmd_var_update (char *command, char **argv, int argc)
return MI_CMD_DONE; return MI_CMD_DONE;
} }
/* Helper for mi_cmd_var_update() Returns 0 if the update for /* Helper for mi_cmd_var_update(). */
the variable fails (usually because the variable is out of
scope), and 1 if it succeeds. */
static int static void
varobj_update_one (struct varobj *var, enum print_values print_values) varobj_update_one (struct varobj *var, enum print_values print_values)
{ {
struct varobj **changelist; struct varobj **changelist;
@ -549,37 +547,39 @@ varobj_update_one (struct varobj *var, enum print_values print_values)
nc = varobj_update (&var, &changelist); nc = varobj_update (&var, &changelist);
/* nc == 0 means that nothing has changed. /* nc >= 0 represents the number of changes reported into changelist.
nc == -1 means that an error occured in updating the variable. nc < 0 means that an error occured or the the variable has
nc == -2 means the variable has changed type. */ changed type (TYPE_CHANGED). */
if (nc == 0) if (nc == 0)
return 1; return;
else if (nc == -1) else if (nc < 0)
{ {
if (mi_version (uiout) > 1) if (mi_version (uiout) > 1)
cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
ui_out_field_string (uiout, "name", varobj_get_objname(var)); ui_out_field_string (uiout, "name", varobj_get_objname(var));
ui_out_field_string (uiout, "in_scope", "false");
if (mi_version (uiout) > 1) switch (nc)
do_cleanups (cleanup); {
return -1; case NOT_IN_SCOPE:
} case WRONG_PARAM:
else if (nc == -2) ui_out_field_string (uiout, "in_scope", "false");
{ break;
if (mi_version (uiout) > 1) case INVALID:
cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_string (uiout, "in_scope", "invalid");
ui_out_field_string (uiout, "name", varobj_get_objname (var)); break;
ui_out_field_string (uiout, "in_scope", "true"); case TYPE_CHANGED:
ui_out_field_string (uiout, "new_type", varobj_get_type(var)); ui_out_field_string (uiout, "in_scope", "true");
ui_out_field_int (uiout, "new_num_children", ui_out_field_string (uiout, "new_type", varobj_get_type(var));
varobj_get_num_children(var)); ui_out_field_int (uiout, "new_num_children",
varobj_get_num_children(var));
break;
}
if (mi_version (uiout) > 1) if (mi_version (uiout) > 1)
do_cleanups (cleanup); do_cleanups (cleanup);
} }
else else
{ {
cc = changelist; cc = changelist;
while (*cc != NULL) while (*cc != NULL)
{ {
@ -595,7 +595,5 @@ varobj_update_one (struct varobj *var, enum print_values print_values)
cc++; cc++;
} }
xfree (changelist); xfree (changelist);
return 1;
} }
return 1;
} }

View file

@ -52,6 +52,7 @@
#include "observer.h" #include "observer.h"
#include "exec.h" #include "exec.h"
#include "parser-defs.h" #include "parser-defs.h"
#include "varobj.h"
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
@ -2602,6 +2603,10 @@ clear_symtab_users (void)
between expressions and which ought to be reset each time. */ between expressions and which ought to be reset each time. */
expression_context_block = NULL; expression_context_block = NULL;
innermost_block = NULL; innermost_block = NULL;
/* Varobj may refer to old symbols, perform a cleanup. */
varobj_invalidate ();
} }
static void static void

View file

@ -71,6 +71,10 @@ struct varobj_root
using the currently selected frame. */ using the currently selected frame. */
int use_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 */ /* Language info for this variable and its children */
struct language_specific *lang; struct language_specific *lang;
@ -742,8 +746,9 @@ varobj_get_type (struct varobj *var)
long length; long length;
/* For the "fake" variables, do not return a type. (It's type is /* For the "fake" variables, do not return a type. (It's type is
NULL, too.) */ NULL, too.)
if (CPLUS_FAKE_CHILD (var)) Do not return a type for invalid variables as well. */
if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
return NULL; return NULL;
stb = mem_fileopen (); stb = mem_fileopen ();
@ -778,7 +783,7 @@ varobj_get_attributes (struct varobj *var)
{ {
int attributes = 0; int attributes = 0;
if (variable_editable (var)) if (var->root->is_valid && variable_editable (var))
/* FIXME: define masks for attributes */ /* FIXME: define masks for attributes */
attributes |= 0x00000001; /* Editable */ attributes |= 0x00000001; /* Editable */
@ -1018,16 +1023,15 @@ install_new_value (struct varobj *var, struct value *value, int initial)
expression to see if it's changed. Then go all the way expression to see if it's changed. Then go all the way
through its children, reconstructing them and noting if they've through its children, reconstructing them and noting if they've
changed. changed.
Return value: Return value:
-1 if there was an error updating the varobj < 0 for error values, see varobj.h.
-2 if the type changed Otherwise it is the number of children + parent changed.
Otherwise it is the number of children + parent changed
Only root variables can be updated... Only root variables can be updated...
NOTE: This function may delete the caller's varobj. If it NOTE: This function may delete the caller's varobj. If it
returns -2, then it has done this and VARP will be modified returns TYPE_CHANGED, then it has done this and VARP will be modified
to point to the new varobj. */ to point to the new varobj. */
int int
varobj_update (struct varobj **varp, struct varobj ***changelist) varobj_update (struct varobj **varp, struct varobj ***changelist)
@ -1046,34 +1050,37 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
struct frame_id old_fid; struct frame_id old_fid;
struct frame_info *fi; struct frame_info *fi;
/* sanity check: have we been passed a pointer? */ /* sanity check: have we been passed a pointer? */
if (changelist == NULL) if (changelist == NULL)
return -1; return WRONG_PARAM;
/* Only root variables can be updated... */ /* Only root variables can be updated... */
if (!is_root_p (*varp)) if (!is_root_p (*varp))
/* Not a root var */ /* Not a root var. */
return -1; return WRONG_PARAM;
if (!(*varp)->root->is_valid)
return INVALID;
/* Save the selected stack frame, since we will need to change it /* Save the selected stack frame, since we will need to change it
in order to evaluate expressions. */ in order to evaluate expressions. */
old_fid = get_frame_id (deprecated_selected_frame); old_fid = get_frame_id (deprecated_selected_frame);
/* Update the root variable. value_of_root can return NULL /* Update the root variable. value_of_root can return NULL
if the variable is no longer around, i.e. we stepped out of if the variable is no longer around, i.e. we stepped out of
the frame in which a local existed. We are letting the the frame in which a local existed. We are letting the
value_of_root variable dispose of the varobj if the type value_of_root variable dispose of the varobj if the type
has changed. */ has changed. */
type_changed = 1; type_changed = 1;
new = value_of_root (varp, &type_changed); new = value_of_root (varp, &type_changed);
/* Restore selected frame */ /* Restore selected frame. */
fi = frame_find_by_id (old_fid); fi = frame_find_by_id (old_fid);
if (fi) if (fi)
select_frame (fi); select_frame (fi);
/* If this is a "use_selected_frame" varobj, and its type has changed, /* 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) if (type_changed)
VEC_safe_push (varobj_p, result, *varp); VEC_safe_push (varobj_p, result, *varp);
@ -1090,12 +1097,12 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
/* This means the varobj itself is out of scope. /* This means the varobj itself is out of scope.
Report it. */ Report it. */
VEC_free (varobj_p, result); VEC_free (varobj_p, result);
return -1; return NOT_IN_SCOPE;
} }
VEC_safe_push (varobj_p, stack, *varp); 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)) while (!VEC_empty (varobj_p, stack))
{ {
v = VEC_pop (varobj_p, stack); v = VEC_pop (varobj_p, stack);
@ -1126,7 +1133,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); changed = VEC_length (varobj_p, result);
*changelist = xmalloc ((changed + 1) * sizeof (struct varobj *)); *changelist = xmalloc ((changed + 1) * sizeof (struct varobj *));
cv = *changelist; cv = *changelist;
@ -1140,7 +1147,7 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
*cv = 0; *cv = 0;
if (type_changed) if (type_changed)
return -2; return TYPE_CHANGED;
else else
return changed; return changed;
} }
@ -1409,6 +1416,7 @@ new_root_variable (void)
var->root->frame = null_frame_id; var->root->frame = null_frame_id;
var->root->use_selected_frame = 0; var->root->use_selected_frame = 0;
var->root->rootvar = NULL; var->root->rootvar = NULL;
var->root->is_valid = 1;
return var; return var;
} }
@ -1692,7 +1700,10 @@ variable_editable (struct varobj *var)
static char * static char *
my_value_of_variable (struct varobj *var) 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 * static char *
@ -2504,3 +2515,44 @@ When non-zero, varobj debugging is enabled."),
show_varobjdebug, show_varobjdebug,
&setlist, &showlist); &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;
}

View file

@ -38,7 +38,16 @@ enum varobj_type
USE_CURRENT_FRAME, /* Use the current frame */ USE_CURRENT_FRAME, /* Use the current frame */
USE_SELECTED_FRAME /* Always reevaluate in selected frame */ USE_SELECTED_FRAME /* Always reevaluate in selected frame */
}; };
/* Error return values for varobj_update function. */
enum varobj_update_error
{
NOT_IN_SCOPE = -1, /* varobj not in scope, can not be updated. */
TYPE_CHANGED = -2, /* varobj type has changed. */
INVALID = -3, /* varobj is not valid anymore. */
WRONG_PARAM = -4 /* function is called with wrong arguments. */
};
/* String representations of gdb's format codes (defined in varobj.c) */ /* String representations of gdb's format codes (defined in varobj.c) */
extern char *varobj_format_string[]; extern char *varobj_format_string[];
@ -99,4 +108,6 @@ extern int varobj_list (struct varobj ***rootlist);
extern int varobj_update (struct varobj **varp, struct varobj ***changelist); extern int varobj_update (struct varobj **varp, struct varobj ***changelist);
extern void varobj_invalidate (void);
#endif /* VAROBJ_H */ #endif /* VAROBJ_H */