Refactor varobj_update interface.
* varobj.c (varobj_update): Report changes as vector. Also return not just a list of varobj, but a list of special structures that tell what exactly has changed. * varobj.h (enum varobj_update_error): Rename to varobj_scope_status. (struct varobj_update_result_t): New. (varobj_update): Adjust prototype. * mi/mi-cmd-var.c: Adjust for changes.
This commit is contained in:
parent
124b52c6d8
commit
f7f9ae2c16
7 changed files with 101 additions and 104 deletions
|
@ -1,3 +1,15 @@
|
|||
2008-05-28 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
Refactor varobj_update interface.
|
||||
* varobj.c (varobj_update): Report changes as vector. Also
|
||||
return not just a list of varobj, but a list of special structures
|
||||
that tell what exactly has changed.
|
||||
* varobj.h (enum varobj_update_error): Rename to
|
||||
varobj_scope_status.
|
||||
(struct varobj_update_result_t): New.
|
||||
(varobj_update): Adjust prototype.
|
||||
* mi/mi-cmd-var.c: Adjust for changes.
|
||||
|
||||
2008-05-28 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* varobj.c (varobj_update): Fix comment typo.
|
||||
|
|
|
@ -654,62 +654,52 @@ static void
|
|||
varobj_update_one (struct varobj *var, enum print_values print_values,
|
||||
int explicit)
|
||||
{
|
||||
struct varobj **changelist;
|
||||
struct varobj **cc;
|
||||
struct cleanup *cleanup = NULL;
|
||||
int nc;
|
||||
|
||||
nc = varobj_update (&var, &changelist, explicit);
|
||||
|
||||
/* nc >= 0 represents the number of changes reported into changelist.
|
||||
nc < 0 means that an error occured or the the variable has
|
||||
changed type (TYPE_CHANGED). */
|
||||
VEC (varobj_update_result) *changes;
|
||||
varobj_update_result *r;
|
||||
int i;
|
||||
|
||||
if (nc == 0)
|
||||
return;
|
||||
else if (nc < 0)
|
||||
changes = varobj_update (&var, explicit);
|
||||
|
||||
for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
|
||||
{
|
||||
if (mi_version (uiout) > 1)
|
||||
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 (r->varobj));
|
||||
|
||||
switch (nc)
|
||||
{
|
||||
case NOT_IN_SCOPE:
|
||||
switch (r->status)
|
||||
{
|
||||
case VAROBJ_IN_SCOPE:
|
||||
if (mi_print_value_p (varobj_get_gdb_type (r->varobj), print_values))
|
||||
ui_out_field_string (uiout, "value", varobj_get_value (r->varobj));
|
||||
ui_out_field_string (uiout, "in_scope", "true");
|
||||
break;
|
||||
case VAROBJ_NOT_IN_SCOPE:
|
||||
ui_out_field_string (uiout, "in_scope", "false");
|
||||
break;
|
||||
case INVALID:
|
||||
case VAROBJ_INVALID:
|
||||
ui_out_field_string (uiout, "in_scope", "invalid");
|
||||
break;
|
||||
case TYPE_CHANGED:
|
||||
ui_out_field_string (uiout, "in_scope", "true");
|
||||
ui_out_field_string (uiout, "type_changed", "true");
|
||||
ui_out_field_string (uiout, "new_type", varobj_get_type(var));
|
||||
ui_out_field_int (uiout, "new_num_children",
|
||||
varobj_get_num_children(var));
|
||||
if (mi_print_value_p (varobj_get_gdb_type (var), print_values))
|
||||
ui_out_field_string (uiout, "value", varobj_get_value (var));
|
||||
break;
|
||||
}
|
||||
if (mi_version (uiout) > 1)
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
else
|
||||
{
|
||||
cc = changelist;
|
||||
while (*cc != NULL)
|
||||
{
|
||||
if (mi_version (uiout) > 1)
|
||||
cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
|
||||
ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
|
||||
if (mi_print_value_p (varobj_get_gdb_type (*cc), print_values))
|
||||
ui_out_field_string (uiout, "value", varobj_get_value (*cc));
|
||||
ui_out_field_string (uiout, "in_scope", "true");
|
||||
ui_out_field_string (uiout, "type_changed", "false");
|
||||
if (mi_version (uiout) > 1)
|
||||
do_cleanups (cleanup);
|
||||
cc++;
|
||||
}
|
||||
xfree (changelist);
|
||||
|
||||
if (r->status != VAROBJ_INVALID)
|
||||
{
|
||||
if (r->type_changed)
|
||||
ui_out_field_string (uiout, "type_changed", "true");
|
||||
else
|
||||
ui_out_field_string (uiout, "type_changed", "false");
|
||||
}
|
||||
|
||||
if (r->type_changed)
|
||||
{
|
||||
ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
|
||||
ui_out_field_int (uiout, "new_num_children",
|
||||
varobj_get_num_children (r->varobj));
|
||||
}
|
||||
|
||||
if (mi_version (uiout) > 1)
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
VEC_free (varobj_update_result, changes);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2008-05-28 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
* gdb.mi/mi-var-cmd.exp: Adjust for the fact that type_changed field is
|
||||
now printed.
|
||||
* gdb.mi/mi2-var-cmd.exp: Likewise.
|
||||
|
||||
2008-05-27 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* gdb.base/frame-args.exp: Handle arguments that are optimized
|
||||
|
|
|
@ -458,7 +458,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
|
|||
# Test: c_variable-2.15
|
||||
# Desc: check for out of scope subroutine1 locals
|
||||
mi_gdb_test "-var-update *" \
|
||||
"\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\},\{name=\"i\",in_scope=\"false\"\}\\\]" \
|
||||
"\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
|
||||
"update all vars: all now out of scope"
|
||||
|
||||
# Done with locals/globals tests. Erase all variables
|
||||
|
|
|
@ -421,7 +421,7 @@ mi_next_to "do_locals_tests" "" "var-cmd.c" \
|
|||
# Test: c_variable-2.15
|
||||
# Desc: check for out of scope subroutine1 locals
|
||||
mi_gdb_test "-var-update *" \
|
||||
"\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\},\{name=\"i\",in_scope=\"false\"\}\\\]" \
|
||||
"\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
|
||||
"update all vars: all now out of scope"
|
||||
|
||||
# Done with locals/globals tests. Erase all variables
|
||||
|
|
77
gdb/varobj.c
77
gdb/varobj.c
|
@ -1120,9 +1120,6 @@ 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:
|
||||
< 0 for error values, see varobj.h.
|
||||
Otherwise it is the number of children + parent changed.
|
||||
|
||||
The EXPLICIT parameter specifies if this call is result
|
||||
of MI request to update this specific variable, or
|
||||
|
@ -1133,9 +1130,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
|
|||
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 explicit)
|
||||
VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
|
||||
{
|
||||
int changed = 0;
|
||||
int type_changed = 0;
|
||||
|
@ -1146,52 +1141,50 @@ varobj_update (struct varobj **varp, struct varobj ***changelist,
|
|||
struct varobj **templist = NULL;
|
||||
struct value *new;
|
||||
VEC (varobj_p) *stack = NULL;
|
||||
VEC (varobj_p) *result = NULL;
|
||||
VEC (varobj_update_result) *result = NULL;
|
||||
struct frame_info *fi;
|
||||
|
||||
/* sanity check: have we been passed a pointer? */
|
||||
gdb_assert (changelist);
|
||||
|
||||
/* 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;
|
||||
return result;
|
||||
|
||||
if (!(*varp)->root->is_valid)
|
||||
return INVALID;
|
||||
{
|
||||
varobj_update_result r = {*varp};
|
||||
r.status = VAROBJ_INVALID;
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((*varp)->root->rootvar == *varp)
|
||||
{
|
||||
varobj_update_result r = {*varp};
|
||||
r.status = VAROBJ_IN_SCOPE;
|
||||
|
||||
/* 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. */
|
||||
new = value_of_root (varp, &type_changed);
|
||||
|
||||
/* If this is a floating varobj, and its type has changed,
|
||||
then note that it's changed. */
|
||||
if (type_changed)
|
||||
VEC_safe_push (varobj_p, result, *varp);
|
||||
|
||||
r.varobj = *varp;
|
||||
|
||||
r.type_changed = type_changed;
|
||||
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);
|
||||
}
|
||||
r.changed = 1;
|
||||
|
||||
if (new == NULL)
|
||||
{
|
||||
/* This means the varobj itself is out of scope.
|
||||
Report it. */
|
||||
VEC_free (varobj_p, result);
|
||||
return NOT_IN_SCOPE;
|
||||
}
|
||||
r.status = VAROBJ_NOT_IN_SCOPE;
|
||||
|
||||
if (r.type_changed || r.changed)
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
|
||||
if (r.status == VAROBJ_NOT_IN_SCOPE)
|
||||
return result;
|
||||
}
|
||||
|
||||
VEC_safe_push (varobj_p, stack, *varp);
|
||||
|
@ -1221,32 +1214,16 @@ varobj_update (struct varobj **varp, struct varobj ***changelist,
|
|||
if (install_new_value (v, new, 0 /* type not changed */))
|
||||
{
|
||||
/* Note that it's changed */
|
||||
VEC_safe_push (varobj_p, result, v);
|
||||
varobj_update_result r = {v};
|
||||
r.changed = 1;
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
v->updated = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Alloc (changed + 1) list entries. */
|
||||
changed = VEC_length (varobj_p, result);
|
||||
*changelist = xmalloc ((changed + 1) * sizeof (struct varobj *));
|
||||
cv = *changelist;
|
||||
|
||||
for (i = 0; i < changed; ++i)
|
||||
{
|
||||
*cv = VEC_index (varobj_p, result, i);
|
||||
gdb_assert (*cv != NULL);
|
||||
++cv;
|
||||
}
|
||||
*cv = 0;
|
||||
|
||||
VEC_free (varobj_p, stack);
|
||||
VEC_free (varobj_p, result);
|
||||
|
||||
if (type_changed)
|
||||
return TYPE_CHANGED;
|
||||
else
|
||||
return changed;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
26
gdb/varobj.h
26
gdb/varobj.h
|
@ -39,12 +39,14 @@ enum varobj_type
|
|||
USE_SELECTED_FRAME /* Always reevaluate in selected frame */
|
||||
};
|
||||
|
||||
/* Error return values for varobj_update function. */
|
||||
enum varobj_update_error
|
||||
/* Enumerator describing if a variable object is in scope. */
|
||||
enum varobj_scope_status
|
||||
{
|
||||
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. */
|
||||
VAROBJ_IN_SCOPE = 0, /* Varobj is scope, value available. */
|
||||
VAROBJ_NOT_IN_SCOPE = 1, /* Varobj is not in scope, value not available,
|
||||
but varobj can become in scope later. */
|
||||
VAROBJ_INVALID = 2, /* Varobj no longer has any value, and never
|
||||
will. */
|
||||
};
|
||||
|
||||
/* String representations of gdb's format codes (defined in varobj.c) */
|
||||
|
@ -65,6 +67,16 @@ struct varobj;
|
|||
typedef struct varobj *varobj_p;
|
||||
DEF_VEC_P (varobj_p);
|
||||
|
||||
typedef struct varobj_update_result_t
|
||||
{
|
||||
struct varobj *varobj;
|
||||
int type_changed;
|
||||
int changed;
|
||||
enum varobj_scope_status status;
|
||||
} varobj_update_result;
|
||||
|
||||
DEF_VEC_O (varobj_update_result);
|
||||
|
||||
/* API functions */
|
||||
|
||||
extern struct varobj *varobj_create (char *objname,
|
||||
|
@ -120,8 +132,8 @@ extern int varobj_set_value (struct varobj *var, char *expression);
|
|||
|
||||
extern int varobj_list (struct varobj ***rootlist);
|
||||
|
||||
extern int varobj_update (struct varobj **varp, struct varobj ***changelist,
|
||||
int explicit);
|
||||
extern VEC(varobj_update_result) *varobj_update (struct varobj **varp,
|
||||
int explicit);
|
||||
|
||||
extern void varobj_invalidate (void);
|
||||
|
||||
|
|
Loading…
Reference in a new issue