[v2] Class-ify ui_out

Message ID 20161212161529.25127-1-simon.marchi@polymtl.ca
State New, archived
Headers

Commit Message

Simon Marchi Dec. 12, 2016, 4:15 p.m. UTC
  This is a merged version of the last two patches of the series
originally posted here:

  https://sourceware.org/ml/gdb-patches/2016-11/msg00744.html

I labeled it v2 even though it doesn't map directly to a previous
patch.

This patch finalizes the C++ conversion of the ui-out subsystem, by
turning the ui_out and ui_out_impl structures into a single class
hierarchy.  ui_out functions are turned into virtual methods of that new
class, so as a result there are a lot of call sites to update.

In the previous version of the patchset, there were separate ui_out and
ui_out_impl classes, but it wasn't really useful and added boilerplate.
In this version there is simply an ui_out base class that is
extended for CLI, TUI and MI.

It's a bit hard to maintain a ChangeLog for such a big patch, I did my
best but I'm sure there are some missing or outdated info in there...

gdb/ChangeLog:

	* ui-out.h (ui_out_begin, ui_out_end, ui_out_table_header,
	ui_out_table_body,  ui_out_field_int, ui_out_field_fmt_int,
	ui_out_field_core_addr, ui_out_field_string, ui_out_field_stream,
	ui_out_field_fmt, ui_out_field_skip, ui_out_spaces, ui_out_text,
	ui_out_message, ui_out_wrap_hint, ui_out_flush, ui_out_test_flags,
	ui_out_query_field, ui_out_is_mi_like_p, ui_out_redirect):
	Remove, replace with a method in class ui_out.
	(table_begin_ftype): Remove, replace with pure virtual method in
	class ui_out.
	(table_body_ftype): Likewise.
	(table_end_ftype): Likewise.
	(table_header_ftype): Likewise.
	(ui_out_begin_ftype): Likewise.
	(ui_out_end_ftype): Likewise.
	(field_int_ftype): Likewise.
	(field_skip_ftype): Likewise.
	(field_string_ftype): Likewise.
	(field_fmt_ftype): Likewise.
	(spaces_ftype): Likewise.
	(text_ftype): Likewise.
	(message_ftype): Likewise.
	(wrap_hint_ftype): Likewise.
	(flush_ftype): Likewise.
	(redirect_ftype): Likewise.
	(data_destroy_ftype): Likewise.
	(struct ui_out_impl): Remove, replace with class ui_out.
	(ui_out_new): Remove.
	(class ui_out): New class.
	* ui-out.c (struct ui_out): Remove, replaced with class ui_out.
	(current_level): Remove, replace with ui_out method.
	(push_level): Likewise.
	(pop_level): Likewise.
	(uo_table_begin, uo_table_body, uo_table_end, uo_table_header,
	uo_begin, uo_end, uo_field_int, uo_field_skip, uo_field_fmt,
	uo_spaces, uo_text, uo_message, uo_wrap_hint, uo_flush,
	uo_redirect, uo_field_string): Remove.
	(ui_out_table_begin): Replace with ...
	(ui_out::table_begin): ... this.
	(ui_out_table_body): Replace with ...
	(ui_out::table_body): ... this.
	(ui_out_table_end): Replace with ...
	(ui_out::table_end): ... this.
	(ui_out_table_header): Replace with ...
	(ui_out::table_header): ... this.
	(ui_out_begin): Replace with ...
	(ui_out::begin): ... this.
	(ui_out_end): Replace with ...
	(ui_out::end): ... this.
	(ui_out_field_int): Replace with ...
	(ui_out::field_int): ... this.
	(ui_out_field_fmt_int): Replace with ...
	(ui_out::field_fmt_int): ... this.
	(ui_out_field_core_addr): Replace with ...
	(ui_out::field_core_addr): ... this.
	(ui_out_field_stream): Replace with ...
	(ui_out::field_stream): ... this.
	(ui_out_field_skip): Replace with ...
	(ui_out::field_skip): ... this.
	(ui_out_field_string): Replace with ...
	(ui_out::field_string): ... this.
	(ui_out_field_fmt): Replace with ...
	(ui_out::field_fmt): ... this.
	(ui_out_spaces): Replace with ...
	(ui_out::spaces): ... this.
	(ui_out_text): Replace with ...
	(ui_out::text): ... this.
	(ui_out_message): Replace with ...
	(ui_out::message): ... this.
	(ui_out_wrap_hint): Replace with ...
	(ui_out::wrap_hint): ... this.
	(ui_out_flush): Replace with ...
	(ui_out::flush): ... this.
	(ui_out_redirect): Replace with ...
	(ui_out::redirect): ... this.
	(ui_out_test_flags): Replace with ...
	(ui_out::test_flags): ... this.
	(ui_out_is_mi_like_p): Replace with ...
	(ui_out::is_mi_like_p): ... this.
	(verify_field): Replace with ...
	(ui_out::verify_field): ... this.
	(ui_out_query_field): Replace with ...
	(ui_out::query_table_field): ... this.
	(ui_out_data): Remove.
	(ui_out_new): Remove, replace with ...
	(ui_out::ui_out): ... this constructor.
	(do_cleanup_table_end, make_cleanup_ui_out_tuple_begin_end,
	do_cleanup_end, make_cleanup_ui_out_tuple_begin_end,
	make_cleanup_ui_out_list_begin_end): Update fallouts of struct
	ui_out -> class ui_out change.
	* cli-out.c (cli_out_data): Remove.
	(cli_uiout_dtor): Remove.
	(cli_table_begin): Replace with ...
	(cli_ui_out::do_table_begin): ... this new method.
	(cli_table_body): Replace with ...
	(cli_ui_out::do_table_body): ... this new method.
	(cli_table_end): Replace with ...
	(cli_ui_out::do_table_end): ... this new method.
	(cli_table_header): Replace with ...
	(cli_ui_out::do_table_header): ... this new method.
	(cli_begin): Replace with ...
	(cli_ui_out::do_begin): ... this new method.
	(cli_end): Replace with ...
	(cli_ui_out::do_end): ... this new method.
	(cli_field_int): Replace with ...
	(cli_ui_out::do_field_int): ... this new method.
	(cli_field_skip): Replace with ...
	(cli_ui_out::do_field_skip): ... this new method.
	(cli_field_string): Replace with ...
	(cli_ui_out::do_field_string): ... this new method.
	(cli_field_fmt): Replace with ...
	(cli_ui_out::do_field_fmt): ... this new method.
	(cli_spaces): Replace with ...
	(cli_ui_out::do_spaces): ... this new method.
	(cli_text): Replace with ...
	(cli_ui_out::do_text): ... this new method.
	(cli_message): Replace with ...
	(cli_ui_out::do_message): ... this new method.
	(cli_wrap_hint): Replace with ...
	(cli_ui_out::do_wrap_hint): ... this new method.
	(cli_flush): Replace with ...
	(cli_ui_out::do_flush): ... this new method.
	(cli_redirect): Replace with ...
	(cli_ui_out::do_redirect): ... this new method.
	(out_field_fmt): Replace with ...
	(cli_ui_out::out_field_fmt): ... this new method.
	(field_separator): Replace with ...
	(cli_ui_out::field_separator): ... this new method.
	(cli_out_set_stream): Replace with ...
	(cli_ui_out::set_stream): ... this new method.
	(cli_ui_out_impl): Remove.
	(cli_out_data_ctor): Remove.
	(cli_ui_out_impl::cli_ui_out_impl): New constructor.
	(cli_ui_out_impl::~cli_ui_out_impl): New destructor.
	(cli_out_new): Change return type to cli_ui_out *, instantiate a
	cli_ui_out.
	* cli-out.h (cli_ui_out_data): Remove, replace with class
	cli_ui_out.
	(class cli_ui_out): New class.
	(cli_ui_out_impl): Remove.
	(cli_out_data_ctor): Remove.
	(cli_out_new): Change return type to cli_ui_out*.
	(cli_out_set_stream): Remove.
	* cli/cli-interp.c (struct cli_interp) <cli_uiout>: Change type
	to cli_ui_out*.
	(cli_interpreter_resume): Adapt.
	(cli_interpreter_exec): Adapt.
	* mi/mi-out.c (mi_ui_out_data, mi_out_data): Remove.
	(mi_ui_out_impl): Remove.
	(mi_table_begin): Replace with ...
	(mi_ui_out::do_table_begin): ... this.
	(mi_table_body): Replace with ...
	(mi_ui_out::do_table_body): ... this.
	(mi_table_end): Replace with ...
	(mi_ui_out::do_table_end): ... this.
	(mi_table_header): Replace with ...
	(mi_ui_out::do_table_header): ... this.
	(mi_begin): Replace with ...
	(mi_ui_out::do_begin): ... this.
	(mi_end): Replace with ...
	(mi_ui_out::do_end): ... this.
	(mi_field_int): Replace with ...
	(mi_ui_out::do_field_int): ... this.
	(mi_field_skip): Replace with ...
	(mi_ui_out::do_field_skip): ... this.
	(mi_field_string): Replace with ...
	(mi_ui_out::do_field_string): ... this.
	(mi_field_fmt): Replace with ...
	(mi_ui_out::do_field_fmt): ... this.
	(mi_spaces): Replace with ...
	(mi_ui_out::do_spaces): ... this.
	(mi_text): Replace with ...
	(mi_ui_out::do_text): ... this.
	(mi_message): Replace with ...
	(mi_ui_out::do_message): ... this.
	(mi_wrap_hint): Replace with ...
	(mi_ui_out::do_wrap_hint): ... this.
	(mi_flush): Replace with ...
	(mi_ui_out::do_flush): ... this.
	(mi_redirect): Replace with ...
	(mi_ui_out::do_redirect):
	(field_separator): Replace with ...
	(mi_ui_out::field_separator):
	(mi_open): Replace with ...
	(mi_ui_out::open): ... this.
	(mi_close): Replace with ...
	(mi_ui_out::close): ... this.
	(mi_out_rewind): Replace with ...
	(mi_ui_out::rewind): ... this.
	(mi_out_put): Replace with ...
	(mi_ui_out::put): ... this.
	(mi_version): Replace with ...
	(mi_ui_out::version): ... this.
	(mi_out_data_ctor): Replace with ...
	(mi_ui_out::mi_ui_out): ... this.
	(mi_out_data_dtor): Replace with ...
	(mi_ui_out::~mi_ui_out): ... this.
	(mi_out_new): Change return type to mi_ui_out*, instantiate
	an mi_ui_out object.
	(as_mi_ui_out): New function.
	(mi_version): Update fallouts of struct ui_out to class ui_out
	transition.
	(mi_out_put): Likewise.
	(mi_out_rewind): Likewise.
	* mi/mi-out.h (mi_out_new): Change return type to mi_ui_out*.
	* tui/tui-out.c (tui_ui_out_data, tui_out_data, tui_ui_out_impl):
	Remove.
	(tui_field_int): Replace with ...
	(tui_ui_out::do_field_int): ... this.
	(tui_field_string): Replace with ...
	(tui_ui_out::do_field_string): ... this.
	(tui_field_fmt): Replace with ...
	(tui_ui_out::do_field_fmt): ... this.
	(tui_text): Replace with ...
	(tui_ui_out::do_text): ... this.
	(tui_out_new): Change return type to tui_ui_out*, instantiate
	tui_ui_out object.
	(tui_ui_out::tui_ui_out): New.
	* tui/tui-out.h: New file.
	* tui/tui.h (tui_out_new): Move declaration to tui/tui-out.h.
	* tui/tui-io.c: Include tui/tui-out.h.
	(tui_old_uiout): Change type to cli_ui_out*.
	(tui_setup_io): Use dynamic_cast.
	* tui/tui-io.h (tui_old_uiout): Change type to cli_ui_out*.
	* tui/tui-interp.c (tui_resume): Adapt.
	* ada-lang.c (print_it_exception): Update fallouts of struct
	ui_out to class ui_out transition.
	(print_one_exception): Likewise.
	(print_mention_exception): Likewise.
	* ada-tasks.c (print_ada_task_info): Likewise.
	(info_task): Likewise.
	(task_command): Likewise.
	* auto-load.c (print_script): Likewise.
	(auto_load_info_scripts): Likewise.
	(info_auto_load_cmd): Likewise.
	* break-catch-sig.c (signal_catchpoint_print_one): Likewise.
	* break-catch-syscall.c (print_it_catch_syscall): Likewise.
	(print_one_catch_syscall): Likewise.
	* break-catch-throw.c (print_it_exception_catchpoint): Likewise.
	(print_one_exception_catchpoint): Likewise.
	(print_one_detail_exception_catchpoint): Likewise.
	(print_mention_exception_catchpoint): Likewise.
	* breakpoint.c (maybe_print_thread_hit_breakpoint): Likewise.
	(print_solib_event): Likewise.
	(watchpoint_check): Likewise.
	(wrap_indent_at_field): Likewise.
	(print_breakpoint_location): Likewise.
	(output_thread_groups): Likewise.
	(print_one_breakpoint_location): Likewise.
	(breakpoint_1): Likewise.
	(default_collect_info): Likewise.
	(watchpoints_info): Likewise.
	(print_it_catch_fork): Likewise.
	(print_one_catch_fork): Likewise.
	(print_it_catch_vfork): Likewise.
	(print_one_catch_vfork): Likewise.
	(print_it_catch_solib): Likewise.
	(print_one_catch_solib): Likewise.
	(print_it_catch_exec): Likewise.
	(print_one_catch_exec): Likewise.
	(mention): Likewise.
	(print_it_ranged_breakpoint): Likewise.
	(print_one_ranged_breakpoint): Likewise.
	(print_one_detail_ranged_breakpoint): Likewise.
	(print_mention_ranged_breakpoint): Likewise.
	(print_it_watchpoint): Likewise.
	(print_mention_watchpoint): Likewise.
	(print_it_masked_watchpoint): Likewise.
	(print_one_detail_masked_watchpoint): Likewise.
	(print_mention_masked_watchpoint): Likewise.
	(bkpt_print_it): Likewise.
	(tracepoint_print_one_detail): Likewise.
	(tracepoint_print_mention): Likewise.
	(update_static_tracepoint): Likewise.
	(tracepoints_info): Likewise.
	(save_breakpoints): Likewise.
	* cli/cli-cmds.c (complete_command): Likewise.
	* cli/cli-logging.c (set_logging_redirect): Likewise.
	(pop_output_files): Likewise.
	(handle_redirections): Likewise.
	* cli/cli-script.c (print_command_lines): Likewise.
	* cli/cli-setshow.c (do_show_command): Likewise.
	(cmd_show_list): Likewise.
	* cp-abi.c (list_cp_abis): Likewise.
	(show_cp_abi_cmd): Likewise.
	* darwin-nat-info.c (darwin_debug_regions_recurse): Likewise.
	* disasm.c (gdb_pretty_print_insn): Likewise.
	(do_mixed_source_and_assembly_deprecated): Likewise.
	(do_mixed_source_and_assembly): Likewise.
	* gdb_bfd.c (print_one_bfd): Likewise.
	(maintenance_info_bfds): Likewise.
	* guile/scm-breakpoint.c (gdbscm_breakpoint_commands): Likewise.
	* guile/scm-ports.c (ioscm_with_output_to_port_worker): Likewise.
	* i386-linux-tdep.c (i386_linux_handle_segmentation_fault): Likewise.
	* i386-tdep.c (i386_mpx_print_bounds): Likewise.
	* infcmd.c (run_command_1): Likewise.
	(print_return_value_1): Likewise.
	* inferior.c (print_selected_inferior): Likewise.
	(print_inferior): Likewise.
	* infrun.c (print_end_stepping_range_reason): Likewise.
	(print_signal_exited_reason): Likewise.
	(print_exited_reason): Likewise.
	(print_signal_received_reason): Likewise.
	(print_no_history_reason): Likewise.
	* interps.c (interp_set): Likewise.
	* linespec.c (decode_line_full): Likewise.
	* linux-thread-db.c (info_auto_load_libthread_db): Likewise.
	* mi/mi-cmd-env.c (mi_cmd_env_pwd): Likewise.
	(mi_cmd_env_path): Likewise.
	(mi_cmd_env_dir): Likewise.
	(mi_cmd_inferior_tty_show): Likewise.
	* mi/mi-cmd-file.c (mi_cmd_file_list_exec_source_file): Likewise.
	(print_partial_file_name): Likewise.
	(mi_cmd_file_list_exec_source_files): Likewise.
	* mi/mi-cmd-info.c (mi_cmd_info_ada_exceptions): Likewise.
	(mi_cmd_info_gdb_mi_command): Likewise.
	* mi/mi-cmd-stack.c (mi_cmd_stack_info_depth): Likewise.
	(mi_cmd_stack_list_args): Likewise.
	(list_arg_or_local): Likewise.
	* mi/mi-cmd-var.c (print_varobj): Likewise.
	(mi_cmd_var_create): Likewise.
	(mi_cmd_var_delete): Likewise.
	(mi_cmd_var_set_format): Likewise.
	(mi_cmd_var_show_format): Likewise.
	(mi_cmd_var_info_num_children): Likewise.
	(mi_cmd_var_list_children): Likewise.
	(mi_cmd_var_info_type): Likewise.
	(mi_cmd_var_info_path_expression): Likewise.
	(mi_cmd_var_info_expression): Likewise.
	(mi_cmd_var_show_attributes): Likewise.
	(mi_cmd_var_evaluate_expression): Likewise.
	(mi_cmd_var_assign): Likewise.
	(varobj_update_one): Likewise.
	* mi/mi-interp.c (as_mi_interp): Likewise.
	(mi_on_normal_stop_1): Likewise.
	(mi_tsv_modified): Likewise.
	(mi_breakpoint_created): Likewise.
	(mi_breakpoint_modified): Likewise.
	(mi_solib_loaded): Likewise.
	(mi_solib_unloaded): Likewise.
	(mi_command_param_changed): Likewise.
	(mi_memory_changed): Likewise.
	(mi_user_selected_context_changed): Likewise.
	* mi/mi-main.c (print_one_inferior): Likewise.
	(output_cores): Likewise.
	(list_available_thread_groups): Likewise.
	(mi_cmd_data_list_register_names): Likewise.
	(mi_cmd_data_list_changed_registers): Likewise.
	(output_register): Likewise.
	(mi_cmd_data_evaluate_expression): Likewise.
	(mi_cmd_data_read_memory): Likewise.
	(mi_cmd_data_read_memory_bytes): Likewise.
	(mi_cmd_list_features): Likewise.
	(mi_cmd_list_target_features): Likewise.
	(mi_cmd_add_inferior): Likewise.
	(mi_execute_command): Likewise.
	(mi_load_progress): Likewise.
	(print_variable_or_computed): Likewise.
	(mi_cmd_trace_frame_collected): Likewise.
	* mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines): Likewise.
	* osdata.c (info_osdata_command): Likewise.
	* probe.c (gen_ui_out_table_header_info): Likewise.
	(print_ui_out_not_applicables): Likewise.
	(print_ui_out_info): Likewise.
	(info_probes_for_ops): Likewise.
	(enable_probes_command): Likewise.
	(disable_probes_command): Likewise.
	* progspace.c (print_program_space): Likewise.
	* python/py-breakpoint.c (bppy_get_commands): Likewise.
	* python/py-framefilter.c (py_print_type): Likewise.
	(py_print_value): Likewise.
	(py_print_single_arg): Likewise.
	(enumerate_args): Likewise.
	(enumerate_locals): Likewise.
	(py_print_args): Likewise.
	(py_print_frame): Likewise.
	* record-btrace.c (btrace_ui_out_decode_error): Likewise.
	(btrace_call_history_insn_range): Likewise.
	(btrace_call_history_src_line): Likewise.
	(btrace_call_history): Likewise.
	* remote.c (show_remote_cmd): Likewise.
	* skip.c (skip_info): Likewise.
	* solib.c (info_sharedlibrary_command): Likewise.
	* source.c (print_source_lines_base): Likewise.
	* spu-tdep.c (info_spu_event_command): Likewise.
	(info_spu_signal_command): Likewise.
	(info_spu_mailbox_list): Likewise.
	(info_spu_dma_cmdlist): Likewise.
	(info_spu_dma_command): Likewise.
	(info_spu_proxydma_command): Likewise.
	* stack.c (print_stack_frame): Likewise.
	(print_frame_arg): Likewise.
	(read_frame_arg): Likewise.
	(print_frame_args): Likewise.
	(print_frame_info): Likewise.
	(print_frame): Likewise.
	* symfile.c (load_progress): Likewise.
	(generic_load): Likewise.
	(print_transfer_performance): Likewise.
	* thread.c (do_captured_list_thread_ids): Likewise.
	(print_thread_info_1): Likewise.
	(restore_selected_frame): Likewise.
	(do_captured_thread_select): Likewise.
	(print_selected_thread_frame): Likewise.
	* top.c (execute_command_to_string): Likewise.
	* tracepoint.c (tvariables_info_1): Likewise.
	(trace_status_mi): Likewise.
	(tfind_1): Likewise.
	(print_one_static_tracepoint_marker): Likewise.
	(info_static_tracepoint_markers_command): Likewise.
	* utils.c (do_ui_out_redirect_pop): Likewise.
	(fputs_maybe_filtered): Likewise.
---
 gdb/ada-lang.c              |  47 ++--
 gdb/ada-tasks.c             |  63 +++--
 gdb/auto-load.c             |  29 ++-
 gdb/break-catch-sig.c       |  16 +-
 gdb/break-catch-syscall.c   |  40 +--
 gdb/break-catch-throw.c     |  52 ++--
 gdb/breakpoint.c            | 590 +++++++++++++++++++++-----------------------
 gdb/cli-out.c               | 301 +++++++---------------
 gdb/cli-out.h               |  60 ++++-
 gdb/cli/cli-cmds.c          |   2 +-
 gdb/cli/cli-interp.c        |  12 +-
 gdb/cli/cli-logging.c       |  12 +-
 gdb/cli/cli-script.c        |  84 +++----
 gdb/cli/cli-setshow.c       |  14 +-
 gdb/cp-abi.c                |  22 +-
 gdb/darwin-nat-info.c       |  48 ++--
 gdb/disasm.c                |  51 ++--
 gdb/gdb_bfd.c               |  16 +-
 gdb/guile/scm-breakpoint.c  |   4 +-
 gdb/guile/scm-ports.c       |   2 +-
 gdb/i386-linux-tdep.c       |  25 +-
 gdb/i386-tdep.c             |  32 +--
 gdb/infcmd.c                |  32 +--
 gdb/inferior.c              |  39 +--
 gdb/infrun.c                |  94 ++++---
 gdb/interps.c               |   4 +-
 gdb/linespec.c              |   2 +-
 gdb/linux-thread-db.c       |  17 +-
 gdb/mi/mi-cmd-env.c         |   9 +-
 gdb/mi/mi-cmd-file.c        |  32 ++-
 gdb/mi/mi-cmd-info.c        |  12 +-
 gdb/mi/mi-cmd-stack.c       |  12 +-
 gdb/mi/mi-cmd-var.c         |  77 +++---
 gdb/mi/mi-interp.c          |  81 +++---
 gdb/mi/mi-main.c            | 149 ++++++-----
 gdb/mi/mi-out.c             | 309 +++++++++--------------
 gdb/mi/mi-out.h             |  69 +++++-
 gdb/mi/mi-symbol-cmds.c     |   5 +-
 gdb/osdata.c                |  10 +-
 gdb/probe.c                 |  67 +++--
 gdb/progspace.c             |  20 +-
 gdb/python/py-breakpoint.c  |   6 +-
 gdb/python/py-framefilter.c |  88 +++----
 gdb/record-btrace.c         |  44 ++--
 gdb/remote.c                |   4 +-
 gdb/skip.c                  |  44 ++--
 gdb/solib.c                 |  39 ++-
 gdb/source.c                |  31 ++-
 gdb/spu-tdep.c              | 124 +++++-----
 gdb/stack.c                 |  84 +++----
 gdb/symfile.c               |  45 ++--
 gdb/thread.c                | 100 ++++----
 gdb/top.c                   |   2 +-
 gdb/tracepoint.c            | 146 +++++------
 gdb/tui/tui-interp.c        |   6 +-
 gdb/tui/tui-io.c            |   6 +-
 gdb/tui/tui-io.h            |   3 +-
 gdb/tui/tui-out.c           | 143 ++++-------
 gdb/tui/tui-out.h           |  48 ++++
 gdb/tui/tui.h               |   2 -
 gdb/ui-out.c                | 501 ++++++++++---------------------------
 gdb/ui-out.h                | 268 +++++++++-----------
 gdb/utils.c                 |   4 +-
 63 files changed, 1926 insertions(+), 2374 deletions(-)
 create mode 100644 gdb/tui/tui-out.h
  

Comments

Pedro Alves Dec. 20, 2016, 12:35 p.m. UTC | #1
On 12/12/2016 04:15 PM, Simon Marchi wrote:

> -static void
> -cli_table_begin (struct ui_out *uiout, int nbrofcols,
> -		 int nr_rows,
> -		 const char *tblid)
> +void
> +cli_ui_out::do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
>  {
> -  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
> -
>    if (nr_rows == 0)
> -    data->suppress_output = 1;
> +    m_suppress_output = true;
>    else
>      /* Only the table suppresses the output and, fortunately, a table
>         is not a recursive data structure.  */
> -    gdb_assert (data->suppress_output == 0);
> +    gdb_assert (m_suppress_output == 0);

    gdb_assert (!m_suppress_output);

> index dfa96d6..3e6a2fd 100644
> --- a/gdb/cli/cli-interp.c
> +++ b/gdb/cli/cli-interp.c
> @@ -34,7 +34,7 @@
>  struct cli_interp
>  {
>    /* The ui_out for the console interpreter.  */
> -  struct ui_out *cli_uiout;
> +  cli_ui_out *cli_uiout;
>  };

Exactly.  Nice.


> -static void
> -mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type)
> +void
> +mi_ui_out::open (const char *name, ui_out_type type)
>  {
> -  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
> -  ui_file *stream = data->streams.back ();
> +  ui_file *stream = m_streams.back ();
> +
> +  field_separator ();
> +  m_suppress_field_separator = 1;

= true;

>  
> -  field_separator (uiout);
> -  data->suppress_field_separator = 1;
>    if (name)
>      fprintf_unfiltered (stream, "%s=", name);
> +
>    switch (type)
>      {
>      case ui_out_type_tuple:
>        fputc_unfiltered ('{', stream);
>        break;
> +
>      case ui_out_type_list:
>        fputc_unfiltered ('[', stream);
>        break;
> +
>      default:
>        internal_error (__FILE__, __LINE__, _("bad switch"));
>      }
>  }
>  


> -static void
> -mi_out_data_ctor (mi_out_data *self, int mi_version, struct ui_file *stream)
> +mi_ui_out::mi_ui_out (int mi_version, ui_file *stream)
> +: m_suppress_field_separator (0),

m_suppress_field_separator (false)

> +  m_suppress_output (false),
> +  m_mi_version (mi_version)
>  {
>    gdb_assert (stream != NULL);
>  
> -  self->streams.push_back (stream);
> +  m_streams.push_back (stream);
> +}
>  
> -  self->suppress_field_separator = 0;
> -  self->mi_version = mi_version;
> +mi_ui_out::~mi_ui_out ()
> +{
>  }
>  


> -/* Initialize private members at startup.  */
> +/* Helper function to return the given UIOUT as an mi_ui_out.  It is an error
> +   to call this fucntion with an ui_out that is not an MI.  */

typo: fucntion.

>  
> -struct ui_out *
> -mi_out_new (int mi_version)
> +static mi_ui_out *
> +as_mi_ui_out (ui_out *uiout)
>  {
> -  ui_out_flags flags = 0;
> -  mi_out_data *data = new mi_out_data ();
> -  struct ui_file *stream = mem_fileopen ();
> +  mi_ui_out *mi_uiout = dynamic_cast<mi_ui_out *> (uiout);
> +
> +  gdb_assert (mi_uiout != NULL);
> +
> +  return mi_uiout;
> +}
>  
> -  mi_out_data_ctor (data, mi_version, stream);
> -  return ui_out_new (&mi_ui_out_impl, data, flags);
> +int
> +mi_version (ui_out *uiout)
> +{
> +  return as_mi_ui_out (uiout)->version ();
> +}


> -/* Return the version number of the current MI.  */
> -extern int mi_version (struct ui_out *uiout);
> +class mi_ui_out : public ui_out
> +{
> +public:
> +
> +  explicit mi_ui_out (int mi_version, ui_file *stream);
> +  virtual ~mi_ui_out ();
> +
> +  /* MI-specific */
> +  void rewind ();
> +  void put (struct ui_file *stream);
> +
> +  /* Return the version number of the current MI.  */
> +  int version ();
> +
> +protected:
> +
> +  virtual void do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
> +    override;
> +  virtual void do_table_body () override;
> +  virtual void do_table_header (int width, ui_align align,
> +			     const std::string &col_name,
> +			     const std::string &col_hdr) override;
> +  virtual void do_table_end () override;
> +
> +  virtual void do_begin (ui_out_type type, const char *id) override;
> +  virtual void do_end (ui_out_type type) override;
> +  virtual void do_field_int (int fldno, int width, ui_align align,
> +			  const char *fldname, int value) override;
> +  virtual void do_field_skip (int fldno, int width, ui_align align,
> +			   const char *fldname) override;
> +  virtual void do_field_string (int fldno, int width, ui_align align,
> +			     const char *fldname, const char *string) override;
> +  virtual void do_field_fmt (int fldno, int width, ui_align align,
> +			  const char *fldname, const char *format, va_list args)
> +    override ATTRIBUTE_PRINTF (6,0);
> +  virtual void do_spaces (int numspaces) override;
> +  virtual void do_text (const char *string) override;
> +  virtual void do_message (const char *format, va_list args) override
> +    ATTRIBUTE_PRINTF (2,0) ;
> +  virtual void do_wrap_hint (const char *identstring) override;
> +  virtual void do_flush () override;
> +  virtual int do_redirect (struct ui_file * outstream) override;

Should do_redirect return bool?

> +
> +  virtual bool do_is_mi_like_p () override
> +  { return true; }
> +
> +private:
> +
> +  void field_separator ();
> +  void open (const char *name, ui_out_type type);
> +  void close (ui_out_type type);
> +
> +  int m_suppress_field_separator;

bool.

> +  bool m_suppress_output;
> +  int m_mi_version;
> +  std::vector<ui_file *> m_streams;
> +};
> +
> +mi_ui_out *mi_out_new (int mi_version);
> +int mi_version (ui_out *uiout);
> +void mi_out_put (ui_out *uiout, struct ui_file *stream);
> +void mi_out_rewind (ui_out *uiout);
>  
>  #endif /* MI_OUT_H */

I'm finding this patch very hard to skim through.  :-(
Mainly because it mixes changing the implementation of the ui_out
types, and elimination of all the ui_out_field_XXX etc. functions.
I.e, I'm finding myself scrolling through the latter all again,
while it probably didn't change vs v1, making the C++-fyication
of the ui-out types hard to see among a forest of mechanical hunks.

I think it'd have been much easier to review if the patch
was split in two patches: one that changes ui-out.h|.c,
cli-out.h|c, mi-out.h|c and tui-out.h|c, leaving the 
ui_out_field_XXX public API in place, and then another
mostly mechanical one that eliminated the ui_out_field_XXX
public API and its uses throughout.

So at this point I applied the patch locally, and diffed
the *-out.h files.  Hopefully I won't miss anything
important.

BTW, git am showed:

$ git am /tmp/simon.mbox
Applying: Class-ify ui_out
.../src/.git/rebase-apply/patch:575: trailing whitespace.
      uiout->field_string ("reason", 
.../src/.git/rebase-apply/patch:949: trailing whitespace.
    uiout->field_fmt ("enabled", "%c", 
.../src/.git/rebase-apply/patch:2866: trailing whitespace.
      uiout->field_string ("min-prot", 
.../src/.git/rebase-apply/patch:2869: trailing whitespace.
      uiout->field_string ("max-prot", 
.../src/.git/rebase-apply/patch:3401: trailing whitespace.
        uiout->field_string ("reason", 
warning: 5 lines add whitespace errors.



I noticed several instances of missing reindentation of
second line in method implementation prototypes, like:

void
cli_ui_out::out_field_fmt (int fldno, const char *fldname,
				const char *format, ...)


~~~~~~~~~~~~~~~~~~~~~~~~
 /* access to ui_out format private members */
 -
 -static void
 -field_separator (struct ui_out *uiout)
 +void
 +mi_ui_out::field_separator ()
  {
 -  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
 -  ui_file *stream = data->streams.back ();
 -
 -  if (data->suppress_field_separator)
 -    data->suppress_field_separator = 0;
 +  if (m_suppress_field_separator)
 +    m_suppress_field_separator = 0;
    else
 -    fputc_unfiltered (',', stream);
 +    fputc_unfiltered (',', m_streams.back ());
  }
~~~~~~~~~~~~~~~~~~~~~~~~

Above should be "m_suppress_field_separator = false;"

Same in mi_ui_out::close, and also in:

 +mi_ui_out::mi_ui_out (int mi_version, ui_file *stream)
 +: m_suppress_field_separator (0),

Should return bool (all implementations of course):

  int
 -ui_out_is_mi_like_p (struct ui_out *uiout)
 +ui_out::is_mi_like_p ()

Otherwise it looks good to me.  Thanks much for doing this!

Please push.

Pedro Alves
  
Simon Marchi Dec. 20, 2016, 3:28 p.m. UTC | #2
On 2016-12-20 07:35, Pedro Alves wrote:
> On 12/12/2016 04:15 PM, Simon Marchi wrote:
> 
>> -static void
>> -cli_table_begin (struct ui_out *uiout, int nbrofcols,
>> -		 int nr_rows,
>> -		 const char *tblid)
>> +void
>> +cli_ui_out::do_table_begin (int nbrofcols, int nr_rows, const char 
>> *tblid)
>>  {
>> -  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
>> -
>>    if (nr_rows == 0)
>> -    data->suppress_output = 1;
>> +    m_suppress_output = true;
>>    else
>>      /* Only the table suppresses the output and, fortunately, a table
>>         is not a recursive data structure.  */
>> -    gdb_assert (data->suppress_output == 0);
>> +    gdb_assert (m_suppress_output == 0);
> 
>     gdb_assert (!m_suppress_output);

Done.

>> index dfa96d6..3e6a2fd 100644
>> --- a/gdb/cli/cli-interp.c
>> +++ b/gdb/cli/cli-interp.c
>> @@ -34,7 +34,7 @@
>>  struct cli_interp
>>  {
>>    /* The ui_out for the console interpreter.  */
>> -  struct ui_out *cli_uiout;
>> +  cli_ui_out *cli_uiout;
>>  };
> 
> Exactly.  Nice.
> 
> 
>> -static void
>> -mi_open (struct ui_out *uiout, const char *name, enum ui_out_type 
>> type)
>> +void
>> +mi_ui_out::open (const char *name, ui_out_type type)
>>  {
>> -  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
>> -  ui_file *stream = data->streams.back ();
>> +  ui_file *stream = m_streams.back ();
>> +
>> +  field_separator ();
>> +  m_suppress_field_separator = 1;
> 
> = true;

Done.

>> -static void
>> -mi_out_data_ctor (mi_out_data *self, int mi_version, struct ui_file 
>> *stream)
>> +mi_ui_out::mi_ui_out (int mi_version, ui_file *stream)
>> +: m_suppress_field_separator (0),
> 
> m_suppress_field_separator (false)

Done.

>> -/* Initialize private members at startup.  */
>> +/* Helper function to return the given UIOUT as an mi_ui_out.  It is 
>> an error
>> +   to call this fucntion with an ui_out that is not an MI.  */
> 
> typo: fucntion.

Done.

>> -/* Return the version number of the current MI.  */
>> -extern int mi_version (struct ui_out *uiout);
>> +class mi_ui_out : public ui_out
>> +{
>> +public:
>> +
>> +  explicit mi_ui_out (int mi_version, ui_file *stream);
>> +  virtual ~mi_ui_out ();
>> +
>> +  /* MI-specific */
>> +  void rewind ();
>> +  void put (struct ui_file *stream);
>> +
>> +  /* Return the version number of the current MI.  */
>> +  int version ();
>> +
>> +protected:
>> +
>> +  virtual void do_table_begin (int nbrofcols, int nr_rows, const char 
>> *tblid)
>> +    override;
>> +  virtual void do_table_body () override;
>> +  virtual void do_table_header (int width, ui_align align,
>> +			     const std::string &col_name,
>> +			     const std::string &col_hdr) override;
>> +  virtual void do_table_end () override;
>> +
>> +  virtual void do_begin (ui_out_type type, const char *id) override;
>> +  virtual void do_end (ui_out_type type) override;
>> +  virtual void do_field_int (int fldno, int width, ui_align align,
>> +			  const char *fldname, int value) override;
>> +  virtual void do_field_skip (int fldno, int width, ui_align align,
>> +			   const char *fldname) override;
>> +  virtual void do_field_string (int fldno, int width, ui_align align,
>> +			     const char *fldname, const char *string) override;
>> +  virtual void do_field_fmt (int fldno, int width, ui_align align,
>> +			  const char *fldname, const char *format, va_list args)
>> +    override ATTRIBUTE_PRINTF (6,0);
>> +  virtual void do_spaces (int numspaces) override;
>> +  virtual void do_text (const char *string) override;
>> +  virtual void do_message (const char *format, va_list args) override
>> +    ATTRIBUTE_PRINTF (2,0) ;
>> +  virtual void do_wrap_hint (const char *identstring) override;
>> +  virtual void do_flush () override;
>> +  virtual int do_redirect (struct ui_file * outstream) override;
> 
> Should do_redirect return bool?

Should it return anything at all?  Both implementations always return 
0...

>> +
>> +  virtual bool do_is_mi_like_p () override
>> +  { return true; }
>> +
>> +private:
>> +
>> +  void field_separator ();
>> +  void open (const char *name, ui_out_type type);
>> +  void close (ui_out_type type);
>> +
>> +  int m_suppress_field_separator;
> 
> bool.

Done.

>> +  bool m_suppress_output;
>> +  int m_mi_version;
>> +  std::vector<ui_file *> m_streams;
>> +};
>> +
>> +mi_ui_out *mi_out_new (int mi_version);
>> +int mi_version (ui_out *uiout);
>> +void mi_out_put (ui_out *uiout, struct ui_file *stream);
>> +void mi_out_rewind (ui_out *uiout);
>> 
>>  #endif /* MI_OUT_H */
> 
> I'm finding this patch very hard to skim through.  :-(
> Mainly because it mixes changing the implementation of the ui_out
> types, and elimination of all the ui_out_field_XXX etc. functions.
> I.e, I'm finding myself scrolling through the latter all again,
> while it probably didn't change vs v1, making the C++-fyication
> of the ui-out types hard to see among a forest of mechanical hunks.
> 
> I think it'd have been much easier to review if the patch
> was split in two patches: one that changes ui-out.h|.c,
> cli-out.h|c, mi-out.h|c and tui-out.h|c, leaving the
> ui_out_field_XXX public API in place, and then another
> mostly mechanical one that eliminated the ui_out_field_XXX
> public API and its uses throughout.
> 
> So at this point I applied the patch locally, and diffed
> the *-out.h files.  Hopefully I won't miss anything
> important.

Indeed it would have been better.  I didn't think about that, sorry.

> BTW, git am showed:
> 
> $ git am /tmp/simon.mbox
> Applying: Class-ify ui_out
> .../src/.git/rebase-apply/patch:575: trailing whitespace.
>       uiout->field_string ("reason",
> .../src/.git/rebase-apply/patch:949: trailing whitespace.
>     uiout->field_fmt ("enabled", "%c",
> .../src/.git/rebase-apply/patch:2866: trailing whitespace.
>       uiout->field_string ("min-prot",
> .../src/.git/rebase-apply/patch:2869: trailing whitespace.
>       uiout->field_string ("max-prot",
> .../src/.git/rebase-apply/patch:3401: trailing whitespace.
>         uiout->field_string ("reason",
> warning: 5 lines add whitespace errors.

Done.

> I noticed several instances of missing reindentation of
> second line in method implementation prototypes, like:
> 
> void
> cli_ui_out::out_field_fmt (int fldno, const char *fldname,
> 				const char *format, ...)

Indeed, there were many instances in cli-out.c, tui-out.c and mi-out.c.

> 
> ~~~~~~~~~~~~~~~~~~~~~~~~
>  /* access to ui_out format private members */
>  -
>  -static void
>  -field_separator (struct ui_out *uiout)
>  +void
>  +mi_ui_out::field_separator ()
>   {
>  -  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
>  -  ui_file *stream = data->streams.back ();
>  -
>  -  if (data->suppress_field_separator)
>  -    data->suppress_field_separator = 0;
>  +  if (m_suppress_field_separator)
>  +    m_suppress_field_separator = 0;
>     else
>  -    fputc_unfiltered (',', stream);
>  +    fputc_unfiltered (',', m_streams.back ());
>   }
> ~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Above should be "m_suppress_field_separator = false;"
> 
> Same in mi_ui_out::close, and also in:
> 
>  +mi_ui_out::mi_ui_out (int mi_version, ui_file *stream)
>  +: m_suppress_field_separator (0),

I looked up all usages of m_suppress_field_separator and 
m_suppress_output to make sure they were using boolean.

> Should return bool (all implementations of course):
> 
>   int
>  -ui_out_is_mi_like_p (struct ui_out *uiout)
>  +ui_out::is_mi_like_p ()

Done.

> Otherwise it looks good to me.  Thanks much for doing this!
> 
> Please push.

Thanks for reviewing, I'm sure it wasn't one of the most pleasant to 
do...

I'll give it a last go on the buildbot and push if it's all good.

Simon
  
Pedro Alves Dec. 20, 2016, 4:56 p.m. UTC | #3
On 12/20/2016 03:28 PM, Simon Marchi wrote:

>>> +  virtual void do_message (const char *format, va_list args) override
>>> +    ATTRIBUTE_PRINTF (2,0) ;
>>> +  virtual void do_wrap_hint (const char *identstring) override;
>>> +  virtual void do_flush () override;
>>> +  virtual int do_redirect (struct ui_file * outstream) override;
>>
>> Should do_redirect return bool?
> 
> Should it return anything at all?  Both implementations always return 0...

Curious.  Guess it wasn't the case at some point.  I checked Insight
too, and its interpreter creates a plain cli_out, not a custom
ui_out, so we're good there too.  I'd push the patch as you had it,
and the clean the method to return void, which will result in some
cascading clean ups at the callers.

Thanks,
Pedro Alves
  
Simon Marchi Dec. 22, 2016, 9:23 p.m. UTC | #4
On 2016-12-20 11:56, Pedro Alves wrote:
> Curious.  Guess it wasn't the case at some point.  I checked Insight
> too, and its interpreter creates a plain cli_out, not a custom
> ui_out, so we're good there too.  I'd push the patch as you had it,
> and the clean the method to return void, which will result in some
> cascading clean ups at the callers.

Ok, will do that.

I have pushed this one.
  

Patch

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d2d0340..a79ec2b 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12469,18 +12469,17 @@  print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
 
   annotate_catchpoint (b->number);
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
 			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
 
-  ui_out_text (uiout,
-               b->disposition == disp_del ? "\nTemporary catchpoint "
-	                                  : "\nCatchpoint ");
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, ", ");
+  uiout->text (b->disposition == disp_del
+	       ? "\nTemporary catchpoint " : "\nCatchpoint ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (", ");
 
   /* ada_exception_name_addr relies on the selected frame being the
      current frame.  Need to do this here because this function may be
@@ -12519,8 +12518,8 @@  print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
 	     hit.  We used ui_out_text to make sure that this extra
 	     info does not pollute the exception name in the MI case.  */
 	  if (ex == ada_catch_exception_unhandled)
-	    ui_out_text (uiout, "unhandled ");
-	  ui_out_field_string (uiout, "exception-name", exception_name);
+	    uiout->text ("unhandled ");
+	  uiout->field_string ("exception-name", exception_name);
 	}
 	break;
       case ada_catch_assert:
@@ -12529,10 +12528,10 @@  print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
 	   that his program just hit an assertion-failure catchpoint.
 	   We used ui_out_text because this info does not belong in
 	   the MI output.  */
-	ui_out_text (uiout, "failed assertion");
+	uiout->text ("failed assertion");
 	break;
     }
-  ui_out_text (uiout, " at ");
+  uiout->text (" at ");
   ada_find_printable_frame (get_current_frame ());
 
   return PRINT_SRC_AND_LOC;
@@ -12553,7 +12552,7 @@  print_one_exception (enum ada_exception_catchpoint_kind ex,
   if (opts.addressprint)
     {
       annotate_field (4);
-      ui_out_field_core_addr (uiout, "addr", b->loc->gdbarch, b->loc->address);
+      uiout->field_core_addr ("addr", b->loc->gdbarch, b->loc->address);
     }
 
   annotate_field (5);
@@ -12565,20 +12564,20 @@  print_one_exception (enum ada_exception_catchpoint_kind ex,
           {
             char *msg = xstrprintf (_("`%s' Ada exception"), c->excep_string);
 
-            ui_out_field_string (uiout, "what", msg);
+            uiout->field_string ("what", msg);
             xfree (msg);
           }
         else
-          ui_out_field_string (uiout, "what", "all Ada exceptions");
+          uiout->field_string ("what", "all Ada exceptions");
         
         break;
 
       case ada_catch_exception_unhandled:
-        ui_out_field_string (uiout, "what", "unhandled Ada exceptions");
+        uiout->field_string ("what", "unhandled Ada exceptions");
         break;
       
       case ada_catch_assert:
-        ui_out_field_string (uiout, "what", "failed Ada assertions");
+        uiout->field_string ("what", "failed Ada assertions");
         break;
 
       default:
@@ -12597,10 +12596,10 @@  print_mention_exception (enum ada_exception_catchpoint_kind ex,
   struct ada_catchpoint *c = (struct ada_catchpoint *) b;
   struct ui_out *uiout = current_uiout;
 
-  ui_out_text (uiout, b->disposition == disp_del ? _("Temporary catchpoint ")
+  uiout->text (b->disposition == disp_del ? _("Temporary catchpoint ")
                                                  : _("Catchpoint "));
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, ": ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (": ");
 
   switch (ex)
     {
@@ -12610,19 +12609,19 @@  print_mention_exception (enum ada_exception_catchpoint_kind ex,
 	    char *info = xstrprintf (_("`%s' Ada exception"), c->excep_string);
 	    struct cleanup *old_chain = make_cleanup (xfree, info);
 
-	    ui_out_text (uiout, info);
+	    uiout->text (info);
 	    do_cleanups (old_chain);
 	  }
         else
-          ui_out_text (uiout, _("all Ada exceptions"));
+          uiout->text (_("all Ada exceptions"));
         break;
 
       case ada_catch_exception_unhandled:
-        ui_out_text (uiout, _("unhandled Ada exceptions"));
+        uiout->text (_("unhandled Ada exceptions"));
         break;
       
       case ada_catch_assert:
-        ui_out_text (uiout, _("failed Ada assertions"));
+        uiout->text (_("failed Ada assertions"));
         break;
 
       default:
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index 31092fd..be8d44b 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -1013,15 +1013,14 @@  print_ada_task_info (struct ui_out *uiout,
 
   if (ada_build_task_list () == 0)
     {
-      ui_out_message (uiout,
-		      _("Your application does not use any Ada tasks.\n"));
+      uiout->message (_("Your application does not use any Ada tasks.\n"));
       return;
     }
 
   if (arg_str != NULL && arg_str[0] != '\0')
     taskno_arg = value_as_long (parse_and_eval (arg_str));
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     /* In GDB/MI mode, we want to provide the thread ID corresponding
        to each task.  This allows clients to quickly find the thread
        associated to any task, which is helpful for commands that
@@ -1047,25 +1046,25 @@  print_ada_task_info (struct ui_out *uiout,
   else
     nb_tasks = VEC_length (ada_task_info_s, data->task_list);
 
-  nb_columns = ui_out_is_mi_like_p (uiout) ? 8 : 7;
+  nb_columns = uiout->is_mi_like_p () ? 8 : 7;
   old_chain = make_cleanup_ui_out_table_begin_end (uiout, nb_columns,
 						   nb_tasks, "tasks");
-  ui_out_table_header (uiout, 1, ui_left, "current", "");
-  ui_out_table_header (uiout, 3, ui_right, "id", "ID");
-  ui_out_table_header (uiout, 9, ui_right, "task-id", "TID");
+  uiout->table_header (1, ui_left, "current", "");
+  uiout->table_header (3, ui_right, "id", "ID");
+  uiout->table_header (9, ui_right, "task-id", "TID");
   /* The following column is provided in GDB/MI mode only because
      it is only really useful in that mode, and also because it
      allows us to keep the CLI output shorter and more compact.  */
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_table_header (uiout, 4, ui_right, "thread-id", "");
-  ui_out_table_header (uiout, 4, ui_right, "parent-id", "P-ID");
-  ui_out_table_header (uiout, 3, ui_right, "priority", "Pri");
-  ui_out_table_header (uiout, 22, ui_left, "state", "State");
+  if (uiout->is_mi_like_p ())
+    uiout->table_header (4, ui_right, "thread-id", "");
+  uiout->table_header (4, ui_right, "parent-id", "P-ID");
+  uiout->table_header (3, ui_right, "priority", "Pri");
+  uiout->table_header (22, ui_left, "state", "State");
   /* Use ui_noalign for the last column, to prevent the CLI uiout
      from printing an extra space at the end of each row.  This
      is a bit of a hack, but does get the job done.  */
-  ui_out_table_header (uiout, 1, ui_noalign, "name", "Name");
-  ui_out_table_body (uiout);
+  uiout->table_header (1, ui_noalign, "name", "Name");
+  uiout->table_body ();
 
   for (taskno = 1;
        taskno <= VEC_length (ada_task_info_s, data->task_list);
@@ -1089,61 +1088,61 @@  print_ada_task_info (struct ui_out *uiout,
       /* Print a star if this task is the current task (or the task
          currently selected).  */
       if (ptid_equal (task_info->ptid, inferior_ptid))
-	ui_out_field_string (uiout, "current", "*");
+	uiout->field_string ("current", "*");
       else
-	ui_out_field_skip (uiout, "current");
+	uiout->field_skip ("current");
 
       /* Print the task number.  */
-      ui_out_field_int (uiout, "id", taskno);
+      uiout->field_int ("id", taskno);
 
       /* Print the Task ID.  */
-      ui_out_field_fmt (uiout, "task-id", "%9lx", (long) task_info->task_id);
+      uiout->field_fmt ("task-id", "%9lx", (long) task_info->task_id);
 
       /* Print the associated Thread ID.  */
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
         {
 	  const int thread_id = ptid_to_global_thread_id (task_info->ptid);
 
 	  if (thread_id != 0)
-	    ui_out_field_int (uiout, "thread-id", thread_id);
+	    uiout->field_int ("thread-id", thread_id);
 	  else
 	    /* This should never happen unless there is a bug somewhere,
 	       but be resilient when that happens.  */
-	    ui_out_field_skip (uiout, "thread-id");
+	    uiout->field_skip ("thread-id");
 	}
 
       /* Print the ID of the parent task.  */
       parent_id = get_task_number_from_id (task_info->parent, inf);
       if (parent_id)
-        ui_out_field_int (uiout, "parent-id", parent_id);
+        uiout->field_int ("parent-id", parent_id);
       else
-        ui_out_field_skip (uiout, "parent-id");
+        uiout->field_skip ("parent-id");
 
       /* Print the base priority of the task.  */
-      ui_out_field_int (uiout, "priority", task_info->priority);
+      uiout->field_int ("priority", task_info->priority);
 
       /* Print the task current state.  */
       if (task_info->caller_task)
-	ui_out_field_fmt (uiout, "state",
+	uiout->field_fmt ("state",
 			  _("Accepting RV with %-4d"),
 			  get_task_number_from_id (task_info->caller_task,
 						   inf));
       else if (task_info->state == Entry_Caller_Sleep
 	       && task_info->called_task)
-	ui_out_field_fmt (uiout, "state",
+	uiout->field_fmt ("state",
 			  _("Waiting on RV with %-3d"),
 			  get_task_number_from_id (task_info->called_task,
 						   inf));
       else
-	ui_out_field_string (uiout, "state", task_states[task_info->state]);
+	uiout->field_string ("state", task_states[task_info->state]);
 
       /* Finally, print the task name.  */
-      ui_out_field_fmt (uiout, "name",
+      uiout->field_fmt ("name",
 			"%s",
 			task_info->name[0] != '\0' ? task_info->name
 						   : _("<no name>"));
 
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
       do_cleanups (chain2);
     }
 
@@ -1163,8 +1162,7 @@  info_task (struct ui_out *uiout, char *taskno_str, struct inferior *inf)
 
   if (ada_build_task_list () == 0)
     {
-      ui_out_message (uiout,
-		      _("Your application does not use any Ada tasks.\n"));
+      uiout->message (_("Your application does not use any Ada tasks.\n"));
       return;
     }
 
@@ -1328,8 +1326,7 @@  task_command (char *taskno_str, int from_tty)
 
   if (ada_build_task_list () == 0)
     {
-      ui_out_message (uiout,
-		      _("Your application does not use any Ada tasks.\n"));
+      uiout->message (_("Your application does not use any Ada tasks.\n"));
       return;
     }
 
diff --git a/gdb/auto-load.c b/gdb/auto-load.c
index 958c24e..52cebf1 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -1271,17 +1271,17 @@  print_script (struct loaded_script *script)
 
   chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
 
-  ui_out_field_string (uiout, "loaded", script->loaded ? "Yes" : "No");
-  ui_out_field_string (uiout, "script", script->name);
-  ui_out_text (uiout, "\n");
+  uiout->field_string ("loaded", script->loaded ? "Yes" : "No");
+  uiout->field_string ("script", script->name);
+  uiout->text ("\n");
 
   /* If the name isn't the full path, print it too.  */
   if (script->full_path != NULL
       && strcmp (script->name, script->full_path) != 0)
     {
-      ui_out_text (uiout, "\tfull name: ");
-      ui_out_field_string (uiout, "full_path", script->full_path);
-      ui_out_text (uiout, "\n");
+      uiout->text ("\tfull name: ");
+      uiout->field_string ("full_path", script->full_path);
+      uiout->text ("\n");
     }
 
   do_cleanups (chain);
@@ -1382,15 +1382,15 @@  auto_load_info_scripts (char *pattern, int from_tty,
   /* Table header shifted right by preceding "gdb-scripts:  " would not match
      its columns.  */
   if (nr_scripts > 0 && pattern == auto_load_info_scripts_pattern_nl)
-    ui_out_text (uiout, "\n");
+    uiout->text ("\n");
 
   /* Note: This creates a cleanup to output the table end marker.  */
   make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts,
 				       "AutoLoadedScriptsTable");
 
-  ui_out_table_header (uiout, 7, ui_left, "loaded", "Loaded");
-  ui_out_table_header (uiout, 70, ui_left, "script", "Script");
-  ui_out_table_body (uiout);
+  uiout->table_header (7, ui_left, "loaded", "Loaded");
+  uiout->table_header (70, ui_left, "script", "Script");
+  uiout->table_body ();
 
   print_scripts (script_files);
   print_scripts (script_texts);
@@ -1401,10 +1401,9 @@  auto_load_info_scripts (char *pattern, int from_tty,
   if (nr_scripts == 0)
     {
       if (pattern && *pattern)
-	ui_out_message (uiout, "No auto-load scripts matching %s.\n",
-			pattern);
+	uiout->message ("No auto-load scripts matching %s.\n", pattern);
       else
-	ui_out_message (uiout, "No auto-load scripts.\n");
+	uiout->message ("No auto-load scripts.\n");
     }
 }
 
@@ -1571,8 +1570,8 @@  info_auto_load_cmd (char *args, int from_tty)
       gdb_assert (!list->prefixlist);
       gdb_assert (list->type == not_set_cmd);
 
-      ui_out_field_string (uiout, "name", list->name);
-      ui_out_text (uiout, ":  ");
+      uiout->field_string ("name", list->name);
+      uiout->text (":  ");
       cmd_func (list, auto_load_info_scripts_pattern_nl, from_tty);
 
       /* Close the tuple.  */
diff --git a/gdb/break-catch-sig.c b/gdb/break-catch-sig.c
index e869a83..97d14b6 100644
--- a/gdb/break-catch-sig.c
+++ b/gdb/break-catch-sig.c
@@ -253,14 +253,14 @@  signal_catchpoint_print_one (struct breakpoint *b,
      not line up too nicely with the headers, but the effect
      is relatively readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
 
   if (c->signals_to_be_caught
       && VEC_length (gdb_signal_type, c->signals_to_be_caught) > 1)
-    ui_out_text (uiout, "signals \"");
+    uiout->text ("signals \"");
   else
-    ui_out_text (uiout, "signal \"");
+    uiout->text ("signal \"");
 
   if (c->signals_to_be_caught)
     {
@@ -278,15 +278,15 @@  signal_catchpoint_print_one (struct breakpoint *b,
 	    text += " ";
 	  text += name;
         }
-      ui_out_field_string (uiout, "what", text.c_str ());
+      uiout->field_string ("what", text.c_str ());
     }
   else
-    ui_out_field_string (uiout, "what",
+    uiout->field_string ("what",
 			 c->catch_all ? "<any signal>" : "<standard signals>");
-  ui_out_text (uiout, "\" ");
+  uiout->text ("\" ");
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "signal");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "signal");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for signal
diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c
index a4df2ce..8d34173 100644
--- a/gdb/break-catch-syscall.c
+++ b/gdb/break-catch-syscall.c
@@ -257,30 +257,30 @@  print_it_catch_syscall (bpstat bs)
   maybe_print_thread_hit_breakpoint (uiout);
 
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
 			   async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
 						? EXEC_ASYNC_SYSCALL_ENTRY
 						: EXEC_ASYNC_SYSCALL_RETURN));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
+  uiout->field_int ("bkptno", b->number);
 
   if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
-    ui_out_text (uiout, " (call to syscall ");
+    uiout->text (" (call to syscall ");
   else
-    ui_out_text (uiout, " (returned from syscall ");
+    uiout->text (" (returned from syscall ");
 
-  if (s.name == NULL || ui_out_is_mi_like_p (uiout))
-    ui_out_field_int (uiout, "syscall-number", last.value.syscall_number);
+  if (s.name == NULL || uiout->is_mi_like_p ())
+    uiout->field_int ("syscall-number", last.value.syscall_number);
   if (s.name != NULL)
-    ui_out_field_string (uiout, "syscall-name", s.name);
+    uiout->field_string ("syscall-name", s.name);
 
-  ui_out_text (uiout, "), ");
+  uiout->text ("), ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -302,14 +302,14 @@  print_one_catch_syscall (struct breakpoint *b,
      line up too nicely with the headers, but the effect is relatively
      readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
 
   if (c->syscalls_to_be_caught
       && VEC_length (int, c->syscalls_to_be_caught) > 1)
-    ui_out_text (uiout, "syscalls \"");
+    uiout->text ("syscalls \"");
   else
-    ui_out_text (uiout, "syscall \"");
+    uiout->text ("syscall \"");
 
   if (c->syscalls_to_be_caught)
     {
@@ -336,14 +336,14 @@  print_one_catch_syscall (struct breakpoint *b,
         }
       /* Remove the last comma.  */
       text[strlen (text) - 2] = '\0';
-      ui_out_field_string (uiout, "what", text);
+      uiout->field_string ("what", text);
     }
   else
-    ui_out_field_string (uiout, "what", "<any syscall>");
-  ui_out_text (uiout, "\" ");
+    uiout->field_string ("what", "<any syscall>");
+  uiout->text ("\" ");
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "syscall");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "syscall");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for syscall
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 955b2ff..4a4e7ec 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -261,21 +261,19 @@  print_it_exception_catchpoint (bpstat bs)
   maybe_print_thread_hit_breakpoint (uiout);
 
   bp_temp = b->disposition == disp_del;
-  ui_out_text (uiout, 
-	       bp_temp ? "Temporary catchpoint "
+  uiout->text (bp_temp ? "Temporary catchpoint "
 		       : "Catchpoint ");
-  if (!ui_out_is_mi_like_p (uiout))
-    ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout,
-	       (kind == EX_EVENT_THROW ? " (exception thrown), "
+  if (!uiout->is_mi_like_p ())
+    uiout->field_int ("bkptno", b->number);
+  uiout->text ((kind == EX_EVENT_THROW ? " (exception thrown), "
 		: (kind == EX_EVENT_CATCH ? " (exception caught), "
 		   : " (exception rethrown), ")));
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason", 
+      uiout->field_string ("reason", 
 			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
-      ui_out_field_int (uiout, "bkptno", b->number);
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
+      uiout->field_int ("bkptno", b->number);
     }
   return PRINT_SRC_AND_LOC;
 }
@@ -293,9 +291,9 @@  print_one_exception_catchpoint (struct breakpoint *b,
     {
       annotate_field (4);
       if (b->loc == NULL || b->loc->shlib_disabled)
-	ui_out_field_string (uiout, "addr", "<PENDING>");
+	uiout->field_string ("addr", "<PENDING>");
       else
-	ui_out_field_core_addr (uiout, "addr",
+	uiout->field_core_addr ("addr",
 				b->loc->gdbarch, b->loc->address);
     }
   annotate_field (5);
@@ -305,21 +303,21 @@  print_one_exception_catchpoint (struct breakpoint *b,
   switch (kind)
     {
     case EX_EVENT_THROW:
-      ui_out_field_string (uiout, "what", "exception throw");
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "catch-type", "throw");
+      uiout->field_string ("what", "exception throw");
+      if (uiout->is_mi_like_p ())
+	uiout->field_string ("catch-type", "throw");
       break;
 
     case EX_EVENT_RETHROW:
-      ui_out_field_string (uiout, "what", "exception rethrow");
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "catch-type", "rethrow");
+      uiout->field_string ("what", "exception rethrow");
+      if (uiout->is_mi_like_p ())
+	uiout->field_string ("catch-type", "rethrow");
       break;
 
     case EX_EVENT_CATCH:
-      ui_out_field_string (uiout, "what", "exception catch");
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "catch-type", "catch");
+      uiout->field_string ("what", "exception catch");
+      if (uiout->is_mi_like_p ())
+	uiout->field_string ("catch-type", "catch");
       break;
     }
 }
@@ -335,9 +333,9 @@  print_one_detail_exception_catchpoint (const struct breakpoint *b,
 
   if (cp->exception_rx != NULL)
     {
-      ui_out_text (uiout, _("\tmatching: "));
-      ui_out_field_string (uiout, "regexp", cp->exception_rx);
-      ui_out_text (uiout, "\n");
+      uiout->text (_("\tmatching: "));
+      uiout->field_string ("regexp", cp->exception_rx);
+      uiout->text ("\n");
     }
 }
 
@@ -349,10 +347,10 @@  print_mention_exception_catchpoint (struct breakpoint *b)
   enum exception_event_kind kind = classify_exception_breakpoint (b);
 
   bp_temp = b->disposition == disp_del;
-  ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ")
+  uiout->text (bp_temp ? _("Temporary catchpoint ")
 			      : _("Catchpoint "));
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, (kind == EX_EVENT_THROW ? _(" (throw)")
+  uiout->field_int ("bkptno", b->number);
+  uiout->text ((kind == EX_EVENT_THROW ? _(" (throw)")
 		       : (kind == EX_EVENT_CATCH ? _(" (catch)")
 			  : _(" (rethrow)"))));
 }
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 92aac3a..bc519c0 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -4800,28 +4800,28 @@  watchpoint_value_print (struct value *val, struct ui_file *stream)
 void
 maybe_print_thread_hit_breakpoint (struct ui_out *uiout)
 {
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     return;
 
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   if (show_thread_that_caused_stop ())
     {
       const char *name;
       struct thread_info *thr = inferior_thread ();
 
-      ui_out_text (uiout, "Thread ");
-      ui_out_field_fmt (uiout, "thread-id", "%s", print_thread_id (thr));
+      uiout->text ("Thread ");
+      uiout->field_fmt ("thread-id", "%s", print_thread_id (thr));
 
       name = thr->name != NULL ? thr->name : target_thread_name (thr);
       if (name != NULL)
 	{
-	  ui_out_text (uiout, " \"");
-	  ui_out_field_fmt (uiout, "name", "%s", name);
-	  ui_out_text (uiout, "\"");
+	  uiout->text (" \"");
+	  uiout->field_fmt ("name", "%s", name);
+	  uiout->text ("\"");
 	}
 
-      ui_out_text (uiout, " hit ");
+      uiout->text (" hit ");
     }
 }
 
@@ -4881,17 +4881,15 @@  print_solib_event (int is_catchpoint)
   if (!is_catchpoint)
     {
       if (any_added || any_deleted)
-	ui_out_text (current_uiout,
-		     _("Stopped due to shared library event:\n"));
+	current_uiout->text (_("Stopped due to shared library event:\n"));
       else
-	ui_out_text (current_uiout,
-		     _("Stopped due to shared library event (no "
-		       "libraries added or removed)\n"));
+	current_uiout->text (_("Stopped due to shared library event (no "
+			       "libraries added or removed)\n"));
     }
 
-  if (ui_out_is_mi_like_p (current_uiout))
-    ui_out_field_string (current_uiout, "reason",
-			 async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
+  if (current_uiout->is_mi_like_p ())
+    current_uiout->field_string ("reason",
+				 async_reason_lookup (EXEC_ASYNC_SOLIB_EVENT));
 
   if (any_deleted)
     {
@@ -4899,7 +4897,7 @@  print_solib_event (int is_catchpoint)
       char *name;
       int ix;
 
-      ui_out_text (current_uiout, _("  Inferior unloaded "));
+      current_uiout->text (_("  Inferior unloaded "));
       cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
 						    "removed");
       for (ix = 0;
@@ -4908,9 +4906,9 @@  print_solib_event (int is_catchpoint)
 	   ++ix)
 	{
 	  if (ix > 0)
-	    ui_out_text (current_uiout, "    ");
-	  ui_out_field_string (current_uiout, "library", name);
-	  ui_out_text (current_uiout, "\n");
+	    current_uiout->text ("    ");
+	  current_uiout->field_string ("library", name);
+	  current_uiout->text ("\n");
 	}
 
       do_cleanups (cleanup);
@@ -4922,7 +4920,7 @@  print_solib_event (int is_catchpoint)
       int ix;
       struct cleanup *cleanup;
 
-      ui_out_text (current_uiout, _("  Inferior loaded "));
+      current_uiout->text (_("  Inferior loaded "));
       cleanup = make_cleanup_ui_out_list_begin_end (current_uiout,
 						    "added");
       for (ix = 0;
@@ -4931,9 +4929,9 @@  print_solib_event (int is_catchpoint)
 	   ++ix)
 	{
 	  if (ix > 0)
-	    ui_out_text (current_uiout, "    ");
-	  ui_out_field_string (current_uiout, "library", iter->so_name);
-	  ui_out_text (current_uiout, "\n");
+	    current_uiout->text ("    ");
+	  current_uiout->field_string ("library", iter->so_name);
+	  current_uiout->text ("\n");
 	}
 
       do_cleanups (cleanup);
@@ -5257,13 +5255,12 @@  watchpoint_check (void *p)
         {
 	  struct ui_out *uiout = current_uiout;
 
-	  if (ui_out_is_mi_like_p (uiout))
-	    ui_out_field_string
-	      (uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
-	  ui_out_text (uiout, "\nWatchpoint ");
-	  ui_out_field_int (uiout, "wpnum", b->base.number);
-	  ui_out_text (uiout,
-		       " deleted because the program has left the block in\n"
+	  if (uiout->is_mi_like_p ())
+	    uiout->field_string
+	      ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
+	  uiout->text ("\nWatchpoint ");
+	  uiout->field_int ("wpnum", b->base.number);
+	  uiout->text (" deleted because the program has left the block in\n"
 		       "which its expression is valid.\n");
 	}
 
@@ -6065,7 +6062,7 @@  wrap_indent_at_field (struct ui_out *uiout, const char *col_name)
   const char *text;
 
   total_width = 0;
-  for (i = 1; ui_out_query_field (uiout, i, &width, &align, &text); i++)
+  for (i = 1; uiout->query_table_field (i, &width, &align, &text); i++)
     {
       if (strcmp (text, col_name) == 0)
 	{
@@ -6158,30 +6155,27 @@  print_breakpoint_location (struct breakpoint *b,
     set_current_program_space (loc->pspace);
 
   if (b->display_canonical)
-    ui_out_field_string (uiout, "what",
-			 event_location_to_string (b->location));
+    uiout->field_string ("what", event_location_to_string (b->location));
   else if (loc && loc->symtab)
     {
       struct symbol *sym 
 	= find_pc_sect_function (loc->address, loc->section);
       if (sym)
 	{
-	  ui_out_text (uiout, "in ");
-	  ui_out_field_string (uiout, "func",
-			       SYMBOL_PRINT_NAME (sym));
-	  ui_out_text (uiout, " ");
-	  ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what"));
-	  ui_out_text (uiout, "at ");
+	  uiout->text ("in ");
+	  uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+	  uiout->text (" ");
+	  uiout->wrap_hint (wrap_indent_at_field (uiout, "what"));
+	  uiout->text ("at ");
 	}
-      ui_out_field_string (uiout, "file",
+      uiout->field_string ("file",
 			   symtab_to_filename_for_display (loc->symtab));
-      ui_out_text (uiout, ":");
+      uiout->text (":");
 
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "fullname",
-			     symtab_to_fullname (loc->symtab));
+      if (uiout->is_mi_like_p ())
+	uiout->field_string ("fullname", symtab_to_fullname (loc->symtab));
       
-      ui_out_field_int (uiout, "line", loc->line_number);
+      uiout->field_int ("line", loc->line_number);
     }
   else if (loc)
     {
@@ -6190,24 +6184,23 @@  print_breakpoint_location (struct breakpoint *b,
 
       print_address_symbolic (loc->gdbarch, loc->address, stb,
 			      demangle, "");
-      ui_out_field_stream (uiout, "at", stb);
+      uiout->field_stream ("at", stb);
 
       do_cleanups (stb_chain);
     }
   else
     {
-      ui_out_field_string (uiout, "pending",
-			   event_location_to_string (b->location));
+      uiout->field_string ("pending", event_location_to_string (b->location));
       /* If extra_string is available, it could be holding a condition
 	 or dprintf arguments.  In either case, make sure it is printed,
 	 too, but only for non-MI streams.  */
-      if (!ui_out_is_mi_like_p (uiout) && b->extra_string != NULL)
+      if (!uiout->is_mi_like_p () && b->extra_string != NULL)
 	{
 	  if (b->type == bp_dprintf)
-	    ui_out_text (uiout, ",");
+	    uiout->text (",");
 	  else
-	    ui_out_text (uiout, " ");
-	  ui_out_text (uiout, b->extra_string);
+	    uiout->text (" ");
+	  uiout->text (b->extra_string);
 	}
     }
 
@@ -6215,10 +6208,10 @@  print_breakpoint_location (struct breakpoint *b,
       && breakpoint_condition_evaluation_mode () == condition_evaluation_target
       && bp_condition_evaluator (b) == condition_evaluation_both)
     {
-      ui_out_text (uiout, " (");
-      ui_out_field_string (uiout, "evaluated-by",
+      uiout->text (" (");
+      uiout->field_string ("evaluated-by",
 			   bp_location_condition_evaluator (loc));
-      ui_out_text (uiout, ")");
+      uiout->text (")");
     }
 
   do_cleanups (old_chain);
@@ -6289,7 +6282,7 @@  output_thread_groups (struct ui_out *uiout,
 		      int mi_only)
 {
   struct cleanup *back_to;
-  int is_mi = ui_out_is_mi_like_p (uiout);
+  int is_mi = uiout->is_mi_like_p ();
   int inf;
   int i;
 
@@ -6307,16 +6300,16 @@  output_thread_groups (struct ui_out *uiout,
 	  char mi_group[10];
 
 	  xsnprintf (mi_group, sizeof (mi_group), "i%d", inf);
-	  ui_out_field_string (uiout, NULL, mi_group);
+	  uiout->field_string (NULL, mi_group);
 	}
       else
 	{
 	  if (i == 0)
-	    ui_out_text (uiout, " inf ");
+	    uiout->text (" inf ");
 	  else
-	    ui_out_text (uiout, ", ");
+	    uiout->text (", ");
 	
-	  ui_out_text (uiout, plongest (inf));
+	  uiout->text (plongest (inf));
 	}
     }
 
@@ -6360,37 +6353,37 @@  print_one_breakpoint_location (struct breakpoint *b,
     {
       char *formatted;
       formatted = xstrprintf ("%d.%d", b->number, loc_number);
-      ui_out_field_string (uiout, "number", formatted);
+      uiout->field_string ("number", formatted);
       xfree (formatted);
     }
   else
     {
-      ui_out_field_int (uiout, "number", b->number);
+      uiout->field_int ("number", b->number);
     }
 
   /* 2 */
   annotate_field (1);
   if (part_of_multiple)
-    ui_out_field_skip (uiout, "type");
+    uiout->field_skip ("type");
   else
-    ui_out_field_string (uiout, "type", bptype_string (b->type));
+    uiout->field_string ("type", bptype_string (b->type));
 
   /* 3 */
   annotate_field (2);
   if (part_of_multiple)
-    ui_out_field_skip (uiout, "disp");
+    uiout->field_skip ("disp");
   else
-    ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    uiout->field_string ("disp", bpdisp_text (b->disposition));
 
 
   /* 4 */
   annotate_field (3);
   if (part_of_multiple)
-    ui_out_field_string (uiout, "enabled", loc->enabled ? "y" : "n");
+    uiout->field_string ("enabled", loc->enabled ? "y" : "n");
   else
-    ui_out_field_fmt (uiout, "enabled", "%c", 
+    uiout->field_fmt ("enabled", "%c", 
 		      bpenables[(int) b->enable_state]);
-  ui_out_spaces (uiout, 2);
+  uiout->spaces (2);
 
   
   /* 5 and 6 */
@@ -6421,9 +6414,9 @@  print_one_breakpoint_location (struct breakpoint *b,
 	     not line up too nicely with the headers, but the effect
 	     is relatively readable).  */
 	  if (opts.addressprint)
-	    ui_out_field_skip (uiout, "addr");
+	    uiout->field_skip ("addr");
 	  annotate_field (5);
-	  ui_out_field_string (uiout, "what", w->exp_string);
+	  uiout->field_string ("what", w->exp_string);
 	}
 	break;
 
@@ -6459,11 +6452,11 @@  print_one_breakpoint_location (struct breakpoint *b,
 	  {
 	    annotate_field (4);
 	    if (header_of_multiple)
-	      ui_out_field_string (uiout, "addr", "<MULTIPLE>");
+	      uiout->field_string ("addr", "<MULTIPLE>");
 	    else if (b->loc == NULL || loc->shlib_disabled)
-	      ui_out_field_string (uiout, "addr", "<PENDING>");
+	      uiout->field_string ("addr", "<PENDING>");
 	    else
-	      ui_out_field_core_addr (uiout, "addr",
+	      uiout->field_core_addr ("addr",
 				      loc->gdbarch, loc->address);
 	  }
 	annotate_field (5);
@@ -6507,17 +6500,17 @@  print_one_breakpoint_location (struct breakpoint *b,
 	{
 	  /* FIXME: This seems to be redundant and lost here; see the
 	     "stop only in" line a little further down.  */
-	  ui_out_text (uiout, " thread ");
-	  ui_out_field_int (uiout, "thread", b->thread);
+	  uiout->text (" thread ");
+	  uiout->field_int ("thread", b->thread);
 	}
       else if (b->task != 0)
 	{
-	  ui_out_text (uiout, " task ");
-	  ui_out_field_int (uiout, "task", b->task);
+	  uiout->text (" task ");
+	  uiout->field_int ("task", b->task);
 	}
     }
 
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   if (!part_of_multiple)
     b->ops->print_one_detail (b, uiout);
@@ -6525,22 +6518,22 @@  print_one_breakpoint_location (struct breakpoint *b,
   if (part_of_multiple && frame_id_p (b->frame_id))
     {
       annotate_field (6);
-      ui_out_text (uiout, "\tstop only in stack frame at ");
+      uiout->text ("\tstop only in stack frame at ");
       /* FIXME: cagney/2002-12-01: Shouldn't be poking around inside
          the frame ID.  */
-      ui_out_field_core_addr (uiout, "frame",
+      uiout->field_core_addr ("frame",
 			      b->gdbarch, b->frame_id.stack_addr);
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
   
   if (!part_of_multiple && b->cond_string)
     {
       annotate_field (7);
       if (is_tracepoint (b))
-	ui_out_text (uiout, "\ttrace only if ");
+	uiout->text ("\ttrace only if ");
       else
-	ui_out_text (uiout, "\tstop only if ");
-      ui_out_field_string (uiout, "cond", b->cond_string);
+	uiout->text ("\tstop only if ");
+      uiout->field_string ("cond", b->cond_string);
 
       /* Print whether the target is doing the breakpoint's condition
 	 evaluation.  If GDB is doing the evaluation, don't print anything.  */
@@ -6548,27 +6541,27 @@  print_one_breakpoint_location (struct breakpoint *b,
 	  && breakpoint_condition_evaluation_mode ()
 	  == condition_evaluation_target)
 	{
-	  ui_out_text (uiout, " (");
-	  ui_out_field_string (uiout, "evaluated-by",
+	  uiout->text (" (");
+	  uiout->field_string ("evaluated-by",
 			       bp_condition_evaluator (b));
-	  ui_out_text (uiout, " evals)");
+	  uiout->text (" evals)");
 	}
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
 
   if (!part_of_multiple && b->thread != -1)
     {
       /* FIXME should make an annotation for this.  */
-      ui_out_text (uiout, "\tstop only in thread ");
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_int (uiout, "thread", b->thread);
+      uiout->text ("\tstop only in thread ");
+      if (uiout->is_mi_like_p ())
+	uiout->field_int ("thread", b->thread);
       else
 	{
 	  struct thread_info *thr = find_thread_global_id (b->thread);
 
-	  ui_out_field_string (uiout, "thread", print_thread_id (thr));
+	  uiout->field_string ("thread", print_thread_id (thr));
 	}
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
   
   if (!part_of_multiple)
@@ -6577,32 +6570,32 @@  print_one_breakpoint_location (struct breakpoint *b,
 	{
 	  /* FIXME should make an annotation for this.  */
 	  if (is_catchpoint (b))
-	    ui_out_text (uiout, "\tcatchpoint");
+	    uiout->text ("\tcatchpoint");
 	  else if (is_tracepoint (b))
-	    ui_out_text (uiout, "\ttracepoint");
+	    uiout->text ("\ttracepoint");
 	  else
-	    ui_out_text (uiout, "\tbreakpoint");
-	  ui_out_text (uiout, " already hit ");
-	  ui_out_field_int (uiout, "times", b->hit_count);
+	    uiout->text ("\tbreakpoint");
+	  uiout->text (" already hit ");
+	  uiout->field_int ("times", b->hit_count);
 	  if (b->hit_count == 1)
-	    ui_out_text (uiout, " time\n");
+	    uiout->text (" time\n");
 	  else
-	    ui_out_text (uiout, " times\n");
+	    uiout->text (" times\n");
 	}
       else
 	{
 	  /* Output the count also if it is zero, but only if this is mi.  */
-	  if (ui_out_is_mi_like_p (uiout))
-	    ui_out_field_int (uiout, "times", b->hit_count);
+	  if (uiout->is_mi_like_p ())
+	    uiout->field_int ("times", b->hit_count);
 	}
     }
 
   if (!part_of_multiple && b->ignore_count)
     {
       annotate_field (8);
-      ui_out_text (uiout, "\tignore next ");
-      ui_out_field_int (uiout, "ignore", b->ignore_count);
-      ui_out_text (uiout, " hits\n");
+      uiout->text ("\tignore next ");
+      uiout->field_int ("ignore", b->ignore_count);
+      uiout->text (" hits\n");
     }
 
   /* Note that an enable count of 1 corresponds to "enable once"
@@ -6611,15 +6604,15 @@  print_one_breakpoint_location (struct breakpoint *b,
   if (!part_of_multiple && b->enable_count > 1)
     {
       annotate_field (8);
-      ui_out_text (uiout, "\tdisable after ");
+      uiout->text ("\tdisable after ");
       /* Tweak the wording to clarify that ignore and enable counts
 	 are distinct, and have additive effect.  */
       if (b->ignore_count)
-	ui_out_text (uiout, "additional ");
+	uiout->text ("additional ");
       else
-	ui_out_text (uiout, "next ");
-      ui_out_field_int (uiout, "enable", b->enable_count);
-      ui_out_text (uiout, " hits\n");
+	uiout->text ("next ");
+      uiout->field_int ("enable", b->enable_count);
+      uiout->text (" hits\n");
     }
 
   if (!part_of_multiple && is_tracepoint (b))
@@ -6628,9 +6621,9 @@  print_one_breakpoint_location (struct breakpoint *b,
 
       if (tp->traceframe_usage)
 	{
-	  ui_out_text (uiout, "\ttrace buffer usage ");
-	  ui_out_field_int (uiout, "traceframe-usage", tp->traceframe_usage);
-	  ui_out_text (uiout, " bytes\n");
+	  uiout->text ("\ttrace buffer usage ");
+	  uiout->field_int ("traceframe-usage", tp->traceframe_usage);
+	  uiout->text (" bytes\n");
 	}
     }
 
@@ -6652,9 +6645,9 @@  print_one_breakpoint_location (struct breakpoint *b,
       if (!part_of_multiple && t->pass_count)
 	{
 	  annotate_field (10);
-	  ui_out_text (uiout, "\tpass count ");
-	  ui_out_field_int (uiout, "pass", t->pass_count);
-	  ui_out_text (uiout, " \n");
+	  uiout->text ("\tpass count ");
+	  uiout->field_int ("pass", t->pass_count);
+	  uiout->text (" \n");
 	}
 
       /* Don't display it when tracepoint or tracepoint location is
@@ -6663,31 +6656,31 @@  print_one_breakpoint_location (struct breakpoint *b,
 	{
 	  annotate_field (11);
 
-	  if (ui_out_is_mi_like_p (uiout))
-	    ui_out_field_string (uiout, "installed",
+	  if (uiout->is_mi_like_p ())
+	    uiout->field_string ("installed",
 				 loc->inserted ? "y" : "n");
 	  else
 	    {
 	      if (loc->inserted)
-		ui_out_text (uiout, "\t");
+		uiout->text ("\t");
 	      else
-		ui_out_text (uiout, "\tnot ");
-	      ui_out_text (uiout, "installed on target\n");
+		uiout->text ("\tnot ");
+	      uiout->text ("installed on target\n");
 	    }
 	}
     }
 
-  if (ui_out_is_mi_like_p (uiout) && !part_of_multiple)
+  if (uiout->is_mi_like_p () && !part_of_multiple)
     {
       if (is_watchpoint (b))
 	{
 	  struct watchpoint *w = (struct watchpoint *) b;
 
-	  ui_out_field_string (uiout, "original-location", w->exp_string);
+	  uiout->field_string ("original-location", w->exp_string);
 	}
       else if (b->location != NULL
 	       && event_location_to_string (b->location) != NULL)
-	ui_out_field_string (uiout, "original-location",
+	uiout->field_string ("original-location",
 			     event_location_to_string (b->location));
     }
 }
@@ -6887,32 +6880,29 @@  breakpoint_1 (char *args, int allflag,
     annotate_breakpoints_headers ();
   if (nr_printable_breakpoints > 0)
     annotate_field (0);
-  ui_out_table_header (uiout, 7, ui_left, "number", "Num");	/* 1 */
+  uiout->table_header (7, ui_left, "number", "Num"); /* 1 */
   if (nr_printable_breakpoints > 0)
     annotate_field (1);
-  ui_out_table_header (uiout, print_type_col_width, ui_left,
-		       "type", "Type");				/* 2 */
+  uiout->table_header (print_type_col_width, ui_left, "type", "Type"); /* 2 */
   if (nr_printable_breakpoints > 0)
     annotate_field (2);
-  ui_out_table_header (uiout, 4, ui_left, "disp", "Disp");	/* 3 */
+  uiout->table_header (4, ui_left, "disp", "Disp"); /* 3 */
   if (nr_printable_breakpoints > 0)
     annotate_field (3);
-  ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");	/* 4 */
+  uiout->table_header (3, ui_left, "enabled", "Enb"); /* 4 */
   if (opts.addressprint)
     {
       if (nr_printable_breakpoints > 0)
 	annotate_field (4);
       if (print_address_bits <= 32)
-	ui_out_table_header (uiout, 10, ui_left, 
-			     "addr", "Address");		/* 5 */
+	uiout->table_header (10, ui_left, "addr", "Address"); /* 5 */
       else
-	ui_out_table_header (uiout, 18, ui_left, 
-			     "addr", "Address");		/* 5 */
+	uiout->table_header (18, ui_left, "addr", "Address"); /* 5 */
     }
   if (nr_printable_breakpoints > 0)
     annotate_field (5);
-  ui_out_table_header (uiout, 40, ui_noalign, "what", "What");	/* 6 */
-  ui_out_table_body (uiout);
+  uiout->table_header (40, ui_noalign, "what", "What"); /* 6 */
+  uiout->table_body ();
   if (nr_printable_breakpoints > 0)
     annotate_breakpoints_table ();
 
@@ -6954,10 +6944,9 @@  breakpoint_1 (char *args, int allflag,
       if (!filter)
 	{
 	  if (args == NULL || *args == '\0')
-	    ui_out_message (uiout, "No breakpoints or watchpoints.\n");
+	    uiout->message ("No breakpoints or watchpoints.\n");
 	  else
-	    ui_out_message (uiout,
-			    "No breakpoint or watchpoint matching '%s'.\n",
+	    uiout->message ("No breakpoint or watchpoint matching '%s'.\n",
 			    args);
 	}
     }
@@ -6990,9 +6979,9 @@  default_collect_info (void)
 
   /* The following phrase lines up nicely with per-tracepoint collect
      actions.  */
-  ui_out_text (uiout, "default collect ");
-  ui_out_field_string (uiout, "default-collect", default_collect);
-  ui_out_text (uiout, " \n");
+  uiout->text ("default collect ");
+  uiout->field_string ("default-collect", default_collect);
+  uiout->text (" \n");
 }
   
 static void
@@ -7012,9 +7001,9 @@  watchpoints_info (char *args, int from_tty)
   if (num_printed == 0)
     {
       if (args == NULL || *args == '\0')
-	ui_out_message (uiout, "No watchpoints.\n");
+	uiout->message ("No watchpoints.\n");
       else
-	ui_out_message (uiout, "No watchpoint matching '%s'.\n", args);
+	uiout->message ("No watchpoint matching '%s'.\n", args);
     }
 }
 
@@ -8133,19 +8122,18 @@  print_it_catch_fork (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
-			   async_reason_lookup (EXEC_ASYNC_FORK));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_FORK));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, " (forked process ");
-  ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
-  ui_out_text (uiout, "), ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (" (forked process ");
+  uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+  uiout->text ("), ");
   return PRINT_SRC_AND_LOC;
 }
 
@@ -8165,19 +8153,18 @@  print_one_catch_fork (struct breakpoint *b, struct bp_location **last_loc)
      line up too nicely with the headers, but the effect is relatively
      readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
-  ui_out_text (uiout, "fork");
+  uiout->text ("fork");
   if (!ptid_equal (c->forked_inferior_pid, null_ptid))
     {
-      ui_out_text (uiout, ", process ");
-      ui_out_field_int (uiout, "what",
-                        ptid_get_pid (c->forked_inferior_pid));
-      ui_out_spaces (uiout, 1);
+      uiout->text (", process ");
+      uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+      uiout->spaces (1);
     }
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "fork");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "fork");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for fork
@@ -8251,19 +8238,18 @@  print_it_catch_vfork (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
-			   async_reason_lookup (EXEC_ASYNC_VFORK));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_VFORK));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, " (vforked process ");
-  ui_out_field_int (uiout, "newpid", ptid_get_pid (c->forked_inferior_pid));
-  ui_out_text (uiout, "), ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (" (vforked process ");
+  uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+  uiout->text ("), ");
   return PRINT_SRC_AND_LOC;
 }
 
@@ -8282,19 +8268,18 @@  print_one_catch_vfork (struct breakpoint *b, struct bp_location **last_loc)
      line up too nicely with the headers, but the effect is relatively
      readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
-  ui_out_text (uiout, "vfork");
+  uiout->text ("vfork");
   if (!ptid_equal (c->forked_inferior_pid, null_ptid))
     {
-      ui_out_text (uiout, ", process ");
-      ui_out_field_int (uiout, "what",
-                        ptid_get_pid (c->forked_inferior_pid));
-      ui_out_spaces (uiout, 1);
+      uiout->text (", process ");
+      uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+      uiout->spaces (1);
     }
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "vfork");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "vfork");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for vfork
@@ -8448,13 +8433,13 @@  print_it_catch_solib (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, "\n");
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+    uiout->text ("Catchpoint ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text ("\n");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("disp", bpdisp_text (b->disposition));
   print_solib_event (1);
   return PRINT_SRC_AND_LOC;
 }
@@ -8474,7 +8459,7 @@  print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
   if (opts.addressprint)
     {
       annotate_field (4);
-      ui_out_field_skip (uiout, "addr");
+      uiout->field_skip ("addr");
     }
 
   annotate_field (5);
@@ -8492,12 +8477,11 @@  print_one_catch_solib (struct breakpoint *b, struct bp_location **locs)
       else
 	msg = xstrdup (_("unload of library"));
     }
-  ui_out_field_string (uiout, "what", msg);
+  uiout->field_string ("what", msg);
   xfree (msg);
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type",
-			 self->is_load ? "load" : "unload");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", self->is_load ? "load" : "unload");
 }
 
 static void
@@ -8718,19 +8702,18 @@  print_it_catch_exec (bpstat bs)
   annotate_catchpoint (b->number);
   maybe_print_thread_hit_breakpoint (uiout);
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "Catchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
-			   async_reason_lookup (EXEC_ASYNC_EXEC));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXEC));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, " (exec'd ");
-  ui_out_field_string (uiout, "new-exec", c->exec_pathname);
-  ui_out_text (uiout, "), ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (" (exec'd ");
+  uiout->field_string ("new-exec", c->exec_pathname);
+  uiout->text ("), ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -8748,18 +8731,18 @@  print_one_catch_exec (struct breakpoint *b, struct bp_location **last_loc)
      not line up too nicely with the headers, but the effect
      is relatively readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
-  ui_out_text (uiout, "exec");
+  uiout->text ("exec");
   if (c->exec_pathname != NULL)
     {
-      ui_out_text (uiout, ", program \"");
-      ui_out_field_string (uiout, "what", c->exec_pathname);
-      ui_out_text (uiout, "\" ");
+      uiout->text (", program \"");
+      uiout->field_string ("what", c->exec_pathname);
+      uiout->text ("\" ");
     }
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "exec");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "exec");
 }
 
 static void
@@ -9019,7 +9002,7 @@  static void
 mention (struct breakpoint *b)
 {
   b->ops->print_mention (b);
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     return;
   printf_filtered ("\n");
 }
@@ -10262,17 +10245,17 @@  print_it_ranged_breakpoint (bpstat bs)
   maybe_print_thread_hit_breakpoint (uiout);
 
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "Temporary ranged breakpoint ");
+    uiout->text ("Temporary ranged breakpoint ");
   else
-    ui_out_text (uiout, "Ranged breakpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Ranged breakpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
 		      async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, ", ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (", ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -10296,7 +10279,7 @@  print_one_ranged_breakpoint (struct breakpoint *b,
   if (opts.addressprint)
     /* We don't print the address range here, it will be printed later
        by print_one_detail_ranged_breakpoint.  */
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
   print_breakpoint_location (b, bl);
   *last_loc = bl;
@@ -10319,12 +10302,12 @@  print_one_detail_ranged_breakpoint (const struct breakpoint *b,
   address_start = bl->address;
   address_end = address_start + bl->length - 1;
 
-  ui_out_text (uiout, "\taddress range: ");
+  uiout->text ("\taddress range: ");
   fprintf_unfiltered (stb, "[%s, %s]",
 		      print_core_address (bl->gdbarch, address_start),
 		      print_core_address (bl->gdbarch, address_end));
-  ui_out_field_stream (uiout, "addr", stb);
-  ui_out_text (uiout, "\n");
+  uiout->field_stream ("addr", stb);
+  uiout->text ("\n");
 
   do_cleanups (cleanup);
 }
@@ -10341,7 +10324,7 @@  print_mention_ranged_breakpoint (struct breakpoint *b)
   gdb_assert (bl);
   gdb_assert (b->type == bp_hardware_breakpoint);
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     return;
 
   printf_filtered (_("Hardware assisted ranged breakpoint %d from %s to %s."),
@@ -10778,64 +10761,62 @@  print_it_watchpoint (bpstat bs)
     {
     case bp_watchpoint:
     case bp_hardware_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string
-	  (uiout, "reason",
-	   async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+	uiout->field_string
+	  ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
       mention (b);
       make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-      ui_out_text (uiout, "\nOld value = ");
+      uiout->text ("\nOld value = ");
       watchpoint_value_print (bs->old_val, stb);
-      ui_out_field_stream (uiout, "old", stb);
-      ui_out_text (uiout, "\nNew value = ");
+      uiout->field_stream ("old", stb);
+      uiout->text ("\nNew value = ");
       watchpoint_value_print (w->val, stb);
-      ui_out_field_stream (uiout, "new", stb);
-      ui_out_text (uiout, "\n");
+      uiout->field_stream ("new", stb);
+      uiout->text ("\n");
       /* More than one watchpoint may have been triggered.  */
       result = PRINT_UNKNOWN;
       break;
 
     case bp_read_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string
-	  (uiout, "reason",
-	   async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+	uiout->field_string
+	  ("reason", async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
       mention (b);
       make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-      ui_out_text (uiout, "\nValue = ");
+      uiout->text ("\nValue = ");
       watchpoint_value_print (w->val, stb);
-      ui_out_field_stream (uiout, "value", stb);
-      ui_out_text (uiout, "\n");
+      uiout->field_stream ("value", stb);
+      uiout->text ("\n");
       result = PRINT_UNKNOWN;
       break;
 
     case bp_access_watchpoint:
       if (bs->old_val != NULL)
 	{
-	  if (ui_out_is_mi_like_p (uiout))
-	    ui_out_field_string
-	      (uiout, "reason",
+	  if (uiout->is_mi_like_p ())
+	    uiout->field_string
+	      ("reason",
 	       async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
 	  mention (b);
 	  make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-	  ui_out_text (uiout, "\nOld value = ");
+	  uiout->text ("\nOld value = ");
 	  watchpoint_value_print (bs->old_val, stb);
-	  ui_out_field_stream (uiout, "old", stb);
-	  ui_out_text (uiout, "\nNew value = ");
+	  uiout->field_stream ("old", stb);
+	  uiout->text ("\nNew value = ");
 	}
       else
 	{
 	  mention (b);
-	  if (ui_out_is_mi_like_p (uiout))
-	    ui_out_field_string
-	      (uiout, "reason",
+	  if (uiout->is_mi_like_p ())
+	    uiout->field_string
+	      ("reason",
 	       async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
 	  make_cleanup_ui_out_tuple_begin_end (uiout, "value");
-	  ui_out_text (uiout, "\nValue = ");
+	  uiout->text ("\nValue = ");
 	}
       watchpoint_value_print (w->val, stb);
-      ui_out_field_stream (uiout, "new", stb);
-      ui_out_text (uiout, "\n");
+      uiout->field_stream ("new", stb);
+      uiout->text ("\n");
       result = PRINT_UNKNOWN;
       break;
     default:
@@ -10859,19 +10840,19 @@  print_mention_watchpoint (struct breakpoint *b)
   switch (b->type)
     {
     case bp_watchpoint:
-      ui_out_text (uiout, "Watchpoint ");
+      uiout->text ("Watchpoint ");
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
       break;
     case bp_hardware_watchpoint:
-      ui_out_text (uiout, "Hardware watchpoint ");
+      uiout->text ("Hardware watchpoint ");
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
       break;
     case bp_read_watchpoint:
-      ui_out_text (uiout, "Hardware read watchpoint ");
+      uiout->text ("Hardware read watchpoint ");
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
       break;
     case bp_access_watchpoint:
-      ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
+      uiout->text ("Hardware access (read/write) watchpoint ");
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
       break;
     default:
@@ -10879,9 +10860,9 @@  print_mention_watchpoint (struct breakpoint *b)
 		      _("Invalid hardware watchpoint type."));
     }
 
-  ui_out_field_int (uiout, "number", b->number);
-  ui_out_text (uiout, ": ");
-  ui_out_field_string (uiout, "exp", w->exp_string);
+  uiout->field_int ("number", b->number);
+  uiout->text (": ");
+  uiout->field_string ("exp", w->exp_string);
   do_cleanups (ui_out_chain);
 }
 
@@ -10994,23 +10975,21 @@  print_it_masked_watchpoint (bpstat bs)
   switch (b->type)
     {
     case bp_hardware_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string
-	  (uiout, "reason",
-	   async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+	uiout->field_string
+	  ("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
       break;
 
     case bp_read_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string
-	  (uiout, "reason",
-	   async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
+      if (uiout->is_mi_like_p ())
+	uiout->field_string
+	  ("reason", async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
       break;
 
     case bp_access_watchpoint:
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string
-	  (uiout, "reason",
+      if (uiout->is_mi_like_p ())
+	uiout->field_string
+	  ("reason",
 	   async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
       break;
     default:
@@ -11019,10 +10998,10 @@  print_it_masked_watchpoint (bpstat bs)
     }
 
   mention (b);
-  ui_out_text (uiout, _("\n\
+  uiout->text (_("\n\
 Check the underlying instruction at PC for the memory\n\
 address and value which triggered this watchpoint.\n"));
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   /* More than one watchpoint may have been triggered.  */
   return PRINT_UNKNOWN;
@@ -11040,9 +11019,9 @@  print_one_detail_masked_watchpoint (const struct breakpoint *b,
   /* Masked watchpoints have only one location.  */
   gdb_assert (b->loc && b->loc->next == NULL);
 
-  ui_out_text (uiout, "\tmask ");
-  ui_out_field_core_addr (uiout, "mask", b->loc->gdbarch, w->hw_wp_mask);
-  ui_out_text (uiout, "\n");
+  uiout->text ("\tmask ");
+  uiout->field_core_addr ("mask", b->loc->gdbarch, w->hw_wp_mask);
+  uiout->text ("\n");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for
@@ -11058,15 +11037,15 @@  print_mention_masked_watchpoint (struct breakpoint *b)
   switch (b->type)
     {
     case bp_hardware_watchpoint:
-      ui_out_text (uiout, "Masked hardware watchpoint ");
+      uiout->text ("Masked hardware watchpoint ");
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
       break;
     case bp_read_watchpoint:
-      ui_out_text (uiout, "Masked hardware read watchpoint ");
+      uiout->text ("Masked hardware read watchpoint ");
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
       break;
     case bp_access_watchpoint:
-      ui_out_text (uiout, "Masked hardware access (read/write) watchpoint ");
+      uiout->text ("Masked hardware access (read/write) watchpoint ");
       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
       break;
     default:
@@ -11074,9 +11053,9 @@  print_mention_masked_watchpoint (struct breakpoint *b)
 		      _("Invalid hardware watchpoint type."));
     }
 
-  ui_out_field_int (uiout, "number", b->number);
-  ui_out_text (uiout, ": ");
-  ui_out_field_string (uiout, "exp", w->exp_string);
+  uiout->field_int ("number", b->number);
+  uiout->text (": ");
+  uiout->field_string ("exp", w->exp_string);
   do_cleanups (ui_out_chain);
 }
 
@@ -13173,17 +13152,17 @@  bkpt_print_it (bpstat bs)
   maybe_print_thread_hit_breakpoint (uiout);
 
   if (bp_temp)
-    ui_out_text (uiout, "Temporary breakpoint ");
+    uiout->text ("Temporary breakpoint ");
   else
-    ui_out_text (uiout, "Breakpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Breakpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
 			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
-  ui_out_text (uiout, ", ");
+  uiout->field_int ("bkptno", b->number);
+  uiout->text (", ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -13191,7 +13170,7 @@  bkpt_print_it (bpstat bs)
 static void
 bkpt_print_mention (struct breakpoint *b)
 {
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     return;
 
   switch (b->type)
@@ -13507,17 +13486,17 @@  tracepoint_print_one_detail (const struct breakpoint *self,
     {
       gdb_assert (self->type == bp_static_tracepoint);
 
-      ui_out_text (uiout, "\tmarker id is ");
-      ui_out_field_string (uiout, "static-tracepoint-marker-string-id",
+      uiout->text ("\tmarker id is ");
+      uiout->field_string ("static-tracepoint-marker-string-id",
 			   tp->static_trace_marker_id);
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
 }
 
 static void
 tracepoint_print_mention (struct breakpoint *b)
 {
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     return;
 
   switch (b->type)
@@ -14157,26 +14136,25 @@  update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
 
 	  sal2 = find_pc_line (tpmarker->address, 0);
 	  sym = find_pc_sect_function (tpmarker->address, NULL);
-	  ui_out_text (uiout, "Now in ");
+	  uiout->text ("Now in ");
 	  if (sym)
 	    {
-	      ui_out_field_string (uiout, "func",
-				   SYMBOL_PRINT_NAME (sym));
-	      ui_out_text (uiout, " at ");
+	      uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+	      uiout->text (" at ");
 	    }
-	  ui_out_field_string (uiout, "file",
+	  uiout->field_string ("file",
 			       symtab_to_filename_for_display (sal2.symtab));
-	  ui_out_text (uiout, ":");
+	  uiout->text (":");
 
-	  if (ui_out_is_mi_like_p (uiout))
+	  if (uiout->is_mi_like_p ())
 	    {
 	      const char *fullname = symtab_to_fullname (sal2.symtab);
 
-	      ui_out_field_string (uiout, "fullname", fullname);
+	      uiout->field_string ("fullname", fullname);
 	    }
 
-	  ui_out_field_int (uiout, "line", sal2.line);
-	  ui_out_text (uiout, "\n");
+	  uiout->field_int ("line", sal2.line);
+	  uiout->text ("\n");
 
 	  b->loc->line_number = sal2.line;
 	  b->loc->symtab = sym != NULL ? sal2.symtab : NULL;
@@ -15470,9 +15448,9 @@  tracepoints_info (char *args, int from_tty)
   if (num_printed == 0)
     {
       if (args == NULL || *args == '\0')
-	ui_out_message (uiout, "No tracepoints.\n");
+	uiout->message ("No tracepoints.\n");
       else
-	ui_out_message (uiout, "No tracepoint matching '%s'.\n", args);
+	uiout->message ("No tracepoint matching '%s'.\n", args);
     }
 
   default_collect_info ();
@@ -15763,19 +15741,19 @@  save_breakpoints (char *filename, int from_tty,
       {
 	fprintf_unfiltered (fp, "  commands\n");
 	
-	ui_out_redirect (current_uiout, fp);
+	current_uiout->redirect (fp);
 	TRY
 	  {
 	    print_command_lines (current_uiout, tp->commands->commands, 2);
 	  }
 	CATCH (ex, RETURN_MASK_ALL)
 	  {
-	    ui_out_redirect (current_uiout, NULL);
+	    current_uiout->redirect (NULL);
 	    throw_exception (ex);
 	  }
 	END_CATCH
 
-	ui_out_redirect (current_uiout, NULL);
+	current_uiout->redirect (NULL);
 	fprintf_unfiltered (fp, "  end\n");
       }
 
diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index f5b5072..83e4cc2 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -26,163 +26,107 @@ 
 #include "completer.h"
 #include "readline/readline.h"
 
-typedef struct cli_ui_out_data cli_out_data;
-
-/* Prototypes for local functions */
-
-static void cli_text (struct ui_out *uiout, const char *string);
-
-static void field_separator (void);
-
-static void out_field_fmt (struct ui_out *uiout, int fldno,
-			   const char *fldname,
-			   const char *format,...) ATTRIBUTE_PRINTF (4, 5);
-
-/* The destructor.  */
-
-static void
-cli_uiout_dtor (struct ui_out *ui_out)
-{
-  cli_out_data *data = (cli_out_data *) ui_out_data (ui_out);
-
-  delete data;
-}
-
 /* These are the CLI output functions */
 
 /* Mark beginning of a table */
 
-static void
-cli_table_begin (struct ui_out *uiout, int nbrofcols,
-		 int nr_rows,
-		 const char *tblid)
+void
+cli_ui_out::do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
   if (nr_rows == 0)
-    data->suppress_output = 1;
+    m_suppress_output = true;
   else
     /* Only the table suppresses the output and, fortunately, a table
        is not a recursive data structure.  */
-    gdb_assert (data->suppress_output == 0);
+    gdb_assert (m_suppress_output == 0);
 }
 
 /* Mark beginning of a table body */
 
-static void
-cli_table_body (struct ui_out *uiout)
+void
+cli_ui_out::do_table_body ()
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
+
   /* first, close the table header line */
-  cli_text (uiout, "\n");
+  text ("\n");
 }
 
 /* Mark end of a table */
 
-static void
-cli_table_end (struct ui_out *uiout)
+void
+cli_ui_out::do_table_end ()
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  data->suppress_output = 0;
+  m_suppress_output = false;
 }
 
 /* Specify table header */
 
-static void
-cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
-		  const std::string &col_name, const std::string &col_hdr)
+void
+cli_ui_out::do_table_header (int width, ui_align alignment,
+			       const std::string &col_name,
+			       const std::string &col_hdr)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  /* Always go through the function pointer (virtual function call).
-     We may have been extended.  */
-  uo_field_string (uiout, 0, width, alignment, 0, col_hdr.c_str ());
+  do_field_string (0, width, alignment, 0, col_hdr.c_str ());
 }
 
 /* Mark beginning of a list */
 
-static void
-cli_begin (struct ui_out *uiout,
-	   enum ui_out_type type,
-	   const char *id)
+void
+cli_ui_out::do_begin (ui_out_type type, const char *id)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
-    return;
 }
 
 /* Mark end of a list */
 
-static void
-cli_end (struct ui_out *uiout,
-	 enum ui_out_type type)
+void
+cli_ui_out::do_end (ui_out_type type)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
-    return;
 }
 
 /* output an int field */
 
-static void
-cli_field_int (struct ui_out *uiout, int fldno, int width,
-	       enum ui_align alignment,
-	       const char *fldname, int value)
+void
+cli_ui_out::do_field_int (int fldno, int width, ui_align alignment,
+			    const char *fldname, int value)
 {
   char buffer[20];	/* FIXME: how many chars long a %d can become? */
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
 
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
+
   xsnprintf (buffer, sizeof (buffer), "%d", value);
 
-  /* Always go through the function pointer (virtual function call).
-     We may have been extended.  */
-  uo_field_string (uiout, fldno, width, alignment, fldname, buffer);
+  do_field_string (fldno, width, alignment, fldname, buffer);
 }
 
-/* used to ommit a field */
+/* used to omit a field */
 
-static void
-cli_field_skip (struct ui_out *uiout, int fldno, int width,
-		enum ui_align alignment,
-		const char *fldname)
+void
+cli_ui_out::do_field_skip (int fldno, int width, ui_align alignment,
+			     const char *fldname)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  /* Always go through the function pointer (virtual function call).
-     We may have been extended.  */
-  uo_field_string (uiout, fldno, width, alignment, fldname, "");
+  do_field_string (fldno, width, alignment, fldname, "");
 }
 
 /* other specific cli_field_* end up here so alignment and field
    separators are both handled by cli_field_string */
 
-static void
-cli_field_string (struct ui_out *uiout,
-		  int fldno,
-		  int width,
-		  enum ui_align align,
-		  const char *fldname,
-		  const char *string)
+void
+cli_ui_out::do_field_string (int fldno, int width, ui_align align,
+			       const char *fldname, const char *string)
 {
   int before = 0;
   int after = 0;
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
 
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
   if ((align != ui_noalign) && string)
@@ -209,11 +153,13 @@  cli_field_string (struct ui_out *uiout,
     }
 
   if (before)
-    ui_out_spaces (uiout, before);
+    spaces (before);
+
   if (string)
-    out_field_fmt (uiout, fldno, fldname, "%s", string);
+    out_field_fmt (fldno, fldname, "%s", string);
+
   if (after)
-    ui_out_spaces (uiout, after);
+    spaces (after);
 
   if (align != ui_noalign)
     field_separator ();
@@ -221,188 +167,131 @@  cli_field_string (struct ui_out *uiout,
 
 /* This is the only field function that does not align.  */
 
-static void ATTRIBUTE_PRINTF (6, 0)
-cli_field_fmt (struct ui_out *uiout, int fldno,
-	       int width, enum ui_align align,
-	       const char *fldname,
-	       const char *format,
-	       va_list args)
+void
+cli_ui_out::do_field_fmt (int fldno, int width, ui_align align,
+			    const char *fldname, const char *format,
+			    va_list args)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *stream;
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  stream = data->streams.back ();
-  vfprintf_filtered (stream, format, args);
+  vfprintf_filtered (m_streams.back (), format, args);
 
   if (align != ui_noalign)
     field_separator ();
 }
 
-static void
-cli_spaces (struct ui_out *uiout, int numspaces)
+void
+cli_ui_out::do_spaces (int numspaces)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *stream;
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  stream = data->streams.back ();
-  print_spaces_filtered (numspaces, stream);
+  print_spaces_filtered (numspaces, m_streams.back ());
 }
 
-static void
-cli_text (struct ui_out *uiout, const char *string)
+void
+cli_ui_out::do_text (const char *string)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *stream;
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  stream = data->streams.back ();
-  fputs_filtered (string, stream);
+  fputs_filtered (string, m_streams.back ());
 }
 
-static void ATTRIBUTE_PRINTF (2, 0)
-cli_message (struct ui_out *uiout, const char *format, va_list args)
+void
+cli_ui_out::do_message (const char *format, va_list args)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  struct ui_file *stream = data->streams.back ();
-  vfprintf_unfiltered (stream, format, args);
+  vfprintf_unfiltered (m_streams.back (), format, args);
 }
 
-static void
-cli_wrap_hint (struct ui_out *uiout, const char *identstring)
+void
+cli_ui_out::do_wrap_hint (const char *identstring)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
+
   wrap_here (identstring);
 }
 
-static void
-cli_flush (struct ui_out *uiout)
+void
+cli_ui_out::do_flush ()
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = data->streams.back ();
-
-  gdb_flush (stream);
+  gdb_flush (m_streams.back ());
 }
 
 /* OUTSTREAM as non-NULL will push OUTSTREAM on the stack of output streams
    and make it therefore active.  OUTSTREAM as NULL will pop the last pushed
    output stream; it is an internal error if it does not exist.  */
 
-static int
-cli_redirect (struct ui_out *uiout, struct ui_file *outstream)
+int
+cli_ui_out::do_redirect (ui_file *outstream)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
   if (outstream != NULL)
-    data->streams.push_back (outstream);
+    m_streams.push_back (outstream);
   else
-    data->streams.pop_back ();
+    m_streams.pop_back ();
 
   return 0;
 }
 
 /* local functions */
 
-/* Like cli_field_fmt, but takes a variable number of args
+/* Like cli_ui_out::do_field_fmt, but takes a variable number of args
    and makes a va_list and does not insert a separator.  */
 
 /* VARARGS */
-static void
-out_field_fmt (struct ui_out *uiout, int fldno,
-	       const char *fldname,
-	       const char *format,...)
+void
+cli_ui_out::out_field_fmt (int fldno, const char *fldname,
+				const char *format, ...)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = data->streams.back ();
   va_list args;
 
   va_start (args, format);
-  vfprintf_filtered (stream, format, args);
+  vfprintf_filtered (m_streams.back (), format, args);
 
   va_end (args);
 }
 
-/* Access to ui_out format private members.  */
-
-static void
-field_separator (void)
+void
+cli_ui_out::field_separator ()
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (current_uiout);
-  struct ui_file *stream = data->streams.back ();
-
-  fputc_filtered (' ', stream);
+  fputc_filtered (' ', m_streams.back ());
 }
 
-/* This is the CLI ui-out implementation functions vector */
+/* Constructor for cli_ui_out.  */
 
-const struct ui_out_impl cli_ui_out_impl =
-{
-  cli_table_begin,
-  cli_table_body,
-  cli_table_end,
-  cli_table_header,
-  cli_begin,
-  cli_end,
-  cli_field_int,
-  cli_field_skip,
-  cli_field_string,
-  cli_field_fmt,
-  cli_spaces,
-  cli_text,
-  cli_message,
-  cli_wrap_hint,
-  cli_flush,
-  cli_redirect,
-  cli_uiout_dtor,
-  0, /* Does not need MI hacks (i.e. needs CLI hacks).  */
-};
-
-/* Constructor for a `cli_out_data' object.  */
-
-void
-cli_out_data_ctor (cli_out_data *self, struct ui_file *stream)
+cli_ui_out::cli_ui_out (ui_file *stream, ui_out_flags flags)
+: ui_out (flags),
+  m_suppress_output (false)
 {
   gdb_assert (stream != NULL);
 
-  self->streams.push_back (stream);
+  m_streams.push_back (stream);
+}
 
-  self->suppress_output = 0;
+cli_ui_out::~cli_ui_out ()
+{
 }
 
 /* Initialize private members at startup.  */
 
-struct ui_out *
+cli_ui_out *
 cli_out_new (struct ui_file *stream)
 {
-  ui_out_flags flags = ui_source_list;
-  cli_out_data *data = new cli_out_data ();
-
-  cli_out_data_ctor (data, stream);
-  return ui_out_new (&cli_ui_out_impl, data, flags);
+  return new cli_ui_out (stream, ui_source_list);
 }
 
-struct ui_file *
-cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
+ui_file *
+cli_ui_out::set_stream (struct ui_file *stream)
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *old;
+  ui_file *old;
 
-  old = data->streams.back ();
-  data->streams.back () = stream;
+  old = m_streams.back ();
+  m_streams.back () = stream;
 
   return old;
 }
diff --git a/gdb/cli-out.h b/gdb/cli-out.h
index 296b8c0..ef996c4 100644
--- a/gdb/cli-out.h
+++ b/gdb/cli-out.h
@@ -23,25 +23,59 @@ 
 #include "ui-out.h"
 #include <vector>
 
-/* These are exported so that they can be extended by other `ui_out'
-   implementations, like TUI's.  */
+class cli_ui_out : public ui_out
+{
+public:
 
-struct cli_ui_out_data
-  {
-    std::vector<ui_file *> streams;
-    int suppress_output;
-  };
+  explicit cli_ui_out (ui_file *stream, ui_out_flags flags);
+  virtual ~cli_ui_out ();
 
-extern const struct ui_out_impl cli_ui_out_impl;
+  ui_file *set_stream (ui_file *stream);
 
+protected:
 
-extern struct ui_out *cli_out_new (struct ui_file *stream);
+  virtual void do_table_begin (int nbrofcols, int nr_rows,
+				  const char *tblid) override;
+  virtual void do_table_body () override;
+  virtual void do_table_end () override;
+  virtual void do_table_header (int width, ui_align align,
+			     const std::string &col_name,
+			     const std::string &col_hdr) override;
+  /* Note: level 0 is the top-level so LEVEL is always greater than
+     zero.  */
+  virtual void do_begin (ui_out_type type, const char *id) override;
+  virtual void do_end (ui_out_type type) override;
+  virtual void do_field_int (int fldno, int width, ui_align align,
+			  const char *fldname, int value) override;
+  virtual void do_field_skip (int fldno, int width, ui_align align,
+			   const char *fldname) override;
+  virtual void do_field_string (int fldno, int width, ui_align align,
+			     const char *fldname, const char *string) override;
+  virtual void do_field_fmt (int fldno, int width, ui_align align,
+			  const char *fldname, const char *format, va_list args)
+    override ATTRIBUTE_PRINTF (6,0);
+  virtual void do_spaces (int numspaces) override;
+  virtual void do_text (const char *string) override;
+  virtual void do_message (const char *format, va_list args) override
+    ATTRIBUTE_PRINTF (2,0);
+  virtual void do_wrap_hint (const char *identstring) override;
+  virtual void do_flush () override;
+  virtual int do_redirect (struct ui_file * outstream) override;
 
-extern void cli_out_data_ctor (struct cli_ui_out_data *data,
-			       struct ui_file *stream);
+  bool suppress_output ()
+  { return m_suppress_output; }
 
-extern struct ui_file *cli_out_set_stream (struct ui_out *uiout,
-					   struct ui_file *stream);
+private:
+
+  void field_separator ();
+  void out_field_fmt (int fldno, const char *fldname, const char *format, ...)
+    ATTRIBUTE_PRINTF (4, 5);
+
+  std::vector<ui_file *> m_streams;
+  bool m_suppress_output;
+};
+
+extern cli_ui_out *cli_out_new (struct ui_file *stream);
 
 extern void cli_display_match_list (char **matches, int len, int max);
 
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 3d1a628..763a6d4 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -254,7 +254,7 @@  complete_command (char *arg, int from_tty)
     {
       /* Only print this for non-mi frontends.  An MI frontend may not
 	 be able to handle this.  */
-      if (!ui_out_is_mi_like_p (current_uiout))
+      if (!current_uiout->is_mi_like_p ())
 	{
 	  printf_unfiltered (_("max-completions is zero,"
 			       " completion is disabled.\n"));
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index dfa96d6..3e6a2fd 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -34,7 +34,7 @@ 
 struct cli_interp
 {
   /* The ui_out for the console interpreter.  */
-  struct ui_out *cli_uiout;
+  cli_ui_out *cli_uiout;
 };
 
 /* Suppress notification struct.  */
@@ -281,10 +281,10 @@  cli_interpreter_resume (void *data)
      previously writing to gdb_stdout, then set it to the new
      gdb_stdout afterwards.  */
 
-  stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
+  stream = cli->cli_uiout->set_stream (gdb_stdout);
   if (stream != gdb_stdout)
     {
-      cli_out_set_stream (cli->cli_uiout, stream);
+      cli->cli_uiout->set_stream (stream);
       stream = NULL;
     }
 
@@ -293,7 +293,7 @@  cli_interpreter_resume (void *data)
   ui->input_handler = command_line_handler;
 
   if (stream != NULL)
-    cli_out_set_stream (cli->cli_uiout, gdb_stdout);
+    cli->cli_uiout->set_stream (gdb_stdout);
 
   return 1;
 }
@@ -324,9 +324,9 @@  cli_interpreter_exec (void *data, const char *command_str)
 
      It is important that it gets reset everytime, since the user
      could set gdb to use a different interpreter.  */
-  old_stream = cli_out_set_stream (cli->cli_uiout, gdb_stdout);
+  old_stream = cli->cli_uiout->set_stream (gdb_stdout);
   result = safe_execute_command (cli->cli_uiout, str, 1);
-  cli_out_set_stream (cli->cli_uiout, old_stream);
+  cli->cli_uiout->set_stream (old_stream);
   return result;
 }
 
diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c
index 46d4741..46c2306 100644
--- a/gdb/cli/cli-logging.c
+++ b/gdb/cli/cli-logging.c
@@ -134,8 +134,8 @@  set_logging_redirect (char *args, int from_tty, struct cmd_list_element *c)
      neither of it.  At least do not try to push OUTPUT if the pop
      already failed.  */
 
-  if (ui_out_redirect (uiout, NULL) < 0
-      || ui_out_redirect (uiout, output) < 0)
+  if (uiout->redirect (NULL) < 0
+      || uiout->redirect (output) < 0)
     warning (_("Current output protocol does not support redirection"));
 
   do_cleanups (cleanups);
@@ -178,8 +178,8 @@  pop_output_files (void)
   saved_output.targerr = NULL;
 
   /* Stay consistent with handle_redirections.  */
-  if (!ui_out_is_mi_like_p (current_uiout))
-    ui_out_redirect (current_uiout, NULL);
+  if (!current_uiout->is_mi_like_p ())
+    current_uiout->redirect (NULL);
 }
 
 /* This is a helper for the `set logging' command.  */
@@ -245,9 +245,9 @@  handle_redirections (int from_tty)
     }
 
   /* Don't do the redirect for MI, it confuses MI's ui-out scheme.  */
-  if (!ui_out_is_mi_like_p (current_uiout))
+  if (!current_uiout->is_mi_like_p ())
     {
-      if (ui_out_redirect (current_uiout, output) < 0)
+      if (current_uiout->redirect (output) < 0)
 	warning (_("Current output protocol does not support redirection"));
     }
 }
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index b19e550..cbcfc10 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -201,13 +201,13 @@  print_command_lines (struct ui_out *uiout, struct command_line *cmd,
   while (list)
     {
       if (depth)
-	ui_out_spaces (uiout, 2 * depth);
+	uiout->spaces (2 * depth);
 
       /* A simple command, print it and continue.  */
       if (list->control_type == simple_control)
 	{
-	  ui_out_field_string (uiout, NULL, list->line);
-	  ui_out_text (uiout, "\n");
+	  uiout->field_string (NULL, list->line);
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
@@ -216,8 +216,8 @@  print_command_lines (struct ui_out *uiout, struct command_line *cmd,
          and continue. */
       if (list->control_type == continue_control)
 	{
-	  ui_out_field_string (uiout, NULL, "loop_continue");
-	  ui_out_text (uiout, "\n");
+	  uiout->field_string (NULL, "loop_continue");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
@@ -226,8 +226,8 @@  print_command_lines (struct ui_out *uiout, struct command_line *cmd,
 	 continue.  */
       if (list->control_type == break_control)
 	{
-	  ui_out_field_string (uiout, NULL, "loop_break");
-	  ui_out_text (uiout, "\n");
+	  uiout->field_string (NULL, "loop_break");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
@@ -241,15 +241,15 @@  print_command_lines (struct ui_out *uiout, struct command_line *cmd,
 	     token.  See comment in process_next_line for explanation.
 	     Here, take care not print 'while-stepping' twice.  */
 	  if (list->control_type == while_control)
-	    ui_out_field_fmt (uiout, NULL, "while %s", list->line);
+	    uiout->field_fmt (NULL, "while %s", list->line);
 	  else
-	    ui_out_field_string (uiout, NULL, list->line);
-	  ui_out_text (uiout, "\n");
+	    uiout->field_string (NULL, list->line);
+	  uiout->text ("\n");
 	  print_command_lines (uiout, *list->body_list, depth + 1);
 	  if (depth)
-	    ui_out_spaces (uiout, 2 * depth);
-	  ui_out_field_string (uiout, NULL, "end");
-	  ui_out_text (uiout, "\n");
+	    uiout->spaces (2 * depth);
+	  uiout->field_string (NULL, "end");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
@@ -258,8 +258,8 @@  print_command_lines (struct ui_out *uiout, struct command_line *cmd,
 	 continueing.  */
       if (list->control_type == if_control)
 	{
-	  ui_out_field_fmt (uiout, NULL, "if %s", list->line);
-	  ui_out_text (uiout, "\n");
+	  uiout->field_fmt (NULL, "if %s", list->line);
+	  uiout->text ("\n");
 	  /* The true arm.  */
 	  print_command_lines (uiout, list->body_list[0], depth + 1);
 
@@ -267,16 +267,16 @@  print_command_lines (struct ui_out *uiout, struct command_line *cmd,
 	  if (list->body_count == 2)
 	    {
 	      if (depth)
-		ui_out_spaces (uiout, 2 * depth);
-	      ui_out_field_string (uiout, NULL, "else");
-	      ui_out_text (uiout, "\n");
+		uiout->spaces (2 * depth);
+	      uiout->field_string (NULL, "else");
+	      uiout->text ("\n");
 	      print_command_lines (uiout, list->body_list[1], depth + 1);
 	    }
 
 	  if (depth)
-	    ui_out_spaces (uiout, 2 * depth);
-	  ui_out_field_string (uiout, NULL, "end");
-	  ui_out_text (uiout, "\n");
+	    uiout->spaces (2 * depth);
+	  uiout->field_string (NULL, "end");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
@@ -286,55 +286,55 @@  print_command_lines (struct ui_out *uiout, struct command_line *cmd,
       if (list->control_type == commands_control)
 	{
 	  if (*(list->line))
-	    ui_out_field_fmt (uiout, NULL, "commands %s", list->line);
+	    uiout->field_fmt (NULL, "commands %s", list->line);
 	  else
-	    ui_out_field_string (uiout, NULL, "commands");
-	  ui_out_text (uiout, "\n");
+	    uiout->field_string (NULL, "commands");
+	  uiout->text ("\n");
 	  print_command_lines (uiout, *list->body_list, depth + 1);
 	  if (depth)
-	    ui_out_spaces (uiout, 2 * depth);
-	  ui_out_field_string (uiout, NULL, "end");
-	  ui_out_text (uiout, "\n");
+	    uiout->spaces (2 * depth);
+	  uiout->field_string (NULL, "end");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
 
       if (list->control_type == python_control)
 	{
-	  ui_out_field_string (uiout, NULL, "python");
-	  ui_out_text (uiout, "\n");
+	  uiout->field_string (NULL, "python");
+	  uiout->text ("\n");
 	  /* Don't indent python code at all.  */
 	  print_command_lines (uiout, *list->body_list, 0);
 	  if (depth)
-	    ui_out_spaces (uiout, 2 * depth);
-	  ui_out_field_string (uiout, NULL, "end");
-	  ui_out_text (uiout, "\n");
+	    uiout->spaces (2 * depth);
+	  uiout->field_string (NULL, "end");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
 
       if (list->control_type == compile_control)
 	{
-	  ui_out_field_string (uiout, NULL, "compile expression");
-	  ui_out_text (uiout, "\n");
+	  uiout->field_string (NULL, "compile expression");
+	  uiout->text ("\n");
 	  print_command_lines (uiout, *list->body_list, 0);
 	  if (depth)
-	    ui_out_spaces (uiout, 2 * depth);
-	  ui_out_field_string (uiout, NULL, "end");
-	  ui_out_text (uiout, "\n");
+	    uiout->spaces (2 * depth);
+	  uiout->field_string (NULL, "end");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
 
       if (list->control_type == guile_control)
 	{
-	  ui_out_field_string (uiout, NULL, "guile");
-	  ui_out_text (uiout, "\n");
+	  uiout->field_string (NULL, "guile");
+	  uiout->text ("\n");
 	  print_command_lines (uiout, *list->body_list, depth + 1);
 	  if (depth)
-	    ui_out_spaces (uiout, 2 * depth);
-	  ui_out_field_string (uiout, NULL, "end");
-	  ui_out_text (uiout, "\n");
+	    uiout->spaces (2 * depth);
+	  uiout->field_string (NULL, "end");
+	  uiout->text ("\n");
 	  list = list->next;
 	  continue;
 	}
diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
index d2ec1df..5f2cd03c 100644
--- a/gdb/cli/cli-setshow.c
+++ b/gdb/cli/cli-setshow.c
@@ -649,8 +649,8 @@  do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
      code to print the value out.  For the latter there should be
      MI and CLI specific versions.  */
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_stream (uiout, "value", stb);
+  if (uiout->is_mi_like_p ())
+    uiout->field_stream ("value", stb);
   else
     {
       std::string value = ui_file_as_string (stb);
@@ -684,8 +684,8 @@  cmd_show_list (struct cmd_list_element *list, int from_tty, const char *prefix)
 	    = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
 	  const char *new_prefix = strstr (list->prefixname, "show ") + 5;
 
-	  if (ui_out_is_mi_like_p (uiout))
-	    ui_out_field_string (uiout, "prefix", new_prefix);
+	  if (uiout->is_mi_like_p ())
+	    uiout->field_string ("prefix", new_prefix);
 	  cmd_show_list (*list->prefixlist, from_tty, new_prefix);
 	  /* Close the tuple.  */
 	  do_cleanups (optionlist_chain);
@@ -697,9 +697,9 @@  cmd_show_list (struct cmd_list_element *list, int from_tty, const char *prefix)
 	      struct cleanup *option_chain
 		= make_cleanup_ui_out_tuple_begin_end (uiout, "option");
 
-	      ui_out_text (uiout, prefix);
-	      ui_out_field_string (uiout, "name", list->name);
-	      ui_out_text (uiout, ":  ");
+	      uiout->text (prefix);
+	      uiout->field_string ("name", list->name);
+	      uiout->text (":  ");
 	      if (list->type == show_cmd)
 		do_show_command ((char *) NULL, from_tty, list);
 	      else
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
index 90f0d08..bcbb778 100644
--- a/gdb/cp-abi.c
+++ b/gdb/cp-abi.c
@@ -317,7 +317,7 @@  list_cp_abis (int from_tty)
   struct cleanup *cleanup_chain;
   int i;
 
-  ui_out_text (uiout, "The available C++ ABIs are:\n");
+  uiout->text ("The available C++ ABIs are:\n");
   cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
 						       "cp-abi-list");
   for (i = 0; i < num_cp_abis; i++)
@@ -325,17 +325,17 @@  list_cp_abis (int from_tty)
       char pad[14];
       int padcount;
 
-      ui_out_text (uiout, "  ");
-      ui_out_field_string (uiout, "cp-abi", cp_abis[i]->shortname);
+      uiout->text ("  ");
+      uiout->field_string ("cp-abi", cp_abis[i]->shortname);
 
       padcount = 16 - 2 - strlen (cp_abis[i]->shortname);
       pad[padcount] = 0;
       while (padcount > 0)
 	pad[--padcount] = ' ';
-      ui_out_text (uiout, pad);
+      uiout->text (pad);
 
-      ui_out_field_string (uiout, "doc", cp_abis[i]->doc);
-      ui_out_text (uiout, "\n");
+      uiout->field_string ("doc", cp_abis[i]->doc);
+      uiout->text ("\n");
     }
   do_cleanups (cleanup_chain);
 }
@@ -384,12 +384,12 @@  show_cp_abi_cmd (char *args, int from_tty)
 {
   struct ui_out *uiout = current_uiout;
 
-  ui_out_text (uiout, "The currently selected C++ ABI is \"");
+  uiout->text ("The currently selected C++ ABI is \"");
 
-  ui_out_field_string (uiout, "cp-abi", current_cp_abi.shortname);
-  ui_out_text (uiout, "\" (");
-  ui_out_field_string (uiout, "longname", current_cp_abi.longname);
-  ui_out_text (uiout, ").\n");
+  uiout->field_string ("cp-abi", current_cp_abi.shortname);
+  uiout->text ("\" (");
+  uiout->field_string ("longname", current_cp_abi.longname);
+  uiout->text (").\n");
 }
 
 extern initialize_file_ftype _initialize_cp_abi; /* -Wmissing-prototypes */
diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c
index 314d265..53f1c42 100644
--- a/gdb/darwin-nat-info.c
+++ b/gdb/darwin-nat-info.c
@@ -624,23 +624,23 @@  darwin_debug_regions_recurse (task_t task)
 
   if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
     {
-      ui_out_table_header (uiout, 10, ui_left, "start", "Start");
-      ui_out_table_header (uiout, 10, ui_left, "end", "End");
+      uiout->table_header (10, ui_left, "start", "Start");
+      uiout->table_header (10, ui_left, "end", "End");
     }
   else
     {
-      ui_out_table_header (uiout, 18, ui_left, "start", "Start");
-      ui_out_table_header (uiout, 18, ui_left, "end", "End");
+      uiout->table_header (18, ui_left, "start", "Start");
+      uiout->table_header (18, ui_left, "end", "End");
     }
-  ui_out_table_header (uiout, 3, ui_left, "min-prot", "Min");
-  ui_out_table_header (uiout, 3, ui_left, "max-prot", "Max");
-  ui_out_table_header (uiout, 5, ui_left, "inheritence", "Inh");
-  ui_out_table_header (uiout, 9, ui_left, "share-mode", "Shr");
-  ui_out_table_header (uiout, 1, ui_left, "depth", "D");
-  ui_out_table_header (uiout, 3, ui_left, "submap", "Sm");
-  ui_out_table_header (uiout, 0, ui_noalign, "tag", "Tag");
+  uiout->table_header (3, ui_left, "min-prot", "Min");
+  uiout->table_header (3, ui_left, "max-prot", "Max");
+  uiout->table_header (5, ui_left, "inheritence", "Inh");
+  uiout->table_header (9, ui_left, "share-mode", "Shr");
+  uiout->table_header (1, ui_left, "depth", "D");
+  uiout->table_header (3, ui_left, "submap", "Sm");
+  uiout->table_header (0, ui_noalign, "tag", "Tag");
 
-  ui_out_table_body (uiout);
+  uiout->table_body ();
 
   r_start = 0;
   r_depth = 0;
@@ -658,29 +658,29 @@  darwin_debug_regions_recurse (task_t task)
 	break;
       row_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "regions-row");
 
-      ui_out_field_core_addr (uiout, "start", target_gdbarch (), r_start);
-      ui_out_field_core_addr (uiout, "end", target_gdbarch (), r_start + r_size);
-      ui_out_field_string (uiout, "min-prot", 
+      uiout->field_core_addr ("start", target_gdbarch (), r_start);
+      uiout->field_core_addr ("end", target_gdbarch (), r_start + r_size);
+      uiout->field_string ("min-prot", 
 			   unparse_protection (r_info.protection));
-      ui_out_field_string (uiout, "max-prot", 
+      uiout->field_string ("max-prot", 
 			   unparse_protection (r_info.max_protection));
-      ui_out_field_string (uiout, "inheritence",
+      uiout->field_string ("inheritence",
 			   unparse_inheritance (r_info.inheritance));
-      ui_out_field_string (uiout, "share-mode",
+      uiout->field_string ("share-mode",
 			   unparse_share_mode (r_info.share_mode));
-      ui_out_field_int (uiout, "depth", r_depth);
-      ui_out_field_string (uiout, "submap",
+      uiout->field_int ("depth", r_depth);
+      uiout->field_string ("submap",
 			   r_info.is_submap ? _("sm ") : _("obj"));
       tag = unparse_user_tag (r_info.user_tag);
       if (tag)
-	ui_out_field_string (uiout, "tag", tag);
+	uiout->field_string ("tag", tag);
       else
-	ui_out_field_int (uiout, "tag", r_info.user_tag);
+	uiout->field_int ("tag", r_info.user_tag);
 
       do_cleanups (row_chain);
 
-      if (!ui_out_is_mi_like_p (uiout))
-	ui_out_text (uiout, "\n");
+      if (!uiout->is_mi_like_p ())
+	uiout->text ("\n");
 
       if (r_info.is_submap)
 	r_depth++;
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 07c3abe..09860a9 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -193,47 +193,47 @@  gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
 
   if (insn->number != 0)
     {
-      ui_out_field_fmt (uiout, "insn-number", "%u", insn->number);
-      ui_out_text (uiout, "\t");
+      uiout->field_fmt ("insn-number", "%u", insn->number);
+      uiout->text ("\t");
     }
 
   if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
     {
       if (insn->is_speculative)
 	{
-	  ui_out_field_string (uiout, "is-speculative", "?");
+	  uiout->field_string ("is-speculative", "?");
 
 	  /* The speculative execution indication overwrites the first
 	     character of the PC prefix.
 	     We assume a PC prefix length of 3 characters.  */
 	  if ((flags & DISASSEMBLY_OMIT_PC) == 0)
-	    ui_out_text (uiout, pc_prefix (pc) + 1);
+	    uiout->text (pc_prefix (pc) + 1);
 	  else
-	    ui_out_text (uiout, "  ");
+	    uiout->text ("  ");
 	}
       else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
-	ui_out_text (uiout, pc_prefix (pc));
+	uiout->text (pc_prefix (pc));
       else
-	ui_out_text (uiout, "   ");
+	uiout->text ("   ");
     }
   else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
-    ui_out_text (uiout, pc_prefix (pc));
-  ui_out_field_core_addr (uiout, "address", gdbarch, pc);
+    uiout->text (pc_prefix (pc));
+  uiout->field_core_addr ("address", gdbarch, pc);
 
   if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
 			       &line, &unmapped))
     {
       /* We don't care now about line, filename and unmapped.  But we might in
 	 the future.  */
-      ui_out_text (uiout, " <");
+      uiout->text (" <");
       if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
-	ui_out_field_string (uiout, "func-name", name);
-      ui_out_text (uiout, "+");
-      ui_out_field_int (uiout, "offset", offset);
-      ui_out_text (uiout, ">:\t");
+	uiout->field_string ("func-name", name);
+      uiout->text ("+");
+      uiout->field_int ("offset", offset);
+      uiout->text (">:\t");
     }
   else
-    ui_out_text (uiout, ":\t");
+    uiout->text (":\t");
 
   if (filename != NULL)
     xfree (filename);
@@ -267,18 +267,18 @@  gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
 	  spacer = " ";
 	}
 
-      ui_out_field_stream (uiout, "opcodes", opcode_stream);
-      ui_out_text (uiout, "\t");
+      uiout->field_stream ("opcodes", opcode_stream);
+      uiout->text ("\t");
 
       do_cleanups (cleanups);
     }
   else
     size = gdbarch_print_insn (gdbarch, pc, di);
 
-  ui_out_field_stream (uiout, "inst", stb);
+  uiout->field_stream ("inst", stb);
   ui_file_rewind (stb);
   do_cleanups (ui_out_chain);
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   return size;
 }
@@ -474,7 +474,7 @@  do_mixed_source_and_assembly_deprecated
 	  do_cleanups (ui_out_tuple_chain);
 	  ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
 	  ui_out_list_chain = make_cleanup (null_cleanup, 0);
-	  ui_out_text (uiout, "\n");
+	  uiout->text ("\n");
 	}
       if (how_many >= 0 && num_displayed >= how_many)
 	break;
@@ -648,7 +648,7 @@  do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 	{
 	  /* Skip the newline if this is the first instruction.  */
 	  if (pc > low)
-	    ui_out_text (uiout, "\n");
+	    uiout->text ("\n");
 	  if (ui_out_tuple_chain != NULL)
 	    {
 	      gdb_assert (ui_out_list_chain != NULL);
@@ -663,12 +663,11 @@  do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 		 output includes the source specs for each line.  */
 	      if (sal.symtab != NULL)
 		{
-		  ui_out_text (uiout,
-			       symtab_to_filename_for_display (sal.symtab));
+		  uiout->text (symtab_to_filename_for_display (sal.symtab));
 		}
 	      else
-		ui_out_text (uiout, "unknown");
-	      ui_out_text (uiout, ":\n");
+		uiout->text ("unknown");
+	      uiout->text (":\n");
 	    }
 	  if (start_preceding_line_to_display > 0)
 	    {
@@ -700,7 +699,7 @@  do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 	  if (sal.symtab != NULL)
 	    print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
 	  else
-	    ui_out_text (uiout, _("--- no source info for this pc ---\n"));
+	    uiout->text (_("--- no source info for this pc ---\n"));
 	  ui_out_list_chain
 	    = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
 	}
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index df00f87..56b699c 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -964,10 +964,10 @@  print_one_bfd (void **slot, void *data)
   struct cleanup *inner;
 
   inner = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-  ui_out_field_int (uiout, "refcount", gdata->refc);
-  ui_out_field_string (uiout, "addr", host_address_to_string (abfd));
-  ui_out_field_string (uiout, "filename", bfd_get_filename (abfd));
-  ui_out_text (uiout, "\n");
+  uiout->field_int ("refcount", gdata->refc);
+  uiout->field_string ("addr", host_address_to_string (abfd));
+  uiout->field_string ("filename", bfd_get_filename (abfd));
+  uiout->text ("\n");
   do_cleanups (inner);
 
   return 1;
@@ -982,11 +982,11 @@  maintenance_info_bfds (char *arg, int from_tty)
   struct ui_out *uiout = current_uiout;
 
   cleanup = make_cleanup_ui_out_table_begin_end (uiout, 3, -1, "bfds");
-  ui_out_table_header (uiout, 10, ui_left, "refcount", "Refcount");
-  ui_out_table_header (uiout, 18, ui_left, "addr", "Address");
-  ui_out_table_header (uiout, 40, ui_left, "filename", "Filename");
+  uiout->table_header (10, ui_left, "refcount", "Refcount");
+  uiout->table_header (18, ui_left, "addr", "Address");
+  uiout->table_header (40, ui_left, "filename", "Filename");
 
-  ui_out_table_body (uiout);
+  uiout->table_body ();
   htab_traverse (all_bfds, print_one_bfd, uiout);
 
   do_cleanups (cleanup);
diff --git a/gdb/guile/scm-breakpoint.c b/gdb/guile/scm-breakpoint.c
index 61d16da..977ba18 100644
--- a/gdb/guile/scm-breakpoint.c
+++ b/gdb/guile/scm-breakpoint.c
@@ -990,12 +990,12 @@  gdbscm_breakpoint_commands (SCM self)
   string_file = mem_fileopen ();
   chain = make_cleanup_ui_file_delete (string_file);
 
-  ui_out_redirect (current_uiout, string_file);
+  current_uiout->redirect (string_file);
   TRY
     {
       print_command_lines (current_uiout, breakpoint_commands (bp), 0);
     }
-  ui_out_redirect (current_uiout, NULL);
+  current_uiout->redirect (NULL);
   CATCH (except, RETURN_MASK_ALL)
     {
       do_cleanups (chain);
diff --git a/gdb/guile/scm-ports.c b/gdb/guile/scm-ports.c
index dea9077..68f2f8d 100644
--- a/gdb/guile/scm-ports.c
+++ b/gdb/guile/scm-ports.c
@@ -531,7 +531,7 @@  ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
     gdb_stderr = port_file;
   else
     {
-      if (ui_out_redirect (current_uiout, port_file) < 0)
+      if (current_uiout->redirect (port_file) < 0)
 	warning (_("Current output protocol does not support redirection"));
       else
 	make_cleanup_ui_out_redirect_pop (current_uiout);
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index eeaf621..c2f23e5 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -429,27 +429,22 @@  i386_linux_handle_segmentation_fault (struct gdbarch *gdbarch,
 
   is_upper = (access > upper_bound ? 1 : 0);
 
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
   if (is_upper)
-    ui_out_field_string (uiout, "sigcode-meaning",
-			 _("Upper bound violation"));
+    uiout->field_string ("sigcode-meaning", _("Upper bound violation"));
   else
-    ui_out_field_string (uiout, "sigcode-meaning",
-			 _("Lower bound violation"));
+    uiout->field_string ("sigcode-meaning", _("Lower bound violation"));
 
-  ui_out_text (uiout, _(" while accessing address "));
-  ui_out_field_fmt (uiout, "bound-access", "%s",
-		    paddress (gdbarch, access));
+  uiout->text (_(" while accessing address "));
+  uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, access));
 
-  ui_out_text (uiout, _("\nBounds: [lower = "));
-  ui_out_field_fmt (uiout, "lower-bound", "%s",
-		    paddress (gdbarch, lower_bound));
+  uiout->text (_("\nBounds: [lower = "));
+  uiout->field_fmt ("lower-bound", "%s", paddress (gdbarch, lower_bound));
 
-  ui_out_text (uiout, _(", upper = "));
-  ui_out_field_fmt (uiout, "upper-bound", "%s",
-		    paddress (gdbarch, upper_bound));
+  uiout->text (_(", upper = "));
+  uiout->field_fmt ("upper-bound", "%s", paddress (gdbarch, upper_bound));
 
-  ui_out_text (uiout, _("]"));
+  uiout->text (_("]"));
 }
 
 /* Parse the arguments of current system call instruction and record
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 22fb54c..bc80735 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8810,22 +8810,22 @@  i386_mpx_print_bounds (const CORE_ADDR bt_entry[4])
 
   if (bounds_in_map == 1)
     {
-      ui_out_text (uiout, "Null bounds on map:");
-      ui_out_text (uiout, " pointer value = ");
-      ui_out_field_core_addr (uiout, "pointer-value", gdbarch, bt_entry[2]);
-      ui_out_text (uiout, ".");
-      ui_out_text (uiout, "\n");
+      uiout->text ("Null bounds on map:");
+      uiout->text (" pointer value = ");
+      uiout->field_core_addr ("pointer-value", gdbarch, bt_entry[2]);
+      uiout->text (".");
+      uiout->text ("\n");
     }
   else
     {
-      ui_out_text (uiout, "{lbound = ");
-      ui_out_field_core_addr (uiout, "lower-bound", gdbarch, bt_entry[0]);
-      ui_out_text (uiout, ", ubound = ");
+      uiout->text ("{lbound = ");
+      uiout->field_core_addr ("lower-bound", gdbarch, bt_entry[0]);
+      uiout->text (", ubound = ");
 
       /* The upper bound is stored in 1's complement.  */
-      ui_out_field_core_addr (uiout, "upper-bound", gdbarch, ~bt_entry[1]);
-      ui_out_text (uiout, "}: pointer value = ");
-      ui_out_field_core_addr (uiout, "pointer-value", gdbarch, bt_entry[2]);
+      uiout->field_core_addr ("upper-bound", gdbarch, ~bt_entry[1]);
+      uiout->text ("}: pointer value = ");
+      uiout->field_core_addr ("pointer-value", gdbarch, bt_entry[2]);
 
       if (gdbarch_ptr_bit (gdbarch) == 64)
 	size = ( (~(int64_t) bt_entry[1]) - (int64_t) bt_entry[0]);
@@ -8837,12 +8837,12 @@  i386_mpx_print_bounds (const CORE_ADDR bt_entry[4])
 	 one to the size.  */
 
       size = (size > -1 ? size + 1 : size);
-      ui_out_text (uiout, ", size = ");
-      ui_out_field_fmt (uiout, "size", "%s", plongest (size));
+      uiout->text (", size = ");
+      uiout->field_fmt ("size", "%s", plongest (size));
 
-      ui_out_text (uiout, ", metadata = ");
-      ui_out_field_core_addr (uiout, "metadata", gdbarch, bt_entry[3]);
-      ui_out_text (uiout, "\n");
+      uiout->text (", metadata = ");
+      uiout->field_core_addr ("metadata", gdbarch, bt_entry[3]);
+      uiout->text ("\n");
     }
 }
 
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 942d61e..a537b0a 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -590,16 +590,16 @@  run_command_1 (char *args, int from_tty, int tbreak_at_main)
 
   if (from_tty)
     {
-      ui_out_field_string (uiout, NULL, "Starting program");
-      ui_out_text (uiout, ": ");
+      uiout->field_string (NULL, "Starting program");
+      uiout->text (": ");
       if (exec_file)
-	ui_out_field_string (uiout, "execfile", exec_file);
-      ui_out_spaces (uiout, 1);
+	uiout->field_string ("execfile", exec_file);
+      uiout->spaces (1);
       /* We call get_inferior_args() because we might need to compute
 	 the value now.  */
-      ui_out_field_string (uiout, "infargs", get_inferior_args ());
-      ui_out_text (uiout, "\n");
-      ui_out_flush (uiout);
+      uiout->field_string ("infargs", get_inferior_args ());
+      uiout->text ("\n");
+      uiout->flush ();
     }
 
   /* Done with ARGS.  */
@@ -1676,23 +1676,23 @@  print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv)
       /* Print it.  */
       stb = mem_fileopen ();
       old_chain = make_cleanup_ui_file_delete (stb);
-      ui_out_text (uiout, "Value returned is ");
-      ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
+      uiout->text ("Value returned is ");
+      uiout->field_fmt ("gdb-result-var", "$%d",
 			rv->value_history_index);
-      ui_out_text (uiout, " = ");
+      uiout->text (" = ");
       get_no_prettyformat_print_options (&opts);
       value_print (rv->value, stb, &opts);
-      ui_out_field_stream (uiout, "return-value", stb);
-      ui_out_text (uiout, "\n");
+      uiout->field_stream ("return-value", stb);
+      uiout->text ("\n");
       do_cleanups (old_chain);
     }
   else
     {
       std::string type_name = type_to_string (rv->type);
-      ui_out_text (uiout, "Value returned has type: ");
-      ui_out_field_string (uiout, "return-type", type_name.c_str ());
-      ui_out_text (uiout, ".");
-      ui_out_text (uiout, " Cannot determine contents\n");
+      uiout->text ("Value returned has type: ");
+      uiout->field_string ("return-type", type_name.c_str ());
+      uiout->text (".");
+      uiout->text (" Cannot determine contents\n");
     }
 }
 
diff --git a/gdb/inferior.c b/gdb/inferior.c
index af6f3af..32b6db2 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -558,9 +558,11 @@  print_selected_inferior (struct ui_out *uiout)
 {
   struct inferior *inf = current_inferior ();
   const char *filename = inf->pspace->pspace_exec_filename;
+
   if (filename == NULL)
     filename = _("<noexec>");
-  ui_out_message (uiout, _("[Switching to inferior %d [%s] (%s)]\n"),
+
+  uiout->message (_("[Switching to inferior %d [%s] (%s)]\n"),
 		  inf->num, inferior_pid_to_str (inf->pid), filename);
 }
 
@@ -589,18 +591,18 @@  print_inferior (struct ui_out *uiout, char *requested_inferiors)
 
   if (inf_count == 0)
     {
-      ui_out_message (uiout, "No inferiors.\n");
+      uiout->message ("No inferiors.\n");
       return;
     }
 
   old_chain = make_cleanup_ui_out_table_begin_end (uiout, 4, inf_count,
 						   "inferiors");
-  ui_out_table_header (uiout, 1, ui_left, "current", "");
-  ui_out_table_header (uiout, 4, ui_left, "number", "Num");
-  ui_out_table_header (uiout, 17, ui_left, "target-id", "Description");
-  ui_out_table_header (uiout, 17, ui_left, "exec", "Executable");
+  uiout->table_header (1, ui_left, "current", "");
+  uiout->table_header (4, ui_left, "number", "Num");
+  uiout->table_header (17, ui_left, "target-id", "Description");
+  uiout->table_header (17, ui_left, "exec", "Executable");
 
-  ui_out_table_body (uiout);
+  uiout->table_body ();
   for (inf = inferior_list; inf; inf = inf->next)
     {
       struct cleanup *chain2;
@@ -611,35 +613,34 @@  print_inferior (struct ui_out *uiout, char *requested_inferiors)
       chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
 
       if (inf == current_inferior ())
-	ui_out_field_string (uiout, "current", "*");
+	uiout->field_string ("current", "*");
       else
-	ui_out_field_skip (uiout, "current");
+	uiout->field_skip ("current");
 
-      ui_out_field_int (uiout, "number", inf->num);
+      uiout->field_int ("number", inf->num);
 
-      ui_out_field_string (uiout, "target-id",
-			   inferior_pid_to_str (inf->pid));
+      uiout->field_string ("target-id", inferior_pid_to_str (inf->pid));
 
       if (inf->pspace->pspace_exec_filename != NULL)
-	ui_out_field_string (uiout, "exec", inf->pspace->pspace_exec_filename);
+	uiout->field_string ("exec", inf->pspace->pspace_exec_filename);
       else
-	ui_out_field_skip (uiout, "exec");
+	uiout->field_skip ("exec");
 
       /* Print extra info that isn't really fit to always present in
 	 tabular form.  Currently we print the vfork parent/child
 	 relationships, if any.  */
       if (inf->vfork_parent)
 	{
-	  ui_out_text (uiout, _("\n\tis vfork child of inferior "));
-	  ui_out_field_int (uiout, "vfork-parent", inf->vfork_parent->num);
+	  uiout->text (_("\n\tis vfork child of inferior "));
+	  uiout->field_int ("vfork-parent", inf->vfork_parent->num);
 	}
       if (inf->vfork_child)
 	{
-	  ui_out_text (uiout, _("\n\tis vfork parent of inferior "));
-	  ui_out_field_int (uiout, "vfork-child", inf->vfork_child->num);
+	  uiout->text (_("\n\tis vfork parent of inferior "));
+	  uiout->field_int ("vfork-child", inf->vfork_child->num);
 	}
 
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
       do_cleanups (chain2);
     }
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index bf0632e..f4321ca 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -7889,9 +7889,9 @@  print_end_stepping_range_reason (struct ui_out *uiout)
 {
   /* For CLI-like interpreters, print nothing.  */
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
 			   async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
     }
 }
@@ -7900,21 +7900,21 @@  void
 print_signal_exited_reason (struct ui_out *uiout, enum gdb_signal siggnal)
 {
   annotate_signalled ();
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string
-      (uiout, "reason", async_reason_lookup (EXEC_ASYNC_EXITED_SIGNALLED));
-  ui_out_text (uiout, "\nProgram terminated with signal ");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string
+      ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_SIGNALLED));
+  uiout->text ("\nProgram terminated with signal ");
   annotate_signal_name ();
-  ui_out_field_string (uiout, "signal-name",
+  uiout->field_string ("signal-name",
 		       gdb_signal_to_name (siggnal));
   annotate_signal_name_end ();
-  ui_out_text (uiout, ", ");
+  uiout->text (", ");
   annotate_signal_string ();
-  ui_out_field_string (uiout, "signal-meaning",
+  uiout->field_string ("signal-meaning",
 		       gdb_signal_to_string (siggnal));
   annotate_signal_string_end ();
-  ui_out_text (uiout, ".\n");
-  ui_out_text (uiout, "The program no longer exists.\n");
+  uiout->text (".\n");
+  uiout->text ("The program no longer exists.\n");
 }
 
 void
@@ -7926,27 +7926,27 @@  print_exited_reason (struct ui_out *uiout, int exitstatus)
   annotate_exited (exitstatus);
   if (exitstatus)
     {
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "reason", 
+      if (uiout->is_mi_like_p ())
+	uiout->field_string ("reason", 
 			     async_reason_lookup (EXEC_ASYNC_EXITED));
-      ui_out_text (uiout, "[Inferior ");
-      ui_out_text (uiout, plongest (inf->num));
-      ui_out_text (uiout, " (");
-      ui_out_text (uiout, pidstr);
-      ui_out_text (uiout, ") exited with code ");
-      ui_out_field_fmt (uiout, "exit-code", "0%o", (unsigned int) exitstatus);
-      ui_out_text (uiout, "]\n");
+      uiout->text ("[Inferior ");
+      uiout->text (plongest (inf->num));
+      uiout->text (" (");
+      uiout->text (pidstr);
+      uiout->text (") exited with code ");
+      uiout->field_fmt ("exit-code", "0%o", (unsigned int) exitstatus);
+      uiout->text ("]\n");
     }
   else
     {
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string
-	  (uiout, "reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
-      ui_out_text (uiout, "[Inferior ");
-      ui_out_text (uiout, plongest (inf->num));
-      ui_out_text (uiout, " (");
-      ui_out_text (uiout, pidstr);
-      ui_out_text (uiout, ") exited normally]\n");
+      if (uiout->is_mi_like_p ())
+	uiout->field_string
+	  ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
+      uiout->text ("[Inferior ");
+      uiout->text (plongest (inf->num));
+      uiout->text (" (");
+      uiout->text (pidstr);
+      uiout->text (") exited normally]\n");
     }
 }
 
@@ -7971,55 +7971,53 @@  print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
 
   annotate_signal ();
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     ;
   else if (show_thread_that_caused_stop ())
     {
       const char *name;
 
-      ui_out_text (uiout, "\nThread ");
-      ui_out_field_fmt (uiout, "thread-id", "%s", print_thread_id (thr));
+      uiout->text ("\nThread ");
+      uiout->field_fmt ("thread-id", "%s", print_thread_id (thr));
 
       name = thr->name != NULL ? thr->name : target_thread_name (thr);
       if (name != NULL)
 	{
-	  ui_out_text (uiout, " \"");
-	  ui_out_field_fmt (uiout, "name", "%s", name);
-	  ui_out_text (uiout, "\"");
+	  uiout->text (" \"");
+	  uiout->field_fmt ("name", "%s", name);
+	  uiout->text ("\"");
 	}
     }
   else
-    ui_out_text (uiout, "\nProgram");
+    uiout->text ("\nProgram");
 
-  if (siggnal == GDB_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
-    ui_out_text (uiout, " stopped");
+  if (siggnal == GDB_SIGNAL_0 && !uiout->is_mi_like_p ())
+    uiout->text (" stopped");
   else
     {
-      ui_out_text (uiout, " received signal ");
+      uiout->text (" received signal ");
       annotate_signal_name ();
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string
-	  (uiout, "reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
-      ui_out_field_string (uiout, "signal-name",
-			   gdb_signal_to_name (siggnal));
+      if (uiout->is_mi_like_p ())
+	uiout->field_string
+	  ("reason", async_reason_lookup (EXEC_ASYNC_SIGNAL_RECEIVED));
+      uiout->field_string ("signal-name", gdb_signal_to_name (siggnal));
       annotate_signal_name_end ();
-      ui_out_text (uiout, ", ");
+      uiout->text (", ");
       annotate_signal_string ();
-      ui_out_field_string (uiout, "signal-meaning",
-			   gdb_signal_to_string (siggnal));
+      uiout->field_string ("signal-meaning", gdb_signal_to_string (siggnal));
 
       if (siggnal == GDB_SIGNAL_SEGV)
 	handle_segmentation_fault (uiout);
 
       annotate_signal_string_end ();
     }
-  ui_out_text (uiout, ".\n");
+  uiout->text (".\n");
 }
 
 void
 print_no_history_reason (struct ui_out *uiout)
 {
-  ui_out_text (uiout, "\nNo more reverse-execution history.\n");
+  uiout->text ("\nNo more reverse-execution history.\n");
 }
 
 /* Print current location without a level number, if we have changed
diff --git a/gdb/interps.c b/gdb/interps.c
index 163c837..115ea58 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -205,7 +205,7 @@  interp_set (struct interp *interp, int top_level)
 
   if (old_interp != NULL)
     {
-      ui_out_flush (current_uiout);
+      current_uiout->flush ();
       if (old_interp->procs->suspend_proc
 	  && !old_interp->procs->suspend_proc (old_interp->data))
 	{
@@ -263,7 +263,7 @@  interp_set (struct interp *interp, int top_level)
     {
       xsnprintf (buffer, sizeof (buffer),
 		 "Switching to interpreter \"%.24s\".\n", interp->name);
-      ui_out_text (current_uiout, buffer);
+      current_uiout->text (buffer);
     }
 
   return 1;
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 1604267..a602652 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -2606,7 +2606,7 @@  decode_line_full (const struct event_location *location, int flags,
 
   if (select_mode == NULL)
     {
-      if (ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
+      if (interp_ui_out (top_level_interpreter ())->is_mi_like_p ())
 	select_mode = multiple_symbols_all;
       else
 	select_mode = multiple_symbols_select_mode ();
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index c1626ff..6072685 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -1621,15 +1621,14 @@  info_auto_load_libthread_db (char *args, int from_tty)
   /* Table header shifted right by preceding "libthread-db:  " would not match
      its columns.  */
   if (info_count > 0 && args == auto_load_info_scripts_pattern_nl)
-    ui_out_text (uiout, "\n");
+    uiout->text ("\n");
 
   make_cleanup_ui_out_table_begin_end (uiout, 2, unique_filenames,
 				       "LinuxThreadDbTable");
 
-  ui_out_table_header (uiout, max_filename_len, ui_left, "filename",
-		       "Filename");
-  ui_out_table_header (uiout, pids_len, ui_left, "PIDs", "Pids");
-  ui_out_table_body (uiout);
+  uiout->table_header (max_filename_len, ui_left, "filename", "Filename");
+  uiout->table_header (pids_len, ui_left, "PIDs", "Pids");
+  uiout->table_body ();
 
   pids = (char *) xmalloc (max_pids_len + 1);
   make_cleanup (xfree, pids);
@@ -1641,7 +1640,7 @@  info_auto_load_libthread_db (char *args, int from_tty)
       char *pids_end;
 
       info = array[i];
-      ui_out_field_string (uiout, "filename", info->filename);
+      uiout->field_string ("filename", info->filename);
       pids_end = pids;
 
       while (i < info_count && strcmp (info->filename, array[i]->filename) == 0)
@@ -1659,16 +1658,16 @@  info_auto_load_libthread_db (char *args, int from_tty)
 	}
       *pids_end = '\0';
 
-      ui_out_field_string (uiout, "pids", pids);
+      uiout->field_string ("pids", pids);
 
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
       do_cleanups (chain);
     }
 
   do_cleanups (back_to);
 
   if (info_count == 0)
-    ui_out_message (uiout, _("No auto-loaded libthread-db.\n"));
+    uiout->message (_("No auto-loaded libthread-db.\n"));
 }
 
 static void
diff --git a/gdb/mi/mi-cmd-env.c b/gdb/mi/mi-cmd-env.c
index 7b52c98..8686317 100644
--- a/gdb/mi/mi-cmd-env.c
+++ b/gdb/mi/mi-cmd-env.c
@@ -84,7 +84,7 @@  mi_cmd_env_pwd (char *command, char **argv, int argc)
     error (_("-environment-pwd: error finding name of working directory: %s"),
            safe_strerror (errno));
     
-  ui_out_field_string (uiout, "cwd", gdb_dirbuf);
+  uiout->field_string ("cwd", gdb_dirbuf);
 }
 
 /* Change working directory.  */
@@ -181,7 +181,7 @@  mi_cmd_env_path (char *command, char **argv, int argc)
   set_in_environ (current_inferior ()->environment, path_var_name, exec_path);
   xfree (exec_path);
   env = get_in_environ (current_inferior ()->environment, path_var_name);
-  ui_out_field_string (uiout, "path", env);
+  uiout->field_string ("path", env);
 }
 
 /* Add zero or more directories to the front of the source path.  */
@@ -241,7 +241,7 @@  mi_cmd_env_dir (char *command, char **argv, int argc)
   for (i = argc - 1; i >= 0; --i)
     env_mod_path (argv[i], &source_path);
 
-  ui_out_field_string (uiout, "source-path", source_path);
+  uiout->field_string ("source-path", source_path);
   forget_cached_source_info ();
 }
 
@@ -264,8 +264,7 @@  mi_cmd_inferior_tty_show (char *command, char **argv, int argc)
     error (_("-inferior-tty-show: Usage: No args"));
 
   if (inferior_io_terminal)
-    ui_out_field_string (current_uiout,
-			 "inferior_tty_terminal", inferior_io_terminal);
+    current_uiout->field_string ("inferior_tty_terminal", inferior_io_terminal);
 }
 
 void 
diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c
index 310cd5b..cf1faa5 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -49,15 +49,13 @@  mi_cmd_file_list_exec_source_file (char *command, char **argv, int argc)
     error (_("-file-list-exec-source-file: No symtab"));
 
   /* Print to the user the line, filename and fullname.  */
-  ui_out_field_int (uiout, "line", st.line);
-  ui_out_field_string (uiout, "file",
-		       symtab_to_filename_for_display (st.symtab));
+  uiout->field_int ("line", st.line);
+  uiout->field_string ("file", symtab_to_filename_for_display (st.symtab));
 
-  ui_out_field_string (uiout, "fullname", symtab_to_fullname (st.symtab));
+  uiout->field_string ("fullname", symtab_to_fullname (st.symtab));
 
-  ui_out_field_int (uiout, "macro-info",
-		    COMPUNIT_MACRO_TABLE
-		      (SYMTAB_COMPUNIT (st.symtab)) != NULL);
+  uiout->field_int ("macro-info",
+		    COMPUNIT_MACRO_TABLE (SYMTAB_COMPUNIT (st.symtab)) != NULL);
 }
 
 /* A callback for map_partial_symbol_filenames.  */
@@ -68,14 +66,14 @@  print_partial_file_name (const char *filename, const char *fullname,
 {
   struct ui_out *uiout = current_uiout;
 
-  ui_out_begin (uiout, ui_out_type_tuple, NULL);
+  uiout->begin (ui_out_type_tuple, NULL);
 
-  ui_out_field_string (uiout, "file", filename);
+  uiout->field_string ("file", filename);
 
   if (fullname)
-    ui_out_field_string (uiout, "fullname", fullname);
+    uiout->field_string ("fullname", fullname);
 
-  ui_out_end (uiout, ui_out_type_tuple);
+  uiout->end (ui_out_type_tuple);
 }
 
 void
@@ -90,21 +88,21 @@  mi_cmd_file_list_exec_source_files (char *command, char **argv, int argc)
     error (_("-file-list-exec-source-files: Usage: No args"));
 
   /* Print the table header.  */
-  ui_out_begin (uiout, ui_out_type_list, "files");
+  uiout->begin (ui_out_type_list, "files");
 
   /* Look at all of the file symtabs.  */
   ALL_FILETABS (objfile, cu, s)
   {
-    ui_out_begin (uiout, ui_out_type_tuple, NULL);
+    uiout->begin (ui_out_type_tuple, NULL);
 
-    ui_out_field_string (uiout, "file", symtab_to_filename_for_display (s));
-    ui_out_field_string (uiout, "fullname", symtab_to_fullname (s));
+    uiout->field_string ("file", symtab_to_filename_for_display (s));
+    uiout->field_string ("fullname", symtab_to_fullname (s));
 
-    ui_out_end (uiout, ui_out_type_tuple);
+    uiout->end (ui_out_type_tuple);
   }
 
   map_symbol_filenames (print_partial_file_name, NULL,
 			1 /*need_fullname*/);
 
-  ui_out_end (uiout, ui_out_type_list);
+  uiout->end (ui_out_type_list);
 }
diff --git a/gdb/mi/mi-cmd-info.c b/gdb/mi/mi-cmd-info.c
index 4d11474..480fd25 100644
--- a/gdb/mi/mi-cmd-info.c
+++ b/gdb/mi/mi-cmd-info.c
@@ -53,17 +53,17 @@  mi_cmd_info_ada_exceptions (char *command, char **argv, int argc)
 
   make_cleanup_ui_out_table_begin_end
     (uiout, 2, VEC_length (ada_exc_info, exceptions), "ada-exceptions");
-  ui_out_table_header (uiout, 1, ui_left, "name", "Name");
-  ui_out_table_header (uiout, 1, ui_left, "address", "Address");
-  ui_out_table_body (uiout);
+  uiout->table_header (1, ui_left, "name", "Name");
+  uiout->table_header (1, ui_left, "address", "Address");
+  uiout->table_body ();
 
   for (ix = 0; VEC_iterate(ada_exc_info, exceptions, ix, info); ix++)
     {
       struct cleanup *sub_chain;
 
       sub_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-      ui_out_field_string (uiout, "name", info->name);
-      ui_out_field_core_addr (uiout, "address", gdbarch, info->addr);
+      uiout->field_string ("name", info->name);
+      uiout->field_core_addr ("address", gdbarch, info->addr);
 
       do_cleanups (sub_chain);
     }
@@ -96,7 +96,7 @@  mi_cmd_info_gdb_mi_command (char *command, char **argv, int argc)
   cmd = mi_lookup (cmd_name);
 
   old_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "command");
-  ui_out_field_string (uiout, "exists", cmd != NULL ? "true" : "false");
+  uiout->field_string ("exists", cmd != NULL ? "true" : "false");
   do_cleanups (old_chain);
 }
 
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index 390fc7e..271cb84 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -202,7 +202,7 @@  mi_cmd_stack_info_depth (char *command, char **argv, int argc)
        i++, fi = get_prev_frame (fi))
     QUIT;
 
-  ui_out_field_int (current_uiout, "depth", i);
+  current_uiout->field_int ("depth", i);
 }
 
 /* Print a list of the locals for the current frame.  With argument of
@@ -391,7 +391,7 @@  mi_cmd_stack_list_args (char *command, char **argv, int argc)
 
 	  QUIT;
 	  cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
-	  ui_out_field_int (uiout, "level", i);
+	  uiout->field_int ("level", i);
 	  list_args_or_locals (arguments, print_values, fi, skip_unavailable);
 	  do_cleanups (cleanup_frame);
 	}
@@ -520,16 +520,16 @@  list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
   fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb);
   if (arg->entry_kind == print_entry_values_only)
     fputs_filtered ("@entry", stb);
-  ui_out_field_stream (uiout, "name", stb);
+  uiout->field_stream ("name", stb);
 
   if (what == all && SYMBOL_IS_ARGUMENT (arg->sym))
-    ui_out_field_int (uiout, "arg", 1);
+    uiout->field_int ("arg", 1);
 
   if (values == PRINT_SIMPLE_VALUES)
     {
       check_typedef (arg->sym->type);
       type_print (arg->sym->type, "", stb, -1);
-      ui_out_field_stream (uiout, "type", stb);
+      uiout->field_stream ("type", stb);
     }
 
   if (arg->val || arg->error)
@@ -558,7 +558,7 @@  list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
       if (error_message != NULL)
 	fprintf_filtered (stb, _("<error reading variable: %s>"),
 			  error_message);
-      ui_out_field_stream (uiout, "value", stb);
+      uiout->field_stream ("value", stb);
     }
 
   do_cleanups (old_chain);
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 4131f99..f0a9056 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -51,39 +51,39 @@  print_varobj (struct varobj *var, enum print_values print_values,
   struct ui_out *uiout = current_uiout;
   int thread_id;
 
-  ui_out_field_string (uiout, "name", varobj_get_objname (var));
+  uiout->field_string ("name", varobj_get_objname (var));
   if (print_expression)
     {
       std::string exp = varobj_get_expression (var);
 
-      ui_out_field_string (uiout, "exp", exp.c_str ());
+      uiout->field_string ("exp", exp.c_str ());
     }
-  ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+  uiout->field_int ("numchild", varobj_get_num_children (var));
   
   if (mi_print_value_p (var, print_values))
     {
       std::string val = varobj_get_value (var);
 
-      ui_out_field_string (uiout, "value", val.c_str ());
+      uiout->field_string ("value", val.c_str ());
     }
 
   std::string type = varobj_get_type (var);
   if (!type.empty ())
-    ui_out_field_string (uiout, "type", type.c_str ());
+    uiout->field_string ("type", type.c_str ());
 
   thread_id = varobj_get_thread_id (var);
   if (thread_id > 0)
-    ui_out_field_int (uiout, "thread-id", thread_id);
+    uiout->field_int ("thread-id", thread_id);
 
   if (varobj_get_frozen (var))
-    ui_out_field_int (uiout, "frozen", 1);
+    uiout->field_int ("frozen", 1);
 
   gdb::unique_xmalloc_ptr<char> display_hint = varobj_get_display_hint (var);
   if (display_hint)
-    ui_out_field_string (uiout, "displayhint", display_hint.get ());
+    uiout->field_string ("displayhint", display_hint.get ());
 
   if (varobj_is_dynamic_p (var))
-    ui_out_field_int (uiout, "dynamic", 1);
+    uiout->field_int ("dynamic", 1);
 }
 
 /* VAROBJ operations */
@@ -144,7 +144,7 @@  mi_cmd_var_create (char *command, char **argv, int argc)
 
   print_varobj (var, PRINT_ALL_VALUES, 0 /* don't print expression */);
 
-  ui_out_field_int (uiout, "has_more", varobj_has_more (var, 0));
+  uiout->field_int ("has_more", varobj_has_more (var, 0));
 
   do_cleanups (old_cleanups);
 }
@@ -197,7 +197,7 @@  mi_cmd_var_delete (char *command, char **argv, int argc)
 
   numdel = varobj_delete (var, children_only_p);
 
-  ui_out_field_int (uiout, "ndeleted", numdel);
+  uiout->field_int ("ndeleted", numdel);
 
   do_cleanups (old_cleanups);
 }
@@ -250,11 +250,11 @@  mi_cmd_var_set_format (char *command, char **argv, int argc)
   varobj_set_display_format (var, format);
 
   /* Report the new current format.  */
-  ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+  uiout->field_string ("format", varobj_format_string[(int) format]);
  
   /* Report the value in the new format.  */
   std::string val = varobj_get_value (var);
-  ui_out_field_string (uiout, "value", val.c_str ());
+  uiout->field_string ("value", val.c_str ());
 }
 
 void
@@ -314,7 +314,7 @@  mi_cmd_var_show_format (char *command, char **argv, int argc)
   format = varobj_get_display_format (var);
 
   /* Report the current format.  */
-  ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+  uiout->field_string ("format", varobj_format_string[(int) format]);
 }
 
 void
@@ -329,7 +329,7 @@  mi_cmd_var_info_num_children (char *command, char **argv, int argc)
   /* Get varobj handle, if a valid var obj name was specified.  */
   var = varobj_get_handle (argv[0]);
 
-  ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+  uiout->field_int ("numchild", varobj_get_num_children (var));
 }
 
 /* Return 1 if given the argument PRINT_VALUES we should display
@@ -397,7 +397,7 @@  mi_cmd_var_list_children (char *command, char **argv, int argc)
     }
 
   children = varobj_list_children (var, &from, &to);
-  ui_out_field_int (uiout, "numchild", to - from);
+  uiout->field_int ("numchild", to - from);
   if (argc == 2 || argc == 4)
     print_values = mi_parse_print_values (argv[0]);
   else
@@ -405,7 +405,7 @@  mi_cmd_var_list_children (char *command, char **argv, int argc)
 
   gdb::unique_xmalloc_ptr<char> display_hint = varobj_get_display_hint (var);
   if (display_hint)
-    ui_out_field_string (uiout, "displayhint", display_hint.get ());
+    uiout->field_string ("displayhint", display_hint.get ());
 
   if (from < to)
     {
@@ -430,7 +430,7 @@  mi_cmd_var_list_children (char *command, char **argv, int argc)
       do_cleanups (cleanup_children);
     }
 
-  ui_out_field_int (uiout, "has_more", varobj_has_more (var, to));
+  uiout->field_int ("has_more", varobj_has_more (var, to));
 }
 
 void
@@ -446,7 +446,7 @@  mi_cmd_var_info_type (char *command, char **argv, int argc)
   var = varobj_get_handle (argv[0]);
 
   std::string type_name = varobj_get_type (var);
-  ui_out_field_string (uiout, "type", type_name.c_str ());
+  uiout->field_string ("type", type_name.c_str ());
 }
 
 void
@@ -463,7 +463,7 @@  mi_cmd_var_info_path_expression (char *command, char **argv, int argc)
   
   const char *path_expr = varobj_get_path_expr (var);
 
-  ui_out_field_string (uiout, "path_expr", path_expr);
+  uiout->field_string ("path_expr", path_expr);
 }
 
 void
@@ -481,10 +481,10 @@  mi_cmd_var_info_expression (char *command, char **argv, int argc)
 
   lang = varobj_get_language (var);
 
-  ui_out_field_string (uiout, "lang", lang->la_natural_name);
+  uiout->field_string ("lang", lang->la_natural_name);
 
   std::string exp = varobj_get_expression (var);
-  ui_out_field_string (uiout, "exp", exp.c_str ());
+  uiout->field_string ("exp", exp.c_str ());
 }
 
 void
@@ -508,7 +508,7 @@  mi_cmd_var_show_attributes (char *command, char **argv, int argc)
   else
     attstr = "noneditable";
 
-  ui_out_field_string (uiout, "attr", attstr);
+  uiout->field_string ("attr", attstr);
 }
 
 void
@@ -568,13 +568,13 @@  mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
     {
       std::string val = varobj_get_formatted_value (var, format);
 
-      ui_out_field_string (uiout, "value", val.c_str ());
+      uiout->field_string ("value", val.c_str ());
     }
   else
     {
       std::string val = varobj_get_value (var);
 
-      ui_out_field_string (uiout, "value", val.c_str ());
+      uiout->field_string ("value", val.c_str ());
     }
 }
 
@@ -605,7 +605,7 @@  mi_cmd_var_assign (char *command, char **argv, int argc)
 	     "expression to variable object"));
 
   std::string val = varobj_get_value (var);
-  ui_out_field_string (uiout, "value", val.c_str ());
+  uiout->field_string ("value", val.c_str ());
 }
 
 /* Type used for parameters passing to mi_cmd_var_update_iter.  */
@@ -718,7 +718,7 @@  varobj_update_one (struct varobj *var, enum print_values print_values,
 
       if (mi_version (uiout) > 1)
 	make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-      ui_out_field_string (uiout, "name", varobj_get_objname (r->varobj));
+      uiout->field_string ("name", varobj_get_objname (r->varobj));
 
       switch (r->status)
 	{
@@ -727,48 +727,47 @@  varobj_update_one (struct varobj *var, enum print_values print_values,
 	    {
 	      std::string val = varobj_get_value (r->varobj);
 
-	      ui_out_field_string (uiout, "value", val.c_str ());
+	      uiout->field_string ("value", val.c_str ());
 	    }
-	  ui_out_field_string (uiout, "in_scope", "true");
+	  uiout->field_string ("in_scope", "true");
 	  break;
         case VAROBJ_NOT_IN_SCOPE:
-          ui_out_field_string (uiout, "in_scope", "false");
+          uiout->field_string ("in_scope", "false");
 	  break;
         case VAROBJ_INVALID:
-          ui_out_field_string (uiout, "in_scope", "invalid");
+          uiout->field_string ("in_scope", "invalid");
  	  break;
 	}
 
       if (r->status != VAROBJ_INVALID)
 	{
 	  if (r->type_changed)
-	    ui_out_field_string (uiout, "type_changed", "true");
+	    uiout->field_string ("type_changed", "true");
 	  else
-	    ui_out_field_string (uiout, "type_changed", "false");
+	    uiout->field_string ("type_changed", "false");
 	}
 
       if (r->type_changed)
 	{
 	  std::string type_name = varobj_get_type (r->varobj);
 
-	  ui_out_field_string (uiout, "new_type", type_name.c_str ());
+	  uiout->field_string ("new_type", type_name.c_str ());
 	}
 
       if (r->type_changed || r->children_changed)
-	ui_out_field_int (uiout, "new_num_children", 
+	uiout->field_int ("new_num_children",
 			  varobj_get_num_children (r->varobj));
 
       gdb::unique_xmalloc_ptr<char> display_hint
 	= varobj_get_display_hint (r->varobj);
       if (display_hint)
-	ui_out_field_string (uiout, "displayhint", display_hint.get ());
+	uiout->field_string ("displayhint", display_hint.get ());
 
       if (varobj_is_dynamic_p (r->varobj))
-	ui_out_field_int (uiout, "dynamic", 1);
+	uiout->field_int ("dynamic", 1);
 
       varobj_get_child_range (r->varobj, &from, &to);
-      ui_out_field_int (uiout, "has_more",
-			varobj_has_more (r->varobj, to));
+      uiout->field_int ("has_more", varobj_has_more (r->varobj, to));
 
       if (r->newobj)
 	{
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 72d63d0..07b2a82 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -107,7 +107,7 @@  display_mi_prompt (struct mi_interp *mi)
 static struct mi_interp *
 as_mi_interp (struct interp *interp)
 {
-  if (ui_out_is_mi_like_p (interp_ui_out (interp)))
+  if (interp_ui_out (interp)->is_mi_like_p ())
     return (struct mi_interp *) interp_data (interp);
   return NULL;
 }
@@ -674,8 +674,7 @@  mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
 	  enum async_reply_reason reason;
 
 	  reason = thread_fsm_async_reply_reason (tp->thread_fsm);
-	  ui_out_field_string (mi_uiout, "reason",
-			       async_reason_lookup (reason));
+	  mi_uiout->field_string ("reason", async_reason_lookup (reason));
 	}
       print_stop_event (mi_uiout);
 
@@ -683,21 +682,21 @@  mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
       if (should_print_stop_to_console (console_interp, tp))
 	print_stop_event (mi->cli_uiout);
 
-      ui_out_field_int (mi_uiout, "thread-id", tp->global_num);
+      mi_uiout->field_int ("thread-id", tp->global_num);
       if (non_stop)
 	{
 	  struct cleanup *back_to = make_cleanup_ui_out_list_begin_end 
 	    (mi_uiout, "stopped-threads");
 
-	  ui_out_field_int (mi_uiout, NULL, tp->global_num);
+	  mi_uiout->field_int (NULL, tp->global_num);
 	  do_cleanups (back_to);
 	}
       else
-	ui_out_field_string (mi_uiout, "stopped-threads", "all");
+	mi_uiout->field_string ("stopped-threads", "all");
 
       core = target_core_of_thread (inferior_ptid);
       if (core != -1)
-	ui_out_field_int (mi_uiout, "core", core);
+	mi_uiout->field_int ("core", core);
     }
   
   fputs_unfiltered ("*stopped", mi->raw_stdout);
@@ -855,15 +854,15 @@  mi_tsv_modified (const struct trace_state_variable *tsv)
       fprintf_unfiltered (mi->event_channel,
 			  "tsv-modified");
 
-      ui_out_redirect (mi_uiout, mi->event_channel);
+      mi_uiout->redirect (mi->event_channel);
 
-      ui_out_field_string (mi_uiout, "name", tsv->name);
-      ui_out_field_string (mi_uiout, "initial",
+      mi_uiout->field_string ("name", tsv->name);
+      mi_uiout->field_string ("initial",
 			   plongest (tsv->initial_value));
       if (tsv->value_known)
-	ui_out_field_string (mi_uiout, "current", plongest (tsv->value));
+	mi_uiout->field_string ("current", plongest (tsv->value));
 
-      ui_out_redirect (mi_uiout, NULL);
+      mi_uiout->redirect (NULL);
 
       gdb_flush (mi->event_channel);
 
@@ -905,7 +904,7 @@  mi_breakpoint_created (struct breakpoint *b)
 	 break if anything is output to mi_uiout prior to calling the
 	 breakpoint_created notifications.  So, we use
 	 ui_out_redirect.  */
-      ui_out_redirect (mi_uiout, mi->event_channel);
+      mi_uiout->redirect (mi->event_channel);
       TRY
 	{
 	  gdb_breakpoint_query (mi_uiout, b->number, NULL);
@@ -915,7 +914,7 @@  mi_breakpoint_created (struct breakpoint *b)
 	}
       END_CATCH
 
-      ui_out_redirect (mi_uiout, NULL);
+      mi_uiout->redirect (NULL);
 
       gdb_flush (mi->event_channel);
 
@@ -984,7 +983,7 @@  mi_breakpoint_modified (struct breakpoint *b)
 	 break if anything is output to mi_uiout prior to calling the
 	 breakpoint_created notifications.  So, we use
 	 ui_out_redirect.  */
-      ui_out_redirect (mi->mi_uiout, mi->event_channel);
+      mi->mi_uiout->redirect (mi->event_channel);
       TRY
 	{
 	  gdb_breakpoint_query (mi->mi_uiout, b->number, NULL);
@@ -994,7 +993,7 @@  mi_breakpoint_modified (struct breakpoint *b)
 	}
       END_CATCH
 
-      ui_out_redirect (mi->mi_uiout, NULL);
+      mi->mi_uiout->redirect (NULL);
 
       gdb_flush (mi->event_channel);
 
@@ -1139,19 +1138,18 @@  mi_solib_loaded (struct so_list *solib)
 
       fprintf_unfiltered (mi->event_channel, "library-loaded");
 
-      ui_out_redirect (uiout, mi->event_channel);
+      uiout->redirect (mi->event_channel);
 
-      ui_out_field_string (uiout, "id", solib->so_original_name);
-      ui_out_field_string (uiout, "target-name", solib->so_original_name);
-      ui_out_field_string (uiout, "host-name", solib->so_name);
-      ui_out_field_int (uiout, "symbols-loaded", solib->symbols_loaded);
+      uiout->field_string ("id", solib->so_original_name);
+      uiout->field_string ("target-name", solib->so_original_name);
+      uiout->field_string ("host-name", solib->so_name);
+      uiout->field_int ("symbols-loaded", solib->symbols_loaded);
       if (!gdbarch_has_global_solist (target_gdbarch ()))
 	{
-	  ui_out_field_fmt (uiout, "thread-group", "i%d",
-			    current_inferior ()->num);
+	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
 	}
 
-      ui_out_redirect (uiout, NULL);
+      uiout->redirect (NULL);
 
       gdb_flush (mi->event_channel);
 
@@ -1178,18 +1176,17 @@  mi_solib_unloaded (struct so_list *solib)
 
       fprintf_unfiltered (mi->event_channel, "library-unloaded");
 
-      ui_out_redirect (uiout, mi->event_channel);
+      uiout->redirect (mi->event_channel);
 
-      ui_out_field_string (uiout, "id", solib->so_original_name);
-      ui_out_field_string (uiout, "target-name", solib->so_original_name);
-      ui_out_field_string (uiout, "host-name", solib->so_name);
+      uiout->field_string ("id", solib->so_original_name);
+      uiout->field_string ("target-name", solib->so_original_name);
+      uiout->field_string ("host-name", solib->so_name);
       if (!gdbarch_has_global_solist (target_gdbarch ()))
 	{
-	  ui_out_field_fmt (uiout, "thread-group", "i%d",
-			    current_inferior ()->num);
+	  uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
 	}
 
-      ui_out_redirect (uiout, NULL);
+      uiout->redirect (NULL);
 
       gdb_flush (mi->event_channel);
 
@@ -1221,12 +1218,12 @@  mi_command_param_changed (const char *param, const char *value)
 
       fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
 
-      ui_out_redirect (mi_uiout, mi->event_channel);
+      mi_uiout->redirect (mi->event_channel);
 
-      ui_out_field_string (mi_uiout, "param", param);
-      ui_out_field_string (mi_uiout, "value", value);
+      mi_uiout->field_string ("param", param);
+      mi_uiout->field_string ("value", value);
 
-      ui_out_redirect (mi_uiout, NULL);
+      mi_uiout->redirect (NULL);
 
       gdb_flush (mi->event_channel);
 
@@ -1260,11 +1257,11 @@  mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
 
       fprintf_unfiltered (mi->event_channel, "memory-changed");
 
-      ui_out_redirect (mi_uiout, mi->event_channel);
+      mi_uiout->redirect (mi->event_channel);
 
-      ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
-      ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr);
-      ui_out_field_fmt (mi_uiout, "len", "%s", hex_string (len));
+      mi_uiout->field_fmt ("thread-group", "i%d", inferior->num);
+      mi_uiout->field_core_addr ("addr", target_gdbarch (), memaddr);
+      mi_uiout->field_fmt ("len", "%s", hex_string (len));
 
       /* Append 'type=code' into notification if MEMADDR falls in the range of
 	 sections contain code.  */
@@ -1275,10 +1272,10 @@  mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
 						  sec->the_bfd_section);
 
 	  if (flags & SEC_CODE)
-	    ui_out_field_string (mi_uiout, "type", "code");
+	    mi_uiout->field_string ("type", "code");
 	}
 
-      ui_out_redirect (mi_uiout, NULL);
+      mi_uiout->redirect (NULL);
 
       gdb_flush (mi->event_channel);
 
@@ -1311,7 +1308,7 @@  mi_user_selected_context_changed (user_selected_what selection)
 
       mi_uiout = interp_ui_out (top_level_interpreter ());
 
-      ui_out_redirect (mi_uiout, mi->event_channel);
+      mi_uiout->redirect (mi->event_channel);
 
       old_chain = make_cleanup_ui_out_redirect_pop (mi_uiout);
 
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 4d276c8..ace9ff7 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -665,17 +665,17 @@  print_one_inferior (struct inferior *inferior, void *xdata)
       struct cleanup *back_to
 	= make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
 
-      ui_out_field_fmt (uiout, "id", "i%d", inferior->num);
-      ui_out_field_string (uiout, "type", "process");
+      uiout->field_fmt ("id", "i%d", inferior->num);
+      uiout->field_string ("type", "process");
       if (inferior->has_exit_code)
-	ui_out_field_string (uiout, "exit-code",
+	uiout->field_string ("exit-code",
 			     int_string (inferior->exit_code, 8, 0, 0, 1));
       if (inferior->pid != 0)
-	ui_out_field_int (uiout, "pid", inferior->pid);
+	uiout->field_int ("pid", inferior->pid);
 
       if (inferior->pspace->pspace_exec_filename != NULL)
 	{
-	  ui_out_field_string (uiout, "executable",
+	  uiout->field_string ("executable",
 			       inferior->pspace->pspace_exec_filename);
 	}
 
@@ -701,7 +701,7 @@  print_one_inferior (struct inferior *inferior, void *xdata)
 	  e = unique (b, e);
 
 	  for (; b != e; ++b)
-	    ui_out_field_int (uiout, NULL, *b);
+	    uiout->field_int (NULL, *b);
 
 	  do_cleanups (back_to_2);
 	}
@@ -730,7 +730,7 @@  output_cores (struct ui_out *uiout, const char *field_name, const char *xcores)
   make_cleanup (xfree, cores);
 
   for (p = strtok (p, ","); p;  p = strtok (NULL, ","))
-    ui_out_field_string (uiout, NULL, p);
+    uiout->field_string (NULL, p);
 
   do_cleanups (back_to);
 }
@@ -853,12 +853,12 @@  list_available_thread_groups (VEC (int) *ids, int recurse)
 
       back_to = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
 
-      ui_out_field_fmt (uiout, "id", "%s", pid);
-      ui_out_field_string (uiout, "type", "process");
+      uiout->field_fmt ("id", "%s", pid);
+      uiout->field_string ("type", "process");
       if (cmd)
-	ui_out_field_string (uiout, "description", cmd);
+	uiout->field_string ("description", cmd);
       if (user)
-	ui_out_field_string (uiout, "user", user);
+	uiout->field_string ("user", user);
       if (cores)
 	output_cores (uiout, "cores", cores);
 
@@ -882,9 +882,9 @@  list_available_thread_groups (VEC (int) *ids, int recurse)
 		  const char *tid = get_osdata_column (child, "tid");
 		  const char *tcore = get_osdata_column (child, "core");
 
-		  ui_out_field_string (uiout, "id", tid);
+		  uiout->field_string ("id", tid);
 		  if (tcore)
-		    ui_out_field_string (uiout, "core", tcore);
+		    uiout->field_string ("core", tcore);
 
 		  do_cleanups (back_to_2);
 		}
@@ -1028,10 +1028,9 @@  mi_cmd_data_list_register_names (char *command, char **argv, int argc)
 	{
 	  if (gdbarch_register_name (gdbarch, regnum) == NULL
 	      || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
-	    ui_out_field_string (uiout, NULL, "");
+	    uiout->field_string (NULL, "");
 	  else
-	    ui_out_field_string (uiout, NULL,
-				 gdbarch_register_name (gdbarch, regnum));
+	    uiout->field_string (NULL, gdbarch_register_name (gdbarch, regnum));
 	}
     }
 
@@ -1044,10 +1043,9 @@  mi_cmd_data_list_register_names (char *command, char **argv, int argc)
 
       if (gdbarch_register_name (gdbarch, regnum) == NULL
 	  || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
-	ui_out_field_string (uiout, NULL, "");
+	uiout->field_string (NULL, "");
       else
-	ui_out_field_string (uiout, NULL,
-			     gdbarch_register_name (gdbarch, regnum));
+	uiout->field_string (NULL, gdbarch_register_name (gdbarch, regnum));
     }
   do_cleanups (cleanup);
 }
@@ -1099,7 +1097,7 @@  mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
 	    error (_("-data-list-changed-registers: "
 		     "Unable to read register contents."));
 	  else if (changed)
-	    ui_out_field_int (uiout, NULL, regnum);
+	    uiout->field_int (NULL, regnum);
 	}
     }
 
@@ -1118,7 +1116,7 @@  mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
 	    error (_("-data-list-changed-registers: "
 		     "Unable to read register contents."));
 	  else if (changed)
-	    ui_out_field_int (uiout, NULL, regnum);
+	    uiout->field_int (NULL, regnum);
 	}
       else
 	error (_("bad register number"));
@@ -1269,7 +1267,7 @@  output_register (struct frame_info *frame, int regnum, int format,
     return;
 
   tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-  ui_out_field_int (uiout, "number", regnum);
+  uiout->field_int ("number", regnum);
 
   if (format == 'N')
     format = 0;
@@ -1285,7 +1283,7 @@  output_register (struct frame_info *frame, int regnum, int format,
   val_print (value_type (val),
 	     value_embedded_offset (val), 0,
 	     stb, 0, val, &opts, current_language);
-  ui_out_field_stream (uiout, "value", stb);
+  uiout->field_stream ("value", stb);
 
   do_cleanups (tuple_cleanup);
 }
@@ -1376,7 +1374,7 @@  mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
   opts.deref_ref = 0;
   common_val_print (val, stb, 0, &opts, current_language);
 
-  ui_out_field_stream (uiout, "value", stb);
+  uiout->field_stream ("value", stb);
 
   do_cleanups (old_chain);
 }
@@ -1508,15 +1506,13 @@  mi_cmd_data_read_memory (char *command, char **argv, int argc)
     error (_("Unable to read memory."));
 
   /* Output the header information.  */
-  ui_out_field_core_addr (uiout, "addr", gdbarch, addr);
-  ui_out_field_int (uiout, "nr-bytes", nr_bytes);
-  ui_out_field_int (uiout, "total-bytes", total_bytes);
-  ui_out_field_core_addr (uiout, "next-row",
-			  gdbarch, addr + word_size * nr_cols);
-  ui_out_field_core_addr (uiout, "prev-row",
-			  gdbarch, addr - word_size * nr_cols);
-  ui_out_field_core_addr (uiout, "next-page", gdbarch, addr + total_bytes);
-  ui_out_field_core_addr (uiout, "prev-page", gdbarch, addr - total_bytes);
+  uiout->field_core_addr ("addr", gdbarch, addr);
+  uiout->field_int ("nr-bytes", nr_bytes);
+  uiout->field_int ("total-bytes", total_bytes);
+  uiout->field_core_addr ("next-row", gdbarch, addr + word_size * nr_cols);
+  uiout->field_core_addr ("prev-row", gdbarch, addr - word_size * nr_cols);
+  uiout->field_core_addr ("next-page", gdbarch, addr + total_bytes);
+  uiout->field_core_addr ("prev-page", gdbarch, addr - total_bytes);
 
   /* Build the result as a two dimentional table.  */
   {
@@ -1540,7 +1536,7 @@  mi_cmd_data_read_memory (char *command, char **argv, int argc)
 	struct value_print_options opts;
 
 	cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-	ui_out_field_core_addr (uiout, "addr", gdbarch, addr + row_byte);
+	uiout->field_core_addr ("addr", gdbarch, addr + row_byte);
 	/* ui_out_field_core_addr_symbolic (uiout, "saddr", addr +
 	   row_byte); */
 	cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data");
@@ -1551,14 +1547,14 @@  mi_cmd_data_read_memory (char *command, char **argv, int argc)
 	  {
 	    if (col_byte + word_size > nr_bytes)
 	      {
-		ui_out_field_string (uiout, NULL, "N/A");
+		uiout->field_string (NULL, "N/A");
 	      }
 	    else
 	      {
 		ui_file_rewind (stream);
 		print_scalar_formatted (&mbuf[col_byte], word_type, &opts,
 					word_asize, stream);
-		ui_out_field_stream (uiout, NULL, stream);
+		uiout->field_stream (NULL, stream);
 	      }
 	  }
 	do_cleanups (cleanup_list_data);
@@ -1577,7 +1573,7 @@  mi_cmd_data_read_memory (char *command, char **argv, int argc)
 		else
 		  fputc_unfiltered (mbuf[byte], stream);
 	      }
-	    ui_out_field_stream (uiout, "ascii", stream);
+	    uiout->field_stream ("ascii", stream);
 	  }
 	do_cleanups (cleanup_tuple);
       }
@@ -1649,10 +1645,9 @@  mi_cmd_data_read_memory_bytes (char *command, char **argv, int argc)
       int i;
       int alloc_len;
 
-      ui_out_field_core_addr (uiout, "begin", gdbarch, read_result->begin);
-      ui_out_field_core_addr (uiout, "offset", gdbarch, read_result->begin
-			      - addr);
-      ui_out_field_core_addr (uiout, "end", gdbarch, read_result->end);
+      uiout->field_core_addr ("begin", gdbarch, read_result->begin);
+      uiout->field_core_addr ("offset", gdbarch, read_result->begin - addr);
+      uiout->field_core_addr ("end", gdbarch, read_result->end);
 
       alloc_len = (read_result->end - read_result->begin) * 2 * unit_size + 1;
       data = (char *) xmalloc (alloc_len);
@@ -1663,7 +1658,7 @@  mi_cmd_data_read_memory_bytes (char *command, char **argv, int argc)
 	{
 	  sprintf (p, "%02x", read_result->data[i]);
 	}
-      ui_out_field_string (uiout, "contents", data);
+      uiout->field_string ("contents", data);
       xfree (data);
       do_cleanups (t);
     }
@@ -1866,19 +1861,19 @@  mi_cmd_list_features (char *command, char **argv, int argc)
       struct ui_out *uiout = current_uiout;
 
       cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
-      ui_out_field_string (uiout, NULL, "frozen-varobjs");
-      ui_out_field_string (uiout, NULL, "pending-breakpoints");
-      ui_out_field_string (uiout, NULL, "thread-info");
-      ui_out_field_string (uiout, NULL, "data-read-memory-bytes");
-      ui_out_field_string (uiout, NULL, "breakpoint-notifications");
-      ui_out_field_string (uiout, NULL, "ada-task-info");
-      ui_out_field_string (uiout, NULL, "language-option");
-      ui_out_field_string (uiout, NULL, "info-gdb-mi-command");
-      ui_out_field_string (uiout, NULL, "undefined-command-error-code");
-      ui_out_field_string (uiout, NULL, "exec-run-start-option");
+      uiout->field_string (NULL, "frozen-varobjs");
+      uiout->field_string (NULL, "pending-breakpoints");
+      uiout->field_string (NULL, "thread-info");
+      uiout->field_string (NULL, "data-read-memory-bytes");
+      uiout->field_string (NULL, "breakpoint-notifications");
+      uiout->field_string (NULL, "ada-task-info");
+      uiout->field_string (NULL, "language-option");
+      uiout->field_string (NULL, "info-gdb-mi-command");
+      uiout->field_string (NULL, "undefined-command-error-code");
+      uiout->field_string (NULL, "exec-run-start-option");
 
       if (ext_lang_initialized_p (get_ext_lang_defn (EXT_LANG_PYTHON)))
-	ui_out_field_string (uiout, NULL, "python");
+	uiout->field_string (NULL, "python");
 
       do_cleanups (cleanup);
       return;
@@ -1897,9 +1892,9 @@  mi_cmd_list_target_features (char *command, char **argv, int argc)
 
       cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
       if (mi_async_p ())
-	ui_out_field_string (uiout, NULL, "async");
+	uiout->field_string (NULL, "async");
       if (target_can_execute_reverse)
-	ui_out_field_string (uiout, NULL, "reverse");
+	uiout->field_string (NULL, "reverse");
       do_cleanups (cleanup);
       return;
     }
@@ -1917,7 +1912,7 @@  mi_cmd_add_inferior (char *command, char **argv, int argc)
 
   inf = add_inferior_with_spaces ();
 
-  ui_out_field_fmt (current_uiout, "inferior", "i%d", inf->num);
+  current_uiout->field_fmt ("inferior", "i%d", inf->num);
 }
 
 /* Callback used to find the first inferior other than the current
@@ -2190,7 +2185,7 @@  mi_execute_command (const char *cmd, int from_tty)
 
       if (/* The notifications are only output when the top-level
 	     interpreter (specified on the command line) is MI.  */
-	  ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
+	  interp_ui_out (top_level_interpreter ())->is_mi_like_p ()
 	  /* Don't try report anything if there are no threads --
 	     the program is dead.  */
 	  && thread_count () != 0
@@ -2422,9 +2417,9 @@  mi_load_progress (const char *section_name,
 	fputs_unfiltered (current_token, mi->raw_stdout);
       fputs_unfiltered ("+download", mi->raw_stdout);
       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-      ui_out_field_string (uiout, "section", section_name);
-      ui_out_field_int (uiout, "section-size", total_section);
-      ui_out_field_int (uiout, "total-size", grand_total);
+      uiout->field_string ("section", section_name);
+      uiout->field_int ("section-size", total_section);
+      uiout->field_int ("total-size", grand_total);
       do_cleanups (cleanup_tuple);
       mi_out_put (uiout, mi->raw_stdout);
       fputs_unfiltered ("\n", mi->raw_stdout);
@@ -2441,11 +2436,11 @@  mi_load_progress (const char *section_name,
 	fputs_unfiltered (current_token, mi->raw_stdout);
       fputs_unfiltered ("+download", mi->raw_stdout);
       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-      ui_out_field_string (uiout, "section", section_name);
-      ui_out_field_int (uiout, "section-sent", sent_so_far);
-      ui_out_field_int (uiout, "section-size", total_section);
-      ui_out_field_int (uiout, "total-sent", total_sent);
-      ui_out_field_int (uiout, "total-size", grand_total);
+      uiout->field_string ("section", section_name);
+      uiout->field_int ("section-sent", sent_so_far);
+      uiout->field_int ("section-size", total_section);
+      uiout->field_int ("total-sent", total_sent);
+      uiout->field_int ("total-size", grand_total);
       do_cleanups (cleanup_tuple);
       mi_out_put (uiout, mi->raw_stdout);
       fputs_unfiltered ("\n", mi->raw_stdout);
@@ -2720,14 +2715,14 @@  print_variable_or_computed (const char *expression, enum print_values values)
 
   if (values != PRINT_NO_VALUES)
     make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-  ui_out_field_string (uiout, "name", expression);
+  uiout->field_string ("name", expression);
 
   switch (values)
     {
     case PRINT_SIMPLE_VALUES:
       type = check_typedef (value_type (val));
       type_print (value_type (val), "", stb, -1);
-      ui_out_field_stream (uiout, "type", stb);
+      uiout->field_stream ("type", stb);
       if (TYPE_CODE (type) != TYPE_CODE_ARRAY
 	  && TYPE_CODE (type) != TYPE_CODE_STRUCT
 	  && TYPE_CODE (type) != TYPE_CODE_UNION)
@@ -2737,7 +2732,7 @@  print_variable_or_computed (const char *expression, enum print_values values)
 	  get_no_prettyformat_print_options (&opts);
 	  opts.deref_ref = 1;
 	  common_val_print (val, stb, 0, &opts, current_language);
-	  ui_out_field_stream (uiout, "value", stb);
+	  uiout->field_stream ("value", stb);
 	}
       break;
     case PRINT_ALL_VALUES:
@@ -2747,7 +2742,7 @@  print_variable_or_computed (const char *expression, enum print_values values)
 	get_no_prettyformat_print_options (&opts);
 	opts.deref_ref = 1;
 	common_val_print (val, stb, 0, &opts, current_language);
-	ui_out_field_stream (uiout, "value", stb);
+	uiout->field_stream ("value", stb);
       }
       break;
     }
@@ -2929,16 +2924,16 @@  mi_cmd_trace_frame_collected (char *command, char **argv, int argc)
 	    tsvname = (char *) xrealloc (tsvname, strlen (tsv->name) + 2);
 	    tsvname[0] = '$';
 	    strcpy (tsvname + 1, tsv->name);
-	    ui_out_field_string (uiout, "name", tsvname);
+	    uiout->field_string ("name", tsvname);
 
 	    tsv->value_known = target_get_trace_state_variable_value (tsv->number,
 								      &tsv->value);
-	    ui_out_field_int (uiout, "current", tsv->value);
+	    uiout->field_int ("current", tsv->value);
 	  }
 	else
 	  {
-	    ui_out_field_skip (uiout, "name");
-	    ui_out_field_skip (uiout, "current");
+	    uiout->field_skip ("name");
+	    uiout->field_skip ("current");
 	  }
 
 	do_cleanups (cleanup_child);
@@ -2967,8 +2962,8 @@  mi_cmd_trace_frame_collected (char *command, char **argv, int argc)
 
 	cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
 
-	ui_out_field_core_addr (uiout, "address", gdbarch, r->start);
-	ui_out_field_int (uiout, "length", r->length);
+	uiout->field_core_addr ("address", gdbarch, r->start);
+	uiout->field_int ("length", r->length);
 
 	data = (gdb_byte *) xmalloc (r->length);
 	make_cleanup (xfree, data);
@@ -2985,10 +2980,10 @@  mi_cmd_trace_frame_collected (char *command, char **argv, int argc)
 
 		for (m = 0, p = data_str; m < r->length; ++m, p += 2)
 		  sprintf (p, "%02x", data[m]);
-		ui_out_field_string (uiout, "contents", data_str);
+		uiout->field_string ("contents", data_str);
 	      }
 	    else
-	      ui_out_field_skip (uiout, "contents");
+	      uiout->field_skip ("contents");
 	  }
 	do_cleanups (cleanup_child);
       }
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 19fcf87..7a197af 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -24,169 +24,85 @@ 
 #include "mi-out.h"
 #include <vector>
 
-struct mi_ui_out_data
-  {
-    int suppress_field_separator;
-    int mi_version;
-    std::vector<ui_file *> streams;
-  };
-typedef struct mi_ui_out_data mi_out_data;
-
-/* These are the MI output functions */
-
-static void mi_out_data_dtor (struct ui_out *ui_out);
-static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
-			    int nr_rows, const char *tblid);
-static void mi_table_body (struct ui_out *uiout);
-static void mi_table_end (struct ui_out *uiout);
-static void mi_table_header (struct ui_out *uiout, int width,
-			     enum ui_align alignment,
-			     const std::string &col_name,
-			     const std::string &col_hdr);
-static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
-		      const char *id);
-static void mi_end (struct ui_out *uiout, enum ui_out_type type);
-static void mi_field_int (struct ui_out *uiout, int fldno, int width,
-			  enum ui_align alig, const char *fldname, int value);
-static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
-			   enum ui_align alig, const char *fldname);
-static void mi_field_string (struct ui_out *uiout, int fldno, int width,
-			     enum ui_align alig, const char *fldname,
-			     const char *string);
-static void mi_field_fmt (struct ui_out *uiout, int fldno,
-			  int width, enum ui_align align,
-			  const char *fldname, const char *format,
-			  va_list args) ATTRIBUTE_PRINTF (6, 0);
-static void mi_spaces (struct ui_out *uiout, int numspaces);
-static void mi_text (struct ui_out *uiout, const char *string);
-static void mi_message (struct ui_out *uiout, const char *format, va_list args)
-     ATTRIBUTE_PRINTF (2, 0);
-static void mi_wrap_hint (struct ui_out *uiout, const char *identstring);
-static void mi_flush (struct ui_out *uiout);
-static int mi_redirect (struct ui_out *uiout, struct ui_file *outstream);
-
-/* This is the MI ui-out implementation functions vector */
-
-static const struct ui_out_impl mi_ui_out_impl =
-{
-  mi_table_begin,
-  mi_table_body,
-  mi_table_end,
-  mi_table_header,
-  mi_begin,
-  mi_end,
-  mi_field_int,
-  mi_field_skip,
-  mi_field_string,
-  mi_field_fmt,
-  mi_spaces,
-  mi_text,
-  mi_message,
-  mi_wrap_hint,
-  mi_flush,
-  mi_redirect,
-  mi_out_data_dtor,
-  1, /* Needs MI hacks.  */
-};
-
-/* Prototypes for local functions */
-
-static void field_separator (struct ui_out *uiout);
-static void mi_open (struct ui_out *uiout, const char *name,
-		     enum ui_out_type type);
-static void mi_close (struct ui_out *uiout, enum ui_out_type type);
-
 /* Mark beginning of a table.  */
 
 void
-mi_table_begin (struct ui_out *uiout,
-		int nr_cols,
-		int nr_rows,
-		const char *tblid)
+mi_ui_out::do_table_begin (int nr_cols, int nr_rows,
+			     const char *tblid)
 {
-  mi_open (uiout, tblid, ui_out_type_tuple);
-  mi_field_int (uiout, -1, -1, ui_left, "nr_rows", nr_rows);
-  mi_field_int (uiout, -1, -1, ui_left, "nr_cols", nr_cols);
-  mi_open (uiout, "hdr", ui_out_type_list);
+  open (tblid, ui_out_type_tuple);
+  do_field_int (-1, -1, ui_left, "nr_rows", nr_rows);
+  do_field_int (-1, -1, ui_left, "nr_cols", nr_cols);
+  open ("hdr", ui_out_type_list);
 }
 
 /* Mark beginning of a table body.  */
 
 void
-mi_table_body (struct ui_out *uiout)
+mi_ui_out::do_table_body ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
   /* close the table header line if there were any headers */
-  mi_close (uiout, ui_out_type_list);
-  mi_open (uiout, "body", ui_out_type_list);
+  close (ui_out_type_list);
+  open ("body", ui_out_type_list);
 }
 
 /* Mark end of a table.  */
 
 void
-mi_table_end (struct ui_out *uiout)
+mi_ui_out::do_table_end ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  mi_close (uiout, ui_out_type_list); /* body */
-  mi_close (uiout, ui_out_type_tuple);
+  close (ui_out_type_list); /* body */
+  close (ui_out_type_tuple);
 }
 
 /* Specify table header.  */
 
 void
-mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
-		 const std::string &col_name, const std::string &col_hdr)
+mi_ui_out::do_table_header (int width, ui_align alignment,
+			      const std::string &col_name,
+			      const std::string &col_hdr)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  mi_open (uiout, NULL, ui_out_type_tuple);
-  mi_field_int (uiout, 0, 0, ui_center, "width", width);
-  mi_field_int (uiout, 0, 0, ui_center, "alignment", alignment);
-  mi_field_string (uiout, 0, 0, ui_center, "col_name", col_name.c_str ());
-  mi_field_string (uiout, 0, width, alignment, "colhdr", col_hdr.c_str ());
-  mi_close (uiout, ui_out_type_tuple);
+  open (NULL, ui_out_type_tuple);
+  do_field_int (0, 0, ui_center, "width", width);
+  do_field_int (0, 0, ui_center, "alignment", alignment);
+  do_field_string (0, 0, ui_center, "col_name", col_name.c_str ());
+  do_field_string (0, width, alignment, "colhdr", col_hdr.c_str ());
+  close (ui_out_type_tuple);
 }
 
 /* Mark beginning of a list.  */
 
 void
-mi_begin (struct ui_out *uiout, enum ui_out_type type, const char *id)
+mi_ui_out::do_begin (ui_out_type type, const char *id)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  mi_open (uiout, id, type);
+  open (id, type);
 }
 
 /* Mark end of a list.  */
 
 void
-mi_end (struct ui_out *uiout, enum ui_out_type type)
+mi_ui_out::do_end (ui_out_type type)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  mi_close (uiout, type);
+  close (type);
 }
 
 /* Output an int field.  */
 
-static void
-mi_field_int (struct ui_out *uiout, int fldno, int width,
-              enum ui_align alignment, const char *fldname, int value)
+void
+mi_ui_out::do_field_int (int fldno, int width, ui_align alignment,
+			   const char *fldname, int value)
 {
   char buffer[20];	/* FIXME: how many chars long a %d can become? */
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
 
   xsnprintf (buffer, sizeof (buffer), "%d", value);
-  mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
+  do_field_string (fldno, width, alignment, fldname, buffer);
 }
 
 /* Used to omit a field.  */
 
 void
-mi_field_skip (struct ui_out *uiout, int fldno, int width,
-               enum ui_align alignment, const char *fldname)
+mi_ui_out::do_field_skip (int fldno, int width, ui_align alignment,
+			    const char *fldname)
 {
 }
 
@@ -194,14 +110,12 @@  mi_field_skip (struct ui_out *uiout, int fldno, int width,
    separators are both handled by mi_field_string. */
 
 void
-mi_field_string (struct ui_out *uiout, int fldno, int width,
-		 enum ui_align align, const char *fldname, const char *string)
+mi_ui_out::do_field_string (int fldno, int width, ui_align align,
+			      const char *fldname, const char *string)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream;
+  ui_file *stream = m_streams.back ();
+  field_separator ();
 
-  stream = data->streams.back ();
-  field_separator (uiout);
   if (fldname)
     fprintf_unfiltered (stream, "%s=", fldname);
   fprintf_unfiltered (stream, "\"");
@@ -213,15 +127,13 @@  mi_field_string (struct ui_out *uiout, int fldno, int width,
 /* This is the only field function that does not align.  */
 
 void
-mi_field_fmt (struct ui_out *uiout, int fldno, int width,
-	      enum ui_align align, const char *fldname,
-	      const char *format, va_list args)
+mi_ui_out::do_field_fmt (int fldno, int width, ui_align align,
+			   const char *fldname, const char *format,
+			   va_list args)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream;
+  ui_file *stream = m_streams.back ();
+  field_separator ();
 
-  stream = data->streams.back ();
-  field_separator (uiout);
   if (fldname)
     fprintf_unfiltered (stream, "%s=\"", fldname);
   else
@@ -231,125 +143,115 @@  mi_field_fmt (struct ui_out *uiout, int fldno, int width,
 }
 
 void
-mi_spaces (struct ui_out *uiout, int numspaces)
+mi_ui_out::do_spaces (int numspaces)
 {
 }
 
 void
-mi_text (struct ui_out *uiout, const char *string)
+mi_ui_out::do_text (const char *string)
 {
 }
 
 void
-mi_message (struct ui_out *uiout, const char *format, va_list args)
+mi_ui_out::do_message (const char *format, va_list args)
 {
 }
 
 void
-mi_wrap_hint (struct ui_out *uiout, const char *identstring)
+mi_ui_out::do_wrap_hint (const char *identstring)
 {
   wrap_here (identstring);
 }
 
 void
-mi_flush (struct ui_out *uiout)
+mi_ui_out::do_flush ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = data->streams.back ();
 
-  gdb_flush (stream);
+  gdb_flush (m_streams.back ());
 }
 
 int
-mi_redirect (struct ui_out *uiout, struct ui_file *outstream)
+mi_ui_out::do_redirect (ui_file *outstream)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
   if (outstream != NULL)
-    data->streams.push_back (outstream);
+    m_streams.push_back (outstream);
   else
-    data->streams.pop_back ();
+    m_streams.pop_back ();
 
   return 0;
 }
 
-/* local functions */
-
-/* access to ui_out format private members */
-
-static void
-field_separator (struct ui_out *uiout)
+void
+mi_ui_out::field_separator ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  ui_file *stream = data->streams.back ();
-
-  if (data->suppress_field_separator)
-    data->suppress_field_separator = 0;
+  if (m_suppress_field_separator)
+    m_suppress_field_separator = 0;
   else
-    fputc_unfiltered (',', stream);
+    fputc_unfiltered (',', m_streams.back ());
 }
 
-static void
-mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type)
+void
+mi_ui_out::open (const char *name, ui_out_type type)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  ui_file *stream = data->streams.back ();
+  ui_file *stream = m_streams.back ();
+
+  field_separator ();
+  m_suppress_field_separator = 1;
 
-  field_separator (uiout);
-  data->suppress_field_separator = 1;
   if (name)
     fprintf_unfiltered (stream, "%s=", name);
+
   switch (type)
     {
     case ui_out_type_tuple:
       fputc_unfiltered ('{', stream);
       break;
+
     case ui_out_type_list:
       fputc_unfiltered ('[', stream);
       break;
+
     default:
       internal_error (__FILE__, __LINE__, _("bad switch"));
     }
 }
 
-static void
-mi_close (struct ui_out *uiout, enum ui_out_type type)
+void
+mi_ui_out::close (ui_out_type type)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  ui_file *stream = data->streams.back ();
+  ui_file *stream = m_streams.back ();
 
   switch (type)
     {
     case ui_out_type_tuple:
       fputc_unfiltered ('}', stream);
       break;
+
     case ui_out_type_list:
       fputc_unfiltered (']', stream);
       break;
+
     default:
       internal_error (__FILE__, __LINE__, _("bad switch"));
     }
-  data->suppress_field_separator = 0;
+
+  m_suppress_field_separator = 0;
 }
 
 /* Clear the buffer.  */
 
 void
-mi_out_rewind (struct ui_out *uiout)
+mi_ui_out::rewind ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  ui_file *stream = data->streams.back ();
-
-  ui_file_rewind (stream);
+  ui_file_rewind (m_streams.back ());
 }
 
 /* Dump the buffer onto the specified stream.  */
 
 void
-mi_out_put (struct ui_out *uiout, struct ui_file *stream)
+mi_ui_out::put (ui_file *stream)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  ui_file *outstream = data->streams.back ();
+  ui_file *outstream = m_streams.back ();
 
   ui_file_put (outstream, ui_file_write_for_put, stream);
   ui_file_rewind (outstream);
@@ -358,45 +260,64 @@  mi_out_put (struct ui_out *uiout, struct ui_file *stream)
 /* Return the current MI version.  */
 
 int
-mi_version (struct ui_out *uiout)
+mi_ui_out::version ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  return data->mi_version;
+  return m_mi_version;
 }
 
 /* Constructor for an `mi_out_data' object.  */
 
-static void
-mi_out_data_ctor (mi_out_data *self, int mi_version, struct ui_file *stream)
+mi_ui_out::mi_ui_out (int mi_version, ui_file *stream)
+: m_suppress_field_separator (0),
+  m_suppress_output (false),
+  m_mi_version (mi_version)
 {
   gdb_assert (stream != NULL);
 
-  self->streams.push_back (stream);
+  m_streams.push_back (stream);
+}
 
-  self->suppress_field_separator = 0;
-  self->mi_version = mi_version;
+mi_ui_out::~mi_ui_out ()
+{
 }
 
-/* The destructor.  */
+/* Initialize private members at startup.  */
 
-static void
-mi_out_data_dtor (struct ui_out *ui_out)
+mi_ui_out *
+mi_out_new (int mi_version)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (ui_out);
+  ui_file *stream = mem_fileopen ();
 
-  delete data;
+  return new mi_ui_out (mi_version, stream);
 }
 
-/* Initialize private members at startup.  */
+/* Helper function to return the given UIOUT as an mi_ui_out.  It is an error
+   to call this fucntion with an ui_out that is not an MI.  */
 
-struct ui_out *
-mi_out_new (int mi_version)
+static mi_ui_out *
+as_mi_ui_out (ui_out *uiout)
 {
-  ui_out_flags flags = 0;
-  mi_out_data *data = new mi_out_data ();
-  struct ui_file *stream = mem_fileopen ();
+  mi_ui_out *mi_uiout = dynamic_cast<mi_ui_out *> (uiout);
+
+  gdb_assert (mi_uiout != NULL);
+
+  return mi_uiout;
+}
 
-  mi_out_data_ctor (data, mi_version, stream);
-  return ui_out_new (&mi_ui_out_impl, data, flags);
+int
+mi_version (ui_out *uiout)
+{
+  return as_mi_ui_out (uiout)->version ();
+}
+
+void
+mi_out_put (ui_out *uiout, struct ui_file *stream)
+{
+  return as_mi_ui_out (uiout)->put (stream);
+}
+
+void
+mi_out_rewind (ui_out *uiout)
+{
+  return as_mi_ui_out (uiout)->rewind ();
 }
diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h
index ba18950..035eddb 100644
--- a/gdb/mi/mi-out.h
+++ b/gdb/mi/mi-out.h
@@ -20,14 +20,73 @@ 
 #ifndef MI_OUT_H
 #define MI_OUT_H 1
 
+#include <vector>
+
 struct ui_out;
 struct ui_file;
 
-extern struct ui_out *mi_out_new (int mi_version);
-extern void mi_out_put (struct ui_out *uiout, struct ui_file *stream);
-extern void mi_out_rewind (struct ui_out *uiout);
 
-/* Return the version number of the current MI.  */
-extern int mi_version (struct ui_out *uiout);
+class mi_ui_out : public ui_out
+{
+public:
+
+  explicit mi_ui_out (int mi_version, ui_file *stream);
+  virtual ~mi_ui_out ();
+
+  /* MI-specific */
+  void rewind ();
+  void put (struct ui_file *stream);
+
+  /* Return the version number of the current MI.  */
+  int version ();
+
+protected:
+
+  virtual void do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
+    override;
+  virtual void do_table_body () override;
+  virtual void do_table_header (int width, ui_align align,
+			     const std::string &col_name,
+			     const std::string &col_hdr) override;
+  virtual void do_table_end () override;
+
+  virtual void do_begin (ui_out_type type, const char *id) override;
+  virtual void do_end (ui_out_type type) override;
+  virtual void do_field_int (int fldno, int width, ui_align align,
+			  const char *fldname, int value) override;
+  virtual void do_field_skip (int fldno, int width, ui_align align,
+			   const char *fldname) override;
+  virtual void do_field_string (int fldno, int width, ui_align align,
+			     const char *fldname, const char *string) override;
+  virtual void do_field_fmt (int fldno, int width, ui_align align,
+			  const char *fldname, const char *format, va_list args)
+    override ATTRIBUTE_PRINTF (6,0);
+  virtual void do_spaces (int numspaces) override;
+  virtual void do_text (const char *string) override;
+  virtual void do_message (const char *format, va_list args) override
+    ATTRIBUTE_PRINTF (2,0) ;
+  virtual void do_wrap_hint (const char *identstring) override;
+  virtual void do_flush () override;
+  virtual int do_redirect (struct ui_file * outstream) override;
+
+  virtual bool do_is_mi_like_p () override
+  { return true; }
+
+private:
+
+  void field_separator ();
+  void open (const char *name, ui_out_type type);
+  void close (ui_out_type type);
+
+  int m_suppress_field_separator;
+  bool m_suppress_output;
+  int m_mi_version;
+  std::vector<ui_file *> m_streams;
+};
+
+mi_ui_out *mi_out_new (int mi_version);
+int mi_version (ui_out *uiout);
+void mi_out_put (ui_out *uiout, struct ui_file *stream);
+void mi_out_rewind (ui_out *uiout);
 
 #endif /* MI_OUT_H */
diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c
index 6236d66..42d4902 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -56,9 +56,8 @@  mi_cmd_symbol_list_lines (char *command, char **argv, int argc)
     for (i = 0; i < SYMTAB_LINETABLE (s)->nitems; i++)
     {
       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-      ui_out_field_core_addr (uiout, "pc", gdbarch,
-			      SYMTAB_LINETABLE (s)->item[i].pc);
-      ui_out_field_int (uiout, "line", SYMTAB_LINETABLE (s)->item[i].line);
+      uiout->field_core_addr ("pc", gdbarch, SYMTAB_LINETABLE (s)->item[i].pc);
+      uiout->field_int ("line", SYMTAB_LINETABLE (s)->item[i].line);
       do_cleanups (cleanup_tuple);
     }
 
diff --git a/gdb/osdata.c b/gdb/osdata.c
index 4ced626..25e3cce 100644
--- a/gdb/osdata.c
+++ b/gdb/osdata.c
@@ -315,7 +315,7 @@  info_osdata_command (char *type, int from_tty)
 	 for a column named "Title", and only include it with MI
 	 output; this column's normal use is for titles for interface
 	 elements like menus, and it clutters up CLI output.  */
-      if (!type && !ui_out_is_mi_like_p (uiout))
+      if (!type && !uiout->is_mi_like_p ())
 	{
 	  struct osdata_column *col;
 	  int ix;
@@ -361,12 +361,12 @@  info_osdata_command (char *type, int from_tty)
 	    continue;
 
 	  snprintf (col_name, 32, "col%d", ix);
-	  ui_out_table_header (uiout, 10, ui_left,
+	  uiout->table_header (10, ui_left,
 			       col_name, col->name);
         }
     }
 
-  ui_out_table_body (uiout);
+  uiout->table_body ();
 
   if (nrows != 0)
     {
@@ -395,12 +395,12 @@  info_osdata_command (char *type, int from_tty)
 	       continue;
 
 	     snprintf (col_name, 32, "col%d", ix_cols);
-	     ui_out_field_string (uiout, col_name, col->value);
+	     uiout->field_string (col_name, col->value);
 	   }
 	 
          do_cleanups (old_chain);
 
-         ui_out_text (uiout, "\n");
+         uiout->text ("\n");
        }
     }
 
diff --git a/gdb/probe.c b/gdb/probe.c
index 611a752..e3bc915 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -438,8 +438,8 @@  gen_ui_out_table_header_info (VEC (bound_probe_s) *probes,
 	  do_cleanups (c2);
 	}
 
-      ui_out_table_header (current_uiout, size_max, ui_left,
-			   column->field_name, column->print_name);
+      current_uiout->table_header (size_max, ui_left,
+				   column->field_name, column->print_name);
     }
 
   do_cleanups (c);
@@ -465,7 +465,7 @@  print_ui_out_not_applicables (const struct probe_ops *pops)
   for (ix = 0;
        VEC_iterate (info_probe_column_s, headings, ix, column);
        ++ix)
-    ui_out_field_string (current_uiout, column->field_name, _("n/a"));
+    current_uiout->field_string (column->field_name, _("n/a"));
 
   do_cleanups (c);
 }
@@ -511,9 +511,9 @@  print_ui_out_info (struct probe *probe)
       const char *val = VEC_index (const_char_ptr, values, j++);
 
       if (val == NULL)
-	ui_out_field_skip (current_uiout, column->field_name);
+	current_uiout->field_skip (column->field_name);
       else
-	ui_out_field_string (current_uiout, column->field_name, val);
+	current_uiout->field_string (column->field_name, val);
     }
 
   do_cleanups (c);
@@ -652,11 +652,11 @@  info_probes_for_ops (const char *arg, int from_tty,
 			       size_objname);
     }
 
-  ui_out_table_header (current_uiout, size_type, ui_left, "type", _("Type"));
-  ui_out_table_header (current_uiout, size_provider, ui_left, "provider",
-		       _("Provider"));
-  ui_out_table_header (current_uiout, size_name, ui_left, "name", _("Name"));
-  ui_out_table_header (current_uiout, size_addr, ui_left, "addr", _("Where"));
+  current_uiout->table_header (size_type, ui_left, "type", _("Type"));
+  current_uiout->table_header (size_provider, ui_left, "provider",
+			       _("Provider"));
+  current_uiout->table_header (size_name, ui_left, "name", _("Name"));
+  current_uiout->table_header (size_addr, ui_left, "addr", _("Where"));
 
   if (pops == NULL)
     {
@@ -673,9 +673,8 @@  info_probes_for_ops (const char *arg, int from_tty,
   else
     gen_ui_out_table_header_info (probes, pops);
 
-  ui_out_table_header (current_uiout, size_objname, ui_left, "object",
-		       _("Object"));
-  ui_out_table_body (current_uiout);
+  current_uiout->table_header (size_objname, ui_left, "object", _("Object"));
+  current_uiout->table_body ();
 
   for (i = 0; VEC_iterate (bound_probe_s, probes, i, probe); ++i)
     {
@@ -684,12 +683,12 @@  info_probes_for_ops (const char *arg, int from_tty,
 
       inner = make_cleanup_ui_out_tuple_begin_end (current_uiout, "probe");
 
-      ui_out_field_string (current_uiout, "type",probe_type);
-      ui_out_field_string (current_uiout, "provider", probe->probe->provider);
-      ui_out_field_string (current_uiout, "name", probe->probe->name);
-      ui_out_field_core_addr (current_uiout, "addr",
-			      probe->probe->arch,
-			      get_probe_address (probe->probe, probe->objfile));
+      current_uiout->field_string ("type",probe_type);
+      current_uiout->field_string ("provider", probe->probe->provider);
+      current_uiout->field_string ("name", probe->probe->name);
+      current_uiout->field_core_addr (
+	"addr", probe->probe->arch,
+	get_probe_address (probe->probe, probe->objfile));
 
       if (pops == NULL)
 	{
@@ -706,9 +705,9 @@  info_probes_for_ops (const char *arg, int from_tty,
       else
 	print_ui_out_info (probe->probe);
 
-      ui_out_field_string (current_uiout, "object",
+      current_uiout->field_string ("object",
 			   objfile_name (probe->objfile));
-      ui_out_text (current_uiout, "\n");
+      current_uiout->text ("\n");
 
       do_cleanups (inner);
     }
@@ -717,7 +716,7 @@  info_probes_for_ops (const char *arg, int from_tty,
   do_cleanups (cleanup);
 
   if (!any_found)
-    ui_out_message (current_uiout, _("No probes matched.\n"));
+    current_uiout->message (_("No probes matched.\n"));
 }
 
 /* Implementation of the `info probes' command.  */
@@ -747,7 +746,7 @@  enable_probes_command (char *arg, int from_tty)
   probes = collect_probes (objname, provider, probe_name, NULL);
   if (VEC_empty (bound_probe_s, probes))
     {
-      ui_out_message (current_uiout, _("No probes matched.\n"));
+      current_uiout->message (_("No probes matched.\n"));
       do_cleanups (cleanup);
       return;
     }
@@ -761,14 +760,12 @@  enable_probes_command (char *arg, int from_tty)
       if (pops->enable_probe != NULL)
 	{
 	  pops->enable_probe (probe->probe);
-	  ui_out_message (current_uiout,
-			  _("Probe %s:%s enabled.\n"),
-			  probe->probe->provider, probe->probe->name);
+	  current_uiout->message (_("Probe %s:%s enabled.\n"),
+				  probe->probe->provider, probe->probe->name);
 	}
       else
-	ui_out_message (current_uiout,
-			_("Probe %s:%s cannot be enabled.\n"),
-			probe->probe->provider, probe->probe->name);
+	current_uiout->message (_("Probe %s:%s cannot be enabled.\n"),
+				probe->probe->provider, probe->probe->name);
     }
 
   do_cleanups (cleanup);
@@ -793,7 +790,7 @@  disable_probes_command (char *arg, int from_tty)
   probes = collect_probes (objname, provider, probe_name, NULL /* pops */);
   if (VEC_empty (bound_probe_s, probes))
     {
-      ui_out_message (current_uiout, _("No probes matched.\n"));
+      current_uiout->message (_("No probes matched.\n"));
       do_cleanups (cleanup);
       return;
     }
@@ -807,14 +804,12 @@  disable_probes_command (char *arg, int from_tty)
       if (pops->disable_probe != NULL)
 	{
 	  pops->disable_probe (probe->probe);
-	  ui_out_message (current_uiout,
-			  _("Probe %s:%s disabled.\n"),
-			  probe->probe->provider, probe->probe->name);
+	  current_uiout->message (_("Probe %s:%s disabled.\n"),
+				  probe->probe->provider, probe->probe->name);
 	}
       else
-	ui_out_message (current_uiout,
-			_("Probe %s:%s cannot be disabled.\n"),
-			probe->probe->provider, probe->probe->name);
+	current_uiout->message (_("Probe %s:%s cannot be disabled.\n"),
+				probe->probe->provider, probe->probe->name);
     }
 
   do_cleanups (cleanup);
diff --git a/gdb/progspace.c b/gdb/progspace.c
index 59a7846..ce3d0f8 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -303,10 +303,10 @@  print_program_space (struct ui_out *uiout, int requested)
   gdb_assert (count > 0);
 
   old_chain = make_cleanup_ui_out_table_begin_end (uiout, 3, count, "pspaces");
-  ui_out_table_header (uiout, 1, ui_left, "current", "");
-  ui_out_table_header (uiout, 4, ui_left, "id", "Id");
-  ui_out_table_header (uiout, 17, ui_left, "exec", "Executable");
-  ui_out_table_body (uiout);
+  uiout->table_header (1, ui_left, "current", "");
+  uiout->table_header (4, ui_left, "id", "Id");
+  uiout->table_header (17, ui_left, "exec", "Executable");
+  uiout->table_body ();
 
   ALL_PSPACES (pspace)
     {
@@ -320,16 +320,16 @@  print_program_space (struct ui_out *uiout, int requested)
       chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
 
       if (pspace == current_program_space)
-	ui_out_field_string (uiout, "current", "*");
+	uiout->field_string ("current", "*");
       else
-	ui_out_field_skip (uiout, "current");
+	uiout->field_skip ("current");
 
-      ui_out_field_int (uiout, "id", pspace->num);
+      uiout->field_int ("id", pspace->num);
 
       if (pspace->pspace_exec_filename)
-	ui_out_field_string (uiout, "exec", pspace->pspace_exec_filename);
+	uiout->field_string ("exec", pspace->pspace_exec_filename);
       else
-	ui_out_field_skip (uiout, "exec");
+	uiout->field_skip ("exec");
 
       /* Print extra info that doesn't really fit in tabular form.
 	 Currently, we print the list of inferiors bound to a pspace.
@@ -353,7 +353,7 @@  print_program_space (struct ui_out *uiout, int requested)
 			       target_pid_to_str (pid_to_ptid (inf->pid)));
 	  }
 
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
       do_cleanups (chain2);
     }
 
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 0897acf..4813a43 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -497,21 +497,21 @@  bppy_get_commands (PyObject *self, void *closure)
   string_file = mem_fileopen ();
   chain = make_cleanup_ui_file_delete (string_file);
 
-  ui_out_redirect (current_uiout, string_file);
+  current_uiout->redirect (string_file);
   TRY
     {
       print_command_lines (current_uiout, breakpoint_commands (bp), 0);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
-      ui_out_redirect (current_uiout, NULL);
+      current_uiout->redirect (NULL);
       do_cleanups (chain);
       gdbpy_convert_exception (except);
       return NULL;
     }
   END_CATCH
 
-  ui_out_redirect (current_uiout, NULL);
+  current_uiout->redirect (NULL);
   std::string cmdstr = ui_file_as_string (string_file);
   result = host_string_to_python_string (cmdstr.c_str ());
   do_cleanups (chain);
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 3beea12..67ad65a 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -219,7 +219,7 @@  py_print_type (struct ui_out *out, struct value *val)
       cleanup = make_cleanup_ui_file_delete (stb);
       check_typedef (value_type (val));
       type_print (value_type (val), "", stb, -1);
-      ui_out_field_stream (out, "type", stb);
+      out->field_stream ("type", stb);
       do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
@@ -290,7 +290,7 @@  py_print_value (struct ui_out *out, struct value *val,
 	  stb = mem_fileopen ();
 	  cleanup = make_cleanup_ui_file_delete (stb);
 	  common_val_print (val, stb, indent, opts, language);
-	  ui_out_field_stream (out, "value", stb);
+	  out->field_stream ("value", stb);
 	  do_cleanups (cleanup);
 	}
       CATCH (except, RETURN_MASK_ALL)
@@ -388,7 +388,7 @@  py_print_single_arg (struct ui_out *out,
       if the value is a frame argument.  This is denoted in this
       function with PRINT_ARGS_FIELD which is flag from the caller to
       emit the ARGS field.  */
-      if (ui_out_is_mi_like_p (out))
+      if (out->is_mi_like_p ())
 	{
 	  if (print_args_field || args_type != NO_VALUES)
 	    make_cleanup_ui_out_tuple_begin_end (out, NULL);
@@ -420,19 +420,19 @@  py_print_single_arg (struct ui_out *out,
 	    {
 	      fputs_filtered ("@entry", stb);
 	    }
-	  ui_out_field_stream (out, "name", stb);
+	  out->field_stream ("name", stb);
 	}
       else
 	/* Otherwise, just output the name.  */
-	ui_out_field_string (out, "name", sym_name);
+	out->field_string ("name", sym_name);
 
       annotate_arg_name_end ();
 
-      if (! ui_out_is_mi_like_p (out))
-	ui_out_text (out, "=");
+      if (! out->is_mi_like_p ())
+	out->text ("=");
 
       if (print_args_field)
-	ui_out_field_int (out, "arg", 1);
+	out->field_int ("arg", 1);
 
       /* For MI print the type, but only for simple values.  This seems
 	 weird, but this is how MI choose to format the various output
@@ -453,8 +453,8 @@  py_print_single_arg (struct ui_out *out,
 
 	  /* If the output is to the CLI, and the user option "set print
 	     frame-arguments" is set to none, just output "...".  */
-	  if (! ui_out_is_mi_like_p (out) && args_type == NO_VALUES)
-	    ui_out_field_string (out, "value", "...");
+	  if (! out->is_mi_like_p () && args_type == NO_VALUES)
+	    out->field_string ("value", "...");
 	  else
 	    {
 	      /* Otherwise, print the value for both MI and the CLI, except
@@ -464,7 +464,7 @@  py_print_single_arg (struct ui_out *out,
 		  if (val == NULL)
 		    {
 		      gdb_assert (fa != NULL && fa->error != NULL);
-		      ui_out_field_fmt (out, "value",
+		      out->field_fmt ("value",
 					_("<error reading variable: %s>"),
 					fa->error);
 		    }
@@ -562,7 +562,7 @@  enumerate_args (PyObject *iter,
       Py_DECREF (item);
       item = NULL;
 
-      if (sym && ui_out_is_mi_like_p (out)
+      if (sym && out->is_mi_like_p ()
 	  && ! mi_should_print (sym, MI_PRINT_ARGS))
 	continue;
 
@@ -616,8 +616,8 @@  enumerate_args (PyObject *iter,
 		{
 		  TRY
 		    {
-		      ui_out_text (out, ", ");
-		      ui_out_wrap_hint (out, "    ");
+		      out->text (", ");
+		      out->wrap_hint ("    ");
 		    }
 		  CATCH (except, RETURN_MASK_ALL)
 		    {
@@ -662,7 +662,7 @@  enumerate_args (PyObject *iter,
 	{
 	  TRY
 	    {
-	      ui_out_text (out, ", ");
+	      out->text (", ");
 	    }
 	  CATCH (except, RETURN_MASK_ALL)
 	    {
@@ -747,7 +747,7 @@  enumerate_locals (PyObject *iter,
 	  goto error;
 	}
 
-      if (sym != NULL && ui_out_is_mi_like_p (out)
+      if (sym != NULL && out->is_mi_like_p ()
 	  && ! mi_should_print (sym, MI_PRINT_LOCALS))
 	{
 	  do_cleanups (locals_cleanups);
@@ -773,23 +773,23 @@  enumerate_locals (PyObject *iter,
       /* With PRINT_NO_VALUES, MI does not emit a tuple normally as
 	 each output contains only one field.  The exception is
 	 -stack-list-variables, which always provides a tuple.  */
-      if (ui_out_is_mi_like_p (out))
+      if (out->is_mi_like_p ())
 	{
 	  if (print_args_field || args_type != NO_VALUES)
 	    make_cleanup_ui_out_tuple_begin_end (out, NULL);
 	}
       TRY
 	{
-	  if (! ui_out_is_mi_like_p (out))
+	  if (! out->is_mi_like_p ())
 	    {
 	      /* If the output is not MI we indent locals.  */
-	      ui_out_spaces (out, local_indent);
+	      out->spaces (local_indent);
 	    }
 
-	  ui_out_field_string (out, "name", sym_name.get ());
+	  out->field_string ("name", sym_name.get ());
 
-	  if (! ui_out_is_mi_like_p (out))
-	    ui_out_text (out, " = ");
+	  if (! out->is_mi_like_p ())
+	    out->text (" = ");
 	}
       CATCH (except, RETURN_MASK_ERROR)
 	{
@@ -810,7 +810,7 @@  enumerate_locals (PyObject *iter,
 
       /* CLI always prints values for locals.  MI uses the
 	 simple/no/all system.  */
-      if (! ui_out_is_mi_like_p (out))
+      if (! out->is_mi_like_p ())
 	{
 	  int val_indent = (indent + 1) * 4;
 
@@ -838,7 +838,7 @@  enumerate_locals (PyObject *iter,
 
       TRY
 	{
-	  ui_out_text (out, "\n");
+	  out->text ("\n");
 	}
       CATCH (except, RETURN_MASK_ERROR)
 	{
@@ -955,8 +955,8 @@  py_print_args (PyObject *filter,
   TRY
     {
       annotate_frame_args ();
-      if (! ui_out_is_mi_like_p (out))
-	ui_out_text (out, " (");
+      if (! out->is_mi_like_p ())
+	out->text (" (");
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -972,8 +972,8 @@  py_print_args (PyObject *filter,
 
   TRY
     {
-      if (! ui_out_is_mi_like_p (out))
-	ui_out_text (out, ")");
+      if (! out->is_mi_like_p ())
+	out->text (")");
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1077,7 +1077,7 @@  py_print_frame (PyObject *filter, int flags,
 	{
 	  TRY
 	    {
-	      ui_out_spaces (out, indent*4);
+	      out->spaces (indent * 4);
 	    }
 	  CATCH (except, RETURN_MASK_ERROR)
 	    {
@@ -1133,14 +1133,14 @@  py_print_frame (PyObject *filter, int flags,
 	     architecture from the eliding frame.  If that is the case, do
 	     not print 'level', but print spaces.  */
 	  if (*slot == frame)
-	    ui_out_field_skip (out, "level");
+	    out->field_skip ("level");
 	  else
 	    {
 	      *slot = frame;
 	      annotate_frame_begin (print_level ? level : 0,
 				    gdbarch, address);
-	      ui_out_text (out, "#");
-	      ui_out_field_fmt_int (out, 2, ui_left, "level",
+	      out->text ("#");
+	      out->field_fmt_int (2, ui_left, "level",
 				    level);
 	    }
 	}
@@ -1162,9 +1162,9 @@  py_print_frame (PyObject *filter, int flags,
 	  TRY
 	    {
 	      annotate_frame_address ();
-	      ui_out_field_core_addr (out, "addr", gdbarch, address);
+	      out->field_core_addr ("addr", gdbarch, address);
 	      annotate_frame_address_end ();
-	      ui_out_text (out, " in ");
+	      out->text (" in ");
 	    }
 	  CATCH (except, RETURN_MASK_ERROR)
 	    {
@@ -1229,9 +1229,9 @@  py_print_frame (PyObject *filter, int flags,
 	    {
 	      annotate_frame_function_name ();
 	      if (function == NULL)
-		ui_out_field_skip (out, "func");
+		out->field_skip ("func");
 	      else
-		ui_out_field_string (out, "func", function);
+		out->field_string ("func", function);
 	    }
 	  CATCH (except, RETURN_MASK_ERROR)
 	    {
@@ -1297,10 +1297,10 @@  py_print_frame (PyObject *filter, int flags,
 
 	      TRY
 		{
-		  ui_out_wrap_hint (out, "   ");
-		  ui_out_text (out, " at ");
+		  out->wrap_hint ("   ");
+		  out->text (" at ");
 		  annotate_frame_source_file ();
-		  ui_out_field_string (out, "file", filename.get ());
+		  out->field_string ("file", filename.get ());
 		  annotate_frame_source_file_end ();
 		}
 	      CATCH (except, RETURN_MASK_ERROR)
@@ -1338,9 +1338,9 @@  py_print_frame (PyObject *filter, int flags,
 
 	      TRY
 		{
-		  ui_out_text (out, ":");
+		  out->text (":");
 		  annotate_frame_source_line ();
-		  ui_out_field_int (out, "line", line);
+		  out->field_int ("line", line);
 		}
 	      CATCH (except, RETURN_MASK_ERROR)
 		{
@@ -1356,12 +1356,12 @@  py_print_frame (PyObject *filter, int flags,
 
   /* For MI we need to deal with the "children" list population of
      elided frames, so if MI output detected do not send newline.  */
-  if (! ui_out_is_mi_like_p (out))
+  if (! out->is_mi_like_p ())
     {
       TRY
 	{
 	  annotate_frame_end ();
-	  ui_out_text (out, "\n");
+	  out->text ("\n");
 	}
       CATCH (except, RETURN_MASK_ERROR)
 	{
@@ -1401,7 +1401,7 @@  py_print_frame (PyObject *filter, int flags,
 
 	make_cleanup_ui_out_list_begin_end (out, "children");
 
-	if (! ui_out_is_mi_like_p (out))
+	if (! out->is_mi_like_p ())
 	  indent++;
 
 	while ((item = PyIter_Next (elided)))
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 7c0e39f..c446682 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -535,15 +535,15 @@  btrace_ui_out_decode_error (struct ui_out *uiout, int errcode,
 #endif /* defined (HAVE_LIBIPT)  */
     }
 
-  ui_out_text (uiout, _("["));
+  uiout->text (_("["));
   if (is_error)
     {
-      ui_out_text (uiout, _("decode error ("));
-      ui_out_field_int (uiout, "errcode", errcode);
-      ui_out_text (uiout, _("): "));
+      uiout->text (_("decode error ("));
+      uiout->field_int ("errcode", errcode);
+      uiout->text (_("): "));
     }
-  ui_out_text (uiout, errstr);
-  ui_out_text (uiout, _("]\n"));
+  uiout->text (errstr);
+  uiout->text (_("]\n"));
 }
 
 /* Print an unsigned int.  */
@@ -551,7 +551,7 @@  btrace_ui_out_decode_error (struct ui_out *uiout, int errcode,
 static void
 ui_out_field_uint (struct ui_out *uiout, const char *fld, unsigned int val)
 {
-  ui_out_field_fmt (uiout, fld, "%u", val);
+  uiout->field_fmt (fld, "%u", val);
 }
 
 /* A range of source lines.  */
@@ -968,7 +968,7 @@  btrace_call_history_insn_range (struct ui_out *uiout,
   end = begin + size - 1;
 
   ui_out_field_uint (uiout, "insn begin", begin);
-  ui_out_text (uiout, ",");
+  uiout->text (",");
   ui_out_field_uint (uiout, "insn end", end);
 }
 
@@ -1026,21 +1026,21 @@  btrace_call_history_src_line (struct ui_out *uiout,
   if (sym == NULL)
     return;
 
-  ui_out_field_string (uiout, "file",
+  uiout->field_string ("file",
 		       symtab_to_filename_for_display (symbol_symtab (sym)));
 
   btrace_compute_src_line_range (bfun, &begin, &end);
   if (end < begin)
     return;
 
-  ui_out_text (uiout, ":");
-  ui_out_field_int (uiout, "min line", begin);
+  uiout->text (":");
+  uiout->field_int ("min line", begin);
 
   if (end == begin)
     return;
 
-  ui_out_text (uiout, ",");
-  ui_out_field_int (uiout, "max line", end);
+  uiout->text (",");
+  uiout->field_int ("max line", end);
 }
 
 /* Get the name of a branch trace function.  */
@@ -1092,7 +1092,7 @@  btrace_call_history (struct ui_out *uiout,
 
       /* Print the function index.  */
       ui_out_field_uint (uiout, "index", bfun->number);
-      ui_out_text (uiout, "\t");
+      uiout->text ("\t");
 
       /* Indicate gaps in the trace.  */
       if (bfun->errcode != 0)
@@ -1114,29 +1114,29 @@  btrace_call_history (struct ui_out *uiout,
 	  int level = bfun->level + btinfo->level, i;
 
 	  for (i = 0; i < level; ++i)
-	    ui_out_text (uiout, "  ");
+	    uiout->text ("  ");
 	}
 
       if (sym != NULL)
-	ui_out_field_string (uiout, "function", SYMBOL_PRINT_NAME (sym));
+	uiout->field_string ("function", SYMBOL_PRINT_NAME (sym));
       else if (msym != NULL)
-	ui_out_field_string (uiout, "function", MSYMBOL_PRINT_NAME (msym));
-      else if (!ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "function", "??");
+	uiout->field_string ("function", MSYMBOL_PRINT_NAME (msym));
+      else if (!uiout->is_mi_like_p ())
+	uiout->field_string ("function", "??");
 
       if ((flags & RECORD_PRINT_INSN_RANGE) != 0)
 	{
-	  ui_out_text (uiout, _("\tinst "));
+	  uiout->text (_("\tinst "));
 	  btrace_call_history_insn_range (uiout, bfun);
 	}
 
       if ((flags & RECORD_PRINT_SRC_LINE) != 0)
 	{
-	  ui_out_text (uiout, _("\tat "));
+	  uiout->text (_("\tat "));
 	  btrace_call_history_src_line (uiout, bfun);
 	}
 
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
     }
 }
 
diff --git a/gdb/remote.c b/gdb/remote.c
index ef6c54e..c0f85c4 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -13785,8 +13785,8 @@  show_remote_cmd (char *args, int from_tty)
 	struct cleanup *option_chain
 	  = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
 
-	ui_out_field_string (uiout, "name", list->name);
-	ui_out_text (uiout, ":  ");
+	uiout->field_string ("name", list->name);
+	uiout->text (":  ");
 	if (list->type == show_cmd)
 	  do_show_command (NULL, from_tty, list);
 	else
diff --git a/gdb/skip.c b/gdb/skip.c
index fa0f0c9..73a6588 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -373,11 +373,10 @@  skip_info (char *arg, int from_tty)
   if (num_printable_entries == 0)
     {
       if (arg == NULL)
-	ui_out_message (current_uiout, _("\
-Not skipping any files or functions.\n"));
+	current_uiout->message (_("Not skipping any files or functions.\n"));
       else
-	ui_out_message (current_uiout,
-			_("No skiplist entries found with number %s.\n"), arg);
+	current_uiout->message (
+	  _("No skiplist entries found with number %s.\n"), arg);
 
       return;
     }
@@ -386,14 +385,13 @@  Not skipping any files or functions.\n"));
 						   num_printable_entries,
 						   "SkiplistTable");
 
-  ui_out_table_header (current_uiout, 5, ui_left, "number", "Num");   /* 1 */
-  ui_out_table_header (current_uiout, 3, ui_left, "enabled", "Enb");  /* 2 */
-  ui_out_table_header (current_uiout, 4, ui_right, "regexp", "Glob"); /* 3 */
-  ui_out_table_header (current_uiout, 20, ui_left, "file", "File");   /* 4 */
-  ui_out_table_header (current_uiout, 2, ui_right, "regexp", "RE");   /* 5 */
-  ui_out_table_header (current_uiout, 40, ui_noalign,
-		       "function", "Function"); /* 6 */
-  ui_out_table_body (current_uiout);
+  current_uiout->table_header (5, ui_left, "number", "Num");   /* 1 */
+  current_uiout->table_header (3, ui_left, "enabled", "Enb");  /* 2 */
+  current_uiout->table_header (4, ui_right, "regexp", "Glob"); /* 3 */
+  current_uiout->table_header (20, ui_left, "file", "File");   /* 4 */
+  current_uiout->table_header (2, ui_right, "regexp", "RE");   /* 5 */
+  current_uiout->table_header (40, ui_noalign, "function", "Function"); /* 6 */
+  current_uiout->table_body ();
 
   ALL_SKIPLIST_ENTRIES (e)
     {
@@ -405,29 +403,29 @@  Not skipping any files or functions.\n"));
 
       entry_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
 							 "blklst-entry");
-      ui_out_field_int (current_uiout, "number", e->number); /* 1 */
+      current_uiout->field_int ("number", e->number); /* 1 */
 
       if (e->enabled)
-	ui_out_field_string (current_uiout, "enabled", "y"); /* 2 */
+	current_uiout->field_string ("enabled", "y"); /* 2 */
       else
-	ui_out_field_string (current_uiout, "enabled", "n"); /* 2 */
+	current_uiout->field_string ("enabled", "n"); /* 2 */
 
       if (e->file_is_glob)
-	ui_out_field_string (current_uiout, "regexp", "y"); /* 3 */
+	current_uiout->field_string ("regexp", "y"); /* 3 */
       else
-	ui_out_field_string (current_uiout, "regexp", "n"); /* 3 */
+	current_uiout->field_string ("regexp", "n"); /* 3 */
 
-      ui_out_field_string (current_uiout, "file",
+      current_uiout->field_string ("file",
 			   e->file ? e->file : "<none>"); /* 4 */
       if (e->function_is_regexp)
-	ui_out_field_string (current_uiout, "regexp", "y"); /* 5 */
+	current_uiout->field_string ("regexp", "y"); /* 5 */
       else
-	ui_out_field_string (current_uiout, "regexp", "n"); /* 5 */
+	current_uiout->field_string ("regexp", "n"); /* 5 */
 
-      ui_out_field_string (current_uiout, "function", 
-			   e->function ? e->function : "<none>"); /* 6 */
+      current_uiout->field_string (
+	"function", e->function ? e->function : "<none>"); /* 6 */
 
-      ui_out_text (current_uiout, "\n");
+      current_uiout->text ("\n");
       do_cleanups (entry_chain);
     }
 
diff --git a/gdb/solib.c b/gdb/solib.c
index c4b2cdc..90b9bbb 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1110,13 +1110,12 @@  info_sharedlibrary_command (char *pattern, int from_tty)
 					 "SharedLibraryTable");
 
   /* The "- 1" is because ui_out adds one space between columns.  */
-  ui_out_table_header (uiout, addr_width - 1, ui_left, "from", "From");
-  ui_out_table_header (uiout, addr_width - 1, ui_left, "to", "To");
-  ui_out_table_header (uiout, 12 - 1, ui_left, "syms-read", "Syms Read");
-  ui_out_table_header (uiout, 0, ui_noalign,
-		       "name", "Shared Object Library");
+  uiout->table_header (addr_width - 1, ui_left, "from", "From");
+  uiout->table_header (addr_width - 1, ui_left, "to", "To");
+  uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read");
+  uiout->table_header (0, ui_noalign, "name", "Shared Object Library");
 
-  ui_out_table_body (uiout);
+  uiout->table_body ();
 
   for (so = so_list_head; so; so = so->next)
     {
@@ -1131,29 +1130,28 @@  info_sharedlibrary_command (char *pattern, int from_tty)
 
       if (so->addr_high != 0)
 	{
-	  ui_out_field_core_addr (uiout, "from", gdbarch, so->addr_low);
-	  ui_out_field_core_addr (uiout, "to", gdbarch, so->addr_high);
+	  uiout->field_core_addr ("from", gdbarch, so->addr_low);
+	  uiout->field_core_addr ("to", gdbarch, so->addr_high);
 	}
       else
 	{
-	  ui_out_field_skip (uiout, "from");
-	  ui_out_field_skip (uiout, "to");
+	  uiout->field_skip ("from");
+	  uiout->field_skip ("to");
 	}
 
-      if (! ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
+      if (! interp_ui_out (top_level_interpreter ())->is_mi_like_p ()
 	  && so->symbols_loaded
 	  && !objfile_has_symbols (so->objfile))
 	{
 	  so_missing_debug_info = 1;
-	  ui_out_field_string (uiout, "syms-read", "Yes (*)");
+	  uiout->field_string ("syms-read", "Yes (*)");
 	}
       else
-	ui_out_field_string (uiout, "syms-read", 
-			     so->symbols_loaded ? "Yes" : "No");
+	uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No");
 
-      ui_out_field_string (uiout, "name", so->so_name);
+      uiout->field_string ("name", so->so_name);
 
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
 
       do_cleanups (lib_cleanup);
     }
@@ -1163,17 +1161,14 @@  info_sharedlibrary_command (char *pattern, int from_tty)
   if (nr_libs == 0)
     {
       if (pattern)
-	ui_out_message (uiout,
-			_("No shared libraries matched.\n"));
+	uiout->message (_("No shared libraries matched.\n"));
       else
-	ui_out_message (uiout,
-			_("No shared libraries loaded at this time.\n"));
+	uiout->message (_("No shared libraries loaded at this time.\n"));
     }
   else
     {
       if (so_missing_debug_info)
-	ui_out_message (uiout,
-			_("(*): Shared library is missing "
+	uiout->message (_("(*): Shared library is missing "
 			  "debugging information.\n"));
     }
 }
diff --git a/gdb/source.c b/gdb/source.c
index a703851..7a71cbd 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1365,7 +1365,7 @@  print_source_lines_base (struct symtab *s, int line, int stopline,
 
   /* If printing of source lines is disabled, just print file and line
      number.  */
-  if (ui_out_test_flags (uiout, ui_source_list))
+  if (uiout->test_flags (ui_source_list))
     {
       /* Only prints "No such file or directory" once.  */
       if ((s != last_source_visited) || (!last_source_error))
@@ -1401,19 +1401,16 @@  print_source_lines_base (struct symtab *s, int line, int stopline,
 	}
       else
 	{
-	  ui_out_field_int (uiout, "line", line);
-	  ui_out_text (uiout, "\tin ");
+	  uiout->field_int ("line", line);
+	  uiout->text ("\tin ");
 
 	  /* CLI expects only the "file" field.  TUI expects only the
 	     "fullname" field (and TUI does break if "file" is printed).
 	     MI expects both fields.  ui_source_list is set only for CLI,
 	     not for TUI.  */
-	  if (ui_out_is_mi_like_p (uiout)
-	      || ui_out_test_flags (uiout, ui_source_list))
-	    ui_out_field_string (uiout, "file",
-				 symtab_to_filename_for_display (s));
-	  if (ui_out_is_mi_like_p (uiout)
-	      || !ui_out_test_flags (uiout, ui_source_list))
+	  if (uiout->is_mi_like_p () || uiout->test_flags (ui_source_list))
+	    uiout->field_string ("file", symtab_to_filename_for_display (s));
+	  if (uiout->is_mi_like_p () || !uiout->test_flags (ui_source_list))
  	    {
 	      const char *s_fullname = symtab_to_fullname (s);
 	      char *local_fullname;
@@ -1424,10 +1421,10 @@  print_source_lines_base (struct symtab *s, int line, int stopline,
 	      local_fullname = (char *) alloca (strlen (s_fullname) + 1);
 	      strcpy (local_fullname, s_fullname);
 
-	      ui_out_field_string (uiout, "fullname", local_fullname);
+	      uiout->field_string ("fullname", local_fullname);
  	    }
 
-	  ui_out_text (uiout, "\n");
+	  uiout->text ("\n");
 	}
 
       return;
@@ -1465,20 +1462,20 @@  print_source_lines_base (struct symtab *s, int line, int stopline,
       last_line_listed = current_source_line;
       if (flags & PRINT_SOURCE_LINES_FILENAME)
         {
-          ui_out_text (uiout, symtab_to_filename_for_display (s));
-          ui_out_text (uiout, ":");
+          uiout->text (symtab_to_filename_for_display (s));
+          uiout->text (":");
         }
       xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++);
-      ui_out_text (uiout, buf);
+      uiout->text (buf);
       do
 	{
 	  if (c < 040 && c != '\t' && c != '\n' && c != '\r')
 	    {
 	      xsnprintf (buf, sizeof (buf), "^%c", c + 0100);
-	      ui_out_text (uiout, buf);
+	      uiout->text (buf);
 	    }
 	  else if (c == 0177)
-	    ui_out_text (uiout, "^?");
+	    uiout->text ("^?");
 	  else if (c == '\r')
 	    {
 	      /* Skip a \r character, but only before a \n.  */
@@ -1492,7 +1489,7 @@  print_source_lines_base (struct symtab *s, int line, int stopline,
 	  else
 	    {
 	      xsnprintf (buf, sizeof (buf), "%c", c);
-	      ui_out_text (uiout, buf);
+	      uiout->text (buf);
 	    }
 	}
       while (c != '\n' && (c = fgetc (stream)) >= 0);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index a7c2bf0..e398a14 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -2097,12 +2097,12 @@  info_spu_event_command (char *args, int from_tty)
  
   chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoEvent");
 
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     {
-      ui_out_field_fmt (current_uiout, "event_status",
-			"0x%s", phex_nz (event_status, 4));
-      ui_out_field_fmt (current_uiout, "event_mask",
-			"0x%s", phex_nz (event_mask, 4));
+      current_uiout->field_fmt ("event_status",
+				"0x%s", phex_nz (event_status, 4));
+      current_uiout->field_fmt ("event_mask",
+				"0x%s", phex_nz (event_mask, 4));
     }
   else
     {
@@ -2174,14 +2174,14 @@  info_spu_signal_command (char *args, int from_tty)
 
   chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoSignal");
 
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     {
-      ui_out_field_int (current_uiout, "signal1_pending", signal1_pending);
-      ui_out_field_fmt (current_uiout, "signal1", "0x%s", phex_nz (signal1, 4));
-      ui_out_field_int (current_uiout, "signal1_type", signal1_type);
-      ui_out_field_int (current_uiout, "signal2_pending", signal2_pending);
-      ui_out_field_fmt (current_uiout, "signal2", "0x%s", phex_nz (signal2, 4));
-      ui_out_field_int (current_uiout, "signal2_type", signal2_type);
+      current_uiout->field_int ("signal1_pending", signal1_pending);
+      current_uiout->field_fmt ("signal1", "0x%s", phex_nz (signal1, 4));
+      current_uiout->field_int ("signal1_type", signal1_type);
+      current_uiout->field_int ("signal2_pending", signal2_pending);
+      current_uiout->field_fmt ("signal2", "0x%s", phex_nz (signal2, 4));
+      current_uiout->field_int ("signal2_type", signal2_type);
     }
   else
     {
@@ -2221,8 +2221,8 @@  info_spu_mailbox_list (gdb_byte *buf, int nr, enum bfd_endian byte_order,
 
   chain = make_cleanup_ui_out_table_begin_end (current_uiout, 1, nr, "mbox");
 
-  ui_out_table_header (current_uiout, 32, ui_left, field, msg);
-  ui_out_table_body (current_uiout);
+  current_uiout->table_header (32, ui_left, field, msg);
+  current_uiout->table_body ();
 
   for (i = 0; i < nr; i++)
     {
@@ -2230,10 +2230,10 @@  info_spu_mailbox_list (gdb_byte *buf, int nr, enum bfd_endian byte_order,
       ULONGEST val;
       val_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "mbox");
       val = extract_unsigned_integer (buf + 4*i, 4, byte_order);
-      ui_out_field_fmt (current_uiout, field, "0x%s", phex (val, 4));
+      current_uiout->field_fmt (field, "0x%s", phex (val, 4));
       do_cleanups (val_chain);
 
-      if (!ui_out_is_mi_like_p (current_uiout))
+      if (!current_uiout->is_mi_like_p ())
 	printf_filtered ("\n");
     }
 
@@ -2378,18 +2378,18 @@  info_spu_dma_cmdlist (gdb_byte *buf, int nr, enum bfd_endian byte_order)
   chain = make_cleanup_ui_out_table_begin_end (current_uiout, 10, nr,
 					       "dma_cmd");
 
-  ui_out_table_header (current_uiout, 7, ui_left, "opcode", "Opcode");
-  ui_out_table_header (current_uiout, 3, ui_left, "tag", "Tag");
-  ui_out_table_header (current_uiout, 3, ui_left, "tid", "TId");
-  ui_out_table_header (current_uiout, 3, ui_left, "rid", "RId");
-  ui_out_table_header (current_uiout, 18, ui_left, "ea", "EA");
-  ui_out_table_header (current_uiout, 7, ui_left, "lsa", "LSA");
-  ui_out_table_header (current_uiout, 7, ui_left, "size", "Size");
-  ui_out_table_header (current_uiout, 7, ui_left, "lstaddr", "LstAddr");
-  ui_out_table_header (current_uiout, 7, ui_left, "lstsize", "LstSize");
-  ui_out_table_header (current_uiout, 1, ui_left, "error_p", "E");
+  current_uiout->table_header (7, ui_left, "opcode", "Opcode");
+  current_uiout->table_header (3, ui_left, "tag", "Tag");
+  current_uiout->table_header (3, ui_left, "tid", "TId");
+  current_uiout->table_header (3, ui_left, "rid", "RId");
+  current_uiout->table_header (18, ui_left, "ea", "EA");
+  current_uiout->table_header (7, ui_left, "lsa", "LSA");
+  current_uiout->table_header (7, ui_left, "size", "Size");
+  current_uiout->table_header (7, ui_left, "lstaddr", "LstAddr");
+  current_uiout->table_header (7, ui_left, "lstsize", "LstSize");
+  current_uiout->table_header (1, ui_left, "error_p", "E");
 
-  ui_out_table_body (current_uiout);
+  current_uiout->table_body ();
 
   for (i = 0; i < nr; i++)
     {
@@ -2432,44 +2432,44 @@  info_spu_dma_cmdlist (gdb_byte *buf, int nr, enum bfd_endian byte_order)
       cmd_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "cmd");
 
       if (spu_mfc_opcode[mfc_cmd_opcode])
-	ui_out_field_string (current_uiout, "opcode", spu_mfc_opcode[mfc_cmd_opcode]);
+	current_uiout->field_string ("opcode", spu_mfc_opcode[mfc_cmd_opcode]);
       else
-	ui_out_field_int (current_uiout, "opcode", mfc_cmd_opcode);
+	current_uiout->field_int ("opcode", mfc_cmd_opcode);
 
-      ui_out_field_int (current_uiout, "tag", mfc_cmd_tag);
-      ui_out_field_int (current_uiout, "tid", tclass_id);
-      ui_out_field_int (current_uiout, "rid", rclass_id);
+      current_uiout->field_int ("tag", mfc_cmd_tag);
+      current_uiout->field_int ("tid", tclass_id);
+      current_uiout->field_int ("rid", rclass_id);
 
       if (ea_valid_p)
-	ui_out_field_fmt (current_uiout, "ea", "0x%s", phex (mfc_ea, 8));
+	current_uiout->field_fmt ("ea", "0x%s", phex (mfc_ea, 8));
       else
-	ui_out_field_skip (current_uiout, "ea");
+	current_uiout->field_skip ("ea");
 
-      ui_out_field_fmt (current_uiout, "lsa", "0x%05x", mfc_lsa << 4);
+      current_uiout->field_fmt ("lsa", "0x%05x", mfc_lsa << 4);
       if (qw_valid_p)
-	ui_out_field_fmt (current_uiout, "size", "0x%05x", mfc_size << 4);
+	current_uiout->field_fmt ("size", "0x%05x", mfc_size << 4);
       else
-	ui_out_field_fmt (current_uiout, "size", "0x%05x", mfc_size);
+	current_uiout->field_fmt ("size", "0x%05x", mfc_size);
 
       if (list_valid_p)
 	{
-	  ui_out_field_fmt (current_uiout, "lstaddr", "0x%05x", list_lsa << 3);
-	  ui_out_field_fmt (current_uiout, "lstsize", "0x%05x", list_size << 3);
+	  current_uiout->field_fmt ("lstaddr", "0x%05x", list_lsa << 3);
+	  current_uiout->field_fmt ("lstsize", "0x%05x", list_size << 3);
 	}
       else
 	{
-	  ui_out_field_skip (current_uiout, "lstaddr");
-	  ui_out_field_skip (current_uiout, "lstsize");
+	  current_uiout->field_skip ("lstaddr");
+	  current_uiout->field_skip ("lstsize");
 	}
 
       if (cmd_error_p)
-	ui_out_field_string (current_uiout, "error_p", "*");
+	current_uiout->field_string ("error_p", "*");
       else
-	ui_out_field_skip (current_uiout, "error_p");
+	current_uiout->field_skip ("error_p");
 
       do_cleanups (cmd_chain);
 
-      if (!ui_out_is_mi_like_p (current_uiout))
+      if (!current_uiout->is_mi_like_p ())
 	printf_filtered ("\n");
     }
 
@@ -2517,18 +2517,18 @@  info_spu_dma_command (char *args, int from_tty)
   
   chain = make_cleanup_ui_out_tuple_begin_end (current_uiout, "SPUInfoDMA");
 
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     {
-      ui_out_field_fmt (current_uiout, "dma_info_type", "0x%s",
-			phex_nz (dma_info_type, 4));
-      ui_out_field_fmt (current_uiout, "dma_info_mask", "0x%s",
-			phex_nz (dma_info_mask, 4));
-      ui_out_field_fmt (current_uiout, "dma_info_status", "0x%s",
-			phex_nz (dma_info_status, 4));
-      ui_out_field_fmt (current_uiout, "dma_info_stall_and_notify", "0x%s",
-			phex_nz (dma_info_stall_and_notify, 4));
-      ui_out_field_fmt (current_uiout, "dma_info_atomic_command_status", "0x%s",
-			phex_nz (dma_info_atomic_command_status, 4));
+      current_uiout->field_fmt ("dma_info_type", "0x%s",
+				phex_nz (dma_info_type, 4));
+      current_uiout->field_fmt ("dma_info_mask", "0x%s",
+				phex_nz (dma_info_mask, 4));
+      current_uiout->field_fmt ("dma_info_status", "0x%s",
+				phex_nz (dma_info_status, 4));
+      current_uiout->field_fmt ("dma_info_stall_and_notify", "0x%s",
+				phex_nz (dma_info_stall_and_notify, 4));
+      current_uiout->field_fmt ("dma_info_atomic_command_status", "0x%s",
+				phex_nz (dma_info_atomic_command_status, 4));
     }
   else
     {
@@ -2590,14 +2590,14 @@  info_spu_proxydma_command (char *args, int from_tty)
   chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
 					       "SPUInfoProxyDMA");
 
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     {
-      ui_out_field_fmt (current_uiout, "proxydma_info_type", "0x%s",
-			phex_nz (dma_info_type, 4));
-      ui_out_field_fmt (current_uiout, "proxydma_info_mask", "0x%s",
-			phex_nz (dma_info_mask, 4));
-      ui_out_field_fmt (current_uiout, "proxydma_info_status", "0x%s",
-			phex_nz (dma_info_status, 4));
+      current_uiout->field_fmt ("proxydma_info_type", "0x%s",
+				phex_nz (dma_info_type, 4));
+      current_uiout->field_fmt ("proxydma_info_mask", "0x%s",
+				phex_nz (dma_info_mask, 4));
+      current_uiout->field_fmt ("proxydma_info_status", "0x%s",
+				phex_nz (dma_info_status, 4));
     }
   else
     {
diff --git a/gdb/stack.c b/gdb/stack.c
index 9b4e356..4e3bc67 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -167,7 +167,7 @@  print_stack_frame (struct frame_info *frame, int print_level,
 {
 
   /* For mi, alway print location and address.  */
-  if (ui_out_is_mi_like_p (current_uiout))
+  if (current_uiout->is_mi_like_p ())
     print_what = LOC_AND_ADDRESS;
 
   TRY
@@ -234,7 +234,7 @@  print_frame_arg (const struct frame_arg *arg)
   gdb_assert (!arg->val || !arg->error);
   gdb_assert (arg->entry_kind == print_entry_values_no
 	      || arg->entry_kind == print_entry_values_only
-	      || (!ui_out_is_mi_like_p (uiout)
+	      || (!uiout->is_mi_like_p ()
 		  && arg->entry_kind == print_entry_values_compact));
 
   annotate_arg_begin ();
@@ -255,12 +255,12 @@  print_frame_arg (const struct frame_arg *arg)
   if (arg->entry_kind == print_entry_values_only
       || arg->entry_kind == print_entry_values_compact)
     fputs_filtered ("@entry", stb);
-  ui_out_field_stream (uiout, "name", stb);
+  uiout->field_stream ("name", stb);
   annotate_arg_name_end ();
-  ui_out_text (uiout, "=");
+  uiout->text ("=");
 
   if (!arg->val && !arg->error)
-    ui_out_text (uiout, "...");
+    uiout->text ("...");
   else
     {
       if (arg->error)
@@ -307,7 +307,7 @@  print_frame_arg (const struct frame_arg *arg)
 			  error_message);
     }
 
-  ui_out_field_stream (uiout, "value", stb);
+  uiout->field_stream ("value", stb);
 
   /* Also invoke ui_out_tuple_end.  */
   do_cleanups (old_chain);
@@ -396,7 +396,7 @@  read_frame_arg (struct symbol *sym, struct frame_info *frame,
 	{
 	  /* For MI do not try to use print_entry_values_compact for ARGP.  */
 
-	  if (val && entryval && !ui_out_is_mi_like_p (current_uiout))
+	  if (val && entryval && !current_uiout->is_mi_like_p ())
 	    {
 	      struct type *type = value_type (val);
 
@@ -518,7 +518,7 @@  read_frame_arg (struct symbol *sym, struct frame_info *frame,
 	   || print_entry_values == print_entry_values_default) && val_equal)
     {
       argp->entry_kind = print_entry_values_compact;
-      gdb_assert (!ui_out_is_mi_like_p (current_uiout));
+      gdb_assert (!current_uiout->is_mi_like_p ());
     }
   else
     argp->entry_kind = print_entry_values_no;
@@ -680,8 +680,8 @@  print_frame_args (struct symbol *func, struct frame_info *frame,
 
 	  /* Print the current arg.  */
 	  if (!first)
-	    ui_out_text (uiout, ", ");
-	  ui_out_wrap_hint (uiout, "    ");
+	    uiout->text (", ");
+	  uiout->wrap_hint ("    ");
 
 	  if (!print_args)
 	    {
@@ -702,8 +702,8 @@  print_frame_args (struct symbol *func, struct frame_info *frame,
 	    {
 	      if (arg.entry_kind != print_entry_values_only)
 		{
-		  ui_out_text (uiout, ", ");
-		  ui_out_wrap_hint (uiout, "    ");
+		  uiout->text (", ");
+		  uiout->wrap_hint ("    ");
 		}
 
 	      print_frame_arg (&entryarg);
@@ -826,14 +826,14 @@  print_frame_info (struct frame_info *frame, int print_level,
          to list for this frame.  */
       if (print_level)
         {
-          ui_out_text (uiout, "#");
-          ui_out_field_fmt_int (uiout, 2, ui_left, "level",
+          uiout->text ("#");
+          uiout->field_fmt_int (2, ui_left, "level",
 				frame_relative_level (frame));
         }
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
         {
           annotate_frame_address ();
-          ui_out_field_core_addr (uiout, "addr",
+          uiout->field_core_addr ("addr",
 				  gdbarch, get_frame_pc (frame));
           annotate_frame_address_end ();
         }
@@ -841,18 +841,18 @@  print_frame_info (struct frame_info *frame, int print_level,
       if (get_frame_type (frame) == DUMMY_FRAME)
         {
           annotate_function_call ();
-          ui_out_field_string (uiout, "func", "<function called from gdb>");
+          uiout->field_string ("func", "<function called from gdb>");
 	}
       else if (get_frame_type (frame) == SIGTRAMP_FRAME)
         {
 	  annotate_signal_handler_caller ();
-          ui_out_field_string (uiout, "func", "<signal handler called>");
+          uiout->field_string ("func", "<signal handler called>");
         }
       else if (get_frame_type (frame) == ARCH_FRAME)
         {
-          ui_out_field_string (uiout, "func", "<cross-architecture call>");
+          uiout->field_string ("func", "<cross-architecture call>");
 	}
-      ui_out_text (uiout, "\n");
+      uiout->text ("\n");
       annotate_frame_end ();
 
       /* If disassemble-next-line is set to auto or on output the next
@@ -921,9 +921,9 @@  print_frame_info (struct frame_info *frame, int print_level,
 		 ability to decide for themselves if it is desired.  */
 	      if (opts.addressprint && mid_statement)
 		{
-		  ui_out_field_core_addr (uiout, "addr",
+		  uiout->field_core_addr ("addr",
 					  gdbarch, get_frame_pc (frame));
-		  ui_out_text (uiout, "\t");
+		  uiout->text ("\t");
 		}
 
 	      print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
@@ -1187,8 +1187,8 @@  print_frame (struct frame_info *frame, int print_level,
 
   if (print_level)
     {
-      ui_out_text (uiout, "#");
-      ui_out_field_fmt_int (uiout, 2, ui_left, "level",
+      uiout->text ("#");
+      uiout->field_fmt_int (2, ui_left, "level",
 			    frame_relative_level (frame));
     }
   get_user_print_options (&opts);
@@ -1199,20 +1199,20 @@  print_frame (struct frame_info *frame, int print_level,
       {
 	annotate_frame_address ();
 	if (pc_p)
-	  ui_out_field_core_addr (uiout, "addr", gdbarch, pc);
+	  uiout->field_core_addr ("addr", gdbarch, pc);
 	else
-	  ui_out_field_string (uiout, "addr", "<unavailable>");
+	  uiout->field_string ("addr", "<unavailable>");
 	annotate_frame_address_end ();
-	ui_out_text (uiout, " in ");
+	uiout->text (" in ");
       }
   annotate_frame_function_name ();
   fprintf_symbol_filtered (stb, funname ? funname : "??",
 			   funlang, DMGL_ANSI);
-  ui_out_field_stream (uiout, "func", stb);
-  ui_out_wrap_hint (uiout, "   ");
+  uiout->field_stream ("func", stb);
+  uiout->wrap_hint ("   ");
   annotate_frame_args ();
       
-  ui_out_text (uiout, " (");
+  uiout->text (" (");
   if (print_args)
     {
       struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1243,27 +1243,27 @@  print_frame (struct frame_info *frame, int print_level,
       do_cleanups (args_list_chain);
       QUIT;
     }
-  ui_out_text (uiout, ")");
+  uiout->text (")");
   if (sal.symtab)
     {
       const char *filename_display;
       
       filename_display = symtab_to_filename_for_display (sal.symtab);
       annotate_frame_source_begin ();
-      ui_out_wrap_hint (uiout, "   ");
-      ui_out_text (uiout, " at ");
+      uiout->wrap_hint ("   ");
+      uiout->text (" at ");
       annotate_frame_source_file ();
-      ui_out_field_string (uiout, "file", filename_display);
-      if (ui_out_is_mi_like_p (uiout))
+      uiout->field_string ("file", filename_display);
+      if (uiout->is_mi_like_p ())
 	{
 	  const char *fullname = symtab_to_fullname (sal.symtab);
 
-	  ui_out_field_string (uiout, "fullname", fullname);
+	  uiout->field_string ("fullname", fullname);
 	}
       annotate_frame_source_file_end ();
-      ui_out_text (uiout, ":");
+      uiout->text (":");
       annotate_frame_source_line ();
-      ui_out_field_int (uiout, "line", sal.line);
+      uiout->field_int ("line", sal.line);
       annotate_frame_source_end ();
     }
 
@@ -1275,15 +1275,15 @@  print_frame (struct frame_info *frame, int print_level,
       if (lib)
 	{
 	  annotate_frame_where ();
-	  ui_out_wrap_hint (uiout, "  ");
-	  ui_out_text (uiout, " from ");
-	  ui_out_field_string (uiout, "from", lib);
+	  uiout->wrap_hint ("  ");
+	  uiout->text (" from ");
+	  uiout->field_string ("from", lib);
 	}
     }
 
   /* do_cleanups will call ui_out_tuple_end() for us.  */
   do_cleanups (list_chain);
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
   do_cleanups (old_chain);
 }
 
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 52f99bf..3a9c488 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1962,9 +1962,10 @@  load_progress (ULONGEST bytes, void *untyped_arg)
     {
       /* The write is just starting.  Let the user know we've started
 	 this section.  */
-      ui_out_message (current_uiout, "Loading section %s, size %s lma %s\n",
-		      args->section_name, hex_string (args->section_size),
-		      paddress (target_gdbarch (), args->lma));
+      current_uiout->message ("Loading section %s, size %s lma %s\n",
+			      args->section_name,
+			      hex_string (args->section_size),
+			      paddress (target_gdbarch (), args->lma));
       return;
     }
 
@@ -2146,11 +2147,11 @@  generic_load (const char *args, int from_tty)
 
   entry = bfd_get_start_address (loadfile_bfd);
   entry = gdbarch_addr_bits_remove (target_gdbarch (), entry);
-  ui_out_text (uiout, "Start address ");
-  ui_out_field_fmt (uiout, "address", "%s", paddress (target_gdbarch (), entry));
-  ui_out_text (uiout, ", load size ");
-  ui_out_field_fmt (uiout, "load-size", "%lu", total_progress.data_count);
-  ui_out_text (uiout, "\n");
+  uiout->text ("Start address ");
+  uiout->field_fmt ("address", "%s", paddress (target_gdbarch (), entry));
+  uiout->text (", load size ");
+  uiout->field_fmt ("load-size", "%lu", total_progress.data_count);
+  uiout->text ("\n");
   regcache_write_pc (get_current_regcache (), entry);
 
   /* Reset breakpoints, now that we have changed the load image.  For
@@ -2187,39 +2188,39 @@  print_transfer_performance (struct ui_file *stream,
 
   milliseconds ms = duration_cast<milliseconds> (time);
 
-  ui_out_text (uiout, "Transfer rate: ");
+  uiout->text ("Transfer rate: ");
   if (ms.count () > 0)
     {
       unsigned long rate = ((ULONGEST) data_count * 1000) / ms.count ();
 
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
 	{
-	  ui_out_field_fmt (uiout, "transfer-rate", "%lu", rate * 8);
-	  ui_out_text (uiout, " bits/sec");
+	  uiout->field_fmt ("transfer-rate", "%lu", rate * 8);
+	  uiout->text (" bits/sec");
 	}
       else if (rate < 1024)
 	{
-	  ui_out_field_fmt (uiout, "transfer-rate", "%lu", rate);
-	  ui_out_text (uiout, " bytes/sec");
+	  uiout->field_fmt ("transfer-rate", "%lu", rate);
+	  uiout->text (" bytes/sec");
 	}
       else
 	{
-	  ui_out_field_fmt (uiout, "transfer-rate", "%lu", rate / 1024);
-	  ui_out_text (uiout, " KB/sec");
+	  uiout->field_fmt ("transfer-rate", "%lu", rate / 1024);
+	  uiout->text (" KB/sec");
 	}
     }
   else
     {
-      ui_out_field_fmt (uiout, "transferred-bits", "%lu", (data_count * 8));
-      ui_out_text (uiout, " bits in <1 sec");
+      uiout->field_fmt ("transferred-bits", "%lu", (data_count * 8));
+      uiout->text (" bits in <1 sec");
     }
   if (write_count > 0)
     {
-      ui_out_text (uiout, ", ");
-      ui_out_field_fmt (uiout, "write-rate", "%lu", data_count / write_count);
-      ui_out_text (uiout, " bytes/write");
+      uiout->text (", ");
+      uiout->field_fmt ("write-rate", "%lu", data_count / write_count);
+      uiout->text (" bytes/write");
     }
-  ui_out_text (uiout, ".\n");
+  uiout->text (".\n");
 }
 
 /* This function allows the addition of incrementally linked object files.
diff --git a/gdb/thread.c b/gdb/thread.c
index e5d6c5f..836dbc2 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -712,14 +712,14 @@  do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
 	current_thread = tp->global_num;
 
       num++;
-      ui_out_field_int (uiout, "thread-id", tp->global_num);
+      uiout->field_int ("thread-id", tp->global_num);
     }
 
   do_cleanups (cleanup_chain);
 
   if (current_thread != -1)
-    ui_out_field_int (uiout, "current-thread-id", current_thread);
-  ui_out_field_int (uiout, "number-of-threads", num);
+    uiout->field_int ("current-thread-id", current_thread);
+  uiout->field_int ("number-of-threads", num);
   return GDB_RC_OK;
 }
 
@@ -1213,7 +1213,7 @@  print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
   /* For backward compatibility, we make a list for MI.  A table is
      preferable for the CLI, though, because it shows table
      headers.  */
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     make_cleanup_ui_out_list_begin_end (uiout, "threads");
   else
     {
@@ -1231,28 +1231,28 @@  print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
       if (n_threads == 0)
 	{
 	  if (requested_threads == NULL || *requested_threads == '\0')
-	    ui_out_message (uiout, _("No threads.\n"));
+	    uiout->message (_("No threads.\n"));
 	  else
-	    ui_out_message (uiout, _("No threads match '%s'.\n"),
+	    uiout->message (_("No threads match '%s'.\n"),
 			    requested_threads);
 	  do_cleanups (old_chain);
 	  return;
 	}
 
-      if (show_global_ids || ui_out_is_mi_like_p (uiout))
+      if (show_global_ids || uiout->is_mi_like_p ())
 	make_cleanup_ui_out_table_begin_end (uiout, 5, n_threads, "threads");
       else
 	make_cleanup_ui_out_table_begin_end (uiout, 4, n_threads, "threads");
 
-      ui_out_table_header (uiout, 1, ui_left, "current", "");
+      uiout->table_header (1, ui_left, "current", "");
 
-      if (!ui_out_is_mi_like_p (uiout))
-	ui_out_table_header (uiout, 4, ui_left, "id-in-tg", "Id");
-      if (show_global_ids || ui_out_is_mi_like_p (uiout))
-	ui_out_table_header (uiout, 4, ui_left, "id", "GId");
-      ui_out_table_header (uiout, 17, ui_left, "target-id", "Target Id");
-      ui_out_table_header (uiout, 1, ui_left, "frame", "Frame");
-      ui_out_table_body (uiout);
+      if (!uiout->is_mi_like_p ())
+	uiout->table_header (4, ui_left, "id-in-tg", "Id");
+      if (show_global_ids || uiout->is_mi_like_p ())
+	uiout->table_header (4, ui_left, "id", "GId");
+      uiout->table_header (17, ui_left, "target-id", "Target Id");
+      uiout->table_header (1, ui_left, "frame", "Frame");
+      uiout->table_body ();
     }
 
   ALL_THREADS_BY_INFERIOR (inf, tp)
@@ -1266,27 +1266,27 @@  print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
 
       chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
 
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
 	{
 	  /* Compatibility.  */
 	  if (ptid_equal (tp->ptid, current_ptid))
-	    ui_out_text (uiout, "* ");
+	    uiout->text ("* ");
 	  else
-	    ui_out_text (uiout, "  ");
+	    uiout->text ("  ");
 	}
       else
 	{
 	  if (ptid_equal (tp->ptid, current_ptid))
-	    ui_out_field_string (uiout, "current", "*");
+	    uiout->field_string ("current", "*");
 	  else
-	    ui_out_field_skip (uiout, "current");
+	    uiout->field_skip ("current");
 	}
 
-      if (!ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "id-in-tg", print_thread_id (tp));
+      if (!uiout->is_mi_like_p ())
+	uiout->field_string ("id-in-tg", print_thread_id (tp));
 
-      if (show_global_ids || ui_out_is_mi_like_p (uiout))
-	ui_out_field_int (uiout, "id", tp->global_num);
+      if (show_global_ids || uiout->is_mi_like_p ())
+	uiout->field_int ("id", tp->global_num);
 
       /* For the CLI, we stuff everything into the target-id field.
 	 This is a gross hack to make the output come out looking
@@ -1299,13 +1299,13 @@  print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
       extra_info = target_extra_thread_info (tp);
       name = tp->name ? tp->name : target_thread_name (tp);
 
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
 	{
-	  ui_out_field_string (uiout, "target-id", target_id);
+	  uiout->field_string ("target-id", target_id);
 	  if (extra_info)
-	    ui_out_field_string (uiout, "details", extra_info);
+	    uiout->field_string ("details", extra_info);
 	  if (name)
-	    ui_out_field_string (uiout, "name", name);
+	    uiout->field_string ("name", name);
 	}
       else
 	{
@@ -1323,12 +1323,12 @@  print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
 	    contents = xstrdup (target_id);
 	  str_cleanup = make_cleanup (xfree, contents);
 
-	  ui_out_field_string (uiout, "target-id", contents);
+	  uiout->field_string ("target-id", contents);
 	  do_cleanups (str_cleanup);
 	}
 
       if (tp->state == THREAD_RUNNING)
-	ui_out_text (uiout, "(running)\n");
+	uiout->text ("(running)\n");
       else
 	{
 	  /* The switch below puts us at the top of the stack (leaf
@@ -1336,22 +1336,22 @@  print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
 	  switch_to_thread (tp->ptid);
 	  print_stack_frame (get_selected_frame (NULL),
 			     /* For MI output, print frame level.  */
-			     ui_out_is_mi_like_p (uiout),
+			     uiout->is_mi_like_p (),
 			     LOCATION, 0);
 	}
 
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
 	{
 	  char *state = "stopped";
 
 	  if (tp->state == THREAD_RUNNING)
 	    state = "running";
-	  ui_out_field_string (uiout, "state", state);
+	  uiout->field_string ("state", state);
 	}
 
       core = target_core_of_thread (tp->ptid);
-      if (ui_out_is_mi_like_p (uiout) && core != -1)
-	ui_out_field_int (uiout, "core", core);
+      if (uiout->is_mi_like_p () && core != -1)
+	uiout->field_int ("core", core);
 
       do_cleanups (chain2);
     }
@@ -1362,22 +1362,22 @@  print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
 
   if (pid == -1 && requested_threads == NULL)
     {
-      if (ui_out_is_mi_like_p (uiout)
+      if (uiout->is_mi_like_p ()
 	  && !ptid_equal (inferior_ptid, null_ptid))
 	{
 	  int num = ptid_to_global_thread_id (inferior_ptid);
 
 	  gdb_assert (num != 0);
-	  ui_out_field_int (uiout, "current-thread-id", num);
+	  uiout->field_int ("current-thread-id", num);
 	}
 
       if (!ptid_equal (inferior_ptid, null_ptid) && is_exited (inferior_ptid))
-	ui_out_message (uiout, "\n\
+	uiout->message ("\n\
 The current thread <Thread ID %s> has terminated.  See `help thread'.\n",
 			print_thread_id (inferior_thread ()));
       else if (thread_list != NULL
 	       && ptid_equal (inferior_ptid, null_ptid))
-	ui_out_message (uiout, "\n\
+	uiout->message ("\n\
 No selected thread.  See `help thread'.\n");
     }
 }
@@ -1515,7 +1515,7 @@  restore_selected_frame (struct frame_id a_frame_id, int frame_level)
   select_frame (get_current_frame ());
 
   /* Warn the user.  */
-  if (frame_level > 0 && !ui_out_is_mi_like_p (current_uiout))
+  if (frame_level > 0 && !current_uiout->is_mi_like_p ())
     {
       warning (_("Couldn't restore frame #%d in "
 		 "current thread.  Bottom (innermost) frame selected:"),
@@ -2055,7 +2055,7 @@  do_captured_thread_select (struct ui_out *uiout, void *tidstr_v)
   const char *tidstr = (const char *) tidstr_v;
   struct thread_info *tp;
 
-  if (ui_out_is_mi_like_p (uiout))
+  if (uiout->is_mi_like_p ())
     {
       int num = value_as_long (parse_and_eval (tidstr));
 
@@ -2094,30 +2094,30 @@  print_selected_thread_frame (struct ui_out *uiout,
 
   if (selection & USER_SELECTED_THREAD)
     {
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
 	{
-	  ui_out_field_int (uiout, "new-thread-id",
+	  uiout->field_int ("new-thread-id",
 			    inferior_thread ()->global_num);
 	}
       else
 	{
-	  ui_out_text (uiout, "[Switching to thread ");
-	  ui_out_field_string (uiout, "new-thread-id", print_thread_id (tp));
-	  ui_out_text (uiout, " (");
-	  ui_out_text (uiout, target_pid_to_str (inferior_ptid));
-	  ui_out_text (uiout, ")]");
+	  uiout->text ("[Switching to thread ");
+	  uiout->field_string ("new-thread-id", print_thread_id (tp));
+	  uiout->text (" (");
+	  uiout->text (target_pid_to_str (inferior_ptid));
+	  uiout->text (")]");
 	}
     }
 
   if (tp->state == THREAD_RUNNING)
     {
       if (selection & USER_SELECTED_THREAD)
-	ui_out_text (uiout, "(running)\n");
+	uiout->text ("(running)\n");
     }
   else if (selection & USER_SELECTED_FRAME)
     {
       if (selection & USER_SELECTED_THREAD)
-	ui_out_text (uiout, "\n");
+	uiout->text ("\n");
 
       if (has_stack_frames ())
 	print_stack_frame_to_uiout (uiout, get_selected_frame (NULL),
diff --git a/gdb/top.c b/gdb/top.c
index 7d8b6e8..077fb2a 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -706,7 +706,7 @@  execute_command_to_string (char *p, int from_tty)
 
   make_cleanup_ui_file_delete (str_file);
 
-  if (ui_out_redirect (current_uiout, str_file) < 0)
+  if (current_uiout->redirect (str_file) < 0)
     warning (_("Current output protocol does not support redirection"));
   else
     make_cleanup_ui_out_redirect_pop (current_uiout);
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 9092d3e..1a00353 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -486,7 +486,7 @@  tvariables_info_1 (void)
   struct cleanup *back_to;
   struct ui_out *uiout = current_uiout;
 
-  if (VEC_length (tsv_s, tvariables) == 0 && !ui_out_is_mi_like_p (uiout))
+  if (VEC_length (tsv_s, tvariables) == 0 && !uiout->is_mi_like_p ())
     {
       printf_filtered (_("No trace state variables.\n"));
       return;
@@ -499,11 +499,11 @@  tvariables_info_1 (void)
 
   back_to = make_cleanup_ui_out_table_begin_end (uiout, 3,
                                                  count, "trace-variables");
-  ui_out_table_header (uiout, 15, ui_left, "name", "Name");
-  ui_out_table_header (uiout, 11, ui_left, "initial", "Initial");
-  ui_out_table_header (uiout, 11, ui_left, "current", "Current");
+  uiout->table_header (15, ui_left, "name", "Name");
+  uiout->table_header (11, ui_left, "initial", "Initial");
+  uiout->table_header (11, ui_left, "current", "Current");
 
-  ui_out_table_body (uiout);
+  uiout->table_body ();
 
   for (ix = 0; VEC_iterate (tsv_s, tvariables, ix, tsv); ++ix)
     {
@@ -515,12 +515,12 @@  tvariables_info_1 (void)
 
       name = concat ("$", tsv->name, (char *) NULL);
       make_cleanup (xfree, name);
-      ui_out_field_string (uiout, "name", name);
-      ui_out_field_string (uiout, "initial", plongest (tsv->initial_value));
+      uiout->field_string ("name", name);
+      uiout->field_string ("initial", plongest (tsv->initial_value));
 
       if (tsv->value_known)
         c = plongest (tsv->value);
-      else if (ui_out_is_mi_like_p (uiout))
+      else if (uiout->is_mi_like_p ())
         /* For MI, we prefer not to use magic string constants, but rather
            omit the field completely.  The difference between unknown and
            undefined does not seem important enough to represent.  */
@@ -532,8 +532,8 @@  tvariables_info_1 (void)
 	/* It is not meaningful to ask about the value.  */
         c = "<undefined>";
       if (c)
-        ui_out_field_string (uiout, "current", c);
-      ui_out_text (uiout, "\n");
+        uiout->field_string ("current", c);
+      uiout->text ("\n");
 
       do_cleanups (back_to2);
     }
@@ -2030,23 +2030,23 @@  trace_status_mi (int on_stop)
 
   if (status == -1 && ts->filename == NULL)
     {
-      ui_out_field_string (uiout, "supported", "0");
+      uiout->field_string ("supported", "0");
       return;
     }
 
   if (ts->filename != NULL)
-    ui_out_field_string (uiout, "supported", "file");
+    uiout->field_string ("supported", "file");
   else if (!on_stop)
-    ui_out_field_string (uiout, "supported", "1");
+    uiout->field_string ("supported", "1");
 
   if (ts->filename != NULL)
-    ui_out_field_string (uiout, "trace-file", ts->filename);
+    uiout->field_string ("trace-file", ts->filename);
 
   gdb_assert (ts->running_known);
 
   if (ts->running)
     {
-      ui_out_field_string (uiout, "running", "1");
+      uiout->field_string ("running", "1");
 
       /* Unlike CLI, do not show the state of 'disconnected-tracing' variable.
 	 Given that the frontend gets the status either on -trace-stop, or from
@@ -2063,7 +2063,7 @@  trace_status_mi (int on_stop)
       int stopping_tracepoint = -1;
 
       if (!on_stop)
-	ui_out_field_string (uiout, "running", "0");
+	uiout->field_string ("running", "0");
 
       if (ts->stop_reason != trace_stop_reason_unknown)
 	{
@@ -2090,31 +2090,31 @@  trace_status_mi (int on_stop)
 	  
 	  if (stop_reason)
 	    {
-	      ui_out_field_string (uiout, "stop-reason", stop_reason);
+	      uiout->field_string ("stop-reason", stop_reason);
 	      if (stopping_tracepoint != -1)
-		ui_out_field_int (uiout, "stopping-tracepoint",
+		uiout->field_int ("stopping-tracepoint",
 				  stopping_tracepoint);
 	      if (ts->stop_reason == tracepoint_error)
-		ui_out_field_string (uiout, "error-description",
+		uiout->field_string ("error-description",
 				     ts->stop_desc);
 	    }
 	}
     }
 
   if (ts->traceframe_count != -1)
-    ui_out_field_int (uiout, "frames", ts->traceframe_count);
+    uiout->field_int ("frames", ts->traceframe_count);
   if (ts->traceframes_created != -1)
-    ui_out_field_int (uiout, "frames-created", ts->traceframes_created);
+    uiout->field_int ("frames-created", ts->traceframes_created);
   if (ts->buffer_size != -1)
-    ui_out_field_int (uiout, "buffer-size", ts->buffer_size);
+    uiout->field_int ("buffer-size", ts->buffer_size);
   if (ts->buffer_free != -1)
-    ui_out_field_int (uiout, "buffer-free", ts->buffer_free);
+    uiout->field_int ("buffer-free", ts->buffer_free);
 
-  ui_out_field_int (uiout, "disconnected",  ts->disconnected_tracing);
-  ui_out_field_int (uiout, "circular",  ts->circular_buffer);
+  uiout->field_int ("disconnected",  ts->disconnected_tracing);
+  uiout->field_int ("circular",  ts->circular_buffer);
 
-  ui_out_field_string (uiout, "user-name", ts->user_name);
-  ui_out_field_string (uiout, "notes", ts->notes);
+  uiout->field_string ("user-name", ts->user_name);
+  uiout->field_string ("notes", ts->notes);
 
   {
     char buf[100];
@@ -2122,11 +2122,11 @@  trace_status_mi (int on_stop)
     xsnprintf (buf, sizeof buf, "%ld.%06ld",
 	       (long int) (ts->start_time / 1000000),
 	       (long int) (ts->start_time % 1000000));
-    ui_out_field_string (uiout, "start-time", buf);
+    uiout->field_string ("start-time", buf);
     xsnprintf (buf, sizeof buf, "%ld.%06ld",
 	       (long int) (ts->stop_time / 1000000),
 	       (long int) (ts->stop_time % 1000000));
-    ui_out_field_string (uiout, "stop-time", buf);
+    uiout->field_string ("stop-time", buf);
   }
 }
 
@@ -2272,11 +2272,11 @@  tfind_1 (enum trace_find_type type, int num,
     {
       /* Use different branches for MI and CLI to make CLI messages
 	 i18n-eable.  */
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
 	{
-	  ui_out_field_string (uiout, "found", "1");
-	  ui_out_field_int (uiout, "tracepoint", tracepoint_number);
-	  ui_out_field_int (uiout, "traceframe", traceframe_number);
+	  uiout->field_string ("found", "1");
+	  uiout->field_int ("tracepoint", tracepoint_number);
+	  uiout->field_int ("traceframe", traceframe_number);
 	}
       else
 	{
@@ -2286,8 +2286,8 @@  tfind_1 (enum trace_find_type type, int num,
     }
   else
     {
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_string (uiout, "found", "0");
+      if (uiout->is_mi_like_p ())
+	uiout->field_string ("found", "0");
       else if (type == tfind_number && num == -1)
 	printf_unfiltered (_("No longer looking at any trace frame\n"));
       else /* This case may never occur, check.  */
@@ -3857,13 +3857,13 @@  print_one_static_tracepoint_marker (int count,
 
   /* A counter field to help readability.  This is not a stable
      identifier!  */
-  ui_out_field_int (uiout, "count", count);
+  uiout->field_int ("count", count);
 
-  ui_out_field_string (uiout, "marker-id", marker->str_id);
+  uiout->field_string ("marker-id", marker->str_id);
 
-  ui_out_field_fmt (uiout, "enabled", "%c",
+  uiout->field_fmt ("enabled", "%c",
 		    !VEC_empty (breakpoint_p, tracepoints) ? 'y' : 'n');
-  ui_out_spaces (uiout, 2);
+  uiout->spaces (2);
 
   strcpy (wrap_indent, "                                   ");
 
@@ -3874,49 +3874,49 @@  print_one_static_tracepoint_marker (int count,
 
   strcpy (extra_field_indent, "         ");
 
-  ui_out_field_core_addr (uiout, "addr", marker->gdbarch, marker->address);
+  uiout->field_core_addr ("addr", marker->gdbarch, marker->address);
 
   sal = find_pc_line (marker->address, 0);
   sym = find_pc_sect_function (marker->address, NULL);
   if (sym)
     {
-      ui_out_text (uiout, "in ");
-      ui_out_field_string (uiout, "func",
+      uiout->text ("in ");
+      uiout->field_string ("func",
 			   SYMBOL_PRINT_NAME (sym));
-      ui_out_wrap_hint (uiout, wrap_indent);
-      ui_out_text (uiout, " at ");
+      uiout->wrap_hint (wrap_indent);
+      uiout->text (" at ");
     }
   else
-    ui_out_field_skip (uiout, "func");
+    uiout->field_skip ("func");
 
   if (sal.symtab != NULL)
     {
-      ui_out_field_string (uiout, "file",
+      uiout->field_string ("file",
 			   symtab_to_filename_for_display (sal.symtab));
-      ui_out_text (uiout, ":");
+      uiout->text (":");
 
-      if (ui_out_is_mi_like_p (uiout))
+      if (uiout->is_mi_like_p ())
 	{
 	  const char *fullname = symtab_to_fullname (sal.symtab);
 
-	  ui_out_field_string (uiout, "fullname", fullname);
+	  uiout->field_string ("fullname", fullname);
 	}
       else
-	ui_out_field_skip (uiout, "fullname");
+	uiout->field_skip ("fullname");
 
-      ui_out_field_int (uiout, "line", sal.line);
+      uiout->field_int ("line", sal.line);
     }
   else
     {
-      ui_out_field_skip (uiout, "fullname");
-      ui_out_field_skip (uiout, "line");
+      uiout->field_skip ("fullname");
+      uiout->field_skip ("line");
     }
 
-  ui_out_text (uiout, "\n");
-  ui_out_text (uiout, extra_field_indent);
-  ui_out_text (uiout, _("Data: \""));
-  ui_out_field_string (uiout, "extra-data", marker->extra);
-  ui_out_text (uiout, "\"\n");
+  uiout->text ("\n");
+  uiout->text (extra_field_indent);
+  uiout->text (_("Data: \""));
+  uiout->field_string ("extra-data", marker->extra);
+  uiout->text ("\"\n");
 
   if (!VEC_empty (breakpoint_p, tracepoints))
     {
@@ -3927,23 +3927,23 @@  print_one_static_tracepoint_marker (int count,
       cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
 							   "tracepoints-at");
 
-      ui_out_text (uiout, extra_field_indent);
-      ui_out_text (uiout, _("Probed by static tracepoints: "));
+      uiout->text (extra_field_indent);
+      uiout->text (_("Probed by static tracepoints: "));
       for (ix = 0; VEC_iterate(breakpoint_p, tracepoints, ix, b); ix++)
 	{
 	  if (ix > 0)
-	    ui_out_text (uiout, ", ");
-	  ui_out_text (uiout, "#");
-	  ui_out_field_int (uiout, "tracepoint-id", b->number);
+	    uiout->text (", ");
+	  uiout->text ("#");
+	  uiout->field_int ("tracepoint-id", b->number);
 	}
 
       do_cleanups (cleanup_chain);
 
-      if (ui_out_is_mi_like_p (uiout))
-	ui_out_field_int (uiout, "number-of-tracepoints",
+      if (uiout->is_mi_like_p ())
+	uiout->field_int ("number-of-tracepoints",
 			  VEC_length(breakpoint_p, tracepoints));
       else
-	ui_out_text (uiout, "\n");
+	uiout->text ("\n");
     }
   VEC_free (breakpoint_p, tracepoints);
 
@@ -3969,18 +3969,18 @@  info_static_tracepoint_markers_command (char *arg, int from_tty)
     = make_cleanup_ui_out_table_begin_end (uiout, 5, -1,
 					   "StaticTracepointMarkersTable");
 
-  ui_out_table_header (uiout, 7, ui_left, "counter", "Cnt");
+  uiout->table_header (7, ui_left, "counter", "Cnt");
 
-  ui_out_table_header (uiout, 40, ui_left, "marker-id", "ID");
+  uiout->table_header (40, ui_left, "marker-id", "ID");
 
-  ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");
+  uiout->table_header (3, ui_left, "enabled", "Enb");
   if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
-    ui_out_table_header (uiout, 10, ui_left, "addr", "Address");
+    uiout->table_header (10, ui_left, "addr", "Address");
   else
-    ui_out_table_header (uiout, 18, ui_left, "addr", "Address");
-  ui_out_table_header (uiout, 40, ui_noalign, "what", "What");
+    uiout->table_header (18, ui_left, "addr", "Address");
+  uiout->table_header (40, ui_noalign, "what", "What");
 
-  ui_out_table_body (uiout);
+  uiout->table_body ();
 
   markers = target_static_tracepoint_markers_by_strid (NULL);
   make_cleanup (VEC_cleanup (static_tracepoint_marker_p), &markers);
diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c
index 8d35124..3e8442e 100644
--- a/gdb/tui/tui-interp.c
+++ b/gdb/tui/tui-interp.c
@@ -252,10 +252,10 @@  tui_resume (void *data)
      previously writing to gdb_stdout, then set it to the new
      gdb_stdout afterwards.  */
 
-  stream = cli_out_set_stream (tui_old_uiout, gdb_stdout);
+  stream = tui_old_uiout->set_stream (gdb_stdout);
   if (stream != gdb_stdout)
     {
-      cli_out_set_stream (tui_old_uiout, stream);
+      tui_old_uiout->set_stream (stream);
       stream = NULL;
     }
 
@@ -264,7 +264,7 @@  tui_resume (void *data)
   ui->input_handler = command_line_handler;
 
   if (stream != NULL)
-    cli_out_set_stream (tui_old_uiout, gdb_stdout);
+    tui_old_uiout->set_stream (gdb_stdout);
 
   if (tui_start_enabled)
     tui_enable ();
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index 93bed88..cde679c 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -32,6 +32,7 @@ 
 #include "tui/tui-win.h"
 #include "tui/tui-wingeneral.h"
 #include "tui/tui-file.h"
+#include "tui/tui-out.h"
 #include "ui-out.h"
 #include "cli-out.h"
 #include <fcntl.h>
@@ -114,7 +115,7 @@  struct ui_out *tui_out;
 /* GDB output files in non-curses mode.  */
 static struct ui_file *tui_old_stdout;
 static struct ui_file *tui_old_stderr;
-struct ui_out *tui_old_uiout;
+cli_ui_out *tui_old_uiout;
 
 /* Readline previous hooks.  */
 static rl_getc_func_t *tui_old_rl_getc_function;
@@ -459,7 +460,8 @@  tui_setup_io (int mode)
       /* Keep track of previous gdb output.  */
       tui_old_stdout = gdb_stdout;
       tui_old_stderr = gdb_stderr;
-      tui_old_uiout = current_uiout;
+      tui_old_uiout = dynamic_cast<cli_ui_out *> (current_uiout);
+      gdb_assert (tui_old_uiout != nullptr);
 
       /* Reconfigure gdb output.  */
       gdb_stdout = tui_stdout;
diff --git a/gdb/tui/tui-io.h b/gdb/tui/tui-io.h
index 67c0273..a080529 100644
--- a/gdb/tui/tui-io.h
+++ b/gdb/tui/tui-io.h
@@ -23,6 +23,7 @@ 
 #define TUI_IO_H
 
 struct ui_out;
+class cli_ui_out;
 
 /* Print the string in the curses command window.  */
 extern void tui_puts (const char *);
@@ -45,7 +46,7 @@  extern void tui_redisplay_readline (void);
 extern char *tui_expand_tabs (const char *, int);
 
 extern struct ui_out *tui_out;
-extern struct ui_out *tui_old_uiout;
+extern cli_ui_out *tui_old_uiout;
 
 extern int key_is_start_sequence (int ch);
 extern int key_is_end_sequence (int ch);
diff --git a/gdb/tui/tui-out.c b/gdb/tui/tui-out.c
index a5f0541..7681036 100644
--- a/gdb/tui/tui-out.c
+++ b/gdb/tui/tui-out.c
@@ -22,156 +22,101 @@ 
 
 #include "defs.h"
 #include "ui-out.h"
-#include "cli-out.h"
+#include "tui-out.h"
 #include "tui.h"
-struct tui_ui_out_data
-  {
-    struct cli_ui_out_data base;
-
-    int line;
-    int start_of_line;
-  };
-typedef struct tui_ui_out_data tui_out_data;
-
-/* This is the TUI ui-out implementation functions vector.  It is
-   initialized below in _initialize_tui_out, inheriting the CLI
-   version, and overriding a few methods.  */
-
-static struct ui_out_impl tui_ui_out_impl;
 
 /* Output an int field.  */
 
-static void
-tui_field_int (struct ui_out *uiout, 
-	       int fldno, int width,
-	       enum ui_align alignment,
-	       const char *fldname, 
-	       int value)
+void
+tui_ui_out::do_field_int (int fldno, int width, ui_align alignment,
+			    const char *fldname, int value)
 {
-  tui_out_data *data = (tui_out_data *) ui_out_data (uiout);
-
-  if (data->base.suppress_output)
+  if (suppress_output ())
     return;
 
   /* Don't print line number, keep it for later.  */
-  if (data->start_of_line == 0 && strcmp (fldname, "line") == 0)
+  if (m_start_of_line == 0 && strcmp (fldname, "line") == 0)
     {
-      data->start_of_line ++;
-      data->line = value;
+      m_start_of_line++;
+      m_line = value;
       return;
     }
-  data->start_of_line ++;
+  m_start_of_line++;
 
-  (*cli_ui_out_impl.field_int) (uiout, fldno,
-				width, alignment, fldname, value);
+  cli_ui_out::do_field_int (fldno, width, alignment, fldname, value);
 }
 
 /* Other cli_field_* end up here so alignment and field separators are
    both handled by tui_field_string.  */
 
-static void
-tui_field_string (struct ui_out *uiout,
-		  int fldno, int width,
-		  enum ui_align align,
-		  const char *fldname,
-		  const char *string)
+void
+tui_ui_out::do_field_string (int fldno, int width, ui_align align,
+			       const char *fldname, const char *string)
 {
-  tui_out_data *data = (tui_out_data *) ui_out_data (uiout);
-
-  if (data->base.suppress_output)
+  if (suppress_output ())
     return;
 
-  if (fldname && data->line > 0 && strcmp (fldname, "fullname") == 0)
+  if (fldname && m_line > 0 && strcmp (fldname, "fullname") == 0)
     {
-      data->start_of_line ++;
-      if (data->line > 0)
+      m_start_of_line++;
+      if (m_line > 0)
         {
-          tui_show_source (string, data->line);
+          tui_show_source (string, m_line);
         }
       return;
     }
   
-  data->start_of_line++;
+  m_start_of_line++;
 
-  (*cli_ui_out_impl.field_string) (uiout, fldno,
-				   width, align,
-				   fldname, string);
+  cli_ui_out::do_field_string (fldno, width, align, fldname, string);
 }
 
 /* This is the only field function that does not align.  */
 
-static void
-tui_field_fmt (struct ui_out *uiout, int fldno,
-	       int width, enum ui_align align,
-	       const char *fldname,
-	       const char *format,
-	       va_list args)
+void
+tui_ui_out::do_field_fmt (int fldno, int width, ui_align align,
+			    const char *fldname, const char *format,
+			    va_list args)
 {
-  tui_out_data *data = (tui_out_data *) ui_out_data (uiout);
-
-  if (data->base.suppress_output)
+  if (suppress_output ())
     return;
 
-  data->start_of_line++;
+  m_start_of_line++;
 
-  (*cli_ui_out_impl.field_fmt) (uiout, fldno,
-				width, align,
-				fldname, format, args);
+  cli_ui_out::do_field_fmt (fldno, width, align, fldname, format, args);
 }
 
-static void
-tui_text (struct ui_out *uiout, const char *string)
+void
+tui_ui_out::do_text (const char *string)
 {
-  tui_out_data *data = (tui_out_data *) ui_out_data (uiout);
-
-  if (data->base.suppress_output)
+  if (suppress_output ())
     return;
-  data->start_of_line ++;
-  if (data->line > 0)
+
+  m_start_of_line++;
+  if (m_line > 0)
     {
       if (strchr (string, '\n') != 0)
         {
-          data->line = -1;
-          data->start_of_line = 0;
+          m_line = -1;
+          m_start_of_line = 0;
         }
       return;
     }
   if (strchr (string, '\n'))
-    data->start_of_line = 0;
+    m_start_of_line = 0;
 
-  (*cli_ui_out_impl.text) (uiout, string);
+  cli_ui_out::do_text (string);
 }
 
-struct ui_out *
-tui_out_new (struct ui_file *stream)
+tui_ui_out::tui_ui_out (ui_file *stream)
+: cli_ui_out (stream, 0),
+  m_line (0),
+  m_start_of_line (-1)
 {
-  ui_out_flags flags = 0;
-
-  tui_out_data *data = new tui_out_data ();
-
-  /* Initialize base "class".  */
-  cli_out_data_ctor (&data->base, stream);
-
-  /* Initialize our fields.  */
-  data->line = -1;
-  data->start_of_line = 0;
-
-  return ui_out_new (&tui_ui_out_impl, data, flags);
 }
 
-/* Standard gdb initialization hook.  */
-
-extern void _initialize_tui_out (void);
-
-void
-_initialize_tui_out (void)
+tui_ui_out *
+tui_out_new (struct ui_file *stream)
 {
-  /* Inherit the CLI version.  */
-  tui_ui_out_impl = cli_ui_out_impl;
-
-  /* Override a few methods.  */
-  tui_ui_out_impl.field_int = tui_field_int;
-  tui_ui_out_impl.field_string = tui_field_string;
-  tui_ui_out_impl.field_fmt = tui_field_fmt;
-  tui_ui_out_impl.text = tui_text;
+  return new tui_ui_out (stream);
 }
diff --git a/gdb/tui/tui-out.h b/gdb/tui/tui-out.h
new file mode 100644
index 0000000..da7821a
--- /dev/null
+++ b/gdb/tui/tui-out.h
@@ -0,0 +1,48 @@ 
+/* Copyright (C) 2016 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 TUI_OUT_H
+#define TUI_OUT_H
+
+#include "cli-out.h"
+
+class tui_ui_out : public cli_ui_out
+{
+public:
+
+  explicit tui_ui_out (ui_file *stream);
+
+protected:
+
+  void do_field_int (int fldno, int width, ui_align align, const char *fldname,
+		  int value) override;
+  void do_field_string (int fldno, int width, ui_align align, const char *fldname,
+		     const char *string) override;
+  void do_field_fmt (int fldno, int width, ui_align align, const char *fldname,
+		  const char *format, va_list args) override
+    ATTRIBUTE_PRINTF (6,0);
+  void do_text (const char *string) override;
+
+private:
+
+  int m_line;
+  int m_start_of_line;
+};
+
+extern tui_ui_out *tui_out_new (struct ui_file *stream);
+
+#endif
diff --git a/gdb/tui/tui.h b/gdb/tui/tui.h
index 5d56df0..aaae851 100644
--- a/gdb/tui/tui.h
+++ b/gdb/tui/tui.h
@@ -93,8 +93,6 @@  extern int tui_active;
 
 extern void tui_show_source (const char *fullname, int line);
 
-extern struct ui_out *tui_out_new (struct ui_file *stream);
-
 /* tui-layout.c */
 extern enum tui_status tui_set_layout_by_name (const char *);
 
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 774be2c..550f7b2 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -28,6 +28,7 @@ 
 #include <vector>
 #include <memory>
 #include <string>
+#include <memory>
 
 /* A header of a ui_out_table.  */
 
@@ -306,172 +307,113 @@  int ui_out_table::entry_level () const
   return m_entry_level;
 }
 
-/* The ui_out structure */
-
-struct ui_out
-  {
-    int flags;
-    /* Specific implementation of ui-out.  */
-    const struct ui_out_impl *impl;
-    void *data;
-
-    /* Vector to store and track the ui-out levels.  */
-    std::vector<std::unique_ptr<ui_out_level>> levels;
-
-    int level () const
-    {
-      return this->levels.size ();
-    }
-
-    /* A table, if any.  At present only a single table is supported.  */
-    std::unique_ptr<ui_out_table> table;
-  };
+int
+ui_out::level () const
+{
+  return m_levels.size ();
+}
 
 /* The current (inner most) level.  */
-static ui_out_level *
-current_level (struct ui_out *uiout)
+
+ui_out_level *
+ui_out::current_level () const
 {
-  return uiout->levels.back ().get ();
+  return m_levels.back ().get ();
 }
 
 /* Create a new level, of TYPE.  */
-static void
-push_level (struct ui_out *uiout,
-	    enum ui_out_type type)
+void
+ui_out::push_level (ui_out_type type)
 {
   std::unique_ptr<ui_out_level> level (new ui_out_level (type));
 
-  uiout->levels.push_back (std::move (level));
+  m_levels.push_back (std::move (level));
 }
 
 /* Discard the current level.  TYPE is the type of the level being
    discarded.  */
-static void
-pop_level (struct ui_out *uiout,
-	   enum ui_out_type type)
+void
+ui_out::pop_level (ui_out_type type)
 {
   /* We had better not underflow the buffer.  */
-  gdb_assert (uiout->level () > 0);
-  gdb_assert (current_level (uiout)->type () == type);
-
-  uiout->levels.pop_back ();
-}
-
-/* These are the interfaces to implementation functions.  */
-
-static void uo_table_begin (struct ui_out *uiout, int nbrofcols,
-			    int nr_rows, const char *tblid);
-static void uo_table_body (struct ui_out *uiout);
-static void uo_table_end (struct ui_out *uiout);
-static void uo_table_header (struct ui_out *uiout, int width,
-			     enum ui_align align,
-			     const std::string &col_name,
-			     const std::string &col_hdr);
-static void uo_begin (struct ui_out *uiout,
-		      enum ui_out_type type,
-		      const char *id);
-static void uo_end (struct ui_out *uiout,
-		    enum ui_out_type type);
-static void uo_field_int (struct ui_out *uiout, int fldno, int width,
-			  enum ui_align align, const char *fldname, int value);
-static void uo_field_skip (struct ui_out *uiout, int fldno, int width,
-			   enum ui_align align, const char *fldname);
-static void uo_field_fmt (struct ui_out *uiout, int fldno, int width,
-			  enum ui_align align, const char *fldname,
-			  const char *format, va_list args)
-     ATTRIBUTE_PRINTF (6, 0);
-static void uo_spaces (struct ui_out *uiout, int numspaces);
-static void uo_text (struct ui_out *uiout, const char *string);
-static void uo_message (struct ui_out *uiout,
-			const char *format, va_list args)
-     ATTRIBUTE_PRINTF (2, 0);
-static void uo_wrap_hint (struct ui_out *uiout, const char *identstring);
-static void uo_flush (struct ui_out *uiout);
-static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream);
-
-/* Prototypes for local functions */
-
-static void verify_field (struct ui_out *uiout, int *fldno, int *width,
-			  enum ui_align *align);
-
-/* exported functions (ui_out API) */
+  gdb_assert (m_levels.size () > 0);
+  gdb_assert (current_level ()->type () == type);
+
+  m_levels.pop_back ();
+}
 
 /* Mark beginning of a table.  */
 
-static void
-ui_out_table_begin (struct ui_out *uiout, int nr_cols,
-		    int nr_rows, const std::string &tblid)
+void
+ui_out::table_begin (int nr_cols, int nr_rows, const std::string &tblid)
 {
-  if (uiout->table != nullptr)
+  if (m_table_up != nullptr)
     internal_error (__FILE__, __LINE__,
 		    _("tables cannot be nested; table_begin found before \
 previous table_end."));
 
-  uiout->table.reset (
-    new ui_out_table (uiout->level () + 1, nr_cols, tblid));
+  m_table_up.reset (new ui_out_table (level () + 1, nr_cols, tblid));
 
-  uo_table_begin (uiout, nr_cols, nr_rows, tblid.c_str ());
+  do_table_begin (nr_cols, nr_rows, tblid.c_str ());
 }
 
 void
-ui_out_table_body (struct ui_out *uiout)
+ui_out::table_header (int width, ui_align alignment,
+		      const std::string &col_name, const std::string &col_hdr)
 {
-  if (uiout->table == nullptr)
+  if (m_table_up == nullptr)
     internal_error (__FILE__, __LINE__,
-		    _("table_body outside a table is not valid; it must be \
-after a table_begin and before a table_end."));
+		    _("table_header outside a table is not valid; it must be \
+after a table_begin and before a table_body."));
 
-  uiout->table->start_body ();
+  m_table_up->append_header (width, alignment, col_name, col_hdr);
 
-  uo_table_body (uiout);
+  do_table_header (width, alignment, col_name, col_hdr);
 }
 
-static void
-ui_out_table_end (struct ui_out *uiout)
+void
+ui_out::table_body ()
 {
-  if (uiout->table == nullptr)
+  if (m_table_up == nullptr)
     internal_error (__FILE__, __LINE__,
-		    _("misplaced table_end or missing table_begin."));
+		    _("table_body outside a table is not valid; it must be "
+		      "after a table_begin and before a table_end."));
 
-  uo_table_end (uiout);
+  m_table_up->start_body ();
 
-  uiout->table = nullptr;
+  do_table_body ();
 }
 
 void
-ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
-		     const std::string &col_name, const std::string &col_hdr)
+ui_out::table_end ()
 {
-  if (uiout->table == nullptr)
+  if (m_table_up == nullptr)
     internal_error (__FILE__, __LINE__,
-		    _("table_header outside a table is not valid; it must be "
-		      "after a table_begin and before a table_body."));
+		    _("misplaced table_end or missing table_begin."));
 
-  uiout->table->append_header (width, alignment, col_name, col_hdr);
+  do_table_end ();
 
-  uo_table_header (uiout, width, alignment, col_name, col_hdr);
+  m_table_up = nullptr;
 }
 
 static void
 do_cleanup_table_end (void *data)
 {
-  struct ui_out *ui_out = (struct ui_out *) data;
+  ui_out *uiout = (ui_out *) data;
 
-  ui_out_table_end (ui_out);
+  uiout->table_end ();
 }
 
 struct cleanup *
-make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, int nr_cols,
-                                     int nr_rows, const char *tblid)
+make_cleanup_ui_out_table_begin_end (ui_out *uiout, int nr_cols, int nr_rows,
+				     const char *tblid)
 {
-  ui_out_table_begin (ui_out, nr_cols, nr_rows, tblid);
-  return make_cleanup (do_cleanup_table_end, ui_out);
+  uiout->table_begin (nr_cols, nr_rows, tblid);
+  return make_cleanup (do_cleanup_table_end, uiout);
 }
 
 void
-ui_out_begin (struct ui_out *uiout,
-	      enum ui_out_type type,
-	      const char *id)
+ui_out::begin (ui_out_type type, const char *id)
 {
   /* Be careful to verify the ``field'' before the new tuple/list is
      pushed onto the stack.  That way the containing list/table/row is
@@ -483,30 +425,29 @@  ui_out_begin (struct ui_out *uiout,
   {
     int fldno;
     int width;
-    enum ui_align align;
+    ui_align align;
 
-    verify_field (uiout, &fldno, &width, &align);
+    verify_field (&fldno, &width, &align);
   }
 
-  push_level (uiout, type);
+  push_level (type);
 
   /* If the push puts us at the same level as a table row entry, we've
      got a new table row.  Put the header pointer back to the start.  */
-  if (uiout->table != nullptr
-      && uiout->table->current_state () == ui_out_table::state::BODY
-      && uiout->table->entry_level () == uiout->level ())
-    uiout->table->start_row ();
+  if (m_table_up != nullptr
+      && m_table_up->current_state () == ui_out_table::state::BODY
+      && m_table_up->entry_level () == level ())
+    m_table_up->start_row ();
 
-  uo_begin (uiout, type, id);
+  do_begin (type, id);
 }
 
 void
-ui_out_end (struct ui_out *uiout,
-	    enum ui_out_type type)
+ui_out::end (ui_out_type type)
 {
-  pop_level (uiout, type);
+  pop_level (type);
 
-  uo_end (uiout, type);
+  do_end (type);
 }
 
 struct ui_out_end_cleanup_data
@@ -521,7 +462,7 @@  do_cleanup_end (void *data)
   struct ui_out_end_cleanup_data *end_cleanup_data
     = (struct ui_out_end_cleanup_data *) data;
 
-  ui_out_end (end_cleanup_data->uiout, end_cleanup_data->type);
+  end_cleanup_data->uiout->end (end_cleanup_data->type);
   xfree (end_cleanup_data);
 }
 
@@ -541,7 +482,7 @@  struct cleanup *
 make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout,
 				     const char *id)
 {
-  ui_out_begin (uiout, ui_out_type_tuple, id);
+  uiout->begin (ui_out_type_tuple, id);
   return make_cleanup_ui_out_end (uiout, ui_out_type_tuple);
 }
 
@@ -549,331 +490,166 @@  struct cleanup *
 make_cleanup_ui_out_list_begin_end (struct ui_out *uiout,
 				    const char *id)
 {
-  ui_out_begin (uiout, ui_out_type_list, id);
+  uiout->begin (ui_out_type_list, id);
   return make_cleanup_ui_out_end (uiout, ui_out_type_list);
 }
 
 void
-ui_out_field_int (struct ui_out *uiout,
-		  const char *fldname,
-		  int value)
+ui_out::field_int (const char *fldname, int value)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_int (uiout, fldno, width, align, fldname, value);
+  do_field_int (fldno, width, align, fldname, value);
 }
 
 void
-ui_out_field_fmt_int (struct ui_out *uiout,
-                      int input_width,
-                      enum ui_align input_align,
-		      const char *fldname,
-		      int value)
+ui_out::field_fmt_int (int input_width, ui_align input_align,
+		       const char *fldname, int value)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_int (uiout, fldno, input_width, input_align, fldname, value);
+  do_field_int (fldno, input_width, input_align, fldname, value);
 }
 
 /* Documented in ui-out.h.  */
 
 void
-ui_out_field_core_addr (struct ui_out *uiout,
-			const char *fldname,
-			struct gdbarch *gdbarch,
-			CORE_ADDR address)
+ui_out::field_core_addr (const char *fldname, struct gdbarch *gdbarch,
+			 CORE_ADDR address)
 {
-  ui_out_field_string (uiout, fldname,
-		       print_core_address (gdbarch, address));
+  field_string (fldname, print_core_address (gdbarch, address));
 }
 
 void
-ui_out_field_stream (struct ui_out *uiout,
-		     const char *fldname,
-		     struct ui_file *stream)
+ui_out::field_stream (const char *fldname, ui_file *stream)
 {
   std::string buffer = ui_file_as_string (stream);
 
   if (!buffer.empty ())
-    ui_out_field_string (uiout, fldname, buffer.c_str ());
+    field_string (fldname, buffer.c_str ());
   else
-    ui_out_field_skip (uiout, fldname);
+    field_skip (fldname);
   ui_file_rewind (stream);
 }
 
 /* Used to omit a field.  */
 
 void
-ui_out_field_skip (struct ui_out *uiout,
-		   const char *fldname)
+ui_out::field_skip (const char *fldname)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_skip (uiout, fldno, width, align, fldname);
+  do_field_skip (fldno, width, align, fldname);
 }
 
 void
-ui_out_field_string (struct ui_out *uiout,
-		     const char *fldname,
-		     const char *string)
+ui_out::field_string (const char *fldname, const char *string)
 {
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
-  uo_field_string (uiout, fldno, width, align, fldname, string);
+  do_field_string (fldno, width, align, fldname, string);
 }
 
 /* VARARGS */
 void
-ui_out_field_fmt (struct ui_out *uiout,
-		  const char *fldname,
-		  const char *format, ...)
+ui_out::field_fmt (const char *fldname, const char *format, ...)
 {
   va_list args;
   int fldno;
   int width;
-  enum ui_align align;
+  ui_align align;
 
   /* Will not align, but has to call anyway.  */
-  verify_field (uiout, &fldno, &width, &align);
+  verify_field (&fldno, &width, &align);
 
   va_start (args, format);
 
-  uo_field_fmt (uiout, fldno, width, align, fldname, format, args);
+  do_field_fmt (fldno, width, align, fldname, format, args);
 
   va_end (args);
 }
 
 void
-ui_out_spaces (struct ui_out *uiout, int numspaces)
+ui_out::spaces (int numspaces)
 {
-  uo_spaces (uiout, numspaces);
+  do_spaces (numspaces);
 }
 
 void
-ui_out_text (struct ui_out *uiout,
-	     const char *string)
+ui_out::text (const char *string)
 {
-  uo_text (uiout, string);
+  do_text (string);
 }
 
 void
-ui_out_message (struct ui_out *uiout, const char *format, ...)
+ui_out::message (const char *format, ...)
 {
   va_list args;
 
   va_start (args, format);
-  uo_message (uiout, format, args);
+  do_message (format, args);
   va_end (args);
 }
 
 void
-ui_out_wrap_hint (struct ui_out *uiout, const char *identstring)
+ui_out::wrap_hint (const char *identstring)
 {
-  uo_wrap_hint (uiout, identstring);
+  do_wrap_hint (identstring);
 }
 
 void
-ui_out_flush (struct ui_out *uiout)
+ui_out::flush ()
 {
-  uo_flush (uiout);
+  do_flush ();
 }
 
 int
-ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream)
+ui_out::redirect (ui_file *outstream)
 {
-  return uo_redirect (uiout, outstream);
+  return do_redirect (outstream);
 }
 
 /* Test the flags against the mask given.  */
-int
-ui_out_test_flags (struct ui_out *uiout, ui_out_flags mask)
+ui_out_flags
+ui_out::test_flags (ui_out_flags mask)
 {
-  return (uiout->flags & mask);
+  return m_flags & mask;
 }
 
 int
-ui_out_is_mi_like_p (struct ui_out *uiout)
+ui_out::is_mi_like_p ()
 {
-  return uiout->impl->is_mi_like_p;
-}
-
-/* Interface to the implementation functions.  */
-
-void
-uo_table_begin (struct ui_out *uiout, int nbrofcols,
-		int nr_rows,
-		const char *tblid)
-{
-  if (!uiout->impl->table_begin)
-    return;
-  uiout->impl->table_begin (uiout, nbrofcols, nr_rows, tblid);
-}
-
-void
-uo_table_body (struct ui_out *uiout)
-{
-  if (!uiout->impl->table_body)
-    return;
-  uiout->impl->table_body (uiout);
-}
-
-void
-uo_table_end (struct ui_out *uiout)
-{
-  if (!uiout->impl->table_end)
-    return;
-  uiout->impl->table_end (uiout);
-}
-
-void
-uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
-		 const std::string &col_name, const std::string &col_hdr)
-{
-  if (!uiout->impl->table_header)
-    return;
-  uiout->impl->table_header (uiout, width, align, col_name, col_hdr);
-}
-
-void
-uo_begin (struct ui_out *uiout,
-	  enum ui_out_type type,
-	  const char *id)
-{
-  if (uiout->impl->begin == NULL)
-    return;
-  uiout->impl->begin (uiout, type, id);
-}
-
-void
-uo_end (struct ui_out *uiout,
-	enum ui_out_type type)
-{
-  if (uiout->impl->end == NULL)
-    return;
-  uiout->impl->end (uiout, type);
-}
-
-void
-uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-	      const char *fldname,
-	      int value)
-{
-  if (!uiout->impl->field_int)
-    return;
-  uiout->impl->field_int (uiout, fldno, width, align, fldname, value);
-}
-
-void
-uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-	       const char *fldname)
-{
-  if (!uiout->impl->field_skip)
-    return;
-  uiout->impl->field_skip (uiout, fldno, width, align, fldname);
-}
-
-void
-uo_field_string (struct ui_out *uiout, int fldno, int width,
-		 enum ui_align align,
-		 const char *fldname,
-		 const char *string)
-{
-  if (!uiout->impl->field_string)
-    return;
-  uiout->impl->field_string (uiout, fldno, width, align, fldname, string);
-}
-
-void
-uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-	      const char *fldname,
-	      const char *format,
-	      va_list args)
-{
-  if (!uiout->impl->field_fmt)
-    return;
-  uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args);
-}
-
-void
-uo_spaces (struct ui_out *uiout, int numspaces)
-{
-  if (!uiout->impl->spaces)
-    return;
-  uiout->impl->spaces (uiout, numspaces);
-}
-
-void
-uo_text (struct ui_out *uiout,
-	 const char *string)
-{
-  if (!uiout->impl->text)
-    return;
-  uiout->impl->text (uiout, string);
-}
-
-void
-uo_message (struct ui_out *uiout,
-	    const char *format,
-	    va_list args)
-{
-  if (!uiout->impl->message)
-    return;
-  uiout->impl->message (uiout, format, args);
-}
-
-void
-uo_wrap_hint (struct ui_out *uiout, const char *identstring)
-{
-  if (!uiout->impl->wrap_hint)
-    return;
-  uiout->impl->wrap_hint (uiout, identstring);
-}
-
-void
-uo_flush (struct ui_out *uiout)
-{
-  if (!uiout->impl->flush)
-    return;
-  uiout->impl->flush (uiout);
-}
-
-int
-uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
-{
-  if (!uiout->impl->redirect)
-    return -1;
-  return uiout->impl->redirect (uiout, outstream);
+  return do_is_mi_like_p ();
 }
 
 /* Verify that the field/tuple/list is correctly positioned.  Return
    the field number and corresponding alignment (if
    available/applicable).  */
 
-static void
-verify_field (struct ui_out *uiout, int *fldno, int *width,
-	      enum ui_align *align)
+void
+ui_out::verify_field (int *fldno, int *width, ui_align *align)
 {
-  ui_out_level *current = current_level (uiout);
+  ui_out_level *current = current_level ();
   const char *text;
 
-  if (uiout->table != nullptr
-      && uiout->table->current_state () != ui_out_table::state::BODY)
+  if (m_table_up != nullptr
+      && m_table_up->current_state () != ui_out_table::state::BODY)
     {
       internal_error (__FILE__, __LINE__,
 		      _("table_body missing; table fields must be \
@@ -882,10 +658,10 @@  specified after table_body and inside a list."));
 
   current->inc_field_count ();
 
-  if (uiout->table != nullptr
-      && uiout->table->current_state () == ui_out_table::state::BODY
-      && uiout->table->entry_level () == uiout->level ()
-      && uiout->table->get_next_header (fldno, width, align, &text))
+  if (m_table_up != nullptr
+      && m_table_up->current_state () == ui_out_table::state::BODY
+      && m_table_up->entry_level () == level ()
+      && m_table_up->get_next_header (fldno, width, align, &text))
     {
       if (*fldno != current->field_count ())
 	internal_error (__FILE__, __LINE__,
@@ -899,40 +675,27 @@  specified after table_body and inside a list."));
     }
 }
 
-
-/* Access to ui-out members data.  */
-
-void *
-ui_out_data (struct ui_out *uiout)
-{
-  return uiout->data;
-}
-
 /* Access table field parameters.  */
-int
-ui_out_query_field (struct ui_out *uiout, int colno,
-		    int *width, int *alignment, const char **col_name)
+
+bool
+ui_out::query_table_field (int colno, int *width, int *alignment,
+			   const char **col_name)
 {
-  if (uiout->table == nullptr)
-    return 0;
+  if (m_table_up == nullptr)
+    return false;
 
-  return uiout->table->query_field (colno, width, alignment, col_name);
+  return m_table_up->query_field (colno, width, alignment, col_name);
 }
 
-/* Initialize private members at startup.  */
+/* The constructor.  */
 
-struct ui_out *
-ui_out_new (const struct ui_out_impl *impl, void *data,
-	    ui_out_flags flags)
+ui_out::ui_out (ui_out_flags flags)
+: m_flags (flags)
 {
-  struct ui_out *uiout = new ui_out ();
-
-  uiout->data = data;
-  uiout->impl = impl;
-  uiout->flags = flags;
-
   /* Create the ui-out level #1, the default level.  */
-  push_level (uiout, ui_out_type_tuple);
+  push_level (ui_out_type_tuple);
+}
 
-  return uiout;
+ui_out::~ui_out ()
+{
 }
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index cdf5671..d3a93cf 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -23,11 +23,12 @@ 
 #ifndef UI_OUT_H
 #define UI_OUT_H 1
 
-#include "common/enum-flags.h"
+#include <vector>
 
-/* The ui_out structure */
+#include "common/enum-flags.h"
 
-struct ui_out;
+class ui_out_level;
+class ui_out_table;
 struct ui_file;
 
 /* the current ui_out */
@@ -65,23 +66,6 @@  enum ui_out_type
     ui_out_type_list
   };
 
-extern void ui_out_begin (struct ui_out *uiout,
-			  enum ui_out_type level_type,
-			  const char *id);
-
-extern void ui_out_end (struct ui_out *uiout, enum ui_out_type type);
-
-/* A table can be considered a special tuple/list combination with the
-   implied structure: ``table = { hdr = { header, ... } , body = [ {
-   field, ... }, ... ] }''.  If NR_ROWS is negative then there is at
-   least one row.  */
-extern void ui_out_table_header (struct ui_out *uiout, int width,
-				 enum ui_align align,
-				 const std::string &col_name,
-				 const std::string &col_hdr);
-
-extern void ui_out_table_body (struct ui_out *uiout);
-
 extern struct cleanup *make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out,
                                                             int nr_cols,
 							    int nr_rows,
@@ -94,141 +78,113 @@  extern struct cleanup *make_cleanup_ui_out_list_begin_end (struct ui_out *uiout,
 extern struct cleanup *make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout,
 							    const char *id);
 
-extern void ui_out_field_int (struct ui_out *uiout, const char *fldname,
-			      int value);
-
-extern void ui_out_field_fmt_int (struct ui_out *uiout, int width,
-				  enum ui_align align, const char *fldname, 
-		 		  int value);
-
-/* Output a field containing an address.  */
-
-extern void ui_out_field_core_addr (struct ui_out *uiout, const char *fldname,
-				    struct gdbarch *gdbarch, CORE_ADDR address);
-
-extern void ui_out_field_string (struct ui_out * uiout, const char *fldname,
-				 const char *string);
-
-extern void ui_out_field_stream (struct ui_out *uiout, const char *fldname,
-				 struct ui_file *stream);
-
-extern void ui_out_field_fmt (struct ui_out *uiout, const char *fldname,
-			      const char *format, ...)
-     ATTRIBUTE_PRINTF (3, 4);
-
-extern void ui_out_field_skip (struct ui_out *uiout, const char *fldname);
-
-extern void ui_out_spaces (struct ui_out *uiout, int numspaces);
-
-extern void ui_out_text (struct ui_out *uiout, const char *string);
-
-extern void ui_out_message (struct ui_out *uiout, const char *format, ...)
-     ATTRIBUTE_PRINTF (2, 3);
-
-extern void ui_out_wrap_hint (struct ui_out *uiout, const char *identstring);
-
-extern void ui_out_flush (struct ui_out *uiout);
-
-extern int ui_out_test_flags (struct ui_out *uiout, ui_out_flags mask);
-
-extern int ui_out_query_field (struct ui_out *uiout, int colno,
-			       int *width, int *alignment,
-			       const char **col_name);
-
-/* HACK: Code in GDB is currently checking to see the type of ui_out
-   builder when determining which output to produce.  This function is
-   a hack to encapsulate that test.  Once GDB manages to separate the
-   CLI/MI from the core of GDB the problem should just go away ....  */
-
-extern int ui_out_is_mi_like_p (struct ui_out *uiout);
-
-/* From here on we have things that are only needed by implementation
-   routines and main.c.   We should pehaps have a separate file for that,
-   like a  ui-out-impl.h  file.  */
-
-/* User Interface Output Implementation Function Table */
-
-/* Type definition of all implementation functions.  */
-
-typedef void (table_begin_ftype) (struct ui_out * uiout,
-				  int nbrofcols, int nr_rows,
-				  const char *tblid);
-typedef void (table_body_ftype) (struct ui_out * uiout);
-typedef void (table_end_ftype) (struct ui_out * uiout);
-typedef void (table_header_ftype) (struct ui_out * uiout, int width,
-				   enum ui_align align,
-				   const std::string &col_name,
-				   const std::string &col_hdr);
-
-typedef void (ui_out_begin_ftype) (struct ui_out *uiout,
-				   enum ui_out_type type,
-				   const char *id);
-typedef void (ui_out_end_ftype) (struct ui_out *uiout,
-				 enum ui_out_type type);
-typedef void (field_int_ftype) (struct ui_out * uiout, int fldno, int width,
-				enum ui_align align,
-				const char *fldname, int value);
-typedef void (field_skip_ftype) (struct ui_out * uiout, int fldno, int width,
-				 enum ui_align align,
-				 const char *fldname);
-typedef void (field_string_ftype) (struct ui_out * uiout, int fldno, int width,
-				   enum ui_align align,
-				   const char *fldname,
-				   const char *string);
-typedef void (field_fmt_ftype) (struct ui_out * uiout, int fldno, int width,
-				enum ui_align align,
-				const char *fldname,
-				const char *format,
-				va_list args) ATTRIBUTE_FPTR_PRINTF(6,0);
-typedef void (spaces_ftype) (struct ui_out * uiout, int numspaces);
-typedef void (text_ftype) (struct ui_out * uiout,
-			   const char *string);
-typedef void (message_ftype) (struct ui_out * uiout,
-			      const char *format, va_list args)
-     ATTRIBUTE_FPTR_PRINTF(2,0);
-typedef void (wrap_hint_ftype) (struct ui_out * uiout, const char *identstring);
-typedef void (flush_ftype) (struct ui_out * uiout);
-typedef int (redirect_ftype) (struct ui_out * uiout,
-			      struct ui_file * outstream);
-typedef void (data_destroy_ftype) (struct ui_out *uiout);
-
-/* ui-out-impl */
-
-struct ui_out_impl
-  {
-    table_begin_ftype *table_begin;
-    table_body_ftype *table_body;
-    table_end_ftype *table_end;
-    table_header_ftype *table_header;
-    ui_out_begin_ftype *begin;
-    ui_out_end_ftype *end;
-    field_int_ftype *field_int;
-    field_skip_ftype *field_skip;
-    field_string_ftype *field_string;
-    field_fmt_ftype *field_fmt;
-    spaces_ftype *spaces;
-    text_ftype *text;
-    message_ftype *message;
-    wrap_hint_ftype *wrap_hint;
-    flush_ftype *flush;
-    redirect_ftype *redirect;
-    data_destroy_ftype *data_destroy;
-    int is_mi_like_p;
-  };
-
-extern void *ui_out_data (struct ui_out *uiout);
-
-extern void uo_field_string (struct ui_out *uiout, int fldno, int width,
-			     enum ui_align align, const char *fldname,
-			     const char *string);
-
-/* Create a ui_out object */
-
-extern struct ui_out *ui_out_new (const struct ui_out_impl *impl, void *data,
-				  ui_out_flags flags);
-
-/* Redirect the ouptut of a ui_out object temporarily.  */
-
-extern int ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream);
+class ui_out
+{
+ public:
+
+  explicit ui_out (ui_out_flags flags = 0);
+  virtual ~ui_out ();
+
+  void push_level (ui_out_type type);
+  void pop_level (ui_out_type type);
+
+  /* A table can be considered a special tuple/list combination with the
+     implied structure: ``table = { hdr = { header, ... } , body = [ {
+     field, ... }, ... ] }''.  If NR_ROWS is negative then there is at
+     least one row.  */
+
+  void table_begin (int nr_cols, int nr_rows, const std::string &tblid);
+  void table_header (int width, ui_align align, const std::string &col_name,
+		     const std::string &col_hdr);
+  void table_body ();
+  void table_end ();
+
+  void begin (ui_out_type type, const char *id);
+  void end (ui_out_type type);
+
+  void field_int (const char *fldname, int value);
+  void field_fmt_int (int width, ui_align align, const char *fldname,
+		      int value);
+  void field_core_addr (const char *fldname, struct gdbarch *gdbarch,
+			CORE_ADDR address);
+  void field_string (const char *fldname, const char *string);
+  void field_stream (const char *fldname, ui_file *stream);
+  void field_skip (const char *fldname);
+  void field_fmt (const char *fldname, const char *format, ...)
+    ATTRIBUTE_PRINTF (3, 4);
+
+  void spaces (int numspaces);
+  void text (const char *string);
+  void message (const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
+  void wrap_hint (const char *identstring);
+
+  void flush ();
+
+  /* Redirect the output of a ui_out object temporarily.  */
+  int redirect (ui_file *outstream);
+
+  ui_out_flags test_flags (ui_out_flags mask);
+
+  /* HACK: Code in GDB is currently checking to see the type of ui_out
+     builder when determining which output to produce.  This function is
+     a hack to encapsulate that test.  Once GDB manages to separate the
+     CLI/MI from the core of GDB the problem should just go away ....  */
+
+  int is_mi_like_p ();
+
+  bool query_table_field (int colno, int *width, int *alignment,
+			  const char **col_name);
+
+ protected:
+
+  virtual void do_table_begin (int nbrofcols, int nr_rows, const char *tblid)
+    = 0;
+  virtual void do_table_body () = 0;
+  virtual void do_table_end () = 0;
+  virtual void do_table_header (int width, ui_align align,
+				const std::string &col_name,
+				const std::string &col_hdr) = 0;
+
+  virtual void do_begin (ui_out_type type, const char *id) = 0;
+  virtual void do_end (ui_out_type type) = 0;
+  virtual void do_field_int (int fldno, int width, ui_align align,
+			     const char *fldname, int value) = 0;
+  virtual void do_field_skip (int fldno, int width, ui_align align,
+			      const char *fldname) = 0;
+  virtual void do_field_string (int fldno, int width, ui_align align,
+				const char *fldname, const char *string) = 0;
+  virtual void do_field_fmt (int fldno, int width, ui_align align,
+			     const char *fldname, const char *format,
+			     va_list args)
+    ATTRIBUTE_PRINTF (6,0) = 0;
+  virtual void do_spaces (int numspaces) = 0;
+  virtual void do_text (const char *string) = 0;
+  virtual void do_message (const char *format, va_list args)
+    ATTRIBUTE_PRINTF (2,0) = 0;
+  virtual void do_wrap_hint (const char *identstring) = 0;
+  virtual void do_flush () = 0;
+  virtual int do_redirect (struct ui_file * outstream) = 0;
+
+  /* Set as not MI-like by default.  It is overridden in subclasses if
+     necessary.  */
+
+  virtual bool do_is_mi_like_p ()
+  { return false; }
+
+ private:
+
+  ui_out_flags m_flags;
+
+  /* Vector to store and track the ui-out levels.  */
+  std::vector<std::unique_ptr<ui_out_level>> m_levels;
+
+  /* A table, if any.  At present only a single table is supported.  */
+  std::unique_ptr<ui_out_table> m_table_up;
+
+  void verify_field (int *fldno, int *width, ui_align *align);
+
+  int level () const;
+  ui_out_level *current_level () const;
+};
 
 #endif /* UI_OUT_H */
diff --git a/gdb/utils.c b/gdb/utils.c
index 3a88e2a..787e0e3 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -218,7 +218,7 @@  do_ui_out_redirect_pop (void *arg)
 {
   struct ui_out *uiout = (struct ui_out *) arg;
 
-  if (ui_out_redirect (uiout, NULL) < 0)
+  if (uiout->redirect (NULL) < 0)
     warning (_("Cannot restore redirection of the current output protocol"));
 }
 
@@ -2034,7 +2034,7 @@  fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
       || batch_flag
       || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
       || top_level_interpreter () == NULL
-      || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
+      || interp_ui_out (top_level_interpreter ())->is_mi_like_p ())
     {
       fputs_unfiltered (linebuffer, stream);
       return;