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

Joel Brobecker
2013-10-02T09:46:43Z

> 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.

Overall, I like the direction that the whole series is taking.
But this is a patch that makes me a little uncomfortable, because
I am not sure really want to introduce this kind of polymorphism
where we cast struct varobj into struct varobj_dynamic. I would
need to think about it some more - it seems to me that at the root
of things, we are always manipulating a varobj_dynamic so it is
always safe to cast it. But this then begs the question why not
declare them as struct varobj_dynamic in the first place. The answer
is probably that we don't want to expose too much of struct varobj,
and in particular the part dealing with dynamicity and pretty-printers.

Perhaps, and this is thinking out loud, another approach would be
to make this data part of the public struct varobj, but inside
an opaque structure?

I'd really like feedback from other maintainers who have experience
in this area...

> ---
> 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

--
Joel