/* Implementation of the GDB variable objects API.
- Copyright (C) 1999-2015 Free Software Foundation, Inc.
+ Copyright (C) 1999-2016 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
/* String representations of gdb's format codes. */
char *varobj_format_string[] =
- { "natural", "binary", "decimal", "hexadecimal", "octal" };
+ { "natural", "binary", "decimal", "hexadecimal", "octal", "zero-hexadecimal" };
/* True if we want to allow Python-based pretty-printing. */
static int pretty_printing = 0;
not NULL. */
struct frame_id frame;
- /* The thread ID that this varobj_root belong to. This field
+ /* The global thread ID that this varobj_root belongs to. This field
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
static struct value *value_of_root (struct varobj **var_handle, int *);
-static struct value *value_of_child (struct varobj *parent, int index);
+static struct value *value_of_child (const struct varobj *parent, int index);
static char *my_value_of_variable (struct varobj *var,
enum varobj_display_formats format);
/* Private data */
/* Mappings of varobj_display_formats enums to gdb's format codes. */
-static int format_code[] = { 0, 't', 'd', 'x', 'o' };
+static int format_code[] = { 0, 't', 'd', 'x', 'o', 'z' };
/* 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. */
+/* A prime large enough to avoid too many collisions. */
#define VAROBJ_TABLE_SIZE 227
/* Pointer to the varobj hash table (built at run time). */
}
#endif
-/* 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. */
return NULL;
}
+/* Creates a varobj (not its children). */
+
struct varobj *
varobj_create (char *objname,
char *expression, CORE_ADDR frame, enum varobj_type type)
const struct block *block;
const char *p;
struct value *value = NULL;
- volatile struct gdb_exception except;
CORE_ADDR pc;
/* Parse and evaluate the expression, filling in as much of the
innermost_block = NULL;
/* Wrap the call to parse expression, so we can
return a sensible error. */
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
var->root->exp = parse_exp_1 (&p, pc, block, 0);
}
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ERROR)
{
do_cleanups (old_chain);
return NULL;
}
+ END_CATCH
/* Don't allow variables to be created for types. */
if (var->root->exp->elts[0].opcode == OP_TYPE
error (_("Failed to find the specified frame"));
var->root->frame = get_frame_id (fi);
- var->root->thread_id = pid_to_thread_id (inferior_ptid);
+ var->root->thread_id = ptid_to_global_thread_id (inferior_ptid);
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(). */
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
value = evaluate_expression (var->root->exp);
}
-
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ERROR)
{
/* Error getting the value. Try to at least get the
right type. */
var->type = value_type (type_only_value);
}
- else
- {
- int real_type_found = 0;
+ END_CATCH
- var->type = value_actual_type (value, 0, &real_type_found);
- if (real_type_found)
- value = value_cast (var->type, value);
- }
+ if (value != NULL)
+ {
+ int real_type_found = 0;
+
+ var->type = value_actual_type (value, 0, &real_type_found);
+ if (real_type_found)
+ value = value_cast (var->type, value);
+ }
/* Set language info */
var->root->lang_ops = var->root->exp->language_defn->la_varobj_ops;
/* We may have been asked to return a list of what has been deleted. */
if (dellist != NULL)
{
- *dellist = xmalloc ((delcount + 1) * sizeof (char *));
+ *dellist = XNEWVEC (char *, delcount + 1);
cp = *dellist;
mycount = delcount;
case FORMAT_DECIMAL:
case FORMAT_HEXADECIMAL:
case FORMAT_OCTAL:
+ case FORMAT_ZHEXADECIMAL:
var->format = format;
break;
install_dynamic_child (struct varobj *var,
VEC (varobj_p) **changed,
VEC (varobj_p) **type_changed,
- VEC (varobj_p) **new,
+ VEC (varobj_p) **newobj,
VEC (varobj_p) **unchanged,
int *cchanged,
int index,
/* There's no child yet. */
struct varobj *child = varobj_add_child (var, item);
- if (new)
+ if (newobj)
{
- VEC_safe_push (varobj_p, *new, child);
+ VEC_safe_push (varobj_p, *newobj, child);
*cchanged = 1;
}
}
update_dynamic_varobj_children (struct varobj *var,
VEC (varobj_p) **changed,
VEC (varobj_p) **type_changed,
- VEC (varobj_p) **new,
+ VEC (varobj_p) **newobj,
VEC (varobj_p) **unchanged,
int *cchanged,
int update_children,
install_dynamic_child (var, can_mention ? changed : NULL,
can_mention ? type_changed : NULL,
- can_mention ? new : NULL,
+ can_mention ? newobj : NULL,
can_mention ? unchanged : NULL,
can_mention ? cchanged : NULL, i,
item);
/* Return the path expression parent for VAR. */
-struct varobj *
-varobj_get_path_expr_parent (struct varobj *var)
+const struct varobj *
+varobj_get_path_expr_parent (const struct varobj *var)
{
- struct varobj *parent = var;
+ const struct varobj *parent = var;
while (!is_root_p (parent) && !is_path_expr_parent (parent))
parent = parent->parent;
/* Return a pointer to the full rooted expression of varobj VAR.
If it has not been computed yet, compute it. */
char *
-varobj_get_path_expr (struct varobj *var)
+varobj_get_path_expr (const struct varobj *var)
{
if (var->path_expr == NULL)
{
/* For root varobjs, we initialize path_expr
when creating varobj, so here it should be
child varobj. */
+ struct varobj *mutable_var = (struct varobj *) var;
gdb_assert (!is_root_p (var));
- var->path_expr = (*var->root->lang_ops->path_expr_of_child) (var);
+ mutable_var->path_expr = (*var->root->lang_ops->path_expr_of_child) (var);
}
return var->path_expr;
struct value *value = NULL; /* Initialize to keep gcc happy. */
int saved_input_radix = input_radix;
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, 0);
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
value = evaluate_expression (exp);
}
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ERROR)
{
/* We cannot proceed without a valid expression. */
xfree (exp);
return 0;
}
+ END_CATCH
/* All types that are editable must also be changeable. */
gdb_assert (varobj_value_is_changeable_p (var));
/* The new value may be lazy. value_assign, or
rather value_contents, will take care of this. */
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
val = value_assign (var->value, value);
}
- if (except.reason < 0)
- return 0;
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ return 0;
+ }
+ END_CATCH
/* If the value has changed, record it, so that next -var-update can
report this change. If a variable had a value of '1', we've set it
will be lazy, which means we've lost that old value. */
if (need_to_fetch && value && value_lazy (value))
{
- struct varobj *parent = var->parent;
+ const struct varobj *parent = var->parent;
int frozen = var->frozen;
for (; !frozen && parent; parent = parent->parent)
}
else
{
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
value_fetch_lazy (value);
}
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ERROR)
{
/* 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;
}
+ END_CATCH
}
}
to point to the new varobj. */
VEC(varobj_update_result) *
-varobj_update (struct varobj **varp, int explicit)
+varobj_update (struct varobj **varp, int is_explicit)
{
int type_changed = 0;
int i;
- struct value *new;
+ struct value *newobj;
VEC (varobj_update_result) *stack = NULL;
VEC (varobj_update_result) *result = NULL;
changing type. One use case for frozen varobjs is
retaining previously evaluated expressions, and we don't
want them to be reevaluated at all. */
- if (!explicit && (*varp)->frozen)
+ if (!is_explicit && (*varp)->frozen)
return result;
if (!(*varp)->root->is_valid)
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);
- if (update_type_if_necessary(*varp, new))
+ newobj = value_of_root (varp, &type_changed);
+ if (update_type_if_necessary(*varp, newobj))
type_changed = 1;
r.varobj = *varp;
r.type_changed = type_changed;
- if (install_new_value ((*varp), new, type_changed))
+ if (install_new_value ((*varp), newobj, type_changed))
r.changed = 1;
- if (new == NULL)
+ if (newobj == NULL)
r.status = VAROBJ_NOT_IN_SCOPE;
r.value_installed = 1;
{
struct type *new_type;
- new = value_of_child (v->parent, v->index);
- if (update_type_if_necessary(v, new))
+ newobj = value_of_child (v->parent, v->index);
+ if (update_type_if_necessary(v, newobj))
r.type_changed = 1;
- if (new)
- new_type = value_type (new);
+ if (newobj)
+ new_type = value_type (newobj);
else
new_type = v->root->lang_ops->type_of_child (v->parent, v->index);
- if (varobj_value_has_mutated (v, new, new_type))
+ if (varobj_value_has_mutated (v, newobj, new_type))
{
/* The children are no longer valid; delete them now.
Report the fact that its type changed as well. */
r.type_changed = 1;
}
- if (install_new_value (v, new, r.type_changed))
+ if (install_new_value (v, newobj, r.type_changed))
{
r.changed = 1;
v->updated = 0;
if (varobj_is_dynamic_p (v))
{
VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0;
- VEC (varobj_p) *new = 0;
+ VEC (varobj_p) *newobj = 0;
int i, children_changed = 0;
if (v->frozen)
/* 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, &type_changed, &new,
+ if (update_dynamic_varobj_children (v, &changed, &type_changed, &newobj,
&unchanged, &children_changed, 1,
v->from, v->to))
{
- if (children_changed || new)
+ if (children_changed || newobj)
{
r.children_changed = 1;
- r.new = new;
+ r.newobj = newobj;
}
/* Push in reverse order so that the first child is
popped from the work stack first, and so will be
error (_("Duplicate variable object name"));
/* Add varobj to hash table. */
- newvl = xmalloc (sizeof (struct vlist));
+ newvl = XNEW (struct vlist);
newvl->next = *(varobj_table + index);
newvl->var = var;
*(varobj_table + index) = newvl;
{
struct varobj *var;
- var = (struct varobj *) xmalloc (sizeof (struct varobj));
+ var = XNEW (struct varobj);
var->name = NULL;
var->path_expr = NULL;
var->obj_name = NULL;
var->num_children = -1;
var->parent = NULL;
var->children = NULL;
- var->format = 0;
+ var->format = FORMAT_NATURAL;
var->root = NULL;
var->updated = 0;
var->print_value = NULL;
var->frozen = 0;
var->not_fetched = 0;
- var->dynamic
- = (struct varobj_dynamic *) xmalloc (sizeof (struct varobj_dynamic));
+ var->dynamic = XNEW (struct varobj_dynamic);
var->dynamic->children_requested = 0;
var->from = -1;
var->to = -1;
{
struct varobj *var = new_variable ();
- var->root = (struct varobj_root *) xmalloc (sizeof (struct varobj_root));
+ var->root = XNEW (struct varobj_root);
var->root->lang_ops = NULL;
var->root->exp = NULL;
var->root->valid_block = NULL;
static void
do_free_variable_cleanup (void *var)
{
- free_variable (var);
+ free_variable ((struct varobj *) var);
}
static struct cleanup *
{
struct cpstack *s;
- s = (struct cpstack *) xmalloc (sizeof (struct cpstack));
+ s = XNEW (struct cpstack);
s->name = name;
s->next = *pstack;
*pstack = s;
}
else
{
- ptid_t ptid = thread_id_to_pid (var->root->thread_id);
- if (in_thread_list (ptid))
+ ptid_t ptid = global_thread_id_to_ptid (var->root->thread_id);
+
+ if (!ptid_equal (minus_one_ptid, ptid))
{
switch_to_thread (ptid);
within_scope = check_scope (var);
if (within_scope)
{
- volatile struct gdb_exception except;
/* We need to catch errors here, because if evaluate
expression fails we want to just return NULL. */
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
new_val = evaluate_expression (var->root->exp);
}
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ }
+ END_CATCH
}
do_cleanups (back_to);
/* What is the ``struct value *'' for the INDEX'th child of PARENT? */
static struct value *
-value_of_child (struct varobj *parent, int index)
+value_of_child (const struct varobj *parent, int index)
{
struct value *value;
}
len = strlen (s);
- thevalue = xmemdup (s, len + 1, len + 1);
+ thevalue = (char *) xmemdup (s, len + 1, len + 1);
type = builtin_type (gdbarch)->builtin_char;
xfree (s);
void
_initialize_varobj (void)
{
- int sizeof_table = sizeof (struct vlist *) * VAROBJ_TABLE_SIZE;
-
- varobj_table = xmalloc (sizeof_table);
- memset (varobj_table, 0, sizeof_table);
+ varobj_table = XCNEWVEC (struct vlist *, VAROBJ_TABLE_SIZE);
add_setshow_zuinteger_cmd ("varobj", class_maintenance,
&varobjdebug,