diff options
author | Jim Ingham <jingham@apple.com> | 2000-03-13 21:51:46 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2000-03-13 21:51:46 +0000 |
commit | 73a93a3251211bf8c5774282e41dbc023820404a (patch) | |
tree | d1cedff69c4d1306c93cc4bfb59d4719026200b6 /gdb/varobj.c | |
parent | 271bb601c426b043736a308b1a5f6d36bb47857a (diff) | |
download | gdb-73a93a3251211bf8c5774282e41dbc023820404a.zip gdb-73a93a3251211bf8c5774282e41dbc023820404a.tar.gz gdb-73a93a3251211bf8c5774282e41dbc023820404a.tar.bz2 |
2000-03-13 James Ingham <jingham@leda.cygnus.com>
Add support for a variable object that tries to evaluate itself in
the currently selected frame, rather than in a fixed frame.
* wrapper.c,h (gdb_parse_exp_1): Added a wrapper for
gdb_parse_exp_1.
* varobj.h: Added USE_CURRENT_FRAME to varobj_type & changed def'n
of varobj_create.
* varobj.c (varobj_list): Return type indicates whether the
variable's type has changed (for current frame variables).
(varobj_update): Handle the case where the variable's type has
changed.
(delete_variable_1): Allow for deletion of variables that have not
been installed yet.
(new_root_variable): Initialize use_selected_frame variable.
(value_of_root): This is where most of the work to handle "current
frame" variables was added. Most of the complexity involves
handling the case where the type of the variable has changed.
(varobj_create): Add a "type" argument, to tell if the
variable is one of these "current frame" variables. Also protect
call to parse_exp_1 from long jumping.
* mi-var-block.exp: The error report from varobj_create changed
since I am now trapping parse_exp_1 errors. Change the tests to
match the new error message.
* mi-var-child.exp: Ditto.
* mi-var-cmd.exp: Ditto.
* lib/gdb.exp: Fix the gdbtk_start routine to correctly find all
the library directories.
* gdbtk-varobj.c (variable_create): Pass the correct
"how_specified" flag to the varobj_create routine.
Diffstat (limited to 'gdb/varobj.c')
-rw-r--r-- | gdb/varobj.c | 195 |
1 files changed, 153 insertions, 42 deletions
diff --git a/gdb/varobj.c b/gdb/varobj.c index f0740c6..e2a2419 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -56,6 +56,10 @@ struct varobj_root /* The frame for this expression */ CORE_ADDR frame; + /* If 1, "update" always recomputes the frame & valid block + using the currently selected frame. */ + int use_selected_frame; + /* Language info for this variable and its children */ struct language_specific *lang; @@ -204,7 +208,8 @@ static char *name_of_variable PARAMS ((struct varobj *)); static char *name_of_child PARAMS ((struct varobj *, int)); -static value_ptr value_of_root PARAMS ((struct varobj * var)); +static value_ptr value_of_root PARAMS ((struct varobj ** var_handle, + int *)); static value_ptr value_of_child PARAMS ((struct varobj * parent, int index)); @@ -224,7 +229,7 @@ static char *c_name_of_variable PARAMS ((struct varobj * parent)); static char *c_name_of_child PARAMS ((struct varobj * parent, int index)); -static value_ptr c_value_of_root PARAMS ((struct varobj * var)); +static value_ptr c_value_of_root PARAMS ((struct varobj ** var_handle)); static value_ptr c_value_of_child PARAMS ((struct varobj * parent, int index)); @@ -244,7 +249,7 @@ static char *cplus_name_of_variable PARAMS ((struct varobj * parent)); static char *cplus_name_of_child PARAMS ((struct varobj * parent, int index)); -static value_ptr cplus_value_of_root PARAMS ((struct varobj * var)); +static value_ptr cplus_value_of_root PARAMS ((struct varobj ** var_handle)); static value_ptr cplus_value_of_child PARAMS ((struct varobj * parent, int index)); @@ -262,7 +267,7 @@ static char *java_name_of_variable PARAMS ((struct varobj * parent)); static char *java_name_of_child PARAMS ((struct varobj * parent, int index)); -static value_ptr java_value_of_root PARAMS ((struct varobj * var)); +static value_ptr java_value_of_root PARAMS ((struct varobj ** var_handle)); static value_ptr java_value_of_child PARAMS ((struct varobj * parent, int index)); @@ -290,7 +295,7 @@ struct language_specific char *(*name_of_child) PARAMS ((struct varobj * parent, int index)); /* The value_ptr of the root variable ROOT. */ - value_ptr (*value_of_root) PARAMS ((struct varobj * root)); + value_ptr (*value_of_root) PARAMS ((struct varobj ** root_handle)); /* The value_ptr of the INDEX'th child of PARENT. */ value_ptr (*value_of_child) PARAMS ((struct varobj * parent, int index)); @@ -401,7 +406,8 @@ static struct vlist **varobj_table; struct varobj * varobj_create (char *objname, - char *expression, CORE_ADDR frame) + char *expression, CORE_ADDR frame, + enum varobj_type type) { struct varobj *var; struct frame_info *fi, *old_fi; @@ -421,19 +427,28 @@ varobj_create (char *objname, of the variable's data as possible */ /* Allow creator to specify context of variable */ - if (frame == (CORE_ADDR) -1) + if ((type == USE_CURRENT_FRAME) + || (type == USE_SELECTED_FRAME)) fi = selected_frame; else fi = find_frame_addr_in_frame_chain (frame); + /* frame = -2 means always use selected frame */ + if (type == USE_SELECTED_FRAME) + var->root->use_selected_frame = 1; + block = NULL; if (fi != NULL) block = get_frame_block (fi); p = expression; innermost_block = NULL; - /* Callee may longjump */ - var->root->exp = parse_exp_1 (&p, block, 0); + /* Wrap the call to parse expression, so we can + return a sensible error. */ + if (!gdb_parse_exp_1 (&p, block, 0, &var->root->exp)) + { + return NULL; + } /* Don't allow variables to be created for types. */ if (var->root->exp->elts[0].opcode == OP_TYPE) @@ -486,7 +501,10 @@ varobj_create (char *objname, select_frame (old_fi, -1); } - if (var != NULL) + /* If the variable object name is null, that means this + is a temporary variable, so don't install it. */ + + if ((var != NULL) && (objname != NULL)) { var->obj_name = savestring (objname, strlen (objname)); @@ -845,6 +863,10 @@ varobj_list (struct varobj ***varlist) 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 Only root variables can be updated... */ @@ -852,6 +874,7 @@ int varobj_update (struct varobj *var, struct varobj ***changelist) { int changed = 0; + int type_changed; int i; int vleft; int error2; @@ -878,19 +901,27 @@ varobj_update (struct varobj *var, struct varobj ***changelist) /* 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. */ - new = value_of_root (var); + 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 (&var, &type_changed); if (new == NULL) - return -1; + { + var->error = 1; + return -1; + } /* Initialize a stack for temporary results */ vpush (&result, NULL); - if (!my_value_equal (var->value, new, &error2)) + if (type_changed || !my_value_equal (var->value, new, &error2)) { /* Note that it's changed There a couple of exceptions here, - though. We don't want some types to be reported as "changed". */ - if (type_changeable (var)) + though. We don't want some types to be reported as + "changed". The exception to this is if this is a + "use_selected_frame" varobj, and its type has changed. */ + if (type_changed || type_changeable (var)) { vpush (&result, var); changed++; @@ -984,7 +1015,10 @@ varobj_update (struct varobj *var, struct varobj ***changelist) /* Restore selected frame */ select_frame (old_fi, -1); - return changed; + if (type_changed) + return -2; + else + return changed; } @@ -1039,9 +1073,9 @@ delete_variable_1 (resultp, delcountp, var, return; /* Otherwise, add it to the list of deleted ones and proceed to do so */ - if (var->obj_name == NULL) - warning ("Assertion failed: NULL var->obj_name unexpectdly found"); - else + /* If the name is null, this is a temporary variable, that has not + yet been installed, don't report it, it belongs to the caller... */ + if (var->obj_name != NULL) { cppush (resultp, strdup (var->obj_name)); *delcountp = *delcountp + 1; @@ -1057,8 +1091,9 @@ delete_variable_1 (resultp, delcountp, var, { remove_child_from_parent (var->parent, var); } - - uninstall_variable (var); + + if (var->obj_name != NULL) + uninstall_variable (var); /* Free memory associated with this variable */ free_variable (var); @@ -1315,6 +1350,7 @@ new_root_variable (void) var->root->exp = NULL; var->root->valid_block = NULL; var->root->frame = (CORE_ADDR) -1; + var->root->use_selected_frame = 0; var->root->rootvar = NULL; return var; @@ -1578,12 +1614,74 @@ name_of_child (var, index) return (*var->root->lang->name_of_child) (var, index); } -/* What is the value_ptr of the root variable VAR? */ +/* What is the value_ptr of the root variable VAR? + TYPE_CHANGED controls what to do if the type of a + use_selected_frame = 1 variable changes. On input, + TYPE_CHANGED = 1 means discard the old varobj, and replace + it with this one. TYPE_CHANGED = 0 means leave it around. + NB: In both cases, var_handle will point to the new varobj, + so if you use TYPE_CHANGED = 0, you will have to stash the + old varobj pointer away somewhere before calling this. + On return, TYPE_CHANGED will be 1 if the type has changed, and + 0 otherwise. */ static value_ptr -value_of_root (var) - struct varobj *var; +value_of_root (var_handle, type_changed) + struct varobj ** var_handle; + int *type_changed; { - return (*var->root->lang->value_of_root) (var); + struct varobj *var; + + if (var_handle == NULL) + return NULL; + + var = *var_handle; + + /* This should really be an exception, since this should + only get called with a root variable. */ + + if (var->root->rootvar != var) + return NULL; + + if (var->root->use_selected_frame) + { + 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; + } + new_type = varobj_get_type (tmp_var); + if (strcmp(old_type, new_type) == 0) + { + varobj_delete (tmp_var, NULL, 0); + *type_changed = 0; + } + else + { + if (*type_changed) + { + tmp_var->obj_name = + savestring (var->obj_name, strlen (var->obj_name)); + uninstall_variable (var); + } + else + { + tmp_var->obj_name = varobj_gen_name (); + } + install_variable (tmp_var); + *var_handle = tmp_var; + *type_changed = 1; + } + } + else + { + *type_changed = 0; + } + + return (*var->root->lang->value_of_root) (var_handle); } /* What is the value_ptr for the INDEX'th child of PARENT? */ @@ -1790,38 +1888,51 @@ c_name_of_child (parent, index) } static value_ptr -c_value_of_root (var) - struct varobj *var; +c_value_of_root (var_handle) + struct varobj **var_handle; { value_ptr new_val; + struct varobj *var = *var_handle; struct frame_info *fi; int within_scope; + /* Only root variables can be updated... */ + if (var->root->rootvar != var) + /* Not a root var */ + return NULL; + + /* Determine whether the variable is still around. */ if (var->root->valid_block == NULL) within_scope = 1; else { reinit_frame_cache (); + + fi = find_frame_addr_in_frame_chain (var->root->frame); + within_scope = fi != NULL; /* FIXME: select_frame could fail */ if (within_scope) select_frame (fi, -1); } - + 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 */ + /* 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)) { if (VALUE_LAZY (new_val)) { - /* We need to catch errors because if value_fetch_lazy fails we - still want to continue (after making val->error = 1) */ - /* FIXME: Shouldn't be using VALUE_CONTENTS? The comment on - value_fetch_lazy() says it is only called from the macro... */ + /* We need to catch errors because if + value_fetch_lazy fails we still want to continue + (after making val->error = 1) */ + /* FIXME: Shouldn't be using VALUE_CONTENTS? The + comment on value_fetch_lazy() says it is only + called from the macro... */ if (!gdb_value_fetch_lazy (new_val)) var->error = 1; else @@ -1830,7 +1941,7 @@ c_value_of_root (var) } else var->error = 1; - + release_value (new_val); return new_val; } @@ -2194,10 +2305,10 @@ cplus_name_of_child (parent, index) } static value_ptr -cplus_value_of_root (var) - struct varobj *var; +cplus_value_of_root (var_handle) + struct varobj **var_handle; { - return c_value_of_root (var); + return c_value_of_root (var_handle); } static value_ptr @@ -2367,10 +2478,10 @@ java_name_of_child (parent, index) } static value_ptr -java_value_of_root (var) - struct varobj *var; +java_value_of_root (var_handle) + struct varobj **var_handle; { - return cplus_value_of_root (var); + return cplus_value_of_root (var_handle); } static value_ptr |