X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvarobj.c;h=9ae145e217090bc48d0713a5f54534a9b0c5341a;hb=a8cdafbd4e8dbf81a28d98de6a046bd9bc5cc097;hp=1ebf21c17e72419e9fba6a9f342c79ab4db8ff05;hpb=8a1a01128de8adbea128525c11808b57bc9b04cd;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/varobj.c b/gdb/varobj.c index 1ebf21c17e..9ae145e217 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -1,5 +1,5 @@ /* Implementation of the GDB variable objects API. - Copyright 1999, 2000 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,7 +20,6 @@ #include "value.h" #include "expression.h" #include "frame.h" -#include "valprint.h" #include "language.h" #include "wrapper.h" #include "gdbcmd.h" @@ -34,122 +33,121 @@ int varobjdebug = 0; /* String representations of gdb's format codes */ char *varobj_format_string[] = -{"natural", "binary", "decimal", "hexadecimal", "octal"}; + { "natural", "binary", "decimal", "hexadecimal", "octal" }; /* String representations of gdb's known languages */ -char *varobj_language_string[] = -{"unknown", "C", "C++", "Java"}; +char *varobj_language_string[] = { "unknown", "C", "C++", "Java" }; /* Data structures */ /* Every root variable has one of these structures saved in its varobj. Members which must be free'd are noted. */ struct varobj_root - { +{ - /* Alloc'd expression for this parent. */ - struct expression *exp; + /* Alloc'd expression for this parent. */ + struct expression *exp; - /* Block for which this expression is valid */ - struct block *valid_block; + /* Block for which this expression is valid */ + struct block *valid_block; - /* The frame for this expression */ - CORE_ADDR frame; + /* 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; + /* 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; + /* Language info for this variable and its children */ + struct language_specific *lang; - /* The varobj for this root node. */ - struct varobj *rootvar; + /* The varobj for this root node. */ + struct varobj *rootvar; - /* Next root variable */ - struct varobj_root *next; - }; + /* Next root variable */ + struct varobj_root *next; +}; /* Every variable in the system has a structure of this type defined for it. This structure holds all information necessary to manipulate a particular object variable. Members which must be freed are noted. */ struct varobj - { +{ - /* Alloc'd name of the variable for this object.. If this variable is a - child, then this name will be the child's source name. - (bar, not foo.bar) */ - /* NOTE: This is the "expression" */ - char *name; + /* Alloc'd name of the variable for this object.. If this variable is a + child, then this name will be the child's source name. + (bar, not foo.bar) */ + /* NOTE: This is the "expression" */ + char *name; - /* The alloc'd name for this variable's object. This is here for - convenience when constructing this object's children. */ - char *obj_name; + /* The alloc'd name for this variable's object. This is here for + convenience when constructing this object's children. */ + char *obj_name; - /* Index of this variable in its parent or -1 */ - int index; + /* Index of this variable in its parent or -1 */ + int index; - /* The type of this variable. This may NEVER be NULL. */ - struct type *type; + /* The type of this variable. This may NEVER be NULL. */ + struct type *type; - /* The value of this expression or subexpression. This may be NULL. */ - value_ptr value; + /* The value of this expression or subexpression. This may be NULL. */ + struct value *value; - /* Did an error occur evaluating the expression or getting its value? */ - int error; + /* Did an error occur evaluating the expression or getting its value? */ + int error; - /* The number of (immediate) children this variable has */ - int num_children; + /* The number of (immediate) children this variable has */ + int num_children; - /* If this object is a child, this points to its immediate parent. */ - struct varobj *parent; + /* If this object is a child, this points to its immediate parent. */ + struct varobj *parent; - /* A list of this object's children */ - struct varobj_child *children; + /* A list of this object's children */ + struct varobj_child *children; - /* Description of the root variable. Points to root variable for children. */ - struct varobj_root *root; + /* Description of the root variable. Points to root variable for children. */ + struct varobj_root *root; - /* The format of the output for this object */ - enum varobj_display_formats format; - }; + /* The format of the output for this object */ + enum varobj_display_formats format; +}; /* Every variable keeps a linked list of its children, described by the following structure. */ /* FIXME: Deprecated. All should use vlist instead */ struct varobj_child - { +{ - /* Pointer to the child's data */ - struct varobj *child; + /* Pointer to the child's data */ + struct varobj *child; - /* Pointer to the next child */ - struct varobj_child *next; - }; + /* Pointer to the next child */ + struct varobj_child *next; +}; /* A stack of varobjs */ /* FIXME: Deprecated. All should use vlist instead */ struct vstack - { - struct varobj *var; - struct vstack *next; - }; +{ + struct varobj *var; + struct vstack *next; +}; struct cpstack - { - char *name; - struct cpstack *next; - }; +{ + char *name; + struct cpstack *next; +}; /* A list of varobjs */ struct vlist - { - struct varobj *var; - struct vlist *next; - }; +{ + struct varobj *var; + struct vlist *next; +}; /* Private function prototypes */ @@ -190,7 +188,7 @@ static struct type *get_target_type (struct type *); static enum varobj_display_formats variable_default_display (struct varobj *); -static int my_value_equal (value_ptr, value_ptr, int *); +static int my_value_equal (struct value *, struct value *, int *); static void vpush (struct vstack **pstack, struct varobj *var); @@ -210,9 +208,9 @@ static char *name_of_variable (struct varobj *); static char *name_of_child (struct varobj *, int); -static value_ptr value_of_root (struct varobj **var_handle, int *); +static struct value *value_of_root (struct varobj **var_handle, int *); -static value_ptr value_of_child (struct varobj *parent, int index); +static struct value *value_of_child (struct varobj *parent, int index); static struct type *type_of_child (struct varobj *var); @@ -230,9 +228,9 @@ static char *c_name_of_variable (struct varobj *parent); static char *c_name_of_child (struct varobj *parent, int index); -static value_ptr c_value_of_root (struct varobj **var_handle); +static struct value *c_value_of_root (struct varobj **var_handle); -static value_ptr c_value_of_child (struct varobj *parent, int index); +static struct value *c_value_of_child (struct varobj *parent, int index); static struct type *c_type_of_child (struct varobj *parent, int index); @@ -250,9 +248,9 @@ static char *cplus_name_of_variable (struct varobj *parent); static char *cplus_name_of_child (struct varobj *parent, int index); -static value_ptr cplus_value_of_root (struct varobj **var_handle); +static struct value *cplus_value_of_root (struct varobj **var_handle); -static value_ptr cplus_value_of_child (struct varobj *parent, int index); +static struct value *cplus_value_of_child (struct varobj *parent, int index); static struct type *cplus_type_of_child (struct varobj *parent, int index); @@ -268,9 +266,9 @@ static char *java_name_of_variable (struct varobj *parent); static char *java_name_of_child (struct varobj *parent, int index); -static value_ptr java_value_of_root (struct varobj **var_handle); +static struct value *java_value_of_root (struct varobj **var_handle); -static value_ptr java_value_of_child (struct varobj *parent, int index); +static struct value *java_value_of_child (struct varobj *parent, int index); static struct type *java_type_of_child (struct varobj *parent, int index); @@ -281,104 +279,98 @@ static char *java_value_of_variable (struct varobj *var); /* The language specific vector */ struct language_specific - { +{ - /* The language of this variable */ - enum varobj_languages language; + /* The language of this variable */ + enum varobj_languages language; - /* The number of children of PARENT. */ - int (*number_of_children) (struct varobj * parent); + /* The number of children of PARENT. */ + int (*number_of_children) (struct varobj * parent); - /* The name (expression) of a root varobj. */ - char *(*name_of_variable) (struct varobj * parent); + /* The name (expression) of a root varobj. */ + char *(*name_of_variable) (struct varobj * parent); - /* The name of the INDEX'th child of PARENT. */ - char *(*name_of_child) (struct varobj * parent, int index); + /* The name of the INDEX'th child of PARENT. */ + char *(*name_of_child) (struct varobj * parent, int index); - /* The value_ptr of the root variable ROOT. */ - value_ptr (*value_of_root) (struct varobj ** root_handle); + /* The ``struct value *'' of the root variable ROOT. */ + struct value *(*value_of_root) (struct varobj ** root_handle); - /* The value_ptr of the INDEX'th child of PARENT. */ - value_ptr (*value_of_child) (struct varobj * parent, int index); + /* The ``struct value *'' of the INDEX'th child of PARENT. */ + struct value *(*value_of_child) (struct varobj * parent, int index); - /* The type of the INDEX'th child of PARENT. */ - struct type *(*type_of_child) (struct varobj * parent, int index); + /* The type of the INDEX'th child of PARENT. */ + struct type *(*type_of_child) (struct varobj * parent, int index); - /* Is VAR editable? */ - int (*variable_editable) (struct varobj * var); + /* Is VAR editable? */ + int (*variable_editable) (struct varobj * var); - /* The current value of VAR. */ - char *(*value_of_variable) (struct varobj * var); - }; + /* The current value of VAR. */ + char *(*value_of_variable) (struct varobj * var); +}; /* Array of known source language routines. */ static struct language_specific - languages[vlang_end][sizeof (struct language_specific)] = -{ + languages[vlang_end][sizeof (struct language_specific)] = { /* Unknown (try treating as C */ { - vlang_unknown, - c_number_of_children, - c_name_of_variable, - c_name_of_child, - c_value_of_root, - c_value_of_child, - c_type_of_child, - c_variable_editable, - c_value_of_variable - } + vlang_unknown, + c_number_of_children, + c_name_of_variable, + c_name_of_child, + c_value_of_root, + c_value_of_child, + c_type_of_child, + c_variable_editable, + c_value_of_variable} , /* C */ { - vlang_c, - c_number_of_children, - c_name_of_variable, - c_name_of_child, - c_value_of_root, - c_value_of_child, - c_type_of_child, - c_variable_editable, - c_value_of_variable - } + vlang_c, + c_number_of_children, + c_name_of_variable, + c_name_of_child, + c_value_of_root, + c_value_of_child, + c_type_of_child, + c_variable_editable, + c_value_of_variable} , /* C++ */ { - vlang_cplus, - cplus_number_of_children, - cplus_name_of_variable, - cplus_name_of_child, - cplus_value_of_root, - cplus_value_of_child, - cplus_type_of_child, - cplus_variable_editable, - cplus_value_of_variable - } + vlang_cplus, + cplus_number_of_children, + cplus_name_of_variable, + cplus_name_of_child, + cplus_value_of_root, + cplus_value_of_child, + cplus_type_of_child, + cplus_variable_editable, + cplus_value_of_variable} , /* Java */ { - vlang_java, - java_number_of_children, - java_name_of_variable, - java_name_of_child, - java_value_of_root, - java_value_of_child, - java_type_of_child, - java_variable_editable, - java_value_of_variable - } + vlang_java, + java_number_of_children, + java_name_of_variable, + java_name_of_child, + java_value_of_root, + java_value_of_child, + java_type_of_child, + java_variable_editable, + java_value_of_variable} }; /* A little convenience enum for dealing with C++/Java */ enum vsections - { - v_public = 0, v_private, v_protected - }; +{ + v_public = 0, v_private, v_protected +}; /* Private data */ /* Mappings of varobj_display_formats enums to gdb's format codes */ -static int format_code[] = -{0, 't', 'd', 'x', 'o'}; +static int format_code[] = { 0, 't', 'd', 'x', 'o' }; /* Header of the list of root variable objects */ static struct varobj_root *rootlist; @@ -391,11 +383,6 @@ static int rootcount = 0; /* number of root varobjs in the list */ /* Pointer to the varobj hash table (built at run time) */ static struct vlist **varobj_table; -#if defined(FREEIF) -#undef FREEIF -#endif -#define FREEIF(x) if (x != NULL) free((char *) (x)) - /* Is the variable X one of our "fake" children? */ #define CPLUS_FAKE_CHILD(x) \ ((x) != NULL && (x)->type == NULL && (x)->value == NULL) @@ -407,11 +394,11 @@ static struct vlist **varobj_table; struct varobj * varobj_create (char *objname, - char *expression, CORE_ADDR frame, - enum varobj_type type) + char *expression, CORE_ADDR frame, enum varobj_type type) { struct varobj *var; - struct frame_info *fi, *old_fi; + struct frame_info *fi; + struct frame_info *old_fi = NULL; struct block *block; struct cleanup *old_chain; @@ -428,8 +415,7 @@ varobj_create (char *objname, of the variable's data as possible */ /* Allow creator to specify context of variable */ - if ((type == USE_CURRENT_FRAME) - || (type == USE_SELECTED_FRAME)) + if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME)) fi = selected_frame; else fi = find_frame_addr_in_frame_chain (frame); @@ -440,7 +426,7 @@ varobj_create (char *objname, block = NULL; if (fi != NULL) - block = get_frame_block (fi); + block = get_frame_block (fi, 0); p = expression; innermost_block = NULL; @@ -456,7 +442,7 @@ varobj_create (char *objname, { do_cleanups (old_chain); fprintf_unfiltered (gdb_stderr, - "Attempt to use a type name as an expression."); + "Attempt to use a type name as an expression."); return NULL; } @@ -472,7 +458,7 @@ varobj_create (char *objname, { var->root->frame = FRAME_FP (fi); old_fi = selected_frame; - select_frame (fi, -1); + select_frame (fi); } /* We definitively need to catch errors here. @@ -499,7 +485,7 @@ varobj_create (char *objname, /* Reset the selected frame */ if (fi != NULL) - select_frame (old_fi, -1); + select_frame (old_fi); } /* If the variable object name is null, that means this @@ -617,7 +603,8 @@ varobj_delete (struct varobj *var, char ***dellist, int only_children) } if (mycount || (*cp != NULL)) - warning ("varobj_delete: assertion failed - mycount(=%d) <> 0", mycount); + warning ("varobj_delete: assertion failed - mycount(=%d) <> 0", + mycount); } return delcount; @@ -709,7 +696,7 @@ varobj_list_children (struct varobj *var, struct varobj ***childlist) char * varobj_get_type (struct varobj *var) { - value_ptr val; + struct value *val; struct cleanup *old_chain; struct ui_file *stb; char *thetype; @@ -723,7 +710,7 @@ varobj_get_type (struct varobj *var) stb = mem_fileopen (); old_chain = make_cleanup_ui_file_delete (stb); - /* To print the type, we simply create a zero value_ptr and + /* To print the type, we simply create a zero ``struct value *'' and cast it to our type. We then typeprint this variable. */ val = value_zero (var->type, not_lval); type_print (VALUE_TYPE (val), "", stb, -1); @@ -764,21 +751,20 @@ varobj_get_value (struct varobj *var) int varobj_set_value (struct varobj *var, char *expression) { - value_ptr val; + struct value *val; int offset = 0; /* The argument "expression" contains the variable's new value. We need to first construct a legal expression for this -- ugh! */ /* Does this cover all the bases? */ struct expression *exp; - value_ptr value; + struct value *value; int saved_input_radix = input_radix; - if (variable_editable (var) && !var->error) + if (var->value != NULL && variable_editable (var) && !var->error) { char *s = expression; int i; - value_ptr temp; input_radix = 10; /* ALWAYS reset to decimal temporarily */ if (!gdb_parse_exp_1 (&s, 0, 0, &exp)) @@ -787,40 +773,12 @@ varobj_set_value (struct varobj *var, char *expression) if (!gdb_evaluate_expression (exp, &value)) { /* We cannot proceed without a valid expression. */ - FREEIF (exp); + xfree (exp); return 0; } - /* If our parent is "public", "private", or "protected", we could - be asking to modify the value of a baseclass. If so, we need to - adjust our address by the offset of our baseclass in the subclass, - since VALUE_ADDRESS (var->value) points at the start of the subclass. - For some reason, value_cast doesn't take care of this properly. */ - temp = var->value; - if (var->parent != NULL && CPLUS_FAKE_CHILD (var->parent)) - { - struct varobj *super, *sub; - struct type *type; - super = var->parent->parent; - sub = super->parent; - if (sub != NULL) - { - /* Yes, it is a baseclass */ - type = get_type_deref (sub); - - if (super->index < TYPE_N_BASECLASSES (type)) - { - temp = value_copy (var->value); - for (i = 0; i < super->index; i++) - offset += TYPE_LENGTH (TYPE_FIELD_TYPE (type, i)); - } - } - } - - VALUE_ADDRESS (temp) += offset; - if (!gdb_value_assign (temp, value, &val)) + if (!gdb_value_assign (var->value, value, &val)) return 0; - VALUE_ADDRESS (val) -= offset; value_free (var->value); release_value (val); var->value = val; @@ -855,8 +813,9 @@ varobj_list (struct varobj ***varlist) *cv = NULL; if (mycount || (croot != NULL)) - warning ("varobj_list: assertion failed - wrong tally of root vars (%d:%d)", - rootcount, mycount); + warning + ("varobj_list: assertion failed - wrong tally of root vars (%d:%d)", + rootcount, mycount); return rootcount; } @@ -871,10 +830,14 @@ varobj_list (struct varobj ***varlist) -2 if the type 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 + returns -2, then it has done this and VARP will be modified + to point to the new varobj. */ int -varobj_update (struct varobj *var, struct varobj ***changelist) +varobj_update (struct varobj **varp, struct varobj ***changelist) { int changed = 0; int type_changed; @@ -883,8 +846,8 @@ varobj_update (struct varobj *var, struct varobj ***changelist) int error2; struct varobj *v; struct varobj **cv; - struct varobj **templist; - value_ptr new; + struct varobj **templist = NULL; + struct value *new; struct vstack *stack = NULL; struct vstack *result = NULL; struct frame_info *old_fi; @@ -894,7 +857,7 @@ varobj_update (struct varobj *var, struct varobj ***changelist) return -1; /* Only root variables can be updated... */ - if (var->root->rootvar != var) + if ((*varp)->root->rootvar != *varp) /* Not a root var */ return -1; @@ -908,10 +871,10 @@ varobj_update (struct varobj *var, struct varobj ***changelist) value_of_root variable dispose of the varobj if the type has changed. */ type_changed = 1; - new = value_of_root (&var, &type_changed); + new = value_of_root (varp, &type_changed); if (new == NULL) { - var->error = 1; + (*varp)->error = 1; return -1; } @@ -922,34 +885,35 @@ varobj_update (struct varobj *var, struct varobj ***changelist) them note that it's changed. */ if (type_changed) { - vpush (&result, var); + vpush (&result, *varp); changed++; } /* If values are not equal, note that it's changed. There a couple of exceptions here, though. We don't want some types to be reported as "changed". */ - else if (type_changeable (var) && !my_value_equal (var->value, new, &error2)) + else if (type_changeable (*varp) + && !my_value_equal ((*varp)->value, new, &error2)) { - vpush (&result, var); + vpush (&result, *varp); changed++; /* error2 replaces var->error since this new value WILL replace the old one. */ - var->error = error2; + (*varp)->error = error2; } /* We must always keep around the new value for this root variable expression, or we lose the updated children! */ - value_free (var->value); - var->value = new; + value_free ((*varp)->value); + (*varp)->value = new; /* Initialize a stack */ vpush (&stack, NULL); /* Push the root's children */ - if (var->children != NULL) + if ((*varp)->children != NULL) { struct varobj_child *c; - for (c = var->children; c != NULL; c = c->next) + for (c = (*varp)->children; c != NULL; c = c->next) vpush (&stack, c->child); } @@ -1013,13 +977,13 @@ varobj_update (struct varobj *var, struct varobj ***changelist) if (changed > 1) { /* Now we revert the order. */ - for (i=0; i < changed; i++) - *(*changelist + i) = *(templist + changed -1 - i); + for (i = 0; i < changed; i++) + *(*changelist + i) = *(templist + changed - 1 - i); *(*changelist + changed) = NULL; } /* Restore selected frame */ - select_frame (old_fi, -1); + select_frame (old_fi); if (type_changed) return -2; @@ -1051,8 +1015,9 @@ delete_variable (struct cpstack **resultp, struct varobj *var, and the parent is not removed we dump core. It must be always initially called with remove_from_parent_p set */ static void -delete_variable_1 (struct cpstack **resultp, int *delcountp, struct varobj *var, - int only_children_p, int remove_from_parent_p) +delete_variable_1 (struct cpstack **resultp, int *delcountp, + struct varobj *var, int only_children_p, + int remove_from_parent_p) { struct varobj_child *vc; struct varobj_child *next; @@ -1064,7 +1029,7 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp, struct varobj *var, vc->child->parent = NULL; delete_variable_1 (resultp, delcountp, vc->child, 0, only_children_p); next = vc->next; - free (vc); + xfree (vc); } /* if we were called to delete only the children we are done here */ @@ -1076,7 +1041,7 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp, struct varobj *var, yet been installed, don't report it, it belongs to the caller... */ if (var->obj_name != NULL) { - cppush (resultp, strdup (var->obj_name)); + cppush (resultp, xstrdup (var->obj_name)); *delcountp = *delcountp + 1; } @@ -1085,12 +1050,11 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp, struct varobj *var, (as indicated by remove_from_parent_p) we don't bother doing an expensive list search to find the element to remove when we are discarding the list afterwards */ - if ((remove_from_parent_p) && - (var->parent != NULL)) + if ((remove_from_parent_p) && (var->parent != NULL)) { remove_child_from_parent (var->parent, var); } - + if (var->obj_name != NULL) uninstall_variable (var); @@ -1172,7 +1136,9 @@ uninstall_variable (struct varobj *var) if (cv == NULL) { - warning ("Assertion failed: Could not find variable object \"%s\" to delete", var->obj_name); + warning + ("Assertion failed: Could not find variable object \"%s\" to delete", + var->obj_name); return; } @@ -1181,7 +1147,7 @@ uninstall_variable (struct varobj *var) else prev->next = cv->next; - free (cv); + xfree (cv); /* If root, remove varobj from root list */ if (var->root->rootvar == var) @@ -1200,7 +1166,9 @@ uninstall_variable (struct varobj *var) } if (cr == NULL) { - warning ("Assertion failed: Could not find varobj \"%s\" in root list", var->obj_name); + warning + ("Assertion failed: Could not find varobj \"%s\" in root list", + var->obj_name); return; } if (prer == NULL) @@ -1216,9 +1184,7 @@ uninstall_variable (struct varobj *var) /* Does a child with the name NAME exist in VAR? If so, return its data. If not, return NULL. */ static struct varobj * -child_exists (var, name) - struct varobj *var; /* Parent */ - char *name; /* name of child */ +child_exists (struct varobj *var, char *name) { struct varobj_child *vc; @@ -1244,12 +1210,13 @@ create_child (struct varobj *parent, int index, char *name) child->name = name; child->index = index; child->value = value_of_child (parent, index); - if (child->value == NULL || parent->error) + if ((!CPLUS_FAKE_CHILD(child) && child->value == NULL) || parent->error) child->error = 1; child->parent = parent; child->root = parent->root; - childs_name = (char *) xmalloc ((strlen (parent->obj_name) + strlen (name) + 2) - * sizeof (char)); + childs_name = + (char *) xmalloc ((strlen (parent->obj_name) + strlen (name) + 2) * + sizeof (char)); sprintf (childs_name, "%s.%s", parent->obj_name, name); child->obj_name = childs_name; install_variable (child); @@ -1354,12 +1321,12 @@ free_variable (struct varobj *var) if (var->root->rootvar == var) { free_current_contents ((char **) &var->root->exp); - FREEIF (var->root); + xfree (var->root); } - FREEIF (var->name); - FREEIF (var->obj_name); - FREEIF (var); + xfree (var->name); + xfree (var->obj_name); + xfree (var); } static void @@ -1431,7 +1398,7 @@ variable_default_display (struct varobj *var) one is "safe" -- it NEVER longjmps. It determines if the VAR's value is the same as VAL2. */ static int -my_value_equal (value_ptr val1, value_ptr val2, int *error2) +my_value_equal (struct value *val1, struct value *val2, int *error2) { int r, err1, err2; @@ -1508,7 +1475,7 @@ vpop (struct vstack **pstack) s = *pstack; v = s->var; *pstack = (*pstack)->next; - free (s); + xfree (s); return v; } @@ -1538,7 +1505,7 @@ cppop (struct cpstack **pstack) s = *pstack; v = s->name; *pstack = (*pstack)->next; - free (s); + xfree (s); return v; } @@ -1597,7 +1564,7 @@ name_of_child (struct varobj *var, int index) return (*var->root->lang->name_of_child) (var, index); } -/* What is the value_ptr of the root variable VAR? +/* What is the ``struct value *'' 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 @@ -1607,7 +1574,7 @@ name_of_child (struct varobj *var, int index) 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 +static struct value * value_of_root (struct varobj **var_handle, int *type_changed) { struct varobj *var; @@ -1635,7 +1602,7 @@ value_of_root (struct varobj **var_handle, int *type_changed) return NULL; } new_type = varobj_get_type (tmp_var); - if (strcmp(old_type, new_type) == 0) + if (strcmp (old_type, new_type) == 0) { varobj_delete (tmp_var, NULL, 0); *type_changed = 0; @@ -1644,16 +1611,17 @@ value_of_root (struct varobj **var_handle, int *type_changed) { if (*type_changed) { - tmp_var->obj_name = + tmp_var->obj_name = savestring (var->obj_name, strlen (var->obj_name)); - uninstall_variable (var); + varobj_delete (var, NULL, 0); } else { - tmp_var->obj_name = varobj_gen_name (); + tmp_var->obj_name = varobj_gen_name (); } install_variable (tmp_var); *var_handle = tmp_var; + var = *var_handle; *type_changed = 1; } } @@ -1665,17 +1633,23 @@ value_of_root (struct varobj **var_handle, int *type_changed) return (*var->root->lang->value_of_root) (var_handle); } -/* What is the value_ptr for the INDEX'th child of PARENT? */ -static value_ptr +/* What is the ``struct value *'' for the INDEX'th child of PARENT? */ +static struct value * value_of_child (struct varobj *parent, int index) { - value_ptr value; + struct value *value; value = (*parent->root->lang->value_of_child) (parent, index); /* If we're being lazy, fetch the real value of the variable. */ if (value != NULL && VALUE_LAZY (value)) - gdb_value_fetch_lazy (value); + { + /* If we fail to fetch the value of the child, return + NULL so that callers notice that we're leaving an + error message. */ + if (!gdb_value_fetch_lazy (value)) + value = NULL; + } return value; } @@ -1725,14 +1699,14 @@ type_changeable (struct varobj *var) switch (TYPE_CODE (type)) { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_ARRAY: - r = 0; - break; + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_ARRAY: + r = 0; + break; - default: - r = 1; + default: + r = 1; } return r; @@ -1754,7 +1728,7 @@ c_number_of_children (struct varobj *var) { case TYPE_CODE_ARRAY: if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (target) > 0 - && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED) + && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED) children = TYPE_LENGTH (type) / TYPE_LENGTH (target); else children = -1; @@ -1768,7 +1742,13 @@ c_number_of_children (struct varobj *var) case TYPE_CODE_PTR: /* This is where things get compilcated. All pointers have one child. Except, of course, for struct and union ptr, which we automagically - dereference for the user and function ptrs, which have no children. */ + dereference for the user and function ptrs, which have no children. + We also don't dereference void* as we don't know what to show. + We can show char* so we allow it to be dereferenced. If you decide + to test for it, please mind that a little magic is necessary to + properly identify it: char* has TYPE_CODE == TYPE_CODE_INT and + TYPE_NAME == "char" */ + switch (TYPE_CODE (target)) { case TYPE_CODE_STRUCT: @@ -1777,17 +1757,12 @@ c_number_of_children (struct varobj *var) break; case TYPE_CODE_FUNC: + case TYPE_CODE_VOID: children = 0; break; default: - /* Don't dereference char* or void*. */ - if (TYPE_NAME (target) != NULL - && (STREQ (TYPE_NAME (target), "char") - || STREQ (TYPE_NAME (target), "void"))) - children = 0; - else - children = 1; + children = 1; } break; @@ -1845,7 +1820,8 @@ c_name_of_child (struct varobj *parent, int index) break; default: - name = (char *) xmalloc ((strlen (parent->name) + 2) * sizeof (char)); + name = + (char *) xmalloc ((strlen (parent->name) + 2) * sizeof (char)); sprintf (name, "*%s", parent->name); break; } @@ -1859,10 +1835,10 @@ c_name_of_child (struct varobj *parent, int index) return name; } -static value_ptr +static struct value * c_value_of_root (struct varobj **var_handle) { - value_ptr new_val; + struct value *new_val; struct varobj *var = *var_handle; struct frame_info *fi; int within_scope; @@ -1872,38 +1848,38 @@ c_value_of_root (struct varobj **var_handle) /* 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); + select_frame (fi); } - + 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 */ + 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) */ + 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... */ + comment on value_fetch_lazy() says it is only + called from the macro... */ if (!gdb_value_fetch_lazy (new_val)) var->error = 1; else @@ -1912,7 +1888,7 @@ c_value_of_root (struct varobj **var_handle) } else var->error = 1; - + release_value (new_val); return new_val; } @@ -1920,10 +1896,12 @@ c_value_of_root (struct varobj **var_handle) return NULL; } -static value_ptr +static struct value * c_value_of_child (struct varobj *parent, int index) { - value_ptr value, temp, indval; + struct value *value; + struct value *temp; + struct value *indval; struct type *type, *target; char *name; @@ -1939,7 +1917,7 @@ c_value_of_child (struct varobj *parent, int index) { case TYPE_CODE_ARRAY: #if 0 - /* This breaks if the array lives in a (vector) register. */ + /* This breaks if the array lives in a (vector) register. */ value = value_slice (temp, index, 1); temp = value_coerce_array (value); gdb_value_ind (temp, &value); @@ -1951,7 +1929,7 @@ c_value_of_child (struct varobj *parent, int index) case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - value = value_struct_elt (&temp, NULL, name, NULL, "vstructure"); + gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure"); break; case TYPE_CODE_PTR: @@ -1959,7 +1937,7 @@ c_value_of_child (struct varobj *parent, int index) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - value = value_struct_elt (&temp, NULL, name, NULL, "vstructure"); + gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure"); break; default: @@ -1976,6 +1954,7 @@ c_value_of_child (struct varobj *parent, int index) if (value != NULL) release_value (value); + xfree (name); return value; } @@ -2018,6 +1997,7 @@ c_type_of_child (struct varobj *parent, int index) break; } + xfree (name); return type; } @@ -2045,16 +2025,6 @@ static char * c_value_of_variable (struct varobj *var) { struct type *type; - value_ptr val; - - if (var->value != NULL) - val = var->value; - else - { - /* This can happen if we attempt to get the value of a struct - member when the parent is an invalid pointer. */ - return xstrdup ("???"); - } /* BOGUS: if val_print sees a struct/class, it will print out its children instead of "{...}" */ @@ -2081,13 +2051,24 @@ c_value_of_variable (struct varobj *var) struct cleanup *old_chain = make_cleanup_ui_file_delete (stb); char *thevalue; - if (VALUE_LAZY (val)) - gdb_value_fetch_lazy (val); - val_print (VALUE_TYPE (val), VALUE_CONTENTS_RAW (val), 0, - VALUE_ADDRESS (val), - stb, format_code[(int) var->format], 1, 0, 0); - thevalue = ui_file_xstrdup (stb, &dummy); - do_cleanups (old_chain); + if (var->value == NULL) + { + /* This can happen if we attempt to get the value of a struct + member when the parent is an invalid pointer. This is an + error condition, so we should tell the caller. */ + return NULL; + } + else + { + if (VALUE_LAZY (var->value)) + gdb_value_fetch_lazy (var->value); + val_print (VALUE_TYPE (var->value), VALUE_CONTENTS_RAW (var->value), 0, + VALUE_ADDRESS (var->value), + stb, format_code[(int) var->format], 1, 0, 0); + thevalue = ui_file_xstrdup (stb, &dummy); + do_cleanups (old_chain); + } + return thevalue; } /* break; */ @@ -2111,7 +2092,7 @@ cplus_number_of_children (struct varobj *var) type = get_type_deref (var); if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) || - ((TYPE_CODE (type)) == TYPE_CODE_UNION)) + ((TYPE_CODE (type)) == TYPE_CODE_UNION)) { int kids[3]; @@ -2156,9 +2137,7 @@ cplus_number_of_children (struct varobj *var) That means we need to descend into all baseclasses and find out how many are there, too. */ static void -cplus_class_num_children (type, children) - struct type *type; - int children[3]; +cplus_class_num_children (struct type *type, int children[3]) { int i; @@ -2169,8 +2148,7 @@ cplus_class_num_children (type, children) for (i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); i++) { /* If we have a virtual table pointer, omit it. */ - if (TYPE_VPTR_BASETYPE (type) == type - && TYPE_VPTR_FIELDNO (type) == i) + if (TYPE_VPTR_BASETYPE (type) == type && TYPE_VPTR_FIELDNO (type) == i) continue; if (TYPE_FIELD_PROTECTED (type, i)) @@ -2212,9 +2190,16 @@ cplus_name_of_child (struct varobj *parent, int index) if (CPLUS_FAKE_CHILD (parent)) { + int i; + + /* Skip over vptr, if it exists. */ + if (TYPE_VPTR_BASETYPE (type) == type + && index >= TYPE_VPTR_FIELDNO (type)) + index++; + /* FIXME: This assumes that type orders inherited, public, private, protected */ - int i = index + TYPE_N_BASECLASSES (type); + i = index + TYPE_N_BASECLASSES (type); if (STREQ (parent->name, "private") || STREQ (parent->name, "protected")) i += children[v_public]; if (STREQ (parent->name, "protected")) @@ -2271,18 +2256,17 @@ cplus_name_of_child (struct varobj *parent, int index) return name; } -static value_ptr +static struct value * cplus_value_of_root (struct varobj **var_handle) { return c_value_of_root (var_handle); } -static value_ptr +static struct value * cplus_value_of_child (struct varobj *parent, int index) { struct type *type; - value_ptr value; - char *name; + struct value *value; if (CPLUS_FAKE_CHILD (parent)) type = get_type_deref (parent->parent); @@ -2290,17 +2274,25 @@ cplus_value_of_child (struct varobj *parent, int index) type = get_type_deref (parent); value = NULL; - name = name_of_child (parent, index); if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) || ((TYPE_CODE (type)) == TYPE_CODE_UNION)) { if (CPLUS_FAKE_CHILD (parent)) { - value_ptr temp = parent->parent->value; - value = value_struct_elt (&temp, NULL, name, - NULL, "cplus_structure"); - release_value (value); + char *name; + struct value *temp = parent->parent->value; + + if (temp == NULL) + return NULL; + + name = name_of_child (parent, index); + gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, + "cplus_structure"); + if (value != NULL) + release_value (value); + + xfree (name); } else if (index >= TYPE_N_BASECLASSES (type)) { @@ -2312,16 +2304,28 @@ cplus_value_of_child (struct varobj *parent, int index) /* Baseclass */ if (parent->value != NULL) { - value_ptr temp; + struct value *temp = NULL; if (TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_PTR || TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_REF) - gdb_value_ind (parent->value, &temp); + { + if (!gdb_value_ind (parent->value, &temp)) + return NULL; + } else temp = parent->value; - value = value_cast (TYPE_FIELD_TYPE (type, index), temp); - release_value (value); + if (temp != NULL) + { + value = value_cast (TYPE_FIELD_TYPE (type, index), temp); + release_value (value); + } + else + { + /* We failed to evaluate the parent's value, so don't even + bother trying to evaluate this child. */ + return NULL; + } } } } @@ -2337,21 +2341,31 @@ cplus_type_of_child (struct varobj *parent, int index) { struct type *type, *t; - t = get_type_deref (parent); + if (CPLUS_FAKE_CHILD (parent)) + { + /* Looking for the type of a child of public, private, or protected. */ + t = get_type_deref (parent->parent); + } + else + t = get_type_deref (parent); + type = NULL; switch (TYPE_CODE (t)) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - if (index >= TYPE_N_BASECLASSES (t)) + if (CPLUS_FAKE_CHILD (parent)) { - /* special */ - return NULL; + char *name = cplus_name_of_child (parent, index); + type = lookup_struct_elt_type (t, name, 0); + xfree (name); } + else if (index < TYPE_N_BASECLASSES (t)) + type = TYPE_FIELD_TYPE (t, index); else { - /* Baseclass */ - type = TYPE_FIELD_TYPE (t, index); + /* special */ + return NULL; } break; @@ -2433,13 +2447,13 @@ java_name_of_child (struct varobj *parent, int index) return name; } -static value_ptr +static struct value * java_value_of_root (struct varobj **var_handle) { return cplus_value_of_root (var_handle); } -static value_ptr +static struct value * java_value_of_child (struct varobj *parent, int index) { return cplus_value_of_child (parent, index); @@ -2472,10 +2486,7 @@ _initialize_varobj (void) varobj_table = xmalloc (sizeof_table); memset (varobj_table, 0, sizeof_table); - add_show_from_set ( - add_set_cmd ("debugvarobj", class_maintenance, var_zinteger, - (char *) &varobjdebug, - "Set varobj debugging.\n\ + add_show_from_set (add_set_cmd ("debugvarobj", class_maintenance, var_zinteger, (char *) &varobjdebug, "Set varobj debugging.\n\ When non-zero, varobj debugging is enabled.", &setlist), - &showlist); + &showlist); }