diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/varobj.c | 113 |
2 files changed, 115 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d055d38..7eeae6d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2012-03-28 Joel Brobecker <brobecker@adacore.com> + + * varobj.c (ada_value_has_mutated): Add declaration. New function. + (struct language_specific): New field "value_has_mutated". + (languages): Set field "value_has_mutated" in each entry of array. + (varobj_value_has_mutated): New function. + (varobj_udpdate): Add handling of type mutation. + (value_of_root): Add handling of type mutation. + (ada_value_has_mutated): New function. + 2012-03-28 Pedro Alves <palves@redhat.com> * ia64-linux-nat.c (supply_fpregset, ia64_linux_fetch_register): diff --git a/gdb/varobj.c b/gdb/varobj.c index b6e67c6..d1b5c33 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -382,6 +382,9 @@ 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_has_mutated (struct varobj *var, struct value *new_val, + struct type *new_type); + /* The language specific vector */ struct language_specific @@ -415,6 +418,21 @@ struct language_specific /* The current value of VAR. */ char *(*value_of_variable) (struct varobj * var, enum varobj_display_formats format); + + /* Return nonzero if the type of VAR has mutated. + + VAR's value is still the varobj's previous value, while NEW_VALUE + is VAR's new value and NEW_TYPE is the var's new type. NEW_VALUE + may be NULL indicating that there is no value available (the varobj + may be out of scope, of may be the child of a null pointer, for + instance). NEW_TYPE, on the other hand, must never be NULL. + + This function should also be able to assume that var's number of + children is set (not < 0). + + Languages where types do not mutate can set this to NULL. */ + int (*value_has_mutated) (struct varobj *var, struct value *new_value, + struct type *new_type); }; /* Array of known source language routines. */ @@ -429,7 +447,8 @@ static struct language_specific languages[vlang_end] = { c_value_of_root, c_value_of_child, c_type_of_child, - c_value_of_variable} + c_value_of_variable, + NULL /* value_has_mutated */} , /* C */ { @@ -441,7 +460,8 @@ static struct language_specific languages[vlang_end] = { c_value_of_root, c_value_of_child, c_type_of_child, - c_value_of_variable} + c_value_of_variable, + NULL /* value_has_mutated */} , /* C++ */ { @@ -453,7 +473,8 @@ static struct language_specific languages[vlang_end] = { cplus_value_of_root, cplus_value_of_child, cplus_type_of_child, - cplus_value_of_variable} + cplus_value_of_variable, + NULL /* value_has_mutated */} , /* Java */ { @@ -465,7 +486,8 @@ static struct language_specific languages[vlang_end] = { java_value_of_root, java_value_of_child, java_type_of_child, - java_value_of_variable}, + java_value_of_variable, + NULL /* value_has_mutated */}, /* Ada */ { vlang_ada, @@ -476,7 +498,8 @@ static struct language_specific languages[vlang_end] = { ada_value_of_root, ada_value_of_child, ada_type_of_child, - ada_value_of_variable} + ada_value_of_variable, + ada_value_has_mutated} }; /* A little convenience enum for dealing with C++/Java. */ @@ -1824,6 +1847,30 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer) #endif } +/* If NEW_VALUE is the new value of the given varobj (var), return + non-zero if var has mutated. In other words, if the type of + the new value is different from the type of the varobj's old + value. + + NEW_VALUE may be NULL, if the varobj is now out of scope. */ + +static int +varobj_value_has_mutated (struct varobj *var, struct value *new_value, + struct type *new_type) +{ + /* If we haven't previously computed the number of children in var, + it does not matter from the front-end's perspective whether + the type has mutated or not. For all intents and purposes, + it has not mutated. */ + if (var->num_children < 0) + return 0; + + if (var->root->lang->value_has_mutated) + return var->root->lang->value_has_mutated (var, new_value, new_type); + else + return 0; +} + /* 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 @@ -1918,9 +1965,28 @@ varobj_update (struct varobj **varp, int explicit) /* Update this variable, unless it's a root, which is already updated. */ if (!r.value_installed) - { + { + struct type *new_type; + new = value_of_child (v->parent, v->index); - if (install_new_value (v, new, 0 /* type not changed */)) + if (new) + new_type = value_type (new); + else + new_type = v->root->lang->type_of_child (v->parent, v->index); + + if (varobj_value_has_mutated (v, new, new_type)) + { + /* The children are no longer valid; delete them now. + Report the fact that its type changed as well. */ + varobj_delete (v, NULL, 1 /* only_children */); + v->num_children = -1; + v->to = -1; + v->from = -1; + v->type = new_type; + r.type_changed = 1; + } + + if (install_new_value (v, new, r.type_changed)) { r.changed = 1; v->updated = 0; @@ -2627,7 +2693,28 @@ value_of_root (struct varobj **var_handle, int *type_changed) *type_changed = 0; } - return (*var->root->lang->value_of_root) (var_handle); + { + struct value *value; + + value = (*var->root->lang->value_of_root) (var_handle); + if (var->value == NULL || value == NULL) + { + /* For root varobj-s, a NULL value indicates a scoping issue. + So, nothing to do in terms of checking for mutations. */ + } + else if (varobj_value_has_mutated (var, value, value_type (value))) + { + /* The type has mutated, so the children are no longer valid. + Just delete them, and tell our caller that the type has + changed. */ + varobj_delete (var, NULL, 1 /* only_children */); + var->num_children = -1; + var->to = -1; + var->from = -1; + *type_changed = 1; + } + return value; + } } /* What is the ``struct value *'' for the INDEX'th child of PARENT? */ @@ -3839,6 +3926,16 @@ ada_value_of_variable (struct varobj *var, enum varobj_display_formats format) return c_value_of_variable (var, format); } +/* Implement the "value_has_mutated" routine for Ada. */ + +static int +ada_value_has_mutated (struct varobj *var, struct value *new_val, + struct type *new_type) +{ + /* Unimplemented for now. */ + return 0; +} + /* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them with an arbitrary caller supplied DATA pointer. */ |