Make varobj::children an std::vector
This patch makes the children field of varobj an std::vector, and updates the fallout. One note is that varobj::parent must be made non-const. The reason is that when a child deletes itself, it modifies its writes NULL to its slot in its parent's children vector. With the VEC, the const didn't made the parent's children vector content const, only the pointer to it, but with std::vector, even the content is. gdb/ChangeLog: * varobj.h (struct varobj) <parent>: Remove const. <children>: Change type to std::vector. (varobj_list_children): Return std::vector const reference. (varobj_restrict_range): Change parameter type to std::vector const reference. * varobj.c (varobj_has_more): Adjust. (varobj_restrict_range): Change parameter type to std::vector const reference and adjust. (install_dynamic_child): Adjust. (update_dynamic_varobj_children): Adjust. (varobj_list_children): Return std::vector const reference and adjust. (varobj_add_child): Adjust. (update_type_if_necessary): Adjust. (varobj_update): Adjust. (delete_variable_1): Adjust. * ada-varobj.c (ada_value_has_mutated): Adjust. * mi/mi-cmd-var.c (mi_cmd_var_list_children): Adjust.
This commit is contained in:
parent
9e5b9d2b29
commit
ddf0ea085b
|
@ -1,3 +1,24 @@
|
||||||
|
2017-11-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
|
||||||
|
* varobj.h (struct varobj) <parent>: Remove const.
|
||||||
|
<children>: Change type to std::vector.
|
||||||
|
(varobj_list_children): Return std::vector const reference.
|
||||||
|
(varobj_restrict_range): Change parameter type to std::vector
|
||||||
|
const reference.
|
||||||
|
* varobj.c (varobj_has_more): Adjust.
|
||||||
|
(varobj_restrict_range): Change parameter type to std::vector
|
||||||
|
const reference and adjust.
|
||||||
|
(install_dynamic_child): Adjust.
|
||||||
|
(update_dynamic_varobj_children): Adjust.
|
||||||
|
(varobj_list_children): Return std::vector const reference and
|
||||||
|
adjust.
|
||||||
|
(varobj_add_child): Adjust.
|
||||||
|
(update_type_if_necessary): Adjust.
|
||||||
|
(varobj_update): Adjust.
|
||||||
|
(delete_variable_1): Adjust.
|
||||||
|
* ada-varobj.c (ada_value_has_mutated): Adjust.
|
||||||
|
* mi/mi-cmd-var.c (mi_cmd_var_list_children): Adjust.
|
||||||
|
|
||||||
2017-11-22 Simon Marchi <simon.marchi@polymtl.ca>
|
2017-11-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
|
||||||
* varobj.h (struct varobj): Add constructor and destructor,
|
* varobj.h (struct varobj): Add constructor and destructor,
|
||||||
|
|
|
@ -959,7 +959,6 @@ static int
|
||||||
ada_value_has_mutated (const struct varobj *var, struct value *new_val,
|
ada_value_has_mutated (const struct varobj *var, struct value *new_val,
|
||||||
struct type *new_type)
|
struct type *new_type)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int from = -1;
|
int from = -1;
|
||||||
int to = -1;
|
int to = -1;
|
||||||
|
|
||||||
|
@ -983,10 +982,10 @@ ada_value_has_mutated (const struct varobj *var, struct value *new_val,
|
||||||
has mutated or not. So just assume it hasn't. */
|
has mutated or not. So just assume it hasn't. */
|
||||||
|
|
||||||
varobj_restrict_range (var->children, &from, &to);
|
varobj_restrict_range (var->children, &from, &to);
|
||||||
for (i = from; i < to; i++)
|
for (int i = from; i < to; i++)
|
||||||
if (ada_varobj_get_name_of_child (new_val, new_type,
|
if (ada_varobj_get_name_of_child (new_val, new_type,
|
||||||
var->name.c_str (), i)
|
var->name.c_str (), i)
|
||||||
!= VEC_index (varobj_p, var->children, i)->name)
|
!= var->children[i]->name)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -352,10 +352,7 @@ mi_cmd_var_list_children (const char *command, char **argv, int argc)
|
||||||
{
|
{
|
||||||
struct ui_out *uiout = current_uiout;
|
struct ui_out *uiout = current_uiout;
|
||||||
struct varobj *var;
|
struct varobj *var;
|
||||||
VEC(varobj_p) *children;
|
|
||||||
struct varobj *child;
|
|
||||||
enum print_values print_values;
|
enum print_values print_values;
|
||||||
int ix;
|
|
||||||
int from, to;
|
int from, to;
|
||||||
|
|
||||||
if (argc < 1 || argc > 4)
|
if (argc < 1 || argc > 4)
|
||||||
|
@ -379,7 +376,9 @@ mi_cmd_var_list_children (const char *command, char **argv, int argc)
|
||||||
to = -1;
|
to = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
children = varobj_list_children (var, &from, &to);
|
const std::vector<varobj *> &children
|
||||||
|
= varobj_list_children (var, &from, &to);
|
||||||
|
|
||||||
uiout->field_int ("numchild", to - from);
|
uiout->field_int ("numchild", to - from);
|
||||||
if (argc == 2 || argc == 4)
|
if (argc == 2 || argc == 4)
|
||||||
print_values = mi_parse_print_values (argv[0]);
|
print_values = mi_parse_print_values (argv[0]);
|
||||||
|
@ -401,13 +400,11 @@ mi_cmd_var_list_children (const char *command, char **argv, int argc)
|
||||||
tuple_emitter.emplace (uiout, "children");
|
tuple_emitter.emplace (uiout, "children");
|
||||||
else
|
else
|
||||||
list_emitter.emplace (uiout, "children");
|
list_emitter.emplace (uiout, "children");
|
||||||
for (ix = from;
|
for (int ix = from; ix < to && ix < children.size (); ix++)
|
||||||
ix < to && VEC_iterate (varobj_p, children, ix, child);
|
|
||||||
++ix)
|
|
||||||
{
|
{
|
||||||
ui_out_emit_tuple child_emitter (uiout, "child");
|
ui_out_emit_tuple child_emitter (uiout, "child");
|
||||||
|
|
||||||
print_varobj (child, print_values, 1 /* print expression */);
|
print_varobj (children[ix], print_values, 1 /* print expression */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
85
gdb/varobj.c
85
gdb/varobj.c
|
@ -558,9 +558,10 @@ varobj_get_display_hint (const struct varobj *var)
|
||||||
int
|
int
|
||||||
varobj_has_more (const struct varobj *var, int to)
|
varobj_has_more (const struct varobj *var, int to)
|
||||||
{
|
{
|
||||||
if (VEC_length (varobj_p, var->children) > to)
|
if (var->children.size () > to)
|
||||||
return 1;
|
return 1;
|
||||||
return ((to == -1 || VEC_length (varobj_p, var->children) == to)
|
|
||||||
|
return ((to == -1 || var->children.size () == to)
|
||||||
&& (var->dynamic->saved_item != NULL));
|
&& (var->dynamic->saved_item != NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,19 +603,22 @@ varobj_get_frozen (const struct varobj *var)
|
||||||
used. */
|
used. */
|
||||||
|
|
||||||
void
|
void
|
||||||
varobj_restrict_range (VEC (varobj_p) *children, int *from, int *to)
|
varobj_restrict_range (const std::vector<varobj *> &children,
|
||||||
|
int *from, int *to)
|
||||||
{
|
{
|
||||||
|
int len = children.size ();
|
||||||
|
|
||||||
if (*from < 0 || *to < 0)
|
if (*from < 0 || *to < 0)
|
||||||
{
|
{
|
||||||
*from = 0;
|
*from = 0;
|
||||||
*to = VEC_length (varobj_p, children);
|
*to = len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*from > VEC_length (varobj_p, children))
|
if (*from > len)
|
||||||
*from = VEC_length (varobj_p, children);
|
*from = len;
|
||||||
if (*to > VEC_length (varobj_p, children))
|
if (*to > len)
|
||||||
*to = VEC_length (varobj_p, children);
|
*to = len;
|
||||||
if (*from > *to)
|
if (*from > *to)
|
||||||
*from = *to;
|
*from = *to;
|
||||||
}
|
}
|
||||||
|
@ -633,7 +637,7 @@ install_dynamic_child (struct varobj *var,
|
||||||
int index,
|
int index,
|
||||||
struct varobj_item *item)
|
struct varobj_item *item)
|
||||||
{
|
{
|
||||||
if (VEC_length (varobj_p, var->children) < index + 1)
|
if (var->children.size () < index + 1)
|
||||||
{
|
{
|
||||||
/* There's no child yet. */
|
/* There's no child yet. */
|
||||||
struct varobj *child = varobj_add_child (var, item);
|
struct varobj *child = varobj_add_child (var, item);
|
||||||
|
@ -646,7 +650,7 @@ install_dynamic_child (struct varobj *var,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
varobj_p existing = VEC_index (varobj_p, var->children, index);
|
varobj *existing = var->children[index];
|
||||||
int type_updated = update_type_if_necessary (existing, item->value);
|
int type_updated = update_type_if_necessary (existing, item->value);
|
||||||
|
|
||||||
if (type_updated)
|
if (type_updated)
|
||||||
|
@ -735,7 +739,7 @@ update_dynamic_varobj_children (struct varobj *var,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
i = VEC_length (varobj_p, var->children);
|
i = var->children.size ();
|
||||||
|
|
||||||
/* We ask for one extra child, so that MI can report whether there
|
/* We ask for one extra child, so that MI can report whether there
|
||||||
are more children. */
|
are more children. */
|
||||||
|
@ -789,22 +793,21 @@ update_dynamic_varobj_children (struct varobj *var,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < VEC_length (varobj_p, var->children))
|
if (i < var->children.size ())
|
||||||
{
|
{
|
||||||
int j;
|
|
||||||
|
|
||||||
*cchanged = 1;
|
*cchanged = 1;
|
||||||
for (j = i; j < VEC_length (varobj_p, var->children); ++j)
|
for (int j = i; j < var->children.size (); ++j)
|
||||||
varobj_delete (VEC_index (varobj_p, var->children, j), 0);
|
varobj_delete (var->children[j], 0);
|
||||||
VEC_truncate (varobj_p, var->children, i);
|
|
||||||
|
var->children.resize (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there are fewer children than requested, note that the list of
|
/* If there are fewer children than requested, note that the list of
|
||||||
children changed. */
|
children changed. */
|
||||||
if (to >= 0 && VEC_length (varobj_p, var->children) < to)
|
if (to >= 0 && var->children.size () < to)
|
||||||
*cchanged = 1;
|
*cchanged = 1;
|
||||||
|
|
||||||
var->num_children = VEC_length (varobj_p, var->children);
|
var->num_children = var->children.size ();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -833,10 +836,10 @@ varobj_get_num_children (struct varobj *var)
|
||||||
/* Creates a list of the immediate children of a variable object;
|
/* Creates a list of the immediate children of a variable object;
|
||||||
the return code is the number of such children or -1 on error. */
|
the return code is the number of such children or -1 on error. */
|
||||||
|
|
||||||
VEC (varobj_p)*
|
const std::vector<varobj *> &
|
||||||
varobj_list_children (struct varobj *var, int *from, int *to)
|
varobj_list_children (struct varobj *var, int *from, int *to)
|
||||||
{
|
{
|
||||||
int i, children_changed;
|
int children_changed;
|
||||||
|
|
||||||
var->dynamic->children_requested = 1;
|
var->dynamic->children_requested = 1;
|
||||||
|
|
||||||
|
@ -860,21 +863,18 @@ varobj_list_children (struct varobj *var, int *from, int *to)
|
||||||
|
|
||||||
/* If we're called when the list of children is not yet initialized,
|
/* If we're called when the list of children is not yet initialized,
|
||||||
allocate enough elements in it. */
|
allocate enough elements in it. */
|
||||||
while (VEC_length (varobj_p, var->children) < var->num_children)
|
while (var->children.size () < var->num_children)
|
||||||
VEC_safe_push (varobj_p, var->children, NULL);
|
var->children.push_back (NULL);
|
||||||
|
|
||||||
for (i = 0; i < var->num_children; i++)
|
for (int i = 0; i < var->num_children; i++)
|
||||||
{
|
{
|
||||||
varobj_p existing = VEC_index (varobj_p, var->children, i);
|
if (var->children[i] == NULL)
|
||||||
|
|
||||||
if (existing == NULL)
|
|
||||||
{
|
{
|
||||||
/* Either it's the first call to varobj_list_children for
|
/* Either it's the first call to varobj_list_children for
|
||||||
this variable object, and the child was never created,
|
this variable object, and the child was never created,
|
||||||
or it was explicitly deleted by the client. */
|
or it was explicitly deleted by the client. */
|
||||||
std::string name = name_of_child (var, i);
|
std::string name = name_of_child (var, i);
|
||||||
existing = create_child (var, i, name);
|
var->children[i] = create_child (var, i, name);
|
||||||
VEC_replace (varobj_p, var->children, i, existing);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,11 +885,10 @@ varobj_list_children (struct varobj *var, int *from, int *to)
|
||||||
static struct varobj *
|
static struct varobj *
|
||||||
varobj_add_child (struct varobj *var, struct varobj_item *item)
|
varobj_add_child (struct varobj *var, struct varobj_item *item)
|
||||||
{
|
{
|
||||||
varobj_p v = create_child_with_value (var,
|
varobj *v = create_child_with_value (var, var->children.size (), item);
|
||||||
VEC_length (varobj_p, var->children),
|
|
||||||
item);
|
var->children.push_back (v);
|
||||||
|
|
||||||
VEC_safe_push (varobj_p, var->children, v);
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,7 +1220,7 @@ update_type_if_necessary (struct varobj *var, struct value *new_value)
|
||||||
|
|
||||||
/* This information may be not valid for a new type. */
|
/* This information may be not valid for a new type. */
|
||||||
varobj_delete (var, 1);
|
varobj_delete (var, 1);
|
||||||
VEC_free (varobj_p, var->children);
|
var->children.clear ();
|
||||||
var->num_children = -1;
|
var->num_children = -1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1737,9 +1736,9 @@ varobj_update (struct varobj **varp, int is_explicit)
|
||||||
child is popped from the work stack first, and so
|
child is popped from the work stack first, and so
|
||||||
will be added to result first. This does not
|
will be added to result first. This does not
|
||||||
affect correctness, just "nicer". */
|
affect correctness, just "nicer". */
|
||||||
for (i = VEC_length (varobj_p, v->children)-1; i >= 0; --i)
|
for (i = v->children.size () - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
varobj_p c = VEC_index (varobj_p, v->children, i);
|
varobj *c = v->children[i];
|
||||||
|
|
||||||
/* Child may be NULL if explicitly deleted by -var-delete. */
|
/* Child may be NULL if explicitly deleted by -var-delete. */
|
||||||
if (c != NULL && !c->frozen)
|
if (c != NULL && !c->frozen)
|
||||||
|
@ -1786,20 +1785,18 @@ static void
|
||||||
delete_variable_1 (int *delcountp, struct varobj *var, int only_children_p,
|
delete_variable_1 (int *delcountp, struct varobj *var, int only_children_p,
|
||||||
int remove_from_parent_p)
|
int remove_from_parent_p)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Delete any children of this variable, too. */
|
/* Delete any children of this variable, too. */
|
||||||
for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
|
for (varobj *child : var->children)
|
||||||
{
|
{
|
||||||
varobj_p child = VEC_index (varobj_p, var->children, i);
|
|
||||||
|
|
||||||
if (!child)
|
if (!child)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!remove_from_parent_p)
|
if (!remove_from_parent_p)
|
||||||
child->parent = NULL;
|
child->parent = NULL;
|
||||||
|
|
||||||
delete_variable_1 (delcountp, child, 0, only_children_p);
|
delete_variable_1 (delcountp, child, 0, only_children_p);
|
||||||
}
|
}
|
||||||
VEC_free (varobj_p, var->children);
|
var->children.clear ();
|
||||||
|
|
||||||
/* if we were called to delete only the children we are done here. */
|
/* if we were called to delete only the children we are done here. */
|
||||||
if (only_children_p)
|
if (only_children_p)
|
||||||
|
@ -1819,9 +1816,7 @@ delete_variable_1 (int *delcountp, struct varobj *var, int only_children_p,
|
||||||
expensive list search to find the element to remove when we are
|
expensive list search to find the element to remove when we are
|
||||||
discarding the list afterwards. */
|
discarding the list afterwards. */
|
||||||
if ((remove_from_parent_p) && (var->parent != NULL))
|
if ((remove_from_parent_p) && (var->parent != NULL))
|
||||||
{
|
var->parent->children[var->index] = NULL;
|
||||||
VEC_replace (varobj_p, var->parent->children, var->index, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!var->obj_name.empty ())
|
if (!var->obj_name.empty ())
|
||||||
uninstall_variable (var);
|
uninstall_variable (var);
|
||||||
|
|
12
gdb/varobj.h
12
gdb/varobj.h
|
@ -124,10 +124,10 @@ struct varobj
|
||||||
int num_children = -1;
|
int num_children = -1;
|
||||||
|
|
||||||
/* If this object is a child, this points to its immediate parent. */
|
/* If this object is a child, this points to its immediate parent. */
|
||||||
const struct varobj *parent = NULL;
|
struct varobj *parent = NULL;
|
||||||
|
|
||||||
/* Children of this object. */
|
/* Children of this object. */
|
||||||
VEC (varobj_p) *children = NULL;
|
std::vector<varobj *> children;
|
||||||
|
|
||||||
/* Description of the root variable. Points to root variable for
|
/* Description of the root variable. Points to root variable for
|
||||||
children. */
|
children. */
|
||||||
|
@ -280,8 +280,8 @@ extern int varobj_get_num_children (struct varobj *var);
|
||||||
that was returned. The resulting VEC will contain at least the
|
that was returned. The resulting VEC will contain at least the
|
||||||
children from *FROM to just before *TO; it might contain more
|
children from *FROM to just before *TO; it might contain more
|
||||||
children, depending on whether any more were available. */
|
children, depending on whether any more were available. */
|
||||||
extern VEC (varobj_p)* varobj_list_children (struct varobj *var,
|
extern const std::vector<varobj *> &
|
||||||
int *from, int *to);
|
varobj_list_children (struct varobj *var, int *from, int *to);
|
||||||
|
|
||||||
extern std::string varobj_get_type (struct varobj *var);
|
extern std::string varobj_get_type (struct varobj *var);
|
||||||
|
|
||||||
|
@ -341,8 +341,8 @@ extern std::string
|
||||||
extern void varobj_formatted_print_options (struct value_print_options *opts,
|
extern void varobj_formatted_print_options (struct value_print_options *opts,
|
||||||
enum varobj_display_formats format);
|
enum varobj_display_formats format);
|
||||||
|
|
||||||
extern void varobj_restrict_range (VEC (varobj_p) *children, int *from,
|
extern void varobj_restrict_range (const std::vector<varobj *> &children,
|
||||||
int *to);
|
int *from, int *to);
|
||||||
|
|
||||||
extern int varobj_default_is_path_expr_parent (const struct varobj *var);
|
extern int varobj_default_is_path_expr_parent (const struct varobj *var);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue