+/* 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
+ and return 0.
+ Otherwise, assign the value and if type_changeable returns non-zero,
+ find if the new value is different from the current value.
+ Return 1 if so, and 0 if the values are equal.
+
+ The VALUE parameter should not be released -- the function will
+ take care of releasing it when needed. */
+static int
+install_new_value (struct varobj *var, struct value *value, int initial)
+{
+ int changeable;
+ int need_to_fetch;
+ int changed = 0;
+ int intentionally_not_fetched = 0;
+ 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. */
+ gdb_assert (var->type || CPLUS_FAKE_CHILD (var));
+ changeable = varobj_value_is_changeable_p (var);
+ need_to_fetch = changeable;
+
+ /* We are not interested in the address of references, and given
+ that in C++ a reference is not rebindable, it cannot
+ meaningfully change. So, get hold of the real value. */
+ if (value)
+ {
+ value = coerce_ref (value);
+ release_value (value);
+ }
+
+ if (var->type && TYPE_CODE (var->type) == TYPE_CODE_UNION)
+ /* For unions, we need to fetch the value implicitly because
+ of implementation of union member fetch. When gdb
+ creates a value for a field and the value of the enclosing
+ structure is not lazy, it immediately copies the necessary
+ bytes from the enclosing values. If the enclosing value is
+ lazy, the call to value_fetch_lazy on the field will read
+ the data from memory. For unions, that means we'll read the
+ same memory more than once, which is not desirable. So
+ fetch now. */
+ need_to_fetch = 1;
+
+ /* The new value might be lazy. If the type is changeable,
+ that is we'll be comparing values of this type, fetch the
+ value now. Otherwise, on the next update the old value
+ will be lazy, which means we've lost that old value. */
+ if (need_to_fetch && value && value_lazy (value))
+ {
+ struct varobj *parent = var->parent;
+ int frozen = var->frozen;
+ for (; !frozen && parent; parent = parent->parent)
+ frozen |= parent->frozen;
+
+ if (frozen && initial)
+ {
+ /* For variables that are frozen, or are children of frozen
+ variables, we don't do fetch on initial assignment.
+ For non-initial assignemnt we do the fetch, since it means we're
+ explicitly asked to compare the new value with the old one. */
+ intentionally_not_fetched = 1;
+ }
+ else if (!gdb_value_fetch_lazy (value))
+ {
+ /* Set the value to NULL, so that for the next -var-update,
+ we don't try to compare the new value with this value,
+ that we couldn't even read. */
+ value = NULL;
+ }
+ }
+
+ /* Below, we'll be comparing string rendering of old and new
+ values. Don't get string rendering if the value is
+ lazy -- if it is, the code above has decided that the value
+ should not be fetched. */
+ if (value && !value_lazy (value))
+ print_value = value_get_print_value (value, var->format);
+
+ /* If the type is changeable, compare the old and the new values.
+ If this is the initial assignment, we don't have any old value
+ 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 (var->updated)
+ {
+ changed = 1;
+ }
+ else
+ {
+ /* Try to compare the values. That requires that both
+ values are non-lazy. */
+ if (var->not_fetched && value_lazy (var->value))
+ {
+ /* This is a frozen varobj and the value was never read.
+ Presumably, UI shows some "never read" indicator.
+ Now that we've fetched the real value, we need to report
+ this varobj as changed so that UI can show the real
+ value. */
+ changed = 1;
+ }
+ else if (var->value == NULL && value == NULL)
+ /* Equal. */
+ ;
+ else if (var->value == NULL || value == NULL)
+ {
+ changed = 1;
+ }
+ else
+ {
+ gdb_assert (!value_lazy (var->value));
+ gdb_assert (!value_lazy (value));
+
+ gdb_assert (var->print_value != NULL && print_value != NULL);
+ if (strcmp (var->print_value, print_value) != 0)
+ changed = 1;
+ }
+ }
+ }
+
+ /* We must always keep the new value, since children depend on it. */
+ if (var->value != NULL && var->value != value)
+ value_free (var->value);
+ var->value = value;
+ if (var->print_value)
+ xfree (var->print_value);
+ var->print_value = print_value;
+ if (value && value_lazy (value) && intentionally_not_fetched)
+ var->not_fetched = 1;
+ else
+ var->not_fetched = 0;
+ var->updated = 0;
+
+ gdb_assert (!var->value || value_type (var->value));
+
+ return changed;
+}
+