X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvarobj.c;h=84588364e2189d9d11455ddd3d8f81b47279bbba;hb=bd712aed2f88ab824d403c55a212c2be3f41a335;hp=d1b5c33f18888fce3f9d78a8acb362571d1e810b;hpb=7a290c40a913feccadbe946ea56b5abbc5648a1c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/varobj.c b/gdb/varobj.c index d1b5c33f18..84588364e2 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -1,6 +1,6 @@ /* Implementation of the GDB variable objects API. - Copyright (C) 1999-2012 Free Software Foundation, Inc. + Copyright (C) 1999-2013 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 @@ -33,6 +33,8 @@ #include "vec.h" #include "gdbthread.h" #include "inferior.h" +#include "ada-varobj.h" +#include "ada-lang.h" #if HAVE_PYTHON #include "python/python.h" @@ -47,7 +49,7 @@ typedef int PyObject; /* Non-zero if we want to see trace of varobj level stuff. */ -int varobjdebug = 0; +unsigned int varobjdebug = 0; static void show_varobjdebug (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) @@ -82,7 +84,7 @@ struct varobj_root struct expression *exp; /* Block for which this expression is valid. */ - struct block *valid_block; + const struct block *valid_block; /* The frame for this expression. This field is set iff valid_block is not NULL. */ @@ -268,6 +270,9 @@ static void cppush (struct cpstack **pstack, char *name); static char *cppop (struct cpstack **pstack); +static int update_type_if_necessary (struct varobj *var, + struct value *new_value); + static int install_new_value (struct varobj *var, struct value *value, int initial); @@ -304,6 +309,8 @@ static struct varobj *varobj_add_child (struct varobj *var, #endif /* HAVE_PYTHON */ +static int default_value_is_changeable_p (struct varobj *var); + /* C implementation */ static int c_number_of_children (struct varobj *var); @@ -382,6 +389,8 @@ static struct type *ada_type_of_child (struct varobj *parent, int index); static char *ada_value_of_variable (struct varobj *var, enum varobj_display_formats format); +static int ada_value_is_changeable_p (struct varobj *var); + static int ada_value_has_mutated (struct varobj *var, struct value *new_val, struct type *new_type); @@ -419,6 +428,16 @@ struct language_specific char *(*value_of_variable) (struct varobj * var, enum varobj_display_formats format); + /* Return non-zero if changes in value of VAR must be detected and + reported by -var-update. Return zero if -var-update should never + report changes of such values. This makes sense for structures + (since the changes in children values will be reported separately), + or for artifical objects (like 'public' pseudo-field in C++). + + Return value of 0 means that gdb need not call value_fetch_lazy + for the value of this variable object. */ + int (*value_is_changeable_p) (struct varobj *var); + /* Return nonzero if the type of VAR has mutated. VAR's value is still the varobj's previous value, while NEW_VALUE @@ -448,6 +467,7 @@ static struct language_specific languages[vlang_end] = { c_value_of_child, c_type_of_child, c_value_of_variable, + default_value_is_changeable_p, NULL /* value_has_mutated */} , /* C */ @@ -461,6 +481,7 @@ static struct language_specific languages[vlang_end] = { c_value_of_child, c_type_of_child, c_value_of_variable, + default_value_is_changeable_p, NULL /* value_has_mutated */} , /* C++ */ @@ -474,6 +495,7 @@ static struct language_specific languages[vlang_end] = { cplus_value_of_child, cplus_type_of_child, cplus_value_of_variable, + default_value_is_changeable_p, NULL /* value_has_mutated */} , /* Java */ @@ -487,6 +509,7 @@ static struct language_specific languages[vlang_end] = { java_value_of_child, java_type_of_child, java_value_of_variable, + default_value_is_changeable_p, NULL /* value_has_mutated */}, /* Ada */ { @@ -499,6 +522,7 @@ static struct language_specific languages[vlang_end] = { ada_value_of_child, ada_type_of_child, ada_value_of_variable, + ada_value_is_changeable_p, ada_value_has_mutated} }; @@ -596,10 +620,11 @@ varobj_create (char *objname, struct frame_info *fi; struct frame_id old_id = null_frame_id; struct block *block; - char *p; + const char *p; enum varobj_languages lang; struct value *value = NULL; volatile struct gdb_exception except; + CORE_ADDR pc; /* Parse and evaluate the expression, filling in as much of the variable's data as possible. */ @@ -626,9 +651,13 @@ varobj_create (char *objname, if (type == USE_SELECTED_FRAME) var->root->floating = 1; + pc = 0; block = NULL; if (fi != NULL) - block = get_frame_block (fi, 0); + { + block = get_frame_block (fi, 0); + pc = get_frame_pc (fi); + } p = expression; innermost_block = NULL; @@ -636,7 +665,7 @@ varobj_create (char *objname, return a sensible error. */ TRY_CATCH (except, RETURN_MASK_ERROR) { - var->root->exp = parse_exp_1 (&p, block, 0); + var->root->exp = parse_exp_1 (&p, pc, block, 0); } if (except.reason < 0) @@ -646,7 +675,9 @@ varobj_create (char *objname, } /* Don't allow variables to be created for types. */ - if (var->root->exp->elts[0].opcode == OP_TYPE) + if (var->root->exp->elts[0].opcode == OP_TYPE + || var->root->exp->elts[0].opcode == OP_TYPEOF + || var->root->exp->elts[0].opcode == OP_DECLTYPE) { do_cleanups (old_chain); fprintf_unfiltered (gdb_stderr, "Attempt to use a type name" @@ -695,15 +726,21 @@ varobj_create (char *objname, var->type = value_type (type_only_value); } - else - var->type = value_type (value); + else + { + int real_type_found = 0; - install_new_value (var, value, 1 /* Initial assignment */); + var->type = value_actual_type (value, 0, &real_type_found); + if (real_type_found) + value = value_cast (var->type, value); + } /* Set language info */ lang = variable_language (var); var->root->lang = &languages[lang]; + install_new_value (var, value, 1 /* Initial assignment */); + /* Set ourselves as our root. */ var->root->rootvar = var; @@ -984,6 +1021,7 @@ restrict_range (VEC (varobj_p) *children, int *from, int *to) static void install_dynamic_child (struct varobj *var, VEC (varobj_p) **changed, + VEC (varobj_p) **type_changed, VEC (varobj_p) **new, VEC (varobj_p) **unchanged, int *cchanged, @@ -1006,12 +1044,18 @@ install_dynamic_child (struct varobj *var, { varobj_p existing = VEC_index (varobj_p, var->children, index); + int type_updated = update_type_if_necessary (existing, value); + if (type_updated) + { + if (type_changed) + VEC_safe_push (varobj_p, *type_changed, existing); + } if (install_new_value (existing, value, 0)) { - if (changed) + if (!type_updated && changed) VEC_safe_push (varobj_p, *changed, existing); } - else if (unchanged) + else if (!type_updated && unchanged) VEC_safe_push (varobj_p, *unchanged, existing); } } @@ -1034,6 +1078,7 @@ dynamic_varobj_has_child_method (struct varobj *var) static int update_dynamic_varobj_children (struct varobj *var, VEC (varobj_p) **changed, + VEC (varobj_p) **type_changed, VEC (varobj_p) **new, VEC (varobj_p) **unchanged, int *cchanged, @@ -1069,9 +1114,6 @@ update_dynamic_varobj_children (struct varobj *var, make_cleanup_py_decref (children); - if (!PyIter_Check (children)) - error (_("Returned value is not iterable")); - Py_XDECREF (var->child_iter); var->child_iter = PyObject_GetIter (children); if (!var->child_iter) @@ -1169,6 +1211,7 @@ update_dynamic_varobj_children (struct varobj *var, if (v == NULL) gdbpy_print_stack (); install_dynamic_child (var, can_mention ? changed : NULL, + can_mention ? type_changed : NULL, can_mention ? new : NULL, can_mention ? unchanged : NULL, can_mention ? cchanged : NULL, i, name, v); @@ -1224,7 +1267,7 @@ varobj_get_num_children (struct varobj *var) /* If we have a dynamic varobj, don't report -1 children. So, try to fetch some children first. */ - update_dynamic_varobj_children (var, NULL, NULL, NULL, &dummy, + update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL, &dummy, 0, 0, 0); } else @@ -1250,8 +1293,8 @@ varobj_list_children (struct varobj *var, int *from, int *to) /* This, in theory, can result in the number of children changing without frontend noticing. But well, calling -var-list-children on the same varobj twice is not something a sane frontend would do. */ - update_dynamic_varobj_children (var, NULL, NULL, NULL, &children_changed, - 0, 0, *to); + update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL, + &children_changed, 0, 0, *to); restrict_range (var->children, from, to); return var->children; } @@ -1426,13 +1469,13 @@ varobj_set_value (struct varobj *var, char *expression) struct expression *exp; struct value *value = NULL; /* Initialize to keep gcc happy. */ int saved_input_radix = input_radix; - char *s = expression; + const char *s = expression; volatile struct gdb_exception except; gdb_assert (varobj_editable_p (var)); input_radix = 10; /* ALWAYS reset to decimal temporarily. */ - exp = parse_exp_1 (&s, 0, 0); + exp = parse_exp_1 (&s, 0, 0, 0); TRY_CATCH (except, RETURN_MASK_ERROR) { value = evaluate_expression (exp); @@ -1598,6 +1641,43 @@ install_new_value_visualizer (struct varobj *var) #endif } +/* When using RTTI to determine variable type it may be changed in runtime when + the variable value is changed. This function checks whether type of varobj + VAR will change when a new value NEW_VALUE is assigned and if it is so + updates the type of VAR. */ + +static int +update_type_if_necessary (struct varobj *var, struct value *new_value) +{ + if (new_value) + { + struct value_print_options opts; + + get_user_print_options (&opts); + if (opts.objectprint) + { + struct type *new_type; + char *curr_type_str, *new_type_str; + + new_type = value_actual_type (new_value, 0, 0); + new_type_str = type_to_string (new_type); + curr_type_str = varobj_get_type (var); + if (strcmp (curr_type_str, new_type_str) != 0) + { + var->type = new_type; + + /* This information may be not valid for a new type. */ + varobj_delete (var, NULL, 1); + VEC_free (varobj_p, var->children); + var->num_children = -1; + return 1; + } + } + } + + return 0; +} + /* Assign a new value to a variable object. If INITIAL is non-zero, this is the first assignement after the variable object was just created, or changed type. In that case, just assign the value @@ -1889,7 +1969,6 @@ varobj_value_has_mutated (struct varobj *var, struct value *new_value, VEC(varobj_update_result) * varobj_update (struct varobj **varp, int explicit) { - int changed = 0; int type_changed = 0; int i; struct value *new; @@ -1927,8 +2006,9 @@ varobj_update (struct varobj **varp, int explicit) value_of_root variable dispose of the varobj if the type has changed. */ new = value_of_root (varp, &type_changed); + if (update_type_if_necessary(*varp, new)) + type_changed = 1; r.varobj = *varp; - r.type_changed = type_changed; if (install_new_value ((*varp), new, type_changed)) r.changed = 1; @@ -1969,6 +2049,8 @@ varobj_update (struct varobj **varp, int explicit) struct type *new_type; new = value_of_child (v->parent, v->index); + if (update_type_if_necessary(v, new)) + r.type_changed = 1; if (new) new_type = value_type (new); else @@ -1998,7 +2080,8 @@ varobj_update (struct varobj **varp, int explicit) invoked. */ if (v->pretty_printer) { - VEC (varobj_p) *changed = 0, *new = 0, *unchanged = 0; + VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0; + VEC (varobj_p) *new = 0; int i, children_changed = 0; if (v->frozen) @@ -2016,7 +2099,7 @@ varobj_update (struct varobj **varp, int explicit) it. */ if (!varobj_has_more (v, 0)) { - update_dynamic_varobj_children (v, NULL, NULL, NULL, + update_dynamic_varobj_children (v, NULL, NULL, NULL, NULL, &dummy, 0, 0, 0); if (varobj_has_more (v, 0)) r.changed = 1; @@ -2030,8 +2113,8 @@ varobj_update (struct varobj **varp, int explicit) /* If update_dynamic_varobj_children returns 0, then we have a non-conforming pretty-printer, so we skip it. */ - if (update_dynamic_varobj_children (v, &changed, &new, &unchanged, - &children_changed, 1, + if (update_dynamic_varobj_children (v, &changed, &type_changed, &new, + &unchanged, &children_changed, 1, v->from, v->to)) { if (children_changed || new) @@ -2043,6 +2126,18 @@ varobj_update (struct varobj **varp, int explicit) popped from the work stack first, and so will be added to result first. This does not affect correctness, just "nicer". */ + for (i = VEC_length (varobj_p, type_changed) - 1; i >= 0; --i) + { + varobj_p tmp = VEC_index (varobj_p, type_changed, i); + varobj_update_result r = {0}; + + /* Type may change only if value was changed. */ + r.varobj = tmp; + r.changed = 1; + r.type_changed = 1; + r.value_installed = 1; + VEC_safe_push (varobj_update_result, stack, &r); + } for (i = VEC_length (varobj_p, changed) - 1; i >= 0; --i) { varobj_p tmp = VEC_index (varobj_p, changed, i); @@ -2069,9 +2164,10 @@ varobj_update (struct varobj **varp, int explicit) if (r.changed || r.children_changed) VEC_safe_push (varobj_update_result, result, &r); - /* Free CHANGED and UNCHANGED, but not NEW, because NEW - has been put into the result vector. */ + /* Free CHANGED, TYPE_CHANGED and UNCHANGED, but not NEW, + because NEW has been put into the result vector. */ VEC_free (varobj_p, changed); + VEC_free (varobj_p, type_changed); VEC_free (varobj_p, unchanged); continue; @@ -2346,7 +2442,7 @@ create_child_with_value (struct varobj *parent, int index, const char *name, if (value != NULL) /* If the child had no evaluation errors, var->value will be non-NULL and contain a valid type. */ - child->type = value_type (value); + child->type = value_actual_type (value, 0, NULL); else /* Otherwise, we must compute the type. */ child->type = (*child->root->lang->type_of_child) (child->parent, @@ -2748,7 +2844,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, { struct ui_file *stb; struct cleanup *old_chain; - gdb_byte *thevalue = NULL; + char *thevalue = NULL; struct value_print_options opts; struct type *type = NULL; long len = 0; @@ -2813,12 +2909,10 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, string_print. Otherwise just return the extracted string as a value. */ - PyObject *py_str - = python_string_to_target_python_string (output); + char *s = python_string_to_target_string (output); - if (py_str) + if (s) { - char *s = PyString_AsString (py_str); char *hint; hint = gdbpy_get_display_hint (value_formatter); @@ -2829,10 +2923,10 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, xfree (hint); } - len = PyString_Size (py_str); + len = strlen (s); thevalue = xmemdup (s, len + 1, len + 1); type = builtin_type (gdbarch)->builtin_char; - Py_DECREF (py_str); + xfree (s); if (!string_print) { @@ -2862,7 +2956,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format, /* If the THEVALUE has contents, it is a regular string. */ if (thevalue) - LA_PRINT_STRING (stb, type, thevalue, len, encoding, 0, &opts); + LA_PRINT_STRING (stb, type, (gdb_byte *) thevalue, len, encoding, 0, &opts); else if (string_print) /* Otherwise, if string_print is set, and it is not a regular string, it is a lazy string. */ @@ -2903,39 +2997,12 @@ varobj_editable_p (struct varobj *var) } } -/* Return non-zero if changes in value of VAR - must be detected and reported by -var-update. - Return zero is -var-update should never report - changes of such values. This makes sense for structures - (since the changes in children values will be reported separately), - or for artifical objects (like 'public' pseudo-field in C++). +/* Call VAR's value_is_changeable_p language-specific callback. */ - Return value of 0 means that gdb need not call value_fetch_lazy - for the value of this variable object. */ static int varobj_value_is_changeable_p (struct varobj *var) { - int r; - struct type *type; - - if (CPLUS_FAKE_CHILD (var)) - return 0; - - type = get_value_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; + return var->root->lang->value_is_changeable_p (var); } /* Return 1 if that varobj is floating, that is is always evaluated in the @@ -2954,6 +3021,10 @@ varobj_floating_p (struct varobj *var) to all types and dereferencing pointers to structures. + If LOOKUP_ACTUAL_TYPE is set the enclosing type of the + value will be fetched and if it differs from static type + the value will be casted to it. + 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 @@ -2965,7 +3036,8 @@ varobj_floating_p (struct varobj *var) static void adjust_value_for_child_access (struct value **value, struct type **type, - int *was_ptr) + int *was_ptr, + int lookup_actual_type) { gdb_assert (type && *type); @@ -3010,9 +3082,53 @@ adjust_value_for_child_access (struct value **value, /* The 'get_target_type' function calls check_typedef on result, so we can immediately check type code. No need to call check_typedef here. */ + + /* Access a real type of the value (if necessary and possible). */ + if (value && *value && lookup_actual_type) + { + struct type *enclosing_type; + int real_type_found = 0; + + enclosing_type = value_actual_type (*value, 1, &real_type_found); + if (real_type_found) + { + *type = enclosing_type; + *value = value_cast (enclosing_type, *value); + } + } +} + +/* Implement the "value_is_changeable_p" varobj callback for most + languages. */ + +static int +default_value_is_changeable_p (struct varobj *var) +{ + int r; + struct type *type; + + if (CPLUS_FAKE_CHILD (var)) + return 0; + + type = get_value_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) { @@ -3020,7 +3136,7 @@ c_number_of_children (struct varobj *var) int children = 0; struct type *target; - adjust_value_for_child_access (NULL, &type, NULL); + adjust_value_for_child_access (NULL, &type, NULL, 0); target = get_target_type (type); switch (TYPE_CODE (type)) @@ -3136,7 +3252,7 @@ c_describe_child (struct varobj *parent, int index, *cfull_expression = NULL; parent_expression = varobj_get_path_expr (get_path_expr_parent (parent)); } - adjust_value_for_child_access (&value, &type, &was_ptr); + adjust_value_for_child_access (&value, &type, &was_ptr, 0); switch (TYPE_CODE (type)) { @@ -3432,16 +3548,29 @@ c_value_of_variable (struct varobj *var, enum varobj_display_formats format) static int cplus_number_of_children (struct varobj *var) { + struct value *value = NULL; struct type *type; int children, dont_know; + int lookup_actual_type = 0; + struct value_print_options opts; dont_know = 1; children = 0; + get_user_print_options (&opts); + if (!CPLUS_FAKE_CHILD (var)) { type = get_value_type (var); - adjust_value_for_child_access (NULL, &type, NULL); + + /* It is necessary to access a real type (via RTTI). */ + if (opts.objectprint) + { + value = var->value; + lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF + || TYPE_CODE (var->type) == TYPE_CODE_PTR); + } + adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type); if (((TYPE_CODE (type)) == TYPE_CODE_STRUCT) || ((TYPE_CODE (type)) == TYPE_CODE_UNION)) @@ -3468,7 +3597,17 @@ cplus_number_of_children (struct varobj *var) int kids[3]; type = get_value_type (var->parent); - adjust_value_for_child_access (NULL, &type, NULL); + + /* It is necessary to access a real type (via RTTI). */ + if (opts.objectprint) + { + struct varobj *parent = var->parent; + + value = parent->value; + lookup_actual_type = (TYPE_CODE (parent->type) == TYPE_CODE_REF + || TYPE_CODE (parent->type) == TYPE_CODE_PTR); + } + adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type); cplus_class_num_children (type, kids); if (strcmp (var->name, "public") == 0) @@ -3550,7 +3689,10 @@ cplus_describe_child (struct varobj *parent, int index, struct value *value; struct type *type; int was_ptr; + int lookup_actual_type = 0; char *parent_expression = NULL; + struct varobj *var; + struct value_print_options opts; if (cname) *cname = NULL; @@ -3561,24 +3703,18 @@ cplus_describe_child (struct varobj *parent, int index, if (cfull_expression) *cfull_expression = NULL; - if (CPLUS_FAKE_CHILD (parent)) - { - value = parent->parent->value; - type = get_value_type (parent->parent); - if (cfull_expression) - parent_expression - = varobj_get_path_expr (get_path_expr_parent (parent->parent)); - } - else - { - value = parent->value; - type = get_value_type (parent); - if (cfull_expression) - parent_expression - = varobj_get_path_expr (get_path_expr_parent (parent)); - } + get_user_print_options (&opts); + + var = (CPLUS_FAKE_CHILD (parent)) ? parent->parent : parent; + if (opts.objectprint) + lookup_actual_type = (TYPE_CODE (var->type) == TYPE_CODE_REF + || TYPE_CODE (var->type) == TYPE_CODE_PTR); + value = var->value; + type = get_value_type (var); + if (cfull_expression) + parent_expression = varobj_get_path_expr (get_path_expr_parent (var)); - adjust_value_for_child_access (&value, &type, &was_ptr); + adjust_value_for_child_access (&value, &type, &was_ptr, lookup_actual_type); if (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION) @@ -3881,7 +4017,7 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format) static int ada_number_of_children (struct varobj *var) { - return c_number_of_children (var); + return ada_varobj_get_number_of_children (var->value, var->type); } static char * @@ -3893,13 +4029,21 @@ ada_name_of_variable (struct varobj *parent) static char * ada_name_of_child (struct varobj *parent, int index) { - return c_name_of_child (parent, index); + return ada_varobj_get_name_of_child (parent->value, parent->type, + parent->name, index); } static char* ada_path_expr_of_child (struct varobj *child) { - return c_path_expr_of_child (child); + struct varobj *parent = child->parent; + const char *parent_path_expr = varobj_get_path_expr (parent); + + return ada_varobj_get_path_expr_of_child (parent->value, + parent->type, + parent->name, + parent_path_expr, + child->index); } static struct value * @@ -3911,19 +4055,53 @@ ada_value_of_root (struct varobj **var_handle) static struct value * ada_value_of_child (struct varobj *parent, int index) { - return c_value_of_child (parent, index); + return ada_varobj_get_value_of_child (parent->value, parent->type, + parent->name, index); } static struct type * ada_type_of_child (struct varobj *parent, int index) { - return c_type_of_child (parent, index); + return ada_varobj_get_type_of_child (parent->value, parent->type, + index); } static char * ada_value_of_variable (struct varobj *var, enum varobj_display_formats format) { - return c_value_of_variable (var, format); + struct value_print_options opts; + + get_formatted_print_options (&opts, format_code[(int) format]); + opts.deref_ref = 0; + opts.raw = 1; + + return ada_varobj_get_value_of_variable (var->value, var->type, &opts); +} + +/* Implement the "value_is_changeable_p" routine for Ada. */ + +static int +ada_value_is_changeable_p (struct varobj *var) +{ + struct type *type = var->value ? value_type (var->value) : var->type; + + if (ada_is_array_descriptor_type (type) + && TYPE_CODE (type) == TYPE_CODE_TYPEDEF) + { + /* This is in reality a pointer to an unconstrained array. + its value is changeable. */ + return 1; + } + + if (ada_is_string_type (type)) + { + /* We display the contents of the string in the array's + "value" field. The contents can change, so consider + that the array is changeable. */ + return 1; + } + + return default_value_is_changeable_p (var); } /* Implement the "value_has_mutated" routine for Ada. */ @@ -3932,7 +4110,36 @@ static int ada_value_has_mutated (struct varobj *var, struct value *new_val, struct type *new_type) { - /* Unimplemented for now. */ + int i; + int from = -1; + int to = -1; + + /* If the number of fields have changed, then for sure the type + has mutated. */ + if (ada_varobj_get_number_of_children (new_val, new_type) + != var->num_children) + return 1; + + /* If the number of fields have remained the same, then we need + to check the name of each field. If they remain the same, + then chances are the type hasn't mutated. This is technically + an incomplete test, as the child's type might have changed + despite the fact that the name remains the same. But we'll + handle this situation by saying that the child has mutated, + not this value. + + If only part (or none!) of the children have been fetched, + then only check the ones we fetched. It does not matter + to the frontend whether a child that it has not fetched yet + has mutated or not. So just assume it hasn't. */ + + restrict_range (var->children, &from, &to); + for (i = from; i < to; i++) + if (strcmp (ada_varobj_get_name_of_child (new_val, new_type, + var->name, i), + VEC_index (varobj_p, var->children, i)->name) != 0) + return 1; + return 0; } @@ -3963,28 +4170,27 @@ _initialize_varobj (void) varobj_table = xmalloc (sizeof_table); 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, - &setlist, &showlist); + add_setshow_zuinteger_cmd ("debugvarobj", class_maintenance, + &varobjdebug, + _("Set varobj debugging."), + _("Show varobj debugging."), + _("When non-zero, varobj debugging is enabled."), + NULL, show_varobjdebug, + &setlist, &showlist); } /* Invalidate varobj VAR if it is tied to locals and re-create it if it is - defined on globals. It is a helper for varobj_invalidate. */ + defined on globals. It is a helper for varobj_invalidate. + + This function is called after changing the symbol file, in this case the + pointers to "struct type" stored by the varobj are no longer valid. All + varobj must be either re-evaluated, or marked as invalid here. */ static void varobj_invalidate_iter (struct varobj *var, void *unused) { - /* Floating varobjs are reparsed on each stop, so we don't care if the - presently parsed expression refers to something that's gone. */ - if (var->root->floating) - return; - - /* global var must be re-evaluated. */ - if (var->root->valid_block == NULL) + /* global and floating var must be re-evaluated. */ + if (var->root->floating || var->root->valid_block == NULL) { struct varobj *tmp_var;