/* Implementation of the GDB variable objects API.
- Copyright (C) 1999-2020 Free Software Foundation, Inc.
+ Copyright (C) 1999-2022 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "gdbcmd.h"
#include "block.h"
#include "valprint.h"
-#include "gdb_regex.h"
+#include "gdbsupport/gdb_regex.h"
#include "varobj.h"
#include "gdbthread.h"
static void delete_variable_1 (int *, struct varobj *, bool, bool);
-static bool install_variable (struct varobj *);
+static void install_variable (struct varobj *);
static void uninstall_variable (struct varobj *);
}
/* Don't allow variables to be created for types. */
- if (var->root->exp->elts[0].opcode == OP_TYPE
- || var->root->exp->elts[0].opcode == OP_TYPEOF
- || var->root->exp->elts[0].opcode == OP_DECLTYPE)
+ enum exp_opcode opcode = var->root->exp->first_opcode ();
+ if (opcode == OP_TYPE
+ || opcode == OP_TYPEOF
+ || opcode == OP_DECLTYPE)
{
fprintf_unfiltered (gdb_stderr, "Attempt to use a type name"
" as an expression.\n");
if ((var != NULL) && (objname != NULL))
{
var->obj_name = objname;
-
- /* If a varobj name is duplicated, the install will fail so
- we must cleanup. */
- if (!install_variable (var.get ()))
- return NULL;
+ install_variable (var.get ());
}
return var.release ();
static PyObject *
instantiate_pretty_printer (PyObject *constructor, struct value *value)
{
- PyObject *val_obj = NULL;
- PyObject *printer;
-
- val_obj = value_to_value_object (value);
- if (! val_obj)
+ gdbpy_ref<> val_obj (value_to_value_object (value));
+ if (val_obj == nullptr)
return NULL;
- printer = PyObject_CallFunctionObjArgs (constructor, val_obj, NULL);
- Py_DECREF (val_obj);
- return printer;
+ return PyObject_CallFunctionObjArgs (constructor, val_obj.get (), NULL);
}
#endif
else
{
varobj *existing = var->children[index];
- bool type_updated = update_type_if_necessary (existing, item->value);
+ bool type_updated = update_type_if_necessary (existing,
+ item->value.get ());
if (type_updated)
{
if (type_changed != NULL)
type_changed->push_back (existing);
}
- if (install_new_value (existing, item->value, 0))
+ if (install_new_value (existing, item->value.get (), 0))
{
if (!type_updated && changed != NULL)
changed->push_back (existing);
return py_varobj_get_iterator (var, var->dynamic->pretty_printer);
#endif
- gdb_assert_not_reached (_("\
-requested an iterator from a non-dynamic varobj"));
-}
-
-/* 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_decref (var->saved_item->value);
- var->saved_item.reset (nullptr);
- }
+ gdb_assert_not_reached ("requested an iterator from a non-dynamic varobj");
}
static bool
if (update_children || var->dynamic->child_iter == NULL)
{
var->dynamic->child_iter = varobj_get_iterator (var);
-
- varobj_clear_saved_item (var->dynamic);
+ var->dynamic->saved_item.reset (nullptr);
i = 0;
if (var->dynamic->saved_item != NULL)
item = std::move (var->dynamic->saved_item);
else
- {
- item = var->dynamic->child_iter->next ();
- /* Release vitem->value so its lifetime is not bound to the
- execution of a command. */
- if (item != NULL && item->value != NULL)
- item->value = release_value (item->value).release ();
- }
+ item = var->dynamic->child_iter->next ();
if (item == NULL)
{
}
/* Install the given variable VAR with the object name VAR->OBJ_NAME. */
-static bool
+static void
install_variable (struct varobj *var)
{
hashval_t hash = htab_hash_string (var->obj_name.c_str ());
/* If root, add varobj to root list. */
if (is_root_p (var))
rootlist.push_front (var->root);
-
- return true; /* OK */
}
/* Uninstall the object VAR. */
struct varobj_item item;
std::swap (item.name, name);
- item.value = value_of_child (parent, index);
+ item.value = release_value (value_of_child (parent, index));
return create_child_with_value (parent, index, &item);
}
if (item->value != NULL)
/* If the child had no evaluation errors, var->value
will be non-NULL and contain a valid type. */
- child->type = value_actual_type (item->value, 0, NULL);
+ child->type = value_actual_type (item->value.get (), 0, NULL);
else
/* Otherwise, we must compute the type. */
child->type = (*child->root->lang_ops->type_of_child) (child->parent,
child->index);
- install_new_value (child, item->value, 1);
+ install_new_value (child, item->value.get (), 1);
return child;
}
}
#endif
- varobj_clear_saved_item (var->dynamic);
+ /* This must be deleted before the root object, because Python-based
+ destructors need access to some components. */
+ delete var->dynamic;
if (is_root_p (var))
delete var->root;
-
- delete var->dynamic;
}
/* Return the type of the value that's stored in VAR,
thevalue = std::string (s.get ());
len = thevalue.size ();
- gdbarch = get_type_arch (value_type (value));
+ gdbarch = value_type (value)->arch ();
type = builtin_type (gdbarch)->builtin_char;
if (!string_print)