along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "exceptions.h"
#include "value.h"
#include "expression.h"
#include "frame.h"
#include "gdbcmd.h"
#include "block.h"
#include "valprint.h"
-
-#include "gdb_assert.h"
-#include <string.h>
#include "gdb_regex.h"
#include "varobj.h"
#include "vec.h"
#include "gdbthread.h"
#include "inferior.h"
+#include "varobj-iter.h"
#if HAVE_PYTHON
#include "python/python.h"
typedef int PyObject;
#endif
-#include "varobj-iter.h"
-
/* Non-zero if we want to see trace of varobj level stuff. */
unsigned int varobjdebug = 0;
struct varobj_root *next;
};
-/* A node or item of varobj, composed of the name and the value. */
-
-struct varobj_item
-{
- /* Name of this item. */
- char *name;
-
- /* Value of this item. */
- struct value *value;
-};
-
/* Dynamic part of varobj. */
struct varobj_dynamic
static int is_root_p (struct varobj *var);
-#if HAVE_PYTHON
-
static struct varobj *varobj_add_child (struct varobj *var,
struct varobj_item *item);
-#endif /* HAVE_PYTHON */
-
/* Private data */
/* Mappings of varobj_display_formats enums to gdb's format codes. */
{
struct frame_info *fi;
struct frame_id old_id = null_frame_id;
- struct block *block;
+ const struct block *block;
const char *p;
struct value *value = NULL;
volatile struct gdb_exception except;
}
}
-#if HAVE_PYTHON
-
/* A helper for update_dynamic_varobj_children that installs a new
child when needed. */
}
}
+#if HAVE_PYTHON
+
static int
dynamic_varobj_has_child_method (struct varobj *var)
{
do_cleanups (back_to);
return result;
}
+#endif
/* A factory for creating dynamic varobj's iterators. Returns an
iterator object suitable for iterating over VAR's children. */
static struct varobj_iter *
varobj_get_iterator (struct varobj *var)
{
+#if HAVE_PYTHON
if (var->dynamic->pretty_printer)
return py_varobj_get_iterator (var, var->dynamic->pretty_printer);
+#endif
gdb_assert_not_reached (_("\
requested an iterator from a non-dynamic varobj"));
}
-#endif
+/* Release and clear VAR's saved item, if any. */
+
+static void
+varobj_clear_saved_item (struct varobj_dynamic *var)
+{
+ if (var->saved_item != NULL)
+ {
+ value_free (var->saved_item->value);
+ xfree (var->saved_item);
+ var->saved_item = NULL;
+ }
+}
static int
update_dynamic_varobj_children (struct varobj *var,
int from,
int to)
{
-#if HAVE_PYTHON
- struct cleanup *back_to;
int i;
- if (!gdb_python_initialized)
- return 0;
-
- back_to = varobj_ensure_python_env (var);
-
*cchanged = 0;
if (update_children || var->dynamic->child_iter == NULL)
varobj_iter_delete (var->dynamic->child_iter);
var->dynamic->child_iter = varobj_get_iterator (var);
- Py_XDECREF (var->dynamic->saved_item);
- var->dynamic->saved_item = NULL;
+ varobj_clear_saved_item (var->dynamic);
i = 0;
if (var->dynamic->child_iter == NULL)
- {
- do_cleanups (back_to);
- return 0;
- }
+ return 0;
}
else
i = VEC_length (varobj_p, var->children);
are more children. */
for (; to < 0 || i < to + 1; ++i)
{
- PyObject *item;
+ varobj_item *item;
/* See if there was a leftover from last time. */
- if (var->dynamic->saved_item)
+ if (var->dynamic->saved_item != NULL)
{
item = var->dynamic->saved_item;
var->dynamic->saved_item = NULL;
else
{
item = varobj_iter_next (var->dynamic->child_iter);
+ /* Release vitem->value so its lifetime is not bound to the
+ execution of a command. */
+ if (item != NULL && item->value != NULL)
+ release_value_or_incref (item->value);
}
if (item == NULL)
/* We don't want to push the extra child on any report list. */
if (to < 0 || i < to)
{
- PyObject *py_v;
- const char *name;
- struct varobj_item varobj_item;
- struct cleanup *inner;
int can_mention = from < 0 || i >= from;
- inner = make_cleanup_py_decref (item);
-
- if (!PyArg_ParseTuple (item, "sO", &name, &py_v))
- {
- gdbpy_print_stack ();
- error (_("Invalid item from the child list"));
- }
-
- varobj_item.value = convert_value_from_python (py_v);
- if (varobj_item.value == NULL)
- gdbpy_print_stack ();
- varobj_item.name = xstrdup (name);
-
install_dynamic_child (var, can_mention ? changed : NULL,
can_mention ? type_changed : NULL,
can_mention ? new : NULL,
can_mention ? unchanged : NULL,
can_mention ? cchanged : NULL, i,
- &varobj_item);
- do_cleanups (inner);
+ item);
+
+ xfree (item);
}
else
{
- Py_XDECREF (var->dynamic->saved_item);
var->dynamic->saved_item = item;
/* We want to truncate the child list just before this
var->num_children = VEC_length (varobj_p, var->children);
- do_cleanups (back_to);
return 1;
-#else
- gdb_assert_not_reached ("should never be called if Python is not enabled");
-#endif
}
int
{
if (var->num_children == -1)
{
- if (var->dynamic->pretty_printer != NULL)
+ if (varobj_is_dynamic_p (var))
{
int dummy;
var->dynamic->children_requested = 1;
- if (var->dynamic->pretty_printer != NULL)
+ if (varobj_is_dynamic_p (var))
{
/* This, in theory, can result in the number of children changing without
frontend noticing. But well, calling -var-list-children on the same
return var->children;
}
-#if HAVE_PYTHON
-
static struct varobj *
varobj_add_child (struct varobj *var, struct varobj_item *item)
{
return v;
}
-#endif /* HAVE_PYTHON */
-
/* Obtain the type of an object Variable as a string similar to the one gdb
prints on the console. */
static int
is_path_expr_parent (struct varobj *var)
{
- struct type *type;
-
- /* "Fake" children are not path_expr parents. */
- if (CPLUS_FAKE_CHILD (var))
- return 0;
+ gdb_assert (var->root->lang_ops->is_path_expr_parent != NULL);
+ return var->root->lang_ops->is_path_expr_parent (var);
+}
- type = varobj_get_value_type (var);
+/* Is VAR a path expression parent, i.e., can it be used to construct
+ a valid path expression? By default we assume any VAR can be a path
+ parent. */
- /* Anonymous unions and structs are also not path_expr parents. */
- return !((TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION)
- && TYPE_NAME (type) == NULL);
+int
+varobj_default_is_path_expr_parent (struct varobj *var)
+{
+ return 1;
}
/* Return the path expression parent for VAR. */
return attributes;
}
+/* Return true if VAR is a dynamic varobj. */
+
int
-varobj_pretty_printed_p (struct varobj *var)
+varobj_is_dynamic_p (struct varobj *var)
{
return var->dynamic->pretty_printer != NULL;
}
}
}
- /* 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->dynamic->pretty_printer != NULL)
+ /* We probably should not get children of a dynamic varobj, but
+ 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) *new = 0;
Py_XDECREF (var->dynamic->constructor);
Py_XDECREF (var->dynamic->pretty_printer);
- Py_XDECREF (var->dynamic->child_iter);
- Py_XDECREF (var->dynamic->saved_item);
do_cleanups (cleanup);
}
#endif
+ varobj_iter_delete (var->dynamic->child_iter);
+ varobj_clear_saved_item (var->dynamic);
value_free (var->value);
/* Free the expression if this is a root variable. */
(*func) (var_root->rootvar, data);
}
}
-\f
-extern void _initialize_varobj (void);
-void
-_initialize_varobj (void)
-{
- int sizeof_table = sizeof (struct vlist *) * VAROBJ_TABLE_SIZE;
-
- varobj_table = xmalloc (sizeof_table);
- memset (varobj_table, 0, sizeof_table);
-
- add_setshow_zuinteger_cmd ("varobj", class_maintenance,
- &varobjdebug,
- _("Set varobj debugging."),
- _("Show varobj debugging."),
- _("When non-zero, varobj debugging is enabled."),
- NULL, show_varobjdebug,
- &setdebuglist, &showdebuglist);
-}
/* Invalidate varobj VAR if it is tied to locals and re-create it if it is
defined on globals. It is a helper for varobj_invalidate.
{
all_root_varobjs (varobj_invalidate_iter, NULL);
}
+\f
+extern void _initialize_varobj (void);
+void
+_initialize_varobj (void)
+{
+ int sizeof_table = sizeof (struct vlist *) * VAROBJ_TABLE_SIZE;
+
+ varobj_table = xmalloc (sizeof_table);
+ memset (varobj_table, 0, sizeof_table);
+
+ add_setshow_zuinteger_cmd ("varobj", class_maintenance,
+ &varobjdebug,
+ _("Set varobj debugging."),
+ _("Show varobj debugging."),
+ _("When non-zero, varobj debugging is enabled."),
+ NULL, show_varobjdebug,
+ &setdebuglist, &showdebuglist);
+}