X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gdb%2Fvarobj.c;h=99d8d45e420917e5348bc2a139bac686a0c97210;hb=808d5e5a0248be14eadfbaafb2d9904d6a46d4c7;hp=72356358777b8caa299bbacfb254463635ac05d2;hpb=372346a639e2006b45fde88442b9fe43e7e362d8;p=pf3gnuchains%2Fsourceware.git diff --git a/gdb/varobj.c b/gdb/varobj.c index 7235635877..99d8d45e42 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -1,7 +1,7 @@ /* Implementation of the GDB variable objects API. Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - 2009 Free Software Foundation, Inc. + 2009, 2010, 2011 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 @@ -53,11 +53,11 @@ show_varobjdebug (struct ui_file *file, int from_tty, fprintf_filtered (file, _("Varobj debugging is %s.\n"), value); } -/* String representations of gdb's format codes */ +/* String representations of gdb's format codes. */ char *varobj_format_string[] = { "natural", "binary", "decimal", "hexadecimal", "octal" }; -/* String representations of gdb's known languages */ +/* String representations of gdb's known languages. */ char *varobj_language_string[] = { "unknown", "C", "C++", "Java" }; /* True if we want to allow Python-based pretty-printing. */ @@ -72,14 +72,14 @@ varobj_enable_pretty_printing (void) /* Data structures */ /* Every root variable has one of these structures saved in its - varobj. Members which must be free'd are noted. */ + varobj. Members which must be free'd are noted. */ struct varobj_root { - /* Alloc'd expression for this parent. */ + /* Alloc'd expression for this parent. */ struct expression *exp; - /* Block for which this expression is valid */ + /* Block for which this expression is valid. */ struct block *valid_block; /* The frame for this expression. This field is set iff valid_block is @@ -87,7 +87,7 @@ struct varobj_root struct frame_id frame; /* The thread ID that this varobj_root belong to. This field - is only valid if valid_block is not NULL. + is only valid if valid_block is not NULL. When not 0, indicates which thread 'frame' belongs to. When 0, indicates that the thread list was empty when the varobj_root was created. */ @@ -95,17 +95,17 @@ struct varobj_root /* If 1, the -var-update always recomputes the value in the current thread and frame. Otherwise, variable object is - always updated in the specific scope/thread/frame */ + always updated in the specific scope/thread/frame. */ int floating; /* Flag that indicates validity: set to 0 when this varobj_root refers to symbols that do not exist anymore. */ int is_valid; - /* Language info for this variable and its children */ + /* Language info for this variable and its children. */ struct language_specific *lang; - /* The varobj for this root node. */ + /* The varobj for this root node. */ struct varobj *rootvar; /* Next root variable */ @@ -113,26 +113,26 @@ struct varobj_root }; /* 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. */ + 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 + /* 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" */ + (bar, not foo.bar). */ + /* NOTE: This is the "expression". */ char *name; /* Alloc'd expression for this child. Can be used to create a root variable corresponding to this child. */ char *path_expr; - /* The alloc'd name for this variable's object. This is here for - convenience when constructing this object's children. */ + /* 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 */ + /* Index of this variable in its parent or -1. */ int index; /* The type of this variable. This can be NULL @@ -146,10 +146,10 @@ struct varobj the value is either NULL, or not lazy. */ struct value *value; - /* The number of (immediate) children this variable has */ + /* The number of (immediate) children this variable has. */ int num_children; - /* If this object is a child, this points to its immediate parent. */ + /* If this object is a child, this points to its immediate parent. */ struct varobj *parent; /* Children of this object. */ @@ -161,13 +161,14 @@ struct varobj can avoid that. */ int children_requested; - /* Description of the root variable. Points to root variable for children. */ + /* Description of the root variable. Points to root variable for + children. */ struct varobj_root *root; - /* The format of the output for this object */ + /* The format of the output for this object. */ enum varobj_display_formats format; - /* Was this variable updated via a varobj_set_value operation */ + /* Was this variable updated via a varobj_set_value operation. */ int updated; /* Last print value. */ @@ -226,7 +227,7 @@ struct vlist /* Private function prototypes */ -/* Helper functions for the above subcommands. */ +/* Helper functions for the above subcommands. */ static int delete_variable (struct cpstack **, struct varobj *, int); @@ -268,7 +269,7 @@ static char *cppop (struct cpstack **pstack); static int install_new_value (struct varobj *var, struct value *value, int initial); -/* Language-specific routines. */ +/* Language-specific routines. */ static enum varobj_languages variable_language (struct varobj *var); @@ -293,8 +294,13 @@ static int varobj_value_is_changeable_p (struct varobj *var); static int is_root_p (struct varobj *var); -static struct varobj * -varobj_add_child (struct varobj *var, const char *name, struct value *value); +#if HAVE_PYTHON + +static struct varobj *varobj_add_child (struct varobj *var, + const char *name, + struct value *value); + +#endif /* HAVE_PYTHON */ /* C implementation */ @@ -360,39 +366,39 @@ static char *java_value_of_variable (struct varobj *var, struct language_specific { - /* The language of this variable */ + /* The language of this variable. */ enum varobj_languages language; - /* The number of children of PARENT. */ + /* The number of children of PARENT. */ int (*number_of_children) (struct varobj * parent); - /* The name (expression) of a root varobj. */ + /* The name (expression) of a root varobj. */ char *(*name_of_variable) (struct varobj * parent); - /* The name of the INDEX'th child of PARENT. */ + /* The name of the INDEX'th child of PARENT. */ char *(*name_of_child) (struct varobj * parent, int index); /* Returns the rooted expression of CHILD, which is a variable obtain that has some parent. */ char *(*path_expr_of_child) (struct varobj * child); - /* The ``struct value *'' of the root variable ROOT. */ + /* 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. */ + /* 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. */ + /* The type of the INDEX'th child of PARENT. */ struct type *(*type_of_child) (struct varobj * parent, int index); - /* The current value of VAR. */ + /* The current value of VAR. */ char *(*value_of_variable) (struct varobj * var, enum varobj_display_formats format); }; -/* Array of known source language routines. */ +/* Array of known source language routines. */ static struct language_specific languages[vlang_end] = { - /* Unknown (try treating as C */ + /* Unknown (try treating as C). */ { vlang_unknown, c_number_of_children, @@ -441,7 +447,7 @@ static struct language_specific languages[vlang_end] = { java_value_of_variable} }; -/* A little convenience enum for dealing with C++/Java */ +/* A little convenience enum for dealing with C++/Java. */ enum vsections { v_public = 0, v_private, v_protected @@ -449,20 +455,20 @@ enum vsections /* Private data */ -/* Mappings of varobj_display_formats enums to gdb's format codes */ +/* 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 */ +/* Header of the list of root variable objects. */ static struct varobj_root *rootlist; -/* Prime number indicating the number of buckets in the hash table */ -/* A prime large enough to avoid too many colisions */ +/* 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) */ +/* Pointer to the varobj hash table (built at run time). */ static struct vlist **varobj_table; -/* Is the variable X one of our "fake" children? */ +/* Is the variable X one of our "fake" children? */ #define CPLUS_FAKE_CHILD(x) \ ((x) != NULL && (x)->type == NULL && (x)->value == NULL) @@ -485,7 +491,7 @@ varobj_ensure_python_env (struct varobj *var) } #endif -/* Creates a varobj (not its children) */ +/* Creates a varobj (not its children). */ /* Return the full FRAME which corresponds to the given CORE_ADDR or NULL if no FRAME on the chain corresponds to CORE_ADDR. */ @@ -508,6 +514,7 @@ find_frame_addr_in_frame_chain (CORE_ADDR frame_addr) comparing it against our argument. */ CORE_ADDR frame_base = get_frame_base_address (frame); int addr_bit = gdbarch_addr_bit (get_frame_arch (frame)); + if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT)) frame_base &= ((CORE_ADDR) 1 << addr_bit) - 1; @@ -523,17 +530,17 @@ 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. */ + /* 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) { + struct frame_info *fi; + struct frame_id old_id = null_frame_id; + struct block *block; char *p; enum varobj_languages lang; struct value *value = NULL; @@ -543,7 +550,7 @@ varobj_create (char *objname, if (has_stack_frames ()) { - /* Allow creator to specify context of variable */ + /* Allow creator to specify context of variable. */ if ((type == USE_CURRENT_FRAME) || (type == USE_SELECTED_FRAME)) fi = get_selected_frame (NULL); else @@ -559,7 +566,7 @@ varobj_create (char *objname, else fi = NULL; - /* frame = -2 means always use selected frame */ + /* frame = -2 means always use selected frame. */ if (type == USE_SELECTED_FRAME) var->root->floating = 1; @@ -570,13 +577,13 @@ varobj_create (char *objname, p = expression; innermost_block = NULL; /* Wrap the call to parse expression, so we can - return a sensible error. */ + 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. */ + /* Don't allow variables to be created for types. */ if (var->root->exp->elts[0].opcode == OP_TYPE) { do_cleanups (old_chain); @@ -594,7 +601,7 @@ varobj_create (char *objname, /* 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. */ + Since select_frame is so benign, just call it for all cases. */ if (innermost_block) { /* User could specify explicit FRAME-ADDR which was not found but @@ -606,18 +613,19 @@ varobj_create (char *objname, var->root->frame = get_frame_id (fi); var->root->thread_id = pid_to_thread_id (inferior_ptid); - old_fi = get_selected_frame (NULL); + old_id = get_frame_id (get_selected_frame (NULL)); select_frame (fi); } /* We definitely 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() */ + But if it fails, we still go on with a call to evaluate_type(). */ if (!gdb_evaluate_expression (var->root->exp, &value)) { /* Error getting the value. Try to at least get the right type. */ struct value *type_only_value = evaluate_type (var->root->exp); + var->type = value_type (type_only_value); } else @@ -629,23 +637,23 @@ varobj_create (char *objname, lang = variable_language (var); var->root->lang = &languages[lang]; - /* Set ourselves as our root */ + /* Set ourselves as our root. */ var->root->rootvar = var; - /* Reset the selected frame */ - if (old_fi != NULL) - select_frame (old_fi); + /* Reset the selected frame. */ + if (frame_id_p (old_id)) + select_frame (frame_find_by_id (old_id)); } /* If the variable object name is null, that means this - is a temporary variable, so don't install it. */ + is a temporary variable, so don't install it. */ if ((var != NULL) && (objname != NULL)) { var->obj_name = xstrdup (objname); /* If a varobj name is duplicated, the install will fail so - we must clenup */ + we must cleanup. */ if (!install_variable (var)) { do_cleanups (old_chain); @@ -657,7 +665,7 @@ varobj_create (char *objname, return var; } -/* Generates an unique name that can be used for a varobj */ +/* Generates an unique name that can be used for a varobj. */ char * varobj_gen_name (void) @@ -665,7 +673,7 @@ varobj_gen_name (void) static int id = 0; char *obj_name; - /* generate a name for this object */ + /* Generate a name for this object. */ id++; obj_name = xstrprintf ("var%d", id); @@ -698,7 +706,7 @@ varobj_get_handle (char *objname) return cv->var; } -/* Given the handle, return the name of the object */ +/* Given the handle, return the name of the object. */ char * varobj_get_objname (struct varobj *var) @@ -706,7 +714,7 @@ varobj_get_objname (struct varobj *var) return var->obj_name; } -/* Given the handle, return the expression represented by the object */ +/* Given the handle, return the expression represented by the object. */ char * varobj_get_expression (struct varobj *var) @@ -715,8 +723,9 @@ varobj_get_expression (struct varobj *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) */ + 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) @@ -726,17 +735,17 @@ varobj_delete (struct varobj *var, char ***dellist, int only_children) struct cpstack *result = NULL; char **cp; - /* Initialize a stack for temporary results */ + /* Initialize a stack for temporary results. */ cppush (&result, NULL); if (only_children) - /* Delete only the variable children */ + /* Delete only the variable children. */ delcount = delete_variable (&result, var, 1 /* only the children */ ); else - /* Delete the variable and all its children */ + /* 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 */ + /* We may have been asked to return a list of what has been deleted. */ if (dellist != NULL) { *dellist = xmalloc ((delcount + 1) * sizeof (char *)); @@ -759,12 +768,13 @@ varobj_delete (struct varobj *var, char ***dellist, int only_children) return delcount; } +#if HAVE_PYTHON + /* Convenience function for varobj_set_visualizer. Instantiate a pretty-printer for a given value. */ static PyObject * instantiate_pretty_printer (PyObject *constructor, struct value *value) { -#if HAVE_PYTHON PyObject *val_obj = NULL; PyObject *printer; @@ -775,11 +785,12 @@ instantiate_pretty_printer (PyObject *constructor, struct value *value) printer = PyObject_CallFunctionObjArgs (constructor, val_obj, NULL); Py_DECREF (val_obj); return printer; -#endif return NULL; } -/* Set/Get variable object display format */ +#endif + +/* Set/Get variable object display format. */ enum varobj_display_formats varobj_set_display_format (struct varobj *var, @@ -846,7 +857,7 @@ varobj_has_more (struct varobj *var, int to) /* If the variable object is bound to a specific thread, that is its evaluation can always be done in context of a frame inside that thread, returns GDB id of the thread -- which - is always positive. Otherwise, returns -1. */ + is always positive. Otherwise, returns -1. */ int varobj_get_thread_id (struct varobj *var) { @@ -899,6 +910,8 @@ restrict_range (VEC (varobj_p) *children, int *from, int *to) } } +#if HAVE_PYTHON + /* A helper for update_dynamic_varobj_children that installs a new child when needed. */ @@ -916,6 +929,7 @@ install_dynamic_child (struct varobj *var, { /* There's no child yet. */ struct varobj *child = varobj_add_child (var, name, value); + if (new) { VEC_safe_push (varobj_p, *new, child); @@ -925,6 +939,7 @@ install_dynamic_child (struct varobj *var, else { varobj_p existing = VEC_index (varobj_p, var->children, index); + if (install_new_value (existing, value, 0)) { if (changed) @@ -935,8 +950,6 @@ install_dynamic_child (struct varobj *var, } } -#if HAVE_PYTHON - static int dynamic_varobj_has_child_method (struct varobj *var) { @@ -1042,6 +1055,8 @@ update_dynamic_varobj_children (struct varobj *var, error (_("Invalid item from the child list")); v = convert_value_from_python (py_v); + if (v == NULL) + gdbpy_print_stack (); install_dynamic_child (var, can_mention ? changed : NULL, can_mention ? new : NULL, can_mention ? unchanged : NULL, @@ -1062,6 +1077,7 @@ update_dynamic_varobj_children (struct varobj *var, if (i < VEC_length (varobj_p, var->children)) { int j; + *cchanged = 1; for (j = i; j < VEC_length (varobj_p, var->children); ++j) varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0); @@ -1105,12 +1121,11 @@ varobj_get_num_children (struct varobj *var) } /* Creates a list of the immediate children of a variable object; - the return code is the number of such children or -1 on error */ + the return code is the number of such children or -1 on error. */ VEC (varobj_p)* varobj_list_children (struct varobj *var, int *from, int *to) { - struct varobj *child; char *name; int i, children_changed; @@ -1158,23 +1173,28 @@ varobj_list_children (struct varobj *var, int *from, int *to) return var->children; } +#if HAVE_PYTHON + static struct varobj * varobj_add_child (struct varobj *var, const char *name, struct value *value) { varobj_p v = create_child_with_value (var, VEC_length (varobj_p, var->children), name, value); + VEC_safe_push (varobj_p, var->children, v); return v; } +#endif /* HAVE_PYTHON */ + /* Obtain the type of an object Variable as a string similar to the one gdb - prints on the console */ + prints on the console. */ char * varobj_get_type (struct varobj *var) { - /* For the "fake" variables, do not return a type. (It's type is + /* For the "fake" variables, do not return a type. (It's type is NULL, too.) Do not return a type for invalid variables as well. */ if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid) @@ -1220,7 +1240,7 @@ varobj_get_attributes (struct varobj *var) int attributes = 0; if (varobj_editable_p (var)) - /* FIXME: define masks for attributes */ + /* FIXME: define masks for attributes. */ attributes |= 0x00000001; /* Editable */ return attributes; @@ -1246,32 +1266,29 @@ varobj_get_value (struct varobj *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() */ + 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; - int error = 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? */ + 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; char *s = expression; - int i; gdb_assert (varobj_editable_p (var)); - input_radix = 10; /* ALWAYS reset to decimal temporarily */ + input_radix = 10; /* ALWAYS reset to decimal temporarily. */ exp = parse_exp_1 (&s, 0, 0); if (!gdb_evaluate_expression (exp, &value)) { - /* We cannot proceed without a valid expression. */ + /* We cannot proceed without a valid expression. */ xfree (exp); return 0; } @@ -1287,7 +1304,7 @@ varobj_set_value (struct varobj *var, char *expression) after assignment, and the first thing value_assign does is coerce the input. For example, if we are assigning an array to a pointer variable we - should compare the pointer with the the array's address, not with the + should compare the pointer with the array's address, not with the array's content. */ value = coerce_array (value); @@ -1304,7 +1321,7 @@ varobj_set_value (struct varobj *var, char *expression) variable as changed -- because the first assignment has set the 'updated' flag. There's no need to optimize that, because return value of -var-update should be considered an approximation. */ - var->updated = install_new_value (var, val, 0 /* Compare values. */); + var->updated = install_new_value (var, val, 0 /* Compare values. */); input_radix = saved_input_radix; return 1; } @@ -1403,7 +1420,6 @@ install_new_value_visualizer (struct varobj *var) if (var->constructor != Py_None && var->value) { struct cleanup *cleanup; - PyObject *pretty_printer = NULL; cleanup = varobj_ensure_python_env (var); @@ -1423,12 +1439,12 @@ install_new_value_visualizer (struct varobj *var) this is the first assignement after the variable object was just created, or changed type. In that case, just assign the value and return 0. - Otherwise, assign the new value, and return 1 if the value is different - from the current one, 0 otherwise. The comparison is done on textual - representation of value. Therefore, some types need not be compared. E.g. - for structures the reported value is always "{...}", so no comparison is - necessary here. If the old value was NULL and new one is not, or vice versa, - we always return 1. + Otherwise, assign the new value, and return 1 if the value is + different from the current one, 0 otherwise. The comparison is + done on textual representation of value. Therefore, some types + need not be compared. E.g. for structures the reported value is + always "{...}", so no comparison is necessary here. If the old + value was NULL and new one is not, or vice versa, we always return 1. The VALUE parameter should not be released -- the function will take care of releasing it when needed. */ @@ -1442,13 +1458,13 @@ install_new_value (struct varobj *var, struct value *value, int initial) char *print_value = NULL; /* We need to know the varobj's type to decide if the value should - be fetched or not. C++ fake children (public/protected/private) don't have - a type. */ + be fetched or not. C++ fake children (public/protected/private) + don't have a type. */ gdb_assert (var->type || CPLUS_FAKE_CHILD (var)); changeable = varobj_value_is_changeable_p (var); /* If the type has custom visualizer, we consider it to be always - changeable. FIXME: need to make sure this behaviour will not + changeable. FIXME: need to make sure this behaviour will not mess up read-sensitive values. */ if (var->pretty_printer) changeable = 1; @@ -1481,6 +1497,7 @@ install_new_value (struct varobj *var, struct value *value, int initial) { struct varobj *parent = var->parent; int frozen = var->frozen; + for (; !frozen && parent; parent = parent->parent) frozen |= parent->frozen; @@ -1514,10 +1531,11 @@ install_new_value (struct varobj *var, struct value *value, int initial) to compare with. */ if (!initial && changeable) { - /* If the value of the varobj was changed by -var-set-value, then the - value in the varobj and in the target is the same. However, that value - is different from the value that the varobj had after the previous - -var-update. So need to the varobj as changed. */ + /* If the value of the varobj was changed by -var-set-value, + then the value in the varobj and in the target is the same. + However, that value is different from the value that the + varobj had after the previous -var-update. So need to the + varobj as changed. */ if (var->updated) { changed = 1; @@ -1536,7 +1554,7 @@ install_new_value (struct varobj *var, struct value *value, int initial) changed = 1; } else if (var->value == NULL && value == NULL) - /* Equal. */ + /* Equal. */ ; else if (var->value == NULL || value == NULL) { @@ -1583,7 +1601,10 @@ install_new_value (struct varobj *var, struct value *value, int initial) { xfree (print_value); print_value = value_get_print_value (var->value, var->format, var); - if (!var->print_value || strcmp (var->print_value, print_value) != 0) + if ((var->print_value == NULL && print_value != NULL) + || (var->print_value != NULL && print_value == NULL) + || (var->print_value != NULL && print_value != NULL + && strcmp (var->print_value, print_value) != 0)) changed = 1; } if (var->print_value) @@ -1620,8 +1641,8 @@ void varobj_set_visualizer (struct varobj *var, const char *visualizer) { #if HAVE_PYTHON - PyObject *mainmod, *globals, *pretty_printer, *constructor; - struct cleanup *back_to, *value; + PyObject *mainmod, *globals, *constructor; + struct cleanup *back_to; back_to = varobj_ensure_python_env (var); @@ -1659,10 +1680,10 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer) The EXPLICIT parameter specifies if this call is result of MI request to update this specific variable, or - result of implicit -var-update *. For implicit request, we don't + result of implicit -var-update *. For implicit request, we don't update frozen variables. - NOTE: This function may delete the caller's varobj. If it + NOTE: This function may delete the caller's varobj. If it returns TYPE_CHANGED, then it has done this and VARP will be modified to point to the new varobj. */ @@ -1671,14 +1692,9 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) int changed = 0; int type_changed = 0; int i; - int vleft; - struct varobj *v; - struct varobj **cv; - struct varobj **templist = NULL; struct value *new; VEC (varobj_update_result) *stack = NULL; VEC (varobj_update_result) *result = NULL; - struct frame_info *fi; /* Frozen means frozen -- we don't check for any change in this varobj, including its going out of scope, or @@ -1690,7 +1706,9 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) if (!(*varp)->root->is_valid) { - varobj_update_result r = {*varp}; + varobj_update_result r = {0}; + + r.varobj = *varp; r.status = VAROBJ_INVALID; VEC_safe_push (varobj_update_result, result, &r); return result; @@ -1698,12 +1716,14 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) if ((*varp)->root->rootvar == *varp) { - varobj_update_result r = {*varp}; + varobj_update_result r = {0}; + + r.varobj = *varp; r.status = VAROBJ_IN_SCOPE; - /* Update the root variable. value_of_root can return NULL + /* Update the root variable. value_of_root can return NULL if the variable is no longer around, i.e. we stepped out of - the frame in which a local existed. We are letting the + the frame in which a local existed. We are letting the value_of_root variable dispose of the varobj if the type has changed. */ new = value_of_root (varp, &type_changed); @@ -1728,7 +1748,9 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) } else { - varobj_update_result r = {*varp}; + varobj_update_result r = {0}; + + r.varobj = *varp; VEC_safe_push (varobj_update_result, stack, &r); } @@ -1754,11 +1776,11 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) /* We probably should not get children of a varobj that has a pretty-printer, but for which -var-list-children was never - invoked. */ + invoked. */ if (v->pretty_printer) { VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0; - int i, children_changed; + int i, children_changed = 0; if (v->frozen) continue; @@ -1805,7 +1827,9 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) for (i = VEC_length (varobj_p, changed) - 1; i >= 0; --i) { varobj_p tmp = VEC_index (varobj_p, changed, i); - varobj_update_result r = {tmp}; + varobj_update_result r = {0}; + + r.varobj = tmp; r.changed = 1; r.value_installed = 1; VEC_safe_push (varobj_update_result, stack, &r); @@ -1813,9 +1837,12 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) for (i = VEC_length (varobj_p, unchanged) - 1; i >= 0; --i) { varobj_p tmp = VEC_index (varobj_p, unchanged, i); + if (!tmp->frozen) { - varobj_update_result r = {tmp}; + varobj_update_result r = {0}; + + r.varobj = tmp; r.value_installed = 1; VEC_safe_push (varobj_update_result, stack, &r); } @@ -1839,10 +1866,13 @@ VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit) for (i = VEC_length (varobj_p, v->children)-1; i >= 0; --i) { varobj_p c = VEC_index (varobj_p, v->children, i); + /* Child may be NULL if explicitly deleted by -var-delete. */ if (c != NULL && !c->frozen) { - varobj_update_result r = {c}; + varobj_update_result r = {0}; + + r.varobj = c; VEC_safe_push (varobj_update_result, stack, &r); } } @@ -1875,10 +1905,10 @@ delete_variable (struct cpstack **resultp, struct varobj *var, return delcount; } -/* Delete the variable object VAR and its children */ +/* 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 */ + 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, @@ -1886,10 +1916,11 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp, { int i; - /* Delete any children of this variable, too. */ + /* Delete any children of this variable, too. */ for (i = 0; i < VEC_length (varobj_p, var->children); ++i) { varobj_p child = VEC_index (varobj_p, var->children, i); + if (!child) continue; if (!remove_from_parent_p) @@ -1898,24 +1929,24 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp, } VEC_free (varobj_p, var->children); - /* if we were called to delete only the children we are done here */ + /* 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 */ + /* 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... */ + 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 */ + /* 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 */ + discarding the list afterwards. */ if ((remove_from_parent_p) && (var->parent != NULL)) { VEC_replace (varobj_p, var->parent->children, var->index, NULL); @@ -1924,11 +1955,11 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp, if (var->obj_name != NULL) uninstall_variable (var); - /* Free memory associated with this variable */ + /* Free memory associated with this variable. */ free_variable (var); } -/* Install the given variable VAR with the object name VAR->OBJ_NAME. */ +/* Install the given variable VAR with the object name VAR->OBJ_NAME. */ static int install_variable (struct varobj *var) { @@ -1950,16 +1981,16 @@ install_variable (struct varobj *var) if (cv != NULL) error (_("Duplicate variable object name")); - /* Add varobj to hash table */ + /* 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 root, add varobj to root list. */ if (is_root_p (var)) { - /* Add to list of root variables */ + /* Add to list of root variables. */ if (rootlist == NULL) var->root->next = NULL; else @@ -1970,7 +2001,7 @@ install_variable (struct varobj *var) return 1; /* OK */ } -/* Unistall the object VAR. */ +/* Unistall the object VAR. */ static void uninstall_variable (struct varobj *var) { @@ -1982,7 +2013,7 @@ uninstall_variable (struct varobj *var) unsigned int index = 0; unsigned int i = 1; - /* Remove varobj from hash table */ + /* Remove varobj from hash table. */ for (chp = var->obj_name; *chp; chp++) { index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE; @@ -2014,10 +2045,10 @@ uninstall_variable (struct varobj *var) xfree (cv); - /* If root, remove varobj from root list */ + /* If root, remove varobj from root list. */ if (is_root_p (var)) { - /* Remove from list of root variables */ + /* Remove from list of root variables. */ if (rootlist == var->root) rootlist = var->root->next; else @@ -2031,9 +2062,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) @@ -2045,7 +2076,7 @@ uninstall_variable (struct varobj *var) } -/* Create and install a child of the parent of the given name */ +/* Create and install a child of the parent of the given name. */ static struct varobj * create_child (struct varobj *parent, int index, char *name) { @@ -2062,7 +2093,7 @@ create_child_with_value (struct varobj *parent, int index, const char *name, child = new_variable (); - /* name is allocated by name_of_child */ + /* Name is allocated by name_of_child. */ /* FIXME: xstrdup should not be here. */ child->name = xstrdup (name); child->index = index; @@ -2076,10 +2107,10 @@ create_child_with_value (struct varobj *parent, int index, const char *name, calling install_new_value. */ if (value != NULL) /* If the child had no evaluation errors, var->value - will be non-NULL and contain a valid type. */ + will be non-NULL and contain a valid type. */ child->type = value_type (value); else - /* Otherwise, we must compute the type. */ + /* Otherwise, we must compute the type. */ child->type = (*child->root->lang->type_of_child) (child->parent, child->index); install_new_value (child, value, 1); @@ -2092,7 +2123,7 @@ create_child_with_value (struct varobj *parent, int index, const char *name, * Miscellaneous utility functions. */ -/* Allocate memory and initialize a new variable */ +/* Allocate memory and initialize a new variable. */ static struct varobj * new_variable (void) { @@ -2125,12 +2156,13 @@ new_variable (void) return var; } -/* Allocate memory and initialize a new root variable */ +/* 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 = (struct varobj_root *) xmalloc (sizeof (struct varobj_root)); var->root->lang = NULL; var->root->exp = NULL; var->root->valid_block = NULL; @@ -2142,7 +2174,7 @@ new_root_variable (void) return var; } -/* Free any allocated memory associated with VAR. */ +/* Free any allocated memory associated with VAR. */ static void free_variable (struct varobj *var) { @@ -2160,7 +2192,7 @@ free_variable (struct varobj *var) value_free (var->value); - /* Free the expression if this is a root variable. */ + /* Free the expression if this is a root variable. */ if (is_root_p (var)) { xfree (var->root->exp); @@ -2186,17 +2218,17 @@ make_cleanup_free_variable (struct varobj *var) return make_cleanup (do_free_variable_cleanup, var); } -/* This returns the type of the variable. It also skips past typedefs +/* This returns the type of the variable. It also skips past typedefs to return the real type of the variable. NOTE: TYPE_TARGET_TYPE should NOT be used anywhere in this file - except within get_target_type and get_type. */ + except within get_target_type and get_type. */ static struct type * get_type (struct varobj *var) { struct type *type; - type = var->type; + type = var->type; if (type != NULL) type = check_typedef (type); @@ -2205,7 +2237,7 @@ get_type (struct varobj *var) /* Return the type of the value that's stored in VAR, or that would have being stored there if the - value were accessible. + value were accessible. This differs from VAR->type in that VAR->type is always the true type of the expession in the source language. @@ -2238,7 +2270,7 @@ get_value_type (struct varobj *var) past typedefs, just like get_type (). NOTE: TYPE_TARGET_TYPE should NOT be used anywhere in this file - except within get_target_type and get_type. */ + except within get_target_type and get_type. */ static struct type * get_target_type (struct type *type) { @@ -2253,14 +2285,14 @@ get_target_type (struct type *type) } /* What is the default display for this variable? We assume that - everything is "natural". Any exceptions? */ + everything is "natural". Any exceptions? */ static enum varobj_display_formats variable_default_display (struct varobj *var) { return FORMAT_NATURAL; } -/* FIXME: The following should be generic for any pointer */ +/* FIXME: The following should be generic for any pointer. */ static void cppush (struct cpstack **pstack, char *name) { @@ -2272,7 +2304,7 @@ cppush (struct cpstack **pstack, char *name) *pstack = s; } -/* FIXME: The following should be generic for any pointer */ +/* FIXME: The following should be generic for any pointer. */ static char * cppop (struct cpstack **pstack) { @@ -2296,7 +2328,7 @@ cppop (struct cpstack **pstack) /* Common entry points */ -/* Get the language of variable VAR. */ +/* Get the language of variable VAR. */ static enum varobj_languages variable_language (struct varobj *var) { @@ -2321,23 +2353,25 @@ variable_language (struct varobj *var) /* 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 + implementation. The number of children returned by this function is the number of children that the user will see in the variable - display. */ + display. */ static int number_of_children (struct varobj *var) { - return (*var->root->lang->number_of_children) (var);; + return (*var->root->lang->number_of_children) (var); } -/* What is the expression for the root varobj VAR? Returns a malloc'd string. */ +/* 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. */ +/* 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) { @@ -2364,7 +2398,7 @@ value_of_root (struct varobj **var_handle, int *type_changed) var = *var_handle; /* This should really be an exception, since this should - only get called with a root variable. */ + only get called with a root variable. */ if (!is_root_p (var)) return NULL; @@ -2391,6 +2425,7 @@ value_of_root (struct varobj **var_handle, int *type_changed) correct in other frames, so update the expression. */ struct expression *tmp_exp = var->root->exp; + var->root->exp = tmp_var->root->exp; tmp_var->root->exp = tmp_exp; @@ -2420,7 +2455,7 @@ value_of_root (struct varobj **var_handle, int *type_changed) return (*var->root->lang->value_of_root) (var_handle); } -/* What is the ``struct value *'' for the INDEX'th child of PARENT? */ +/* What is the ``struct value *'' for the INDEX'th child of PARENT? */ static struct value * value_of_child (struct varobj *parent, int index) { @@ -2431,7 +2466,7 @@ value_of_child (struct varobj *parent, int index) return value; } -/* GDB already has a command called "value_of_variable". Sigh. */ +/* GDB already has a command called "value_of_variable". Sigh. */ static char * my_value_of_variable (struct varobj *var, enum varobj_display_formats format) { @@ -2453,28 +2488,41 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, struct cleanup *old_chain; gdb_byte *thevalue = NULL; struct value_print_options opts; - int len = 0; + struct type *type = NULL; + long len = 0; + char *encoding = NULL; + struct gdbarch *gdbarch = NULL; + /* Initialize it just to avoid a GCC false warning. */ + CORE_ADDR str_addr = 0; + int string_print = 0; if (value == NULL) return NULL; + stb = mem_fileopen (); + old_chain = make_cleanup_ui_file_delete (stb); + + gdbarch = get_type_arch (value_type (value)); #if HAVE_PYTHON { - struct cleanup *back_to = varobj_ensure_python_env (var); PyObject *value_formatter = var->pretty_printer; + varobj_ensure_python_env (var); + if (value_formatter) { /* First check to see if we have any children at all. If so, we simply return {...}. */ if (dynamic_varobj_has_child_method (var)) - return xstrdup ("{...}"); + { + do_cleanups (old_chain); + return xstrdup ("{...}"); + } if (PyObject_HasAttr (value_formatter, gdbpy_to_string_cst)) { char *hint; struct value *replacement; - int string_print = 0; PyObject *output = NULL; hint = gdbpy_get_display_hint (value_formatter); @@ -2486,46 +2534,59 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, } output = apply_varobj_pretty_printer (value_formatter, - &replacement); + &replacement, + stb); if (output) { - PyObject *py_str - = python_string_to_target_python_string (output); - if (py_str) + make_cleanup_py_decref (output); + + if (gdbpy_is_lazy_string (output)) { - char *s = PyString_AsString (py_str); - len = PyString_Size (py_str); - thevalue = xmemdup (s, len + 1, len + 1); - Py_DECREF (py_str); + gdbpy_extract_lazy_string (output, &str_addr, &type, + &len, &encoding); + make_cleanup (free_current_contents, &encoding); + string_print = 1; + } + else + { + PyObject *py_str + = python_string_to_target_python_string (output); + + if (py_str) + { + char *s = PyString_AsString (py_str); + + len = PyString_Size (py_str); + thevalue = xmemdup (s, len + 1, len + 1); + type = builtin_type (gdbarch)->builtin_char; + Py_DECREF (py_str); + + if (!string_print) + { + do_cleanups (old_chain); + return thevalue; + } + + make_cleanup (xfree, thevalue); + } + else + gdbpy_print_stack (); } - Py_DECREF (output); - } - if (thevalue && !string_print) - { - do_cleanups (back_to); - return thevalue; } if (replacement) value = replacement; } } - do_cleanups (back_to); } #endif - stb = mem_fileopen (); - old_chain = make_cleanup_ui_file_delete (stb); - get_formatted_print_options (&opts, format_code[(int) format]); opts.deref_ref = 0; opts.raw = 1; if (thevalue) - { - struct gdbarch *gdbarch = get_type_arch (value_type (value)); - make_cleanup (xfree, thevalue); - LA_PRINT_STRING (stb, builtin_type (gdbarch)->builtin_char, - thevalue, len, 0, &opts); - } + LA_PRINT_STRING (stb, type, thevalue, len, encoding, 0, &opts); + else if (string_print) + val_print_string (type, encoding, str_addr, len, stb, &opts); else common_val_print (value, stb, 0, &opts, current_language); thevalue = ui_file_xstrdup (stb, NULL); @@ -2538,7 +2599,6 @@ int varobj_editable_p (struct varobj *var) { struct type *type; - struct value *value; if (!(var->root->is_valid && var->value && VALUE_LVAL (var->value))) return 0; @@ -2610,12 +2670,12 @@ varobj_floating_p (struct varobj *var) for getting children of the variable object. This includes dereferencing top-level references to all types and dereferencing pointers to - structures. + structures. - Both TYPE and *TYPE should be non-null. VALUE + Both TYPE and *TYPE should be non-null. VALUE can be null if we want to only translate type. *VALUE can be null as well -- if the parent - value is not known. + value is not known. If WAS_PTR is not NULL, set *WAS_PTR to 0 or 1 depending on whether pointer was dereferenced @@ -2649,7 +2709,8 @@ adjust_value_for_child_access (struct value **value, { if (value && *value) { - int success = gdb_value_ind (*value, value); + int success = gdb_value_ind (*value, value); + if (!success) *value = NULL; } @@ -2693,14 +2754,14 @@ c_number_of_children (struct varobj *var) break; case TYPE_CODE_PTR: - /* The type here is a pointer to non-struct. Typically, pointers + /* The type here is a pointer to non-struct. Typically, pointers have one child, except for function ptrs, which have no children, and except for 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" */ + TYPE_NAME == "char". */ if (TYPE_CODE (target) == TYPE_CODE_FUNC || TYPE_CODE (target) == TYPE_CODE_VOID) children = 0; @@ -2709,7 +2770,7 @@ c_number_of_children (struct varobj *var) break; default: - /* Other types have no children */ + /* Other types have no children. */ break; } @@ -2724,7 +2785,7 @@ c_name_of_variable (struct varobj *parent) /* Return the value of element TYPE_INDEX of a structure value VALUE. VALUE's type should be a structure, - or union, or a typedef to struct/union. + or union, or a typedef to struct/union. Returns NULL if getting the value fails. Never throws. */ static struct value * @@ -2732,8 +2793,8 @@ value_struct_element_index (struct value *value, int type_index) { struct value *result = NULL; volatile struct gdb_exception e; - struct type *type = value_type (value); + type = check_typedef (type); gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT @@ -2757,7 +2818,7 @@ value_struct_element_index (struct value *value, int type_index) } /* Obtain the information about child INDEX of the variable - object PARENT. + object PARENT. If CNAME is not null, sets *CNAME to the name of the child relative to the parent. If CVALUE is not null, sets *CVALUE to the value of the child. @@ -2793,12 +2854,15 @@ c_describe_child (struct varobj *parent, int index, { case TYPE_CODE_ARRAY: if (cname) - *cname = xstrprintf ("%d", index - + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type))); + *cname + = xstrdup (int_string (index + + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)), + 10, 1, 0, 0)); if (cvalue && value) { int real_index = index + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)); + gdb_value_subscript (value, real_index, cvalue); } @@ -2806,9 +2870,11 @@ c_describe_child (struct varobj *parent, int index, *ctype = get_target_type (type); if (cfull_expression) - *cfull_expression = xstrprintf ("(%s)[%d]", parent_expression, - index - + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type))); + *cfull_expression = + xstrprintf ("(%s)[%s]", parent_expression, + int_string (index + + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)), + 10, 1, 0, 0)); break; @@ -2830,6 +2896,7 @@ c_describe_child (struct varobj *parent, int index, if (cfull_expression) { char *join = was_ptr ? "->" : "."; + *cfull_expression = xstrprintf ("(%s)%s%s", parent_expression, join, TYPE_FIELD_NAME (type, index)); } @@ -2843,6 +2910,7 @@ c_describe_child (struct varobj *parent, int index, if (cvalue && value) { int success = gdb_value_ind (value, cvalue); + if (!success) *cvalue = NULL; } @@ -2859,12 +2927,12 @@ c_describe_child (struct varobj *parent, int index, break; default: - /* This should not happen */ + /* This should not happen. */ if (cname) *cname = xstrdup ("???"); if (cfull_expression) *cfull_expression = xstrdup ("???"); - /* Don't set value and type, we don't know then. */ + /* Don't set value and type, we don't know then. */ } } @@ -2872,6 +2940,7 @@ static char * c_name_of_child (struct varobj *parent, int index) { char *name; + c_describe_child (parent, index, &name, NULL, NULL, NULL); return name; } @@ -2898,6 +2967,7 @@ check_scope (struct varobj *var) if (fi) { CORE_ADDR pc = get_frame_pc (fi); + if (pc < BLOCK_START (var->root->valid_block) || pc >= BLOCK_END (var->root->valid_block)) scope = 0; @@ -2912,18 +2982,17 @@ c_value_of_root (struct varobj **var_handle) { struct value *new_val = NULL; struct varobj *var = *var_handle; - struct frame_info *fi; int within_scope = 0; struct cleanup *back_to; - /* Only root variables can be updated... */ + /* Only root variables can be updated... */ if (!is_root_p (var)) - /* Not a root var */ + /* Not a root var. */ return NULL; back_to = make_cleanup_restore_current_thread (); - /* Determine whether the variable is still around. */ + /* Determine whether the variable is still around. */ if (var->root->valid_block == NULL || var->root->floating) within_scope = 1; else if (var->root->thread_id == 0) @@ -2961,8 +3030,8 @@ static struct value * c_value_of_child (struct varobj *parent, int index) { struct value *value = NULL; - c_describe_child (parent, index, NULL, &value, NULL, NULL); + c_describe_child (parent, index, NULL, &value, NULL, NULL); return value; } @@ -2970,6 +3039,7 @@ static struct type * c_type_of_child (struct varobj *parent, int index) { struct type *type = NULL; + c_describe_child (parent, index, NULL, NULL, &type, NULL); return type; } @@ -2987,7 +3057,7 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) if (var->pretty_printer && var->print_value) return xstrdup (var->print_value); - /* Strip top-level references. */ + /* Strip top-level references. */ while (TYPE_CODE (type) == TYPE_CODE_REF) type = check_typedef (TYPE_TARGET_TYPE (type)); @@ -3001,6 +3071,7 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) case TYPE_CODE_ARRAY: { char *number; + number = xstrprintf ("[%d]", var->num_children); return (number); } @@ -3011,8 +3082,8 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) 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. */ + member when the parent is an invalid pointer. This is an + error condition, so we should tell the caller. */ return NULL; } else @@ -3027,7 +3098,7 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) gdb_assert (!value_lazy (var->value)); /* If the specified format is the current one, - we can reuse print_value */ + we can reuse print_value. */ if (format == var->format) return xstrdup (var->print_value); else @@ -3067,11 +3138,11 @@ cplus_number_of_children (struct varobj *var) if (kids[v_protected] != 0) children++; - /* Add any baseclasses */ + /* Add any baseclasses. */ children += TYPE_N_BASECLASSES (type); dont_know = 0; - /* FIXME: save children in var */ + /* FIXME: save children in var. */ } } else @@ -3099,20 +3170,25 @@ cplus_number_of_children (struct varobj *var) /* 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. */ + how many are there, too. */ static void cplus_class_num_children (struct type *type, int children[3]) { - int i; + int i, vptr_fieldno; + struct type *basetype = NULL; children[v_public] = 0; children[v_private] = 0; children[v_protected] = 0; + vptr_fieldno = get_vptr_fieldno (type, &basetype); 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 we have a virtual table pointer, omit it. Even if virtual + table pointers are not specifically marked in the debug info, + they should be artificial. */ + if ((type == basetype && i == vptr_fieldno) + || TYPE_FIELD_ARTIFICIAL (type, i)) continue; if (TYPE_FIELD_PROTECTED (type, i)) @@ -3153,7 +3229,6 @@ cplus_describe_child (struct varobj *parent, int index, char **cname, struct value **cvalue, struct type **ctype, char **cfull_expression) { - char *name = NULL; struct value *value; struct type *type; int was_ptr; @@ -3189,6 +3264,7 @@ cplus_describe_child (struct varobj *parent, int index, || TYPE_CODE (type) == TYPE_CODE_UNION) { char *join = was_ptr ? "->" : "."; + if (CPLUS_FAKE_CHILD (parent)) { /* The fields of the class type are ordered as they @@ -3196,9 +3272,13 @@ cplus_describe_child (struct varobj *parent, int index, particular access control type ("public","protected", or "private"). We must skip over fields that don't have the access control we are looking for to properly - find the indexed field. */ + find the indexed field. */ int type_index = TYPE_N_BASECLASSES (type); enum accessibility acc = public_field; + int vptr_fieldno; + struct type *basetype = NULL; + + vptr_fieldno = get_vptr_fieldno (type, &basetype); if (strcmp (parent->name, "private") == 0) acc = private_field; else if (strcmp (parent->name, "protected") == 0) @@ -3206,8 +3286,8 @@ cplus_describe_child (struct varobj *parent, int index, while (index >= 0) { - if (TYPE_VPTR_BASETYPE (type) == type - && type_index == TYPE_VPTR_FIELDNO (type)) + if ((type == basetype && type_index == vptr_fieldno) + || TYPE_FIELD_ARTIFICIAL (type, type_index)) ; /* ignore vptr */ else if (match_accessibility (type, type_index, acc)) --index; @@ -3225,9 +3305,10 @@ cplus_describe_child (struct varobj *parent, int index, *ctype = TYPE_FIELD_TYPE (type, type_index); if (cfull_expression) - *cfull_expression = xstrprintf ("((%s)%s%s)", parent_expression, - join, - TYPE_FIELD_NAME (type, type_index)); + *cfull_expression + = xstrprintf ("((%s)%s%s)", parent_expression, + join, + TYPE_FIELD_NAME (type, type_index)); } else if (index < TYPE_N_BASECLASSES (type)) { @@ -3246,7 +3327,8 @@ cplus_describe_child (struct varobj *parent, int index, if (cfull_expression) { char *ptr = was_ptr ? "*" : ""; - /* Cast the parent to the base' type. Note that in gdb, + + /* Cast the parent to the base' type. Note that in gdb, expression like (Base1)d will create an lvalue, for all appearences, so we don't @@ -3264,13 +3346,14 @@ cplus_describe_child (struct varobj *parent, int index, { char *access = NULL; int children[3]; + cplus_class_num_children (type, children); /* Everything beyond the baseclasses can only be "public", "private", or "protected" The special "fake" children are always output by varobj in - this order. So if INDEX == 2, it MUST be "protected". */ + this order. So if INDEX == 2, it MUST be "protected". */ index -= TYPE_N_BASECLASSES (type); switch (index) { @@ -3294,11 +3377,11 @@ cplus_describe_child (struct varobj *parent, int index, access = "protected"; break; case 2: - /* Must be protected */ + /* Must be protected. */ access = "protected"; break; default: - /* error! */ + /* error! */ break; } @@ -3319,6 +3402,7 @@ static char * cplus_name_of_child (struct varobj *parent, int index) { char *name = NULL; + cplus_describe_child (parent, index, &name, NULL, NULL, NULL); return name; } @@ -3341,6 +3425,7 @@ static struct value * cplus_value_of_child (struct varobj *parent, int index) { struct value *value = NULL; + cplus_describe_child (parent, index, NULL, &value, NULL, NULL); return value; } @@ -3349,16 +3434,18 @@ static struct type * cplus_type_of_child (struct varobj *parent, int index) { struct type *type = NULL; + cplus_describe_child (parent, index, NULL, NULL, &type, NULL); return type; } static char * -cplus_value_of_variable (struct varobj *var, enum varobj_display_formats format) +cplus_value_of_variable (struct varobj *var, + enum varobj_display_formats format) { /* If we have one of our special types, don't print out - any value. */ + any value. */ if (CPLUS_FAKE_CHILD (var)) return xstrdup (""); @@ -3380,7 +3467,7 @@ java_name_of_variable (struct varobj *parent) name = cplus_name_of_variable (parent); /* If the name has "-" in it, it is because we - needed to escape periods in the name... */ + needed to escape periods in the name... */ p = name; while (*p != '\000') @@ -3399,7 +3486,7 @@ 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... */ + /* Escape any periods in the name... */ p = name; while (*p != '\000') @@ -3470,12 +3557,11 @@ _initialize_varobj (void) memset (varobj_table, 0, sizeof_table); add_setshow_zinteger_cmd ("debugvarobj", class_maintenance, - &varobjdebug, _("\ -Set varobj debugging."), _("\ -Show varobj debugging."), _("\ -When non-zero, varobj debugging is enabled."), - NULL, - show_varobjdebug, + &varobjdebug, + _("Set varobj debugging."), + _("Show varobj debugging."), + _("When non-zero, varobj debugging is enabled."), + NULL, show_varobjdebug, &setlist, &showlist); }