[PATCH 4/7] Move struct varobj to varobj.h.

Yao Qi
2013-09-18T13:55:43Z

Hi,
This patch moves most of the fields of struct varobj to varobj.h, and
continue to name it 'struct varobj.h' there. New struct
varobj_dynamic 'extends' struct varobj in varobj.c.

Move part of struct varobj to varobj.h

gdb:

2013-09-18 Yao Qi <yao@codesourcery.com>

* varobj.c (struct varobj): Move most of the fields to
varobj.h.
(struct varobj_dynamic): New struct.
(varobj_get_display_hint) [HAVE_PYTHON]: Cast 'var' to type
'struct varobj_dynamic'.
(varobj_has_more): Likewise.
(dynamic_varobj_has_child_method): Change type of parameter
'var' to 'struct varobj_dynamic *'.
(update_dynamic_varobj_children): Likewise.
(install_visualizer): Likewise.
(install_default_visualizer, construct_visualizer): Likewise.
(varobj_get_num_children): Likewise.
(dynamic_varobj_has_child_method): Adjust.
(varobj_list_children, varobj_get_attributes): Likewise.
(varobj_set_value, install_new_value): Likewise.
(varobj_update, new_variable): Likewise.
(my_value_of_variable, value_get_print_value): Likewise.
* varobj.h (struct varobj): Moved from varobj.c.
---
gdb/varobj.c | 239 +++++++++++++++++++++++-----------------------------------
gdb/varobj.h | 74 ++++++++++++++++++
2 files changed, 167 insertions(+), 146 deletions(-)

diff --git a/gdb/varobj.c b/gdb/varobj.c
index 3ecf702..672d246 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -116,48 +116,11 @@ struct varobj_root
struct varobj_root *next;
};

-/* 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. */
-struct varobj
-{
-
- /* Alloc'd name of the variable for this object. If this variable is a
- child, then this name will be the child's source name.
- (bar, not foo.bar). */
- /* NOTE: This is the "expression". */
- char *name;
-
- /* Alloc'd expression for this child. Can be used to create a
- root variable corresponding to this child. */
- char *path_expr;
-
- /* The alloc'd name for this variable's object. This is here for
- convenience when constructing this object's children. */
- char *obj_name;
-
- /* Index of this variable in its parent or -1. */
- int index;
-
- /* The type of this variable. This can be NULL
- for artifial variable objects -- currently, the "accessibility"
- variable objects in C++. */
- struct type *type;
+/* Dynamic varobj. */

- /* The value of this expression or subexpression. A NULL value
- indicates there was an error getting this value.
- Invariant: if varobj_value_is_changeable_p (this) is non-zero,
- the value is either NULL, or not lazy. */
- struct value *value;
-
- /* The number of (immediate) children this variable has. */
- int num_children;
-
- /* If this object is a child, this points to its immediate parent. */
- struct varobj *parent;
-
- /* Children of this object. */
- VEC (varobj_p) *children;
+struct varobj_dynamic
+{
+ struct varobj base;

/* Whether the children of this varobj were requested. This field is
used to decide if dynamic varobj should recompute their children.
@@ -165,35 +128,6 @@ struct varobj
can avoid that. */
int children_requested;

- /* Description of the root variable. Points to root variable for
- children. */
- struct varobj_root *root;
-
- /* The format of the output for this object. */
- enum varobj_display_formats format;
-
- /* Was this variable updated via a varobj_set_value operation. */
- int updated;
-
- /* Last print value. */
- char *print_value;
-
- /* Is this variable frozen. Frozen variables are never implicitly
- updated by -var-update *
- or -var-update <direct-or-indirect-parent>. */
- int frozen;
-
- /* Is the value of this variable intentionally not fetched? It is
- not fetched if either the variable is frozen, or any parents is
- frozen. */
- int not_fetched;
-
- /* Sub-range of children which the MI consumer has requested. If
- FROM < 0 or TO < 0, means that all children have been
- requested. */
- int from;
- int to;
-
/* The pretty-printer constructor. If NULL, then the default
pretty-printer will be looked up. If None, then no
pretty-printer will be installed. */
@@ -899,14 +833,15 @@ varobj_get_display_hint (struct varobj *var)

#if HAVE_PYTHON
struct cleanup *back_to;
+ PyObject *pretty_printer = ((struct varobj_dynamic *) var)->pretty_printer;

if (!gdb_python_initialized)
return NULL;

back_to = varobj_ensure_python_env (var);

- if (var->pretty_printer)
- result = gdbpy_get_display_hint (var->pretty_printer);
+ if (pretty_printer != NULL)
+ result = gdbpy_get_display_hint (pretty_printer);

do_cleanups (back_to);
#endif
@@ -922,7 +857,7 @@ varobj_has_more (struct varobj *var, int to)
if (VEC_length (varobj_p, var->children) > to)
return 1;
return ((to == -1 || VEC_length (varobj_p, var->children) == to)
- && var->saved_item != NULL);
+ && ((struct varobj_dynamic *) var)->saved_item != NULL);
}

