mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 04:25:10 +08:00
gdb/
* varobj.c: Include "vec.h". (varobj_p): New typedef, declare vector of those. (struct varobj): Use vector for the 'children' member. (child_exists): Remove. (save_child_in_parent): Remove. (remove_child_from_parent): Remove. (struct varobj_child): Remove. (struct vstack): Remove. (vpush, vpop): Remove. (varobj_list_children): Adjust to work work vector. (varobj_update): Likewise. Use vectors for working stack and result. (delete_variable_1): Likewise. * Makefile.in (varobj.o): Update dependencies.
This commit is contained in:
parent
b2c2bd757e
commit
28335dccfb
@ -1,3 +1,21 @@
|
||||
2007-01-04 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
gdb/
|
||||
* varobj.c: Include "vec.h".
|
||||
(varobj_p): New typedef, declare vector of those.
|
||||
(struct varobj): Use vector for the 'children' member.
|
||||
(child_exists): Remove.
|
||||
(save_child_in_parent): Remove.
|
||||
(remove_child_from_parent): Remove.
|
||||
(struct varobj_child): Remove.
|
||||
(struct vstack): Remove.
|
||||
(vpush, vpop): Remove.
|
||||
(varobj_list_children): Adjust to work work vector.
|
||||
(varobj_update): Likewise. Use vectors for
|
||||
working stack and result.
|
||||
(delete_variable_1): Likewise.
|
||||
* Makefile.in (varobj.o): Update dependencies.
|
||||
|
||||
2007-01-04 Vladimir Prus <vladimir@codesourcery.com>
|
||||
|
||||
Port from Apple's version.
|
||||
|
@ -2838,7 +2838,7 @@ value.o: value.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
||||
$(gdb_assert_h) $(regcache_h) $(block_h)
|
||||
varobj.o: varobj.c $(defs_h) $(exceptions_h) $(value_h) $(expression_h) \
|
||||
$(frame_h) $(language_h) $(wrapper_h) $(gdbcmd_h) $(gdb_assert_h) \
|
||||
$(gdb_string_h) $(varobj_h)
|
||||
$(gdb_string_h) $(varobj_h) $(vec_h)
|
||||
vaxbsd-nat.o: vaxbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) $(target_h) \
|
||||
$(vax_tdep_h) $(inf_ptrace_h) $(bsd_kvm_h)
|
||||
vax-nat.o: vax-nat.c $(defs_h) $(inferior_h) $(gdb_assert_h) $(vax_tdep_h) \
|
||||
|
273
gdb/varobj.c
273
gdb/varobj.c
@ -32,6 +32,7 @@
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "varobj.h"
|
||||
#include "vec.h"
|
||||
|
||||
/* Non-zero if we want to see trace of varobj level stuff. */
|
||||
|
||||
@ -80,6 +81,10 @@ struct varobj_root
|
||||
struct varobj_root *next;
|
||||
};
|
||||
|
||||
typedef struct varobj *varobj_p;
|
||||
|
||||
DEF_VEC_P (varobj_p);
|
||||
|
||||
/* Every variable in the system has a structure of this type defined
|
||||
for it. This structure holds all information necessary to manipulate
|
||||
a particular object variable. Members which must be freed are noted. */
|
||||
@ -116,8 +121,8 @@ struct varobj
|
||||
/* If this object is a child, this points to its immediate parent. */
|
||||
struct varobj *parent;
|
||||
|
||||
/* A list of this object's children */
|
||||
struct varobj_child *children;
|
||||
/* Children of this object. */
|
||||
VEC (varobj_p) *children;
|
||||
|
||||
/* Description of the root variable. Points to root variable for children. */
|
||||
struct varobj_root *root;
|
||||
@ -129,29 +134,6 @@ struct varobj
|
||||
int updated;
|
||||
};
|
||||
|
||||
/* Every variable keeps a linked list of its children, described
|
||||
by the following structure. */
|
||||
/* FIXME: Deprecated. All should use vlist instead */
|
||||
|
||||
struct varobj_child
|
||||
{
|
||||
|
||||
/* Pointer to the child's data */
|
||||
struct varobj *child;
|
||||
|
||||
/* Pointer to the next child */
|
||||
struct varobj_child *next;
|
||||
};
|
||||
|
||||
/* A stack of varobjs */
|
||||
/* FIXME: Deprecated. All should use vlist instead */
|
||||
|
||||
struct vstack
|
||||
{
|
||||
struct varobj *var;
|
||||
struct vstack *next;
|
||||
};
|
||||
|
||||
struct cpstack
|
||||
{
|
||||
char *name;
|
||||
@ -179,14 +161,8 @@ static int install_variable (struct varobj *);
|
||||
|
||||
static void uninstall_variable (struct varobj *);
|
||||
|
||||
static struct varobj *child_exists (struct varobj *, char *);
|
||||
|
||||
static struct varobj *create_child (struct varobj *, int, char *);
|
||||
|
||||
static void save_child_in_parent (struct varobj *, struct varobj *);
|
||||
|
||||
static void remove_child_from_parent (struct varobj *, struct varobj *);
|
||||
|
||||
/* Utility routines */
|
||||
|
||||
static struct varobj *new_variable (void);
|
||||
@ -205,10 +181,6 @@ static struct type *get_target_type (struct type *);
|
||||
|
||||
static enum varobj_display_formats variable_default_display (struct varobj *);
|
||||
|
||||
static void vpush (struct vstack **pstack, struct varobj *var);
|
||||
|
||||
static struct varobj *vpop (struct vstack **pstack);
|
||||
|
||||
static void cppush (struct cpstack **pstack, char *name);
|
||||
|
||||
static char *cppop (struct cpstack **pstack);
|
||||
@ -713,21 +685,34 @@ varobj_list_children (struct varobj *var, struct varobj ***childlist)
|
||||
if (var->num_children == -1)
|
||||
var->num_children = number_of_children (var);
|
||||
|
||||
/* If we're called when the list of children is not yet initialized,
|
||||
allocate enough elements in it. */
|
||||
while (VEC_length (varobj_p, var->children) < var->num_children)
|
||||
VEC_safe_push (varobj_p, var->children, NULL);
|
||||
|
||||
/* List of children */
|
||||
*childlist = xmalloc ((var->num_children + 1) * sizeof (struct varobj *));
|
||||
|
||||
for (i = 0; i < var->num_children; i++)
|
||||
{
|
||||
varobj_p existing;
|
||||
|
||||
/* Mark as the end in case we bail out */
|
||||
*((*childlist) + i) = NULL;
|
||||
|
||||
/* check if child exists, if not create */
|
||||
name = name_of_child (var, i);
|
||||
child = child_exists (var, name);
|
||||
if (child == NULL)
|
||||
child = create_child (var, i, name);
|
||||
existing = VEC_index (varobj_p, var->children, i);
|
||||
|
||||
*((*childlist) + i) = child;
|
||||
if (existing == NULL)
|
||||
{
|
||||
/* Either it's the first call to varobj_list_children for
|
||||
this variable object, and the child was never created,
|
||||
or it was explicitly deleted by the client. */
|
||||
name = name_of_child (var, i);
|
||||
existing = create_child (var, i, name);
|
||||
VEC_replace (varobj_p, var->children, i, existing);
|
||||
}
|
||||
|
||||
*((*childlist) + i) = existing;
|
||||
}
|
||||
|
||||
/* End of list is marked by a NULL pointer */
|
||||
@ -1034,8 +1019,8 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
|
||||
struct varobj **cv;
|
||||
struct varobj **templist = NULL;
|
||||
struct value *new;
|
||||
struct vstack *stack = NULL;
|
||||
struct vstack *result = NULL;
|
||||
VEC (varobj_p) *stack = NULL;
|
||||
VEC (varobj_p) *result = NULL;
|
||||
struct frame_id old_fid;
|
||||
struct frame_info *fi;
|
||||
|
||||
@ -1071,94 +1056,64 @@ varobj_update (struct varobj **varp, struct varobj ***changelist)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize a stack for temporary results */
|
||||
vpush (&result, NULL);
|
||||
|
||||
/* If this is a "use_selected_frame" varobj, and its type has changed,
|
||||
them note that it's changed. */
|
||||
if (type_changed)
|
||||
{
|
||||
vpush (&result, *varp);
|
||||
changed++;
|
||||
}
|
||||
VEC_safe_push (varobj_p, result, *varp);
|
||||
|
||||
if (install_new_value ((*varp), new, type_changed))
|
||||
{
|
||||
/* If type_changed is 1, install_new_value will never return
|
||||
non-zero, so we'll never report the same variable twice. */
|
||||
gdb_assert (!type_changed);
|
||||
vpush (&result, (*varp));
|
||||
changed++;
|
||||
VEC_safe_push (varobj_p, result, *varp);
|
||||
}
|
||||
|
||||
/* Initialize a stack */
|
||||
vpush (&stack, NULL);
|
||||
|
||||
/* Push the root's children */
|
||||
if ((*varp)->children != NULL)
|
||||
{
|
||||
struct varobj_child *c;
|
||||
for (c = (*varp)->children; c != NULL; c = c->next)
|
||||
vpush (&stack, c->child);
|
||||
}
|
||||
VEC_safe_push (varobj_p, stack, *varp);
|
||||
|
||||
/* Walk through the children, reconstructing them all. */
|
||||
v = vpop (&stack);
|
||||
while (v != NULL)
|
||||
while (!VEC_empty (varobj_p, stack))
|
||||
{
|
||||
/* Push any children */
|
||||
if (v->children != NULL)
|
||||
v = VEC_pop (varobj_p, stack);
|
||||
|
||||
/* Push any children. Use 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, v->children)-1; i >= 0; --i)
|
||||
{
|
||||
struct varobj_child *c;
|
||||
for (c = v->children; c != NULL; c = c->next)
|
||||
vpush (&stack, c->child);
|
||||
varobj_p c = VEC_index (varobj_p, v->children, i);
|
||||
/* Child may be NULL if explicitly deleted by -var-delete. */
|
||||
if (c != NULL)
|
||||
VEC_safe_push (varobj_p, stack, c);
|
||||
}
|
||||
|
||||
/* Update this variable */
|
||||
new = value_of_child (v->parent, v->index);
|
||||
if (install_new_value (v, new, 0 /* type not changed */))
|
||||
{
|
||||
/* Note that it's changed */
|
||||
vpush (&result, v);
|
||||
v->updated = 0;
|
||||
changed++;
|
||||
/* Update this variable, unless it's a root, which is already
|
||||
updated. */
|
||||
if (v != *varp)
|
||||
{
|
||||
new = value_of_child (v->parent, v->index);
|
||||
if (install_new_value (v, new, 0 /* type not changed */))
|
||||
{
|
||||
/* Note that it's changed */
|
||||
VEC_safe_push (varobj_p, result, v);
|
||||
v->updated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get next child */
|
||||
v = vpop (&stack);
|
||||
}
|
||||
|
||||
/* Alloc (changed + 1) list entries */
|
||||
/* FIXME: add a cleanup for the allocated list(s)
|
||||
because one day the select_frame called below can longjump */
|
||||
changed = VEC_length (varobj_p, result);
|
||||
*changelist = xmalloc ((changed + 1) * sizeof (struct varobj *));
|
||||
if (changed > 1)
|
||||
{
|
||||
templist = xmalloc ((changed + 1) * sizeof (struct varobj *));
|
||||
cv = templist;
|
||||
}
|
||||
else
|
||||
cv = *changelist;
|
||||
cv = *changelist;
|
||||
|
||||
/* Copy from result stack to list */
|
||||
vleft = changed;
|
||||
*cv = vpop (&result);
|
||||
while ((*cv != NULL) && (vleft > 0))
|
||||
for (i = 0; i < changed; ++i)
|
||||
{
|
||||
vleft--;
|
||||
cv++;
|
||||
*cv = vpop (&result);
|
||||
}
|
||||
if (vleft)
|
||||
warning (_("varobj_update: assertion failed - vleft <> 0"));
|
||||
|
||||
if (changed > 1)
|
||||
{
|
||||
/* Now we revert the order. */
|
||||
for (i = 0; i < changed; i++)
|
||||
*(*changelist + i) = *(templist + changed - 1 - i);
|
||||
*(*changelist + changed) = NULL;
|
||||
*cv = VEC_index (varobj_p, result, i);
|
||||
gdb_assert (*cv != NULL);
|
||||
++cv;
|
||||
}
|
||||
*cv = 0;
|
||||
|
||||
if (type_changed)
|
||||
return -2;
|
||||
@ -1194,18 +1149,17 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp,
|
||||
struct varobj *var, int only_children_p,
|
||||
int remove_from_parent_p)
|
||||
{
|
||||
struct varobj_child *vc;
|
||||
struct varobj_child *next;
|
||||
int i;
|
||||
|
||||
/* Delete any children of this variable, too. */
|
||||
for (vc = var->children; vc != NULL; vc = next)
|
||||
{
|
||||
for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
|
||||
{
|
||||
varobj_p child = VEC_index (varobj_p, var->children, i);
|
||||
if (!remove_from_parent_p)
|
||||
vc->child->parent = NULL;
|
||||
delete_variable_1 (resultp, delcountp, vc->child, 0, only_children_p);
|
||||
next = vc->next;
|
||||
xfree (vc);
|
||||
child->parent = NULL;
|
||||
delete_variable_1 (resultp, delcountp, child, 0, only_children_p);
|
||||
}
|
||||
VEC_free (varobj_p, var->children);
|
||||
|
||||
/* if we were called to delete only the children we are done here */
|
||||
if (only_children_p)
|
||||
@ -1227,7 +1181,7 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp,
|
||||
discarding the list afterwards */
|
||||
if ((remove_from_parent_p) && (var->parent != NULL))
|
||||
{
|
||||
remove_child_from_parent (var->parent, var);
|
||||
VEC_replace (varobj_p, var->parent->children, var->index, NULL);
|
||||
}
|
||||
|
||||
if (var->obj_name != NULL)
|
||||
@ -1356,22 +1310,6 @@ uninstall_variable (struct varobj *var)
|
||||
|
||||
}
|
||||
|
||||
/* Does a child with the name NAME exist in VAR? If so, return its data.
|
||||
If not, return NULL. */
|
||||
static struct varobj *
|
||||
child_exists (struct varobj *var, char *name)
|
||||
{
|
||||
struct varobj_child *vc;
|
||||
|
||||
for (vc = var->children; vc != NULL; vc = vc->next)
|
||||
{
|
||||
if (strcmp (vc->child->name, name) == 0)
|
||||
return vc->child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create and install a child of the parent of the given name */
|
||||
static struct varobj *
|
||||
create_child (struct varobj *parent, int index, char *name)
|
||||
@ -1392,9 +1330,6 @@ create_child (struct varobj *parent, int index, char *name)
|
||||
child->obj_name = childs_name;
|
||||
install_variable (child);
|
||||
|
||||
/* Save a pointer to this child in the parent */
|
||||
save_child_in_parent (parent, child);
|
||||
|
||||
/* Compute the type of the child. Must do this before
|
||||
calling install_new_value. */
|
||||
if (value != NULL)
|
||||
@ -1412,46 +1347,6 @@ create_child (struct varobj *parent, int index, char *name)
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
/* FIXME: This should be a generic add to list */
|
||||
/* Save CHILD in the PARENT's data. */
|
||||
static void
|
||||
save_child_in_parent (struct varobj *parent, struct varobj *child)
|
||||
{
|
||||
struct varobj_child *vc;
|
||||
|
||||
/* Insert the child at the top */
|
||||
vc = parent->children;
|
||||
parent->children =
|
||||
(struct varobj_child *) xmalloc (sizeof (struct varobj_child));
|
||||
|
||||
parent->children->next = vc;
|
||||
parent->children->child = child;
|
||||
}
|
||||
|
||||
/* FIXME: This should be a generic remove from list */
|
||||
/* Remove the CHILD from the PARENT's list of children. */
|
||||
static void
|
||||
remove_child_from_parent (struct varobj *parent, struct varobj *child)
|
||||
{
|
||||
struct varobj_child *vc, *prev;
|
||||
|
||||
/* Find the child in the parent's list */
|
||||
prev = NULL;
|
||||
for (vc = parent->children; vc != NULL;)
|
||||
{
|
||||
if (vc->child == child)
|
||||
break;
|
||||
prev = vc;
|
||||
vc = vc->next;
|
||||
}
|
||||
|
||||
if (prev == NULL)
|
||||
parent->children = vc->next;
|
||||
else
|
||||
prev->next = vc->next;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@ -1583,36 +1478,6 @@ variable_default_display (struct varobj *var)
|
||||
return FORMAT_NATURAL;
|
||||
}
|
||||
|
||||
/* FIXME: The following should be generic for any pointer */
|
||||
static void
|
||||
vpush (struct vstack **pstack, struct varobj *var)
|
||||
{
|
||||
struct vstack *s;
|
||||
|
||||
s = (struct vstack *) xmalloc (sizeof (struct vstack));
|
||||
s->var = var;
|
||||
s->next = *pstack;
|
||||
*pstack = s;
|
||||
}
|
||||
|
||||
/* FIXME: The following should be generic for any pointer */
|
||||
static struct varobj *
|
||||
vpop (struct vstack **pstack)
|
||||
{
|
||||
struct vstack *s;
|
||||
struct varobj *v;
|
||||
|
||||
if ((*pstack)->var == NULL && (*pstack)->next == NULL)
|
||||
return NULL;
|
||||
|
||||
s = *pstack;
|
||||
v = s->var;
|
||||
*pstack = (*pstack)->next;
|
||||
xfree (s);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/* FIXME: The following should be generic for any pointer */
|
||||
static void
|
||||
cppush (struct cpstack **pstack, char *name)
|
||||
|
Loading…
Reference in New Issue
Block a user