From patchwork Sun Jan 15 13:42:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 18907 Received: (qmail 127626 invoked by alias); 15 Jan 2017 13:43:14 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 127429 invoked by uid 89); 15 Jan 2017 13:43:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=*cleanup, HX-HELO:sk:gproxy6, CATCH, H*RU:67.222.39.168 X-HELO: gproxy6-pub.mail.unifiedlayer.com Received: from gproxy6-pub.mail.unifiedlayer.com (HELO gproxy6-pub.mail.unifiedlayer.com) (67.222.39.168) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with SMTP; Sun, 15 Jan 2017 13:43:02 +0000 Received: (qmail 17512 invoked by uid 0); 15 Jan 2017 13:43:00 -0000 Received: from unknown (HELO cmgw3) (10.0.90.84) by gproxy6.mail.unifiedlayer.com with SMTP; 15 Jan 2017 13:43:00 -0000 Received: from box522.bluehost.com ([74.220.219.122]) by cmgw3 with id Ydix1u0012f2jeq01dj0Rx; Sun, 15 Jan 2017 06:43:00 -0700 X-Authority-Analysis: v=2.1 cv=YuCcGeoX c=1 sm=1 tr=0 a=GsOEXm/OWkKvwdLVJsfwcA==:117 a=GsOEXm/OWkKvwdLVJsfwcA==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=IgFoBzBjUZAA:10 a=zstS-IiYAAAA:8 a=KKAkSRfTAAAA:8 a=mDV3o1hIAAAA:8 a=qHApTrgb8RKrqPnAAvgA:9 a=pMK7q_H4_orHzxId:21 a=516ytvtY_krx_T4z:21 a=4G6NA9xxw8l3yy4pmD5M:22 a=cvBusfyB2V15izCimMoJ:22 a=_FVE-zBwftR9WsbkzFJk:22 Received: from 174-16-146-181.hlrn.qwest.net ([174.16.146.181]:40602 helo=bapiya.Home) by box522.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.87) (envelope-from ) id 1cSl5E-0002Lj-HA; Sun, 15 Jan 2017 06:42:56 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [RFA 1/5] Remove some ui_out-related cleanups from Python Date: Sun, 15 Jan 2017 06:42:49 -0700 Message-Id: <20170115134253.24018-2-tom@tromey.com> In-Reply-To: <20170115134253.24018-1-tom@tromey.com> References: <20170115134253.24018-1-tom@tromey.com> X-BWhitelist: no X-Exim-ID: 1cSl5E-0002Lj-HA X-Source-Sender: 174-16-146-181.hlrn.qwest.net (bapiya.Home) [174.16.146.181]:40602 X-Source-Auth: tom+tromey.com X-Email-Count: 2 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTIyLmJsdWVob3N0LmNvbQ== 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 , even with -std=c++1z; so, because I could not test it, the patch does not do this. 2017-01-15 Tom Tromey * 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_option.h: New file. --- gdb/ChangeLog | 13 +++ gdb/common/gdb_option.h | 87 ++++++++++++++++++ gdb/python/py-framefilter.c | 213 ++++++++++++-------------------------------- gdb/ui-out.h | 33 +++++++ 4 files changed, 189 insertions(+), 157 deletions(-) create mode 100644 gdb/common/gdb_option.h diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 39d66b8..8a2848f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2017-01-15 Tom Tromey + + * 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_option.h: New file. + 2017-01-13 Yao Qi * remote.c (REMOTE_DEBUG_MAX_CHAR): New macro. diff --git a/gdb/common/gdb_option.h b/gdb/common/gdb_option.h new file mode 100644 index 0000000..e2ac107 --- /dev/null +++ b/gdb/common/gdb_option.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 . */ + +#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 stack allocation is + guaranteed. */ +template +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 &operator= (const optional &other) = delete; + + template + void emplace (Args &&... args) + { + if (m_instantiated) + destroy (); + new (&m_item) T (std::forward(args)...); + m_instantiated = true; + } + +private: + + /* Destroy the object. */ + void destroy () + { + gdb_assert (m_instantiated); + m_instantiated = false; + m_item.~T (); + } + + /* True if the object was ever emplaced. */ + bool m_instantiated; + + /* The object. */ + union + { + struct { } m_dummy; + T m_item; + }; +}; + +} + +#endif /* GDB_OPTIONAL_H */ diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index bdd9911..ae5197a 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_option.h" enum mi_print_types { @@ -373,7 +374,7 @@ py_print_single_arg (struct ui_out *out, TRY { - struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); + gdb::optional 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 @@ -384,7 +385,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 (); @@ -394,9 +395,10 @@ py_print_single_arg (struct ui_out *out, if (fa != NULL) { struct ui_file *stb; + struct cleanup *cleanup; stb = mem_fileopen (); - make_cleanup_ui_file_delete (stb); + cleanup = make_cleanup_ui_file_delete (stb); fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym), SYMBOL_LANGUAGE (fa->sym), DMGL_PARAMS | DMGL_ANSI); @@ -414,6 +416,7 @@ py_print_single_arg (struct ui_out *out, fputs_filtered ("@entry", stb); } out->field_stream ("name", stb); + do_cleanups (cleanup); } else /* Otherwise, just output the name. */ @@ -433,10 +436,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) @@ -466,8 +466,6 @@ py_print_single_arg (struct ui_out *out, retval = EXT_LANG_BT_ERROR; } } - - do_cleanups (cleanups); } } CATCH (except, RETURN_MASK_ERROR) @@ -707,35 +705,24 @@ enumerate_locals (PyObject *iter, struct symbol *sym; struct block *sym_block; int local_indent = 8 + (8 * indent); - struct cleanup *locals_cleanups; + gdb::optional 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) @@ -747,8 +734,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 } @@ -759,7 +745,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 { @@ -777,18 +763,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 @@ -799,10 +781,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 { @@ -810,15 +789,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"); @@ -826,7 +800,7 @@ enumerate_locals (PyObject *iter, CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); - goto error; + return EXT_LANG_BT_ERROR; } END_CATCH } @@ -834,7 +808,6 @@ enumerate_locals (PyObject *iter, if (!PyErr_Occurred ()) return EXT_LANG_BT_OK; - error: return EXT_LANG_BT_ERROR; } @@ -847,8 +820,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; @@ -857,24 +828,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 @@ -888,25 +854,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 @@ -920,13 +879,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 { @@ -937,14 +894,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 { @@ -954,16 +911,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 @@ -990,7 +942,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 function_to_free; @@ -1034,12 +985,12 @@ py_print_frame (PyObject *filter, int flags, return EXT_LANG_BT_COMPLETED; } - cleanup_stack = make_cleanup (null_cleanup, NULL); + gdb::optional 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) { @@ -1054,7 +1005,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 @@ -1067,18 +1017,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; } @@ -1117,7 +1061,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 @@ -1139,7 +1082,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 @@ -1152,20 +1094,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 (); } @@ -1175,10 +1111,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) @@ -1189,7 +1122,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; } @@ -1204,7 +1136,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 @@ -1217,10 +1148,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. */ @@ -1233,7 +1161,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 @@ -1243,10 +1170,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) { @@ -1254,10 +1178,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 { @@ -1270,7 +1191,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 @@ -1283,19 +1203,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 { @@ -1306,7 +1220,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 @@ -1326,7 +1239,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 @@ -1336,26 +1248,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++; @@ -1370,20 +1276,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 b8bea97..7d5a1fc 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 +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 &) = delete; + ui_out_emit_type &operator= (const ui_out_emit_type &) + = delete; + +private: + + struct ui_out *m_uiout; +}; + +typedef ui_out_emit_type ui_out_emit_tuple; +typedef ui_out_emit_type ui_out_emit_list; + #endif /* UI_OUT_H */