diff options
Diffstat (limited to 'gdb/varobj.c')
-rw-r--r-- | gdb/varobj.c | 2492 |
1 files changed, 0 insertions, 2492 deletions
diff --git a/gdb/varobj.c b/gdb/varobj.c deleted file mode 100644 index f56b7aa1fd1..00000000000 --- a/gdb/varobj.c +++ /dev/null @@ -1,2492 +0,0 @@ -/* Implementation of the GDB variable objects API. - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "value.h" -#include "expression.h" -#include "frame.h" -#include "language.h" -#include "wrapper.h" -#include "gdbcmd.h" -#include <math.h> - -#include "varobj.h" - -/* Non-zero if we want to see trace of varobj level stuff. */ - -int varobjdebug = 0; - -/* String representations of gdb's format codes */ -char *varobj_format_string[] = - { "natural", "binary", "decimal", "hexadecimal", "octal" }; - -/* String representations of gdb's known languages */ -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; - - /* Block for which this expression is valid */ - struct block *valid_block; - - /* 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; - - /* The varobj for this root node. */ - struct varobj *rootvar; - - /* 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; - - /* 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; - - /* The type of this variable. This may NEVER be NULL. */ - struct type *type; - - /* 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; - - /* 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; - - /* 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; - - /* 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 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 cpstack -{ - char *name; - struct cpstack *next; -}; - -/* A list of varobjs */ - -struct vlist -{ - struct varobj *var; - struct vlist *next; -}; - -/* Private function prototypes */ - -/* Helper functions for the above subcommands. */ - -static int delete_variable (struct cpstack **, struct varobj *, int); - -static void delete_variable_1 (struct cpstack **, int *, - struct varobj *, int, int); - -static int install_variable (struct varobj *); - -static void uninstall_variable (struct varobj *); - -static struct varobj *child_exists (struct varobj *, char *); - -static struct varobj *create_child (struct varobj *, int, char *); - -static void save_child_in_parent (struct varobj *, struct varobj *); - -static void remove_child_from_parent (struct varobj *, struct varobj *); - -/* Utility routines */ - -static struct varobj *new_variable (void); - -static struct varobj *new_root_variable (void); - -static void free_variable (struct varobj *var); - -static struct cleanup *make_cleanup_free_variable (struct varobj *var); - -static struct type *get_type (struct varobj *var); - -static struct type *get_type_deref (struct varobj *var); - -static struct type *get_target_type (struct type *); - -static enum varobj_display_formats variable_default_display (struct varobj *); - -static int my_value_equal (struct value *, struct value *, int *); - -static void vpush (struct vstack **pstack, struct varobj *var); - -static struct varobj *vpop (struct vstack **pstack); - -static void cppush (struct cpstack **pstack, char *name); - -static char *cppop (struct cpstack **pstack); - -/* Language-specific routines. */ - -static enum varobj_languages variable_language (struct varobj *var); - -static int number_of_children (struct varobj *); - -static char *name_of_variable (struct varobj *); - -static char *name_of_child (struct varobj *, int); - -static struct value *value_of_root (struct varobj **var_handle, int *); - -static struct value *value_of_child (struct varobj *parent, int index); - -static struct type *type_of_child (struct varobj *var); - -static int variable_editable (struct varobj *var); - -static char *my_value_of_variable (struct varobj *var); - -static int type_changeable (struct varobj *var); - -/* C implementation */ - -static int c_number_of_children (struct varobj *var); - -static char *c_name_of_variable (struct varobj *parent); - -static char *c_name_of_child (struct varobj *parent, int index); - -static struct value *c_value_of_root (struct varobj **var_handle); - -static struct value *c_value_of_child (struct varobj *parent, int index); - -static struct type *c_type_of_child (struct varobj *parent, int index); - -static int c_variable_editable (struct varobj *var); - -static char *c_value_of_variable (struct varobj *var); - -/* C++ implementation */ - -static int cplus_number_of_children (struct varobj *var); - -static void cplus_class_num_children (struct type *type, int children[3]); - -static char *cplus_name_of_variable (struct varobj *parent); - -static char *cplus_name_of_child (struct varobj *parent, int index); - -static struct value *cplus_value_of_root (struct varobj **var_handle); - -static struct value *cplus_value_of_child (struct varobj *parent, int index); - -static struct type *cplus_type_of_child (struct varobj *parent, int index); - -static int cplus_variable_editable (struct varobj *var); - -static char *cplus_value_of_variable (struct varobj *var); - -/* Java implementation */ - -static int java_number_of_children (struct varobj *var); - -static char *java_name_of_variable (struct varobj *parent); - -static char *java_name_of_child (struct varobj *parent, int index); - -static struct value *java_value_of_root (struct varobj **var_handle); - -static struct value *java_value_of_child (struct varobj *parent, int index); - -static struct type *java_type_of_child (struct varobj *parent, int index); - -static int java_variable_editable (struct varobj *var); - -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 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 of the INDEX'th child of PARENT. */ - char *(*name_of_child) (struct varobj * parent, int index); - - /* The ``struct value *'' of the root variable ROOT. */ - struct value *(*value_of_root) (struct varobj ** root_handle); - - /* 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); - - /* Is VAR editable? */ - int (*variable_editable) (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)] = { - /* 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} - , - /* 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} - , - /* 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} - , - /* 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} -}; - -/* A little convenience enum for dealing with C++/Java */ -enum vsections -{ - 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' }; - -/* Header of the list of root variable objects */ -static struct varobj_root *rootlist; -static int rootcount = 0; /* number of root varobjs in the list */ - -/* Prime number indicating the number of buckets in the hash table */ -/* A prime large enough to avoid too many colisions */ -#define VAROBJ_TABLE_SIZE 227 - -/* Pointer to the varobj hash table (built at run time) */ -static struct vlist **varobj_table; - -/* Is the variable X one of our "fake" children? */ -#define CPLUS_FAKE_CHILD(x) \ -((x) != NULL && (x)->type == NULL && (x)->value == NULL) - - -/* API Implementation */ - -/* Creates a varobj (not its children) */ - -struct varobj * -varobj_create (char *objname, - char *expression, CORE_ADDR frame, enum varobj_type type) -{ - struct varobj *var; - struct frame_info *fi; - struct frame_info *old_fi = NULL; - struct block *block; - struct cleanup *old_chain; - - /* Fill out a varobj structure for the (root) variable being constructed. */ - var = new_root_variable (); - old_chain = make_cleanup_free_variable (var); - - if (expression != NULL) - { - char *p; - enum varobj_languages lang; - - /* Parse and evaluate the expression, filling in as much - of the variable's data as possible */ - - /* Allow creator to specify context of variable */ - 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; - /* 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) - { - do_cleanups (old_chain); - fprintf_unfiltered (gdb_stderr, - "Attempt to use a type name as an expression."); - return NULL; - } - - var->format = variable_default_display (var); - var->root->valid_block = innermost_block; - var->name = savestring (expression, strlen (expression)); - - /* When the frame is different from the current frame, - we must select the appropriate frame before parsing - the expression, otherwise the value will not be current. - Since select_frame is so benign, just call it for all cases. */ - if (fi != NULL) - { - var->root->frame = FRAME_FP (fi); - old_fi = selected_frame; - select_frame (fi, -1); - } - - /* We definitively need to catch errors here. - If evaluate_expression succeeds we got the value we wanted. - But if it fails, we still go on with a call to evaluate_type() */ - if (gdb_evaluate_expression (var->root->exp, &var->value)) - { - /* no error */ - release_value (var->value); - if (VALUE_LAZY (var->value)) - gdb_value_fetch_lazy (var->value); - } - else - var->value = evaluate_type (var->root->exp); - - var->type = VALUE_TYPE (var->value); - - /* Set language info */ - lang = variable_language (var); - var->root->lang = languages[lang]; - - /* Set ourselves as our root */ - var->root->rootvar = var; - - /* Reset the selected frame */ - if (fi != NULL) - select_frame (old_fi, -1); - } - - /* 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)); - - /* If a varobj name is duplicated, the install will fail so - we must clenup */ - if (!install_variable (var)) - { - do_cleanups (old_chain); - return NULL; - } - } - - discard_cleanups (old_chain); - return var; -} - -/* Generates an unique name that can be used for a varobj */ - -char * -varobj_gen_name (void) -{ - static int id = 0; - char obj_name[31]; - - /* generate a name for this object */ - id++; - sprintf (obj_name, "var%d", id); - - return xstrdup (obj_name); -} - -/* Given an "objname", returns the pointer to the corresponding varobj - or NULL if not found */ - -struct varobj * -varobj_get_handle (char *objname) -{ - struct vlist *cv; - const char *chp; - unsigned int index = 0; - unsigned int i = 1; - - for (chp = objname; *chp; chp++) - { - index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE; - } - - cv = *(varobj_table + index); - while ((cv != NULL) && (strcmp (cv->var->obj_name, objname) != 0)) - cv = cv->next; - - if (cv == NULL) - error ("Variable object not found"); - - return cv->var; -} - -/* Given the handle, return the name of the object */ - -char * -varobj_get_objname (struct varobj *var) -{ - return var->obj_name; -} - -/* Given the handle, return the expression represented by the object */ - -char * -varobj_get_expression (struct varobj *var) -{ - return name_of_variable (var); -} - -/* Deletes a varobj and all its children if only_children == 0, - otherwise deletes only the children; returns a malloc'ed list of all the - (malloc'ed) names of the variables that have been deleted (NULL terminated) */ - -int -varobj_delete (struct varobj *var, char ***dellist, int only_children) -{ - int delcount; - int mycount; - struct cpstack *result = NULL; - char **cp; - - /* Initialize a stack for temporary results */ - cppush (&result, NULL); - - if (only_children) - /* Delete only the variable children */ - delcount = delete_variable (&result, var, 1 /* only the children */ ); - else - /* Delete the variable and all its children */ - delcount = delete_variable (&result, var, 0 /* parent+children */ ); - - /* We may have been asked to return a list of what has been deleted */ - if (dellist != NULL) - { - *dellist = xmalloc ((delcount + 1) * sizeof (char *)); - - cp = *dellist; - mycount = delcount; - *cp = cppop (&result); - while ((*cp != NULL) && (mycount > 0)) - { - mycount--; - cp++; - *cp = cppop (&result); - } - - if (mycount || (*cp != NULL)) - warning ("varobj_delete: assertion failed - mycount(=%d) <> 0", - mycount); - } - - return delcount; -} - -/* Set/Get variable object display format */ - -enum varobj_display_formats -varobj_set_display_format (struct varobj *var, - enum varobj_display_formats format) -{ - switch (format) - { - case FORMAT_NATURAL: - case FORMAT_BINARY: - case FORMAT_DECIMAL: - case FORMAT_HEXADECIMAL: - case FORMAT_OCTAL: - var->format = format; - break; - - default: - var->format = variable_default_display (var); - } - - return var->format; -} - -enum varobj_display_formats -varobj_get_display_format (struct varobj *var) -{ - return var->format; -} - -int -varobj_get_num_children (struct varobj *var) -{ - if (var->num_children == -1) - var->num_children = number_of_children (var); - - return var->num_children; -} - -/* Creates a list of the immediate children of a variable object; - the return code is the number of such children or -1 on error */ - -int -varobj_list_children (struct varobj *var, struct varobj ***childlist) -{ - struct varobj *child; - char *name; - int i; - - /* sanity check: have we been passed a pointer? */ - if (childlist == NULL) - return -1; - - *childlist = NULL; - - if (var->num_children == -1) - var->num_children = number_of_children (var); - - /* List of children */ - *childlist = xmalloc ((var->num_children + 1) * sizeof (struct varobj *)); - - for (i = 0; i < var->num_children; i++) - { - /* Mark as the end in case we bail out */ - *((*childlist) + i) = NULL; - - /* check if child exists, if not create */ - name = name_of_child (var, i); - child = child_exists (var, name); - if (child == NULL) - child = create_child (var, i, name); - - *((*childlist) + i) = child; - } - - /* End of list is marked by a NULL pointer */ - *((*childlist) + i) = NULL; - - return var->num_children; -} - -/* Obtain the type of an object Variable as a string similar to the one gdb - prints on the console */ - -char * -varobj_get_type (struct varobj *var) -{ - struct value *val; - struct cleanup *old_chain; - struct ui_file *stb; - char *thetype; - long length; - - /* For the "fake" variables, do not return a type. (It's type is - NULL, too.) */ - if (CPLUS_FAKE_CHILD (var)) - return NULL; - - stb = mem_fileopen (); - old_chain = make_cleanup_ui_file_delete (stb); - - /* 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); - - thetype = ui_file_xstrdup (stb, &length); - do_cleanups (old_chain); - return thetype; -} - -enum varobj_languages -varobj_get_language (struct varobj *var) -{ - return variable_language (var); -} - -int -varobj_get_attributes (struct varobj *var) -{ - int attributes = 0; - - if (variable_editable (var)) - /* FIXME: define masks for attributes */ - attributes |= 0x00000001; /* Editable */ - - return attributes; -} - -char * -varobj_get_value (struct varobj *var) -{ - return my_value_of_variable (var); -} - -/* Set the value of an object variable (if it is editable) to the - value of the given expression */ -/* Note: Invokes functions that can call error() */ - -int -varobj_set_value (struct varobj *var, char *expression) -{ - 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; - struct value *value; - int saved_input_radix = input_radix; - - if (var->value != NULL && variable_editable (var) && !var->error) - { - char *s = expression; - int i; - - input_radix = 10; /* ALWAYS reset to decimal temporarily */ - if (!gdb_parse_exp_1 (&s, 0, 0, &exp)) - /* We cannot proceed without a well-formed expression. */ - return 0; - if (!gdb_evaluate_expression (exp, &value)) - { - /* We cannot proceed without a valid expression. */ - xfree (exp); - return 0; - } - - if (!gdb_value_assign (var->value, value, &val)) - return 0; - value_free (var->value); - release_value (val); - var->value = val; - input_radix = saved_input_radix; - return 1; - } - - return 0; -} - -/* Returns a malloc'ed list with all root variable objects */ -int -varobj_list (struct varobj ***varlist) -{ - struct varobj **cv; - struct varobj_root *croot; - int mycount = rootcount; - - /* Alloc (rootcount + 1) entries for the result */ - *varlist = xmalloc ((rootcount + 1) * sizeof (struct varobj *)); - - cv = *varlist; - croot = rootlist; - while ((croot != NULL) && (mycount > 0)) - { - *cv = croot->rootvar; - mycount--; - cv++; - croot = croot->next; - } - /* Mark the end of the list */ - *cv = NULL; - - if (mycount || (croot != NULL)) - warning - ("varobj_list: assertion failed - wrong tally of root vars (%d:%d)", - rootcount, mycount); - - return rootcount; -} - -/* Update the values for a variable and its children. This is a - two-pronged attack. First, re-parse the value for the root's - 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... - - 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 **varp, struct varobj ***changelist) -{ - int changed = 0; - int type_changed; - int i; - int vleft; - int error2; - struct varobj *v; - struct varobj **cv; - struct varobj **templist = NULL; - struct value *new; - struct vstack *stack = NULL; - struct vstack *result = NULL; - struct frame_info *old_fi; - - /* sanity check: have we been passed a pointer? */ - if (changelist == NULL) - return -1; - - /* Only root variables can be updated... */ - if ((*varp)->root->rootvar != *varp) - /* Not a root var */ - return -1; - - /* Save the selected stack frame, since we will need to change it - in order to evaluate expressions. */ - old_fi = 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. */ - type_changed = 1; - new = value_of_root (varp, &type_changed); - if (new == NULL) - { - (*varp)->error = 1; - return -1; - } - - /* Initialize a stack for temporary results */ - vpush (&result, NULL); - - /* If this is a "use_selected_frame" varobj, and its type has changed, - them note that it's changed. */ - if (type_changed) - { - 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 (*varp) - && !my_value_equal ((*varp)->value, new, &error2)) - { - vpush (&result, *varp); - changed++; - /* error2 replaces var->error since this new value - WILL replace the old one. */ - (*varp)->error = error2; - } - - /* We must always keep around the new value for this root - variable expression, or we lose the updated children! */ - value_free ((*varp)->value); - (*varp)->value = new; - - /* Initialize a stack */ - vpush (&stack, NULL); - - /* Push the root's children */ - if ((*varp)->children != NULL) - { - struct varobj_child *c; - for (c = (*varp)->children; c != NULL; c = c->next) - vpush (&stack, c->child); - } - - /* Walk through the children, reconstructing them all. */ - v = vpop (&stack); - while (v != NULL) - { - /* Push any children */ - if (v->children != NULL) - { - struct varobj_child *c; - for (c = v->children; c != NULL; c = c->next) - vpush (&stack, c->child); - } - - /* Update this variable */ - new = value_of_child (v->parent, v->index); - if (type_changeable (v) && !my_value_equal (v->value, new, &error2)) - { - /* Note that it's changed */ - vpush (&result, v); - changed++; - } - /* error2 replaces v->error since this new value - WILL replace the old one. */ - v->error = error2; - - /* We must always keep new values, since children depend on it. */ - if (v->value != NULL) - value_free (v->value); - v->value = new; - - /* Get next child */ - v = vpop (&stack); - } - - /* Alloc (changed + 1) list entries */ - /* FIXME: add a cleanup for the allocated list(s) - because one day the select_frame called below can longjump */ - *changelist = xmalloc ((changed + 1) * sizeof (struct varobj *)); - if (changed > 1) - { - templist = xmalloc ((changed + 1) * sizeof (struct varobj *)); - cv = templist; - } - else - cv = *changelist; - - /* Copy from result stack to list */ - vleft = changed; - *cv = vpop (&result); - while ((*cv != NULL) && (vleft > 0)) - { - vleft--; - cv++; - *cv = vpop (&result); - } - if (vleft) - warning ("varobj_update: assertion failed - vleft <> 0"); - - if (changed > 1) - { - /* Now we revert the order. */ - for (i = 0; i < changed; i++) - *(*changelist + i) = *(templist + changed - 1 - i); - *(*changelist + changed) = NULL; - } - - /* Restore selected frame */ - select_frame (old_fi, -1); - - if (type_changed) - return -2; - else - return changed; -} - - -/* Helper functions */ - -/* - * Variable object construction/destruction - */ - -static int -delete_variable (struct cpstack **resultp, struct varobj *var, - int only_children_p) -{ - int delcount = 0; - - delete_variable_1 (resultp, &delcount, var, - only_children_p, 1 /* remove_from_parent_p */ ); - - return delcount; -} - -/* Delete the variable object VAR and its children */ -/* IMPORTANT NOTE: If we delete a variable which is a child - 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) -{ - struct varobj_child *vc; - struct varobj_child *next; - - /* Delete any children of this variable, too. */ - for (vc = var->children; vc != NULL; vc = next) - { - if (!remove_from_parent_p) - vc->child->parent = NULL; - delete_variable_1 (resultp, delcountp, vc->child, 0, only_children_p); - next = vc->next; - xfree (vc); - } - - /* if we were called to delete only the children we are done here */ - if (only_children_p) - return; - - /* Otherwise, add it to the list of deleted ones and proceed to do so */ - /* 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, xstrdup (var->obj_name)); - *delcountp = *delcountp + 1; - } - - /* If this variable has a parent, remove it from its parent's list */ - /* OPTIMIZATION: if the parent of this variable is also being deleted, - (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)) - { - remove_child_from_parent (var->parent, var); - } - - if (var->obj_name != NULL) - uninstall_variable (var); - - /* Free memory associated with this variable */ - free_variable (var); -} - -/* Install the given variable VAR with the object name VAR->OBJ_NAME. */ -static int -install_variable (struct varobj *var) -{ - struct vlist *cv; - struct vlist *newvl; - const char *chp; - unsigned int index = 0; - unsigned int i = 1; - - for (chp = var->obj_name; *chp; chp++) - { - index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE; - } - - cv = *(varobj_table + index); - while ((cv != NULL) && (strcmp (cv->var->obj_name, var->obj_name) != 0)) - cv = cv->next; - - if (cv != NULL) - error ("Duplicate variable object name"); - - /* Add varobj to hash table */ - newvl = xmalloc (sizeof (struct vlist)); - newvl->next = *(varobj_table + index); - newvl->var = var; - *(varobj_table + index) = newvl; - - /* If root, add varobj to root list */ - if (var->root->rootvar == var) - { - /* Add to list of root variables */ - if (rootlist == NULL) - var->root->next = NULL; - else - var->root->next = rootlist; - rootlist = var->root; - rootcount++; - } - - return 1; /* OK */ -} - -/* Unistall the object VAR. */ -static void -uninstall_variable (struct varobj *var) -{ - struct vlist *cv; - struct vlist *prev; - struct varobj_root *cr; - struct varobj_root *prer; - const char *chp; - unsigned int index = 0; - unsigned int i = 1; - - /* Remove varobj from hash table */ - for (chp = var->obj_name; *chp; chp++) - { - index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE; - } - - cv = *(varobj_table + index); - prev = NULL; - while ((cv != NULL) && (strcmp (cv->var->obj_name, var->obj_name) != 0)) - { - prev = cv; - cv = cv->next; - } - - if (varobjdebug) - fprintf_unfiltered (gdb_stdlog, "Deleting %s\n", var->obj_name); - - if (cv == NULL) - { - warning - ("Assertion failed: Could not find variable object \"%s\" to delete", - var->obj_name); - return; - } - - if (prev == NULL) - *(varobj_table + index) = cv->next; - else - prev->next = cv->next; - - xfree (cv); - - /* If root, remove varobj from root list */ - if (var->root->rootvar == var) - { - /* Remove from list of root variables */ - if (rootlist == var->root) - rootlist = var->root->next; - else - { - prer = NULL; - cr = rootlist; - while ((cr != NULL) && (cr->rootvar != var)) - { - prer = cr; - cr = cr->next; - } - if (cr == NULL) - { - warning - ("Assertion failed: Could not find varobj \"%s\" in root list", - var->obj_name); - return; - } - if (prer == NULL) - rootlist = NULL; - else - prer->next = cr->next; - } - rootcount--; - } - -} - -/* Does a child with the name NAME exist in VAR? If so, return its data. - If not, return NULL. */ -static struct varobj * -child_exists (struct varobj *var, char *name) -{ - struct varobj_child *vc; - - for (vc = var->children; vc != NULL; vc = vc->next) - { - if (STREQ (vc->child->name, name)) - return vc->child; - } - - return NULL; -} - -/* Create and install a child of the parent of the given name */ -static struct varobj * -create_child (struct varobj *parent, int index, char *name) -{ - struct varobj *child; - char *childs_name; - - child = new_variable (); - - /* name is allocated by name_of_child */ - child->name = name; - child->index = index; - child->value = value_of_child (parent, index); - 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)); - sprintf (childs_name, "%s.%s", parent->obj_name, name); - child->obj_name = childs_name; - install_variable (child); - - /* Save a pointer to this child in the parent */ - save_child_in_parent (parent, child); - - /* Note the type of this child */ - child->type = type_of_child (child); - - return child; -} - -/* FIXME: This should be a generic add to list */ -/* Save CHILD in the PARENT's data. */ -static void -save_child_in_parent (struct varobj *parent, struct varobj *child) -{ - struct varobj_child *vc; - - /* Insert the child at the top */ - vc = parent->children; - parent->children = - (struct varobj_child *) xmalloc (sizeof (struct varobj_child)); - - parent->children->next = vc; - parent->children->child = child; -} - -/* FIXME: This should be a generic remove from list */ -/* Remove the CHILD from the PARENT's list of children. */ -static void -remove_child_from_parent (struct varobj *parent, struct varobj *child) -{ - struct varobj_child *vc, *prev; - - /* Find the child in the parent's list */ - prev = NULL; - for (vc = parent->children; vc != NULL;) - { - if (vc->child == child) - break; - prev = vc; - vc = vc->next; - } - - if (prev == NULL) - parent->children = vc->next; - else - prev->next = vc->next; - -} - - -/* - * Miscellaneous utility functions. - */ - -/* Allocate memory and initialize a new variable */ -static struct varobj * -new_variable (void) -{ - struct varobj *var; - - var = (struct varobj *) xmalloc (sizeof (struct varobj)); - var->name = NULL; - var->obj_name = NULL; - var->index = -1; - var->type = NULL; - var->value = NULL; - var->error = 0; - var->num_children = -1; - var->parent = NULL; - var->children = NULL; - var->format = 0; - var->root = NULL; - - return var; -} - -/* Allocate memory and initialize a new root variable */ -static struct varobj * -new_root_variable (void) -{ - struct varobj *var = new_variable (); - var->root = (struct varobj_root *) xmalloc (sizeof (struct varobj_root));; - var->root->lang = NULL; - 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; -} - -/* Free any allocated memory associated with VAR. */ -static void -free_variable (struct varobj *var) -{ - /* Free the expression if this is a root variable. */ - if (var->root->rootvar == var) - { - free_current_contents ((char **) &var->root->exp); - xfree (var->root); - } - - xfree (var->name); - xfree (var->obj_name); - xfree (var); -} - -static void -do_free_variable_cleanup (void *var) -{ - free_variable (var); -} - -static struct cleanup * -make_cleanup_free_variable (struct varobj *var) -{ - return make_cleanup (do_free_variable_cleanup, var); -} - -/* This returns the type of the variable. This skips past typedefs - and returns the real type of the variable. It also dereferences - pointers and references. */ -static struct type * -get_type (struct varobj *var) -{ - struct type *type; - type = var->type; - - while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF) - type = TYPE_TARGET_TYPE (type); - - return type; -} - -/* This returns the type of the variable, dereferencing pointers, too. */ -static struct type * -get_type_deref (struct varobj *var) -{ - struct type *type; - - type = get_type (var); - - if (type != NULL && (TYPE_CODE (type) == TYPE_CODE_PTR - || TYPE_CODE (type) == TYPE_CODE_REF)) - type = get_target_type (type); - - return type; -} - -/* This returns the target type (or NULL) of TYPE, also skipping - past typedefs, just like get_type (). */ -static struct type * -get_target_type (struct type *type) -{ - if (type != NULL) - { - type = TYPE_TARGET_TYPE (type); - while (type != NULL && TYPE_CODE (type) == TYPE_CODE_TYPEDEF) - type = TYPE_TARGET_TYPE (type); - } - - return type; -} - -/* What is the default display for this variable? We assume that - everything is "natural". Any exceptions? */ -static enum varobj_display_formats -variable_default_display (struct varobj *var) -{ - return FORMAT_NATURAL; -} - -/* This function is similar to gdb's value_equal, except that this - one is "safe" -- it NEVER longjmps. It determines if the VAR's - value is the same as VAL2. */ -static int -my_value_equal (struct value *val1, struct value *val2, int *error2) -{ - int r, err1, err2; - - *error2 = 0; - /* Special case: NULL values. If both are null, say - they're equal. */ - if (val1 == NULL && val2 == NULL) - return 1; - else if (val1 == NULL || val2 == NULL) - return 0; - - /* This is bogus, but unfortunately necessary. We must know - exactly what caused an error -- reading val1 or val2 -- so - that we can really determine if we think that something has changed. */ - err1 = 0; - err2 = 0; - /* We do need to catch errors here because the whole purpose - is to test if value_equal() has errored */ - if (!gdb_value_equal (val1, val1, &r)) - err1 = 1; - - if (!gdb_value_equal (val2, val2, &r)) - *error2 = err2 = 1; - - if (err1 != err2) - return 0; - - if (!gdb_value_equal (val1, val2, &r)) - { - /* An error occurred, this could have happened if - either val1 or val2 errored. ERR1 and ERR2 tell - us which of these it is. If both errored, then - we assume nothing has changed. If one of them is - valid, though, then something has changed. */ - if (err1 == err2) - { - /* both the old and new values caused errors, so - we say the value did not change */ - /* This is indeterminate, though. Perhaps we should - be safe and say, yes, it changed anyway?? */ - return 1; - } - else - { - return 0; - } - } - - return r; -} - -/* FIXME: The following should be generic for any pointer */ -static void -vpush (struct vstack **pstack, struct varobj *var) -{ - struct vstack *s; - - s = (struct vstack *) xmalloc (sizeof (struct vstack)); - s->var = var; - s->next = *pstack; - *pstack = s; -} - -/* FIXME: The following should be generic for any pointer */ -static struct varobj * -vpop (struct vstack **pstack) -{ - struct vstack *s; - struct varobj *v; - - if ((*pstack)->var == NULL && (*pstack)->next == NULL) - return NULL; - - s = *pstack; - v = s->var; - *pstack = (*pstack)->next; - xfree (s); - - return v; -} - -/* FIXME: The following should be generic for any pointer */ -static void -cppush (struct cpstack **pstack, char *name) -{ - struct cpstack *s; - - s = (struct cpstack *) xmalloc (sizeof (struct cpstack)); - s->name = name; - s->next = *pstack; - *pstack = s; -} - -/* FIXME: The following should be generic for any pointer */ -static char * -cppop (struct cpstack **pstack) -{ - struct cpstack *s; - char *v; - - if ((*pstack)->name == NULL && (*pstack)->next == NULL) - return NULL; - - s = *pstack; - v = s->name; - *pstack = (*pstack)->next; - xfree (s); - - return v; -} - -/* - * Language-dependencies - */ - -/* Common entry points */ - -/* Get the language of variable VAR. */ -static enum varobj_languages -variable_language (struct varobj *var) -{ - enum varobj_languages lang; - - switch (var->root->exp->language_defn->la_language) - { - default: - case language_c: - lang = vlang_c; - break; - case language_cplus: - lang = vlang_cplus; - break; - case language_java: - lang = vlang_java; - break; - } - - return lang; -} - -/* Return the number of children for a given variable. - The result of this function is defined by the language - implementation. The number of children returned by this function - is the number of children that the user will see in the variable - display. */ -static int -number_of_children (struct varobj *var) -{ - return (*var->root->lang->number_of_children) (var);; -} - -/* What is the expression for the root varobj VAR? Returns a malloc'd string. */ -static char * -name_of_variable (struct varobj *var) -{ - return (*var->root->lang->name_of_variable) (var); -} - -/* What is the name of the INDEX'th child of VAR? Returns a malloc'd string. */ -static char * -name_of_child (struct varobj *var, int index) -{ - return (*var->root->lang->name_of_child) (var, index); -} - -/* 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 - 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 struct value * -value_of_root (struct varobj **var_handle, int *type_changed) -{ - 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)); - varobj_delete (var, NULL, 0); - } - else - { - tmp_var->obj_name = varobj_gen_name (); - } - install_variable (tmp_var); - *var_handle = tmp_var; - var = *var_handle; - *type_changed = 1; - } - } - else - { - *type_changed = 0; - } - - return (*var->root->lang->value_of_root) (var_handle); -} - -/* What is the ``struct value *'' for the INDEX'th child of PARENT? */ -static struct value * -value_of_child (struct varobj *parent, int index) -{ - 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)) - { - /* 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; -} - -/* What is the type of VAR? */ -static struct type * -type_of_child (struct varobj *var) -{ - - /* If the child had no evaluation errors, var->value - will be non-NULL and contain a valid type. */ - if (var->value != NULL) - return VALUE_TYPE (var->value); - - /* Otherwise, we must compute the type. */ - return (*var->root->lang->type_of_child) (var->parent, var->index); -} - -/* Is this variable editable? Use the variable's type to make - this determination. */ -static int -variable_editable (struct varobj *var) -{ - return (*var->root->lang->variable_editable) (var); -} - -/* GDB already has a command called "value_of_variable". Sigh. */ -static char * -my_value_of_variable (struct varobj *var) -{ - return (*var->root->lang->value_of_variable) (var); -} - -/* Is VAR something that can change? Depending on language, - some variable's values never change. For example, - struct and unions never change values. */ -static int -type_changeable (struct varobj *var) -{ - int r; - struct type *type; - - if (CPLUS_FAKE_CHILD (var)) - return 0; - - type = get_type (var); - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_ARRAY: - r = 0; - break; - - default: - r = 1; - } - - return r; -} - -/* C */ -static int -c_number_of_children (struct varobj *var) -{ - struct type *type; - struct type *target; - int children; - - type = get_type (var); - target = get_target_type (type); - children = 0; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (target) > 0 - && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED) - children = TYPE_LENGTH (type) / TYPE_LENGTH (target); - else - children = -1; - break; - - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - children = TYPE_NFIELDS (type); - break; - - 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. - 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: - case TYPE_CODE_UNION: - children = TYPE_NFIELDS (target); - break; - - case TYPE_CODE_FUNC: - case TYPE_CODE_VOID: - children = 0; - break; - - default: - children = 1; - } - break; - - default: - /* Other types have no children */ - break; - } - - return children; -} - -static char * -c_name_of_variable (struct varobj *parent) -{ - return savestring (parent->name, strlen (parent->name)); -} - -static char * -c_name_of_child (struct varobj *parent, int index) -{ - struct type *type; - struct type *target; - char *name; - char *string; - - type = get_type (parent); - target = get_target_type (type); - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: - { - /* We never get here unless parent->num_children is greater than 0... */ - int len = 1; - while ((int) pow ((double) 10, (double) len) < index) - len++; - name = (char *) xmalloc (1 + len * sizeof (char)); - sprintf (name, "%d", index); - } - break; - - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - string = TYPE_FIELD_NAME (type, index); - name = savestring (string, strlen (string)); - break; - - case TYPE_CODE_PTR: - switch (TYPE_CODE (target)) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - string = TYPE_FIELD_NAME (target, index); - name = savestring (string, strlen (string)); - break; - - default: - name = - (char *) xmalloc ((strlen (parent->name) + 2) * sizeof (char)); - sprintf (name, "*%s", parent->name); - break; - } - break; - - default: - /* This should not happen */ - name = xstrdup ("???"); - } - - return name; -} - -static struct value * -c_value_of_root (struct varobj **var_handle) -{ - struct value *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 */ - 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... */ - if (!gdb_value_fetch_lazy (new_val)) - var->error = 1; - else - var->error = 0; - } - } - else - var->error = 1; - - release_value (new_val); - return new_val; - } - - return NULL; -} - -static struct value * -c_value_of_child (struct varobj *parent, int index) -{ - struct value *value; - struct value *temp; - struct value *indval; - struct type *type, *target; - char *name; - - type = get_type (parent); - target = get_target_type (type); - name = name_of_child (parent, index); - temp = parent->value; - value = NULL; - - if (temp != NULL) - { - switch (TYPE_CODE (type)) - { - case TYPE_CODE_ARRAY: -#if 0 - /* 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); -#else - indval = value_from_longest (builtin_type_int, (LONGEST) index); - gdb_value_subscript (temp, indval, &value); -#endif - break; - - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure"); - break; - - case TYPE_CODE_PTR: - switch (TYPE_CODE (target)) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - gdb_value_struct_elt (NULL, &value, &temp, NULL, name, NULL, "vstructure"); - break; - - default: - gdb_value_ind (temp, &value); - break; - } - break; - - default: - break; - } - } - - if (value != NULL) - release_value (value); - - xfree (name); - return value; -} - -static struct type * -c_type_of_child (struct varobj *parent, int index) -{ - struct type *type; - char *name = name_of_child (parent, index); - - switch (TYPE_CODE (parent->type)) - { - case TYPE_CODE_ARRAY: - type = TYPE_TARGET_TYPE (parent->type); - break; - - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - type = lookup_struct_elt_type (parent->type, name, 0); - break; - - case TYPE_CODE_PTR: - switch (TYPE_CODE (TYPE_TARGET_TYPE (parent->type))) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - type = lookup_struct_elt_type (parent->type, name, 0); - break; - - default: - type = TYPE_TARGET_TYPE (parent->type); - break; - } - break; - - default: - /* This should not happen as only the above types have children */ - warning ("Child of parent whose type does not allow children"); - /* FIXME: Can we still go on? */ - type = NULL; - break; - } - - xfree (name); - return type; -} - -static int -c_variable_editable (struct varobj *var) -{ - switch (TYPE_CODE (get_type (var))) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - case TYPE_CODE_ARRAY: - case TYPE_CODE_FUNC: - case TYPE_CODE_MEMBER: - case TYPE_CODE_METHOD: - return 0; - break; - - default: - return 1; - break; - } -} - -static char * -c_value_of_variable (struct varobj *var) -{ - struct type *type; - - /* BOGUS: if val_print sees a struct/class, it will print out its - children instead of "{...}" */ - type = get_type (var); - switch (TYPE_CODE (type)) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - return xstrdup ("{...}"); - /* break; */ - - case TYPE_CODE_ARRAY: - { - char number[18]; - sprintf (number, "[%d]", var->num_children); - return xstrdup (number); - } - /* break; */ - - default: - { - long dummy; - struct ui_file *stb = mem_fileopen (); - struct cleanup *old_chain = make_cleanup_ui_file_delete (stb); - char *thevalue; - - 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; */ - } -} - - -/* C++ */ - -static int -cplus_number_of_children (struct varobj *var) -{ - struct type *type; - int children, dont_know; - - dont_know = 1; - children = 0; - - if (!CPLUS_FAKE_CHILD (var)) - { - type = get_type_deref (var); - - if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) || - ((TYPE_CODE (type)) == TYPE_CODE_UNION)) - { - int kids[3]; - - cplus_class_num_children (type, kids); - if (kids[v_public] != 0) - children++; - if (kids[v_private] != 0) - children++; - if (kids[v_protected] != 0) - children++; - - /* Add any baseclasses */ - children += TYPE_N_BASECLASSES (type); - dont_know = 0; - - /* FIXME: save children in var */ - } - } - else - { - int kids[3]; - - type = get_type_deref (var->parent); - - cplus_class_num_children (type, kids); - if (STREQ (var->name, "public")) - children = kids[v_public]; - else if (STREQ (var->name, "private")) - children = kids[v_private]; - else - children = kids[v_protected]; - dont_know = 0; - } - - if (dont_know) - children = c_number_of_children (var); - - return children; -} - -/* Compute # of public, private, and protected variables in this class. - That means we need to descend into all baseclasses and find out - how many are there, too. */ -static void -cplus_class_num_children (struct type *type, int children[3]) -{ - int i; - - children[v_public] = 0; - children[v_private] = 0; - children[v_protected] = 0; - - 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) - continue; - - if (TYPE_FIELD_PROTECTED (type, i)) - children[v_protected]++; - else if (TYPE_FIELD_PRIVATE (type, i)) - children[v_private]++; - else - children[v_public]++; - } -} - -static char * -cplus_name_of_variable (struct varobj *parent) -{ - return c_name_of_variable (parent); -} - -static char * -cplus_name_of_child (struct varobj *parent, int index) -{ - char *name; - struct type *type; - int children[3]; - - if (CPLUS_FAKE_CHILD (parent)) - { - /* Looking for children of public, private, or protected. */ - type = get_type_deref (parent->parent); - } - else - type = get_type_deref (parent); - - name = NULL; - switch (TYPE_CODE (type)) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - cplus_class_num_children (type, children); - - 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 */ - i = index + TYPE_N_BASECLASSES (type); - if (STREQ (parent->name, "private") || STREQ (parent->name, "protected")) - i += children[v_public]; - if (STREQ (parent->name, "protected")) - i += children[v_private]; - - name = TYPE_FIELD_NAME (type, i); - } - else if (index < TYPE_N_BASECLASSES (type)) - name = TYPE_FIELD_NAME (type, index); - else - { - /* Everything beyond the baseclasses can - only be "public", "private", or "protected" */ - index -= TYPE_N_BASECLASSES (type); - switch (index) - { - case 0: - if (children[v_public] != 0) - { - name = "public"; - break; - } - case 1: - if (children[v_private] != 0) - { - name = "private"; - break; - } - case 2: - if (children[v_protected] != 0) - { - name = "protected"; - break; - } - default: - /* error! */ - break; - } - } - break; - - default: - break; - } - - if (name == NULL) - return c_name_of_child (parent, index); - else - { - if (name != NULL) - name = savestring (name, strlen (name)); - } - - return name; -} - -static struct value * -cplus_value_of_root (struct varobj **var_handle) -{ - return c_value_of_root (var_handle); -} - -static struct value * -cplus_value_of_child (struct varobj *parent, int index) -{ - struct type *type; - struct value *value; - - if (CPLUS_FAKE_CHILD (parent)) - type = get_type_deref (parent->parent); - else - type = get_type_deref (parent); - - value = NULL; - - if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) || - ((TYPE_CODE (type)) == TYPE_CODE_UNION)) - { - if (CPLUS_FAKE_CHILD (parent)) - { - 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)) - { - /* public, private, or protected */ - return NULL; - } - else - { - /* Baseclass */ - if (parent->value != NULL) - { - struct value *temp = NULL; - - if (TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_PTR - || TYPE_CODE (VALUE_TYPE (parent->value)) == TYPE_CODE_REF) - { - if (!gdb_value_ind (parent->value, &temp)) - return NULL; - } - else - temp = parent->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; - } - } - } - } - - if (value == NULL) - return c_value_of_child (parent, index); - - return value; -} - -static struct type * -cplus_type_of_child (struct varobj *parent, int index) -{ - struct type *type, *t; - - 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 (CPLUS_FAKE_CHILD (parent)) - { - 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 - { - /* special */ - return NULL; - } - break; - - default: - break; - } - - if (type == NULL) - return c_type_of_child (parent, index); - - return type; -} - -static int -cplus_variable_editable (struct varobj *var) -{ - if (CPLUS_FAKE_CHILD (var)) - return 0; - - return c_variable_editable (var); -} - -static char * -cplus_value_of_variable (struct varobj *var) -{ - - /* If we have one of our special types, don't print out - any value. */ - if (CPLUS_FAKE_CHILD (var)) - return xstrdup (""); - - return c_value_of_variable (var); -} - -/* Java */ - -static int -java_number_of_children (struct varobj *var) -{ - return cplus_number_of_children (var); -} - -static char * -java_name_of_variable (struct varobj *parent) -{ - char *p, *name; - - name = cplus_name_of_variable (parent); - /* If the name has "-" in it, it is because we - needed to escape periods in the name... */ - p = name; - - while (*p != '\000') - { - if (*p == '-') - *p = '.'; - p++; - } - - return name; -} - -static char * -java_name_of_child (struct varobj *parent, int index) -{ - char *name, *p; - - name = cplus_name_of_child (parent, index); - /* Escape any periods in the name... */ - p = name; - - while (*p != '\000') - { - if (*p == '.') - *p = '-'; - p++; - } - - return name; -} - -static struct value * -java_value_of_root (struct varobj **var_handle) -{ - return cplus_value_of_root (var_handle); -} - -static struct value * -java_value_of_child (struct varobj *parent, int index) -{ - return cplus_value_of_child (parent, index); -} - -static struct type * -java_type_of_child (struct varobj *parent, int index) -{ - return cplus_type_of_child (parent, index); -} - -static int -java_variable_editable (struct varobj *var) -{ - return cplus_variable_editable (var); -} - -static char * -java_value_of_variable (struct varobj *var) -{ - return cplus_value_of_variable (var); -} - -extern void _initialize_varobj (void); -void -_initialize_varobj (void) -{ - int sizeof_table = sizeof (struct vlist *) * VAROBJ_TABLE_SIZE; - - 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\ -When non-zero, varobj debugging is enabled.", &setlist), - &showlist); -} |