/* If the variable object is bound to a specific thread, that
@@ -1029,7 +964,7 @@ install_dynamic_child (struct varobj *var,
}

static int
-dynamic_varobj_has_child_method (struct varobj *var)
+dynamic_varobj_has_child_method (struct varobj_dynamic *var)
{
struct cleanup *back_to;
PyObject *printer = var->pretty_printer;
@@ -1038,7 +973,7 @@ dynamic_varobj_has_child_method (struct varobj *var)
if (!gdb_python_initialized)
return 0;

- back_to = varobj_ensure_python_env (var);
+ back_to = varobj_ensure_python_env ((struct varobj *) var);
result = PyObject_HasAttr (printer, gdbpy_children_cst);
do_cleanups (back_to);
return result;
@@ -1047,7 +982,7 @@ dynamic_varobj_has_child_method (struct varobj *var)
#endif

static int
-update_dynamic_varobj_children (struct varobj *var,
+update_dynamic_varobj_children (struct varobj_dynamic *var,
VEC (varobj_p) **changed,
VEC (varobj_p) **type_changed,
VEC (varobj_p) **new,
@@ -1066,7 +1001,7 @@ update_dynamic_varobj_children (struct varobj *var,
if (!gdb_python_initialized)
return 0;

- back_to = varobj_ensure_python_env (var);
+ back_to = varobj_ensure_python_env ((struct varobj *) var);

*cchanged = 0;
if (!PyObject_HasAttr (printer, gdbpy_children_cst))
@@ -1102,7 +1037,7 @@ update_dynamic_varobj_children (struct varobj *var,
i = 0;
}
else
- i = VEC_length (varobj_p, var->children);
+ i = VEC_length (varobj_p, var->base.children);

/* We ask for one extra child, so that MI can report whether there
are more children. */
@@ -1184,7 +1119,8 @@ update_dynamic_varobj_children (struct varobj *var,
v = convert_value_from_python (py_v);
if (v == NULL)
gdbpy_print_stack ();
- install_dynamic_child (var, can_mention ? changed : NULL,
+ install_dynamic_child ((struct varobj *) var,
+ can_mention ? changed : NULL,
can_mention ? type_changed : NULL,
can_mention ? new : NULL,
can_mention ? unchanged : NULL,
@@ -1205,22 +1141,22 @@ update_dynamic_varobj_children (struct varobj *var,
break;
}

- if (i < VEC_length (varobj_p, var->children))
+ if (i < VEC_length (varobj_p, var->base.children))
{
int j;

*cchanged = 1;
- for (j = i; j < VEC_length (varobj_p, var->children); ++j)
- varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0);
- VEC_truncate (varobj_p, var->children, i);
+ for (j = i; j < VEC_length (varobj_p, var->base.children); ++j)
+ varobj_delete (VEC_index (varobj_p, var->base.children, j), NULL, 0);
+ VEC_truncate (varobj_p, var->base.children, i);
}

/* If there are fewer children than requested, note that the list of
children changed. */
- if (to >= 0 && VEC_length (varobj_p, var->children) < to)
+ if (to >= 0 && VEC_length (varobj_p, var->base.children) < to)
*cchanged = 1;

- var->num_children = VEC_length (varobj_p, var->children);
+ var->base.num_children = VEC_length (varobj_p, var->base.children);

do_cleanups (back_to);

@@ -1235,14 +1171,16 @@ varobj_get_num_children (struct varobj *var)
{
if (var->num_children == -1)
{
- if (var->pretty_printer)
+ struct varobj_dynamic *var_dyn = (struct varobj_dynamic *) var;
+
+ if (var_dyn->pretty_printer)
{
int dummy;

/* If we have a dynamic varobj, don't report -1 children.
So, try to fetch some children first. */
- update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL, &dummy,
- 0, 0, 0);
+ update_dynamic_varobj_children (var_dyn, NULL, NULL, NULL,
+ NULL, &dummy, 0, 0, 0);
}
else
var->num_children = number_of_children (var);
@@ -1259,15 +1197,16 @@ varobj_list_children (struct varobj *var, int *from, int *to)
{
char *name;
int i, children_changed;
+ struct varobj_dynamic *var_dyn = (struct varobj_dynamic *) var;

- var->children_requested = 1;
+ var_dyn->children_requested = 1;

- if (var->pretty_printer)
+ if (var_dyn->pretty_printer)
{
/* This, in theory, can result in the number of children changing without
frontend noticing. But well, calling -var-list-children on the same
varobj twice is not something a sane frontend would do. */
- update_dynamic_varobj_children (var, NULL, NULL, NULL, NULL,
+ update_dynamic_varobj_children (var_dyn, NULL, NULL, NULL, NULL,
&children_changed, 0, 0, *to);
restrict_range (var->children, from, to);
return var->children;
@@ -1413,7 +1352,7 @@ varobj_get_attributes (struct varobj *var)
int
varobj_pretty_printed_p (struct varobj *var)
{
- return var->pretty_printer != NULL;
+ return ((struct varobj_dynamic *) var)->pretty_printer != NULL;
}

char *
@@ -1504,7 +1443,7 @@ varobj_set_value (struct varobj *var, char *expression)
in a varobj. */

static void
-install_visualizer (struct varobj *var, PyObject *constructor,
+install_visualizer (struct varobj_dynamic *var, PyObject *constructor,
PyObject *visualizer)
{
Py_XDECREF (var->constructor);
@@ -1520,19 +1459,19 @@ install_visualizer (struct varobj *var, PyObject *constructor,
/* Install the default visualizer for VAR. */

static void
-install_default_visualizer (struct varobj *var)
+install_default_visualizer (struct varobj_dynamic *var)
{
/* Do not install a visualizer on a CPLUS_FAKE_CHILD. */
- if (CPLUS_FAKE_CHILD (var))
+ if (CPLUS_FAKE_CHILD (&var->base))
return;

if (pretty_printing)
{
PyObject *pretty_printer = NULL;

- if (var->value)
+ if (var->base.value != NULL)
{
- pretty_printer = gdbpy_get_varobj_pretty_printer (var->value);
+ pretty_printer = gdbpy_get_varobj_pretty_printer (var->base.value);
if (! pretty_printer)
{
gdbpy_print_stack ();
@@ -1554,12 +1493,12 @@ install_default_visualizer (struct varobj *var)
make a new object. */

static void
-construct_visualizer (struct varobj *var, PyObject *constructor)
+construct_visualizer (struct varobj_dynamic *var, PyObject *constructor)
{
PyObject *pretty_printer;

/* Do not install a visualizer on a CPLUS_FAKE_CHILD. */
- if (CPLUS_FAKE_CHILD (var))
+ if (CPLUS_FAKE_CHILD (&var->base))
return;

Py_INCREF (constructor);
@@ -1567,7 +1506,8 @@ construct_visualizer (struct varobj *var, PyObject *constructor)
pretty_printer = NULL;
else
{
- pretty_printer = instantiate_pretty_printer (constructor, var->value);
+ pretty_printer = instantiate_pretty_printer (constructor,
+ var->base.value);
if (! pretty_printer)
{
gdbpy_print_stack ();
@@ -1592,7 +1532,7 @@ construct_visualizer (struct varobj *var, PyObject *constructor)
a visualizer for VAR, if appropriate. */

static void
-install_new_value_visualizer (struct varobj *var)
+install_new_value_visualizer (struct varobj_dynamic *var)
{
#if HAVE_PYTHON
/* If the constructor is None, then we want the raw value. If VAR
@@ -1600,13 +1540,13 @@ install_new_value_visualizer (struct varobj *var)
if (!gdb_python_initialized)
return;

- if (var->constructor != Py_None && var->value)
+ if (var->constructor != Py_None && var->base.value)
{
struct cleanup *cleanup;

- cleanup = varobj_ensure_python_env (var);
+ cleanup = varobj_ensure_python_env ((struct varobj *) var);

- if (!var->constructor)
+ if (var->constructor == NULL)
install_default_visualizer (var);
else
construct_visualizer (var, var->constructor);
@@ -1676,6 +1616,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
int changed = 0;
int intentionally_not_fetched = 0;
char *print_value = NULL;
+ struct varobj_dynamic *var_dyn = (struct varobj_dynamic *) var;

/* We need to know the varobj's type to decide if the value should
be fetched or not. C++ fake children (public/protected/private)
@@ -1686,7 +1627,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
/* If the type has custom visualizer, we consider it to be always
changeable. FIXME: need to make sure this behaviour will not
mess up read-sensitive values. */
- if (var->pretty_printer)
+ if (var_dyn->pretty_printer != NULL)
changeable = 1;

need_to_fetch = changeable;
@@ -1757,7 +1698,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
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) && !var->pretty_printer)
+ if (value && !value_lazy (value) && var_dyn->pretty_printer == NULL)
print_value = value_get_print_value (value, var->format, var);

/* If the type is changeable, compare the old and the new values.
@@ -1774,7 +1715,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
{
changed = 1;
}
- else if (! var->pretty_printer)
+ else if (var_dyn->pretty_printer == NULL)
{
/* Try to compare the values. That requires that both
values are non-lazy. */
@@ -1825,11 +1766,11 @@ install_new_value (struct varobj *var, struct value *value, int initial)
var->not_fetched = 0;
var->updated = 0;

- install_new_value_visualizer (var);
+ install_new_value_visualizer (var_dyn);

/* If we installed a pretty-printer, re-compare the printed version
to see if the variable changed. */
- if (var->pretty_printer)
+ if (var_dyn->pretty_printer != NULL)
{
xfree (print_value);
print_value = value_get_print_value (var->value, var->format, var);
@@ -1894,7 +1835,7 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
error (_("Could not evaluate visualizer expression: %s"), visualizer);
}

- construct_visualizer (var, constructor);
+ construct_visualizer ((struct varobj_dynamic *) var, constructor);
Py_XDECREF (constructor);

/* If there are any children now, wipe them. */
@@ -2019,6 +1960,7 @@ varobj_update (struct varobj **varp, int explicit)
{
varobj_update_result r = *(VEC_last (varobj_update_result, stack));
struct varobj *v = r.varobj;
+ struct varobj_dynamic *v_dyn = (struct varobj_dynamic *) v;

VEC_pop (varobj_update_result, stack);

@@ -2058,7 +2000,7 @@ varobj_update (struct varobj **varp, int explicit)
/* We probably should not get children of a varobj that has a
pretty-printer, but for which -var-list-children was never
invoked. */
- if (v->pretty_printer)
+ if (v_dyn->pretty_printer != NULL)
{
VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0;
VEC (varobj_p) *new = 0;
@@ -2067,7 +2009,7 @@ varobj_update (struct varobj **varp, int explicit)
if (v->frozen)
continue;

- if (!v->children_requested)
+ if (!v_dyn->children_requested)
{
int dummy;

@@ -2079,8 +2021,8 @@ varobj_update (struct varobj **varp, int explicit)
it. */
if (!varobj_has_more (v, 0))
{
- update_dynamic_varobj_children (v, NULL, NULL, NULL, NULL,
- &dummy, 0, 0, 0);
+ update_dynamic_varobj_children (v_dyn, NULL, NULL, NULL,
+ NULL, &dummy, 0, 0, 0);
if (varobj_has_more (v, 0))
r.changed = 1;
}
@@ -2093,9 +2035,10 @@ varobj_update (struct varobj **varp, int explicit)

/* 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,
- &unchanged, &children_changed, 1,
- v->from, v->to))
+ if (update_dynamic_varobj_children (v_dyn, &changed, &type_changed,
+ &new, &unchanged,
+ &children_changed, 1, v->from,
+ v->to))
{
if (children_changed || new)
{
@@ -2441,33 +2384,33 @@ create_child_with_value (struct varobj *parent, int index, const char *name,
static struct varobj *
new_variable (void)
{
- struct varobj *var;
-
- var = (struct varobj *) xmalloc (sizeof (struct varobj));
- var->name = NULL;
- var->path_expr = NULL;
- var->obj_name = NULL;
- var->index = -1;
- var->type = NULL;
- var->value = NULL;
- var->num_children = -1;
- var->parent = NULL;
- var->children = NULL;
- var->format = 0;
- var->root = NULL;
- var->updated = 0;
- var->print_value = NULL;
- var->frozen = 0;
- var->not_fetched = 0;
+ struct varobj_dynamic *var;
+
+ var = (struct varobj_dynamic *) xmalloc (sizeof (struct varobj_dynamic));
+ var->base.name = NULL;
+ var->base.path_expr = NULL;
+ var->base.obj_name = NULL;
+ var->base.index = -1;
+ var->base.type = NULL;
+ var->base.value = NULL;
+ var->base.num_children = -1;
+ var->base.parent = NULL;
+ var->base.children = NULL;
+ var->base.format = 0;
+ var->base.root = NULL;
+ var->base.updated = 0;
+ var->base.print_value = NULL;
+ var->base.frozen = 0;
+ var->base.not_fetched = 0;
var->children_requested = 0;
- var->from = -1;
- var->to = -1;
+ var->base.from = -1;
+ var->base.to = -1;
var->constructor = 0;
var->pretty_printer = 0;
var->child_iter = 0;
var->saved_item = 0;

- return var;
+ return (struct varobj *) var;
}

/* Allocate memory and initialize a new root variable. */
@@ -2493,13 +2436,16 @@ static void
free_variable (struct varobj *var)
{
#if HAVE_PYTHON
- if (var->pretty_printer)
+ struct varobj_dynamic *var_dyn = (struct varobj_dynamic *) var;
+
+ if (var_dyn->pretty_printer)
{
struct cleanup *cleanup = varobj_ensure_python_env (var);
- Py_XDECREF (var->constructor);
- Py_XDECREF (var->pretty_printer);
- Py_XDECREF (var->child_iter);
- Py_XDECREF (var->saved_item);
+
+ Py_XDECREF (var_dyn->constructor);
+ Py_XDECREF (var_dyn->pretty_printer);
+ Py_XDECREF (var_dyn->child_iter);
+ Py_XDECREF (var_dyn->saved_item);
do_cleanups (cleanup);
}
#endif
@@ -2889,7 +2835,7 @@ my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
if (var->root->is_valid)
{
- if (var->pretty_printer)
+ if (((struct varobj_dynamic *) var)->pretty_printer)
return value_get_print_value (var->value, var->format, var);
return (*var->root->lang->value_of_variable) (var, format);
}
@@ -2923,7 +2869,8 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
#if HAVE_PYTHON
if (gdb_python_initialized)
{
- PyObject *value_formatter = var->pretty_printer;
+ PyObject *value_formatter
+ = ((struct varobj_dynamic *) var)->pretty_printer;

varobj_ensure_python_env (var);

@@ -2931,7 +2878,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
{
/* First check to see if we have any children at all. If so,
we simply return {...}. */
- if (dynamic_varobj_has_child_method (var))
+ if (dynamic_varobj_has_child_method ((struct varobj_dynamic *) var))
{
do_cleanups (old_chain);
return xstrdup ("{...}");
diff --git a/gdb/varobj.h b/gdb/varobj.h
index d4abb99..894ba03 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -88,6 +88,80 @@ typedef struct varobj_update_result_t

DEF_VEC_O (varobj_update_result);

+struct varobj_root;
+
+/* 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. */
+struct varobj
+{
+ /* Alloc'd name of the variable for this object. If this variable is a
+ child, then this name will be the child's source name.
+ (bar, not foo.bar). */
+ /* NOTE: This is the "expression". */
+ char *name;
+
+ /* Alloc'd expression for this child. Can be used to create a
+ root variable corresponding to this child. */
+ char *path_expr;
+
+ /* The alloc'd name for this variable's object. This is here for
+ convenience when constructing this object's children. */
+ char *obj_name;
+
+ /* Index of this variable in its parent or -1. */
+ int index;
+
+ /* The type of this variable. This can be NULL
+ for artifial variable objects -- currently, the "accessibility"
+ variable objects in C++. */
+ struct type *type;
+
+ /* The value of this expression or subexpression. A NULL value
+ indicates there was an error getting this value.
+ Invariant: if varobj_value_is_changeable_p (this) is non-zero,
+ the value is either NULL, or not lazy. */
+ struct value *value;
+
+ /* The number of (immediate) children this variable has. */
+ int num_children;
+
+ /* If this object is a child, this points to its immediate parent. */
+ struct varobj *parent;
+
+ /* Children of this object. */
+ VEC (varobj_p) *children;
+
+ /* Description of the root variable. Points to root variable for
+ children. */
+ struct varobj_root *root;
+
+ /* The format of the output for this object. */
+ enum varobj_display_formats format;
+
+ /* Was this variable updated via a varobj_set_value operation. */
+ int updated;
+
+ /* Last print value. */
+ char *print_value;
+
+ /* Is this variable frozen. Frozen variables are never implicitly
+ updated by -var-update *
+ or -var-update <direct-or-indirect-parent>. */
+ int frozen;
+
+ /* Is the value of this variable intentionally not fetched? It is
+ not fetched if either the variable is frozen, or any parents is
+ frozen. */
+ int not_fetched;
+
+ /* Sub-range of children which the MI consumer has requested. If
+ FROM < 0 or TO < 0, means that all children have been
+ requested. */
+ int from;
+ int to;
+};
+
/* API functions */

extern struct varobj *varobj_create (char *objname,
--
1.7.7.6