public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFA v2 0/7] more cleanup removal in Python
@ 2017-02-09 21:25 Tom Tromey
  2017-02-09 21:25 ` [RFA v2 2/7] Turn gdbpy_ref into a template Tom Tromey
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches

This is version 2 of my cleanup removal patch for the Python code.

Version 1 is here:
https://sourceware.org/ml/gdb-patches/2017-01/msg00279.html

I think this version addresses all the review comments; but there are
some other changes from v1:

* As discussed, use gdbpy_ref<> to wrap PyObject*; the old
  "gdbpy_subclass" is now just a different instantiation of gdbpy_ref.
  The initial work for this is done in a new patch (patch #2 in this
  series), for clarity.

* Drop the ui_file_up patch, as this was done in a better way by
  Pedro.

* Add a couple of obvious patches for issues I found while working on
  this again: remove a couple of unused local variables, and fix a
  couple of Python test cases.

* Fix one instance of the "declare gdbpy_ref object before a
  gdbpy_enter object" bug that I found while re-reviewing the patch in
  this series that adds some gdbpy_ref uses.

I built and tested the series locally; but I'm also running it through
the buildbot.

Let me know what you think.

Tom


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

* [RFA v2 4/7] Change one more spot to use gdbpy_ref
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
  2017-02-09 21:25 ` [RFA v2 2/7] Turn gdbpy_ref into a template Tom Tromey
@ 2017-02-09 21:25 ` Tom Tromey
  2017-02-09 21:25 ` [RFA v2 1/7] Remove some ui_out-related cleanups from Python Tom Tromey
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This patch changes one more spot in the Python layer to use gdbpy_ref.

2017-02-09  Tom Tromey  <tom@tromey.com>

	* python/py-prettyprint.c (pretty_print_one_value): Use
	gdbpy_ref.
---
 gdb/ChangeLog               |  5 +++++
 gdb/python/py-prettyprint.c | 15 ++++++++-------
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 446ad24..169c2f7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2017-02-09  Tom Tromey  <tom@tromey.com>
 
+	* python/py-prettyprint.c (pretty_print_one_value): Use
+	gdbpy_ref.
+
+2017-02-09  Tom Tromey  <tom@tromey.com>
+
 	* python/py-cmd.c (cmdpy_destroyer): Use gdbpy_ref.
 	* python/py-breakpoint.c (gdbpy_breakpoint_deleted): Use
 	gdbpy_ref.
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index e0d2110..66929bf 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -190,21 +190,22 @@ find_pretty_printer (PyObject *value)
 static PyObject *
 pretty_print_one_value (PyObject *printer, struct value **out_value)
 {
-  PyObject *result = NULL;
+  gdbpy_ref<> result;
 
   *out_value = NULL;
   TRY
     {
-      result = PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst, NULL);
-      if (result)
+      result.reset (PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst,
+						NULL));
+      if (result != NULL)
 	{
-	  if (! gdbpy_is_string (result) && ! gdbpy_is_lazy_string (result)
+	  if (! gdbpy_is_string (result.get ())
+	      && ! gdbpy_is_lazy_string (result.get ())
 	      && result != Py_None)
 	    {
-	      *out_value = convert_value_from_python (result);
+	      *out_value = convert_value_from_python (result.get ());
 	      if (PyErr_Occurred ())
 		*out_value = NULL;
-	      Py_DECREF (result);
 	      result = NULL;
 	    }
 	}
@@ -214,7 +215,7 @@ pretty_print_one_value (PyObject *printer, struct value **out_value)
     }
   END_CATCH
 
-  return result;
+  return result.release ();
 }
 
 /* Return the display hint for the object printer, PRINTER.  Return
-- 
2.9.3

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

* [RFA v2 6/7] Remove unnecessary local variables
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
                   ` (5 preceding siblings ...)
  2017-02-09 21:25 ` [RFA v2 7/7] Fix Python test to use lowercase command Tom Tromey
@ 2017-02-09 21:25 ` Tom Tromey
  2017-02-10 16:21 ` [RFA v2 0/7] more cleanup removal in Python Simon Marchi
  7 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

I found an unused local variables in a couple of places in the Python
code; this removes them.

2017-02-09  Tom Tromey  <tom@tromey.com>

	* python/py-value.c (valpy_richcompare_throw): Remove unnecessary
	"cleanup" local.
	* python/py-type.c (typy_legacy_template_argument): Remove
	unnecessary "cleanup" local.
---
 gdb/ChangeLog         | 7 +++++++
 gdb/python/py-type.c  | 1 -
 gdb/python/py-value.c | 1 -
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b00c095..6ff2873 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2017-02-09  Tom Tromey  <tom@tromey.com>
 
+	* python/py-value.c (valpy_richcompare_throw): Remove unnecessary
+	"cleanup" local.
+	* python/py-type.c (typy_legacy_template_argument): Remove
+	unnecessary "cleanup" local.
+
+2017-02-09  Tom Tromey  <tom@tromey.com>
+
 	* python/python.c (do_start_initialization): New function, from
 	_initialize_python.
 	(_initialize_python): Call do_start_initialization.
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 9c20582..d3506ca 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -833,7 +833,6 @@ typy_legacy_template_argument (struct type *type, const struct block *block,
   std::unique_ptr<demangle_parse_info> info;
   const char *err;
   struct type *argtype;
-  struct cleanup *cleanup;
 
   if (TYPE_NAME (type) == NULL)
     {
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index b9b012b..eb3d307 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1330,7 +1330,6 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
   int result;
   struct value *value_other;
   struct value *value_self;
-  struct cleanup *cleanup;
 
   scoped_value_mark free_values;
 
-- 
2.9.3

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

* [RFA v2 2/7] Turn gdbpy_ref into a template
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
@ 2017-02-09 21:25 ` Tom Tromey
  2017-02-09 21:25 ` [RFA v2 4/7] Change one more spot to use gdbpy_ref Tom Tromey
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This turns gdbpy_ref into a template class, so that it can be used to
wrap subclasses of PyObject.  The default argument remains PyObject;
and this necessitated renaming uses of "gdbpy_ref" to "gdbpy_ref<>".

2017-02-09  Tom Tromey  <tom@tromey.com>

	* python/py-ref.h (gdbpy_ref_policy): Now a template.
	(gdbpy_ref): Now a template; allow subclasses of PyObject to be
	used.
	* python/py-arch.c, python/py-bpevent.c, python/py-breakpoint.c,
	python/py-cmd.c, python/py-continueevent.c, python/py-event.c,
	python/py-exitedevent.c, python/py-finishbreakpoint.c,
	python/py-framefilter.c, python/py-function.c,
	python/py-inferior.c, python/py-infevents.c,
	python/py-linetable.c, python/py-newobjfileevent.c,
	python/py-param.c, python/py-prettyprint.c, python/py-ref.h,
	python/py-signalevent.c, python/py-stopevent.c,
	python/py-symbol.c, python/py-threadevent.c, python/py-type.c,
	python/py-unwind.c, python/py-utils.c, python/py-value.c,
	python/py-varobj.c, python/py-xmethods.c, python/python.c,
	varobj.c: Change gdbpy_ref to gdbpy_ref<>.
---
 gdb/ChangeLog                    | 18 ++++++++++
 gdb/python/py-arch.c             |  4 +--
 gdb/python/py-bpevent.c          |  2 +-
 gdb/python/py-breakpoint.c       |  4 +--
 gdb/python/py-cmd.c              | 42 ++++++++++++------------
 gdb/python/py-continueevent.c    |  2 +-
 gdb/python/py-event.c            |  5 +--
 gdb/python/py-exitedevent.c      |  8 ++---
 gdb/python/py-finishbreakpoint.c |  4 +--
 gdb/python/py-framefilter.c      | 61 +++++++++++++++++-----------------
 gdb/python/py-function.c         | 14 ++++----
 gdb/python/py-inferior.c         |  6 ++--
 gdb/python/py-infevents.c        | 24 +++++++-------
 gdb/python/py-linetable.c        |  8 ++---
 gdb/python/py-newobjfileevent.c  |  8 ++---
 gdb/python/py-param.c            | 12 +++----
 gdb/python/py-prettyprint.c      | 55 ++++++++++++++++---------------
 gdb/python/py-ref.h              | 13 +++++---
 gdb/python/py-signalevent.c      |  4 +--
 gdb/python/py-stopevent.c        |  4 +--
 gdb/python/py-symbol.c           |  2 +-
 gdb/python/py-threadevent.c      |  2 +-
 gdb/python/py-type.c             | 18 +++++-----
 gdb/python/py-unwind.c           | 10 +++---
 gdb/python/py-utils.c            | 12 +++----
 gdb/python/py-value.c            | 12 +++----
 gdb/python/py-varobj.c           |  6 ++--
 gdb/python/py-xmethods.c         | 71 ++++++++++++++++++++--------------------
 gdb/python/python.c              | 51 +++++++++++++++--------------
 gdb/varobj.c                     | 12 +++----
 30 files changed, 260 insertions(+), 234 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4ec4dd5..43dc3ed 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,23 @@
 2017-02-09  Tom Tromey  <tom@tromey.com>
 
+	* python/py-ref.h (gdbpy_ref_policy): Now a template.
+	(gdbpy_ref): Now a template; allow subclasses of PyObject to be
+	used.
+	* python/py-arch.c, python/py-bpevent.c, python/py-breakpoint.c,
+	python/py-cmd.c, python/py-continueevent.c, python/py-event.c,
+	python/py-exitedevent.c, python/py-finishbreakpoint.c,
+	python/py-framefilter.c, python/py-function.c,
+	python/py-inferior.c, python/py-infevents.c,
+	python/py-linetable.c, python/py-newobjfileevent.c,
+	python/py-param.c, python/py-prettyprint.c, python/py-ref.h,
+	python/py-signalevent.c, python/py-stopevent.c,
+	python/py-symbol.c, python/py-threadevent.c, python/py-type.c,
+	python/py-unwind.c, python/py-utils.c, python/py-value.c,
+	python/py-varobj.c, python/py-xmethods.c, python/python.c,
+	varobj.c: Change gdbpy_ref to gdbpy_ref<>.
+
+2017-02-09  Tom Tromey  <tom@tromey.com>
+
 	* ui-out.h (ui_out_emit_type): New class.
 	(ui_out_emit_tuple, ui_out_emit_list): New typedefs.
 	* python/py-framefilter.c (py_print_single_arg): Use gdb::optional
diff --git a/gdb/python/py-arch.c b/gdb/python/py-arch.c
index 8d0ec33..71d2989 100644
--- a/gdb/python/py-arch.c
+++ b/gdb/python/py-arch.c
@@ -178,7 +178,7 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
         }
     }
 
-  gdbpy_ref result_list (PyList_New (0));
+  gdbpy_ref<> result_list (PyList_New (0));
   if (result_list == NULL)
     return NULL;
 
@@ -193,7 +193,7 @@ archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
        || (end_obj == NULL && count_obj == NULL && pc == start);)
     {
       int insn_len = 0;
-      gdbpy_ref insn_dict (PyDict_New ());
+      gdbpy_ref<> insn_dict (PyDict_New ());
 
       if (insn_dict == NULL)
 	return NULL;
diff --git a/gdb/python/py-bpevent.c b/gdb/python/py-bpevent.c
index c9b53b5..c5a85b6 100644
--- a/gdb/python/py-bpevent.c
+++ b/gdb/python/py-bpevent.c
@@ -30,7 +30,7 @@ extern PyTypeObject breakpoint_event_object_type
 PyObject *
 create_breakpoint_event_object (PyObject *breakpoint_list, PyObject *first_bp)
 {
-  gdbpy_ref breakpoint_event_obj
+  gdbpy_ref<> breakpoint_event_obj
     (create_stop_event_object (&breakpoint_event_object_type));
 
   if (breakpoint_event_obj == NULL)
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index ac64900..507b866 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -758,7 +758,7 @@ gdbpy_breakpoints (PyObject *self, PyObject *args)
   if (bppy_live == 0)
     return PyTuple_New (0);
 
-  gdbpy_ref list (PyList_New (0));
+  gdbpy_ref<> list (PyList_New (0));
   if (list == NULL)
     return NULL;
 
@@ -798,7 +798,7 @@ gdbpy_breakpoint_cond_says_stop (const struct extension_language_defn *extlang,
 
   if (PyObject_HasAttrString (py_bp, stop_func))
     {
-      gdbpy_ref result (PyObject_CallMethod (py_bp, stop_func, NULL));
+      gdbpy_ref<> result (PyObject_CallMethod (py_bp, stop_func, NULL));
 
       stop = 1;
       if (result != NULL)
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index 28c391c..cd2a9bb 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -134,19 +134,19 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
 
   if (! args)
     args = "";
-  gdbpy_ref argobj (PyUnicode_Decode (args, strlen (args), host_charset (),
-				      NULL));
+  gdbpy_ref<> argobj (PyUnicode_Decode (args, strlen (args), host_charset (),
+					NULL));
   if (argobj == NULL)
     {
       gdbpy_print_stack ();
       error (_("Could not convert arguments to Python string."));
     }
 
-  gdbpy_ref ttyobj (from_tty ? Py_True : Py_False);
+  gdbpy_ref<> ttyobj (from_tty ? Py_True : Py_False);
   Py_INCREF (ttyobj.get ());
-  gdbpy_ref result (PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst,
-						argobj.get (), ttyobj.get (),
-						NULL));
+  gdbpy_ref<> result (PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst,
+						  argobj.get (), ttyobj.get (),
+						  NULL));
 
   if (result == NULL)
     {
@@ -241,19 +241,19 @@ cmdpy_completer_helper (struct cmd_list_element *command,
       return NULL;
     }
 
-  gdbpy_ref textobj (PyUnicode_Decode (text, strlen (text), host_charset (),
-				       NULL));
+  gdbpy_ref<> textobj (PyUnicode_Decode (text, strlen (text), host_charset (),
+					 NULL));
   if (textobj == NULL)
     error (_("Could not convert argument to Python string."));
-  gdbpy_ref wordobj (PyUnicode_Decode (word, strlen (word), host_charset (),
-				       NULL));
+  gdbpy_ref<> wordobj (PyUnicode_Decode (word, strlen (word), host_charset (),
+					 NULL));
   if (wordobj == NULL)
     error (_("Could not convert argument to Python string."));
 
-  gdbpy_ref resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj,
-						   complete_cst,
-						   textobj.get (),
-						   wordobj.get (), NULL));
+  gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj,
+						     complete_cst,
+						     textobj.get (),
+						     wordobj.get (), NULL));
   if (resultobj == NULL)
     {
       /* Just swallow errors here.  */
@@ -276,7 +276,7 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
 
   /* Calling our helper to obtain the PyObject of the Python
      function.  */
-  gdbpy_ref resultobj (cmdpy_completer_helper (command, text, word));
+  gdbpy_ref<> resultobj (cmdpy_completer_helper (command, text, word));
 
   /* Check if there was an error.  */
   if (resultobj == NULL)
@@ -317,7 +317,7 @@ cmdpy_completer (struct cmd_list_element *command,
 
   /* Calling our helper to obtain the PyObject of the Python
      function.  */
-  gdbpy_ref resultobj (cmdpy_completer_helper (command, text, word));
+  gdbpy_ref<> resultobj (cmdpy_completer_helper (command, text, word));
 
   /* If the result object of calling the Python function is NULL, it
      means that there was an error.  In this case, just give up and
@@ -342,14 +342,14 @@ cmdpy_completer (struct cmd_list_element *command,
     }
   else
     {
-      gdbpy_ref iter (PyObject_GetIter (resultobj.get ()));
+      gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ()));
 
       if (iter == NULL)
 	return NULL;
 
       while (true)
 	{
-	  gdbpy_ref elt (PyIter_Next (iter.get ()));
+	  gdbpy_ref<> elt (PyIter_Next (iter.get ()));
 	  if (elt == NULL)
 	    break;
 
@@ -569,7 +569,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
     }
   if (PyObject_HasAttr (self, gdbpy_doc_cst))
     {
-      gdbpy_ref ds_obj (PyObject_GetAttr (self, gdbpy_doc_cst));
+      gdbpy_ref<> ds_obj (PyObject_GetAttr (self, gdbpy_doc_cst));
 
       if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
 	{
@@ -756,7 +756,7 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args)
   if (!PyArg_ParseTuple (args, "s", &input))
     return NULL;
 
-  gdbpy_ref py_argv (PyList_New (0));
+  gdbpy_ref<> py_argv (PyList_New (0));
   if (py_argv == NULL)
     return NULL;
 
@@ -771,7 +771,7 @@ gdbpy_string_to_argv (PyObject *self, PyObject *args)
 
       for (i = 0; c_argv[i] != NULL; ++i)
 	{
-	  gdbpy_ref argp (PyString_FromString (c_argv[i]));
+	  gdbpy_ref<> argp (PyString_FromString (c_argv[i]));
 
 	  if (argp == NULL
 	      || PyList_Append (py_argv.get (), argp.get ()) < 0)
diff --git a/gdb/python/py-continueevent.c b/gdb/python/py-continueevent.c
index 84d2352..8be28c2 100644
--- a/gdb/python/py-continueevent.c
+++ b/gdb/python/py-continueevent.c
@@ -40,7 +40,7 @@ emit_continue_event (ptid_t ptid)
   if (evregpy_no_listeners_p (gdb_py_events.cont))
     return 0;
 
-  gdbpy_ref event (create_continue_event_object ());
+  gdbpy_ref<> event (create_continue_event_object ());
   if (event != NULL)
     return evpy_emit_event (event.get (), gdb_py_events.cont);
   return -1;
diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c
index a50da1f..161a5e1 100644
--- a/gdb/python/py-event.c
+++ b/gdb/python/py-event.c
@@ -95,7 +95,7 @@ evpy_emit_event (PyObject *event,
      notifying listeners to avoid skipping callbacks
      in the case of a callback being disconnected during
      a notification.  */
-  gdbpy_ref callback_list_copy (PySequence_List (registry->callbacks));
+  gdbpy_ref<> callback_list_copy (PySequence_List (registry->callbacks));
   if (callback_list_copy == NULL)
     return -1;
 
@@ -106,7 +106,8 @@ evpy_emit_event (PyObject *event,
       if (func == NULL)
 	return -1;
 
-      gdbpy_ref func_result (PyObject_CallFunctionObjArgs (func, event, NULL));
+      gdbpy_ref<> func_result (PyObject_CallFunctionObjArgs (func, event,
+							     NULL));
 
       if (func_result == NULL)
 	{
diff --git a/gdb/python/py-exitedevent.c b/gdb/python/py-exitedevent.c
index 4590077..967fb1b 100644
--- a/gdb/python/py-exitedevent.c
+++ b/gdb/python/py-exitedevent.c
@@ -26,14 +26,14 @@ extern PyTypeObject exited_event_object_type
 static PyObject *
 create_exited_event_object (const LONGEST *exit_code, struct inferior *inf)
 {
-  gdbpy_ref exited_event (create_event_object (&exited_event_object_type));
+  gdbpy_ref<> exited_event (create_event_object (&exited_event_object_type));
 
   if (exited_event == NULL)
     return NULL;
 
   if (exit_code)
     {
-      gdbpy_ref exit_code_obj (PyLong_FromLongLong (*exit_code));
+      gdbpy_ref<> exit_code_obj (PyLong_FromLongLong (*exit_code));
 
       if (exit_code_obj == NULL)
 	return NULL;
@@ -42,7 +42,7 @@ create_exited_event_object (const LONGEST *exit_code, struct inferior *inf)
 	return NULL;
     }
 
-  gdbpy_ref inf_obj (inferior_to_inferior_object (inf));
+  gdbpy_ref<> inf_obj (inferior_to_inferior_object (inf));
   if (inf_obj == NULL || evpy_add_attribute (exited_event.get (),
 					     "inferior",
 					     inf_obj.get ()) < 0)
@@ -60,7 +60,7 @@ emit_exited_event (const LONGEST *exit_code, struct inferior *inf)
   if (evregpy_no_listeners_p (gdb_py_events.exited))
     return 0;
 
-  gdbpy_ref event (create_exited_event_object (exit_code, inf));
+  gdbpy_ref<> event (create_exited_event_object (exit_code, inf));
 
   if (event != NULL)
     return evpy_emit_event (event.get (), gdb_py_events.exited);
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 7f30d86..106fe34 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -338,8 +338,8 @@ bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj)
   if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled
       && PyObject_HasAttrString (py_obj, outofscope_func))
     {
-      gdbpy_ref meth_result (PyObject_CallMethod (py_obj, outofscope_func,
-						  NULL));
+      gdbpy_ref<> meth_result (PyObject_CallMethod (py_obj, outofscope_func,
+						    NULL));
       if (meth_result == NULL)
 	gdbpy_print_stack ();
     }
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index a4a22a0..6db4aab 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -58,7 +58,7 @@ extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr<char> *name,
 	     struct symbol **sym, struct block **sym_block,
 	     const struct language_defn **language)
 {
-  gdbpy_ref result (PyObject_CallMethod (obj, "symbol", NULL));
+  gdbpy_ref<> result (PyObject_CallMethod (obj, "symbol", NULL));
 
   if (result == NULL)
     return EXT_LANG_BT_ERROR;
@@ -129,7 +129,7 @@ extract_value (PyObject *obj, struct value **value)
 {
   if (PyObject_HasAttrString (obj, "value"))
     {
-      gdbpy_ref vresult (PyObject_CallMethod (obj, "value", NULL));
+      gdbpy_ref<> vresult (PyObject_CallMethod (obj, "value", NULL));
 
       if (vresult == NULL)
 	return EXT_LANG_BT_ERROR;
@@ -305,7 +305,7 @@ get_py_iter_from_func (PyObject *filter, char *func)
 {
   if (PyObject_HasAttrString (filter, func))
     {
-      gdbpy_ref result (PyObject_CallMethod (filter, func, NULL));
+      gdbpy_ref<> result (PyObject_CallMethod (filter, func, NULL));
 
       if (result != NULL)
 	{
@@ -508,7 +508,7 @@ enumerate_args (PyObject *iter,
       commas in the argument output is correct.  At the end of the
       loop block collect another item from the iterator, and, if it is
       not null emit a comma.  */
-  gdbpy_ref item (PyIter_Next (iter));
+  gdbpy_ref<> item (PyIter_Next (iter));
   if (item == NULL && PyErr_Occurred ())
     return EXT_LANG_BT_ERROR;
 
@@ -693,7 +693,7 @@ enumerate_locals (PyObject *iter,
       int local_indent = 8 + (8 * indent);
       gdb::optional<ui_out_emit_tuple> tuple;
 
-      gdbpy_ref item (PyIter_Next (iter));
+      gdbpy_ref<> item (PyIter_Next (iter));
       if (item == NULL)
 	break;
 
@@ -806,11 +806,11 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
 		       enum ext_lang_frame_args args_type,
 		       struct frame_info *frame)
 {
-  gdbpy_ref args_iter (get_py_iter_from_func (filter, "frame_args"));
+  gdbpy_ref<> args_iter (get_py_iter_from_func (filter, "frame_args"));
   if (args_iter == NULL)
     return EXT_LANG_BT_ERROR;
 
-  gdbpy_ref locals_iter (get_py_iter_from_func (filter, "frame_locals"));
+  gdbpy_ref<> locals_iter (get_py_iter_from_func (filter, "frame_locals"));
   if (locals_iter == NULL)
     return EXT_LANG_BT_ERROR;
 
@@ -840,7 +840,7 @@ py_print_locals (PyObject *filter,
 		 int indent,
 		 struct frame_info *frame)
 {
-  gdbpy_ref locals_iter (get_py_iter_from_func (filter, "frame_locals"));
+  gdbpy_ref<> locals_iter (get_py_iter_from_func (filter, "frame_locals"));
   if (locals_iter == NULL)
     return EXT_LANG_BT_ERROR;
 
@@ -865,7 +865,7 @@ py_print_args (PyObject *filter,
 	       enum ext_lang_frame_args args_type,
 	       struct frame_info *frame)
 {
-  gdbpy_ref args_iter (get_py_iter_from_func (filter, "frame_args"));
+  gdbpy_ref<> args_iter (get_py_iter_from_func (filter, "frame_args"));
   if (args_iter == NULL)
     return EXT_LANG_BT_ERROR;
 
@@ -943,7 +943,8 @@ py_print_frame (PyObject *filter, int flags,
   /* Get the underlying frame.  This is needed to determine GDB
   architecture, and also, in the cases of frame variables/arguments to
   read them if they returned filter object requires us to do so.  */
-  gdbpy_ref py_inf_frame (PyObject_CallMethod (filter, "inferior_frame", NULL));
+  gdbpy_ref<> py_inf_frame (PyObject_CallMethod (filter, "inferior_frame",
+						 NULL));
   if (py_inf_frame == NULL)
     return EXT_LANG_BT_ERROR;
 
@@ -1000,7 +1001,7 @@ py_print_frame (PyObject *filter, int flags,
 	 address printing.  */
       if (PyObject_HasAttrString (filter, "address"))
 	{
-	  gdbpy_ref paddr (PyObject_CallMethod (filter, "address", NULL));
+	  gdbpy_ref<> paddr (PyObject_CallMethod (filter, "address", NULL));
 
 	  if (paddr == NULL)
 	    return EXT_LANG_BT_ERROR;
@@ -1076,7 +1077,7 @@ py_print_frame (PyObject *filter, int flags,
       /* Print frame function name.  */
       if (PyObject_HasAttrString (filter, "function"))
 	{
-	  gdbpy_ref py_func (PyObject_CallMethod (filter, "function", NULL));
+	  gdbpy_ref<> py_func (PyObject_CallMethod (filter, "function", NULL));
 	  const char *function = NULL;
 
 	  if (py_func == NULL)
@@ -1153,7 +1154,7 @@ py_print_frame (PyObject *filter, int flags,
 
       if (PyObject_HasAttrString (filter, "filename"))
 	{
-	  gdbpy_ref py_fn (PyObject_CallMethod (filter, "filename", NULL));
+	  gdbpy_ref<> py_fn (PyObject_CallMethod (filter, "filename", NULL));
 
 	  if (py_fn == NULL)
 	    return EXT_LANG_BT_ERROR;
@@ -1185,7 +1186,7 @@ py_print_frame (PyObject *filter, int flags,
 
       if (PyObject_HasAttrString (filter, "line"))
 	{
-	  gdbpy_ref py_line (PyObject_CallMethod (filter, "line", NULL));
+	  gdbpy_ref<> py_line (PyObject_CallMethod (filter, "line", NULL));
 	  int line;
 
 	  if (py_line == NULL)
@@ -1239,7 +1240,7 @@ py_print_frame (PyObject *filter, int flags,
 
   {
     /* Finally recursively print elided frames, if any.  */
-    gdbpy_ref elided (get_py_iter_from_func (filter, "elided"));
+    gdbpy_ref<> elided (get_py_iter_from_func (filter, "elided"));
     if (elided == NULL)
       return EXT_LANG_BT_ERROR;
 
@@ -1254,7 +1255,7 @@ py_print_frame (PyObject *filter, int flags,
 
 	while ((item = PyIter_Next (elided.get ())))
 	  {
-	    gdbpy_ref item_ref (item);
+	    gdbpy_ref<> item_ref (item);
 
 	    enum ext_lang_bt_status success = py_print_frame (item, flags,
 							      args_type, out,
@@ -1279,32 +1280,32 @@ static PyObject *
 bootstrap_python_frame_filters (struct frame_info *frame,
 				int frame_low, int frame_high)
 {
-  gdbpy_ref frame_obj (frame_info_to_frame_object (frame));
+  gdbpy_ref<> frame_obj (frame_info_to_frame_object (frame));
   if (frame_obj == NULL)
     return NULL;
 
-  gdbpy_ref module (PyImport_ImportModule ("gdb.frames"));
+  gdbpy_ref<> module (PyImport_ImportModule ("gdb.frames"));
   if (module == NULL)
     return NULL;
 
-  gdbpy_ref sort_func (PyObject_GetAttrString (module.get (),
-					       "execute_frame_filters"));
+  gdbpy_ref<> sort_func (PyObject_GetAttrString (module.get (),
+						 "execute_frame_filters"));
   if (sort_func == NULL)
     return NULL;
 
-  gdbpy_ref py_frame_low (PyInt_FromLong (frame_low));
+  gdbpy_ref<> py_frame_low (PyInt_FromLong (frame_low));
   if (py_frame_low == NULL)
     return NULL;
 
-  gdbpy_ref py_frame_high (PyInt_FromLong (frame_high));
+  gdbpy_ref<> py_frame_high (PyInt_FromLong (frame_high));
   if (py_frame_high == NULL)
     return NULL;
 
-  gdbpy_ref iterable (PyObject_CallFunctionObjArgs (sort_func.get (),
-						    frame_obj.get (),
-						    py_frame_low.get (),
-						    py_frame_high.get (),
-						    NULL));
+  gdbpy_ref<> iterable (PyObject_CallFunctionObjArgs (sort_func.get (),
+						      frame_obj.get (),
+						      py_frame_low.get (),
+						      py_frame_high.get (),
+						      NULL));
   if (iterable == NULL)
     return NULL;
 
@@ -1354,8 +1355,8 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
 
   gdbpy_enter enter_py (gdbarch, current_language);
 
-  gdbpy_ref iterable (bootstrap_python_frame_filters (frame, frame_low,
-						      frame_high));
+  gdbpy_ref<> iterable (bootstrap_python_frame_filters (frame, frame_low,
+							frame_high));
 
   if (iterable == NULL)
     {
@@ -1389,7 +1390,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
 
   while (true)
     {
-      gdbpy_ref item (PyIter_Next (iterable.get ()));
+      gdbpy_ref<> item (PyIter_Next (iterable.get ()));
 
       if (item == NULL)
 	{
diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c
index 6762a6d..0b2a934 100644
--- a/gdb/python/py-function.c
+++ b/gdb/python/py-function.c
@@ -38,14 +38,14 @@ static PyObject *
 convert_values_to_python (int argc, struct value **argv)
 {
   int i;
-  gdbpy_ref result (PyTuple_New (argc));
+  gdbpy_ref<> result (PyTuple_New (argc));
 
   if (result == NULL)
     return NULL;
 
   for (i = 0; i < argc; ++i)
     {
-      gdbpy_ref elt (value_to_value_object (argv[i]));
+      gdbpy_ref<> elt (value_to_value_object (argv[i]));
       if (elt == NULL)
 	return NULL;
       PyTuple_SetItem (result.get (), i, elt.release ());
@@ -63,8 +63,8 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
      be destroyed.  */
   gdbpy_enter enter_py (gdbarch, language);
   struct value *value;
-  gdbpy_ref result;
-  gdbpy_ref args (convert_values_to_python (argc, argv));
+  gdbpy_ref<> result;
+  gdbpy_ref<> args (convert_values_to_python (argc, argv));
 
   /* convert_values_to_python can return NULL on error.  If we
      encounter this, do not call the function, but allow the Python ->
@@ -74,8 +74,8 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
 
   if (args != NULL)
     {
-      gdbpy_ref callable (PyObject_GetAttrString ((PyObject *) cookie,
-						  "invoke"));
+      gdbpy_ref<> callable (PyObject_GetAttrString ((PyObject *) cookie,
+						    "invoke"));
       if (callable == NULL)
 	error (_("No method named 'invoke' in object."));
 
@@ -159,7 +159,7 @@ fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
 
   if (PyObject_HasAttrString (self, "__doc__"))
     {
-      gdbpy_ref ds_obj (PyObject_GetAttrString (self, "__doc__"));
+      gdbpy_ref<> ds_obj (PyObject_GetAttrString (self, "__doc__"));
       if (ds_obj != NULL)
 	{
 	  if (gdbpy_is_string (ds_obj.get ()))
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index b2aaf25..0118caa 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -256,7 +256,7 @@ find_thread_object (ptid_t ptid)
   if (pid == 0)
     return NULL;
 
-  gdbpy_ref inf_obj (find_inferior_object (pid));
+  gdbpy_ref<> inf_obj (find_inferior_object (pid));
   if (inf_obj == NULL)
     return NULL;
 
@@ -405,7 +405,7 @@ static int
 build_inferior_list (struct inferior *inf, void *arg)
 {
   PyObject *list = (PyObject *) arg;
-  gdbpy_ref inferior (inferior_to_inferior_object (inf));
+  gdbpy_ref<> inferior (inferior_to_inferior_object (inf));
 
   if (inferior  == NULL)
     return 0;
@@ -418,7 +418,7 @@ build_inferior_list (struct inferior *inf, void *arg)
 PyObject *
 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
 {
-  gdbpy_ref list (PyList_New (0));
+  gdbpy_ref<> list (PyList_New (0));
   if (list == NULL)
     return NULL;
 
diff --git a/gdb/python/py-infevents.c b/gdb/python/py-infevents.c
index 23bf57b..6e3c8c8 100644
--- a/gdb/python/py-infevents.c
+++ b/gdb/python/py-infevents.c
@@ -37,7 +37,7 @@ static PyObject *
 create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid,
 				   CORE_ADDR addr)
 {
-  gdbpy_ref event;
+  gdbpy_ref<> event;
   int failed;
 
   switch (flag)
@@ -52,14 +52,14 @@ create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid,
       gdb_assert_not_reached ("invalid inferior_call_kind");
     }
 
-  gdbpy_ref ptid_obj (gdbpy_create_ptid_object (ptid));
+  gdbpy_ref<> ptid_obj (gdbpy_create_ptid_object (ptid));
   if (ptid_obj == NULL)
     return NULL;
 
   if (evpy_add_attribute (event.get (), "ptid", ptid_obj.get ()) < 0)
     return NULL;
 
-  gdbpy_ref addr_obj (PyLong_FromLongLong (addr));
+  gdbpy_ref<> addr_obj (PyLong_FromLongLong (addr));
   if (addr_obj == NULL)
     return NULL;
 
@@ -76,18 +76,18 @@ static PyObject *
 create_register_changed_event_object (struct frame_info *frame, 
 				      int regnum)
 {
-  gdbpy_ref event (create_event_object (&register_changed_event_object_type));
+  gdbpy_ref<> event (create_event_object (&register_changed_event_object_type));
   if (event == NULL)
     return NULL;
 
-  gdbpy_ref frame_obj (frame_info_to_frame_object (frame));
+  gdbpy_ref<> frame_obj (frame_info_to_frame_object (frame));
   if (frame_obj == NULL)
     return NULL;
 
   if (evpy_add_attribute (event.get (), "frame", frame_obj.get ()) < 0)
     return NULL;
 
-  gdbpy_ref regnum_obj (PyLong_FromLongLong (regnum));
+  gdbpy_ref<> regnum_obj (PyLong_FromLongLong (regnum));
   if (regnum_obj == NULL)
     return NULL;
 
@@ -103,19 +103,19 @@ create_register_changed_event_object (struct frame_info *frame,
 static PyObject *
 create_memory_changed_event_object (CORE_ADDR addr, ssize_t len)
 {
-  gdbpy_ref event (create_event_object (&memory_changed_event_object_type));
+  gdbpy_ref<> event (create_event_object (&memory_changed_event_object_type));
 
   if (event == NULL)
     return NULL;
 
-  gdbpy_ref addr_obj (PyLong_FromLongLong (addr));
+  gdbpy_ref<> addr_obj (PyLong_FromLongLong (addr));
   if (addr_obj == NULL)
     return NULL;
 
   if (evpy_add_attribute (event.get (), "address", addr_obj.get ()) < 0)
     return NULL;
 
-  gdbpy_ref len_obj (PyLong_FromLong (len));
+  gdbpy_ref<> len_obj (PyLong_FromLong (len));
   if (len_obj == NULL)
     return NULL;
 
@@ -137,7 +137,7 @@ emit_inferior_call_event (inferior_call_kind flag, ptid_t thread,
   if (evregpy_no_listeners_p (gdb_py_events.inferior_call))
     return 0;
 
-  gdbpy_ref event (create_inferior_call_event_object (flag, thread, addr));
+  gdbpy_ref<> event (create_inferior_call_event_object (flag, thread, addr));
   if (event != NULL)
     return evpy_emit_event (event.get (), gdb_py_events.inferior_call);
   return -1;
@@ -152,7 +152,7 @@ emit_memory_changed_event (CORE_ADDR addr, ssize_t len)
   if (evregpy_no_listeners_p (gdb_py_events.memory_changed))
     return 0;
 
-  gdbpy_ref event (create_memory_changed_event_object (addr, len));
+  gdbpy_ref<> event (create_memory_changed_event_object (addr, len));
   if (event != NULL)
     return evpy_emit_event (event.get (), gdb_py_events.memory_changed);
   return -1;
@@ -167,7 +167,7 @@ emit_register_changed_event (struct frame_info* frame, int regnum)
   if (evregpy_no_listeners_p (gdb_py_events.register_changed))
     return 0;
 
-  gdbpy_ref event (create_register_changed_event_object (frame, regnum));
+  gdbpy_ref<> event (create_register_changed_event_object (frame, regnum));
   if (event != NULL)
     return evpy_emit_event (event.get (), gdb_py_events.register_changed);
   return -1;
diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c
index 1f73ff7..d8597e4 100644
--- a/gdb/python/py-linetable.c
+++ b/gdb/python/py-linetable.c
@@ -132,14 +132,14 @@ build_line_table_tuple_from_pcs (int line, VEC (CORE_ADDR) *vec)
   if (vec_len < 1)
     Py_RETURN_NONE;
 
-  gdbpy_ref tuple (PyTuple_New (vec_len));
+  gdbpy_ref<> tuple (PyTuple_New (vec_len));
 
   if (tuple == NULL)
     return NULL;
 
   for (i = 0; VEC_iterate (CORE_ADDR, vec, i, pc); ++i)
     {
-      gdbpy_ref obj (build_linetable_entry (line, pc));
+      gdbpy_ref<> obj (build_linetable_entry (line, pc));
 
       if (obj == NULL)
 	return NULL;
@@ -238,7 +238,7 @@ ltpy_get_all_source_lines (PyObject *self, PyObject *args)
       return NULL;
     }
 
-  gdbpy_ref source_dict (PyDict_New ());
+  gdbpy_ref<> source_dict (PyDict_New ());
   if (source_dict == NULL)
     return NULL;
 
@@ -250,7 +250,7 @@ ltpy_get_all_source_lines (PyObject *self, PyObject *args)
 	 include in the source set. */
       if (item->line > 0)
 	{
-	  gdbpy_ref line (gdb_py_object_from_longest (item->line));
+	  gdbpy_ref<> line (gdb_py_object_from_longest (item->line));
 
 	  if (line == NULL)
 	    return NULL;
diff --git a/gdb/python/py-newobjfileevent.c b/gdb/python/py-newobjfileevent.c
index b8f9774..dc09e0f 100644
--- a/gdb/python/py-newobjfileevent.c
+++ b/gdb/python/py-newobjfileevent.c
@@ -30,7 +30,7 @@ create_new_objfile_event_object (struct objfile *objfile)
 {
   PyObject *py_objfile;
 
-  gdbpy_ref objfile_event
+  gdbpy_ref<> objfile_event
     (create_event_object (&new_objfile_event_object_type));
   if (objfile_event == NULL)
     return NULL;
@@ -56,7 +56,7 @@ emit_new_objfile_event (struct objfile *objfile)
   if (evregpy_no_listeners_p (gdb_py_events.new_objfile))
     return 0;
 
-  gdbpy_ref event (create_new_objfile_event_object (objfile));
+  gdbpy_ref<> event (create_new_objfile_event_object (objfile));
   if (event != NULL)
     return evpy_emit_event (event.get (), gdb_py_events.new_objfile);
   return -1;
@@ -75,7 +75,7 @@ create_clear_objfiles_event_object (void)
 {
   PyObject *py_progspace;
 
-  gdbpy_ref objfile_event
+  gdbpy_ref<> objfile_event
     (create_event_object (&clear_objfiles_event_object_type));
   if (objfile_event == NULL)
     return NULL;
@@ -102,7 +102,7 @@ emit_clear_objfiles_event (void)
   if (evregpy_no_listeners_p (gdb_py_events.clear_objfiles))
     return 0;
 
-  gdbpy_ref event (create_clear_objfiles_event_object ());
+  gdbpy_ref<> event (create_clear_objfiles_event_object ());
   if (event != NULL)
     return evpy_emit_event (event.get (), gdb_py_events.clear_objfiles);
   return -1;
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
index c285bb5..d80b731 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -307,7 +307,7 @@ get_doc_string (PyObject *object, PyObject *attr)
 
   if (PyObject_HasAttr (object, attr))
     {
-      gdbpy_ref ds_obj (PyObject_GetAttr (object, attr));
+      gdbpy_ref<> ds_obj (PyObject_GetAttr (object, attr));
 
       if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
 	{
@@ -329,7 +329,7 @@ static gdb::unique_xmalloc_ptr<char>
 call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
 {
   gdb::unique_xmalloc_ptr<char> data;
-  gdbpy_ref result (PyObject_CallMethodObjArgs (obj, method, arg, NULL));
+  gdbpy_ref<> result (PyObject_CallMethodObjArgs (obj, method, arg, NULL));
 
   if (result == NULL)
     return NULL;
@@ -364,7 +364,7 @@ get_set_value (char *args, int from_tty,
   gdb::unique_xmalloc_ptr<char> set_doc_string;
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
-  gdbpy_ref set_doc_func (PyString_FromString ("get_set_string"));
+  gdbpy_ref<> set_doc_func (PyString_FromString ("get_set_string"));
 
   if (set_doc_func == NULL)
     {
@@ -407,7 +407,7 @@ get_show_value (struct ui_file *file, int from_tty,
   gdb::unique_xmalloc_ptr<char> show_doc_string;
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
-  gdbpy_ref show_doc_func (PyString_FromString ("get_show_string"));
+  gdbpy_ref<> show_doc_func (PyString_FromString ("get_show_string"));
 
   if (show_doc_func == NULL)
     {
@@ -417,7 +417,7 @@ get_show_value (struct ui_file *file, int from_tty,
 
   if (PyObject_HasAttr (obj, show_doc_func.get ()))
     {
-      gdbpy_ref val_obj (PyString_FromString (value));
+      gdbpy_ref<> val_obj (PyString_FromString (value));
 
       if (val_obj == NULL)
 	{
@@ -586,7 +586,7 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values)
 
   for (i = 0; i < size; ++i)
     {
-      gdbpy_ref item (PySequence_GetItem (enum_values, i));
+      gdbpy_ref<> item (PySequence_GetItem (enum_values, i));
 
       if (item == NULL)
 	{
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index d6d157a..e0d2110 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -60,7 +60,7 @@ search_pp_list (PyObject *list, PyObject *value)
       /* Skip if disabled.  */
       if (PyObject_HasAttr (function, gdbpy_enabled_cst))
 	{
-	  gdbpy_ref attr (PyObject_GetAttr (function, gdbpy_enabled_cst));
+	  gdbpy_ref<> attr (PyObject_GetAttr (function, gdbpy_enabled_cst));
 	  int cmp;
 
 	  if (attr == NULL)
@@ -73,7 +73,8 @@ search_pp_list (PyObject *list, PyObject *value)
 	    continue;
 	}
 
-      gdbpy_ref printer (PyObject_CallFunctionObjArgs (function, value, NULL));
+      gdbpy_ref<> printer (PyObject_CallFunctionObjArgs (function, value,
+							 NULL));
       if (printer == NULL)
 	return NULL;
       else if (printer != Py_None)
@@ -104,8 +105,8 @@ find_pretty_printer_from_objfiles (PyObject *value)
 	continue;
       }
 
-    gdbpy_ref pp_list (objfpy_get_printers (objf, NULL));
-    gdbpy_ref function (search_pp_list (pp_list.get (), value));
+    gdbpy_ref<> pp_list (objfpy_get_printers (objf, NULL));
+    gdbpy_ref<> function (search_pp_list (pp_list.get (), value));
 
     /* If there is an error in any objfile list, abort the search and exit.  */
     if (function == NULL)
@@ -131,7 +132,7 @@ find_pretty_printer_from_progspace (PyObject *value)
 
   if (!obj)
     return NULL;
-  gdbpy_ref pp_list (pspy_get_printers (obj, NULL));
+  gdbpy_ref<> pp_list (pspy_get_printers (obj, NULL));
   return search_pp_list (pp_list.get (), value);
 }
 
@@ -148,8 +149,8 @@ find_pretty_printer_from_gdb (PyObject *value)
   if (gdb_python_module == NULL
       || ! PyObject_HasAttrString (gdb_python_module, "pretty_printers"))
     Py_RETURN_NONE;
-  gdbpy_ref pp_list (PyObject_GetAttrString (gdb_python_module,
-					     "pretty_printers"));
+  gdbpy_ref<> pp_list (PyObject_GetAttrString (gdb_python_module,
+					       "pretty_printers"));
   if (pp_list == NULL || ! PyList_Check (pp_list.get ()))
     Py_RETURN_NONE;
 
@@ -165,7 +166,7 @@ find_pretty_printer (PyObject *value)
 {
   /* Look at the pretty-printer list for each objfile
      in the current program-space.  */
-  gdbpy_ref function (find_pretty_printer_from_objfiles (value));
+  gdbpy_ref<> function (find_pretty_printer_from_objfiles (value));
   if (function == NULL || function != Py_None)
     return function.release ();
 
@@ -228,8 +229,8 @@ gdbpy_get_display_hint (PyObject *printer)
   if (! PyObject_HasAttr (printer, gdbpy_display_hint_cst))
     return NULL;
 
-  gdbpy_ref hint (PyObject_CallMethodObjArgs (printer, gdbpy_display_hint_cst,
-					      NULL));
+  gdbpy_ref<> hint (PyObject_CallMethodObjArgs (printer, gdbpy_display_hint_cst,
+						NULL));
   if (hint != NULL)
     {
       if (gdbpy_is_string (hint.get ()))
@@ -256,9 +257,9 @@ print_stack_unless_memory_error (struct ui_file *stream)
 
       PyErr_Fetch (&type, &value, &trace);
 
-      gdbpy_ref type_ref (type);
-      gdbpy_ref value_ref (value);
-      gdbpy_ref trace_ref (trace);
+      gdbpy_ref<> type_ref (type);
+      gdbpy_ref<> value_ref (value);
+      gdbpy_ref<> trace_ref (trace);
 
       gdb::unique_xmalloc_ptr<char>
 	msg (gdbpy_exception_to_string (type, value));
@@ -286,7 +287,7 @@ print_string_repr (PyObject *printer, const char *hint,
   struct value *replacement = NULL;
   enum string_repr_result result = string_repr_ok;
 
-  gdbpy_ref py_str (pretty_print_one_value (printer, &replacement));
+  gdbpy_ref<> py_str (pretty_print_one_value (printer, &replacement));
   if (py_str != NULL)
     {
       if (py_str == Py_None)
@@ -308,7 +309,7 @@ print_string_repr (PyObject *printer, const char *hint,
 	}
       else
 	{
-	  gdbpy_ref string
+	  gdbpy_ref<> string
 	    (python_string_to_target_python_string (py_str.get ()));
 	  if (string != NULL)
 	    {
@@ -379,7 +380,7 @@ class dummy_python_frame
 
   bool m_valid;
   PyFrameObject *m_saved_frame;
-  gdbpy_ref m_frame;
+  gdbpy_ref<> m_frame;
   PyThreadState *m_tstate;
 };
 
@@ -391,11 +392,11 @@ dummy_python_frame::dummy_python_frame ()
   PyCodeObject *code;
   PyFrameObject *frame;
 
-  gdbpy_ref empty_string (PyString_FromString (""));
+  gdbpy_ref<> empty_string (PyString_FromString (""));
   if (empty_string == NULL)
     return;
 
-  gdbpy_ref null_tuple (PyTuple_New (0));
+  gdbpy_ref<> null_tuple (PyTuple_New (0));
   if (null_tuple == NULL)
     return;
 
@@ -418,9 +419,9 @@ dummy_python_frame::dummy_python_frame ()
 		     );
   if (code == NULL)
     return;
-  gdbpy_ref code_holder ((PyObject *) code);
+  gdbpy_ref<> code_holder ((PyObject *) code);
 
-  gdbpy_ref globals (PyDict_New ());
+  gdbpy_ref<> globals (PyDict_New ());
   if (globals == NULL)
     return;
 
@@ -457,15 +458,15 @@ print_children (PyObject *printer, const char *hint,
   is_map = hint && ! strcmp (hint, "map");
   is_array = hint && ! strcmp (hint, "array");
 
-  gdbpy_ref children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
-						  NULL));
+  gdbpy_ref<> children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+						    NULL));
   if (children == NULL)
     {
       print_stack_unless_memory_error (stream);
       return;
     }
 
-  gdbpy_ref iter (PyObject_GetIter (children.get ()));
+  gdbpy_ref<> iter (PyObject_GetIter (children.get ()));
   if (iter == NULL)
     {
       print_stack_unless_memory_error (stream);
@@ -502,7 +503,7 @@ print_children (PyObject *printer, const char *hint,
       PyObject *py_v;
       const char *name;
 
-      gdbpy_ref item (PyIter_Next (iter.get ()));
+      gdbpy_ref<> item (PyIter_Next (iter.get ()));
       if (item == NULL)
 	{
 	  if (PyErr_Occurred ())
@@ -674,7 +675,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
   /* Instantiate the printer.  */
   value = value_from_component (val, type, embedded_offset);
 
-  gdbpy_ref val_obj (value_to_value_object (value));
+  gdbpy_ref<> val_obj (value_to_value_object (value));
   if (val_obj == NULL)
     {
       print_stack_unless_memory_error (stream);
@@ -682,7 +683,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang,
     }
 
   /* Find the constructor.  */
-  gdbpy_ref printer (find_pretty_printer (val_obj.get ()));
+  gdbpy_ref<> printer (find_pretty_printer (val_obj.get ()));
   if (printer == NULL)
     {
       print_stack_unless_memory_error (stream);
@@ -750,7 +751,7 @@ gdbpy_get_varobj_pretty_printer (struct value *value)
     }
   END_CATCH
 
-  gdbpy_ref val_obj (value_to_value_object (value));
+  gdbpy_ref<> val_obj (value_to_value_object (value));
   if (val_obj == NULL)
     return NULL;
 
diff --git a/gdb/python/py-ref.h b/gdb/python/py-ref.h
index b2479bf..8568e5c 100644
--- a/gdb/python/py-ref.h
+++ b/gdb/python/py-ref.h
@@ -1,6 +1,6 @@
 /* Python reference-holding class
 
-   Copyright (C) 2016 Free Software Foundation, Inc.
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -23,20 +23,23 @@
 #include "common/gdb_ref_ptr.h"
 
 /* A policy class for gdb::ref_ptr for Python reference counting.  */
+template<typename T>
 struct gdbpy_ref_policy
 {
-  static void incref (PyObject *ptr)
+  static void incref (T *ptr)
   {
     Py_INCREF (ptr);
   }
 
-  static void decref (PyObject *ptr)
+  static void decref (T *ptr)
   {
     Py_DECREF (ptr);
   }
 };
 
-/* A gdb::ref_ptr that has been specialized for Python objects.  */
-typedef gdb::ref_ptr<PyObject, gdbpy_ref_policy> gdbpy_ref;
+/* A gdb::ref_ptr that has been specialized for Python objects or
+   their "subclasses".  */
+template<typename T = PyObject> using gdbpy_ref
+  = gdb::ref_ptr<T, gdbpy_ref_policy<T>>;
 
 #endif /* GDB_PYTHON_REF_H */
diff --git a/gdb/python/py-signalevent.c b/gdb/python/py-signalevent.c
index e4e9768..a8f41c2 100644
--- a/gdb/python/py-signalevent.c
+++ b/gdb/python/py-signalevent.c
@@ -27,7 +27,7 @@ PyObject *
 create_signal_event_object (enum gdb_signal stop_signal)
 {
   const char *signal_name;
-  gdbpy_ref signal_event_obj
+  gdbpy_ref<> signal_event_obj
     (create_stop_event_object (&signal_event_object_type));
 
   if (signal_event_obj == NULL)
@@ -35,7 +35,7 @@ create_signal_event_object (enum gdb_signal stop_signal)
 
   signal_name = gdb_signal_to_name (stop_signal);
 
-  gdbpy_ref signal_name_obj (PyString_FromString (signal_name));
+  gdbpy_ref<> signal_name_obj (PyString_FromString (signal_name));
   if (signal_name_obj == NULL)
     return NULL;
   if (evpy_add_attribute (signal_event_obj.get (),
diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c
index b87ebda..cfa4591 100644
--- a/gdb/python/py-stopevent.c
+++ b/gdb/python/py-stopevent.c
@@ -36,8 +36,8 @@ create_stop_event_object (PyTypeObject *py_type)
 int
 emit_stop_event (struct bpstats *bs, enum gdb_signal stop_signal)
 {
-  gdbpy_ref stop_event_obj;
-  gdbpy_ref list;
+  gdbpy_ref<> stop_event_obj;
+  gdbpy_ref<> list;
   PyObject *first_bp = NULL;
   struct bpstats *current_bs;
 
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 34e953f..b71cfb4 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -411,7 +411,7 @@ gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
     }
   END_CATCH
 
-  gdbpy_ref ret_tuple (PyTuple_New (2));
+  gdbpy_ref<> ret_tuple (PyTuple_New (2));
   if (ret_tuple == NULL)
     return NULL;
 
diff --git a/gdb/python/py-threadevent.c b/gdb/python/py-threadevent.c
index bba974b..9217444 100644
--- a/gdb/python/py-threadevent.c
+++ b/gdb/python/py-threadevent.c
@@ -52,7 +52,7 @@ create_thread_event_object (PyTypeObject *py_type)
 {
   PyObject *thread = NULL;
 
-  gdbpy_ref thread_event_obj (create_event_object (py_type));
+  gdbpy_ref<> thread_event_obj (create_event_object (py_type));
   if (thread_event_obj == NULL)
     return NULL;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index f6e8dd6..857c4e2 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -169,12 +169,12 @@ typy_get_code (PyObject *self, void *closure)
 static PyObject *
 convert_field (struct type *type, int field)
 {
-  gdbpy_ref result (field_new ());
+  gdbpy_ref<> result (field_new ());
 
   if (result == NULL)
     return NULL;
 
-  gdbpy_ref arg (type_to_type_object (type));
+  gdbpy_ref<> arg (type_to_type_object (type));
   if (arg == NULL)
     return NULL;
   if (PyObject_SetAttrString (result.get (), "parent_type", arg.get ()) < 0)
@@ -292,13 +292,13 @@ make_fielditem (struct type *type, int i, enum gdbpy_iter_kind kind)
     {
     case iter_items:
       {
-	gdbpy_ref key (field_name (type, i));
+	gdbpy_ref<> key (field_name (type, i));
 	if (key == NULL)
 	  return NULL;
-	gdbpy_ref value (convert_field (type, i));
+	gdbpy_ref<> value (convert_field (type, i));
 	if (value == NULL)
 	  return NULL;
-	gdbpy_ref item (PyTuple_New (2));
+	gdbpy_ref<> item (PyTuple_New (2));
 	if (item == NULL)
 	  return NULL;
 	PyTuple_SET_ITEM (item.get (), 0, key.release ());
@@ -376,7 +376,7 @@ typy_fields (PyObject *self, PyObject *args)
   /* Array type.  Handle this as a special case because the common
      machinery wants struct or union or enum types.  Build a list of
      one entry which is the range for the array.  */
-  gdbpy_ref r (convert_field (type, 0));
+  gdbpy_ref<> r (convert_field (type, 0));
   if (r == NULL)
     return NULL;
 
@@ -602,15 +602,15 @@ typy_range (PyObject *self, PyObject *args)
       break;
     }
 
-  gdbpy_ref low_bound (PyLong_FromLong (low));
+  gdbpy_ref<> low_bound (PyLong_FromLong (low));
   if (low_bound == NULL)
     return NULL;
 
-  gdbpy_ref high_bound (PyLong_FromLong (high));
+  gdbpy_ref<> high_bound (PyLong_FromLong (high));
   if (high_bound == NULL)
     return NULL;
 
-  gdbpy_ref result (PyTuple_New (2));
+  gdbpy_ref<> result (PyTuple_New (2));
   if (result == NULL)
     return NULL;
 
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index d1b63ad..b7821b5 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -177,7 +177,7 @@ pyuw_object_attribute_to_pointer (PyObject *pyo, const char *attr_name,
 
   if (PyObject_HasAttrString (pyo, attr_name))
     {
-      gdbpy_ref pyo_value (PyObject_GetAttrString (pyo, attr_name));
+      gdbpy_ref<> pyo_value (PyObject_GetAttrString (pyo, attr_name));
 
       if (pyo_value != NULL && pyo_value != Py_None)
         {
@@ -515,7 +515,7 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
   /* Create PendingFrame instance to pass to sniffers.  */
   pending_frame_object *pfo = PyObject_New (pending_frame_object,
 					    &pending_frame_object_type);
-  gdbpy_ref pyo_pending_frame ((PyObject *) pfo);
+  gdbpy_ref<> pyo_pending_frame ((PyObject *) pfo);
   if (pyo_pending_frame == NULL)
     {
       gdbpy_print_stack ();
@@ -535,15 +535,15 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
       gdbpy_print_stack ();
       return 0;
     }
-  gdbpy_ref pyo_execute (PyObject_GetAttrString (gdb_python_module,
-						 "execute_unwinders"));
+  gdbpy_ref<> pyo_execute (PyObject_GetAttrString (gdb_python_module,
+						   "execute_unwinders"));
   if (pyo_execute == NULL)
     {
       gdbpy_print_stack ();
       return 0;
     }
 
-  gdbpy_ref pyo_unwind_info
+  gdbpy_ref<> pyo_unwind_info
     (PyObject_CallFunctionObjArgs (pyo_execute.get (),
 				   pyo_pending_frame.get (), NULL));
   if (pyo_unwind_info == NULL)
diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c
index e26de41..890220a 100644
--- a/gdb/python/py-utils.c
+++ b/gdb/python/py-utils.c
@@ -71,7 +71,7 @@ unicode_to_encoded_string (PyObject *unicode_str, const char *charset)
   gdb::unique_xmalloc_ptr<char> result;
 
   /* Translate string to named charset.  */
-  gdbpy_ref string (PyUnicode_AsEncodedString (unicode_str, charset, NULL));
+  gdbpy_ref<> string (PyUnicode_AsEncodedString (unicode_str, charset, NULL));
   if (string == NULL)
     return NULL;
 
@@ -123,7 +123,7 @@ unicode_to_target_python_string (PyObject *unicode_str)
 gdb::unique_xmalloc_ptr<char>
 python_string_to_target_string (PyObject *obj)
 {
-  gdbpy_ref str (python_string_to_unicode (obj));
+  gdbpy_ref<> str (python_string_to_unicode (obj));
   if (str == NULL)
     return NULL;
 
@@ -138,7 +138,7 @@ python_string_to_target_string (PyObject *obj)
 PyObject *
 python_string_to_target_python_string (PyObject *obj)
 {
-  gdbpy_ref str (python_string_to_unicode (obj));
+  gdbpy_ref<> str (python_string_to_unicode (obj));
   if (str == NULL)
     return NULL;
 
@@ -151,7 +151,7 @@ python_string_to_target_python_string (PyObject *obj)
 gdb::unique_xmalloc_ptr<char>
 python_string_to_host_string (PyObject *obj)
 {
-  gdbpy_ref str (python_string_to_unicode (obj));
+  gdbpy_ref<> str (python_string_to_unicode (obj));
   if (str == NULL)
     return NULL;
 
@@ -185,7 +185,7 @@ gdbpy_is_string (PyObject *obj)
 gdb::unique_xmalloc_ptr<char>
 gdbpy_obj_to_string (PyObject *obj)
 {
-  gdbpy_ref str_obj (PyObject_Str (obj));
+  gdbpy_ref<> str_obj (PyObject_Str (obj));
 
   if (str_obj != NULL)
     {
@@ -269,7 +269,7 @@ get_addr_from_python (PyObject *obj, CORE_ADDR *addr)
     }
   else
     {
-      gdbpy_ref num (PyNumber_Long (obj));
+      gdbpy_ref<> num (PyNumber_Long (obj));
       gdb_py_ulongest val;
 
       if (num == NULL)
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 8e4d06d..b9b012b 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -566,7 +566,7 @@ value_has_field (struct value *v, PyObject *field)
 {
   struct type *parent_type, *val_type;
   enum type_code type_code;
-  gdbpy_ref type_object (PyObject_GetAttrString (field, "parent_type"));
+  gdbpy_ref<> type_object (PyObject_GetAttrString (field, "parent_type"));
   int has_field = 0;
 
   if (type_object == NULL)
@@ -612,7 +612,7 @@ value_has_field (struct value *v, PyObject *field)
 static int
 get_field_flag (PyObject *field, const char *flag_name)
 {
-  gdbpy_ref flag_object (PyObject_GetAttrString (field, flag_name));
+  gdbpy_ref<> flag_object (PyObject_GetAttrString (field, flag_name));
 
   if (flag_object == NULL)
     return -1;
@@ -626,7 +626,7 @@ get_field_flag (PyObject *field, const char *flag_name)
 static struct type *
 get_field_type (PyObject *field)
 {
-  gdbpy_ref ftype_obj (PyObject_GetAttrString (field, "type"));
+  gdbpy_ref<> ftype_obj (PyObject_GetAttrString (field, "type"));
   struct type *ftype;
 
   if (ftype_obj == NULL)
@@ -687,7 +687,7 @@ valpy_getitem (PyObject *self, PyObject *key)
 	}
       else
 	{
-	  gdbpy_ref name_obj (PyObject_GetAttrString (key, "name"));
+	  gdbpy_ref<> name_obj (PyObject_GetAttrString (key, "name"));
 
 	  if (name_obj == NULL)
 	    return NULL;
@@ -708,7 +708,7 @@ valpy_getitem (PyObject *self, PyObject *key)
 
 		  return NULL;
 		}
-	      gdbpy_ref bitpos_obj (PyObject_GetAttrString (key, "bitpos"));
+	      gdbpy_ref<> bitpos_obj (PyObject_GetAttrString (key, "bitpos"));
 	      if (bitpos_obj == NULL)
 		return NULL;
 	      if (!gdb_py_int_as_long (bitpos_obj.get (), &bitpos))
@@ -1576,7 +1576,7 @@ convert_value_from_python (PyObject *obj)
 		  PyObject *etype, *evalue, *etraceback;
 
 		  PyErr_Fetch (&etype, &evalue, &etraceback);
-		  gdbpy_ref zero (PyInt_FromLong (0));
+		  gdbpy_ref<> zero (PyInt_FromLong (0));
 
 		  /* Check whether obj is positive.  */
 		  if (PyObject_RichCompareBool (obj, zero.get (), Py_GT) > 0)
diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index bac226f..e858556 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -59,7 +59,7 @@ py_varobj_iter_next (struct varobj_iter *self)
 
   gdbpy_enter_varobj enter_py (self->var);
 
-  gdbpy_ref item (PyIter_Next (t->iter));
+  gdbpy_ref<> item (PyIter_Next (t->iter));
 
   if (item == NULL)
     {
@@ -170,8 +170,8 @@ py_varobj_get_iterator (struct varobj *var, PyObject *printer)
   if (!PyObject_HasAttr (printer, gdbpy_children_cst))
     return NULL;
 
-  gdbpy_ref children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
-						  NULL));
+  gdbpy_ref<> children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+						    NULL));
   if (children == NULL)
     {
       gdbpy_print_stack ();
diff --git a/gdb/python/py-xmethods.c b/gdb/python/py-xmethods.c
index 6505d06..d293c71 100644
--- a/gdb/python/py-xmethods.c
+++ b/gdb/python/py-xmethods.c
@@ -96,8 +96,8 @@ invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
 {
   int enabled;
 
-  gdbpy_ref enabled_field (PyObject_GetAttrString (matcher,
-						   enabled_field_name));
+  gdbpy_ref<> enabled_field (PyObject_GetAttrString (matcher,
+						     enabled_field_name));
   if (enabled_field == NULL)
     return NULL;
 
@@ -110,11 +110,12 @@ invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
       Py_RETURN_NONE;
     }
 
-  gdbpy_ref match_method (PyObject_GetAttrString (matcher, match_method_name));
+  gdbpy_ref<> match_method (PyObject_GetAttrString (matcher,
+						    match_method_name));
   if (match_method == NULL)
     return NULL;
 
-  gdbpy_ref py_xmethod_name (PyString_FromString (xmethod_name));
+  gdbpy_ref<> py_xmethod_name (PyString_FromString (xmethod_name));
   if (py_xmethod_name == NULL)
     return NULL;
 
@@ -139,7 +140,7 @@ gdbpy_get_matching_xmethod_workers
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
-  gdbpy_ref py_type (type_to_type_object (obj_type));
+  gdbpy_ref<> py_type (type_to_type_object (obj_type));
   if (py_type == NULL)
     {
       gdbpy_print_stack ();
@@ -147,7 +148,7 @@ gdbpy_get_matching_xmethod_workers
     }
 
   /* Create an empty list of debug methods.  */
-  gdbpy_ref py_xmethod_matcher_list (PyList_New (0));
+  gdbpy_ref<> py_xmethod_matcher_list (PyList_New (0));
   if (py_xmethod_matcher_list == NULL)
     {
       gdbpy_print_stack ();
@@ -167,9 +168,9 @@ gdbpy_get_matching_xmethod_workers
 	  return EXT_LANG_RC_ERROR;
 	}
 
-      gdbpy_ref objfile_matchers (objfpy_get_xmethods (py_objfile, NULL));
-      gdbpy_ref temp (PySequence_Concat (py_xmethod_matcher_list.get (),
-					 objfile_matchers.get ()));
+      gdbpy_ref<> objfile_matchers (objfpy_get_xmethods (py_objfile, NULL));
+      gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
+					   objfile_matchers.get ()));
       if (temp == NULL)
 	{
 	  gdbpy_print_stack ();
@@ -184,10 +185,10 @@ gdbpy_get_matching_xmethod_workers
   py_progspace = pspace_to_pspace_object (current_program_space);
   if (py_progspace != NULL)
     {
-      gdbpy_ref pspace_matchers (pspy_get_xmethods (py_progspace, NULL));
+      gdbpy_ref<> pspace_matchers (pspy_get_xmethods (py_progspace, NULL));
 
-      gdbpy_ref temp (PySequence_Concat (py_xmethod_matcher_list.get (),
-					 pspace_matchers.get ()));
+      gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
+					   pspace_matchers.get ()));
       if (temp == NULL)
 	{
 	  gdbpy_print_stack ();
@@ -206,12 +207,12 @@ gdbpy_get_matching_xmethod_workers
   if (gdb_python_module != NULL
       && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
     {
-      gdbpy_ref gdb_matchers (PyObject_GetAttrString (gdb_python_module,
-						      matchers_attr_str));
+      gdbpy_ref<> gdb_matchers (PyObject_GetAttrString (gdb_python_module,
+							matchers_attr_str));
       if (gdb_matchers != NULL)
 	{
-	  gdbpy_ref temp (PySequence_Concat (py_xmethod_matcher_list.get (),
-					     gdb_matchers.get ()));
+	  gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
+					       gdb_matchers.get ()));
 	  if (temp == NULL)
 	    {
 	      gdbpy_print_stack ();
@@ -227,7 +228,7 @@ gdbpy_get_matching_xmethod_workers
 	}
     }
 
-  gdbpy_ref list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
+  gdbpy_ref<> list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
   if (list_iter == NULL)
     {
       gdbpy_print_stack ();
@@ -235,7 +236,7 @@ gdbpy_get_matching_xmethod_workers
     }
   while (true)
     {
-      gdbpy_ref matcher (PyIter_Next (list_iter.get ()));
+      gdbpy_ref<> matcher (PyIter_Next (list_iter.get ()));
       if (matcher == NULL)
 	{
 	  if (PyErr_Occurred ())
@@ -246,9 +247,9 @@ gdbpy_get_matching_xmethod_workers
 	  break;
 	}
 
-      gdbpy_ref match_result (invoke_match_method (matcher.get (),
-						   py_type.get (),
-						   method_name));
+      gdbpy_ref<> match_result (invoke_match_method (matcher.get (),
+						     py_type.get (),
+						     method_name));
 
       if (match_result == NULL)
 	{
@@ -259,7 +260,7 @@ gdbpy_get_matching_xmethod_workers
 	; /* This means there was no match.  */
       else if (PySequence_Check (match_result.get ()))
 	{
-	  gdbpy_ref iter (PyObject_GetIter (match_result.get ()));
+	  gdbpy_ref<> iter (PyObject_GetIter (match_result.get ()));
 
 	  if (iter == NULL)
 	    {
@@ -270,7 +271,7 @@ gdbpy_get_matching_xmethod_workers
 	    {
 	      struct xmethod_worker *worker;
 
-	      gdbpy_ref py_worker (PyIter_Next (iter.get ()));
+	      gdbpy_ref<> py_worker (PyIter_Next (iter.get ()));
 	      if (py_worker == NULL)
 		{
 		  if (PyErr_Occurred ())
@@ -316,13 +317,13 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
   PyObject *py_worker = worker_data->worker;
   struct type *obj_type;
   int i = 1, arg_count;
-  gdbpy_ref list_iter;
+  gdbpy_ref<> list_iter;
 
   /* Set nargs to -1 so that any premature return from this function returns
      an invalid/unusable number of arg types.  */
   *nargs = -1;
 
-  gdbpy_ref get_arg_types_method
+  gdbpy_ref<> get_arg_types_method
     (PyObject_GetAttrString (py_worker, get_arg_types_method_name));
   if (get_arg_types_method == NULL)
     {
@@ -330,7 +331,7 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
       return EXT_LANG_RC_ERROR;
     }
 
-  gdbpy_ref py_argtype_list
+  gdbpy_ref<> py_argtype_list
     (PyObject_CallMethodObjArgs (py_worker, py_get_arg_types_method_name,
 				 NULL));
   if (py_argtype_list == NULL)
@@ -368,7 +369,7 @@ gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
     {
       while (true)
 	{
-	  gdbpy_ref item (PyIter_Next (list_iter.get ()));
+	  gdbpy_ref<> item (PyIter_Next (list_iter.get ()));
 	  if (item == NULL)
 	    {
 	      if (PyErr_Occurred ())
@@ -445,7 +446,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
 
   /* First see if there is a get_result_type method.
      If not this could be an old xmethod (pre 7.9.1).  */
-  gdbpy_ref get_result_type_method
+  gdbpy_ref<> get_result_type_method
     (PyObject_GetAttrString (py_worker, get_result_type_method_name));
   if (get_result_type_method == NULL)
     {
@@ -475,14 +476,14 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_type))
 	obj = value_cast (this_type, obj);
     }
-  gdbpy_ref py_value_obj (value_to_value_object (obj));
+  gdbpy_ref<> py_value_obj (value_to_value_object (obj));
   if (py_value_obj == NULL)
     {
       gdbpy_print_stack ();
       return EXT_LANG_RC_ERROR;
     }
 
-  gdbpy_ref py_arg_tuple (PyTuple_New (nargs + 1));
+  gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
   if (py_arg_tuple == NULL)
     {
       gdbpy_print_stack ();
@@ -505,7 +506,7 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
     }
 
-  gdbpy_ref py_result_type
+  gdbpy_ref<> py_result_type
     (PyObject_CallObject (get_result_type_method.get (), py_arg_tuple.get ()));
   if (py_result_type == NULL)
     {
@@ -563,14 +564,14 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       if (!types_equal (obj_type, this_type))
 	obj = value_cast (this_type, obj);
     }
-  gdbpy_ref py_value_obj (value_to_value_object (obj));
+  gdbpy_ref<> py_value_obj (value_to_value_object (obj));
   if (py_value_obj == NULL)
     {
       gdbpy_print_stack ();
       error (_("Error while executing Python code."));
     }
 
-  gdbpy_ref py_arg_tuple (PyTuple_New (nargs + 1));
+  gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
   if (py_arg_tuple == NULL)
     {
       gdbpy_print_stack ();
@@ -594,8 +595,8 @@ gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
     }
 
-  gdbpy_ref py_result (PyObject_CallObject (xmethod_worker,
-					    py_arg_tuple.get ()));
+  gdbpy_ref<> py_result (PyObject_CallObject (xmethod_worker,
+					      py_arg_tuple.get ()));
   if (py_result == NULL)
     {
       gdbpy_print_stack ();
diff --git a/gdb/python/python.c b/gdb/python/python.c
index ab5a6a4..74a6f42 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -273,7 +273,7 @@ eval_python_command (const char *command)
   d = PyModule_GetDict (m);
   if (d == NULL)
     return -1;
-  gdbpy_ref v (PyRun_StringFlags (command, Py_single_input, d, d, NULL));
+  gdbpy_ref<> v (PyRun_StringFlags (command, Py_single_input, d, d, NULL));
   if (v == NULL)
     return -1;
 
@@ -351,7 +351,7 @@ python_run_simple_file (FILE *file, const char *filename)
   /* Because we have a string for a filename, and are using Python to
      open the file, we need to expand any tilde in the path first.  */
   gdb::unique_xmalloc_ptr<char> full_path (tilde_expand (filename));
-  gdbpy_ref python_file (PyFile_FromString (full_path.get (), "r"));
+  gdbpy_ref<> python_file (PyFile_FromString (full_path.get (), "r"));
   if (python_file == NULL)
     {
       gdbpy_print_stack ();
@@ -669,8 +669,8 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
   struct symtab_and_line sal;
   char *arg = NULL;
   struct cleanup *cleanups;
-  gdbpy_ref result;
-  gdbpy_ref unparsed;
+  gdbpy_ref<> result;
+  gdbpy_ref<> unparsed;
   struct event_location *location = NULL;
 
   if (! PyArg_ParseTuple (args, "|s", &arg))
@@ -745,7 +745,7 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
       Py_INCREF (Py_None);
     }
 
-  gdbpy_ref return_result (PyTuple_New (2));
+  gdbpy_ref<> return_result (PyTuple_New (2));
   if (return_result == NULL)
     {
       do_cleanups (cleanups);
@@ -897,7 +897,7 @@ gdbpy_run_events (int error, gdb_client_data client_data)
 	gdbpy_event_list_end = &gdbpy_event_list;
 
       /* Ignore errors.  */
-      gdbpy_ref call_result (PyObject_CallObject (item->event, NULL));
+      gdbpy_ref<> call_result (PyObject_CallObject (item->event, NULL));
       if (call_result == NULL)
 	PyErr_Clear ();
 
@@ -972,8 +972,8 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
   if (gdb_python_module
       && PyObject_HasAttrString (gdb_python_module, "prompt_hook"))
     {
-      gdbpy_ref hook (PyObject_GetAttrString (gdb_python_module,
-					      "prompt_hook"));
+      gdbpy_ref<> hook (PyObject_GetAttrString (gdb_python_module,
+						"prompt_hook"));
       if (hook == NULL)
 	{
 	  gdbpy_print_stack ();
@@ -982,16 +982,16 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
 
       if (PyCallable_Check (hook.get ()))
 	{
-	  gdbpy_ref current_prompt (PyString_FromString (current_gdb_prompt));
+	  gdbpy_ref<> current_prompt (PyString_FromString (current_gdb_prompt));
 	  if (current_prompt == NULL)
 	    {
 	      gdbpy_print_stack ();
 	      return EXT_LANG_RC_ERROR;
 	    }
 
-	  gdbpy_ref result (PyObject_CallFunctionObjArgs (hook.get (),
-							  current_prompt.get (),
-							  NULL));
+	  gdbpy_ref<> result
+	    (PyObject_CallFunctionObjArgs (hook.get (), current_prompt.get (),
+					   NULL));
 	  if (result == NULL)
 	    {
 	      gdbpy_print_stack ();
@@ -1206,7 +1206,7 @@ gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
 {
   struct program_space *ps;
 
-  gdbpy_ref list (PyList_New (0));
+  gdbpy_ref<> list (PyList_New (0));
   if (list == NULL)
     return NULL;
 
@@ -1296,7 +1296,7 @@ gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
 {
   struct objfile *objf;
 
-  gdbpy_ref list (PyList_New (0));
+  gdbpy_ref<> list (PyList_New (0));
   if (list == NULL)
     return NULL;
 
@@ -1327,15 +1327,15 @@ gdbpy_start_type_printers (const struct extension_language_defn *extlang,
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
-  gdbpy_ref type_module (PyImport_ImportModule ("gdb.types"));
+  gdbpy_ref<> type_module (PyImport_ImportModule ("gdb.types"));
   if (type_module == NULL)
     {
       gdbpy_print_stack ();
       return;
     }
 
-  gdbpy_ref func (PyObject_GetAttrString (type_module.get (),
-					  "get_type_recognizers"));
+  gdbpy_ref<> func (PyObject_GetAttrString (type_module.get (),
+					    "get_type_recognizers"));
   if (func == NULL)
     {
       gdbpy_print_stack ();
@@ -1372,31 +1372,32 @@ gdbpy_apply_type_printers (const struct extension_language_defn *extlang,
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
-  gdbpy_ref type_obj (type_to_type_object (type));
+  gdbpy_ref<> type_obj (type_to_type_object (type));
   if (type_obj == NULL)
     {
       gdbpy_print_stack ();
       return EXT_LANG_RC_ERROR;
     }
 
-  gdbpy_ref type_module (PyImport_ImportModule ("gdb.types"));
+  gdbpy_ref<> type_module (PyImport_ImportModule ("gdb.types"));
   if (type_module == NULL)
     {
       gdbpy_print_stack ();
       return EXT_LANG_RC_ERROR;
     }
 
-  gdbpy_ref func (PyObject_GetAttrString (type_module.get (),
-					  "apply_type_recognizers"));
+  gdbpy_ref<> func (PyObject_GetAttrString (type_module.get (),
+					    "apply_type_recognizers"));
   if (func == NULL)
     {
       gdbpy_print_stack ();
       return EXT_LANG_RC_ERROR;
     }
 
-  gdbpy_ref result_obj (PyObject_CallFunctionObjArgs (func.get (), printers_obj,
-						      type_obj.get (),
-						      (char *) NULL));
+  gdbpy_ref<> result_obj (PyObject_CallFunctionObjArgs (func.get (),
+							printers_obj,
+							type_obj.get (),
+							(char *) NULL));
   if (result_obj == NULL)
     {
       gdbpy_print_stack ();
@@ -1798,7 +1799,7 @@ do_finish_initialization (const struct extension_language_defn *extlang)
     }
   if (sys_path && PyList_Check (sys_path))
     {
-      gdbpy_ref pythondir (PyString_FromString (gdb_pythondir.c_str ()));
+      gdbpy_ref<> pythondir (PyString_FromString (gdb_pythondir.c_str ()));
       if (pythondir == NULL || PyList_Insert (sys_path, 0, pythondir.get ()))
 	return false;
     }
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 3b2771f5..4b12826 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -1478,11 +1478,11 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
   gdbpy_enter_varobj enter_py (var);
 
   mainmod = PyImport_AddModule ("__main__");
-  gdbpy_ref globals (PyModule_GetDict (mainmod));
+  gdbpy_ref<> globals (PyModule_GetDict (mainmod));
   Py_INCREF (globals.get ());
 
-  gdbpy_ref constructor (PyRun_String (visualizer, Py_eval_input,
-				       globals.get (), globals.get ()));
+  gdbpy_ref<> constructor (PyRun_String (visualizer, Py_eval_input,
+					 globals.get (), globals.get ()));
 
   if (constructor == NULL)
     {
@@ -2432,9 +2432,9 @@ varobj_value_get_print_value (struct value *value,
 	    {
 	      struct value *replacement;
 
-	      gdbpy_ref output (apply_varobj_pretty_printer (value_formatter,
-							     &replacement,
-							     &stb));
+	      gdbpy_ref<> output (apply_varobj_pretty_printer (value_formatter,
+							       &replacement,
+							       &stb));
 
 	      /* If we have string like output ...  */
 	      if (output != NULL)
-- 
2.9.3

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

* [RFA v2 1/7] Remove some ui_out-related cleanups from Python
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
  2017-02-09 21:25 ` [RFA v2 2/7] Turn gdbpy_ref into a template Tom Tromey
  2017-02-09 21:25 ` [RFA v2 4/7] Change one more spot to use gdbpy_ref Tom Tromey
@ 2017-02-09 21:25 ` Tom Tromey
  2017-02-10 15:57   ` Simon Marchi
  2017-02-09 21:25 ` [RFA v2 5/7] Remove some gotos " Tom Tromey
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This patch introduces a bit of infrastructure -- namely, a minimal
std::optional analogue called gdb::optional, and an RAII template
class that works like make_cleanup_ui_out_tuple_begin_end or
make_cleanup_ui_out_list_begin_end -- and then uses these in the
Python code.  This removes a number of cleanups and generally
simplifies this code.

std::optional is only available in C++17.  Normally I would have had
this code check __cplusplus, but my gcc apparently isn't new enough to
find <optional>, even with -std=c++1z; so, because I could not test
it, the patch does not do this.

2017-02-09  Tom Tromey  <tom@tromey.com>

	* ui-out.h (ui_out_emit_type): New class.
	(ui_out_emit_tuple, ui_out_emit_list): New typedefs.
	* python/py-framefilter.c (py_print_single_arg): Use gdb::optional
	and ui_out_emit_tuple.
	(enumerate_locals): Likewise.
	(py_mi_print_variables, py_print_locals, py_print_args): Use
	ui_out_emit_list.
	(py_print_frame): Use gdb::optional, ui_out_emit_tuple,
	ui_out_emit_list.
	* common/gdb_optional.h: New file.
---
 gdb/ChangeLog               |  13 +++
 gdb/common/gdb_optional.h   |  87 ++++++++++++++++++
 gdb/python/py-framefilter.c | 209 +++++++++++---------------------------------
 gdb/ui-out.h                |  33 +++++++
 4 files changed, 186 insertions(+), 156 deletions(-)
 create mode 100644 gdb/common/gdb_optional.h

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 318dbaf..4ec4dd5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2017-02-09  Tom Tromey  <tom@tromey.com>
+
+	* ui-out.h (ui_out_emit_type): New class.
+	(ui_out_emit_tuple, ui_out_emit_list): New typedefs.
+	* python/py-framefilter.c (py_print_single_arg): Use gdb::optional
+	and ui_out_emit_tuple.
+	(enumerate_locals): Likewise.
+	(py_mi_print_variables, py_print_locals, py_print_args): Use
+	ui_out_emit_list.
+	(py_print_frame): Use gdb::optional, ui_out_emit_tuple,
+	ui_out_emit_list.
+	* common/gdb_optional.h: New file.
+
 2017-02-09  Gary Benson  <gbenson@redhat.com>
 
 	* symtab.c (add_symtab_completions): Prevent NULL pointer
diff --git a/gdb/common/gdb_optional.h b/gdb/common/gdb_optional.h
new file mode 100644
index 0000000..d991da1
--- /dev/null
+++ b/gdb/common/gdb_optional.h
@@ -0,0 +1,87 @@
+/* An optional object.
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_OPTIONAL_H
+#define GDB_OPTIONAL_H
+
+namespace gdb
+{
+
+/* This class attempts to be a compatible subset of std::optional,
+   which is slated to be available in C++17.  This class optionally
+   holds an object of some type -- by default it is constructed not
+   holding an object, but later the object can be "emplaced".  This is
+   similar to using std::unique_ptr, but in-object allocation is
+   guaranteed.  */
+template<typename T>
+class optional
+{
+public:
+
+  optional ()
+    : m_instantiated (false)
+  {
+  }
+
+  ~optional ()
+  {
+    if (m_instantiated)
+      destroy ();
+  }
+
+  /* These aren't deleted in std::optional, but it was simpler to
+     delete them here, because currently the users of this class don't
+     need them, and making them depend on the definition of T is
+     somewhat complicated.  */
+  optional (const optional &other) = delete;
+  optional<T> &operator= (const optional &other) = delete;
+
+  template<typename... Args>
+  void emplace (Args &&... args)
+  {
+    if (m_instantiated)
+      destroy ();
+    new (&m_item) T (std::forward<Args>(args)...);
+    m_instantiated = true;
+  }
+
+private:
+
+  /* Destroy the object.  */
+  void destroy ()
+  {
+    gdb_assert (m_instantiated);
+    m_instantiated = false;
+    m_item.~T ();
+  }
+
+  /* The object.  */
+  union
+  {
+    struct { } m_dummy;
+    T m_item;
+  };
+
+  /* True if the object was ever emplaced.  */
+  bool m_instantiated;
+};
+
+}
+
+#endif /* GDB_OPTIONAL_H */
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 9dc01ba..a4a22a0 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -31,6 +31,7 @@
 #include "mi/mi-cmds.h"
 #include "python-internal.h"
 #include "py-ref.h"
+#include "common/gdb_optional.h"
 
 enum mi_print_types
 {
@@ -365,7 +366,7 @@ py_print_single_arg (struct ui_out *out,
 
   TRY
     {
-      struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+      gdb::optional<ui_out_emit_tuple> maybe_tuple;
 
       /*  MI has varying rules for tuples, but generally if there is only
       one element in each item in the list, do not start a tuple.  The
@@ -376,7 +377,7 @@ py_print_single_arg (struct ui_out *out,
       if (out->is_mi_like_p ())
 	{
 	  if (print_args_field || args_type != NO_VALUES)
-	    make_cleanup_ui_out_tuple_begin_end (out, NULL);
+	    maybe_tuple.emplace (out, nullptr);
 	}
 
       annotate_arg_begin ();
@@ -421,10 +422,7 @@ py_print_single_arg (struct ui_out *out,
       if (args_type == MI_PRINT_SIMPLE_VALUES && val != NULL)
 	{
 	  if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
-	    {
-	      retval = EXT_LANG_BT_ERROR;
-	      do_cleanups (cleanups);
-	    }
+	    retval = EXT_LANG_BT_ERROR;
 	}
 
       if (retval != EXT_LANG_BT_ERROR)
@@ -454,8 +452,6 @@ py_print_single_arg (struct ui_out *out,
 		    retval = EXT_LANG_BT_ERROR;
 		}
 	    }
-
-	  do_cleanups (cleanups);
 	}
     }
   CATCH (except, RETURN_MASK_ERROR)
@@ -695,35 +691,24 @@ enumerate_locals (PyObject *iter,
       struct symbol *sym;
       struct block *sym_block;
       int local_indent = 8 + (8 * indent);
-      struct cleanup *locals_cleanups;
+      gdb::optional<ui_out_emit_tuple> tuple;
 
       gdbpy_ref item (PyIter_Next (iter));
       if (item == NULL)
 	break;
 
-      locals_cleanups = make_cleanup (null_cleanup, NULL);
-
       success = extract_sym (item.get (), &sym_name, &sym, &sym_block,
 			     &language);
       if (success == EXT_LANG_BT_ERROR)
-	{
-	  do_cleanups (locals_cleanups);
-	  goto error;
-	}
+	return EXT_LANG_BT_ERROR;
 
       success = extract_value (item.get (), &val);
       if (success == EXT_LANG_BT_ERROR)
-	{
-	  do_cleanups (locals_cleanups);
-	  goto error;
-	}
+	return EXT_LANG_BT_ERROR;
 
       if (sym != NULL && out->is_mi_like_p ()
 	  && ! mi_should_print (sym, MI_PRINT_LOCALS))
-	{
-	  do_cleanups (locals_cleanups);
-	  continue;
-	}
+	continue;
 
       /* If the object did not provide a value, read it.  */
       if (val == NULL)
@@ -735,8 +720,7 @@ enumerate_locals (PyObject *iter,
 	  CATCH (except, RETURN_MASK_ERROR)
 	    {
 	      gdbpy_convert_exception (except);
-	      do_cleanups (locals_cleanups);
-	      goto error;
+	      return EXT_LANG_BT_ERROR;
 	    }
 	  END_CATCH
 	}
@@ -747,7 +731,7 @@ enumerate_locals (PyObject *iter,
       if (out->is_mi_like_p ())
 	{
 	  if (print_args_field || args_type != NO_VALUES)
-	    make_cleanup_ui_out_tuple_begin_end (out, NULL);
+	    tuple.emplace (out, nullptr);
 	}
       TRY
 	{
@@ -765,18 +749,14 @@ enumerate_locals (PyObject *iter,
       CATCH (except, RETURN_MASK_ERROR)
 	{
 	  gdbpy_convert_exception (except);
-	  do_cleanups (locals_cleanups);
-	  goto error;
+	  return EXT_LANG_BT_ERROR;
 	}
       END_CATCH
 
       if (args_type == MI_PRINT_SIMPLE_VALUES)
 	{
 	  if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
-	    {
-	      do_cleanups (locals_cleanups);
-	      goto error;
-	    }
+	    return EXT_LANG_BT_ERROR;
 	}
 
       /* CLI always prints values for locals.  MI uses the
@@ -787,10 +767,7 @@ enumerate_locals (PyObject *iter,
 
 	  if (py_print_value (out, val, &opts, val_indent, args_type,
 			      language) == EXT_LANG_BT_ERROR)
-	    {
-	      do_cleanups (locals_cleanups);
-	      goto error;
-	    }
+	    return EXT_LANG_BT_ERROR;
 	}
       else
 	{
@@ -798,15 +775,10 @@ enumerate_locals (PyObject *iter,
 	    {
 	      if (py_print_value (out, val, &opts, 0, args_type,
 				  language) == EXT_LANG_BT_ERROR)
-		{
-		  do_cleanups (locals_cleanups);
-		  goto error;
-		}
+		return EXT_LANG_BT_ERROR;
 	    }
 	}
 
-      do_cleanups (locals_cleanups);
-
       TRY
 	{
 	  out->text ("\n");
@@ -814,7 +786,7 @@ enumerate_locals (PyObject *iter,
       CATCH (except, RETURN_MASK_ERROR)
 	{
 	  gdbpy_convert_exception (except);
-	  goto error;
+	  return EXT_LANG_BT_ERROR;
 	}
       END_CATCH
     }
@@ -822,7 +794,6 @@ enumerate_locals (PyObject *iter,
   if (!PyErr_Occurred ())
     return EXT_LANG_BT_OK;
 
- error:
   return EXT_LANG_BT_ERROR;
 }
 
@@ -835,8 +806,6 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
 		       enum ext_lang_frame_args args_type,
 		       struct frame_info *frame)
 {
-  struct cleanup *old_chain;
-
   gdbpy_ref args_iter (get_py_iter_from_func (filter, "frame_args"));
   if (args_iter == NULL)
     return EXT_LANG_BT_ERROR;
@@ -845,24 +814,19 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
   if (locals_iter == NULL)
     return EXT_LANG_BT_ERROR;
 
-  old_chain = make_cleanup_ui_out_list_begin_end (out, "variables");
+  ui_out_emit_list list_emitter (out, "variables");
 
-  if (args_iter != Py_None)
-    if (enumerate_args (args_iter.get (), out, args_type, 1, frame)
-	== EXT_LANG_BT_ERROR)
-      goto error;
+  if (args_iter != Py_None
+      && (enumerate_args (args_iter.get (), out, args_type, 1, frame)
+	  == EXT_LANG_BT_ERROR))
+    return EXT_LANG_BT_ERROR;
 
-  if (locals_iter != Py_None)
-    if (enumerate_locals (locals_iter.get (), out, 1, args_type, 1, frame)
-	== EXT_LANG_BT_ERROR)
-      goto error;
+  if (locals_iter != Py_None
+      && (enumerate_locals (locals_iter.get (), out, 1, args_type, 1, frame)
+	  == EXT_LANG_BT_ERROR))
+    return EXT_LANG_BT_ERROR;
 
-  do_cleanups (old_chain);
   return EXT_LANG_BT_OK;
-
- error:
-  do_cleanups (old_chain);
-  return EXT_LANG_BT_ERROR;
 }
 
 /* Helper function for printing locals.  This function largely just
@@ -876,25 +840,18 @@ py_print_locals (PyObject *filter,
 		 int indent,
 		 struct frame_info *frame)
 {
-  struct cleanup *old_chain;
-
   gdbpy_ref locals_iter (get_py_iter_from_func (filter, "frame_locals"));
   if (locals_iter == NULL)
     return EXT_LANG_BT_ERROR;
 
-  old_chain = make_cleanup_ui_out_list_begin_end (out, "locals");
+  ui_out_emit_list list_emitter (out, "locals");
 
-  if (locals_iter != Py_None)
-    if (enumerate_locals (locals_iter.get (), out, indent, args_type,
-			  0, frame) == EXT_LANG_BT_ERROR)
-      goto locals_error;
+  if (locals_iter != Py_None
+      && (enumerate_locals (locals_iter.get (), out, indent, args_type,
+			    0, frame) == EXT_LANG_BT_ERROR))
+    return EXT_LANG_BT_ERROR;
 
-  do_cleanups (old_chain);
   return EXT_LANG_BT_OK;
-
- locals_error:
-  do_cleanups (old_chain);
-  return EXT_LANG_BT_ERROR;
 }
 
 /* Helper function for printing frame arguments.  This function
@@ -908,13 +865,11 @@ py_print_args (PyObject *filter,
 	       enum ext_lang_frame_args args_type,
 	       struct frame_info *frame)
 {
-  struct cleanup *old_chain;
-
   gdbpy_ref args_iter (get_py_iter_from_func (filter, "frame_args"));
   if (args_iter == NULL)
     return EXT_LANG_BT_ERROR;
 
-  old_chain = make_cleanup_ui_out_list_begin_end (out, "args");
+  ui_out_emit_list list_emitter (out, "args");
 
   TRY
     {
@@ -925,14 +880,14 @@ py_print_args (PyObject *filter,
   CATCH (except, RETURN_MASK_ALL)
     {
       gdbpy_convert_exception (except);
-      goto args_error;
+      return EXT_LANG_BT_ERROR;
     }
   END_CATCH
 
-  if (args_iter != Py_None)
-    if (enumerate_args (args_iter.get (), out, args_type, 0, frame)
-	== EXT_LANG_BT_ERROR)
-      goto args_error;
+  if (args_iter != Py_None
+      && (enumerate_args (args_iter.get (), out, args_type, 0, frame)
+	  == EXT_LANG_BT_ERROR))
+    return EXT_LANG_BT_ERROR;
 
   TRY
     {
@@ -942,16 +897,11 @@ py_print_args (PyObject *filter,
   CATCH (except, RETURN_MASK_ALL)
     {
       gdbpy_convert_exception (except);
-      goto args_error;
+      return EXT_LANG_BT_ERROR;
     }
   END_CATCH
 
-  do_cleanups (old_chain);
   return EXT_LANG_BT_OK;
-
- args_error:
-  do_cleanups (old_chain);
-  return EXT_LANG_BT_ERROR;
 }
 
 /*  Print a single frame to the designated output stream, detecting
@@ -978,7 +928,6 @@ py_print_frame (PyObject *filter, int flags,
   CORE_ADDR address = 0;
   struct gdbarch *gdbarch = NULL;
   struct frame_info *frame = NULL;
-  struct cleanup *cleanup_stack;
   struct value_print_options opts;
   int print_level, print_frame_info, print_args, print_locals;
   gdb::unique_xmalloc_ptr<char> function_to_free;
@@ -1022,12 +971,12 @@ py_print_frame (PyObject *filter, int flags,
       return EXT_LANG_BT_COMPLETED;
     }
 
-  cleanup_stack = make_cleanup (null_cleanup, NULL);
+  gdb::optional<ui_out_emit_tuple> tuple;
 
   /* -stack-list-locals does not require a
      wrapping frame attribute.  */
   if (print_frame_info || (print_args && ! print_locals))
-    make_cleanup_ui_out_tuple_begin_end (out, "frame");
+    tuple.emplace (out, "frame");
 
   if (print_frame_info)
     {
@@ -1042,7 +991,6 @@ py_print_frame (PyObject *filter, int flags,
 	  CATCH (except, RETURN_MASK_ERROR)
 	    {
 	      gdbpy_convert_exception (except);
-	      do_cleanups (cleanup_stack);
 	      return EXT_LANG_BT_ERROR;
 	    }
 	  END_CATCH
@@ -1055,18 +1003,12 @@ py_print_frame (PyObject *filter, int flags,
 	  gdbpy_ref paddr (PyObject_CallMethod (filter, "address", NULL));
 
 	  if (paddr == NULL)
-	    {
-	      do_cleanups (cleanup_stack);
-	      return EXT_LANG_BT_ERROR;
-	    }
+	    return EXT_LANG_BT_ERROR;
 
 	  if (paddr != Py_None)
 	    {
 	      if (get_addr_from_python (paddr.get (), &address) < 0)
-		{
-		  do_cleanups (cleanup_stack);
-		  return EXT_LANG_BT_ERROR;
-		}
+		return EXT_LANG_BT_ERROR;
 
 	      has_addr = 1;
 	    }
@@ -1105,7 +1047,6 @@ py_print_frame (PyObject *filter, int flags,
       CATCH (except, RETURN_MASK_ERROR)
 	{
 	  gdbpy_convert_exception (except);
-	  do_cleanups (cleanup_stack);
 	  return EXT_LANG_BT_ERROR;
 	}
       END_CATCH
@@ -1127,7 +1068,6 @@ py_print_frame (PyObject *filter, int flags,
 	  CATCH (except, RETURN_MASK_ERROR)
 	    {
 	      gdbpy_convert_exception (except);
-	      do_cleanups (cleanup_stack);
 	      return EXT_LANG_BT_ERROR;
 	    }
 	  END_CATCH
@@ -1140,20 +1080,14 @@ py_print_frame (PyObject *filter, int flags,
 	  const char *function = NULL;
 
 	  if (py_func == NULL)
-	    {
-	      do_cleanups (cleanup_stack);
-	      return EXT_LANG_BT_ERROR;
-	    }
+	    return EXT_LANG_BT_ERROR;
 
 	  if (gdbpy_is_string (py_func.get ()))
 	    {
 	      function_to_free = python_string_to_host_string (py_func.get ());
 
 	      if (function_to_free == NULL)
-		{
-		  do_cleanups (cleanup_stack);
-		  return EXT_LANG_BT_ERROR;
-		}
+		return EXT_LANG_BT_ERROR;
 
 	      function = function_to_free.get ();
 	    }
@@ -1163,10 +1097,7 @@ py_print_frame (PyObject *filter, int flags,
 	      struct bound_minimal_symbol msymbol;
 
 	      if (get_addr_from_python (py_func.get (), &addr) < 0)
-		{
-		  do_cleanups (cleanup_stack);
-		  return EXT_LANG_BT_ERROR;
-		}
+		return EXT_LANG_BT_ERROR;
 
 	      msymbol = lookup_minimal_symbol_by_pc (addr);
 	      if (msymbol.minsym != NULL)
@@ -1177,7 +1108,6 @@ py_print_frame (PyObject *filter, int flags,
 	      PyErr_SetString (PyExc_RuntimeError,
 			       _("FrameDecorator.function: expecting a " \
 				 "String, integer or None."));
-	      do_cleanups (cleanup_stack);
 	      return EXT_LANG_BT_ERROR;
 	    }
 
@@ -1192,7 +1122,6 @@ py_print_frame (PyObject *filter, int flags,
 	  CATCH (except, RETURN_MASK_ERROR)
 	    {
 	      gdbpy_convert_exception (except);
-	      do_cleanups (cleanup_stack);
 	      return EXT_LANG_BT_ERROR;
 	    }
 	  END_CATCH
@@ -1205,10 +1134,7 @@ py_print_frame (PyObject *filter, int flags,
   if (print_args)
     {
       if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR)
-	{
-	  do_cleanups (cleanup_stack);
-	  return EXT_LANG_BT_ERROR;
-	}
+	return EXT_LANG_BT_ERROR;
     }
 
   /* File name/source/line number information.  */
@@ -1221,7 +1147,6 @@ py_print_frame (PyObject *filter, int flags,
       CATCH (except, RETURN_MASK_ERROR)
 	{
 	  gdbpy_convert_exception (except);
-	  do_cleanups (cleanup_stack);
 	  return EXT_LANG_BT_ERROR;
 	}
       END_CATCH
@@ -1231,10 +1156,7 @@ py_print_frame (PyObject *filter, int flags,
 	  gdbpy_ref py_fn (PyObject_CallMethod (filter, "filename", NULL));
 
 	  if (py_fn == NULL)
-	    {
-	      do_cleanups (cleanup_stack);
-	      return EXT_LANG_BT_ERROR;
-	    }
+	    return EXT_LANG_BT_ERROR;
 
 	  if (py_fn != Py_None)
 	    {
@@ -1242,10 +1164,7 @@ py_print_frame (PyObject *filter, int flags,
 		filename (python_string_to_host_string (py_fn.get ()));
 
 	      if (filename == NULL)
-		{
-		  do_cleanups (cleanup_stack);
-		  return EXT_LANG_BT_ERROR;
-		}
+		return EXT_LANG_BT_ERROR;
 
 	      TRY
 		{
@@ -1258,7 +1177,6 @@ py_print_frame (PyObject *filter, int flags,
 	      CATCH (except, RETURN_MASK_ERROR)
 		{
 		  gdbpy_convert_exception (except);
-		  do_cleanups (cleanup_stack);
 		  return EXT_LANG_BT_ERROR;
 		}
 	      END_CATCH
@@ -1271,19 +1189,13 @@ py_print_frame (PyObject *filter, int flags,
 	  int line;
 
 	  if (py_line == NULL)
-	    {
-	      do_cleanups (cleanup_stack);
-	      return EXT_LANG_BT_ERROR;
-	    }
+	    return EXT_LANG_BT_ERROR;
 
 	  if (py_line != Py_None)
 	    {
 	      line = PyLong_AsLong (py_line.get ());
 	      if (PyErr_Occurred ())
-		{
-		  do_cleanups (cleanup_stack);
-		  return EXT_LANG_BT_ERROR;
-		}
+		return EXT_LANG_BT_ERROR;
 
 	      TRY
 		{
@@ -1294,7 +1206,6 @@ py_print_frame (PyObject *filter, int flags,
 	      CATCH (except, RETURN_MASK_ERROR)
 		{
 		  gdbpy_convert_exception (except);
-		  do_cleanups (cleanup_stack);
 		  return EXT_LANG_BT_ERROR;
 		}
 	      END_CATCH
@@ -1314,7 +1225,6 @@ py_print_frame (PyObject *filter, int flags,
       CATCH (except, RETURN_MASK_ERROR)
 	{
 	  gdbpy_convert_exception (except);
-	  do_cleanups (cleanup_stack);
 	  return EXT_LANG_BT_ERROR;
 	}
       END_CATCH
@@ -1324,26 +1234,20 @@ py_print_frame (PyObject *filter, int flags,
     {
       if (py_print_locals (filter, out, args_type, indent,
 			   frame) == EXT_LANG_BT_ERROR)
-	{
-	  do_cleanups (cleanup_stack);
-	  return EXT_LANG_BT_ERROR;
-	}
+	return EXT_LANG_BT_ERROR;
     }
 
   {
     /* Finally recursively print elided frames, if any.  */
     gdbpy_ref elided (get_py_iter_from_func (filter, "elided"));
     if (elided == NULL)
-      {
-	do_cleanups (cleanup_stack);
-	return EXT_LANG_BT_ERROR;
-      }
+      return EXT_LANG_BT_ERROR;
 
     if (elided != Py_None)
       {
 	PyObject *item;
 
-	make_cleanup_ui_out_list_begin_end (out, "children");
+	ui_out_emit_list inner_list_emiter (out, "children");
 
 	if (! out->is_mi_like_p ())
 	  indent++;
@@ -1358,20 +1262,13 @@ py_print_frame (PyObject *filter, int flags,
 							      levels_printed);
 
 	    if (success == EXT_LANG_BT_ERROR)
-	      {
-		do_cleanups (cleanup_stack);
-		return EXT_LANG_BT_ERROR;
-	      }
+	      return EXT_LANG_BT_ERROR;
 	  }
 	if (item == NULL && PyErr_Occurred ())
-	  {
-	    do_cleanups (cleanup_stack);
-	    return EXT_LANG_BT_ERROR;
-	  }
+	  return EXT_LANG_BT_ERROR;
       }
   }
 
-  do_cleanups (cleanup_stack);
   return EXT_LANG_BT_COMPLETED;
 }
 
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index d54843d..9278cab 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -187,4 +187,37 @@ class ui_out
   ui_out_level *current_level () const;
 };
 
+/* This is similar to make_cleanup_ui_out_tuple_begin_end and
+   make_cleanup_ui_out_list_begin_end, but written as an RAII template
+   class.  It takes the ui_out_type as a template parameter.  Normally
+   this is used via the typedefs ui_out_emit_tuple and
+   ui_out_emit_list.  */
+template<ui_out_type Type>
+class ui_out_emit_type
+{
+public:
+
+  ui_out_emit_type (struct ui_out *uiout, const char *id)
+    : m_uiout (uiout)
+  {
+    uiout->begin (Type, id);
+  }
+
+  ~ui_out_emit_type ()
+  {
+    m_uiout->end (Type);
+  }
+
+  ui_out_emit_type (const ui_out_emit_type<Type> &) = delete;
+  ui_out_emit_type<Type> &operator= (const ui_out_emit_type<Type> &)
+      = delete;
+
+private:
+
+  struct ui_out *m_uiout;
+};
+
+typedef ui_out_emit_type<ui_out_type_tuple> ui_out_emit_tuple;
+typedef ui_out_emit_type<ui_out_type_list> ui_out_emit_list;
+
 #endif /* UI_OUT_H */
-- 
2.9.3

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

* [RFA v2 7/7] Fix Python test to use lowercase command
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
                   ` (4 preceding siblings ...)
  2017-02-09 21:25 ` [RFA v2 3/7] Use gdbpy_ref to simplify some logic Tom Tromey
@ 2017-02-09 21:25 ` Tom Tromey
  2017-02-09 21:25 ` [RFA v2 6/7] Remove unnecessary local variables Tom Tromey
  2017-02-10 16:21 ` [RFA v2 0/7] more cleanup removal in Python Simon Marchi
  7 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

While testing this series I saw some errors from the Python test
suite.  There were a couple of tests using "P" as a command; this
changes them to "p".

2017-02-09  Tom Tromey  <tom@tromey.com>

	* gdb.python/py-xmethods.exp: Use "p" command, not "P".
---
 gdb/testsuite/ChangeLog                  | 4 ++++
 gdb/testsuite/gdb.python/py-xmethods.exp | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 39f6776..8798319 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-09  Tom Tromey  <tom@tromey.com>
+
+	* gdb.python/py-xmethods.exp: Use "p" command, not "P".
+
 2017-02-08  Jerome Guitton  <guitton@adacore.com>
 
 	* gdb.base/define.exp: Add test for command abbreviations
diff --git a/gdb/testsuite/gdb.python/py-xmethods.exp b/gdb/testsuite/gdb.python/py-xmethods.exp
index dcd7191..6f8e023 100644
--- a/gdb/testsuite/gdb.python/py-xmethods.exp
+++ b/gdb/testsuite/gdb.python/py-xmethods.exp
@@ -106,8 +106,8 @@ gdb_test "p a1.geta()" "From Python <A_geta>.*5" "after: a1.geta()"
 gdb_test "p ++a1" "From Python <plus_plus_A>.*6" "after: ++a1"
 gdb_test "p a1.getarrayind(5)" "From Python <A_getarrayind>.*5" \
   "after: a1.getarrayind(5)"
-gdb_test "P a1\[6\]" ".*int &.*6" "after a1\[\]"
-gdb_test "P b1\[7\]" ".*const int &.*7" "after b1\[\]"
+gdb_test "p a1\[6\]" ".*int &.*6" "after a1\[\]"
+gdb_test "p b1\[7\]" ".*const int &.*7" "after b1\[\]"
 # Note the following test.  Xmethods on dynamc types are not looked up
 # currently.  Hence, even though a_ptr points to a B object, the xmethod
 # defined for A objects is invoked.
-- 
2.9.3

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

* [RFA v2 3/7] Use gdbpy_ref to simplify some logic
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
                   ` (3 preceding siblings ...)
  2017-02-09 21:25 ` [RFA v2 5/7] Remove some gotos " Tom Tromey
@ 2017-02-09 21:25 ` Tom Tromey
  2017-02-09 21:25 ` [RFA v2 7/7] Fix Python test to use lowercase command Tom Tromey
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This uses the new gdbpy_ref template to simplify logic in various
parts of the Python layer; for example removing repeated error code or
removing gotos.

2017-02-09  Tom Tromey  <tom@tromey.com>

	* python/py-cmd.c (cmdpy_destroyer): Use gdbpy_ref.
	* python/py-breakpoint.c (gdbpy_breakpoint_deleted): Use
	gdbpy_ref.
	* python/py-type.c (field_new): Use gdbpy_ref.
	* python/py-symtab.c (symtab_and_line_to_sal_object): Use
	gdbpy_ref.
	* python/py-progspace.c (pspy_new): Use gdbpy_ref.
	(py_free_pspace): Likewise.
	(pspace_to_pspace_object): Likewise.
	* python/py-objfile.c (objfpy_new): Use gdbpy_ref.
	(py_free_objfile): Likewise.
	(objfile_to_objfile_object): Likewise.
	* python/py-inferior.c (delete_thread_object): Use
	gdbpy_ref.
	(infpy_read_memory): Likewise.
	(py_free_inferior): Likewise.
	* python/py-evtregistry.c (create_eventregistry_object): Use
	gdbpy_ref.
	* python/py-event.c (create_event_object): Use gdbpy_ref.
---
 gdb/ChangeLog               | 22 ++++++++++++++++++++++
 gdb/python/py-breakpoint.c  |  8 +++-----
 gdb/python/py-cmd.c         |  5 +----
 gdb/python/py-event.c       | 16 +++++-----------
 gdb/python/py-evtregistry.c | 17 +++++++----------
 gdb/python/py-frame.c       |  9 ++++-----
 gdb/python/py-inferior.c    | 26 +++++++++-----------------
 gdb/python/py-objfile.c     | 40 ++++++++++++++++------------------------
 gdb/python/py-progspace.c   | 39 ++++++++++++++++-----------------------
 gdb/python/py-symtab.c      | 16 ++++++----------
 gdb/python/py-type.c        | 12 +++++-------
 11 files changed, 94 insertions(+), 116 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 43dc3ed..446ad24 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,27 @@
 2017-02-09  Tom Tromey  <tom@tromey.com>
 
+	* python/py-cmd.c (cmdpy_destroyer): Use gdbpy_ref.
+	* python/py-breakpoint.c (gdbpy_breakpoint_deleted): Use
+	gdbpy_ref.
+	* python/py-type.c (field_new): Use gdbpy_ref.
+	* python/py-symtab.c (symtab_and_line_to_sal_object): Use
+	gdbpy_ref.
+	* python/py-progspace.c (pspy_new): Use gdbpy_ref.
+	(py_free_pspace): Likewise.
+	(pspace_to_pspace_object): Likewise.
+	* python/py-objfile.c (objfpy_new): Use gdbpy_ref.
+	(py_free_objfile): Likewise.
+	(objfile_to_objfile_object): Likewise.
+	* python/py-inferior.c (delete_thread_object): Use
+	gdbpy_ref.
+	(infpy_read_memory): Likewise.
+	(py_free_inferior): Likewise.
+	* python/py-evtregistry.c (create_eventregistry_object): Use
+	gdbpy_ref.
+	* python/py-event.c (create_event_object): Use gdbpy_ref.
+
+2017-02-09  Tom Tromey  <tom@tromey.com>
+
 	* python/py-ref.h (gdbpy_ref_policy): Now a template.
 	(gdbpy_ref): Now a template; allow subclasses of PyObject to be
 	used.
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 507b866..724a7ed 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -911,25 +911,23 @@ gdbpy_breakpoint_deleted (struct breakpoint *b)
   int num = b->number;
   PyGILState_STATE state;
   struct breakpoint *bp = NULL;
-  gdbpy_breakpoint_object *bp_obj;
 
   state = PyGILState_Ensure ();
   bp = get_breakpoint (num);
   if (bp)
     {
-      bp_obj = bp->py_bp_object;
-      if (bp_obj)
+      gdbpy_ref<gdbpy_breakpoint_object> bp_obj (bp->py_bp_object);
+      if (bp_obj != NULL)
 	{
 	  if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_deleted))
 	    {
-	      if (evpy_emit_event ((PyObject *) bp_obj,
+	      if (evpy_emit_event ((PyObject *) bp_obj.get (),
 				   gdb_py_events.breakpoint_deleted) < 0)
 		gdbpy_print_stack ();
 	    }
 
 	  bp_obj->bp = NULL;
 	  --bppy_live;
-	  Py_DECREF (bp_obj);
 	}
     }
   PyGILState_Release (state);
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index cd2a9bb..3aaf7f9 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -95,14 +95,11 @@ cmdpy_dont_repeat (PyObject *self, PyObject *args)
 static void
 cmdpy_destroyer (struct cmd_list_element *self, void *context)
 {
-  cmdpy_object *cmd;
-
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
   /* Release our hold on the command object.  */
-  cmd = (cmdpy_object *) context;
+  gdbpy_ref<cmdpy_object> cmd ((cmdpy_object *) context);
   cmd->command = NULL;
-  Py_DECREF (cmd);
 
   /* We allocated the name, doc string, and perhaps the prefix
      name.  */
diff --git a/gdb/python/py-event.c b/gdb/python/py-event.c
index 161a5e1..127dcc7 100644
--- a/gdb/python/py-event.c
+++ b/gdb/python/py-event.c
@@ -30,21 +30,15 @@ evpy_dealloc (PyObject *self)
 PyObject *
 create_event_object (PyTypeObject *py_type)
 {
-  event_object *event_obj;
-
-  event_obj = PyObject_New (event_object, py_type);
-  if (!event_obj)
-    goto fail;
+  gdbpy_ref<event_object> event_obj (PyObject_New (event_object, py_type));
+  if (event_obj == NULL)
+    return NULL;
 
   event_obj->dict = PyDict_New ();
   if (!event_obj->dict)
-    goto fail;
-
-  return (PyObject*) event_obj;
+    return NULL;
 
- fail:
-  Py_XDECREF (event_obj);
-  return NULL;
+  return (PyObject*) event_obj.release ();
 }
 
 /* Add the attribute ATTR to the event object EVENT.  In
diff --git a/gdb/python/py-evtregistry.c b/gdb/python/py-evtregistry.c
index 81bf927..4d4045b 100644
--- a/gdb/python/py-evtregistry.c
+++ b/gdb/python/py-evtregistry.c
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "command.h"
 #include "py-events.h"
+#include "py-ref.h"
 
 events_object gdb_py_events;
 
@@ -79,22 +80,18 @@ evregpy_disconnect (PyObject *self, PyObject *function)
 eventregistry_object *
 create_eventregistry_object (void)
 {
-  eventregistry_object *eventregistry_obj;
+  gdbpy_ref<eventregistry_object>
+    eventregistry_obj (PyObject_New (eventregistry_object,
+				     &eventregistry_object_type));
 
-  eventregistry_obj = PyObject_New (eventregistry_object,
-                                    &eventregistry_object_type);
-
-  if (!eventregistry_obj)
+  if (eventregistry_obj == NULL)
     return NULL;
 
   eventregistry_obj->callbacks = PyList_New (0);
   if (!eventregistry_obj->callbacks)
-    {
-      Py_DECREF (eventregistry_obj);
-      return NULL;
-    }
+    return NULL;
 
-  return eventregistry_obj;
+  return eventregistry_obj.release ();
 }
 
 static void
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 8f5ddd0..891f44e 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -28,6 +28,7 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "user-regs.h"
+#include "py-ref.h"
 
 typedef struct {
   PyObject_HEAD
@@ -359,9 +360,8 @@ frapy_function (PyObject *self, PyObject *args)
 PyObject *
 frame_info_to_frame_object (struct frame_info *frame)
 {
-  frame_object *frame_obj;
-
-  frame_obj = PyObject_New (frame_object, &frame_object_type);
+  gdbpy_ref<frame_object> frame_obj (PyObject_New (frame_object,
+						   &frame_object_type));
   if (frame_obj == NULL)
     return NULL;
 
@@ -387,13 +387,12 @@ frame_info_to_frame_object (struct frame_info *frame)
     }
   CATCH (except, RETURN_MASK_ALL)
     {
-      Py_DECREF (frame_obj);
       gdbpy_convert_exception (except);
       return NULL;
     }
   END_CATCH
 
-  return (PyObject *) frame_obj;
+  return (PyObject *) frame_obj.release ();
 }
 
 /* Implementation of gdb.Frame.older (self) -> gdb.Frame.
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 0118caa..46a0aad 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -300,7 +300,6 @@ add_thread_object (struct thread_info *tp)
 static void
 delete_thread_object (struct thread_info *tp, int ignore)
 {
-  inferior_object *inf_obj;
   struct threadlist_entry **entry, *tmp;
 
   if (!gdb_python_initialized)
@@ -308,9 +307,9 @@ delete_thread_object (struct thread_info *tp, int ignore)
 
   gdbpy_enter enter_py (python_gdbarch, python_language);
 
-  inf_obj
-    = (inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid));
-  if (!inf_obj)
+  gdbpy_ref<inferior_object> inf_obj
+    ((inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid)));
+  if (inf_obj == NULL)
     return;
 
   /* Find thread entry in its inferior's thread_list.  */
@@ -320,10 +319,7 @@ delete_thread_object (struct thread_info *tp, int ignore)
       break;
 
   if (!*entry)
-    {
-      Py_DECREF (inf_obj);
-      return;
-    }
+    return;
 
   tmp = *entry;
   tmp->thread_obj->thread = NULL;
@@ -332,7 +328,6 @@ delete_thread_object (struct thread_info *tp, int ignore)
   inf_obj->nthreads--;
 
   Py_DECREF (tmp->thread_obj);
-  Py_DECREF (inf_obj);
   xfree (tmp);
 }
 
@@ -439,7 +434,6 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
 {
   CORE_ADDR addr, length;
   gdb_byte *buffer = NULL;
-  membuf_object *membuf_obj;
   PyObject *addr_obj, *length_obj, *result;
   static char *keywords[] = { "address", "length", NULL };
 
@@ -464,7 +458,8 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
     }
   END_CATCH
 
-  membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
+  gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
+						     &membuf_object_type));
   if (membuf_obj == NULL)
     {
       xfree (buffer);
@@ -476,12 +471,11 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
   membuf_obj->length = length;
 
 #ifdef IS_PY3K
-  result = PyMemoryView_FromObject ((PyObject *) membuf_obj);
+  result = PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
 #else
-  result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
+  result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj.get (), 0,
 					 Py_END_OF_BUFFER);
 #endif
-  Py_DECREF (membuf_obj);
 
   return result;
 }
@@ -769,7 +763,7 @@ infpy_dealloc (PyObject *obj)
 static void
 py_free_inferior (struct inferior *inf, void *datum)
 {
-  inferior_object *inf_obj = (inferior_object *) datum;
+  gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
   struct threadlist_entry *th_entry, *th_tmp;
 
   if (!gdb_python_initialized)
@@ -790,8 +784,6 @@ py_free_inferior (struct inferior *inf, void *datum)
     }
 
   inf_obj->nthreads = 0;
-
-  Py_DECREF ((PyObject *) inf_obj);
 }
 
 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
index 694fa09..105d88a 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -24,6 +24,7 @@
 #include "language.h"
 #include "build-id.h"
 #include "symtab.h"
+#include "py-ref.h"
 
 typedef struct
 {
@@ -227,18 +228,15 @@ objfpy_initialize (objfile_object *self)
 static PyObject *
 objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
 {
-  objfile_object *self = (objfile_object *) type->tp_alloc (type, 0);
+  gdbpy_ref<objfile_object> self ((objfile_object *) type->tp_alloc (type, 0));
 
-  if (self)
+  if (self != NULL)
     {
-      if (!objfpy_initialize (self))
-	{
-	  Py_DECREF (self);
-	  return NULL;
-	}
+      if (!objfpy_initialize (self.get ()))
+	return NULL;
     }
 
-  return (PyObject *) self;
+  return (PyObject *) self.release ();
 }
 
 PyObject *
@@ -612,11 +610,9 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
 static void
 py_free_objfile (struct objfile *objfile, void *datum)
 {
-  objfile_object *object = (objfile_object *) datum;
-
   gdbpy_enter enter_py (get_objfile_arch (objfile), current_language);
+  gdbpy_ref<objfile_object> object ((objfile_object *) datum);
   object->objfile = NULL;
-  Py_DECREF ((PyObject *) object);
 }
 
 /* Return a borrowed reference to the Python object of type Objfile
@@ -627,26 +623,22 @@ py_free_objfile (struct objfile *objfile, void *datum)
 PyObject *
 objfile_to_objfile_object (struct objfile *objfile)
 {
-  objfile_object *object;
-
-  object = (objfile_object *) objfile_data (objfile, objfpy_objfile_data_key);
-  if (!object)
+  gdbpy_ref<objfile_object> object
+    ((objfile_object *) objfile_data (objfile, objfpy_objfile_data_key));
+  if (object == NULL)
     {
-      object = PyObject_New (objfile_object, &objfile_object_type);
-      if (object)
+      object.reset (PyObject_New (objfile_object, &objfile_object_type));
+      if (object != NULL)
 	{
-	  if (!objfpy_initialize (object))
-	    {
-	      Py_DECREF (object);
-	      return NULL;
-	    }
+	  if (!objfpy_initialize (object.get ()))
+	    return NULL;
 
 	  object->objfile = objfile;
-	  set_objfile_data (objfile, objfpy_objfile_data_key, object);
+	  set_objfile_data (objfile, objfpy_objfile_data_key, object.get ());
 	}
     }
 
-  return (PyObject *) object;
+  return (PyObject *) object.release ();
 }
 
 int
diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
index b0d9458..1e06a75 100644
--- a/gdb/python/py-progspace.c
+++ b/gdb/python/py-progspace.c
@@ -24,6 +24,7 @@
 #include "objfiles.h"
 #include "language.h"
 #include "arch-utils.h"
+#include "py-ref.h"
 
 typedef struct
 {
@@ -128,18 +129,15 @@ pspy_initialize (pspace_object *self)
 static PyObject *
 pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
 {
-  pspace_object *self = (pspace_object *) type->tp_alloc (type, 0);
+  gdbpy_ref<pspace_object> self ((pspace_object *) type->tp_alloc (type, 0));
 
-  if (self)
+  if (self != NULL)
     {
-      if (!pspy_initialize (self))
-	{
-	  Py_DECREF (self);
-	  return NULL;
-	}
+      if (!pspy_initialize (self.get ()))
+	return NULL;
     }
 
-  return (PyObject *) self;
+  return (PyObject *) self.release ();
 }
 
 PyObject *
@@ -323,7 +321,6 @@ pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
 static void
 py_free_pspace (struct program_space *pspace, void *datum)
 {
-  pspace_object *object = (pspace_object *) datum;
   /* This is a fiction, but we're in a nasty spot: The pspace is in the
      process of being deleted, we can't rely on anything in it.  Plus
      this is one time when the current program space and current inferior
@@ -336,8 +333,8 @@ py_free_pspace (struct program_space *pspace, void *datum)
   struct gdbarch *arch = target_gdbarch ();
 
   gdbpy_enter enter_py (arch, current_language);
+  gdbpy_ref<pspace_object> object ((pspace_object *) datum);
   object->pspace = NULL;
-  Py_DECREF ((PyObject *) object);
 }
 
 /* Return a borrowed reference to the Python object of type Pspace
@@ -348,26 +345,22 @@ py_free_pspace (struct program_space *pspace, void *datum)
 PyObject *
 pspace_to_pspace_object (struct program_space *pspace)
 {
-  pspace_object *object;
-
-  object = (pspace_object *) program_space_data (pspace, pspy_pspace_data_key);
-  if (!object)
+  gdbpy_ref<pspace_object> object
+    ((pspace_object *) program_space_data (pspace, pspy_pspace_data_key));
+  if (object == NULL)
     {
-      object = PyObject_New (pspace_object, &pspace_object_type);
-      if (object)
+      object.reset (PyObject_New (pspace_object, &pspace_object_type));
+      if (object != NULL)
 	{
-	  if (!pspy_initialize (object))
-	    {
-	      Py_DECREF (object);
-	      return NULL;
-	    }
+	  if (!pspy_initialize (object.get ()))
+	    return NULL;
 
 	  object->pspace = pspace;
-	  set_program_space_data (pspace, pspy_pspace_data_key, object);
+	  set_program_space_data (pspace, pspy_pspace_data_key, object.get ());
 	}
     }
 
-  return (PyObject *) object;
+  return (PyObject *) object.release ();
 }
 
 int
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index 9fdb42f..09cab22 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -24,6 +24,7 @@
 #include "python-internal.h"
 #include "objfiles.h"
 #include "block.h"
+#include "py-ref.h"
 
 typedef struct stpy_symtab_object {
   PyObject_HEAD
@@ -436,19 +437,14 @@ symtab_to_symtab_object (struct symtab *symtab)
 PyObject *
 symtab_and_line_to_sal_object (struct symtab_and_line sal)
 {
-  sal_object *sal_obj;
-
-  sal_obj = PyObject_New (sal_object, &sal_object_type);
-  if (sal_obj)
+  gdbpy_ref<sal_object> sal_obj (PyObject_New (sal_object, &sal_object_type));
+  if (sal_obj != NULL)
     {
-      if (set_sal (sal_obj, sal) < 0)
-	{
-	  Py_DECREF (sal_obj);
-	  return NULL;
-	}
+      if (set_sal (sal_obj.get (), sal) < 0)
+	return NULL;
     }
 
-  return (PyObject *) sal_obj;
+  return (PyObject *) sal_obj.release ();
 }
 
 /* Return struct symtab_and_line reference that is wrapped by this
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 857c4e2..9c20582 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -130,18 +130,16 @@ field_dealloc (PyObject *obj)
 static PyObject *
 field_new (void)
 {
-  field_object *result = PyObject_New (field_object, &field_object_type);
+  gdbpy_ref<field_object> result (PyObject_New (field_object,
+						&field_object_type));
 
-  if (result)
+  if (result != NULL)
     {
       result->dict = PyDict_New ();
       if (!result->dict)
-	{
-	  Py_DECREF (result);
-	  result = NULL;
-	}
+	return NULL;
     }
-  return (PyObject *) result;
+  return (PyObject *) result.release ();
 }
 
 \f
-- 
2.9.3

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

* [RFA v2 5/7] Remove some gotos from Python
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
                   ` (2 preceding siblings ...)
  2017-02-09 21:25 ` [RFA v2 1/7] Remove some ui_out-related cleanups from Python Tom Tromey
@ 2017-02-09 21:25 ` Tom Tromey
  2017-02-09 21:25 ` [RFA v2 3/7] Use gdbpy_ref to simplify some logic Tom Tromey
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-09 21:25 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This patch slightly refactors a couple of spots in the Python code to
avoid some gotos.

2017-02-09  Tom Tromey  <tom@tromey.com>

	* python/python.c (do_start_initialization): New function, from
	_initialize_python.
	(_initialize_python): Call do_start_initialization.
	* python/py-linetable.c (ltpy_iternext): Use explicit returns, not
	goto.
---
 gdb/ChangeLog             |   8 ++
 gdb/python/py-linetable.c |  14 ++--
 gdb/python/python.c       | 192 ++++++++++++++++++++++++----------------------
 3 files changed, 115 insertions(+), 99 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 169c2f7..b00c095 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@
 2017-02-09  Tom Tromey  <tom@tromey.com>
 
+	* python/python.c (do_start_initialization): New function, from
+	_initialize_python.
+	(_initialize_python): Call do_start_initialization.
+	* python/py-linetable.c (ltpy_iternext): Use explicit returns, not
+	goto.
+
+2017-02-09  Tom Tromey  <tom@tromey.com>
+
 	* python/py-prettyprint.c (pretty_print_one_value): Use
 	gdbpy_ref.
 
diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c
index d8597e4..a5e57b0 100644
--- a/gdb/python/py-linetable.c
+++ b/gdb/python/py-linetable.c
@@ -407,7 +407,10 @@ ltpy_iternext (PyObject *self)
   LTPY_REQUIRE_VALID (iter_obj->source, symtab);
 
   if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
-    goto stop_iteration;
+    {
+      PyErr_SetNone (PyExc_StopIteration);
+      return NULL;
+    }
 
   item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
 
@@ -419,7 +422,10 @@ ltpy_iternext (PyObject *self)
 
       /* Exit if the internal value is the last item in the line table.  */
       if (iter_obj->current_index >= SYMTAB_LINETABLE (symtab)->nitems)
-	goto stop_iteration;
+	{
+	  PyErr_SetNone (PyExc_StopIteration);
+	  return NULL;
+	}
       item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
     }
 
@@ -427,10 +433,6 @@ ltpy_iternext (PyObject *self)
   iter_obj->current_index++;
 
   return obj;
-
- stop_iteration:
-  PyErr_SetNone (PyExc_StopIteration);
-  return NULL;
 }
 
 /* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 74a6f42..1f5ab42 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1525,8 +1525,10 @@ finalize_python (void *ignore)
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 extern initialize_file_ftype _initialize_python;
 
-void
-_initialize_python (void)
+#ifdef HAVE_PYTHON
+
+static bool
+do_start_initialization ()
 {
   char *progname;
 #ifdef IS_PY3K
@@ -1536,77 +1538,6 @@ _initialize_python (void)
   wchar_t *progname_copy;
 #endif
 
-  add_com ("python-interactive", class_obscure,
-	   python_interactive_command,
-#ifdef HAVE_PYTHON
-	   _("\
-Start an interactive Python prompt.\n\
-\n\
-To return to GDB, type the EOF character (e.g., Ctrl-D on an empty\n\
-prompt).\n\
-\n\
-Alternatively, a single-line Python command can be given as an\n\
-argument, and if the command is an expression, the result will be\n\
-printed.  For example:\n\
-\n\
-    (gdb) python-interactive 2 + 3\n\
-    5\n\
-")
-#else /* HAVE_PYTHON */
-	   _("\
-Start a Python interactive prompt.\n\
-\n\
-Python scripting is not supported in this copy of GDB.\n\
-This command is only a placeholder.")
-#endif /* HAVE_PYTHON */
-	   );
-  add_com_alias ("pi", "python-interactive", class_obscure, 1);
-
-  add_com ("python", class_obscure, python_command,
-#ifdef HAVE_PYTHON
-	   _("\
-Evaluate a Python command.\n\
-\n\
-The command can be given as an argument, for instance:\n\
-\n\
-    python print 23\n\
-\n\
-If no argument is given, the following lines are read and used\n\
-as the Python commands.  Type a line containing \"end\" to indicate\n\
-the end of the command.")
-#else /* HAVE_PYTHON */
-	   _("\
-Evaluate a Python command.\n\
-\n\
-Python scripting is not supported in this copy of GDB.\n\
-This command is only a placeholder.")
-#endif /* HAVE_PYTHON */
-	   );
-  add_com_alias ("py", "python", class_obscure, 1);
-
-  /* Add set/show python print-stack.  */
-  add_prefix_cmd ("python", no_class, user_show_python,
-		  _("Prefix command for python preference settings."),
-		  &user_show_python_list, "show python ", 0,
-		  &showlist);
-
-  add_prefix_cmd ("python", no_class, user_set_python,
-		  _("Prefix command for python preference settings."),
-		  &user_set_python_list, "set python ", 0,
-		  &setlist);
-
-  add_setshow_enum_cmd ("print-stack", no_class, python_excp_enums,
-			&gdbpy_should_print_stack, _("\
-Set mode for Python stack dump on error."), _("\
-Show the mode of Python stack printing on error."), _("\
-none  == no stack or message will be printed.\n\
-full == a message and a stack will be printed.\n\
-message == an error message without a stack will be printed."),
-			NULL, NULL,
-			&user_set_python_list,
-			&user_show_python_list);
-
-#ifdef HAVE_PYTHON
 #ifdef WITH_PYTHON_PATH
   /* Work around problem where python gets confused about where it is,
      and then can't find its libraries, etc.
@@ -1625,14 +1556,14 @@ message == an error message without a stack will be printed."),
     {
       xfree (oldloc);
       fprintf (stderr, "out of memory\n");
-      return;
+      return false;
     }
   count = mbstowcs (progname_copy, progname, progsize + 1);
   if (count == (size_t) -1)
     {
       xfree (oldloc);
       fprintf (stderr, "Could not convert python path to string\n");
-      return;
+      return false;
     }
   setlocale (LC_ALL, oldloc);
   xfree (oldloc);
@@ -1657,7 +1588,7 @@ message == an error message without a stack will be printed."),
   gdb_module = Py_InitModule ("_gdb", python_GdbMethods);
 #endif
   if (gdb_module == NULL)
-    goto fail;
+    return false;
 
   /* The casts to (char*) are for python 2.4.  */
   if (PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version) < 0
@@ -1665,31 +1596,31 @@ message == an error message without a stack will be printed."),
 				     (char*) host_name) < 0
       || PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG",
 				     (char*) target_name) < 0)
-    goto fail;
+    return false;
 
   /* Add stream constants.  */
   if (PyModule_AddIntConstant (gdb_module, "STDOUT", 0) < 0
       || PyModule_AddIntConstant (gdb_module, "STDERR", 1) < 0
       || PyModule_AddIntConstant (gdb_module, "STDLOG", 2) < 0)
-    goto fail;
+    return false;
 
   gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL);
   if (gdbpy_gdb_error == NULL
       || gdb_pymodule_addobject (gdb_module, "error", gdbpy_gdb_error) < 0)
-    goto fail;
+    return false;
 
   gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError",
 					       gdbpy_gdb_error, NULL);
   if (gdbpy_gdb_memory_error == NULL
       || gdb_pymodule_addobject (gdb_module, "MemoryError",
 				 gdbpy_gdb_memory_error) < 0)
-    goto fail;
+    return false;
 
   gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL);
   if (gdbpy_gdberror_exc == NULL
       || gdb_pymodule_addobject (gdb_module, "GdbError",
 				 gdbpy_gdberror_exc) < 0)
-    goto fail;
+    return false;
 
   gdbpy_initialize_gdb_readline ();
 
@@ -1730,26 +1661,26 @@ message == an error message without a stack will be printed."),
       || gdbpy_initialize_arch () < 0
       || gdbpy_initialize_xmethods () < 0
       || gdbpy_initialize_unwind () < 0)
-    goto fail;
+    return false;
 
   gdbpy_to_string_cst = PyString_FromString ("to_string");
   if (gdbpy_to_string_cst == NULL)
-    goto fail;
+    return false;
   gdbpy_children_cst = PyString_FromString ("children");
   if (gdbpy_children_cst == NULL)
-    goto fail;
+    return false;
   gdbpy_display_hint_cst = PyString_FromString ("display_hint");
   if (gdbpy_display_hint_cst == NULL)
-    goto fail;
+    return false;
   gdbpy_doc_cst = PyString_FromString ("__doc__");
   if (gdbpy_doc_cst == NULL)
-    goto fail;
+    return false;
   gdbpy_enabled_cst = PyString_FromString ("enabled");
   if (gdbpy_enabled_cst == NULL)
-    goto fail;
+    return false;
   gdbpy_value_cst = PyString_FromString ("value");
   if (gdbpy_value_cst == NULL)
-    goto fail;
+    return false;
 
   /* Release the GIL while gdb runs.  */
   PyThreadState_Swap (NULL);
@@ -1757,14 +1688,89 @@ message == an error message without a stack will be printed."),
 
   make_final_cleanup (finalize_python, NULL);
 
+  /* Only set this when initialization has succeeded.  */
   gdb_python_initialized = 1;
-  return;
+  return true;
+}
+
+#endif /* HAVE_PYTHON */
+
+void
+_initialize_python (void)
+{
+  add_com ("python-interactive", class_obscure,
+	   python_interactive_command,
+#ifdef HAVE_PYTHON
+	   _("\
+Start an interactive Python prompt.\n\
+\n\
+To return to GDB, type the EOF character (e.g., Ctrl-D on an empty\n\
+prompt).\n\
+\n\
+Alternatively, a single-line Python command can be given as an\n\
+argument, and if the command is an expression, the result will be\n\
+printed.  For example:\n\
+\n\
+    (gdb) python-interactive 2 + 3\n\
+    5\n\
+")
+#else /* HAVE_PYTHON */
+	   _("\
+Start a Python interactive prompt.\n\
+\n\
+Python scripting is not supported in this copy of GDB.\n\
+This command is only a placeholder.")
+#endif /* HAVE_PYTHON */
+	   );
+  add_com_alias ("pi", "python-interactive", class_obscure, 1);
+
+  add_com ("python", class_obscure, python_command,
+#ifdef HAVE_PYTHON
+	   _("\
+Evaluate a Python command.\n\
+\n\
+The command can be given as an argument, for instance:\n\
+\n\
+    python print 23\n\
+\n\
+If no argument is given, the following lines are read and used\n\
+as the Python commands.  Type a line containing \"end\" to indicate\n\
+the end of the command.")
+#else /* HAVE_PYTHON */
+	   _("\
+Evaluate a Python command.\n\
+\n\
+Python scripting is not supported in this copy of GDB.\n\
+This command is only a placeholder.")
+#endif /* HAVE_PYTHON */
+	   );
+  add_com_alias ("py", "python", class_obscure, 1);
+
+  /* Add set/show python print-stack.  */
+  add_prefix_cmd ("python", no_class, user_show_python,
+		  _("Prefix command for python preference settings."),
+		  &user_show_python_list, "show python ", 0,
+		  &showlist);
 
- fail:
-  gdbpy_print_stack ();
-  /* Do not set 'gdb_python_initialized'.  */
-  return;
+  add_prefix_cmd ("python", no_class, user_set_python,
+		  _("Prefix command for python preference settings."),
+		  &user_set_python_list, "set python ", 0,
+		  &setlist);
 
+  add_setshow_enum_cmd ("print-stack", no_class, python_excp_enums,
+			&gdbpy_should_print_stack, _("\
+Set mode for Python stack dump on error."), _("\
+Show the mode of Python stack printing on error."), _("\
+none  == no stack or message will be printed.\n\
+full == a message and a stack will be printed.\n\
+message == an error message without a stack will be printed."),
+			NULL, NULL,
+			&user_set_python_list,
+			&user_show_python_list);
+
+#ifdef HAVE_PYTHON
+  if (!do_start_initialization () && PyErr_Occurred ())
+    gdbpy_print_stack ();
 #endif /* HAVE_PYTHON */
 }
 
-- 
2.9.3

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

* Re: [RFA v2 1/7] Remove some ui_out-related cleanups from Python
  2017-02-09 21:25 ` [RFA v2 1/7] Remove some ui_out-related cleanups from Python Tom Tromey
@ 2017-02-10 15:57   ` Simon Marchi
  2017-02-10 19:18     ` Tom Tromey
  0 siblings, 1 reply; 13+ messages in thread
From: Simon Marchi @ 2017-02-10 15:57 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 2017-02-09 16:24, Tom Tromey wrote:
> This patch introduces a bit of infrastructure -- namely, a minimal
> std::optional analogue called gdb::optional, and an RAII template
> class that works like make_cleanup_ui_out_tuple_begin_end or
> make_cleanup_ui_out_list_begin_end -- and then uses these in the
> Python code.  This removes a number of cleanups and generally
> simplifies this code.
> 
> std::optional is only available in C++17.  Normally I would have had
> this code check __cplusplus, but my gcc apparently isn't new enough to
> find <optional>, even with -std=c++1z; so, because I could not test
> it, the patch does not do this.

I am curious what are the differences between using an std::optional and 
a std::unique_ptr.  Obviously

   std::optional<Foo> opt;
   std::unique_ptr<Foo> ptr;

   opt.emplace (arg);
   ptr.reset (new Foo (arg));

The obvious one is stack memory allocation for optional and heap for 
unique_ptr, but apart from that, any difference in the functionality?

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

* Re: [RFA v2 0/7] more cleanup removal in Python
  2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
                   ` (6 preceding siblings ...)
  2017-02-09 21:25 ` [RFA v2 6/7] Remove unnecessary local variables Tom Tromey
@ 2017-02-10 16:21 ` Simon Marchi
  2017-02-10 16:36   ` Pedro Alves
  7 siblings, 1 reply; 13+ messages in thread
From: Simon Marchi @ 2017-02-10 16:21 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 2017-02-09 16:24, Tom Tromey wrote:
> This is version 2 of my cleanup removal patch for the Python code.
> 
> Version 1 is here:
> https://sourceware.org/ml/gdb-patches/2017-01/msg00279.html
> 
> I think this version addresses all the review comments; but there are
> some other changes from v1:
> 
> * As discussed, use gdbpy_ref<> to wrap PyObject*; the old
>   "gdbpy_subclass" is now just a different instantiation of gdbpy_ref.
>   The initial work for this is done in a new patch (patch #2 in this
>   series), for clarity.
> 
> * Drop the ui_file_up patch, as this was done in a better way by
>   Pedro.
> 
> * Add a couple of obvious patches for issues I found while working on
>   this again: remove a couple of unused local variables, and fix a
>   couple of Python test cases.
> 
> * Fix one instance of the "declare gdbpy_ref object before a
>   gdbpy_enter object" bug that I found while re-reviewing the patch in
>   this series that adds some gdbpy_ref uses.
> 
> I built and tested the series locally; but I'm also running it through
> the buildbot.
> 
> Let me know what you think.
> 
> Tom

This series looks good to me.

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

* Re: [RFA v2 0/7] more cleanup removal in Python
  2017-02-10 16:21 ` [RFA v2 0/7] more cleanup removal in Python Simon Marchi
@ 2017-02-10 16:36   ` Pedro Alves
  2017-02-10 19:18     ` Tom Tromey
  0 siblings, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2017-02-10 16:36 UTC (permalink / raw)
  To: Simon Marchi, Tom Tromey; +Cc: gdb-patches

On 02/10/2017 04:20 PM, Simon Marchi wrote:
> On 2017-02-09 16:24, Tom Tromey wrote:
>> Let me know what you think.
> 
> This series looks good to me.

To me too.

Thanks,
Pedro Alves

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

* Re: [RFA v2 1/7] Remove some ui_out-related cleanups from Python
  2017-02-10 15:57   ` Simon Marchi
@ 2017-02-10 19:18     ` Tom Tromey
  0 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-10 19:18 UTC (permalink / raw)
  To: Simon Marchi; +Cc: Tom Tromey, gdb-patches

>>>>> "Simon" == Simon Marchi <simon.marchi@polymtl.ca> writes:

Simon> I am curious what are the differences between using an
Simon> std::optional and a std::unique_ptr.
[...]
Simon> The obvious one is stack memory allocation for optional and heap for
Simon> unique_ptr, but apart from that, any difference in the functionality?

No, they're basically equivalent.

Tom

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

* Re: [RFA v2 0/7] more cleanup removal in Python
  2017-02-10 16:36   ` Pedro Alves
@ 2017-02-10 19:18     ` Tom Tromey
  0 siblings, 0 replies; 13+ messages in thread
From: Tom Tromey @ 2017-02-10 19:18 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Simon Marchi, Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

>> This series looks good to me.

Pedro> To me too.

Thanks to both of you.  The buildbot results looked reasonable so I am
going to push it.

Tom

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

end of thread, other threads:[~2017-02-10 19:18 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-09 21:25 [RFA v2 0/7] more cleanup removal in Python Tom Tromey
2017-02-09 21:25 ` [RFA v2 2/7] Turn gdbpy_ref into a template Tom Tromey
2017-02-09 21:25 ` [RFA v2 4/7] Change one more spot to use gdbpy_ref Tom Tromey
2017-02-09 21:25 ` [RFA v2 1/7] Remove some ui_out-related cleanups from Python Tom Tromey
2017-02-10 15:57   ` Simon Marchi
2017-02-10 19:18     ` Tom Tromey
2017-02-09 21:25 ` [RFA v2 5/7] Remove some gotos " Tom Tromey
2017-02-09 21:25 ` [RFA v2 3/7] Use gdbpy_ref to simplify some logic Tom Tromey
2017-02-09 21:25 ` [RFA v2 7/7] Fix Python test to use lowercase command Tom Tromey
2017-02-09 21:25 ` [RFA v2 6/7] Remove unnecessary local variables Tom Tromey
2017-02-10 16:21 ` [RFA v2 0/7] more cleanup removal in Python Simon Marchi
2017-02-10 16:36   ` Pedro Alves
2017-02-10 19:18     ` 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).