public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 00/11] Some varobj C++-ification and cleanup
@ 2020-10-24 21:08 Tom Tromey
  2020-10-24 21:08 ` [PATCH 01/11] Use htab_t in varobj Tom Tromey
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches

I was looking at varobj recently and noticed a few relatively simple
things that could be done to simplify the code and somewhat C++-ify
it.  This series is the result.

Tested on x86-64 Fedora 28.

Tom



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 01/11] Use htab_t in varobj
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 02/11] Change varobj.c:rootlist to a std::list Tom Tromey
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

varobj.c currently has its own hash table implementation.  This patch
replaces it with htab_t, simplifying the code.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (VAROBJ_TABLE_SIZE): Remove.
	(varobj_table): Now htab_t.
	(varobj_get_handle, install_variable, uninstall_variable):
	Update.
	(hash_varobj, eq_varobj_and_string): New functions.
	(hash_varobj): Update.
---
 gdb/ChangeLog |   9 +++++
 gdb/varobj.c  | 109 ++++++++++++++++----------------------------------
 2 files changed, 44 insertions(+), 74 deletions(-)

diff --git a/gdb/varobj.c b/gdb/varobj.c
index 85530e3f3cf..3af1ef22d7e 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -200,12 +200,8 @@ static int format_code[] = { 0, 't', 'd', 'x', 'o', 'z' };
 /* Header of the list of root variable objects.  */
 static struct varobj_root *rootlist;
 
-/* Prime number indicating the number of buckets in the hash table.  */
-/* A prime large enough to avoid too many collisions.  */
-#define VAROBJ_TABLE_SIZE 227
-
 /* Pointer to the varobj hash table (built at run time).  */
-static struct vlist **varobj_table;
+static htab_t varobj_table;
 
 \f
 
@@ -432,24 +428,13 @@ varobj_gen_name (void)
 struct varobj *
 varobj_get_handle (const char *objname)
 {
-  struct vlist *cv;
-  const char *chp;
-  unsigned int index = 0;
-  unsigned int i = 1;
-
-  for (chp = objname; *chp; chp++)
-    {
-      index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
-    }
+  varobj *var = (varobj *) htab_find_with_hash (varobj_table, objname,
+						htab_hash_string (objname));
 
-  cv = *(varobj_table + index);
-  while (cv != NULL && cv->var->obj_name != objname)
-    cv = cv->next;
-
-  if (cv == NULL)
+  if (var == NULL)
     error (_("Variable object not found"));
 
-  return cv->var;
+  return var;
 }
 
 /* Given the handle, return the name of the object.  */
@@ -1793,29 +1778,15 @@ delete_variable_1 (int *delcountp, struct varobj *var, bool only_children_p,
 static bool
 install_variable (struct varobj *var)
 {
-  struct vlist *cv;
-  struct vlist *newvl;
-  const char *chp;
-  unsigned int index = 0;
-  unsigned int i = 1;
-
-  for (chp = var->obj_name.c_str (); *chp; chp++)
-    {
-      index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
-    }
-
-  cv = *(varobj_table + index);
-  while (cv != NULL && cv->var->obj_name != var->obj_name)
-    cv = cv->next;
-
-  if (cv != NULL)
+  hashval_t hash = htab_hash_string (var->obj_name.c_str ());
+  void **slot = htab_find_slot_with_hash (varobj_table,
+					  var->obj_name.c_str (),
+					  hash, INSERT);
+  if (*slot != nullptr)
     error (_("Duplicate variable object name"));
 
   /* Add varobj to hash table.  */
-  newvl = XNEW (struct vlist);
-  newvl->next = *(varobj_table + index);
-  newvl->var = var;
-  *(varobj_table + index) = newvl;
+  *slot = var;
 
   /* If root, add varobj to root list.  */
   if (is_root_p (var))
@@ -1835,46 +1806,15 @@ install_variable (struct varobj *var)
 static void
 uninstall_variable (struct varobj *var)
 {
-  struct vlist *cv;
-  struct vlist *prev;
   struct varobj_root *cr;
   struct varobj_root *prer;
-  const char *chp;
-  unsigned int index = 0;
-  unsigned int i = 1;
-
-  /* Remove varobj from hash table.  */
-  for (chp = var->obj_name.c_str (); *chp; chp++)
-    {
-      index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
-    }
 
-  cv = *(varobj_table + index);
-  prev = NULL;
-  while (cv != NULL && cv->var->obj_name != var->obj_name)
-    {
-      prev = cv;
-      cv = cv->next;
-    }
+  hashval_t hash = htab_hash_string (var->obj_name.c_str ());
+  htab_remove_elt_with_hash (varobj_table, var->obj_name.c_str (), hash);
 
   if (varobjdebug)
     fprintf_unfiltered (gdb_stdlog, "Deleting %s\n", var->obj_name.c_str ());
 
-  if (cv == NULL)
-    {
-      warning
-	("Assertion failed: Could not find variable object \"%s\" to delete",
-	 var->obj_name.c_str ());
-      return;
-    }
-
-  if (prev == NULL)
-    *(varobj_table + index) = cv->next;
-  else
-    prev->next = cv->next;
-
-  xfree (cv);
-
   /* If root, remove varobj from root list.  */
   if (is_root_p (var))
     {
@@ -2520,11 +2460,32 @@ varobj_invalidate (void)
   all_root_varobjs (varobj_invalidate_iter, NULL);
 }
 
+/* A hash function for a varobj.  */
+
+static hashval_t
+hash_varobj (const void *a)
+{
+  const varobj *obj = (const varobj *) a;
+  return htab_hash_string (obj->obj_name.c_str ());
+}
+
+/* A hash table equality function for varobjs.  */
+
+static int
+eq_varobj_and_string (const void *a, const void *b)
+{
+  const varobj *obj = (const varobj *) a;
+  const char *name = (const char *) b;
+
+  return obj->obj_name == name;
+}
+
 void _initialize_varobj ();
 void
 _initialize_varobj ()
 {
-  varobj_table = XCNEWVEC (struct vlist *, VAROBJ_TABLE_SIZE);
+  varobj_table = htab_create_alloc (5, hash_varobj, eq_varobj_and_string,
+				    nullptr, xcalloc, xfree);
 
   add_setshow_zuinteger_cmd ("varobj", class_maintenance,
 			     &varobjdebug,
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 02/11] Change varobj.c:rootlist to a std::list
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
  2020-10-24 21:08 ` [PATCH 01/11] Use htab_t in varobj Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 03/11] Change all_root_varobjs to take a function_view Tom Tromey
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes varobj.c:rootlist to be a std::list.  This lets us remove
some code.  std::list is chosen because its iterator invalidation
approach suits the all_root_varobjs API.

I considered replacing all_root_varobjs with "external iteration", but
haven't gotten around to doing so.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (struct varobj_root) <next>: Remove.
	(struct vlist): Remove.
	(rootlist): Now a std::list.
	(install_variable, uninstall_variable, all_root_varobjs): Update.
---
 gdb/ChangeLog |  7 ++++++
 gdb/varobj.c  | 67 +++++++++------------------------------------------
 2 files changed, 18 insertions(+), 56 deletions(-)

diff --git a/gdb/varobj.c b/gdb/varobj.c
index 3af1ef22d7e..ea57a79aa41 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -31,6 +31,7 @@
 #include "varobj-iter.h"
 #include "parser-defs.h"
 #include "gdbarch.h"
+#include <algorithm>
 
 #if HAVE_PYTHON
 #include "python/python.h"
@@ -100,9 +101,6 @@ struct varobj_root
 
   /* The varobj for this root node.  */
   struct varobj *rootvar = NULL;
-
-  /* Next root variable */
-  struct varobj_root *next = NULL;
 };
 
 /* Dynamic part of varobj.  */
@@ -136,14 +134,6 @@ struct varobj_dynamic
   varobj_item *saved_item = NULL;
 };
 
-/* A list of varobjs */
-
-struct vlist
-{
-  struct varobj *var;
-  struct vlist *next;
-};
-
 /* Private function prototypes */
 
 /* Helper functions for the above subcommands.  */
@@ -197,8 +187,8 @@ static struct varobj *varobj_add_child (struct varobj *var,
 /* Mappings of varobj_display_formats enums to gdb's format codes.  */
 static int format_code[] = { 0, 't', 'd', 'x', 'o', 'z' };
 
-/* Header of the list of root variable objects.  */
-static struct varobj_root *rootlist;
+/* List of root variable objects.  */
+static std::list<struct varobj_root *> rootlist;
 
 /* Pointer to the varobj hash table (built at run time).  */
 static htab_t varobj_table;
@@ -1790,14 +1780,7 @@ install_variable (struct varobj *var)
 
   /* If root, add varobj to root list.  */
   if (is_root_p (var))
-    {
-      /* Add to list of root variables.  */
-      if (rootlist == NULL)
-	var->root->next = NULL;
-      else
-	var->root->next = rootlist;
-      rootlist = var->root;
-    }
+    rootlist.push_front (var->root);
 
   return true;			/* OK */
 }
@@ -1806,9 +1789,6 @@ install_variable (struct varobj *var)
 static void
 uninstall_variable (struct varobj *var)
 {
-  struct varobj_root *cr;
-  struct varobj_root *prer;
-
   hashval_t hash = htab_hash_string (var->obj_name.c_str ());
   htab_remove_elt_with_hash (varobj_table, var->obj_name.c_str (), hash);
 
@@ -1818,32 +1798,9 @@ uninstall_variable (struct varobj *var)
   /* If root, remove varobj from root list.  */
   if (is_root_p (var))
     {
-      /* Remove from list of root variables.  */
-      if (rootlist == var->root)
-	rootlist = var->root->next;
-      else
-	{
-	  prer = NULL;
-	  cr = rootlist;
-	  while ((cr != NULL) && (cr->rootvar != var))
-	    {
-	      prer = cr;
-	      cr = cr->next;
-	    }
-	  if (cr == NULL)
-	    {
-	      warning (_("Assertion failed: Could not find "
-		         "varobj \"%s\" in root list"),
-		       var->obj_name.c_str ());
-	      return;
-	    }
-	  if (prer == NULL)
-	    rootlist = NULL;
-	  else
-	    prer->next = cr->next;
-	}
+      auto iter = std::find (rootlist.begin (), rootlist.end (), var->root);
+      rootlist.erase (iter);
     }
-
 }
 
 /* Create and install a child of the parent of the given name.
@@ -2406,15 +2363,13 @@ varobj_default_value_is_changeable_p (const struct varobj *var)
 void
 all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
 {
-  struct varobj_root *var_root, *var_root_next;
-
   /* Iterate "safely" - handle if the callee deletes its passed VAROBJ.  */
-
-  for (var_root = rootlist; var_root != NULL; var_root = var_root_next)
+  auto iter = rootlist.begin ();
+  auto end = rootlist.end ();
+  while (iter != end)
     {
-      var_root_next = var_root->next;
-
-      (*func) (var_root->rootvar, data);
+      auto self = iter++;
+      (*func) ((*self)->rootvar, data);
     }
 }
 
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 03/11] Change all_root_varobjs to take a function_view
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
  2020-10-24 21:08 ` [PATCH 01/11] Use htab_t in varobj Tom Tromey
  2020-10-24 21:08 ` [PATCH 02/11] Change varobj.c:rootlist to a std::list Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 04/11] C++-ify varobj iteration Tom Tromey
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes all_root_varobjs to take a function_view.  This
simplifies some of the callers, in particular we can remove a data
type that only existed to be passed through.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.h (all_root_varobjs): Take a function_view.
	* varobj.c (all_root_varobjs): Take a function_view.
	(varobj_invalidate_iter): Remove unused parameter.
	(varobj_invalidate): Update.
	* mi/mi-cmd-var.c (struct mi_cmd_var_update): Remove.
	(mi_cmd_var_update_iter): Change parameters.
---
 gdb/ChangeLog       |  9 +++++++++
 gdb/mi/mi-cmd-var.c | 26 ++++++++------------------
 gdb/varobj.c        | 12 ++++++------
 gdb/varobj.h        |  3 +--
 4 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 65a2ba146dd..5a228ddc24b 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -585,20 +585,12 @@ mi_cmd_var_assign (const char *command, char **argv, int argc)
   uiout->field_string ("value", val.c_str ());
 }
 
-/* Type used for parameters passing to mi_cmd_var_update_iter.  */
-
-struct mi_cmd_var_update
-  {
-    int only_floating;
-    enum print_values print_values;
-  };
-
 /* Helper for mi_cmd_var_update - update each VAR.  */
 
 static void
-mi_cmd_var_update_iter (struct varobj *var, void *data_pointer)
+mi_cmd_var_update_iter (struct varobj *var, bool only_floating,
+			enum print_values print_values)
 {
-  struct mi_cmd_var_update *data = (struct mi_cmd_var_update *) data_pointer;
   bool thread_stopped;
 
   int thread_id = varobj_get_thread_id (var);
@@ -617,8 +609,8 @@ mi_cmd_var_update_iter (struct varobj *var, void *data_pointer)
     }
 
   if (thread_stopped
-      && (!data->only_floating || varobj_floating_p (var)))
-    varobj_update_one (var, data->print_values, false /* implicit */);
+      && (!only_floating || varobj_floating_p (var)))
+    varobj_update_one (var, print_values, false /* implicit */);
 }
 
 void
@@ -656,16 +648,14 @@ mi_cmd_var_update (const char *command, char **argv, int argc)
 
   if ((*name == '*' || *name == '@') && (*(name + 1) == '\0'))
     {
-      struct mi_cmd_var_update data;
-
-      data.only_floating = (*name == '@');
-      data.print_values = print_values;
-
       /* varobj_update_one automatically updates all the children of
 	 VAROBJ.  Therefore update each VAROBJ only once by iterating
 	 only the root VAROBJs.  */
 
-      all_root_varobjs (mi_cmd_var_update_iter, &data);
+      all_root_varobjs ([=] (varobj *var)
+        {
+	  mi_cmd_var_update_iter (var, *name == '0', print_values);
+	});
     }
   else
     {
diff --git a/gdb/varobj.c b/gdb/varobj.c
index ea57a79aa41..ce5c85f163b 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -2357,11 +2357,11 @@ varobj_default_value_is_changeable_p (const struct varobj *var)
   return r;
 }
 
-/* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
-   with an arbitrary caller supplied DATA pointer.  */
+/* Iterate all the existing _root_ VAROBJs and call the FUNC callback
+   for each one.  */
 
 void
-all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
+all_root_varobjs (gdb::function_view<void (struct varobj *var)> func)
 {
   /* Iterate "safely" - handle if the callee deletes its passed VAROBJ.  */
   auto iter = rootlist.begin ();
@@ -2369,7 +2369,7 @@ all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
   while (iter != end)
     {
       auto self = iter++;
-      (*func) ((*self)->rootvar, data);
+      func ((*self)->rootvar);
     }
 }
 
@@ -2381,7 +2381,7 @@ all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
    varobj must be either re-evaluated, or marked as invalid here.  */
 
 static void
-varobj_invalidate_iter (struct varobj *var, void *unused)
+varobj_invalidate_iter (struct varobj *var)
 {
   /* global and floating var must be re-evaluated.  */
   if (var->root->floating || var->root->valid_block == NULL)
@@ -2412,7 +2412,7 @@ varobj_invalidate_iter (struct varobj *var, void *unused)
 void 
 varobj_invalidate (void)
 {
-  all_root_varobjs (varobj_invalidate_iter, NULL);
+  all_root_varobjs (varobj_invalidate_iter);
 }
 
 /* A hash function for a varobj.  */
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 7831e76b973..abf333664af 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -309,8 +309,7 @@ extern std::string varobj_get_value (struct varobj *var);
 
 extern bool varobj_set_value (struct varobj *var, const char *expression);
 
-extern void all_root_varobjs (void (*func) (struct varobj *var, void *data),
-			      void *data);
+extern void all_root_varobjs (gdb::function_view<void (struct varobj *var)>);
 
 extern std::vector<varobj_update_result>
   varobj_update (struct varobj **varp, bool is_explicit);
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 04/11] C++-ify varobj iteration
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (2 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 03/11] Change all_root_varobjs to take a function_view Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 05/11] Change varobj_iter::next to return unique_ptr Tom Tromey
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes the varobj iteration code to use a C++ class rather than
a C struct with a separate "ops" structure.  The only implementation
is updated to use inheritance.  This simplifies the code quite nicely.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (update_dynamic_varobj_children, install_visualizer)
	(varobj::~varobj): Update.
	* varobj-iter.h (struct varobj_iter): Change to interface class.
	(struct varobj_iter_ops): Remove.
	(varobj_iter_next, varobj_iter_delete): Remove.
	* python/py-varobj.c (struct py_varobj_iter): Derive from
	varobj_iter.  Add constructor, destructor.  Rename members.
	(py_varobj_iter::~py_varobj_iter): Rename from
	py_varobj_iter_dtor.
	(py_varobj_iter::next): Rename from py_varobj_iter_next.
	(py_varobj_iter_ops): Remove.
	(py_varobj_iter): Rename from py_varobj_iter_ctor.
	(py_varobj_iter_new): Remove.
	(py_varobj_get_iterator): Update.
---
 gdb/ChangeLog          | 17 +++++++++
 gdb/python/py-varobj.c | 80 +++++++++++++++---------------------------
 gdb/varobj-iter.h      | 41 ++--------------------
 gdb/varobj.c           | 10 +++---
 4 files changed, 54 insertions(+), 94 deletions(-)

diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index 9c791f64df1..df6f9c5a953 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -21,34 +21,43 @@
 /* A dynamic varobj iterator "class" for python pretty-printed
    varobjs.  This inherits struct varobj_iter.  */
 
-struct py_varobj_iter
+struct py_varobj_iter : public varobj_iter
 {
-  /* The 'base class'.  */
-  struct varobj_iter base;
+  py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter);
+  ~py_varobj_iter () override;
+
+  varobj_item *next () override;
+
+private:
+
+  /* The varobj this iterator is listing children for.  */
+  struct varobj *m_var;
+
+  /* The next raw index we will try to check is available.  If it is
+     equal to number_of_children, then we've already iterated the
+     whole set.  */
+  int m_next_raw_index = 0;
 
   /* The python iterator returned by the printer's 'children' method,
      or NULL if not available.  */
-  PyObject *iter;
+  PyObject *m_iter;
 };
 
 /* Implementation of the 'dtor' method of pretty-printed varobj
    iterators.  */
 
-static void
-py_varobj_iter_dtor (struct varobj_iter *self)
+py_varobj_iter::~py_varobj_iter ()
 {
-  struct py_varobj_iter *dis = (struct py_varobj_iter *) self;
-  gdbpy_enter_varobj enter_py (self->var);
-  Py_XDECREF (dis->iter);
+  gdbpy_enter_varobj enter_py (m_var);
+  Py_XDECREF (m_iter);
 }
 
 /* Implementation of the 'next' method of pretty-printed varobj
    iterators.  */
 
-static varobj_item *
-py_varobj_iter_next (struct varobj_iter *self)
+varobj_item *
+py_varobj_iter::next ()
 {
-  struct py_varobj_iter *t = (struct py_varobj_iter *) self;
   PyObject *py_v;
   varobj_item *vitem;
   const char *name = NULL;
@@ -56,9 +65,9 @@ py_varobj_iter_next (struct varobj_iter *self)
   if (!gdb_python_initialized)
     return NULL;
 
-  gdbpy_enter_varobj enter_py (self->var);
+  gdbpy_enter_varobj enter_py (m_var);
 
-  gdbpy_ref<> item (PyIter_Next (t->iter));
+  gdbpy_ref<> item (PyIter_Next (m_iter));
 
   if (item == NULL)
     {
@@ -78,7 +87,7 @@ py_varobj_iter_next (struct varobj_iter *self)
 	    }
 
 	  std::string name_str = string_printf ("<error at %d>",
-						self->next_raw_index++);
+						m_next_raw_index++);
 	  item.reset (Py_BuildValue ("(ss)", name_str.c_str (),
 				     value_str.get ()));
 	  if (item == NULL)
@@ -107,45 +116,18 @@ py_varobj_iter_next (struct varobj_iter *self)
     gdbpy_print_stack ();
   vitem->name = name;
 
-  self->next_raw_index++;
+  m_next_raw_index++;
   return vitem;
 }
 
-/* The 'vtable' of pretty-printed python varobj iterators.  */
-
-static const struct varobj_iter_ops py_varobj_iter_ops =
-{
-  py_varobj_iter_dtor,
-  py_varobj_iter_next
-};
-
 /* Constructor of pretty-printed varobj iterators.  VAR is the varobj
    whose children the iterator will be iterating over.  PYITER is the
    python iterator actually responsible for the iteration.  */
 
-static void
-py_varobj_iter_ctor (struct py_varobj_iter *self,
-		     struct varobj *var, gdbpy_ref<> &&pyiter)
+py_varobj_iter::py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter)
+  : m_var (var),
+    m_iter (pyiter.release ())
 {
-  self->base.var = var;
-  self->base.ops = &py_varobj_iter_ops;
-  self->base.next_raw_index = 0;
-  self->iter = pyiter.release ();
-}
-
-/* Allocate and construct a pretty-printed varobj iterator.  VAR is
-   the varobj whose children the iterator will be iterating over.
-   PYITER is the python iterator actually responsible for the
-   iteration.  */
-
-static struct py_varobj_iter *
-py_varobj_iter_new (struct varobj *var, gdbpy_ref<> &&pyiter)
-{
-  struct py_varobj_iter *self;
-
-  self = XNEW (struct py_varobj_iter);
-  py_varobj_iter_ctor (self, var, std::move (pyiter));
-  return self;
 }
 
 /* Return a new pretty-printed varobj iterator suitable to iterate
@@ -154,8 +136,6 @@ py_varobj_iter_new (struct varobj *var, gdbpy_ref<> &&pyiter)
 struct varobj_iter *
 py_varobj_get_iterator (struct varobj *var, PyObject *printer)
 {
-  struct py_varobj_iter *py_iter;
-
   gdbpy_enter_varobj enter_py (var);
 
   if (!PyObject_HasAttr (printer, gdbpy_children_cst))
@@ -176,7 +156,5 @@ py_varobj_get_iterator (struct varobj *var, PyObject *printer)
       error (_("Could not get children iterator"));
     }
 
-  py_iter = py_varobj_iter_new (var, std::move (iter));
-
-  return &py_iter->base;
+  return new py_varobj_iter (var, std::move (iter));
 }
diff --git a/gdb/varobj-iter.h b/gdb/varobj-iter.h
index 240b686b256..ed654190ca5 100644
--- a/gdb/varobj-iter.h
+++ b/gdb/varobj-iter.h
@@ -28,50 +28,15 @@ struct varobj_item
   struct value *value;
 };
 
-struct varobj_iter_ops;
-
 /* A dynamic varobj iterator "class".  */
 
 struct varobj_iter
 {
-  /* The 'vtable'.  */
-  const struct varobj_iter_ops *ops;
-
-  /* The varobj this iterator is listing children for.  */
-  struct varobj *var;
-
-  /* The next raw index we will try to check is available.  If it is
-     equal to number_of_children, then we've already iterated the
-     whole set.  */
-  int next_raw_index;
-};
-
-/* The vtable of the varobj iterator class.  */
+public:
 
-struct varobj_iter_ops
-{
-  /* Destructor.  Releases everything from SELF (but not SELF
-     itself).  */
-  void (*dtor) (struct varobj_iter *self);
+  virtual ~varobj_iter () = default;
 
-  /* Returns the next object or NULL if it has reached the end.  */
-  varobj_item *(*next) (struct varobj_iter *self);
+  virtual varobj_item *next () = 0;
 };
 
-/* Returns the next varobj or NULL if it has reached the end.  */
-
-#define varobj_iter_next(ITER)	(ITER)->ops->next (ITER)
-
-/* Delete a varobj_iter object.  */
-
-#define varobj_iter_delete(ITER)	       \
-  do					       \
-    {					       \
-      if ((ITER) != NULL)		       \
-	{				       \
-	  (ITER)->ops->dtor (ITER);	       \
-	  xfree (ITER);		       \
-	}				       \
-    } while (0)
-
 #endif /* VAROBJ_ITER_H */
diff --git a/gdb/varobj.c b/gdb/varobj.c
index ce5c85f163b..edcaad417f6 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -702,7 +702,7 @@ update_dynamic_varobj_children (struct varobj *var,
 
   if (update_children || var->dynamic->child_iter == NULL)
     {
-      varobj_iter_delete (var->dynamic->child_iter);
+      delete var->dynamic->child_iter;
       var->dynamic->child_iter = varobj_get_iterator (var);
 
       varobj_clear_saved_item (var->dynamic);
@@ -729,7 +729,7 @@ update_dynamic_varobj_children (struct varobj *var,
 	}
       else
 	{
-	  item = varobj_iter_next (var->dynamic->child_iter);
+	  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)
@@ -739,7 +739,7 @@ update_dynamic_varobj_children (struct varobj *var,
       if (item == NULL)
 	{
 	  /* Iteration is done.  Remove iterator from VAR.  */
-	  varobj_iter_delete (var->dynamic->child_iter);
+	  delete var->dynamic->child_iter;
 	  var->dynamic->child_iter = NULL;
 	  break;
 	}
@@ -1070,7 +1070,7 @@ install_visualizer (struct varobj_dynamic *var, PyObject *constructor,
   Py_XDECREF (var->pretty_printer);
   var->pretty_printer = visualizer;
 
-  varobj_iter_delete (var->child_iter);
+  delete var->child_iter;
   var->child_iter = NULL;
 }
 
@@ -1881,7 +1881,7 @@ varobj::~varobj ()
     }
 #endif
 
-  varobj_iter_delete (var->dynamic->child_iter);
+  delete var->dynamic->child_iter;
   varobj_clear_saved_item (var->dynamic);
 
   if (is_root_p (var))
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 05/11] Change varobj_iter::next to return unique_ptr
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (3 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 04/11] C++-ify varobj iteration Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 06/11] Change varobj_dynamic::saved_item to unique_ptr Tom Tromey
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes varobj_iter::next to return a unique_ptr.  This fits in
with the ongoing theme of trying to express these ownership transfers
via the type system.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (update_dynamic_varobj_children): Update.
	* varobj-iter.h (struct varobj_iter) <next>: Change return type.
	* python/py-varobj.c (struct py_varobj_iter) <next>: Change return
	type.
	(py_varobj_iter::next): Likewise.
---
 gdb/ChangeLog          |  8 ++++++++
 gdb/python/py-varobj.c |  6 +++---
 gdb/varobj-iter.h      |  2 +-
 gdb/varobj.c           | 10 ++++------
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index df6f9c5a953..c3fb2e96a9c 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -26,7 +26,7 @@ struct py_varobj_iter : public varobj_iter
   py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter);
   ~py_varobj_iter () override;
 
-  varobj_item *next () override;
+  std::unique_ptr<varobj_item> next () override;
 
 private:
 
@@ -55,7 +55,7 @@ py_varobj_iter::~py_varobj_iter ()
 /* Implementation of the 'next' method of pretty-printed varobj
    iterators.  */
 
-varobj_item *
+std::unique_ptr<varobj_item>
 py_varobj_iter::next ()
 {
   PyObject *py_v;
@@ -117,7 +117,7 @@ py_varobj_iter::next ()
   vitem->name = name;
 
   m_next_raw_index++;
-  return vitem;
+  return std::unique_ptr<varobj_item> (vitem);
 }
 
 /* Constructor of pretty-printed varobj iterators.  VAR is the varobj
diff --git a/gdb/varobj-iter.h b/gdb/varobj-iter.h
index ed654190ca5..a05f1cbf8f3 100644
--- a/gdb/varobj-iter.h
+++ b/gdb/varobj-iter.h
@@ -36,7 +36,7 @@ struct varobj_iter
 
   virtual ~varobj_iter () = default;
 
-  virtual varobj_item *next () = 0;
+  virtual std::unique_ptr<varobj_item> next () = 0;
 };
 
 #endif /* VAROBJ_ITER_H */
diff --git a/gdb/varobj.c b/gdb/varobj.c
index edcaad417f6..fcfc319008b 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -719,12 +719,12 @@ update_dynamic_varobj_children (struct varobj *var,
      are more children.  */
   for (; to < 0 || i < to + 1; ++i)
     {
-      varobj_item *item;
+      std::unique_ptr<varobj_item> item;
 
       /* See if there was a leftover from last time.  */
       if (var->dynamic->saved_item != NULL)
 	{
-	  item = var->dynamic->saved_item;
+	  item = std::unique_ptr<varobj_item> (var->dynamic->saved_item);
 	  var->dynamic->saved_item = NULL;
 	}
       else
@@ -753,13 +753,11 @@ update_dynamic_varobj_children (struct varobj *var,
 				 can_mention ? newobj : NULL,
 				 can_mention ? unchanged : NULL,
 				 can_mention ? cchanged : NULL, i,
-				 item);
-
-	  delete item;
+				 item.get ());
 	}
       else
 	{
-	  var->dynamic->saved_item = item;
+	  var->dynamic->saved_item = item.release ();
 
 	  /* We want to truncate the child list just before this
 	     element.  */
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 06/11] Change varobj_dynamic::saved_item to unique_ptr
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (4 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 05/11] Change varobj_iter::next to return unique_ptr Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 07/11] Change varobj_dynamic::child_iter " Tom Tromey
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes varobj_dynamic::saved_item to be a unique_ptr.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (struct varobj_dynamic) <saved_item>: Now unique_ptr.
	(varobj_clear_saved_item, update_dynamic_varobj_children):
	Update.
---
 gdb/ChangeLog |  6 ++++++
 gdb/varobj.c  | 12 ++++--------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/gdb/varobj.c b/gdb/varobj.c
index fcfc319008b..21e03eb397a 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -131,7 +131,7 @@ struct varobj_dynamic
      already reported.  However, we don't want to install this value
      when we read it, because that will mess up future updates.  So,
      we stash it here instead.  */
-  varobj_item *saved_item = NULL;
+  std::unique_ptr<varobj_item> saved_item;
 };
 
 /* Private function prototypes */
@@ -680,8 +680,7 @@ varobj_clear_saved_item (struct varobj_dynamic *var)
   if (var->saved_item != NULL)
     {
       value_decref (var->saved_item->value);
-      delete var->saved_item;
-      var->saved_item = NULL;
+      var->saved_item.reset (nullptr);
     }
 }
 
@@ -723,10 +722,7 @@ update_dynamic_varobj_children (struct varobj *var,
 
       /* See if there was a leftover from last time.  */
       if (var->dynamic->saved_item != NULL)
-	{
-	  item = std::unique_ptr<varobj_item> (var->dynamic->saved_item);
-	  var->dynamic->saved_item = NULL;
-	}
+	item = std::move (var->dynamic->saved_item);
       else
 	{
 	  item = var->dynamic->child_iter->next ();
@@ -757,7 +753,7 @@ update_dynamic_varobj_children (struct varobj *var,
 	}
       else
 	{
-	  var->dynamic->saved_item = item.release ();
+	  var->dynamic->saved_item = std::move (item);
 
 	  /* We want to truncate the child list just before this
 	     element.  */
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 07/11] Change varobj_dynamic::child_iter to unique_ptr
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (5 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 06/11] Change varobj_dynamic::saved_item to unique_ptr Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 08/11] Change varobj_item::value to a value_ref_ptr Tom Tromey
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes varobj_dynamic::child_iter to be a unique_ptr, removing
some manual management.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (struct varobj_dynamic) <child_iter>: Now unique_ptr.
	(varobj_get_iterator): Return unique_ptr.
	(update_dynamic_varobj_children, install_visualizer)
	(varobj::~varobj): Update.
	* python/python-internal.h (py_varobj_get_iterator): Return
	unique_ptr.
	* python/py-varobj.c (py_varobj_get_iterator): Return unique_ptr.
---
 gdb/ChangeLog                | 10 ++++++++++
 gdb/python/py-varobj.c       |  5 +++--
 gdb/python/python-internal.h |  4 ++--
 gdb/varobj.c                 | 12 ++++--------
 4 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index c3fb2e96a9c..dfc9e2baf6c 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -133,7 +133,7 @@ py_varobj_iter::py_varobj_iter (struct varobj *var, gdbpy_ref<> &&pyiter)
 /* Return a new pretty-printed varobj iterator suitable to iterate
    over VAR's children.  */
 
-struct varobj_iter *
+std::unique_ptr<varobj_iter>
 py_varobj_get_iterator (struct varobj *var, PyObject *printer)
 {
   gdbpy_enter_varobj enter_py (var);
@@ -156,5 +156,6 @@ py_varobj_get_iterator (struct varobj *var, PyObject *printer)
       error (_("Could not get children iterator"));
     }
 
-  return new py_varobj_iter (var, std::move (iter));
+  return std::unique_ptr<varobj_iter> (new py_varobj_iter (var,
+							   std::move (iter)));
 }
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 36c1ab281f8..77d2779bac1 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -754,8 +754,8 @@ int gdb_pymodule_addobject (PyObject *module, const char *name,
 
 struct varobj_iter;
 struct varobj;
-struct varobj_iter *py_varobj_get_iterator (struct varobj *var,
-					    PyObject *printer);
+std::unique_ptr<varobj_iter> py_varobj_get_iterator (struct varobj *var,
+						     PyObject *printer);
 
 /* Deleter for Py_buffer unique_ptr specialization.  */
 
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 21e03eb397a..9f6d5d651a5 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -124,7 +124,7 @@ struct varobj_dynamic
 
   /* The iterator returned by the printer's 'children' method, or NULL
      if not available.  */
-  struct varobj_iter *child_iter = NULL;
+  std::unique_ptr<varobj_iter> child_iter;
 
   /* We request one extra item from the iterator, so that we can
      report to the caller whether there are more items than we have
@@ -660,7 +660,7 @@ dynamic_varobj_has_child_method (const struct varobj *var)
 /* A factory for creating dynamic varobj's iterators.  Returns an
    iterator object suitable for iterating over VAR's children.  */
 
-static struct varobj_iter *
+static std::unique_ptr<varobj_iter>
 varobj_get_iterator (struct varobj *var)
 {
 #if HAVE_PYTHON
@@ -701,7 +701,6 @@ update_dynamic_varobj_children (struct varobj *var,
 
   if (update_children || var->dynamic->child_iter == NULL)
     {
-      delete var->dynamic->child_iter;
       var->dynamic->child_iter = varobj_get_iterator (var);
 
       varobj_clear_saved_item (var->dynamic);
@@ -735,8 +734,7 @@ update_dynamic_varobj_children (struct varobj *var,
       if (item == NULL)
 	{
 	  /* Iteration is done.  Remove iterator from VAR.  */
-	  delete var->dynamic->child_iter;
-	  var->dynamic->child_iter = NULL;
+	  var->dynamic->child_iter.reset (nullptr);
 	  break;
 	}
       /* We don't want to push the extra child on any report list.  */
@@ -1064,8 +1062,7 @@ install_visualizer (struct varobj_dynamic *var, PyObject *constructor,
   Py_XDECREF (var->pretty_printer);
   var->pretty_printer = visualizer;
 
-  delete var->child_iter;
-  var->child_iter = NULL;
+  var->child_iter.reset (nullptr);
 }
 
 /* Install the default visualizer for VAR.  */
@@ -1875,7 +1872,6 @@ varobj::~varobj ()
     }
 #endif
 
-  delete var->dynamic->child_iter;
   varobj_clear_saved_item (var->dynamic);
 
   if (is_root_p (var))
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 08/11] Change varobj_item::value to a value_ref_ptr
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (6 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 07/11] Change varobj_dynamic::child_iter " Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 09/11] Remove varobj_clear_saved_item Tom Tromey
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes varobj_item::value to be a value_ref_ptr, removing some
manual management.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (install_dynamic_child, varobj_clear_saved_item)
	(update_dynamic_varobj_children, create_child)
	(create_child_with_value): Update.
	* varobj-iter.h (struct varobj_item) <value>: Now a
	value_ref_ptr.
	* python/py-varobj.c (py_varobj_iter::next): Call release_value.
---
 gdb/ChangeLog          |  9 +++++++++
 gdb/python/py-varobj.c |  2 +-
 gdb/varobj-iter.h      |  2 +-
 gdb/varobj.c           | 24 ++++++++----------------
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index dfc9e2baf6c..e550c7bf785 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -111,7 +111,7 @@ py_varobj_iter::next ()
     }
 
   vitem = new varobj_item ();
-  vitem->value = convert_value_from_python (py_v);
+  vitem->value = release_value (convert_value_from_python (py_v));
   if (vitem->value == NULL)
     gdbpy_print_stack ();
   vitem->name = name;
diff --git a/gdb/varobj-iter.h b/gdb/varobj-iter.h
index a05f1cbf8f3..fea14d6c1c6 100644
--- a/gdb/varobj-iter.h
+++ b/gdb/varobj-iter.h
@@ -25,7 +25,7 @@ struct varobj_item
   std::string name;
 
   /* Value of this item.  */
-  struct value *value;
+  value_ref_ptr value;
 };
 
 /* A dynamic varobj iterator "class".  */
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 9f6d5d651a5..ad7a93f5bfa 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -625,14 +625,15 @@ install_dynamic_child (struct varobj *var,
   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);
@@ -678,10 +679,7 @@ 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);
-    }
+    var->saved_item.reset (nullptr);
 }
 
 static bool
@@ -723,13 +721,7 @@ update_dynamic_varobj_children (struct varobj *var,
       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)
 	{
@@ -1804,7 +1796,7 @@ create_child (struct varobj *parent, int index, std::string &name)
   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);
 }
@@ -1835,12 +1827,12 @@ create_child_with_value (struct varobj *parent, int index,
   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;
 }
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 09/11] Remove varobj_clear_saved_item
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (7 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 08/11] Change varobj_item::value to a value_ref_ptr Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 10/11] Use gdbpy_ref in instantiate_pretty_printer Tom Tromey
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

One call to varobj_clear_saved_item is from the varobj destructor.
This is no longer needed, so this patch removes the call; then inlines
the function into the sole remaining caller.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (varobj_clear_saved_item): Remove.
	(update_dynamic_varobj_children): Update.
	(varobj::~varobj): Don't call varobj_clear_saved_item.
---
 gdb/ChangeLog |  6 ++++++
 gdb/varobj.c  | 14 +-------------
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/gdb/varobj.c b/gdb/varobj.c
index ad7a93f5bfa..8b02eb338b4 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -673,15 +673,6 @@ varobj_get_iterator (struct varobj *var)
 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)
-    var->saved_item.reset (nullptr);
-}
-
 static bool
 update_dynamic_varobj_children (struct varobj *var,
 				std::vector<varobj *> *changed,
@@ -700,8 +691,7 @@ update_dynamic_varobj_children (struct varobj *var,
   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;
 
@@ -1864,8 +1854,6 @@ varobj::~varobj ()
     }
 #endif
 
-  varobj_clear_saved_item (var->dynamic);
-
   if (is_root_p (var))
     delete var->root;
 
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 10/11] Use gdbpy_ref in instantiate_pretty_printer
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (8 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 09/11] Remove varobj_clear_saved_item Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-10-24 21:08 ` [PATCH 11/11] install_variable cannot fail Tom Tromey
  2020-12-11 16:46 ` [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes instantiate_pretty_printer to use gdbpy_ref, removing a
call to Py_DECREF.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (instantiate_pretty_printer): Use gdbpy_ref.
---
 gdb/ChangeLog |  4 ++++
 gdb/varobj.c  | 11 +++--------
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/gdb/varobj.c b/gdb/varobj.c
index 8b02eb338b4..be161eb0208 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -459,16 +459,11 @@ varobj_delete (struct varobj *var, bool only_children)
 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
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 11/11] install_variable cannot fail
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (9 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 10/11] Use gdbpy_ref in instantiate_pretty_printer Tom Tromey
@ 2020-10-24 21:08 ` Tom Tromey
  2020-12-11 16:46 ` [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-10-24 21:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

I noticed that install_variable will never return false, so this patch
changes the return type to void.  I couldn't find a spot in history
where it did return false, maybe it's always been like this.

gdb/ChangeLog
2020-10-24  Tom Tromey  <tom@tromey.com>

	* varobj.c (varobj_create): Update.
	(install_variable): Return void.
---
 gdb/ChangeLog |  5 +++++
 gdb/varobj.c  | 12 +++---------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/gdb/varobj.c b/gdb/varobj.c
index be161eb0208..8254f686653 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -142,7 +142,7 @@ static int delete_variable (struct varobj *, bool);
 
 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 *);
 
@@ -390,11 +390,7 @@ varobj_create (const char *objname,
   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 ();
@@ -1733,7 +1729,7 @@ delete_variable_1 (int *delcountp, struct varobj *var, bool only_children_p,
 }
 
 /* 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 ());
@@ -1749,8 +1745,6 @@ install_variable (struct varobj *var)
   /* If root, add varobj to root list.  */
   if (is_root_p (var))
     rootlist.push_front (var->root);
-
-  return true;			/* OK */
 }
 
 /* Uninstall the object VAR.  */
-- 
2.17.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 00/11] Some varobj C++-ification and cleanup
  2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
                   ` (10 preceding siblings ...)
  2020-10-24 21:08 ` [PATCH 11/11] install_variable cannot fail Tom Tromey
@ 2020-12-11 16:46 ` Tom Tromey
  11 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2020-12-11 16:46 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

>>>>> "Tom" == Tom Tromey <tom@tromey.com> writes:

Tom> I was looking at varobj recently and noticed a few relatively simple
Tom> things that could be done to simplify the code and somewhat C++-ify
Tom> it.  This series is the result.

Tom> Tested on x86-64 Fedora 28.

I've rebased this and re-regression tested it.  I am going to check it
in.

Tom

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-12-11 16:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-24 21:08 [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey
2020-10-24 21:08 ` [PATCH 01/11] Use htab_t in varobj Tom Tromey
2020-10-24 21:08 ` [PATCH 02/11] Change varobj.c:rootlist to a std::list Tom Tromey
2020-10-24 21:08 ` [PATCH 03/11] Change all_root_varobjs to take a function_view Tom Tromey
2020-10-24 21:08 ` [PATCH 04/11] C++-ify varobj iteration Tom Tromey
2020-10-24 21:08 ` [PATCH 05/11] Change varobj_iter::next to return unique_ptr Tom Tromey
2020-10-24 21:08 ` [PATCH 06/11] Change varobj_dynamic::saved_item to unique_ptr Tom Tromey
2020-10-24 21:08 ` [PATCH 07/11] Change varobj_dynamic::child_iter " Tom Tromey
2020-10-24 21:08 ` [PATCH 08/11] Change varobj_item::value to a value_ref_ptr Tom Tromey
2020-10-24 21:08 ` [PATCH 09/11] Remove varobj_clear_saved_item Tom Tromey
2020-10-24 21:08 ` [PATCH 10/11] Use gdbpy_ref in instantiate_pretty_printer Tom Tromey
2020-10-24 21:08 ` [PATCH 11/11] install_variable cannot fail Tom Tromey
2020-12-11 16:46 ` [PATCH 00/11] Some varobj C++-ification and cleanup Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).