Replace VEC (varobj_update_result) with std::vector
This patch replaces makes varobj_update return an std::vector, and updates the fallouts. To make that easier, the varobj_update_result is c++ified a bit. I added a constructor and initialized its fields in-class. The newobj vector is also made an std::vector, so that it's automatically freed when varobj_update_result is destroyed and handled correctly by the default move constructor. I disabled copy constructor and assignment for that structure, because normally it never needs to be copied, only moved. As a result, the newobj parameter of update_dynamic_varobj_children must be changed to an std::vector. The patch converts the other vector parameters of update_dynamic_varobj_children to std::vector. It's not strictly necessary to do it in the same patch, but I think it makes sense to do it. gdb/ChangeLog: * varobj.h (struct varobj_update_result): Add constructor, add move constructor, disable copy and assign, initialize fields. <newobj>: Change type to std::vector. (varobj_update): Return std::vector. * varobj.c (install_dynamic_child): Change VEC parameters to std::vector and adjust. (update_dynamic_varobj_children): Likewise. (varobj_update): Return std::vector and adjust. * mi/mi-cmd-var.c (varobj_update_one): Adjust to vector changes.
This commit is contained in:
parent
ddf0ea085b
commit
0604393c22
|
@ -1,3 +1,15 @@
|
|||
2017-11-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* varobj.h (struct varobj_update_result): Add constructor, add
|
||||
move constructor, disable copy and assign, initialize fields.
|
||||
<newobj>: Change type to std::vector.
|
||||
(varobj_update): Return std::vector.
|
||||
* varobj.c (install_dynamic_child): Change VEC parameters to
|
||||
std::vector and adjust.
|
||||
(update_dynamic_varobj_children): Likewise.
|
||||
(varobj_update): Return std::vector and adjust.
|
||||
* mi/mi-cmd-var.c (varobj_update_one): Adjust to vector changes.
|
||||
|
||||
2017-11-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* varobj.h (struct varobj) <parent>: Remove const.
|
||||
|
|
|
@ -685,27 +685,24 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
|
|||
int is_explicit)
|
||||
{
|
||||
struct ui_out *uiout = current_uiout;
|
||||
VEC (varobj_update_result) *changes;
|
||||
varobj_update_result *r;
|
||||
int i;
|
||||
|
||||
std::vector<varobj_update_result> changes = varobj_update (&var, is_explicit);
|
||||
|
||||
changes = varobj_update (&var, is_explicit);
|
||||
|
||||
for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
|
||||
for (const varobj_update_result &r : changes)
|
||||
{
|
||||
int from, to;
|
||||
|
||||
gdb::optional<ui_out_emit_tuple> tuple_emitter;
|
||||
if (mi_version (uiout) > 1)
|
||||
tuple_emitter.emplace (uiout, nullptr);
|
||||
uiout->field_string ("name", varobj_get_objname (r->varobj));
|
||||
uiout->field_string ("name", varobj_get_objname (r.varobj));
|
||||
|
||||
switch (r->status)
|
||||
switch (r.status)
|
||||
{
|
||||
case VAROBJ_IN_SCOPE:
|
||||
if (mi_print_value_p (r->varobj, print_values))
|
||||
if (mi_print_value_p (r.varobj, print_values))
|
||||
{
|
||||
std::string val = varobj_get_value (r->varobj);
|
||||
std::string val = varobj_get_value (r.varobj);
|
||||
|
||||
uiout->field_string ("value", val.c_str ());
|
||||
}
|
||||
|
@ -719,53 +716,47 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
|
|||
break;
|
||||
}
|
||||
|
||||
if (r->status != VAROBJ_INVALID)
|
||||
if (r.status != VAROBJ_INVALID)
|
||||
{
|
||||
if (r->type_changed)
|
||||
if (r.type_changed)
|
||||
uiout->field_string ("type_changed", "true");
|
||||
else
|
||||
uiout->field_string ("type_changed", "false");
|
||||
}
|
||||
|
||||
if (r->type_changed)
|
||||
if (r.type_changed)
|
||||
{
|
||||
std::string type_name = varobj_get_type (r->varobj);
|
||||
std::string type_name = varobj_get_type (r.varobj);
|
||||
|
||||
uiout->field_string ("new_type", type_name.c_str ());
|
||||
}
|
||||
|
||||
if (r->type_changed || r->children_changed)
|
||||
if (r.type_changed || r.children_changed)
|
||||
uiout->field_int ("new_num_children",
|
||||
varobj_get_num_children (r->varobj));
|
||||
varobj_get_num_children (r.varobj));
|
||||
|
||||
gdb::unique_xmalloc_ptr<char> display_hint
|
||||
= varobj_get_display_hint (r->varobj);
|
||||
= varobj_get_display_hint (r.varobj);
|
||||
if (display_hint)
|
||||
uiout->field_string ("displayhint", display_hint.get ());
|
||||
|
||||
if (varobj_is_dynamic_p (r->varobj))
|
||||
if (varobj_is_dynamic_p (r.varobj))
|
||||
uiout->field_int ("dynamic", 1);
|
||||
|
||||
varobj_get_child_range (r->varobj, &from, &to);
|
||||
uiout->field_int ("has_more", varobj_has_more (r->varobj, to));
|
||||
varobj_get_child_range (r.varobj, &from, &to);
|
||||
uiout->field_int ("has_more", varobj_has_more (r.varobj, to));
|
||||
|
||||
if (r->newobj)
|
||||
if (!r.newobj.empty ())
|
||||
{
|
||||
int j;
|
||||
varobj_p child;
|
||||
|
||||
ui_out_emit_list list_emitter (uiout, "new_children");
|
||||
for (j = 0; VEC_iterate (varobj_p, r->newobj, j, child); ++j)
|
||||
|
||||
for (varobj *child : r.newobj)
|
||||
{
|
||||
ui_out_emit_tuple tuple_emitter (uiout, NULL);
|
||||
print_varobj (child, print_values, 1 /* print_expression */);
|
||||
}
|
||||
|
||||
VEC_free (varobj_p, r->newobj);
|
||||
r->newobj = NULL; /* Paranoia. */
|
||||
}
|
||||
}
|
||||
VEC_free (varobj_update_result, changes);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
146
gdb/varobj.c
146
gdb/varobj.c
|
@ -629,10 +629,10 @@ varobj_restrict_range (const std::vector<varobj *> &children,
|
|||
|
||||
static void
|
||||
install_dynamic_child (struct varobj *var,
|
||||
VEC (varobj_p) **changed,
|
||||
VEC (varobj_p) **type_changed,
|
||||
VEC (varobj_p) **newobj,
|
||||
VEC (varobj_p) **unchanged,
|
||||
std::vector<varobj *> *changed,
|
||||
std::vector<varobj *> *type_changed,
|
||||
std::vector<varobj *> *newobj,
|
||||
std::vector<varobj *> *unchanged,
|
||||
int *cchanged,
|
||||
int index,
|
||||
struct varobj_item *item)
|
||||
|
@ -642,9 +642,9 @@ install_dynamic_child (struct varobj *var,
|
|||
/* There's no child yet. */
|
||||
struct varobj *child = varobj_add_child (var, item);
|
||||
|
||||
if (newobj)
|
||||
if (newobj != NULL)
|
||||
{
|
||||
VEC_safe_push (varobj_p, *newobj, child);
|
||||
newobj->push_back (child);
|
||||
*cchanged = 1;
|
||||
}
|
||||
}
|
||||
|
@ -655,16 +655,16 @@ install_dynamic_child (struct varobj *var,
|
|||
|
||||
if (type_updated)
|
||||
{
|
||||
if (type_changed)
|
||||
VEC_safe_push (varobj_p, *type_changed, existing);
|
||||
if (type_changed != NULL)
|
||||
type_changed->push_back (existing);
|
||||
}
|
||||
if (install_new_value (existing, item->value, 0))
|
||||
{
|
||||
if (!type_updated && changed)
|
||||
VEC_safe_push (varobj_p, *changed, existing);
|
||||
if (!type_updated && changed != NULL)
|
||||
changed->push_back (existing);
|
||||
}
|
||||
else if (!type_updated && unchanged)
|
||||
VEC_safe_push (varobj_p, *unchanged, existing);
|
||||
else if (!type_updated && unchanged != NULL)
|
||||
unchanged->push_back (existing);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,10 +713,10 @@ varobj_clear_saved_item (struct varobj_dynamic *var)
|
|||
|
||||
static int
|
||||
update_dynamic_varobj_children (struct varobj *var,
|
||||
VEC (varobj_p) **changed,
|
||||
VEC (varobj_p) **type_changed,
|
||||
VEC (varobj_p) **newobj,
|
||||
VEC (varobj_p) **unchanged,
|
||||
std::vector<varobj *> *changed,
|
||||
std::vector<varobj *> *type_changed,
|
||||
std::vector<varobj *> *newobj,
|
||||
std::vector<varobj *> *unchanged,
|
||||
int *cchanged,
|
||||
int update_children,
|
||||
int from,
|
||||
|
@ -1525,14 +1525,13 @@ varobj_value_has_mutated (const struct varobj *var, struct value *new_value,
|
|||
returns TYPE_CHANGED, then it has done this and VARP will be modified
|
||||
to point to the new varobj. */
|
||||
|
||||
VEC(varobj_update_result) *
|
||||
std::vector<varobj_update_result>
|
||||
varobj_update (struct varobj **varp, int is_explicit)
|
||||
{
|
||||
int type_changed = 0;
|
||||
int i;
|
||||
struct value *newobj;
|
||||
VEC (varobj_update_result) *stack = NULL;
|
||||
VEC (varobj_update_result) *result = NULL;
|
||||
std::vector<varobj_update_result> stack;
|
||||
std::vector<varobj_update_result> result;
|
||||
|
||||
/* Frozen means frozen -- we don't check for any change in
|
||||
this varobj, including its going out of scope, or
|
||||
|
@ -1544,20 +1543,13 @@ varobj_update (struct varobj **varp, int is_explicit)
|
|||
|
||||
if (!(*varp)->root->is_valid)
|
||||
{
|
||||
varobj_update_result r = {0};
|
||||
|
||||
r.varobj = *varp;
|
||||
r.status = VAROBJ_INVALID;
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
result.emplace_back (*varp, VAROBJ_INVALID);
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((*varp)->root->rootvar == *varp)
|
||||
{
|
||||
varobj_update_result r = {0};
|
||||
|
||||
r.varobj = *varp;
|
||||
r.status = VAROBJ_IN_SCOPE;
|
||||
varobj_update_result r (*varp);
|
||||
|
||||
/* Update the root variable. value_of_root can return NULL
|
||||
if the variable is no longer around, i.e. we stepped out of
|
||||
|
@ -1579,28 +1571,23 @@ varobj_update (struct varobj **varp, int is_explicit)
|
|||
if (r.status == VAROBJ_NOT_IN_SCOPE)
|
||||
{
|
||||
if (r.type_changed || r.changed)
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
result.push_back (std::move (r));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
VEC_safe_push (varobj_update_result, stack, &r);
|
||||
|
||||
stack.push_back (std::move (r));
|
||||
}
|
||||
else
|
||||
{
|
||||
varobj_update_result r = {0};
|
||||
|
||||
r.varobj = *varp;
|
||||
VEC_safe_push (varobj_update_result, stack, &r);
|
||||
}
|
||||
stack.emplace_back (*varp);
|
||||
|
||||
/* Walk through the children, reconstructing them all. */
|
||||
while (!VEC_empty (varobj_update_result, stack))
|
||||
while (!stack.empty ())
|
||||
{
|
||||
varobj_update_result r = *(VEC_last (varobj_update_result, stack));
|
||||
varobj_update_result r = std::move (stack.back ());
|
||||
stack.pop_back ();
|
||||
struct varobj *v = r.varobj;
|
||||
|
||||
VEC_pop (varobj_update_result, stack);
|
||||
|
||||
/* Update this variable, unless it's a root, which is already
|
||||
updated. */
|
||||
if (!r.value_installed)
|
||||
|
@ -1638,9 +1625,8 @@ varobj_update (struct varobj **varp, int is_explicit)
|
|||
for which -var-list-children was never invoked. */
|
||||
if (varobj_is_dynamic_p (v))
|
||||
{
|
||||
VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0;
|
||||
VEC (varobj_p) *newobj = 0;
|
||||
int i, children_changed = 0;
|
||||
std::vector<varobj *> changed, type_changed, unchanged, newobj;
|
||||
int children_changed = 0;
|
||||
|
||||
if (v->frozen)
|
||||
continue;
|
||||
|
@ -1664,7 +1650,7 @@ varobj_update (struct varobj **varp, int is_explicit)
|
|||
}
|
||||
|
||||
if (r.changed)
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
result.push_back (std::move (r));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -1675,58 +1661,48 @@ varobj_update (struct varobj **varp, int is_explicit)
|
|||
&unchanged, &children_changed, 1,
|
||||
v->from, v->to))
|
||||
{
|
||||
if (children_changed || newobj)
|
||||
if (children_changed || !newobj.empty ())
|
||||
{
|
||||
r.children_changed = 1;
|
||||
r.newobj = newobj;
|
||||
r.newobj = std::move (newobj);
|
||||
}
|
||||
/* Push in reverse order so that the first child is
|
||||
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)
|
||||
for (int i = type_changed.size () - 1; i >= 0; --i)
|
||||
{
|
||||
varobj_p tmp = VEC_index (varobj_p, type_changed, i);
|
||||
varobj_update_result r = {0};
|
||||
varobj_update_result r (type_changed[i]);
|
||||
|
||||
/* 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);
|
||||
varobj_update_result r = {0};
|
||||
|
||||
r.varobj = tmp;
|
||||
stack.push_back (std::move (r));
|
||||
}
|
||||
for (int i = changed.size () - 1; i >= 0; --i)
|
||||
{
|
||||
varobj_update_result r (changed[i]);
|
||||
|
||||
r.changed = 1;
|
||||
r.value_installed = 1;
|
||||
VEC_safe_push (varobj_update_result, stack, &r);
|
||||
|
||||
stack.push_back (std::move (r));
|
||||
}
|
||||
for (i = VEC_length (varobj_p, unchanged) - 1; i >= 0; --i)
|
||||
{
|
||||
varobj_p tmp = VEC_index (varobj_p, unchanged, i);
|
||||
for (int i = unchanged.size () - 1; i >= 0; --i)
|
||||
{
|
||||
if (!unchanged[i]->frozen)
|
||||
{
|
||||
varobj_update_result r (unchanged[i]);
|
||||
|
||||
if (!tmp->frozen)
|
||||
{
|
||||
varobj_update_result r = {0};
|
||||
r.value_installed = 1;
|
||||
|
||||
r.varobj = tmp;
|
||||
r.value_installed = 1;
|
||||
VEC_safe_push (varobj_update_result, stack, &r);
|
||||
}
|
||||
}
|
||||
stack.push_back (std::move (r));
|
||||
}
|
||||
}
|
||||
if (r.changed || r.children_changed)
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
|
||||
/* 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);
|
||||
result.push_back (std::move (r));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -1736,29 +1712,21 @@ varobj_update (struct varobj **varp, int is_explicit)
|
|||
child is popped from the work stack first, and so
|
||||
will be added to result first. This does not
|
||||
affect correctness, just "nicer". */
|
||||
for (i = v->children.size () - 1; i >= 0; --i)
|
||||
for (int i = v->children.size () - 1; i >= 0; --i)
|
||||
{
|
||||
varobj *c = v->children[i];
|
||||
|
||||
/* Child may be NULL if explicitly deleted by -var-delete. */
|
||||
if (c != NULL && !c->frozen)
|
||||
{
|
||||
varobj_update_result r = {0};
|
||||
|
||||
r.varobj = c;
|
||||
VEC_safe_push (varobj_update_result, stack, &r);
|
||||
}
|
||||
stack.emplace_back (c);
|
||||
}
|
||||
|
||||
if (r.changed || r.type_changed)
|
||||
VEC_safe_push (varobj_update_result, result, &r);
|
||||
result.push_back (std::move (r));
|
||||
}
|
||||
|
||||
VEC_free (varobj_update_result, stack);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Helper functions */
|
||||
|
||||
|
|
29
gdb/varobj.h
29
gdb/varobj.h
|
@ -60,26 +60,33 @@ struct varobj;
|
|||
typedef struct varobj *varobj_p;
|
||||
DEF_VEC_P (varobj_p);
|
||||
|
||||
typedef struct varobj_update_result_t
|
||||
struct varobj_update_result
|
||||
{
|
||||
varobj_update_result (struct varobj *varobj_,
|
||||
varobj_scope_status status_ = VAROBJ_IN_SCOPE)
|
||||
: varobj (varobj_), status (status_)
|
||||
{}
|
||||
|
||||
varobj_update_result (varobj_update_result &&other) = default;
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (varobj_update_result);
|
||||
|
||||
struct varobj *varobj;
|
||||
int type_changed;
|
||||
int children_changed;
|
||||
int changed;
|
||||
int type_changed = 0;
|
||||
int children_changed = 0;
|
||||
int changed = 0;
|
||||
enum varobj_scope_status status;
|
||||
/* This variable is used internally by varobj_update to indicate if the
|
||||
new value of varobj is already computed and installed, or has to
|
||||
be yet installed. Don't use this outside varobj.c. */
|
||||
int value_installed;
|
||||
int value_installed = 0;
|
||||
|
||||
/* This will be non-NULL when new children were added to the varobj.
|
||||
It lists the new children (which must necessarily come at the end
|
||||
of the child list) added during an update. The caller is
|
||||
responsible for freeing this vector. */
|
||||
VEC (varobj_p) *newobj;
|
||||
} varobj_update_result;
|
||||
|
||||
DEF_VEC_O (varobj_update_result);
|
||||
std::vector<struct varobj *> newobj;
|
||||
};
|
||||
|
||||
struct varobj_root;
|
||||
struct varobj_dynamic;
|
||||
|
@ -305,8 +312,8 @@ extern int varobj_set_value (struct varobj *var, const char *expression);
|
|||
extern void all_root_varobjs (void (*func) (struct varobj *var, void *data),
|
||||
void *data);
|
||||
|
||||
extern VEC(varobj_update_result) *varobj_update (struct varobj **varp,
|
||||
int is_explicit);
|
||||
extern std::vector<varobj_update_result>
|
||||
varobj_update (struct varobj **varp, int is_explicit);
|
||||
|
||||
extern void varobj_invalidate (void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue