public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 00/22] Convert ui-out subsystem to C++
@ 2016-11-24 15:24 Simon Marchi
  2016-11-24 15:24 ` [PATCH 01/22] Remove unused functions and declarations Simon Marchi
                   ` (23 more replies)
  0 siblings, 24 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Hi all,

This patchset converts the various data structures of the ui-out susbsystem to
C++ classes.  Except when stated otherwise, the goal is to preserve the same
structure, which was already very class-like, and the same behaviour.  There
are also a few cleanup patches here and there.

The patch "Class-ify ui_out" introduces many clang -Wmismatched-tags warnings,
which John aimed to fix in another series.  I am preparing a patch that fixes
them, but since it will only be boring and mechanical changes, I didn't want to
delay the submission of this series further.

The series is also available here:

  https://github.com/simark/binutils-gdb/tree/cxx-ui-out-v1

Simon

Simon Marchi (22):
  Remove unused functions and declarations
  Rename ui_out_data to mi_ui_out_data
  Remove ui_out_destroy
  Fix return value of uo_redirect
  Constify wrap_here/wrap_hint code path
  Remove verbosity from ui_out_message and friends
  Remove stale comments
  Use new/delete instead of malloc/free-based functions
  Use std::vector for ui_out::levels
  Use std::vector for mi_ui_out_data::streams
  Use std::vector for cli_ui_out_data::streams
  Use std::string in ui_out_table
  Replace hand-made linked list of ui_out_hdr by vector and iterator
  Use std::string for ui_out_hdr's text fields
  Class-ify ui_out_hdr
  Class-ify ui_out_level
  Simplify ui-out level code
  ui_out_table: Replace boolean flag with enum
  Class-ify ui_out_impl
  Class-ify ui_out_table
  Class-ify ui_out
  Introduce enum_flag type for ui_out flags

 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            | 592 +++++++++++++--------------
 gdb/cli-out.c               | 321 +++++----------
 gdb/cli-out.h               |  77 ++--
 gdb/cli/cli-cmds.c          |   2 +-
 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              |  37 +-
 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             | 351 ++++++----------
 gdb/mi/mi-out.h             |  70 +++-
 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-out.c           | 156 +++----
 gdb/tui/tui.h               |   2 +-
 gdb/ui-out.c                | 973 +++++++++++++++-----------------------------
 gdb/ui-out.h                | 320 +++++++--------
 gdb/utils.c                 |   8 +-
 gdb/utils.h                 |   2 +-
 59 files changed, 2151 insertions(+), 2697 deletions(-)

-- 
2.10.0

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

* [PATCH 06/22] Remove verbosity from ui_out_message and friends
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
  2016-11-24 15:24 ` [PATCH 01/22] Remove unused functions and declarations Simon Marchi
  2016-11-24 15:24 ` [PATCH 02/22] Rename ui_out_data to mi_ui_out_data Simon Marchi
@ 2016-11-24 15:24 ` Simon Marchi
  2016-11-24 15:24 ` [PATCH 08/22] Use new/delete instead of malloc/free-based functions Simon Marchi
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

That concept is never actually used, so it's just a burden.  Removing it
facilitates the refactoring in upcoming patches.

gdb/ChangeLog:

	* mi/mi-out.c (mi_message): Remove verbosity argument.
	* ada-tasks.c (print_ada_task_info, info_task, task_command):
	Update call.
	* auto-load.c (auto_load_info_scripts): Likewise.
	* breakpoint.c (breakpoint_1, watchpoints_info, tracepoints_info):
	Likewise.
	* cli-out.c (cli_message): Remove verbosity argument.
	* inferior.c (print_inferior): Update call.
	* linux-thread-db.c (info_auto_load_libthread_db): Likewise.
	* probe.c (info_probes_for_ops): Likewise.
	* skip.c (skip_info): Likewise.
	* solib.c (info_sharedlibrary_command): Likewise.
	* symfile.c (load_progress): Likewise.
	* thread.c (print_thread_info_1): Likewise.
	* ui-out.c (uo_message, ui_out_message): Remove verbosity argument.
	(ui_out_get_verblvl): Remove.
	* ui-out.h (ui_out_message): Remove verbosity argument.
	(ui_out_get_verblvl): Remove.
	(message_ftype): Remove verbosity argument.
---
 gdb/ada-tasks.c       |  6 +++---
 gdb/auto-load.c       |  4 ++--
 gdb/breakpoint.c      | 12 ++++++------
 gdb/cli-out.c         | 13 ++++---------
 gdb/inferior.c        |  2 +-
 gdb/linux-thread-db.c |  2 +-
 gdb/mi/mi-out.c       |  8 +++-----
 gdb/probe.c           | 14 +++++++-------
 gdb/skip.c            |  4 ++--
 gdb/solib.c           |  6 +++---
 gdb/symfile.c         |  2 +-
 gdb/thread.c          |  8 ++++----
 gdb/ui-out.c          | 23 ++++++-----------------
 gdb/ui-out.h          | 11 ++++-------
 14 files changed, 47 insertions(+), 68 deletions(-)

diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index c067ae6..31092fd 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -1013,7 +1013,7 @@ print_ada_task_info (struct ui_out *uiout,
 
   if (ada_build_task_list () == 0)
     {
-      ui_out_message (uiout, 0,
+      ui_out_message (uiout,
 		      _("Your application does not use any Ada tasks.\n"));
       return;
     }
@@ -1163,7 +1163,7 @@ info_task (struct ui_out *uiout, char *taskno_str, struct inferior *inf)
 
   if (ada_build_task_list () == 0)
     {
-      ui_out_message (uiout, 0,
+      ui_out_message (uiout,
 		      _("Your application does not use any Ada tasks.\n"));
       return;
     }
@@ -1328,7 +1328,7 @@ task_command (char *taskno_str, int from_tty)
 
   if (ada_build_task_list () == 0)
     {
-      ui_out_message (uiout, 0,
+      ui_out_message (uiout,
 		      _("Your application does not use any Ada tasks.\n"));
       return;
     }
diff --git a/gdb/auto-load.c b/gdb/auto-load.c
index de64112..958c24e 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -1401,10 +1401,10 @@ auto_load_info_scripts (char *pattern, int from_tty,
   if (nr_scripts == 0)
     {
       if (pattern && *pattern)
-	ui_out_message (uiout, 0, "No auto-load scripts matching %s.\n",
+	ui_out_message (uiout, "No auto-load scripts matching %s.\n",
 			pattern);
       else
-	ui_out_message (uiout, 0, "No auto-load scripts.\n");
+	ui_out_message (uiout, "No auto-load scripts.\n");
     }
 }
 
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 67b610c..89ae6c5 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -6954,9 +6954,9 @@ breakpoint_1 (char *args, int allflag,
       if (!filter)
 	{
 	  if (args == NULL || *args == '\0')
-	    ui_out_message (uiout, 0, "No breakpoints or watchpoints.\n");
+	    ui_out_message (uiout, "No breakpoints or watchpoints.\n");
 	  else
-	    ui_out_message (uiout, 0, 
+	    ui_out_message (uiout,
 			    "No breakpoint or watchpoint matching '%s'.\n",
 			    args);
 	}
@@ -7012,9 +7012,9 @@ watchpoints_info (char *args, int from_tty)
   if (num_printed == 0)
     {
       if (args == NULL || *args == '\0')
-	ui_out_message (uiout, 0, "No watchpoints.\n");
+	ui_out_message (uiout, "No watchpoints.\n");
       else
-	ui_out_message (uiout, 0, "No watchpoint matching '%s'.\n", args);
+	ui_out_message (uiout, "No watchpoint matching '%s'.\n", args);
     }
 }
 
@@ -15478,9 +15478,9 @@ tracepoints_info (char *args, int from_tty)
   if (num_printed == 0)
     {
       if (args == NULL || *args == '\0')
-	ui_out_message (uiout, 0, "No tracepoints.\n");
+	ui_out_message (uiout, "No tracepoints.\n");
       else
-	ui_out_message (uiout, 0, "No tracepoint matching '%s'.\n", args);
+	ui_out_message (uiout, "No tracepoint matching '%s'.\n", args);
     }
 
   default_collect_info ();
diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index d208207..e882756 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -272,21 +272,16 @@ cli_text (struct ui_out *uiout, const char *string)
   fputs_filtered (string, stream);
 }
 
-static void ATTRIBUTE_PRINTF (3, 0)
-cli_message (struct ui_out *uiout, int verbosity,
-	     const char *format, va_list args)
+static void ATTRIBUTE_PRINTF (2, 0)
+cli_message (struct ui_out *uiout, const char *format, va_list args)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
 
   if (data->suppress_output)
     return;
 
-  if (ui_out_get_verblvl (uiout) >= verbosity)
-    {
-      struct ui_file *stream = VEC_last (ui_filep, data->streams);
-
-      vfprintf_unfiltered (stream, format, args);
-    }
+  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  vfprintf_unfiltered (stream, format, args);
 }
 
 static void
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 92a18d6..0abd2c0 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -594,7 +594,7 @@ print_inferior (struct ui_out *uiout, char *requested_inferiors)
 
   if (inf_count == 0)
     {
-      ui_out_message (uiout, 0, "No inferiors.\n");
+      ui_out_message (uiout, "No inferiors.\n");
       return;
     }
 
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 6ed3997..c1626ff 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -1668,7 +1668,7 @@ info_auto_load_libthread_db (char *args, int from_tty)
   do_cleanups (back_to);
 
   if (info_count == 0)
-    ui_out_message (uiout, 0, _("No auto-loaded libthread-db.\n"));
+    ui_out_message (uiout, _("No auto-loaded libthread-db.\n"));
 }
 
 static void
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 960529c..44e28b1 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -62,9 +62,8 @@ static void mi_field_fmt (struct ui_out *uiout, int fldno,
 			  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, int verbosity,
-			const char *format, va_list args)
-     ATTRIBUTE_PRINTF (3, 0);
+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);
@@ -267,8 +266,7 @@ mi_text (struct ui_out *uiout, const char *string)
 }
 
 void
-mi_message (struct ui_out *uiout, int verbosity,
-	    const char *format, va_list args)
+mi_message (struct ui_out *uiout, const char *format, va_list args)
 {
 }
 
diff --git a/gdb/probe.c b/gdb/probe.c
index 285f4e1..611a752 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -717,7 +717,7 @@ info_probes_for_ops (const char *arg, int from_tty,
   do_cleanups (cleanup);
 
   if (!any_found)
-    ui_out_message (current_uiout, 0, _("No probes matched.\n"));
+    ui_out_message (current_uiout, _("No probes matched.\n"));
 }
 
 /* Implementation of the `info probes' command.  */
@@ -747,7 +747,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, 0, _("No probes matched.\n"));
+      ui_out_message (current_uiout, _("No probes matched.\n"));
       do_cleanups (cleanup);
       return;
     }
@@ -761,12 +761,12 @@ enable_probes_command (char *arg, int from_tty)
       if (pops->enable_probe != NULL)
 	{
 	  pops->enable_probe (probe->probe);
-	  ui_out_message (current_uiout, 0,
+	  ui_out_message (current_uiout,
 			  _("Probe %s:%s enabled.\n"),
 			  probe->probe->provider, probe->probe->name);
 	}
       else
-	ui_out_message (current_uiout, 0,
+	ui_out_message (current_uiout,
 			_("Probe %s:%s cannot be enabled.\n"),
 			probe->probe->provider, probe->probe->name);
     }
@@ -793,7 +793,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, 0, _("No probes matched.\n"));
+      ui_out_message (current_uiout, _("No probes matched.\n"));
       do_cleanups (cleanup);
       return;
     }
@@ -807,12 +807,12 @@ disable_probes_command (char *arg, int from_tty)
       if (pops->disable_probe != NULL)
 	{
 	  pops->disable_probe (probe->probe);
-	  ui_out_message (current_uiout, 0,
+	  ui_out_message (current_uiout,
 			  _("Probe %s:%s disabled.\n"),
 			  probe->probe->provider, probe->probe->name);
 	}
       else
-	ui_out_message (current_uiout, 0,
+	ui_out_message (current_uiout,
 			_("Probe %s:%s cannot be disabled.\n"),
 			probe->probe->provider, probe->probe->name);
     }
diff --git a/gdb/skip.c b/gdb/skip.c
index 15681cc..fa0f0c9 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -373,10 +373,10 @@ skip_info (char *arg, int from_tty)
   if (num_printable_entries == 0)
     {
       if (arg == NULL)
-	ui_out_message (current_uiout, 0, _("\
+	ui_out_message (current_uiout, _("\
 Not skipping any files or functions.\n"));
       else
-	ui_out_message (current_uiout, 0,
+	ui_out_message (current_uiout,
 			_("No skiplist entries found with number %s.\n"), arg);
 
       return;
diff --git a/gdb/solib.c b/gdb/solib.c
index 29b25d5..db370e9 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1163,16 +1163,16 @@ info_sharedlibrary_command (char *pattern, int from_tty)
   if (nr_libs == 0)
     {
       if (pattern)
-	ui_out_message (uiout, 0,
+	ui_out_message (uiout,
 			_("No shared libraries matched.\n"));
       else
-	ui_out_message (uiout, 0,
+	ui_out_message (uiout,
 			_("No shared libraries loaded at this time.\n"));
     }
   else
     {
       if (so_missing_debug_info)
-	ui_out_message (uiout, 0,
+	ui_out_message (uiout,
 			_("(*): Shared library is missing "
 			  "debugging information.\n"));
     }
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 517c277..52f99bf 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1962,7 +1962,7 @@ 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, 0, "Loading section %s, size %s lma %s\n",
+      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));
       return;
diff --git a/gdb/thread.c b/gdb/thread.c
index 57b20ff..e5d6c5f 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1231,9 +1231,9 @@ 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, 0, _("No threads.\n"));
+	    ui_out_message (uiout, _("No threads.\n"));
 	  else
-	    ui_out_message (uiout, 0, _("No threads match '%s'.\n"),
+	    ui_out_message (uiout, _("No threads match '%s'.\n"),
 			    requested_threads);
 	  do_cleanups (old_chain);
 	  return;
@@ -1372,12 +1372,12 @@ print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
 	}
 
       if (!ptid_equal (inferior_ptid, null_ptid) && is_exited (inferior_ptid))
-	ui_out_message (uiout, 0, "\n\
+	ui_out_message (uiout, "\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, 0, "\n\
+	ui_out_message (uiout, "\n\
 No selected thread.  See `help thread'.\n");
     }
 }
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 840254d..da979af 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -171,9 +171,9 @@ static void uo_field_fmt (struct ui_out *uiout, int fldno, int width,
      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, int verbosity,
+static void uo_message (struct ui_out *uiout,
 			const char *format, va_list args)
-     ATTRIBUTE_PRINTF (3, 0);
+     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);
@@ -496,13 +496,12 @@ ui_out_text (struct ui_out *uiout,
 }
 
 void
-ui_out_message (struct ui_out *uiout, int verbosity,
-		const char *format,...)
+ui_out_message (struct ui_out *uiout, const char *format, ...)
 {
   va_list args;
 
   va_start (args, format);
-  uo_message (uiout, verbosity, format, args);
+  uo_message (uiout, format, args);
   va_end (args);
 }
 
@@ -531,16 +530,6 @@ ui_out_test_flags (struct ui_out *uiout, int mask)
   return (uiout->flags & mask);
 }
 
-/* Obtain the current verbosity level (as stablished by the
-   'set verbositylevel' command.  */
-
-int
-ui_out_get_verblvl (struct ui_out *uiout)
-{
-  /* FIXME: not implemented yet.  */
-  return 0;
-}
-
 int
 ui_out_is_mi_like_p (struct ui_out *uiout)
 {
@@ -675,13 +664,13 @@ uo_text (struct ui_out *uiout,
 }
 
 void
-uo_message (struct ui_out *uiout, int verbosity,
+uo_message (struct ui_out *uiout,
 	    const char *format,
 	    va_list args)
 {
   if (!uiout->impl->message)
     return;
-  uiout->impl->message (uiout, verbosity, format, args);
+  uiout->impl->message (uiout, format, args);
 }
 
 void
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index 1865765..baf4e44 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -119,16 +119,13 @@ 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, int verbosity,
-			    const char *format, ...)
-     ATTRIBUTE_PRINTF (3, 4);
+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_get_verblvl (struct ui_out *uiout);
-
 extern int ui_out_test_flags (struct ui_out *uiout, int mask);
 
 extern int ui_out_query_field (struct ui_out *uiout, int colno,
@@ -183,9 +180,9 @@ typedef void (field_fmt_ftype) (struct ui_out * uiout, int fldno, int width,
 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, int verbosity,
+typedef void (message_ftype) (struct ui_out * uiout,
 			      const char *format, va_list args)
-     ATTRIBUTE_FPTR_PRINTF(3,0);
+     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,
-- 
2.10.0

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

* [PATCH 07/22] Remove stale comments
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (5 preceding siblings ...)
  2016-11-24 15:24 ` [PATCH 09/22] Use std::vector for ui_out::levels Simon Marchi
@ 2016-11-24 15:24 ` Simon Marchi
  2016-11-24 18:38   ` Pedro Alves
  2016-11-24 15:27 ` [PATCH 10/22] Use std::vector for mi_ui_out_data::streams Simon Marchi
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

I am pretty sure that these comments aren't true anymore.

gdb/ChangeLog:

	* ui-out.h (struct ui_out_impl): Remove comment.
	* ui-out.c (struct ui_out): Remove comment.
---
 gdb/ui-out.c | 2 --
 gdb/ui-out.h | 3 ---
 2 files changed, 5 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index da979af..b8253c9 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -87,8 +87,6 @@ struct ui_out_table
 
 
 /* The ui_out structure */
-/* Any change here requires a corresponding one in the initialization
-   of the default uiout, which is statically initialized.  */
 
 struct ui_out
   {
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index baf4e44..e251d77 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -191,9 +191,6 @@ typedef void (data_destroy_ftype) (struct ui_out *uiout);
 
 /* ui-out-impl */
 
-/* IMPORTANT: If you change this structure, make sure to change the default
-   initialization in ui-out.c.  */
-
 struct ui_out_impl
   {
     table_begin_ftype *table_begin;
-- 
2.10.0

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

* [PATCH 01/22] Remove unused functions and declarations
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
@ 2016-11-24 15:24 ` Simon Marchi
  2016-11-24 15:24 ` [PATCH 02/22] Rename ui_out_data to mi_ui_out_data Simon Marchi
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

gdb/ChangeLog:

	* ui-out.c (_initialize_ui_out): Remove.
	(ui_out_set_flags): Remove.
	(ui_out_clear_flags): Remove.
	* ui-out.h (ui_out_begin_cleanup_end): Remove.
	(ui_out_begin_cleanup_end): Remove.
	(ui_out_set_flags): Remove.
	(ui_out_clear_flags): Remove.
	* mi/mi-out.c (_initialize_mi_out): Remove.
	(mi_out_buffered): Remove.
	* mi/mi-out.h (mi_out_buffered): Remove.
---
 gdb/mi/mi-out.c | 12 ------------
 gdb/mi/mi-out.h |  1 -
 gdb/ui-out.c    | 29 -----------------------------
 gdb/ui-out.h    |  8 --------
 4 files changed, 50 deletions(-)

diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 9513267..491caf5 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -95,7 +95,6 @@ static const struct ui_out_impl mi_ui_out_impl =
 
 /* Prototypes for local functions */
 
-extern void _initialize_mi_out (void);
 static void field_separator (struct ui_out *uiout);
 static void mi_open (struct ui_out *uiout, const char *name,
 		     enum ui_out_type type);
@@ -360,17 +359,6 @@ mi_close (struct ui_out *uiout, enum ui_out_type type)
   data->suppress_field_separator = 0;
 }
 
-/* Add a string to the buffer.  */
-
-void
-mi_out_buffered (struct ui_out *uiout, char *string)
-{
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
-
-  fprintf_unfiltered (stream, "%s", string);
-}
-
 /* Clear the buffer.  */
 
 void
diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h
index ace93bd..ba18950 100644
--- a/gdb/mi/mi-out.h
+++ b/gdb/mi/mi-out.h
@@ -26,7 +26,6 @@ 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);
-extern void mi_out_buffered (struct ui_out *uiout, char *string);
 
 /* Return the version number of the current MI.  */
 extern int mi_version (struct ui_out *uiout);
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 60d18ee..249d059 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -181,7 +181,6 @@ static void uo_data_destroy (struct ui_out *uiout);
 
 /* Prototypes for local functions */
 
-extern void _initialize_ui_out (void);
 static void append_header_to_list (struct ui_out *uiout, int width,
 				   enum ui_align alignment, const char *col_name,
 				   const char *colhdr);
@@ -526,26 +525,6 @@ ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream)
   return uo_redirect (uiout, outstream);
 }
 
-/* Set the flags specified by the mask given.  */
-int
-ui_out_set_flags (struct ui_out *uiout, int mask)
-{
-  int oldflags = uiout->flags;
-
-  uiout->flags |= mask;
-  return oldflags;
-}
-
-/* Clear the flags specified by the mask given.  */
-int
-ui_out_clear_flags (struct ui_out *uiout, int mask)
-{
-  int oldflags = uiout->flags;
-
-  uiout->flags &= ~mask;
-  return oldflags;
-}
-
 /* Test the flags against the mask given.  */
 int
 ui_out_test_flags (struct ui_out *uiout, int mask)
@@ -948,11 +927,3 @@ ui_out_destroy (struct ui_out *uiout)
   clear_table (uiout);
   xfree (uiout);
 }
-
-/* Standard gdb initialization hook.  */
-
-void
-_initialize_ui_out (void)
-{
-  /* nothing needs to be done */
-}
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index 9e1e74d..a5e693c 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -69,10 +69,6 @@ extern void ui_out_begin (struct ui_out *uiout,
 
 extern void ui_out_end (struct ui_out *uiout, enum ui_out_type type);
 
-extern struct cleanup *ui_out_begin_cleanup_end (struct ui_out *uiout,
-						 enum ui_out_type level_type,
-						 const char *id);
-
 /* 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
@@ -131,10 +127,6 @@ extern void ui_out_wrap_hint (struct ui_out *uiout, char *identstring);
 
 extern void ui_out_flush (struct ui_out *uiout);
 
-extern int ui_out_set_flags (struct ui_out *uiout, int mask);
-
-extern int ui_out_clear_flags (struct ui_out *uiout, int mask);
-
 extern int ui_out_get_verblvl (struct ui_out *uiout);
 
 extern int ui_out_test_flags (struct ui_out *uiout, int mask);
-- 
2.10.0

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

* [PATCH 02/22] Rename ui_out_data to mi_ui_out_data
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
  2016-11-24 15:24 ` [PATCH 01/22] Remove unused functions and declarations Simon Marchi
@ 2016-11-24 15:24 ` Simon Marchi
  2016-11-24 15:24 ` [PATCH 06/22] Remove verbosity from ui_out_message and friends Simon Marchi
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Just a little cleanup, so the name is more consistent with the naming of
the equivalent structures of cli and tui.  It goes away in subsequent
patches anyway, but it might help follow the changes in those patches...

gdb/ChangeLog:

	* mi/mi-out.c (ui_out_data): Rename to ...
	(mi_ui_out_data): ... this.
---
 gdb/mi/mi-out.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 491caf5..0f48426 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -27,14 +27,14 @@
 typedef struct ui_file *ui_filep;
 DEF_VEC_P (ui_filep);
 
-struct ui_out_data
+struct mi_ui_out_data
   {
     int suppress_field_separator;
     int suppress_output;
     int mi_version;
     VEC (ui_filep) *streams;
   };
-typedef struct ui_out_data mi_out_data;
+typedef struct mi_ui_out_data mi_out_data;
 
 /* These are the MI output functions */
 
-- 
2.10.0

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

* [PATCH 08/22] Use new/delete instead of malloc/free-based functions
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (2 preceding siblings ...)
  2016-11-24 15:24 ` [PATCH 06/22] Remove verbosity from ui_out_message and friends Simon Marchi
@ 2016-11-24 15:24 ` Simon Marchi
  2016-11-24 15:24 ` [PATCH 03/22] Remove ui_out_destroy Simon Marchi
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

The following patches introduce C++ vectors and strings as fields of the
various ui_out structures.  We therefore need to use new/delete so that
their contructor/destructor is called.  I find it simpler to change all
the allocations in a separate preliminary patch, rather than in each
individual patch.

gdb/ChangeLog:

	* cli-out.c (cli_uiout_dtor): Use delete instead of xfree.
	(cli_out_new): Use new instead of XNEW.
	* mi/mi-out.c (mi_out_data_dtor): Use delete instead of xfree.
	(mi_out_new): Use new instead of XNEW.
	* tui/tui-out.c (tui_out_new): Likewise.
	* ui-out.c (push_level): Likewise.
	(pop_level): Use delete instead of xfree.
	(clear_header_list): Use delete instead of xfree.
	(append_header_to_list): Use new instead of XNEW.
	(ui_out_new): Likewise.
---
 gdb/cli-out.c     |  4 ++--
 gdb/mi/mi-out.c   |  4 ++--
 gdb/tui/tui-out.c |  2 +-
 gdb/ui-out.c      | 13 +++++++------
 4 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index e882756..b98af4a 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -47,7 +47,7 @@ cli_uiout_dtor (struct ui_out *ui_out)
   cli_out_data *data = (cli_out_data *) ui_out_data (ui_out);
 
   VEC_free (ui_filep, data->streams);
-  xfree (data);
+  delete data;
 }
 
 /* These are the CLI output functions */
@@ -395,7 +395,7 @@ struct ui_out *
 cli_out_new (struct ui_file *stream)
 {
   int flags = ui_source_list;
-  cli_out_data *data = XNEW (cli_out_data);
+  cli_out_data *data = new cli_out_data ();
 
   cli_out_data_ctor (data, stream);
   return ui_out_new (&cli_ui_out_impl, data, flags);
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 44e28b1..2561f16 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -413,7 +413,7 @@ mi_out_data_dtor (struct ui_out *ui_out)
   mi_out_data *data = (mi_out_data *) ui_out_data (ui_out);
 
   VEC_free (ui_filep, data->streams);
-  xfree (data);
+  delete data;
 }
 
 /* Initialize private members at startup.  */
@@ -422,7 +422,7 @@ struct ui_out *
 mi_out_new (int mi_version)
 {
   int flags = 0;
-  mi_out_data *data = XNEW (mi_out_data);
+  mi_out_data *data = new mi_out_data ();
   struct ui_file *stream = mem_fileopen ();
 
   mi_out_data_ctor (data, mi_version, stream);
diff --git a/gdb/tui/tui-out.c b/gdb/tui/tui-out.c
index 0232370..4856562 100644
--- a/gdb/tui/tui-out.c
+++ b/gdb/tui/tui-out.c
@@ -147,7 +147,7 @@ tui_out_new (struct ui_file *stream)
 {
   int flags = 0;
 
-  tui_out_data *data = XNEW (tui_out_data);
+  tui_out_data *data = new tui_out_data ();
 
   /* Initialize base "class".  */
   cli_out_data_ctor (&data->base, stream);
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index b8253c9..bb37ece 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -120,7 +120,7 @@ push_level (struct ui_out *uiout,
   struct ui_out_level *current;
 
   uiout->level++;
-  current = XNEW (struct ui_out_level);
+  current = new ui_out_level ();
   current->field_count = 0;
   current->type = type;
   VEC_safe_push (ui_out_level_p, uiout->levels, current);
@@ -139,7 +139,7 @@ pop_level (struct ui_out *uiout,
   gdb_assert (uiout->level > 0);
   gdb_assert (current_level (uiout)->type == type);
   current = VEC_pop (ui_out_level_p, uiout->levels);
-  xfree (current);
+  delete current;
   uiout->level--;
   return uiout->level + 1;
 }
@@ -708,8 +708,9 @@ clear_header_list (struct ui_out *uiout)
       uiout->table.header_first = uiout->table.header_first->next;
       xfree (uiout->table.header_next->colhdr);
       xfree (uiout->table.header_next->col_name);
-      xfree (uiout->table.header_next);
+      delete uiout->table.header_next;
     }
+
   gdb_assert (uiout->table.header_first == NULL);
   uiout->table.header_last = NULL;
   uiout->table.header_next = NULL;
@@ -724,7 +725,7 @@ append_header_to_list (struct ui_out *uiout,
 {
   struct ui_out_hdr *temphdr;
 
-  temphdr = XNEW (struct ui_out_hdr);
+  temphdr = new ui_out_hdr ();
   temphdr->width = width;
   temphdr->alignment = alignment;
   /* We have to copy the column title as the original may be an
@@ -859,8 +860,8 @@ struct ui_out *
 ui_out_new (const struct ui_out_impl *impl, void *data,
 	    int flags)
 {
-  struct ui_out *uiout = XNEW (struct ui_out);
-  struct ui_out_level *current = XNEW (struct ui_out_level);
+  struct ui_out *uiout = new ui_out ();
+  struct ui_out_level *current = new ui_out_level ();
 
   uiout->data = data;
   uiout->impl = impl;
-- 
2.10.0

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

* [PATCH 09/22] Use std::vector for ui_out::levels
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (4 preceding siblings ...)
  2016-11-24 15:24 ` [PATCH 03/22] Remove ui_out_destroy Simon Marchi
@ 2016-11-24 15:24 ` Simon Marchi
  2016-11-24 15:24 ` [PATCH 07/22] Remove stale comments Simon Marchi
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Convert the levels field of struct ui_out to be a vector of unique_ptr
to ui_out_level.  This way, the ownership of the ui_out_level objects by
the ui_out instance is clear.

gdb/ChangeLog:

	* ui-out.c (ui_out_level_p): Remove typedef.
	(DEF_VEC_P (ui_out_level_p)): Remove definition.
	(struct ui_out) <levels>: Change type to vector of unique_ptr of
	ui_out_level.
	(current_level): Update.
	(push_level): Update.
	(pop_level): Update, don't manually delete the ui_out_level
	instance.
	(ui_out_new): Update.
---
 gdb/ui-out.c | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index bb37ece..1713183 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -25,6 +25,9 @@
 #include "language.h"
 #include "ui-out.h"
 
+#include <vector>
+#include <memory>
+
 /* table header structures */
 
 struct ui_out_hdr
@@ -45,9 +48,6 @@ struct ui_out_level
     enum ui_out_type type;
   };
 
-/* Define uiout->level vector types and operations.  */
-typedef struct ui_out_level *ui_out_level_p;
-DEF_VEC_P (ui_out_level_p);
 
 /* Tables are special.  Maintain a separate structure that tracks
    their state.  At present an output can only contain a single table
@@ -99,7 +99,7 @@ struct ui_out
     int level;
 
     /* Vector to store and track the ui-out levels.  */
-    VEC (ui_out_level_p) *levels;
+    std::vector<std::unique_ptr<ui_out_level>> levels;
 
     /* A table, if any.  At present only a single table is supported.  */
     struct ui_out_table table;
@@ -109,7 +109,7 @@ struct ui_out
 static struct ui_out_level *
 current_level (struct ui_out *uiout)
 {
-  return VEC_index (ui_out_level_p, uiout->levels, uiout->level);
+  return uiout->levels[uiout->level].get ();
 }
 
 /* Create a new level, of TYPE.  Return the new level's index.  */
@@ -117,13 +117,14 @@ static int
 push_level (struct ui_out *uiout,
 	    enum ui_out_type type)
 {
-  struct ui_out_level *current;
+  std::unique_ptr<ui_out_level> current (new ui_out_level ());
 
-  uiout->level++;
-  current = new ui_out_level ();
   current->field_count = 0;
   current->type = type;
-  VEC_safe_push (ui_out_level_p, uiout->levels, current);
+
+  uiout->level++;
+  uiout->levels.push_back (std::move (current));
+
   return uiout->level;
 }
 
@@ -133,14 +134,13 @@ static int
 pop_level (struct ui_out *uiout,
 	   enum ui_out_type type)
 {
-  struct ui_out_level *current;
-
   /* We had better not underflow the buffer.  */
   gdb_assert (uiout->level > 0);
   gdb_assert (current_level (uiout)->type == type);
-  current = VEC_pop (ui_out_level_p, uiout->levels);
-  delete current;
+
+  uiout->levels.pop_back ();
   uiout->level--;
+
   return uiout->level + 1;
 }
 
@@ -861,7 +861,7 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
 	    int flags)
 {
   struct ui_out *uiout = new ui_out ();
-  struct ui_out_level *current = new ui_out_level ();
+  std::unique_ptr<ui_out_level> current (new ui_out_level ());
 
   uiout->data = data;
   uiout->impl = impl;
@@ -869,12 +869,11 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
   uiout->table.flag = 0;
   uiout->table.body_flag = 0;
   uiout->level = 0;
-  uiout->levels = NULL;
 
   /* Create uiout->level 0, the default level.  */
   current->type = ui_out_type_tuple;
   current->field_count = 0;
-  VEC_safe_push (ui_out_level_p, uiout->levels, current);
+  uiout->levels.push_back (std::move (current));
 
   uiout->table.id = NULL;
   uiout->table.header_first = NULL;
-- 
2.10.0

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

* [PATCH 03/22] Remove ui_out_destroy
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (3 preceding siblings ...)
  2016-11-24 15:24 ` [PATCH 08/22] Use new/delete instead of malloc/free-based functions Simon Marchi
@ 2016-11-24 15:24 ` Simon Marchi
  2016-11-24 15:24 ` [PATCH 09/22] Use std::vector for ui_out::levels Simon Marchi
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

It's not actually used, and removing it simplifies the upcoming patches
a bit.  After the whole series, destroying an ui_out object will be
simply "delete uiout", which will call the default destructor.

gdb/ChangeLog:

	* ui-out.c (ui_out_destroy, uo_data_destroy): Remove.
	* ui-out.h (ui_out_destroy): Remove.
---
 gdb/ui-out.c | 32 --------------------------------
 gdb/ui-out.h |  4 ----
 2 files changed, 36 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 249d059..9ac22dd 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -177,7 +177,6 @@ static void uo_message (struct ui_out *uiout, int verbosity,
 static void uo_wrap_hint (struct ui_out *uiout, char *identstring);
 static void uo_flush (struct ui_out *uiout);
 static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream);
-static void uo_data_destroy (struct ui_out *uiout);
 
 /* Prototypes for local functions */
 
@@ -710,15 +709,6 @@ uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
   return 0;
 }
 
-void
-uo_data_destroy (struct ui_out *uiout)
-{
-  if (!uiout->impl->data_destroy)
-    return;
-
-  uiout->impl->data_destroy (uiout);
-}
-
 /* local functions */
 
 /* List of column headers manipulation routines.  */
@@ -905,25 +895,3 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
   uiout->table.header_next = NULL;
   return uiout;
 }
-
-/* Free  UIOUT and the memory areas it references.  */
-
-void
-ui_out_destroy (struct ui_out *uiout)
-{
-  int i;
-  struct ui_out_level *current;
-
-  /* Make sure that all levels are freed in the case where levels have
-     been pushed, but not popped before the ui_out object is
-     destroyed.  */
-  for (i = 0;
-       VEC_iterate (ui_out_level_p, uiout->levels, i, current);
-       ++i)
-    xfree (current);
-
-  VEC_free (ui_out_level_p, uiout->levels);
-  uo_data_destroy (uiout);
-  clear_table (uiout);
-  xfree (uiout);
-}
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index a5e693c..a76dfe8 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -231,10 +231,6 @@ extern struct ui_out *ui_out_new (const struct ui_out_impl *impl,
 				  void *data,
 				  int flags);
 
-/* Destroy a ui_out object.  */
-
-extern void ui_out_destroy (struct ui_out *uiout);
-
 /* Redirect the ouptut of a ui_out object temporarily.  */
 
 extern int ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream);
-- 
2.10.0

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

* [PATCH 10/22] Use std::vector for mi_ui_out_data::streams
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (6 preceding siblings ...)
  2016-11-24 15:24 ` [PATCH 07/22] Remove stale comments Simon Marchi
@ 2016-11-24 15:27 ` Simon Marchi
  2016-11-24 18:38   ` Pedro Alves
  2016-11-24 15:28 ` [PATCH 16/22] Class-ify ui_out_level Simon Marchi
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Use a standard vector instead of the home-made version.  I used a vector
of plain pointers, because the mi_ui_out_data object doesn't own the
streams objects (i.e. they shouldn't be deleted when the vector is
deleted).

gdb/ChangeLog:

	* mi/mi-out.c (mi_ui_out_data) <streams>: Change type to
	std::vector.
	(mi_field_string): Update.
	(mi_field_fmt): Update.
	(mi_flush): Update.
	(mi_redirect): Update.
	(field_separator): Update.
	(mi_open): Update.
	(mi_close): Update.
	(mi_out_buffered): Update.
	(mi_out_rewind): Update.
	(mi_out_put): Update.
	(mi_out_data_ctor): Update.
	(mi_out_data_dtor): Don't free streams.
---
 gdb/mi/mi-out.c | 30 +++++++++++++-----------------
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 2561f16..c89076a 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -23,16 +23,14 @@
 #include "ui-out.h"
 #include "mi-out.h"
 #include "vec.h"
-
-typedef struct ui_file *ui_filep;
-DEF_VEC_P (ui_filep);
+#include <vector>
 
 struct mi_ui_out_data
   {
     int suppress_field_separator;
     int suppress_output;
     int mi_version;
-    VEC (ui_filep) *streams;
+    std::vector<ui_file *> streams;
   };
 typedef struct mi_ui_out_data mi_out_data;
 
@@ -222,7 +220,7 @@ mi_field_string (struct ui_out *uiout, int fldno, int width,
   if (data->suppress_output)
     return;
 
-  stream = VEC_last (ui_filep, data->streams);
+  stream = data->streams.back ();
   field_separator (uiout);
   if (fldname)
     fprintf_unfiltered (stream, "%s=", fldname);
@@ -245,7 +243,7 @@ mi_field_fmt (struct ui_out *uiout, int fldno, int width,
   if (data->suppress_output)
     return;
 
-  stream = VEC_last (ui_filep, data->streams);
+  stream = data->streams.back ();
   field_separator (uiout);
   if (fldname)
     fprintf_unfiltered (stream, "%s=\"", fldname);
@@ -280,7 +278,7 @@ void
 mi_flush (struct ui_out *uiout)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  struct ui_file *stream = data->streams.back ();
 
   gdb_flush (stream);
 }
@@ -291,9 +289,9 @@ mi_redirect (struct ui_out *uiout, struct ui_file *outstream)
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
 
   if (outstream != NULL)
-    VEC_safe_push (ui_filep, data->streams, outstream);
+    data->streams.push_back (outstream);
   else
-    VEC_pop (ui_filep, data->streams);
+    data->streams.pop_back ();
 
   return 0;
 }
@@ -306,7 +304,7 @@ static void
 field_separator (struct ui_out *uiout)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  ui_file *stream = data->streams.back ();
 
   if (data->suppress_field_separator)
     data->suppress_field_separator = 0;
@@ -318,7 +316,7 @@ static void
 mi_open (struct ui_out *uiout, const char *name, enum ui_out_type type)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  ui_file *stream = data->streams.back ();
 
   field_separator (uiout);
   data->suppress_field_separator = 1;
@@ -341,7 +339,7 @@ static void
 mi_close (struct ui_out *uiout, enum ui_out_type type)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  ui_file *stream = data->streams.back ();
 
   switch (type)
     {
@@ -363,7 +361,7 @@ void
 mi_out_rewind (struct ui_out *uiout)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  ui_file *stream = data->streams.back ();
 
   ui_file_rewind (stream);
 }
@@ -374,7 +372,7 @@ void
 mi_out_put (struct ui_out *uiout, struct ui_file *stream)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-  struct ui_file *outstream = VEC_last (ui_filep, data->streams);
+  ui_file *outstream = data->streams.back ();
 
   ui_file_put (outstream, ui_file_write_for_put, stream);
   ui_file_rewind (outstream);
@@ -397,8 +395,7 @@ mi_out_data_ctor (mi_out_data *self, int mi_version, struct ui_file *stream)
 {
   gdb_assert (stream != NULL);
 
-  self->streams = NULL;
-  VEC_safe_push (ui_filep, self->streams, stream);
+  self->streams.push_back (stream);
 
   self->suppress_field_separator = 0;
   self->suppress_output = 0;
@@ -412,7 +409,6 @@ mi_out_data_dtor (struct ui_out *ui_out)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (ui_out);
 
-  VEC_free (ui_filep, data->streams);
   delete data;
 }
 
-- 
2.10.0

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

* [PATCH 18/22] ui_out_table: Replace boolean flag with enum
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (13 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 11/22] Use std::vector for cli_ui_out_data::streams Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 18:42   ` Pedro Alves
  2016-11-24 15:28 ` [PATCH 14/22] Use std::string for ui_out_hdr's text fields Simon Marchi
                   ` (8 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch is just a little cleanup, it replaces the body_flag field of
ui_out_table with an enum.  It expresses more explicitly the
intent of the field (check that state == TABLE_STATE_HEADERS conveys
more what we want to do than checking for !body_flag).

gdb/ChangeLog:

	* ui-out.c (enum ui_out_table_state): New enum.
	(struct ui_out_table) <body_flag>: Remove field.
	<state>: New field.
	(ui_out_table_begin): Replace usages of body_flag with state.
	(ui_out_table_body): Likewise.
	(ui_out_table_end): Likewise.
	(ui_out_table_header): Likewise.
	(ui_out_begin): Likewise.
	(verify_field): Likewise.
	(ui_out_new): Likewise.
---
 gdb/ui-out.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 25a14f7..1717491 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -126,6 +126,16 @@ class ui_out_level
   int m_field_count;
 };
 
+/* States (steps) of a table generation.  */
+
+enum ui_out_table_state
+{
+  /* We are generating the table headers.  */
+  TABLE_STATE_HEADERS,
+
+  /* We are generating the table body.  */
+  TABLE_STATE_BODY,
+};
 
 /* Tables are special.  Maintain a separate structure that tracks
    their state.  At present an output can only contain a single table
@@ -136,9 +146,7 @@ struct ui_out_table
   /* If on, a table is being generated.  */
   int flag;
 
-  /* If on, the body of a table is being generated.  If off, the table
-     header is being generated.  */
-  int body_flag;
+  ui_out_table_state state;
 
   /* The level at which each entry of the table is to be found.  A row
      (a tuple) is made up of entries.  Consequently ENTRY_LEVEL is one
@@ -271,7 +279,7 @@ ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
 previous table_end."));
 
   uiout->table.flag = 1;
-  uiout->table.body_flag = 0;
+  uiout->table.state = ui_out_table_state::TABLE_STATE_HEADERS;
   uiout->table.entry_level = uiout->level () + 1;
   uiout->table.columns = nbrofcols;
   uiout->table.id = tblid;
@@ -288,16 +296,18 @@ ui_out_table_body (struct ui_out *uiout)
     internal_error (__FILE__, __LINE__,
 		    _("table_body outside a table is not valid; it must be \
 after a table_begin and before a table_end."));
-  if (uiout->table.body_flag)
+
+  if (uiout->table.state == TABLE_STATE_BODY)
     internal_error (__FILE__, __LINE__,
 		    _("extra table_body call not allowed; there must be \
 only one table_body after a table_begin and before a table_end."));
+
   if (uiout->table.headers.size () != uiout->table.columns)
     internal_error (__FILE__, __LINE__,
 		    _("number of headers differ from number of table \
 columns."));
 
-  uiout->table.body_flag = 1;
+  uiout->table.state = TABLE_STATE_BODY;
 
   uo_table_body (uiout);
 }
@@ -310,7 +320,7 @@ ui_out_table_end (struct ui_out *uiout)
 		    _("misplaced table_end or missing table_begin."));
 
   uiout->table.entry_level = 0;
-  uiout->table.body_flag = 0;
+  uiout->table.state = TABLE_STATE_HEADERS;
   uiout->table.flag = 0;
 
   uo_table_end (uiout);
@@ -321,7 +331,7 @@ 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)
 {
-  if (!uiout->table.flag || uiout->table.body_flag)
+  if (!uiout->table.flag || uiout->table.state != TABLE_STATE_HEADERS)
     internal_error (__FILE__, __LINE__,
 		    _("table header must be specified after table_begin \
 and before table_body."));
@@ -352,7 +362,7 @@ ui_out_begin (struct ui_out *uiout,
 	      enum ui_out_type type,
 	      const char *id)
 {
-  if (uiout->table.flag && !uiout->table.body_flag)
+  if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY)
     internal_error (__FILE__, __LINE__,
 		    _("table header or table_body expected; lists must be \
 specified after table_body."));
@@ -376,7 +386,7 @@ specified after table_body."));
 
   /* 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.body_flag
+  if (uiout->table.state == TABLE_STATE_BODY
       && uiout->table.entry_level == uiout->level ())
     uiout->table.headers_iterator = uiout->table.headers.begin ();
 
@@ -817,11 +827,10 @@ verify_field (struct ui_out *uiout, int *fldno, int *width,
   ui_out_level *current = current_level (uiout);
   const char *text;
 
-  if (uiout->table.flag)
+  if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY)
     {
-      if (!uiout->table.body_flag)
-	internal_error (__FILE__, __LINE__,
-			_("table_body missing; table fields must be \
+      internal_error (__FILE__, __LINE__,
+		      _("table_body missing; table fields must be \
 specified after table_body and inside a list."));
       /* NOTE: cagney/2001-12-08: There was a check here to ensure
 	 that this code was only executed when uiout->level () was
@@ -832,7 +841,7 @@ specified after table_body and inside a list."));
 
   current->inc_field_count ();
 
-  if (uiout->table.body_flag
+  if (uiout->table.state == TABLE_STATE_BODY
       && uiout->table.entry_level == uiout->level ()
       && get_next_header (uiout, fldno, width, align, &text))
     {
@@ -896,7 +905,7 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
   uiout->impl = impl;
   uiout->flags = flags;
   uiout->table.flag = 0;
-  uiout->table.body_flag = 0;
+  uiout->table.state = TABLE_STATE_HEADERS;
 
   /* Create uiout->level () 0, the default level.  */
   push_level (uiout, ui_out_type_tuple);
-- 
2.10.0

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

* [PATCH 16/22] Class-ify ui_out_level
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (7 preceding siblings ...)
  2016-11-24 15:27 ` [PATCH 10/22] Use std::vector for mi_ui_out_data::streams Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 18:41   ` Pedro Alves
  2016-11-24 15:28 ` [PATCH 15/22] Class-ify ui_out_hdr Simon Marchi
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch changes struct ui_out_level to be a real C++ class.  No
behavioral changes.

gdb/ChangeLog:

	* ui-out.c (struct ui_out_level): Replace with ...
	(class ui_out_level): ... this.
	(current_level): Update.
	(push_level): Update.
	(pop_level): Update.
	(verify_field): Update.
	(ui_out_new): Update.
---
 gdb/ui-out.c | 65 ++++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 44 insertions(+), 21 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 410f40c..594338a 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -90,13 +90,41 @@ class ui_out_hdr
   std::string m_header;
 };
 
-struct ui_out_level
+/* A level of nesting (either a list or a tuple) in a ui_out output.  */
+
+class ui_out_level
+{
+ public:
+
+  ui_out_level (ui_out_type type)
+  : m_type (type),
+    m_field_count (0)
   {
-    /* Count each field; the first element is for non-list fields.  */
-    int field_count;
-    /* The type of this level.  */
-    enum ui_out_type type;
-  };
+  }
+
+  ui_out_type type (void) const
+  {
+    return m_type;
+  }
+
+  int field_count (void) const
+  {
+    return m_field_count;
+  }
+
+  void inc_field_count (void)
+  {
+    m_field_count++;
+  }
+
+ private:
+
+  /* The type of this level.  */
+  ui_out_type m_type;
+
+  /* Count each field; the first element is for non-list fields.  */
+  int m_field_count;
+};
 
 
 /* Tables are special.  Maintain a separate structure that tracks
@@ -153,7 +181,7 @@ struct ui_out
   };
 
 /* The current (inner most) level.  */
-static struct ui_out_level *
+static ui_out_level *
 current_level (struct ui_out *uiout)
 {
   return uiout->levels[uiout->level].get ();
@@ -164,13 +192,10 @@ static int
 push_level (struct ui_out *uiout,
 	    enum ui_out_type type)
 {
-  std::unique_ptr<ui_out_level> current (new ui_out_level ());
-
-  current->field_count = 0;
-  current->type = type;
+  std::unique_ptr<ui_out_level> level (new ui_out_level (type));
 
+  uiout->levels.push_back (std::move (level));
   uiout->level++;
-  uiout->levels.push_back (std::move (current));
 
   return uiout->level;
 }
@@ -183,7 +208,7 @@ pop_level (struct ui_out *uiout,
 {
   /* We had better not underflow the buffer.  */
   gdb_assert (uiout->level > 0);
-  gdb_assert (current_level (uiout)->type == type);
+  gdb_assert (current_level (uiout)->type () == type);
 
   uiout->levels.pop_back ();
   uiout->level--;
@@ -798,7 +823,7 @@ static void
 verify_field (struct ui_out *uiout, int *fldno, int *width,
 	      enum ui_align *align)
 {
-  struct ui_out_level *current = current_level (uiout);
+  ui_out_level *current = current_level (uiout);
   const char *text;
 
   if (uiout->table.flag)
@@ -814,13 +839,13 @@ specified after table_body and inside a list."));
 	 level is zero.  */
     }
 
-  current->field_count += 1;
+  current->inc_field_count ();
 
   if (uiout->table.body_flag
       && uiout->table.entry_level == uiout->level
       && get_next_header (uiout, fldno, width, align, &text))
     {
-      if (*fldno != current->field_count)
+      if (*fldno != current->field_count ())
 	internal_error (__FILE__, __LINE__,
 			_("ui-out internal error in handling headers."));
     }
@@ -828,7 +853,7 @@ specified after table_body and inside a list."));
     {
       *width = 0;
       *align = ui_noalign;
-      *fldno = current->field_count;
+      *fldno = current->field_count ();
     }
 }
 
@@ -875,7 +900,6 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
 	    int flags)
 {
   struct ui_out *uiout = new ui_out ();
-  std::unique_ptr<ui_out_level> current (new ui_out_level ());
 
   uiout->data = data;
   uiout->impl = impl;
@@ -885,9 +909,8 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
   uiout->level = 0;
 
   /* Create uiout->level 0, the default level.  */
-  current->type = ui_out_type_tuple;
-  current->field_count = 0;
-  uiout->levels.push_back (std::move (current));
+  std::unique_ptr<ui_out_level> level (new ui_out_level (ui_out_type_tuple));
+  uiout->levels.push_back (std::move (level));
 
   uiout->table.headers_iterator = uiout->table.headers.end ();
 
-- 
2.10.0

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

* [PATCH 12/22] Use std::string in ui_out_table
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (10 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by vector and iterator Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 15:28 ` [PATCH 17/22] Simplify ui-out level code Simon Marchi
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Use std::string for the id field of the ui_out_table object.

I found that all users of ui_out_table_begin passed a non-NULL value to
the tblid parameter, so we don't have to worry about the NULL case.  I
changed the tblid parameter to be a std::string while at it.

gdb/ChangeLog:

	* ui-out.c (struct ui_out_table) <id>: Change type to
	std::string.
	(ui_out_table_begin): Change tblid parameter type to
	std::string, adapt code.
	update following type change.
	(clear_table): Update.
	(ui_out_new): Update.
---
 gdb/ui-out.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 1713183..a40ac0a 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -27,6 +27,7 @@
 
 #include <vector>
 #include <memory>
+#include <string>
 
 /* table header structures */
 
@@ -72,7 +73,7 @@ struct ui_out_table
 
   /* String identifying the table (as specified in the table_begin
      call).  */
-  char *id;
+  std::string id;
 
   /* Points to the first table header (if any).  */
   struct ui_out_hdr *header_first;
@@ -194,8 +195,7 @@ static void verify_field (struct ui_out *uiout, int *fldno, int *width,
 
 static void
 ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
-		    int nr_rows,
-		    const char *tblid)
+		    int nr_rows, const std::string &tblid)
 {
   if (uiout->table.flag)
     internal_error (__FILE__, __LINE__,
@@ -206,13 +206,11 @@ previous table_end."));
   uiout->table.body_flag = 0;
   uiout->table.entry_level = uiout->level + 1;
   uiout->table.columns = nbrofcols;
-  if (tblid != NULL)
-    uiout->table.id = xstrdup (tblid);
-  else
-    uiout->table.id = NULL;
+  uiout->table.id = tblid;
+
   clear_header_list (uiout);
 
-  uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id);
+  uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id.c_str ());
 }
 
 void
@@ -577,8 +575,7 @@ uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
 static void
 clear_table (struct ui_out *uiout)
 {
-  xfree (uiout->table.id);
-  uiout->table.id = NULL;
+  uiout->table.id.clear ();
   clear_header_list (uiout);
 }
 
@@ -875,7 +872,6 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
   current->field_count = 0;
   uiout->levels.push_back (std::move (current));
 
-  uiout->table.id = NULL;
   uiout->table.header_first = NULL;
   uiout->table.header_last = NULL;
   uiout->table.header_next = NULL;
-- 
2.10.0

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

* [PATCH 15/22] Class-ify ui_out_hdr
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (8 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 16/22] Class-ify ui_out_level Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 15:28 ` [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by vector and iterator Simon Marchi
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch makes ui_out_hdr (the object that represents an ui-out table
header) a proper C++ class.  No behavior changes, it's all about
encapsulation.

gdb/ChangeLog:

	* ui-out.c (struct ui_out_hdr): Replace with ...
	(class ui_out_hdr): ... this.
	(append_header_to_list): Update.
	(get_next_header): Update.
	(ui_out_query_field): Update.
---
 gdb/ui-out.c | 96 +++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 69 insertions(+), 27 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 3cd5695..410f40c 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -29,16 +29,66 @@
 #include <memory>
 #include <string>
 
-/* table header structures */
+/* A header of a ui_out_table.  */
 
-struct ui_out_hdr
+class ui_out_hdr
+{
+ public:
+
+  ui_out_hdr (int number, int min_width, ui_align alignment,
+	      const std::string &name, const std::string &header)
+  : m_number (number),
+    m_min_width (min_width),
+    m_alignment (alignment),
+    m_name (name),
+    m_header (header)
   {
-    int colno;
-    int width;
-    enum ui_align alignment;
-    std::string col_name;
-    std::string col_hdr;
-  };
+  }
+
+  int number () const
+  {
+    return m_number;
+  }
+
+  int min_width () const
+  {
+    return m_min_width;
+  }
+
+  ui_align alignment () const
+  {
+    return m_alignment;
+  }
+
+  const std::string &header () const
+  {
+    return m_header;
+  }
+
+  const std::string &name () const
+  {
+    return m_name;
+  }
+
+ private:
+
+  /* The number of the table column this header represents, 1-based.  */
+  int m_number;
+
+  /* Minimal column width in characters.  May or may not be applicable,
+     depending on the actual implementation of ui_out.  */
+  int m_min_width;
+
+  /* Alignment of the content in the column.  May or may not be applicable,
+     depending on the actual implementation of ui_out.  */
+  ui_align m_alignment;
+
+  /* Internal column name, used to internally refer to the column.  */
+  std::string m_name;
+
+  /* Printed header text of the column.  */
+  std::string m_header;
+};
 
 struct ui_out_level
   {
@@ -705,17 +755,9 @@ append_header_to_list (struct ui_out *uiout,
 		       const std::string &col_name,
 		       const std::string &col_hdr)
 {
-  std::unique_ptr<ui_out_hdr> temphdr (new ui_out_hdr ());
-
-  temphdr->width = width;
-  temphdr->alignment = alignment;
-
-  /* Make our own copy of the strings, since the lifetime of the original
-     versions may be too short.  */
-  temphdr->col_hdr = col_hdr;
-  temphdr->col_name = col_name;
-
-  temphdr->colno = uiout->table.headers.size () + 1;
+  std::unique_ptr<ui_out_hdr> temphdr(
+    new ui_out_hdr (uiout->table.headers.size () + 1, width,
+		    alignment, col_name, col_hdr));
 
   uiout->table.headers.push_back (std::move (temphdr));
 }
@@ -736,10 +778,10 @@ get_next_header (struct ui_out *uiout,
 
   ui_out_hdr *hdr = uiout->table.headers_iterator->get ();
 
-  *colno = hdr->colno;
-  *width = hdr->width;
-  *alignment = hdr->alignment;
-  *col_hdr = hdr->col_hdr.c_str ();
+  *colno = hdr->number ();
+  *width = hdr->min_width ();
+  *alignment = hdr->alignment ();
+  *col_hdr = hdr->header ().c_str ();
 
   /* Advance the header pointer to the next entry.  */
   uiout->table.headers_iterator++;
@@ -814,11 +856,11 @@ ui_out_query_field (struct ui_out *uiout, int colno,
     {
       ui_out_hdr *hdr = uiout->table.headers[index].get ();
 
-      gdb_assert (colno == hdr->colno);
+      gdb_assert (colno == hdr->number ());
 
-      *width = hdr->width;
-      *alignment = hdr->alignment;
-      *col_name = hdr->col_name.c_str ();
+      *width = hdr->min_width ();
+      *alignment = hdr->alignment ();
+      *col_name = hdr->name ().c_str ();
 
       return 1;
     }
-- 
2.10.0

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

* [PATCH 17/22] Simplify ui-out level code
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (11 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 12/22] Use std::string in ui_out_table Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 18:42   ` Pedro Alves
  2016-11-24 15:28 ` [PATCH 11/22] Use std::vector for cli_ui_out_data::streams Simon Marchi
                   ` (10 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Now that we use a vector to store the levels, we don't have to keep a
separate level field in ui_out to keep track of the current level.  We
can efficiently derive it from the vector size.  That causes a little
change in the meaning of the level, as in they are now 1-based instead
of 0-based (the initial level has the "id" 1 now), but it shouldn't
change anything in the behavior.

Additionally, push_level and pop_level don't really need to return the
new level, making them return void simplifies the code a bit.

Finally, the ui_out_begin/ui_out_end callbacks in the ui_out_impl
interface don't need to be passed the level, it's never actually used.

gdb/ChangeLog:

	* ui-out.h (ui_out_begin_ftype): Remove level parameter.
	(ui_out_end_ftype): Likewise.
	* ui-out.c (struct ui_out) <level>: Replace field with a method
	that dynamically computes the result.
	(current_level): Get vector's back item instead of using
	uiout->level.
	(push_level): Make return type void.
	(pop_level): Make return type void and update access to
	ui_out::level.
	(uo_begin): Remove level parameter.
	(uo_end): Likewise.
	(ui_out_table_begin): Update access to uiout::level.
	(ui_out_begin): Don't read return value from push_level, call
	uiout->level() instead, update call to uo_begin.
	(ui_out_end): Don't read return value from pop_level, update
	call to uo_end.
	(verify_field): Update access to uiout->level.
	(ui_out_new): Don't initialize ui_out::level, call push_level
	to push the initial level instead of doing it by hand.
	* cli-out.c (cli_begin): Remove level parameter.
	(cli_end): Likewise.
	* mi/mi-out.c (mi_begin): Likewise.
	(mi_end): Likewise.
---
 gdb/cli-out.c   |  4 +---
 gdb/mi/mi-out.c |  9 ++++-----
 gdb/ui-out.c    | 59 +++++++++++++++++++++++----------------------------------
 gdb/ui-out.h    |  8 +++-----
 4 files changed, 32 insertions(+), 48 deletions(-)

diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index 9ba1d17..e042926 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -112,7 +112,6 @@ cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
 static void
 cli_begin (struct ui_out *uiout,
 	   enum ui_out_type type,
-	   int level,
 	   const char *id)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
@@ -125,8 +124,7 @@ cli_begin (struct ui_out *uiout,
 
 static void
 cli_end (struct ui_out *uiout,
-	 enum ui_out_type type,
-	 int level)
+	 enum ui_out_type type)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
 
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 72e84b2..b7cd433 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -46,8 +46,8 @@ static void mi_table_header (struct ui_out *uiout, int width,
 			     const std::string &col_name,
 			     const std::string &col_hdr);
 static void mi_begin (struct ui_out *uiout, enum ui_out_type type,
-		      int level, const char *id);
-static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level);
+		      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,
@@ -160,8 +160,7 @@ mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
 /* Mark beginning of a list.  */
 
 void
-mi_begin (struct ui_out *uiout, enum ui_out_type type, int level,
-	  const char *id)
+mi_begin (struct ui_out *uiout, enum ui_out_type type, const char *id)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
 
@@ -174,7 +173,7 @@ mi_begin (struct ui_out *uiout, enum ui_out_type type, int level,
 /* Mark end of a list.  */
 
 void
-mi_end (struct ui_out *uiout, enum ui_out_type type, int level)
+mi_end (struct ui_out *uiout, enum ui_out_type type)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
 
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 594338a..25a14f7 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -170,12 +170,14 @@ struct ui_out
     const struct ui_out_impl *impl;
     void *data;
 
-    /* Current level.  */
-    int level;
-
     /* Vector to store and track the ui-out levels.  */
     std::vector<std::unique_ptr<ui_out_level>> levels;
 
+    int level (void) const
+    {
+      return this->levels.size ();
+    }
+
     /* A table, if any.  At present only a single table is supported.  */
     struct ui_out_table table;
   };
@@ -184,36 +186,30 @@ struct ui_out
 static ui_out_level *
 current_level (struct ui_out *uiout)
 {
-  return uiout->levels[uiout->level].get ();
+  return uiout->levels.back ().get ();
 }
 
 /* Create a new level, of TYPE.  Return the new level's index.  */
-static int
+static void
 push_level (struct ui_out *uiout,
 	    enum ui_out_type type)
 {
   std::unique_ptr<ui_out_level> level (new ui_out_level (type));
 
   uiout->levels.push_back (std::move (level));
-  uiout->level++;
-
-  return uiout->level;
 }
 
 /* Discard the current level, return the discarded level's index.
    TYPE is the type of the level being discarded.  */
-static int
+static void
 pop_level (struct ui_out *uiout,
 	   enum ui_out_type type)
 {
   /* We had better not underflow the buffer.  */
-  gdb_assert (uiout->level > 0);
+  gdb_assert (uiout->level () > 0);
   gdb_assert (current_level (uiout)->type () == type);
 
   uiout->levels.pop_back ();
-  uiout->level--;
-
-  return uiout->level + 1;
 }
 
 /* These are the interfaces to implementation functions.  */
@@ -228,10 +224,9 @@ static void uo_table_header (struct ui_out *uiout, int width,
 			     const std::string &col_hdr);
 static void uo_begin (struct ui_out *uiout,
 		      enum ui_out_type type,
-		      int level, const char *id);
+		      const char *id);
 static void uo_end (struct ui_out *uiout,
-		    enum ui_out_type type,
-		    int level);
+		    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,
@@ -277,7 +272,7 @@ previous table_end."));
 
   uiout->table.flag = 1;
   uiout->table.body_flag = 0;
-  uiout->table.entry_level = uiout->level + 1;
+  uiout->table.entry_level = uiout->level () + 1;
   uiout->table.columns = nbrofcols;
   uiout->table.id = tblid;
 
@@ -357,8 +352,6 @@ ui_out_begin (struct ui_out *uiout,
 	      enum ui_out_type type,
 	      const char *id)
 {
-  int new_level;
-
   if (uiout->table.flag && !uiout->table.body_flag)
     internal_error (__FILE__, __LINE__,
 		    _("table header or table_body expected; lists must be \
@@ -379,24 +372,24 @@ specified after table_body."));
     verify_field (uiout, &fldno, &width, &align);
   }
 
-  new_level = push_level (uiout, type);
+  push_level (uiout, 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.body_flag
-      && uiout->table.entry_level == new_level)
+      && uiout->table.entry_level == uiout->level ())
     uiout->table.headers_iterator = uiout->table.headers.begin ();
 
-  uo_begin (uiout, type, new_level, id);
+  uo_begin (uiout, type, id);
 }
 
 void
 ui_out_end (struct ui_out *uiout,
 	    enum ui_out_type type)
 {
-  int old_level = pop_level (uiout, type);
+  pop_level (uiout, type);
 
-  uo_end (uiout, type, old_level);
+  uo_end (uiout, type);
 }
 
 struct ui_out_end_cleanup_data
@@ -652,22 +645,20 @@ clear_table (struct ui_out *uiout)
 void
 uo_begin (struct ui_out *uiout,
 	  enum ui_out_type type,
-	  int level,
 	  const char *id)
 {
   if (uiout->impl->begin == NULL)
     return;
-  uiout->impl->begin (uiout, type, level, id);
+  uiout->impl->begin (uiout, type, id);
 }
 
 void
 uo_end (struct ui_out *uiout,
-	enum ui_out_type type,
-	int level)
+	enum ui_out_type type)
 {
   if (uiout->impl->end == NULL)
     return;
-  uiout->impl->end (uiout, type, level);
+  uiout->impl->end (uiout, type);
 }
 
 void
@@ -833,7 +824,7 @@ verify_field (struct ui_out *uiout, int *fldno, int *width,
 			_("table_body missing; table fields must be \
 specified after table_body and inside a list."));
       /* NOTE: cagney/2001-12-08: There was a check here to ensure
-	 that this code was only executed when uiout->level was
+	 that this code was only executed when uiout->level () was
 	 greater than zero.  That no longer applies - this code is run
 	 before each table row tuple is started and at that point the
 	 level is zero.  */
@@ -842,7 +833,7 @@ specified after table_body and inside a list."));
   current->inc_field_count ();
 
   if (uiout->table.body_flag
-      && uiout->table.entry_level == uiout->level
+      && uiout->table.entry_level == uiout->level ()
       && get_next_header (uiout, fldno, width, align, &text))
     {
       if (*fldno != current->field_count ())
@@ -906,11 +897,9 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
   uiout->flags = flags;
   uiout->table.flag = 0;
   uiout->table.body_flag = 0;
-  uiout->level = 0;
 
-  /* Create uiout->level 0, the default level.  */
-  std::unique_ptr<ui_out_level> level (new ui_out_level (ui_out_type_tuple));
-  uiout->levels.push_back (std::move (level));
+  /* Create uiout->level () 0, the default level.  */
+  push_level (uiout, ui_out_type_tuple);
 
   uiout->table.headers_iterator = uiout->table.headers.end ();
 
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index ed2911d..06c05e2 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -157,14 +157,12 @@ 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);
-/* Note: level 0 is the top-level so LEVEL is always greater than
-   zero.  */
+
 typedef void (ui_out_begin_ftype) (struct ui_out *uiout,
 				   enum ui_out_type type,
-				   int level, const char *id);
+				   const char *id);
 typedef void (ui_out_end_ftype) (struct ui_out *uiout,
-				 enum ui_out_type type,
-				 int level);
+				 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);
-- 
2.10.0

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

* [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by vector and iterator
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (9 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 15/22] Class-ify ui_out_hdr Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 18:41   ` Pedro Alves
  2016-11-24 15:28 ` [PATCH 12/22] Use std::string in ui_out_table Simon Marchi
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Instead of keeping pointers to first, last and current ui_out_hdr in
ui_out_table, we can use an std::vector and an iterator.  Direct random
access of to vector helps make get_next_header a bit nicer by avoiding
iterating on all the headers.  append_header_to_list is also a bit
simpler.

Also, using unique_ptr inside the vector allows expressing the ownership
of the ui_out_hdr objects by the ui_out_table object, and it simplifies
the destruction.

gdb/ChangeLog:

	* ui-out.c (struct ui_out_hdr) <next>: Remove.
	(struct ui_out_table) <header_first, header_last, header_next>: Remove.
	<headers, headers_iterator>: New fields.
	(ui_out_table_body): Update for the new data structure.
	(ui_out_begin): Likewise.
	(clear_header_list): Likewise.
	(append_header_to_list): Likewise.
	(get_next_header): Likewise.
	(ui_out_query_field): Likewise.
	(ui_out_new): Likewise.
---
 gdb/ui-out.c | 100 ++++++++++++++++++++++++++---------------------------------
 1 file changed, 44 insertions(+), 56 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index a40ac0a..8e44698 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -38,7 +38,6 @@ struct ui_out_hdr
     enum ui_align alignment;
     char *col_name;
     char *colhdr;
-    struct ui_out_hdr *next;
   };
 
 struct ui_out_level
@@ -75,14 +74,11 @@ struct ui_out_table
      call).  */
   std::string id;
 
-  /* Points to the first table header (if any).  */
-  struct ui_out_hdr *header_first;
+  /* Pointers to the column headers.  */
+  std::vector<std::unique_ptr<ui_out_hdr>> headers;
 
-  /* Points to the last table header (if any).  */
-  struct ui_out_hdr *header_last;
-
-  /* Points to header of NEXT column to format.  */
-  struct ui_out_hdr *header_next;
+  /* Iterator over the headers vector, used when printing successive fields.  */
+  std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator headers_iterator;
 
 };
 
@@ -224,13 +220,12 @@ after a table_begin and before a table_end."));
     internal_error (__FILE__, __LINE__,
 		    _("extra table_body call not allowed; there must be \
 only one table_body after a table_begin and before a table_end."));
-  if (uiout->table.header_next->colno != uiout->table.columns)
+  if (uiout->table.headers.size () != uiout->table.columns)
     internal_error (__FILE__, __LINE__,
 		    _("number of headers differ from number of table \
 columns."));
 
   uiout->table.body_flag = 1;
-  uiout->table.header_next = uiout->table.header_first;
 
   uo_table_body (uiout);
 }
@@ -314,7 +309,7 @@ specified after table_body."));
      got a new table row.  Put the header pointer back to the start.  */
   if (uiout->table.body_flag
       && uiout->table.entry_level == new_level)
-    uiout->table.header_next = uiout->table.header_first;
+    uiout->table.headers_iterator = uiout->table.headers.begin ();
 
   uo_begin (uiout, type, new_level, id);
 }
@@ -699,18 +694,14 @@ uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
 static void
 clear_header_list (struct ui_out *uiout)
 {
-  while (uiout->table.header_first != NULL)
+  for (auto &it : uiout->table.headers)
     {
-      uiout->table.header_next = uiout->table.header_first;
-      uiout->table.header_first = uiout->table.header_first->next;
-      xfree (uiout->table.header_next->colhdr);
-      xfree (uiout->table.header_next->col_name);
-      delete uiout->table.header_next;
+      xfree (it->colhdr);
+      xfree (it->col_name);
     }
 
-  gdb_assert (uiout->table.header_first == NULL);
-  uiout->table.header_last = NULL;
-  uiout->table.header_next = NULL;
+  uiout->table.headers.clear ();
+  uiout->table.headers_iterator = uiout->table.headers.end ();
 }
 
 static void
@@ -720,9 +711,8 @@ append_header_to_list (struct ui_out *uiout,
 		       const char *col_name,
 		       const char *colhdr)
 {
-  struct ui_out_hdr *temphdr;
+  std::unique_ptr<ui_out_hdr> temphdr (new ui_out_hdr ());
 
-  temphdr = new ui_out_hdr ();
   temphdr->width = width;
   temphdr->alignment = alignment;
   /* We have to copy the column title as the original may be an
@@ -739,20 +729,9 @@ append_header_to_list (struct ui_out *uiout,
   else
     temphdr->col_name = NULL;
 
-  temphdr->next = NULL;
-  if (uiout->table.header_first == NULL)
-    {
-      temphdr->colno = 1;
-      uiout->table.header_first = temphdr;
-      uiout->table.header_last = temphdr;
-    }
-  else
-    {
-      temphdr->colno = uiout->table.header_last->colno + 1;
-      uiout->table.header_last->next = temphdr;
-      uiout->table.header_last = temphdr;
-    }
-  uiout->table.header_next = uiout->table.header_last;
+  temphdr->colno = uiout->table.headers.size () + 1;
+
+  uiout->table.headers.push_back (std::move (temphdr));
 }
 
 /* Extract the format information for the NEXT header and advance
@@ -766,14 +745,19 @@ get_next_header (struct ui_out *uiout,
 		 char **colhdr)
 {
   /* There may be no headers at all or we may have used all columns.  */
-  if (uiout->table.header_next == NULL)
+  if (uiout->table.headers_iterator == uiout->table.headers.end ())
     return 0;
-  *colno = uiout->table.header_next->colno;
-  *width = uiout->table.header_next->width;
-  *alignment = uiout->table.header_next->alignment;
-  *colhdr = uiout->table.header_next->colhdr;
+
+  ui_out_hdr *hdr = uiout->table.headers_iterator->get ();
+
+  *colno = hdr->colno;
+  *width = hdr->width;
+  *alignment = hdr->alignment;
+  *colhdr = hdr->colhdr;
+
   /* Advance the header pointer to the next entry.  */
-  uiout->table.header_next = uiout->table.header_next->next;
+  uiout->table.headers_iterator++;
+
   return 1;
 }
 
@@ -834,21 +818,26 @@ int
 ui_out_query_field (struct ui_out *uiout, int colno,
 		    int *width, int *alignment, char **col_name)
 {
-  struct ui_out_hdr *hdr;
-
   if (!uiout->table.flag)
     return 0;
 
-  for (hdr = uiout->table.header_first; hdr; hdr = hdr->next)
-    if (hdr->colno == colno)
-      {
-	*width = hdr->width;
-	*alignment = hdr->alignment;
-	*col_name = hdr->col_name;
-	return 1;
-      }
+  /* Column numbers are 1-based, so convert to 0-based index.  */
+  int index = colno - 1;
+
+  if (index >= 0 && index < uiout->table.headers.size ())
+    {
+      ui_out_hdr *hdr = uiout->table.headers[index].get ();
+
+      gdb_assert (colno == hdr->colno);
 
-  return 0;
+      *width = hdr->width;
+      *alignment = hdr->alignment;
+      *col_name = hdr->col_name;
+
+      return 1;
+    }
+  else
+    return 0;
 }
 
 /* Initialize private members at startup.  */
@@ -872,8 +861,7 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
   current->field_count = 0;
   uiout->levels.push_back (std::move (current));
 
-  uiout->table.header_first = NULL;
-  uiout->table.header_last = NULL;
-  uiout->table.header_next = NULL;
+  uiout->table.headers_iterator = uiout->table.headers.end ();
+
   return uiout;
 }
-- 
2.10.0

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

* [PATCH 14/22] Use std::string for ui_out_hdr's text fields
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (14 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 18/22] ui_out_table: Replace boolean flag with enum Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 15:32 ` [PATCH 22/22] Introduce enum_flag type for ui_out flags Simon Marchi
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch makes ui_out_hdr use std::string for its text fields.  It
makes freeing automatic when the object is deleted.

gdb/ChangeLog:

	* mi/mi-out.c (mi_table_header): Change char * args to
	std::string.
	* cli-out.c (cli_table_header): Likewise.
	* ui-out.h (table_header_ftype): Likewise.
	(ui_out_table_header): Constify colhdr argument.
	(ui_out_query_field): Constify col_name argument.
	* ui-out.c (ui_out_hdr) <col_name, colhdr>: Change type to
	std::string.
	(uo_table_header): Change char * args to std::string.
	(ui_out_table_header): Likewise.
	(get_next_header): Constify colhdr argument and adapt.
	(clear_header_list): Don't free col_name/colhdr fields.
	(append_header_to_list): Change char * args to std::string and
	adapt.
	(verify_field): Constify variable.
	(ui_out_query_field): Constify col_name argument and adapt.
	* breakpoint.c (wrap_indent_at_field): Constify variable.
---
 gdb/breakpoint.c |  2 +-
 gdb/cli-out.c    |  5 ++---
 gdb/mi/mi-out.c  | 11 +++++-----
 gdb/ui-out.c     | 64 ++++++++++++++++++++++----------------------------------
 gdb/ui-out.h     | 13 +++++++-----
 5 files changed, 42 insertions(+), 53 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 89ae6c5..4535d59 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -6062,7 +6062,7 @@ wrap_indent_at_field (struct ui_out *uiout, const char *col_name)
 {
   static char wrap_indent[80];
   int i, total_width, width, align;
-  char *text;
+  const char *text;
 
   total_width = 0;
   for (i = 1; ui_out_query_field (uiout, i, &width, &align, &text); i++)
diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index 83da5ac..9ba1d17 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -95,8 +95,7 @@ cli_table_end (struct ui_out *uiout)
 
 static void
 cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
-		  const char *col_name,
-		  const char *colhdr)
+		  const std::string &col_name, const std::string &col_hdr)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
 
@@ -105,7 +104,7 @@ cli_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
 
   /* Always go through the function pointer (virtual function call).
      We may have been extended.  */
-  uo_field_string (uiout, 0, width, alignment, 0, colhdr);
+  uo_field_string (uiout, 0, width, alignment, 0, col_hdr.c_str ());
 }
 
 /* Mark beginning of a list */
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index c89076a..72e84b2 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -42,8 +42,9 @@ static void mi_table_begin (struct ui_out *uiout, int nbrofcols,
 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 alig, const char *col_name,
-			     const char *colhdr);
+			     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,
 		      int level, const char *id);
 static void mi_end (struct ui_out *uiout, enum ui_out_type type, int level);
@@ -141,7 +142,7 @@ mi_table_end (struct ui_out *uiout)
 
 void
 mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
-		 const char *col_name, const char *colhdr)
+		 const std::string &col_name, const std::string &col_hdr)
 {
   mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
 
@@ -151,8 +152,8 @@ mi_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
   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);
-  mi_field_string (uiout, 0, width, alignment, "colhdr", colhdr);
+  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);
 }
 
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 8e44698..3cd5695 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -36,8 +36,8 @@ struct ui_out_hdr
     int colno;
     int width;
     enum ui_align alignment;
-    char *col_name;
-    char *colhdr;
+    std::string col_name;
+    std::string col_hdr;
   };
 
 struct ui_out_level
@@ -148,8 +148,9 @@ static void uo_table_begin (struct ui_out *uiout, int nbrofcols,
 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 char *col_name,
-			     const char *colhdr);
+			     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,
 		      int level, const char *id);
@@ -176,10 +177,11 @@ static int uo_redirect (struct ui_out *uiout, struct ui_file *outstream);
 /* Prototypes for local functions */
 
 static void append_header_to_list (struct ui_out *uiout, int width,
-				   enum ui_align alignment, const char *col_name,
-				   const char *colhdr);
+				   enum ui_align alignment,
+				   const std::string &col_name,
+				   const std::string &col_hdr);
 static int get_next_header (struct ui_out *uiout, int *colno, int *width,
-			    enum ui_align *alignment, char **colhdr);
+			    enum ui_align *alignment, const char **col_hdr);
 static void clear_header_list (struct ui_out *uiout);
 static void clear_table (struct ui_out *uiout);
 static void verify_field (struct ui_out *uiout, int *fldno, int *width,
@@ -247,17 +249,16 @@ ui_out_table_end (struct ui_out *uiout)
 
 void
 ui_out_table_header (struct ui_out *uiout, int width, enum ui_align alignment,
-		     const char *col_name,
-		     const char *colhdr)
+		     const std::string &col_name, const std::string &col_hdr)
 {
   if (!uiout->table.flag || uiout->table.body_flag)
     internal_error (__FILE__, __LINE__,
 		    _("table header must be specified after table_begin \
 and before table_body."));
 
-  append_header_to_list (uiout, width, alignment, col_name, colhdr);
+  append_header_to_list (uiout, width, alignment, col_name, col_hdr);
 
-  uo_table_header (uiout, width, alignment, col_name, colhdr);
+  uo_table_header (uiout, width, alignment, col_name, col_hdr);
 }
 
 static void
@@ -557,12 +558,11 @@ uo_table_end (struct ui_out *uiout)
 
 void
 uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
-		 const char *col_name,
-		 const char *colhdr)
+		 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, colhdr);
+  uiout->impl->table_header (uiout, width, align, col_name, col_hdr);
 }
 
 /* Clear the table associated with UIOUT.  */
@@ -694,12 +694,6 @@ uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
 static void
 clear_header_list (struct ui_out *uiout)
 {
-  for (auto &it : uiout->table.headers)
-    {
-      xfree (it->colhdr);
-      xfree (it->col_name);
-    }
-
   uiout->table.headers.clear ();
   uiout->table.headers_iterator = uiout->table.headers.end ();
 }
@@ -708,26 +702,18 @@ static void
 append_header_to_list (struct ui_out *uiout,
 		       int width,
 		       enum ui_align alignment,
-		       const char *col_name,
-		       const char *colhdr)
+		       const std::string &col_name,
+		       const std::string &col_hdr)
 {
   std::unique_ptr<ui_out_hdr> temphdr (new ui_out_hdr ());
 
   temphdr->width = width;
   temphdr->alignment = alignment;
-  /* We have to copy the column title as the original may be an
-     automatic.  */
-  if (colhdr != NULL)
-    temphdr->colhdr = xstrdup (colhdr);
-  else
-    temphdr->colhdr = NULL;
 
-  if (col_name != NULL)
-    temphdr->col_name = xstrdup (col_name);
-  else if (colhdr != NULL)
-    temphdr->col_name = xstrdup (colhdr);
-  else
-    temphdr->col_name = NULL;
+  /* Make our own copy of the strings, since the lifetime of the original
+     versions may be too short.  */
+  temphdr->col_hdr = col_hdr;
+  temphdr->col_name = col_name;
 
   temphdr->colno = uiout->table.headers.size () + 1;
 
@@ -742,7 +728,7 @@ get_next_header (struct ui_out *uiout,
 		 int *colno,
 		 int *width,
 		 enum ui_align *alignment,
-		 char **colhdr)
+		 const char **col_hdr)
 {
   /* There may be no headers at all or we may have used all columns.  */
   if (uiout->table.headers_iterator == uiout->table.headers.end ())
@@ -753,7 +739,7 @@ get_next_header (struct ui_out *uiout,
   *colno = hdr->colno;
   *width = hdr->width;
   *alignment = hdr->alignment;
-  *colhdr = hdr->colhdr;
+  *col_hdr = hdr->col_hdr.c_str ();
 
   /* Advance the header pointer to the next entry.  */
   uiout->table.headers_iterator++;
@@ -771,7 +757,7 @@ verify_field (struct ui_out *uiout, int *fldno, int *width,
 	      enum ui_align *align)
 {
   struct ui_out_level *current = current_level (uiout);
-  char *text;
+  const char *text;
 
   if (uiout->table.flag)
     {
@@ -816,7 +802,7 @@ ui_out_data (struct ui_out *uiout)
 /* Access table field parameters.  */
 int
 ui_out_query_field (struct ui_out *uiout, int colno,
-		    int *width, int *alignment, char **col_name)
+		    int *width, int *alignment, const char **col_name)
 {
   if (!uiout->table.flag)
     return 0;
@@ -832,7 +818,7 @@ ui_out_query_field (struct ui_out *uiout, int colno,
 
       *width = hdr->width;
       *alignment = hdr->alignment;
-      *col_name = hdr->col_name;
+      *col_name = hdr->col_name.c_str ();
 
       return 1;
     }
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index e251d77..ed2911d 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -74,8 +74,9 @@ extern void ui_out_end (struct ui_out *uiout, enum ui_out_type type);
    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 char *col_name,
-				 const char *colhdr);
+				 enum ui_align align,
+				 const std::string &col_name,
+				 const std::string &col_hdr);
 
 extern void ui_out_table_body (struct ui_out *uiout);
 
@@ -129,7 +130,8 @@ extern void ui_out_flush (struct ui_out *uiout);
 extern int ui_out_test_flags (struct ui_out *uiout, int mask);
 
 extern int ui_out_query_field (struct ui_out *uiout, int colno,
-			       int *width, int *alignment, char **col_name);
+			       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
@@ -152,8 +154,9 @@ typedef void (table_begin_ftype) (struct ui_out * uiout,
 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 char *col_name,
-				   const char *colhdr);
+				   enum ui_align align,
+				   const std::string &col_name,
+				   const std::string &col_hdr);
 /* Note: level 0 is the top-level so LEVEL is always greater than
    zero.  */
 typedef void (ui_out_begin_ftype) (struct ui_out *uiout,
-- 
2.10.0

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

* [PATCH 11/22] Use std::vector for cli_ui_out_data::streams
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (12 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 17/22] Simplify ui-out level code Simon Marchi
@ 2016-11-24 15:28 ` Simon Marchi
  2016-11-24 18:41   ` Pedro Alves
  2016-11-24 15:28 ` [PATCH 18/22] ui_out_table: Replace boolean flag with enum Simon Marchi
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Use a standard vector instead of the home-made version.  I used a vector
of plain pointers, because the cli_ui_out_data object doesn't own the
streams objects (i.e. they shouldn't be deleted when the vector is
deleted).

gdb/ChangeLog:

	* cli-out.h (cli_ui_out_data) <streams>: Change type to
	std::vector.
	* cli-out.c (cli_uiout_dtor): Update.
	(cli_field_fmt): Update.
	(cli_spaces): Update.
	(cli_text): Update.
	(cli_message): Update.
	(cli_flush): Update.
	(cli_redirect): Update.
	(out_field_fmt): Update.
	(field_separator): Update.
	(cli_out_data_ctor): Update.
	(cli_out_new): Update.
	(cli_out_set_stream): Update.
---
 gdb/cli-out.c | 31 +++++++++++++++----------------
 gdb/cli-out.h |  9 ++-------
 2 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index b98af4a..83da5ac 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -46,7 +46,6 @@ cli_uiout_dtor (struct ui_out *ui_out)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (ui_out);
 
-  VEC_free (ui_filep, data->streams);
   delete data;
 }
 
@@ -239,7 +238,7 @@ cli_field_fmt (struct ui_out *uiout, int fldno,
   if (data->suppress_output)
     return;
 
-  stream = VEC_last (ui_filep, data->streams);
+  stream = data->streams.back ();
   vfprintf_filtered (stream, format, args);
 
   if (align != ui_noalign)
@@ -255,7 +254,7 @@ cli_spaces (struct ui_out *uiout, int numspaces)
   if (data->suppress_output)
     return;
 
-  stream = VEC_last (ui_filep, data->streams);
+  stream = data->streams.back ();
   print_spaces_filtered (numspaces, stream);
 }
 
@@ -268,7 +267,7 @@ cli_text (struct ui_out *uiout, const char *string)
   if (data->suppress_output)
     return;
 
-  stream = VEC_last (ui_filep, data->streams);
+  stream = data->streams.back ();
   fputs_filtered (string, stream);
 }
 
@@ -280,7 +279,7 @@ cli_message (struct ui_out *uiout, const char *format, va_list args)
   if (data->suppress_output)
     return;
 
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  struct ui_file *stream = data->streams.back ();
   vfprintf_unfiltered (stream, format, args);
 }
 
@@ -298,7 +297,7 @@ static void
 cli_flush (struct ui_out *uiout)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  struct ui_file *stream = data->streams.back ();
 
   gdb_flush (stream);
 }
@@ -313,9 +312,9 @@ cli_redirect (struct ui_out *uiout, struct ui_file *outstream)
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
 
   if (outstream != NULL)
-    VEC_safe_push (ui_filep, data->streams, outstream);
+    data->streams.push_back (outstream);
   else
-    VEC_pop (ui_filep, data->streams);
+    data->streams.pop_back ();
 
   return 0;
 }
@@ -332,7 +331,7 @@ out_field_fmt (struct ui_out *uiout, int fldno,
 	       const char *format,...)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  struct ui_file *stream = data->streams.back ();
   va_list args;
 
   va_start (args, format);
@@ -347,7 +346,7 @@ static void
 field_separator (void)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (current_uiout);
-  struct ui_file *stream = VEC_last (ui_filep, data->streams);
+  struct ui_file *stream = data->streams.back ();
 
   fputc_filtered (' ', stream);
 }
@@ -383,8 +382,7 @@ cli_out_data_ctor (cli_out_data *self, struct ui_file *stream)
 {
   gdb_assert (stream != NULL);
 
-  self->streams = NULL;
-  VEC_safe_push (ui_filep, self->streams, stream);
+  self->streams.push_back (stream);
 
   self->suppress_output = 0;
 }
@@ -406,13 +404,14 @@ cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
   struct ui_file *old;
-  
-  old = VEC_pop (ui_filep, data->streams);
-  VEC_quick_push (ui_filep, data->streams, stream);
+
+  old = data->streams.back ();
+  data->streams.pop_back ();
+  data->streams.push_back (stream);
 
   return old;
 }
-\f
+
 /* CLI interface to display tab-completion matches.  */
 
 /* CLI version of displayer.crlf.  */
diff --git a/gdb/cli-out.h b/gdb/cli-out.h
index 55d80a7..296b8c0 100644
--- a/gdb/cli-out.h
+++ b/gdb/cli-out.h
@@ -21,19 +21,14 @@
 #define CLI_OUT_H
 
 #include "ui-out.h"
-#include "vec.h"
-
-/* Used for cli_ui_out_data->streams.  */
-
-typedef struct ui_file *ui_filep;
-DEF_VEC_P (ui_filep);
+#include <vector>
 
 /* These are exported so that they can be extended by other `ui_out'
    implementations, like TUI's.  */
 
 struct cli_ui_out_data
   {
-    VEC (ui_filep) *streams;
+    std::vector<ui_file *> streams;
     int suppress_output;
   };
 
-- 
2.10.0

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

* [PATCH 22/22] Introduce enum_flag type for ui_out flags
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (15 preceding siblings ...)
  2016-11-24 15:28 ` [PATCH 14/22] Use std::string for ui_out_hdr's text fields Simon Marchi
@ 2016-11-24 15:32 ` Simon Marchi
  2016-11-30 13:34   ` Pedro Alves
  2016-11-24 15:36 ` [PATCH 05/22] Constify wrap_here/wrap_hint code path Simon Marchi
                   ` (6 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:32 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch changes the ui_out flags to be an enum flag.

gdb/ChangeLog:

	* ui-out.c (ui_out::test_flags): Change type of parameter to
	ui_out_flags.
	(ui_out::ui_out): Likewise.
	* ui-out.h (enum ui_flags): Rename to ...
	(enum ui_out_flag): ... this.
	(ui_out_flags): Define enum flag type.
	(ui_out::ui_out): Change type of parameter to ui_out_flags.
	(ui_out::test_flags): Likewise.
	(ui_out::m_flags): Likewise.
---
 gdb/ui-out.c |  6 +++---
 gdb/ui-out.h | 10 +++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 3257f89..e262cd8 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -558,8 +558,8 @@ ui_out::redirect (ui_file *outstream)
 }
 
 /* Test the flags against the mask given.  */
-int
-ui_out::test_flags (int mask)
+ui_out_flags
+ui_out::test_flags (ui_out_flags mask)
 {
   return m_flags & mask;
 }
@@ -626,7 +626,7 @@ ui_out::query_table_field (int colno, int *width, int *alignment,
 
 /* The constructor.  */
 
-ui_out::ui_out (ui_out_impl_base *impl, int flags)
+ui_out::ui_out (ui_out_impl_base *impl, ui_out_flags flags)
 : m_impl (impl),
   m_flags (flags)
 {
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index a0d8348..ea6440e 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -45,12 +45,12 @@ enum ui_align
   };
 
 /* flags enum */
-enum ui_flags
+enum ui_out_flag
   {
-    ui_from_tty = 1,
     ui_source_list = 2
   };
 
+DEF_ENUM_FLAGS_TYPE (ui_out_flag, ui_out_flags);
 
 /* Prototypes for ui-out API.  */
 
@@ -162,7 +162,7 @@ class ui_out
 {
  public:
 
-  ui_out (ui_out_impl_base *impl, int flags = 0);
+  ui_out (ui_out_impl_base *impl, ui_out_flags flags = 0);
 
   ui_out_impl_base *impl ();
 
@@ -204,7 +204,7 @@ class ui_out
   /* Redirect the output of a ui_out object temporarily.  */
   int redirect (ui_file *outstream);
 
-  int test_flags (int mask);
+  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
@@ -221,7 +221,7 @@ class ui_out
   /* Specific implementation of ui-out.  */
   std::unique_ptr<ui_out_impl_base> m_impl;
 
-  int m_flags;
+  ui_out_flags m_flags;
 
   /* Vector to store and track the ui-out levels.  */
   std::vector<std::unique_ptr<ui_out_level>> m_levels;
-- 
2.10.0

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

* [PATCH 04/22] Fix return value of uo_redirect
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (17 preceding siblings ...)
  2016-11-24 15:36 ` [PATCH 05/22] Constify wrap_here/wrap_hint code path Simon Marchi
@ 2016-11-24 15:36 ` Simon Marchi
  2016-11-24 16:08 ` [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:36 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

The wrapper uo_redirect seems like it should return the return value
from of implementation function, since callers rely on it, but it
doesn't.

gdb/ChangeLog:

	* ui-out.c (uo_redirect): Return the return value from the
	implementation function.
---
 gdb/ui-out.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 9ac22dd..a7fdcd0 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -705,8 +705,7 @@ uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
 {
   if (!uiout->impl->redirect)
     return -1;
-  uiout->impl->redirect (uiout, outstream);
-  return 0;
+  return uiout->impl->redirect (uiout, outstream);
 }
 
 /* local functions */
-- 
2.10.0

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

* [PATCH 05/22] Constify wrap_here/wrap_hint code path
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (16 preceding siblings ...)
  2016-11-24 15:32 ` [PATCH 22/22] Introduce enum_flag type for ui_out flags Simon Marchi
@ 2016-11-24 15:36 ` Simon Marchi
  2016-11-24 15:36 ` [PATCH 04/22] Fix return value of uo_redirect Simon Marchi
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 15:36 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Constify the data path between ui_out_wrap_hint and the wrap_indent
global, because we can.  It's clearer that the argument passed to
wrap_hint is not intended to be modified by the ui_out implementation.

gdb/ChangeLog:

	* mi/mi-out.c (mi_wrap_hint): Constify argument.
	* cli-out.c (cli_wrap_hint): Likewise.
	* ui-out.c (ui_out_wrap_hint, uo_wrap_hint): Likewise.
	* ui-out.h (ui_out_wrap_hint, wrap_hint_ftype): Likewise.
	* utils.c (wrap_here): Likewise.
	(wrap_indent): Constify.
	* utils.h (wrap_here): Constify argument.
---
 gdb/cli-out.c   | 2 +-
 gdb/mi/mi-out.c | 4 ++--
 gdb/ui-out.c    | 6 +++---
 gdb/ui-out.h    | 4 ++--
 gdb/utils.c     | 4 ++--
 gdb/utils.h     | 2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index 0c982cb..d208207 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -290,7 +290,7 @@ cli_message (struct ui_out *uiout, int verbosity,
 }
 
 static void
-cli_wrap_hint (struct ui_out *uiout, char *identstring)
+cli_wrap_hint (struct ui_out *uiout, const char *identstring)
 {
   cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
 
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 0f48426..960529c 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -65,7 +65,7 @@ static void mi_text (struct ui_out *uiout, const char *string);
 static void mi_message (struct ui_out *uiout, int verbosity,
 			const char *format, va_list args)
      ATTRIBUTE_PRINTF (3, 0);
-static void mi_wrap_hint (struct ui_out *uiout, char *identstring);
+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);
 
@@ -273,7 +273,7 @@ mi_message (struct ui_out *uiout, int verbosity,
 }
 
 void
-mi_wrap_hint (struct ui_out *uiout, char *identstring)
+mi_wrap_hint (struct ui_out *uiout, const char *identstring)
 {
   wrap_here (identstring);
 }
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index a7fdcd0..840254d 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -174,7 +174,7 @@ static void uo_text (struct ui_out *uiout, const char *string);
 static void uo_message (struct ui_out *uiout, int verbosity,
 			const char *format, va_list args)
      ATTRIBUTE_PRINTF (3, 0);
-static void uo_wrap_hint (struct ui_out *uiout, char *identstring);
+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);
 
@@ -507,7 +507,7 @@ ui_out_message (struct ui_out *uiout, int verbosity,
 }
 
 void
-ui_out_wrap_hint (struct ui_out *uiout, char *identstring)
+ui_out_wrap_hint (struct ui_out *uiout, const char *identstring)
 {
   uo_wrap_hint (uiout, identstring);
 }
@@ -685,7 +685,7 @@ uo_message (struct ui_out *uiout, int verbosity,
 }
 
 void
-uo_wrap_hint (struct ui_out *uiout, char *identstring)
+uo_wrap_hint (struct ui_out *uiout, const char *identstring)
 {
   if (!uiout->impl->wrap_hint)
     return;
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index a76dfe8..1865765 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -123,7 +123,7 @@ extern void ui_out_message (struct ui_out *uiout, int verbosity,
 			    const char *format, ...)
      ATTRIBUTE_PRINTF (3, 4);
 
-extern void ui_out_wrap_hint (struct ui_out *uiout, char *identstring);
+extern void ui_out_wrap_hint (struct ui_out *uiout, const char *identstring);
 
 extern void ui_out_flush (struct ui_out *uiout);
 
@@ -186,7 +186,7 @@ typedef void (text_ftype) (struct ui_out * uiout,
 typedef void (message_ftype) (struct ui_out * uiout, int verbosity,
 			      const char *format, va_list args)
      ATTRIBUTE_FPTR_PRINTF(3,0);
-typedef void (wrap_hint_ftype) (struct ui_out * uiout, char *identstring);
+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);
diff --git a/gdb/utils.c b/gdb/utils.c
index 8ca0a2e..3a88e2a 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -1628,7 +1628,7 @@ static char *wrap_pointer;
 
 /* String to indent by if the wrap occurs.  Must not be NULL if wrap_column
    is non-zero.  */
-static char *wrap_indent;
+static const char *wrap_indent;
 
 /* Column number on the screen where wrap_buffer begins, or 0 if wrapping
    is not in effect.  */
@@ -1911,7 +1911,7 @@ reinitialize_more_filter (void)
    used to force out output from the wrap_buffer.  */
 
 void
-wrap_here (char *indent)
+wrap_here (const char *indent)
 {
   /* This should have been allocated, but be paranoid anyway.  */
   if (!wrap_buffer)
diff --git a/gdb/utils.h b/gdb/utils.h
index 62091f0..f2fb54d 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -146,7 +146,7 @@ extern int yquery (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
 
 extern void begin_line (void);
 
-extern void wrap_here (char *);
+extern void wrap_here (const char *);
 
 extern void reinitialize_more_filter (void);
 
-- 
2.10.0

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (18 preceding siblings ...)
  2016-11-24 15:36 ` [PATCH 04/22] Fix return value of uo_redirect Simon Marchi
@ 2016-11-24 16:08 ` Simon Marchi
  2016-11-24 18:46   ` Pedro Alves
  2016-11-24 18:47   ` Pedro Alves
  2016-11-24 19:11 ` [PATCH 20/22] Class-ify ui_out_table Simon Marchi
                   ` (3 subsequent siblings)
  23 siblings, 2 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 16:08 UTC (permalink / raw)
  To: gdb-patches

On 2016-11-24 10:24, Simon Marchi wrote:
> Hi all,
> 
> This patchset converts the various data structures of the ui-out 
> susbsystem to
> C++ classes.  Except when stated otherwise, the goal is to preserve the 
> same
> structure, which was already very class-like, and the same behaviour.  
> There
> are also a few cleanup patches here and there.
> 
> The patch "Class-ify ui_out" introduces many clang -Wmismatched-tags 
> warnings,
> which John aimed to fix in another series.  I am preparing a patch that 
> fixes
> them, but since it will only be boring and mechanical changes, I didn't 
> want to
> delay the submission of this series further.
> 
> The series is also available here:
> 
>   https://github.com/simark/binutils-gdb/tree/cxx-ui-out-v1
> 
> Simon

My patch "[PATCH 21/22] Class-ify ui_out" bounced, being considered 
spam... is there anything I can do about that?

Patches 19 and 20 are also missing, but I didn't receive a bounce notice 
about them, so maybe they'll come out of the void eventually.

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

* Re: [PATCH 07/22] Remove stale comments
  2016-11-24 15:24 ` [PATCH 07/22] Remove stale comments Simon Marchi
@ 2016-11-24 18:38   ` Pedro Alves
  2016-11-26 15:29     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:38 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:24 PM, Simon Marchi wrote:
> I am pretty sure that these comments aren't true anymore.

Right, the default ui_out is gone, since:

commit 23ff98d2fed4a1eaeb815e18cd4169e5aa7aaa60
Author:     Pedro Alves <palves@redhat.com>
AuthorDate: Tue Jun 21 01:11:48 2016 +0100

    Delete def_uiout

Thanks,
Pedro Alves

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

* Re: [PATCH 10/22] Use std::vector for mi_ui_out_data::streams
  2016-11-24 15:27 ` [PATCH 10/22] Use std::vector for mi_ui_out_data::streams Simon Marchi
@ 2016-11-24 18:38   ` Pedro Alves
  2016-11-26 15:48     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:38 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:26 PM, Simon Marchi wrote:

> --- a/gdb/mi/mi-out.c
> +++ b/gdb/mi/mi-out.c
> @@ -23,16 +23,14 @@
>  #include "ui-out.h"
>  #include "mi-out.h"
>  #include "vec.h"

I think this include "vec.h" can go too.

Thanks,
Pedro Alves

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

* Re: [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by vector and iterator
  2016-11-24 15:28 ` [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by vector and iterator Simon Marchi
@ 2016-11-24 18:41   ` Pedro Alves
  2016-11-26 16:13     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:41 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:27 PM, Simon Marchi wrote:
> Instead of keeping pointers to first, last and current ui_out_hdr in
> ui_out_table, we can use an std::vector and an iterator.  Direct random
> access of to vector helps make get_next_header a bit nicer by avoiding
> iterating on all the headers.  append_header_to_list is also a bit
> simpler.

Inserting into a vector invalidates iterators if it causes reallocation.
I think we're good because there's be some call to start_body
or start_row before the iterator is ever dereferenced, right?

Thanks,
Pedro Alves

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

* Re: [PATCH 11/22] Use std::vector for cli_ui_out_data::streams
  2016-11-24 15:28 ` [PATCH 11/22] Use std::vector for cli_ui_out_data::streams Simon Marchi
@ 2016-11-24 18:41   ` Pedro Alves
  2016-11-26 15:51     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:41 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:26 PM, Simon Marchi wrote:
> @@ -406,13 +404,14 @@ cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
>  {
>    cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
>    struct ui_file *old;
> -  
> -  old = VEC_pop (ui_filep, data->streams);
> -  VEC_quick_push (ui_filep, data->streams, stream);
> +
> +  old = data->streams.back ();
> +  data->streams.pop_back ();
> +  data->streams.push_back (stream);

back() returns a reference, so this pop/push can be just:

     data->streams.back () = stream;

Thanks,
Pedro Alves

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-24 15:28 ` [PATCH 16/22] Class-ify ui_out_level Simon Marchi
@ 2016-11-24 18:41   ` Pedro Alves
  2016-11-26 16:22     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:41 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:27 PM, Simon Marchi wrote:
> This patch changes struct ui_out_level to be a real C++ class.  No
> behavioral changes.
> 
> gdb/ChangeLog:
> 
> 	* ui-out.c (struct ui_out_level): Replace with ...
> 	(class ui_out_level): ... this.
> 	(current_level): Update.
> 	(push_level): Update.
> 	(pop_level): Update.
> 	(verify_field): Update.
> 	(ui_out_new): Update.
> ---
>  gdb/ui-out.c | 65 ++++++++++++++++++++++++++++++++++++++++--------------------
>  1 file changed, 44 insertions(+), 21 deletions(-)
> 
> diff --git a/gdb/ui-out.c b/gdb/ui-out.c
> index 410f40c..594338a 100644
> --- a/gdb/ui-out.c
> +++ b/gdb/ui-out.c
> @@ -90,13 +90,41 @@ class ui_out_hdr
>    std::string m_header;
>  };
>  
> -struct ui_out_level
> +/* A level of nesting (either a list or a tuple) in a ui_out output.  */
> +
> +class ui_out_level
> +{
> + public:
> +
> +  ui_out_level (ui_out_type type)

explicit ?

> +  : m_type (type),
> +    m_field_count (0)
>    {
> -    /* Count each field; the first element is for non-list fields.  */
> -    int field_count;
> -    /* The type of this level.  */
> -    enum ui_out_type type;
> -  };
> +  }
> +
> +  ui_out_type type (void) const

"(void)" is not necessary in C++ (and not very idiomatic).

I saw this in several places in the series.

> +  {
> +    return m_type;
> +  }
> +
> +  int field_count (void) const
> +  {
> +    return m_field_count;
> +  }
> +
> +  void inc_field_count (void)
> +  {
> +    m_field_count++;
> +  }

Thanks,
Pedro Alves

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

* Re: [PATCH 17/22] Simplify ui-out level code
  2016-11-24 15:28 ` [PATCH 17/22] Simplify ui-out level code Simon Marchi
@ 2016-11-24 18:42   ` Pedro Alves
  2016-11-26 16:39     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:42 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:27 PM, Simon Marchi wrote:
>  /* Discard the current level, return the discarded level's index.

"return the..." is stale.

>     TYPE is the type of the level being discarded.  */

> -static int
> +static void
>  pop_level (struct ui_out *uiout,
>  	   enum ui_out_type type)
>  {



>  specified after table_body and inside a list."));
>        /* NOTE: cagney/2001-12-08: There was a check here to ensure
> -	 that this code was only executed when uiout->level was
> +	 that this code was only executed when uiout->level () was
>  	 greater than zero.  That no longer applies - this code is run
>  	 before each table row tuple is started and at that point the
>  	 level is zero.  */

This is talking about level zero.  Should we just delete the whole
comment?

> @@ -842,7 +833,7 @@ specified after table_body and inside a list."));


> @@ -906,11 +897,9 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
>    uiout->flags = flags;
>    uiout->table.flag = 0;
>    uiout->table.body_flag = 0;
> -  uiout->level = 0;
>  
> -  /* Create uiout->level 0, the default level.  */
> -  std::unique_ptr<ui_out_level> level (new ui_out_level (ui_out_type_tuple));
> -  uiout->levels.push_back (std::move (level));
> +  /* Create uiout->level () 0, the default level.  */
> +  push_level (uiout, ui_out_type_tuple);

level 0 again?

Thanks,
Pedro Alves

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

* Re: [PATCH 18/22] ui_out_table: Replace boolean flag with enum
  2016-11-24 15:28 ` [PATCH 18/22] ui_out_table: Replace boolean flag with enum Simon Marchi
@ 2016-11-24 18:42   ` Pedro Alves
  2016-11-26 16:47     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:42 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:27 PM, Simon Marchi wrote:
> This patch is just a little cleanup, it replaces the body_flag field of
> ui_out_table with an enum.  It expresses more explicitly the
> intent of the field (check that state == TABLE_STATE_HEADERS conveys
> more what we want to do than checking for !body_flag).

Yay for avoiding the boolean trap.


> @@ -271,7 +279,7 @@ ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
>  previous table_end."));
>  
>    uiout->table.flag = 1;
> -  uiout->table.body_flag = 0;
> +  uiout->table.state = ui_out_table_state::TABLE_STATE_HEADERS;

Nit: This one stood out, as none of the other places fully qualify
the enum.

You could also consider moving the enum to within
the table class, and/and use "enum class" to shorten the
names, if you want to scope it.

Thanks,
Pedro Alves

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-11-24 16:08 ` [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
@ 2016-11-24 18:46   ` Pedro Alves
  2016-11-24 19:15     ` Simon Marchi
  2016-11-24 18:47   ` Pedro Alves
  1 sibling, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:46 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 04:07 PM, Simon Marchi wrote:
> On 2016-11-24 10:24, Simon Marchi wrote:
>> Hi all,
>>
>> This patchset converts the various data structures of the ui-out
>> susbsystem to
>> C++ classes.  Except when stated otherwise, the goal is to preserve
>> the same
>> structure, which was already very class-like, and the same behaviour. 
>> There
>> are also a few cleanup patches here and there.
>>
>> The patch "Class-ify ui_out" introduces many clang -Wmismatched-tags
>> warnings,
>> which John aimed to fix in another series.  I am preparing a patch
>> that fixes
>> them, but since it will only be boring and mechanical changes, I
>> didn't want to
>> delay the submission of this series further.
>>
>> The series is also available here:
>>
>>   https://github.com/simark/binutils-gdb/tree/cxx-ui-out-v1
>>
>> Simon
> 
> My patch "[PATCH 21/22] Class-ify ui_out" bounced, being considered
> spam... is there anything I can do about that?

Try the suggestion here: https://sourceware.org/lists.html#spam

(and then I'd suggest resending the missing ones with
with git send email --in-reply-to=)

> 
> Patches 19 and 20 are also missing, but I didn't receive a bounce notice
> about them, so maybe they'll come out of the void eventually.

Thanks,
Pedro Alves

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-11-24 16:08 ` [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
  2016-11-24 18:46   ` Pedro Alves
@ 2016-11-24 18:47   ` Pedro Alves
  2016-11-27  3:14     ` Simon Marchi
  2016-12-01  2:51     ` Simon Marchi
  1 sibling, 2 replies; 71+ messages in thread
From: Pedro Alves @ 2016-11-24 18:47 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 04:07 PM, Simon Marchi wrote:
> On 2016-11-24 10:24, Simon Marchi wrote:
>> Hi all,
>>
>> This patchset converts the various data structures of the ui-out
>> susbsystem to
>> C++ classes.  Except when stated otherwise, the goal is to preserve
>> the same
>> structure, which was already very class-like, and the same behaviour. 
>> There
>> are also a few cleanup patches here and there.
>>
>> The patch "Class-ify ui_out" introduces many clang -Wmismatched-tags
>> warnings,
>> which John aimed to fix in another series.  I am preparing a patch
>> that fixes
>> them, but since it will only be boring and mechanical changes, I
>> didn't want to
>> delay the submission of this series further.
>>
>> The series is also available here:
>>
>>   https://github.com/simark/binutils-gdb/tree/cxx-ui-out-v1
>>
>> Simon
> 
> My patch "[PATCH 21/22] Class-ify ui_out" bounced, being considered
> spam... is there anything I can do about that?
> 
> Patches 19 and 20 are also missing, but I didn't receive a bounce notice
> about them, so maybe they'll come out of the void eventually.

BTW, all other patches (I haven't looked at the missing ones)
look good to me, apart from the nits I sent.

Thanks,
Pedro Alves

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

* [PATCH 20/22] Class-ify ui_out_table
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (19 preceding siblings ...)
  2016-11-24 16:08 ` [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
@ 2016-11-24 19:11 ` Simon Marchi
  2016-11-30 12:29   ` Pedro Alves
  2016-11-24 19:19 ` [PATCH 21/22] Class-ify ui_out Simon Marchi
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 19:11 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This patch makes a class out of the ui_out_table structure, the
structure responsible for managing the generation of an UI table.

To simplify the ui_out_table object, I changed it so that it can only be
used for generating a single object.  Instead of clearing the header
list when starting a new table, we an ui_out_table when starting a
table and delete it when we're done.  Therefore, the checks:

  if (uiout->table->flag)
  if (!uiout->table->flag)

are respectively replaced with

  if (uiout->table != nullptr)
  if (uiout->table == nullptr)

Note: I removed the check at the beginning of ui_out_begin, because
there is an equivalent check at the beginning of verify_field.

gdb/ChangeLog:

	* ui-out.c (enum ui_out_table_state): Move to class
	ui_out_table.
	(struct ui_out_table): Change to ...
	(class ui_out_table): ... this.
	<flag>: Remove.
	<entry_level>: Rename to ...
	<m_entry_level>: ... this.
	<columns>: Rename to ...
	<m_nr_cols>: ... this.
	<id>: Rename to ...
	<m_id>: ... this.
	<headers>: Rename to ...
	<m_headers>: ... this.
	<headers_iterator>: Rename to ...
	<m_headers_iterator>: ... this.
	<start_body, append_header, start_row, get_next_header,
	query_field, current_state, entry_level>: New methods.
	(struct ui_out) <table>: Change type to unique_ptr to
	ui_out_table.
	(append_header_to_list, get_next_header, clear_header_list,
	clear_table): Remove.
	(ui_out_table_begin): Instantiate ui_out_table object.  Update
	table check.
	(ui_out_table_body): Update table check, replace code with call
	to ui_out_table::start_body.
	(ui_out_table_end): Update table check, replace manual cleanup
	with assignment of uiout->table unique_ptr to nullptr.
	(ui_out_table_header): Update table check, replace call to
	append_header_to_list with call to append_header method.
	(ui_out_begin): Remove one table state check, update another.
	Replace code with call to start_row method.
	(verify_field): Update table checks.
	(ui_out_query_field): Update table check, replace code with call
	to query_field method.
	(ui_out_new): Remove table initialization code.
---
 gdb/ui-out.c | 313 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 154 insertions(+), 159 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 78db2be..a943ec2 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -127,49 +127,154 @@ class ui_out_level
   int m_field_count;
 };
 
-/* States (steps) of a table generation.  */
-
-enum ui_out_table_state
-{
-  /* We are generating the table headers.  */
-  TABLE_STATE_HEADERS,
-
-  /* We are generating the table body.  */
-  TABLE_STATE_BODY,
-};
-
 /* Tables are special.  Maintain a separate structure that tracks
    their state.  At present an output can only contain a single table
    but that restriction might eventually be lifted.  */
 
-struct ui_out_table
+class ui_out_table
 {
-  /* If on, a table is being generated.  */
-  int flag;
+ public:
+
+  /* States (steps) of a table generation.  */
+
+  enum state
+  {
+    /* We are generating the table headers.  */
+    TABLE_STATE_HEADERS,
+
+    /* We are generating the table body.  */
+    TABLE_STATE_BODY,
+  };
+
+  ui_out_table (int entry_level, int nr_cols, const std::string &id)
+  : m_state (TABLE_STATE_HEADERS),
+    m_entry_level (entry_level),
+    m_nr_cols (nr_cols),
+    m_id (id)
+  {
+  }
+
+  /* Start building the body of the table.  */
+
+  void start_body ()
+  {
+    if (m_state != TABLE_STATE_HEADERS)
+      internal_error (__FILE__, __LINE__,
+		      _("extra table_body call not allowed; there must be "
+			"only one table_body after a table_begin and before a "
+			"table_end."));
+
+    /* Check if the number of defined headers matches the number of expected
+       columns.  */
+    if (m_headers.size () != m_nr_cols)
+      internal_error (__FILE__, __LINE__,
+		      _("number of headers differ from number of table "
+			"columns."));
+
+    m_state = TABLE_STATE_BODY;
+    m_headers_iterator = m_headers.begin ();
+  }
+
+  /* Add a new header to the table.  */
+
+  void append_header (int width, ui_align alignment,
+		      const std::string &col_name, const std::string &col_hdr)
+  {
+    if (m_state != TABLE_STATE_HEADERS)
+      internal_error (__FILE__, __LINE__,
+		    _("table header must be specified after table_begin and "
+		      "before table_body."));
 
-  ui_out_table_state state;
+    std::unique_ptr<ui_out_hdr> header (new ui_out_hdr (m_headers.size () + 1,
+							width, alignment,
+							col_name, col_hdr));
+
+    m_headers.push_back (std::move (header));
+  }
+
+  void start_row ()
+  {
+    m_headers_iterator = m_headers.begin ();
+  }
+
+  /* Extract the format information for the next header and advance
+     the header iterator.  Return false if there was no next header.  */
+
+  bool get_next_header (int *colno, int *width, ui_align *alignment,
+		       const char **col_hdr)
+  {
+    /* There may be no headers at all or we may have used all columns.  */
+    if (m_headers_iterator == m_headers.end ())
+      return false;
+
+    ui_out_hdr *hdr = m_headers_iterator->get ();
+
+    *colno = hdr->number ();
+    *width = hdr->min_width ();
+    *alignment = hdr->alignment ();
+    *col_hdr = hdr->header ().c_str ();
+
+    /* Advance the header pointer to the next entry.  */
+    m_headers_iterator++;
+
+    return true;
+  }
+
+  bool query_field (int colno, int *width, int *alignment,
+		    const char **col_name)
+  {
+    /* Column numbers are 1-based, so convert to 0-based index.  */
+    int index = colno - 1;
+
+    if (index >= 0 && index < m_headers.size ())
+      {
+        ui_out_hdr *hdr = m_headers[index].get ();
+
+        gdb_assert (colno == hdr->number ());
+
+        *width = hdr->min_width ();
+        *alignment = hdr->alignment ();
+        *col_name = hdr->name ().c_str ();
+
+        return true;
+      }
+    else
+      return false;
+  }
+
+  state current_state ()
+  {
+    return m_state;
+  }
+
+  int entry_level ()
+  {
+    return m_entry_level;
+  }
+
+ private:
+
+  state m_state;
 
   /* The level at which each entry of the table is to be found.  A row
      (a tuple) is made up of entries.  Consequently ENTRY_LEVEL is one
      above that of the table.  */
-  int entry_level;
+  int m_entry_level;
 
   /* Number of table columns (as specified in the table_begin call).  */
-  int columns;
+  int m_nr_cols;
 
   /* String identifying the table (as specified in the table_begin
      call).  */
-  std::string id;
+  std::string m_id;
 
   /* Pointers to the column headers.  */
-  std::vector<std::unique_ptr<ui_out_hdr>> headers;
+  std::vector<std::unique_ptr<ui_out_hdr>> m_headers;
 
   /* Iterator over the headers vector, used when printing successive fields.  */
-  std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator headers_iterator;
-
+  std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator;
 };
 
-
 /* The ui_out structure */
 
 struct ui_out
@@ -187,7 +292,7 @@ struct ui_out
     }
 
     /* A table, if any.  At present only a single table is supported.  */
-    struct ui_out_table table;
+    std::unique_ptr<ui_out_table> table;
   };
 
 /* The current (inner most) level.  */
@@ -258,14 +363,6 @@ static void uo_field_string (struct ui_out *uiout, int fldno, int width,
 
 /* Prototypes for local functions */
 
-static void append_header_to_list (struct ui_out *uiout, int width,
-				   enum ui_align alignment,
-				   const std::string &col_name,
-				   const std::string &col_hdr);
-static int get_next_header (struct ui_out *uiout, int *colno, int *width,
-			    enum ui_align *alignment, const char **col_hdr);
-static void clear_header_list (struct ui_out *uiout);
-static void clear_table (struct ui_out *uiout);
 static void verify_field (struct ui_out *uiout, int *fldno, int *width,
 			  enum ui_align *align);
 
@@ -274,44 +371,29 @@ static void verify_field (struct ui_out *uiout, int *fldno, int *width,
 /* Mark beginning of a table.  */
 
 static void
-ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
+ui_out_table_begin (struct ui_out *uiout, int nr_cols,
 		    int nr_rows, const std::string &tblid)
 {
-  if (uiout->table.flag)
+  if (uiout->table != nullptr)
     internal_error (__FILE__, __LINE__,
 		    _("tables cannot be nested; table_begin found before \
 previous table_end."));
 
-  uiout->table.flag = 1;
-  uiout->table.state = ui_out_table_state::TABLE_STATE_HEADERS;
-  uiout->table.entry_level = uiout->level () + 1;
-  uiout->table.columns = nbrofcols;
-  uiout->table.id = tblid;
-
-  clear_header_list (uiout);
+  uiout->table.reset (
+    new ui_out_table (uiout->level () + 1, nr_cols, tblid));
 
-  uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id.c_str ());
+  uo_table_begin (uiout, nr_cols, nr_rows, tblid.c_str ());
 }
 
 void
 ui_out_table_body (struct ui_out *uiout)
 {
-  if (!uiout->table.flag)
+  if (uiout->table == 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."));
 
-  if (uiout->table.state == TABLE_STATE_BODY)
-    internal_error (__FILE__, __LINE__,
-		    _("extra table_body call not allowed; there must be \
-only one table_body after a table_begin and before a table_end."));
-
-  if (uiout->table.headers.size () != uiout->table.columns)
-    internal_error (__FILE__, __LINE__,
-		    _("number of headers differ from number of table \
-columns."));
-
-  uiout->table.state = TABLE_STATE_BODY;
+  uiout->table->start_body ();
 
   uo_table_body (uiout);
 }
@@ -319,28 +401,25 @@ columns."));
 static void
 ui_out_table_end (struct ui_out *uiout)
 {
-  if (!uiout->table.flag)
+  if (uiout->table == nullptr)
     internal_error (__FILE__, __LINE__,
 		    _("misplaced table_end or missing table_begin."));
 
-  uiout->table.entry_level = 0;
-  uiout->table.state = TABLE_STATE_HEADERS;
-  uiout->table.flag = 0;
-
   uo_table_end (uiout);
-  clear_table (uiout);
+
+  uiout->table = nullptr;
 }
 
 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)
 {
-  if (!uiout->table.flag || uiout->table.state != TABLE_STATE_HEADERS)
+  if (uiout->table == nullptr)
     internal_error (__FILE__, __LINE__,
-		    _("table header must be specified after table_begin \
-and before table_body."));
+		    _("table_header outside a table is not valid; it must be "
+		      "after a table_begin and before a table_body."));
 
-  append_header_to_list (uiout, width, alignment, col_name, col_hdr);
+  uiout->table->append_header (width, alignment, col_name, col_hdr);
 
   uo_table_header (uiout, width, alignment, col_name, col_hdr);
 }
@@ -366,11 +445,6 @@ ui_out_begin (struct ui_out *uiout,
 	      enum ui_out_type type,
 	      const char *id)
 {
-  if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY)
-    internal_error (__FILE__, __LINE__,
-		    _("table header or table_body expected; lists must be \
-specified after table_body."));
-
   /* Be careful to verify the ``field'' before the new tuple/list is
      pushed onto the stack.  That way the containing list/table/row is
      verified and not the newly created tuple/list.  This verification
@@ -390,9 +464,10 @@ specified after table_body."));
 
   /* 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.state == TABLE_STATE_BODY
-      && uiout->table.entry_level == uiout->level ())
-    uiout->table.headers_iterator = uiout->table.headers.begin ();
+  if (uiout->table != nullptr
+      && uiout->table->current_state () == ui_out_table::TABLE_STATE_BODY
+      && uiout->table->entry_level () == uiout->level ())
+    uiout->table->start_row ();
 
   uo_begin (uiout, type, id);
 }
@@ -639,15 +714,6 @@ uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
   uiout->impl->table_header (width, align, col_name, col_hdr);
 }
 
-/* Clear the table associated with UIOUT.  */
-
-static void
-clear_table (struct ui_out *uiout)
-{
-  uiout->table.id.clear ();
-  clear_header_list (uiout);
-}
-
 void
 uo_begin (struct ui_out *uiout,
 	  enum ui_out_type type,
@@ -735,59 +801,6 @@ uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
   return uiout->impl->redirect (outstream);
 }
 
-/* local functions */
-
-/* List of column headers manipulation routines.  */
-
-static void
-clear_header_list (struct ui_out *uiout)
-{
-  uiout->table.headers.clear ();
-  uiout->table.headers_iterator = uiout->table.headers.end ();
-}
-
-static void
-append_header_to_list (struct ui_out *uiout,
-		       int width,
-		       enum ui_align alignment,
-		       const std::string &col_name,
-		       const std::string &col_hdr)
-{
-  std::unique_ptr<ui_out_hdr> temphdr(
-    new ui_out_hdr (uiout->table.headers.size () + 1, width,
-		    alignment, col_name, col_hdr));
-
-  uiout->table.headers.push_back (std::move (temphdr));
-}
-
-/* Extract the format information for the NEXT header and advance
-   the header pointer.  Return 0 if there was no next header.  */
-
-static int
-get_next_header (struct ui_out *uiout,
-		 int *colno,
-		 int *width,
-		 enum ui_align *alignment,
-		 const char **col_hdr)
-{
-  /* There may be no headers at all or we may have used all columns.  */
-  if (uiout->table.headers_iterator == uiout->table.headers.end ())
-    return 0;
-
-  ui_out_hdr *hdr = uiout->table.headers_iterator->get ();
-
-  *colno = hdr->number ();
-  *width = hdr->min_width ();
-  *alignment = hdr->alignment ();
-  *col_hdr = hdr->header ().c_str ();
-
-  /* Advance the header pointer to the next entry.  */
-  uiout->table.headers_iterator++;
-
-  return 1;
-}
-
-
 /* Verify that the field/tuple/list is correctly positioned.  Return
    the field number and corresponding alignment (if
    available/applicable).  */
@@ -799,7 +812,8 @@ verify_field (struct ui_out *uiout, int *fldno, int *width,
   ui_out_level *current = current_level (uiout);
   const char *text;
 
-  if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY)
+  if (uiout->table != nullptr
+      && uiout->table->current_state () != ui_out_table::TABLE_STATE_BODY)
     {
       internal_error (__FILE__, __LINE__,
 		      _("table_body missing; table fields must be \
@@ -813,9 +827,10 @@ specified after table_body and inside a list."));
 
   current->inc_field_count ();
 
-  if (uiout->table.state == TABLE_STATE_BODY
-      && uiout->table.entry_level == uiout->level ()
-      && get_next_header (uiout, fldno, width, align, &text))
+  if (uiout->table != nullptr
+      && uiout->table->current_state () == ui_out_table::TABLE_STATE_BODY
+      && uiout->table->entry_level () == uiout->level ()
+      && uiout->table->get_next_header (fldno, width, align, &text))
     {
       if (*fldno != current->field_count ())
 	internal_error (__FILE__, __LINE__,
@@ -834,26 +849,10 @@ int
 ui_out_query_field (struct ui_out *uiout, int colno,
 		    int *width, int *alignment, const char **col_name)
 {
-  if (!uiout->table.flag)
+  if (uiout->table == nullptr)
     return 0;
 
-  /* Column numbers are 1-based, so convert to 0-based index.  */
-  int index = colno - 1;
-
-  if (index >= 0 && index < uiout->table.headers.size ())
-    {
-      ui_out_hdr *hdr = uiout->table.headers[index].get ();
-
-      gdb_assert (colno == hdr->number ());
-
-      *width = hdr->min_width ();
-      *alignment = hdr->alignment ();
-      *col_name = hdr->name ().c_str ();
-
-      return 1;
-    }
-  else
-    return 0;
+  return uiout->table->query_field (colno, width, alignment, col_name);
 }
 
 /* Initialize private members at startup.  */
@@ -865,14 +864,10 @@ ui_out_new (ui_out_impl_base *impl, int flags)
 
   uiout->impl.reset (impl);
   uiout->flags = flags;
-  uiout->table.flag = 0;
-  uiout->table.state = TABLE_STATE_HEADERS;
 
   /* Create uiout->level () 0, the default level.  */
   push_level (uiout, ui_out_type_tuple);
 
-  uiout->table.headers_iterator = uiout->table.headers.end ();
-
   return uiout;
 }
 
-- 
2.10.0

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-11-24 18:46   ` Pedro Alves
@ 2016-11-24 19:15     ` Simon Marchi
  2016-11-24 20:33       ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 19:15 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:46, Pedro Alves wrote:
> Try the suggestion here: https://sourceware.org/lists.html#spam

Thanks for the reference.  Indeed I am not subscribed to the list with 
the address I am sending the patches from (even though they are 
aliases).

> (and then I'd suggest resending the missing ones with
> with git send email --in-reply-to=)

I'll do that.

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

* [PATCH 21/22] Class-ify ui_out
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (20 preceding siblings ...)
  2016-11-24 19:11 ` [PATCH 20/22] Class-ify ui_out_table Simon Marchi
@ 2016-11-24 19:19 ` Simon Marchi
  2016-11-30 12:46   ` Pedro Alves
  2016-11-26 15:20 ` [PATCH 19/22] Class-ify ui_out_impl simon.marchi
       [not found] ` <20161124153228.25177-20-simon.marchi@polymtl.ca>
  23 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 19:19 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This is the big one.  It changes struct ui_out to be a real C++ class,
and fixes the fallouts of that.

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_impl, ui_out_redirect):
	Remove, replace with a method in class ui_out.
	(ui_out_new): Remove.
	(ui_out_level): Move from ui-out.c.
	(class ui_out): New class.
	(current_level): Replace with ...
	(ui_out::current_level): ... this.
	(push_level): Replace with ...
	(ui_out::push_level): ... this.
	(pop_level): Replace with ...
	(ui_out::pop_level): ... this.
	(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_field): ... this.
	(ui_out_new): Remove, replace with ...
	(ui_out::ui_out): ... this constructor.
	(ui_out_impl): Replace with ...
	(ui_out::impl): ... this.
	(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.
	* ui-out.c (ui_out_level): Move to ui-out.h.
	(struct ui_out): Remove, replace with class ui_out.
	* cli-out.c (cli_out_new): Contruct ui_out using constructor.
	(cli_out_set_stream): Update fallouts of struct ui_out to class
	ui_out transition.
	* cli-out.h (cli_out_new): Change return type from struct
	ui_out* to ui_out*.
	* mi/mi-out.c (mi_out_new): Construct ui_out using constructor.
	(mi_version): Update fallouts of struct ui_out to class ui_out
	transition.
	(mi_out_put): Likewise.
	(mi_out_rewind): Likewise.
	* tui/tui-out.c (tui_out_new): Construct ui_out using
	constructor.
	* tui/tui.h (extern): Change return type from struct ui_out* to
	ui_out*.
	* 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               |   8 +-
 gdb/cli-out.h               |   2 +-
 gdb/cli/cli-cmds.c          |   2 +-
 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              |  37 ++-
 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             |   6 +-
 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-out.c           |   6 +-
 gdb/tui/tui.h               |   2 +-
 gdb/ui-out.c                | 499 ++++++++++---------------------------
 gdb/ui-out.h                | 188 ++++++++------
 gdb/utils.c                 |   4 +-
 57 files changed, 1509 insertions(+), 1772 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 0647a9b..082472e 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 4535d59..898ac90 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);
     }
 }
 
@@ -8141,19 +8130,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;
 }
 
@@ -8173,19 +8161,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
@@ -8259,19 +8246,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;
 }
 
@@ -8290,19 +8276,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
@@ -8456,13 +8441,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;
 }
@@ -8482,7 +8467,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);
@@ -8500,12 +8485,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
@@ -8726,19 +8710,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;
 }
@@ -8756,18 +8739,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
@@ -9027,7 +9010,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");
 }
@@ -10270,17 +10253,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;
 }
@@ -10304,7 +10287,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;
@@ -10327,12 +10310,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);
 }
@@ -10349,7 +10332,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."),
@@ -10786,64 +10769,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:
@@ -10867,19 +10848,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:
@@ -10887,9 +10868,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);
 }
 
@@ -11002,23 +10983,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:
@@ -11027,10 +11006,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;
@@ -11048,9 +11027,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
@@ -11066,15 +11045,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:
@@ -11082,9 +11061,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);
 }
 
@@ -13181,17 +13160,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;
 }
@@ -13199,7 +13178,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)
@@ -13515,17 +13494,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)
@@ -14165,26 +14144,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;
@@ -15478,9 +15456,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 ();
@@ -15771,19 +15749,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 93ca5ed..3132afa 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -281,12 +281,10 @@ cli_ui_out_impl::~cli_ui_out_impl ()
 
 /* Initialize private members at startup.  */
 
-struct ui_out *
+ui_out *
 cli_out_new (struct ui_file *stream)
 {
-  cli_ui_out_impl *impl = new cli_ui_out_impl (stream);
-
-  return ui_out_new (impl, ui_source_list);
+  return new ui_out (new cli_ui_out_impl (stream), ui_source_list);
 }
 
 ui_file *
@@ -304,7 +302,7 @@ cli_ui_out_impl::set_stream (struct ui_file *stream)
 ui_file *
 cli_out_set_stream (struct ui_out *uiout, ui_file *stream)
 {
-  cli_ui_out_impl *impl = dynamic_cast<cli_ui_out_impl *> (ui_out_impl (uiout));
+  cli_ui_out_impl *impl = dynamic_cast<cli_ui_out_impl *> (uiout->impl ());
 
   gdb_assert (impl != NULL);
 
diff --git a/gdb/cli-out.h b/gdb/cli-out.h
index aacb8c5..763c203 100644
--- a/gdb/cli-out.h
+++ b/gdb/cli-out.h
@@ -74,7 +74,7 @@ private:
     out_field_fmt (int fldno, const char *fldname, const char *format, ...);
 };
 
-extern struct ui_out *cli_out_new (struct ui_file *stream);
+extern ui_out *cli_out_new (struct ui_file *stream);
 
 extern struct ui_file *cli_out_set_stream (struct ui_out *uiout,
 					   struct ui_file *stream);
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-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 ce4d8cb..061b511 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -159,13 +159,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;
 	}
@@ -174,8 +174,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;
 	}
@@ -184,8 +184,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;
 	}
@@ -199,15 +199,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;
 	}
@@ -216,8 +216,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);
 
@@ -225,16 +225,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;
 	}
@@ -244,55 +244,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 2440c0c..8c7afee 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 0abd2c0..7e9a67c 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -566,7 +566,7 @@ print_selected_inferior (struct ui_out *uiout)
 	     (inf->pspace->pspace_exec_filename != NULL
 	      ? inf->pspace->pspace_exec_filename
 	      : _("<noexec>")));
-  ui_out_text (uiout, buf);
+  uiout->text (buf);
 }
 
 /* Prints the list of inferiors and their details on UIOUT.  This is a
@@ -594,18 +594,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;
@@ -616,35 +616,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 744b113..4280afa 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -305,13 +305,13 @@ mi_ui_out_impl::~mi_ui_out_impl ()
 
 /* Initialize private members at startup.  */
 
-struct ui_out *
+ui_out *
 mi_out_new (int mi_version)
 {
   ui_file *stream = mem_fileopen ();
   mi_ui_out_impl *impl = new mi_ui_out_impl (mi_version, stream);
 
-  return ui_out_new (impl);
+  return new ui_out (impl);
 }
 
 /* Helper to return the implementation behind UIOUT, casted to a
@@ -321,7 +321,7 @@ mi_out_new (int mi_version)
 static mi_ui_out_impl *
 mi_ui_out_impl_from (ui_out *uiout)
 {
-  mi_ui_out_impl *impl = dynamic_cast<mi_ui_out_impl *> (ui_out_impl (uiout));
+  mi_ui_out_impl *impl = dynamic_cast<mi_ui_out_impl *> (uiout->impl ());
 
   gdb_assert (impl != NULL);
 
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 db370e9..2048eb6 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);
 }
 \f
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 7435380..c7e8799 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-out.c b/gdb/tui/tui-out.c
index 70633f3..3c426b6 100644
--- a/gdb/tui/tui-out.c
+++ b/gdb/tui/tui-out.c
@@ -136,10 +136,8 @@ tui_ui_out_impl::tui_ui_out_impl (ui_file *stream)
 {
 }
 
-struct ui_out *
+ui_out *
 tui_out_new (struct ui_file *stream)
 {
-  tui_ui_out_impl *impl = new tui_ui_out_impl (stream);
-
-  return ui_out_new (impl, 0);
+  return new ui_out (new tui_ui_out_impl (stream));
 }
diff --git a/gdb/tui/tui.h b/gdb/tui/tui.h
index 5d56df0..5f55e19 100644
--- a/gdb/tui/tui.h
+++ b/gdb/tui/tui.h
@@ -93,7 +93,7 @@ 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);
+extern 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 a943ec2..3257f89 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -91,42 +91,6 @@ class ui_out_hdr
   std::string m_header;
 };
 
-/* A level of nesting (either a list or a tuple) in a ui_out output.  */
-
-class ui_out_level
-{
- public:
-
-  ui_out_level (ui_out_type type)
-  : m_type (type),
-    m_field_count (0)
-  {
-  }
-
-  ui_out_type type (void) const
-  {
-    return m_type;
-  }
-
-  int field_count (void) const
-  {
-    return m_field_count;
-  }
-
-  void inc_field_count (void)
-  {
-    m_field_count++;
-  }
-
- private:
-
-  /* The type of this level.  */
-  ui_out_type m_type;
-
-  /* Count each field; the first element is for non-list fields.  */
-  int m_field_count;
-};
-
 /* Tables are special.  Maintain a separate structure that tracks
    their state.  At present an output can only contain a single table
    but that restriction might eventually be lifted.  */
@@ -275,175 +239,113 @@ class ui_out_table
   std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator;
 };
 
-/* The ui_out structure */
-
-struct ui_out
-  {
-    int flags;
-    /* Specific implementation of ui-out.  */
-    std::unique_ptr<ui_out_impl_base> impl;
-
-    /* Vector to store and track the ui-out levels.  */
-    std::vector<std::unique_ptr<ui_out_level>> levels;
-
-    int level (void) 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.  Return the new level's index.  */
-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, return the discarded level's index.
    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);
-static void uo_field_string (struct ui_out *uiout, int fldno, int width,
-			     enum ui_align align, const char *fldname,
-			     const char *string);
-
-
-/* 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 ());
+  m_impl->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);
+  m_impl->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;
+  m_impl->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);
+  m_impl->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
@@ -455,30 +357,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::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::TABLE_STATE_BODY
+      && m_table_up->entry_level () == level ())
+    m_table_up->start_row ();
 
-  uo_begin (uiout, type, id);
+  m_impl->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);
+  m_impl->end (type);
 }
 
 struct ui_out_end_cleanup_data
@@ -493,7 +394,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);
 }
 
@@ -513,7 +414,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);
 }
 
@@ -521,299 +422,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);
+  m_impl->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);
+  m_impl->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);
+  m_impl->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);
+  m_impl->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);
+  m_impl->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);
+  m_impl->spaces (numspaces);
 }
 
 void
-ui_out_text (struct ui_out *uiout,
-	     const char *string)
+ui_out::text (const char *string)
 {
-  uo_text (uiout, string);
+  m_impl->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);
+  m_impl->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);
+  m_impl->wrap_hint (identstring);
 }
 
 void
-ui_out_flush (struct ui_out *uiout)
+ui_out::flush ()
 {
-  uo_flush (uiout);
+  m_impl->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 m_impl->redirect (outstream);
 }
 
 /* Test the flags against the mask given.  */
 int
-ui_out_test_flags (struct ui_out *uiout, int mask)
-{
-  return (uiout->flags & mask);
-}
-
-int
-ui_out_is_mi_like_p (struct ui_out *uiout)
-{
-  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)
-{
-  uiout->impl->table_begin (nbrofcols, nr_rows, tblid);
-}
-
-void
-uo_table_body (struct ui_out *uiout)
+ui_out::test_flags (int mask)
 {
-  uiout->impl->table_body ();
-}
-
-void
-uo_table_end (struct ui_out *uiout)
-{
-  uiout->impl->table_end ();
-}
-
-void
-uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
-		 const std::string &col_name, const std::string &col_hdr)
-{
-  uiout->impl->table_header (width, align, col_name, col_hdr);
-}
-
-void
-uo_begin (struct ui_out *uiout,
-	  enum ui_out_type type,
-	  const char *id)
-{
-  uiout->impl->begin (type, id);
-}
-
-void
-uo_end (struct ui_out *uiout,
-	enum ui_out_type type)
-{
-  uiout->impl->end (type);
-}
-
-void
-uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-	      const char *fldname,
-	      int value)
-{
-  uiout->impl->field_int (fldno, width, align, fldname, value);
-}
-
-void
-uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align,
-	       const char *fldname)
-{
-  uiout->impl->field_skip (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)
-{
-  uiout->impl->field_string (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)
-{
-  uiout->impl->field_fmt (fldno, width, align, fldname, format, args);
-}
-
-void
-uo_spaces (struct ui_out *uiout, int numspaces)
-{
-  uiout->impl->spaces (numspaces);
-}
-
-void
-uo_text (struct ui_out *uiout,
-	 const char *string)
-{
-  uiout->impl->text (string);
-}
-
-void
-uo_message (struct ui_out *uiout,
-	    const char *format,
-	    va_list args)
-{
-  uiout->impl->message (format, args);
-}
-
-void
-uo_wrap_hint (struct ui_out *uiout, const char *identstring)
-{
-  uiout->impl->wrap_hint (identstring);
-}
-
-void
-uo_flush (struct ui_out *uiout)
-{
-  uiout->impl->flush ();
+  return m_flags & mask;
 }
 
 int
-uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
+ui_out::is_mi_like_p ()
 {
-  return uiout->impl->redirect (outstream);
+  return m_impl->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::TABLE_STATE_BODY)
+  if (m_table_up != nullptr
+      && m_table_up->current_state () != ui_out_table::TABLE_STATE_BODY)
     {
       internal_error (__FILE__, __LINE__,
 		      _("table_body missing; table fields must be \
@@ -827,10 +595,10 @@ specified after table_body and inside a list."));
 
   current->inc_field_count ();
 
-  if (uiout->table != nullptr
-      && uiout->table->current_state () == ui_out_table::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::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__,
@@ -845,34 +613,29 @@ specified after table_body and inside a list."));
 }
 
 /* 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 (ui_out_impl_base *impl, int flags)
+ui_out::ui_out (ui_out_impl_base *impl, int flags)
+: m_impl (impl),
+  m_flags (flags)
 {
-  struct ui_out *uiout = new ui_out ();
-
-  uiout->impl.reset (impl);
-  uiout->flags = flags;
-
-  /* Create uiout->level () 0, the default level.  */
-  push_level (uiout, ui_out_type_tuple);
-
-  return uiout;
+  /* Create level 0, the default level.  */
+  push_level (ui_out_type_tuple);
 }
 
 ui_out_impl_base *
-ui_out_impl (ui_out *uiout)
+ui_out::impl ()
 {
-  return uiout->impl.get ();
+  return m_impl.get ();
 }
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index 17c502e..a0d8348 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -23,9 +23,9 @@
 #ifndef UI_OUT_H
 #define UI_OUT_H 1
 
-/* The ui_out structure */
+#include <vector>
 
-struct ui_out;
+class ui_out_table;
 struct ui_file;
 
 /* the current ui_out */
@@ -63,23 +63,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,
@@ -92,54 +75,6 @@ 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, int 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);
-
 /* Base of all ui-out implementations.  */
 
 class ui_out_impl_base
@@ -181,14 +116,123 @@ class ui_out_impl_base
   { return 0; }
 };
 
-ui_out_impl_base *ui_out_impl (ui_out *uiout);
+/* A level of nesting (either a list or a tuple) in a ui_out output.  */
 
-/* Create a ui_out object */
+class ui_out_level
+{
+ public:
 
-extern ui_out *ui_out_new (ui_out_impl_base *impl, int flags = 0);
+  ui_out_level (ui_out_type type)
+  : m_field_count (0),
+    m_type (type)
+  {
+  }
+
+  ui_out_type
+  type (void) const
+  {
+    return m_type;
+  }
+
+  int
+  field_count (void) const
+  {
+    return m_field_count;
+  }
+
+  void
+  inc_field_count (void)
+  {
+    m_field_count++;
+  }
 
-/* Redirect the ouptut of a ui_out object temporarily.  */
+ private:
 
-extern int ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream);
+  /* Count each field; the first element is for non-list fields.  */
+  int m_field_count;
+
+  /* The type of this level.  */
+  ui_out_type m_type;
+};
+
+
+/* The ui_out structure */
+
+class ui_out
+{
+ public:
+
+  ui_out (ui_out_impl_base *impl, int flags = 0);
+
+  ui_out_impl_base *impl ();
+
+  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);
+
+  int test_flags (int 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);
+
+ private:
+
+  /* Specific implementation of ui-out.  */
+  std::unique_ptr<ui_out_impl_base> m_impl;
+
+  int 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 (void) 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;
-- 
2.10.2

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-11-24 19:15     ` Simon Marchi
@ 2016-11-24 20:33       ` Simon Marchi
  0 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-24 20:33 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 14:15, Simon Marchi wrote:
> On 2016-11-24 13:46, Pedro Alves wrote:
>> Try the suggestion here: https://sourceware.org/lists.html#spam
> 
> Thanks for the reference.  Indeed I am not subscribed to the list with
> the address I am sending the patches from (even though they are
> aliases).
> 
>> (and then I'd suggest resending the missing ones with
>> with git send email --in-reply-to=)
> 
> I'll do that.

Ok, so 20/22 and 21/22 went through, but not 19/22.  I've tried 
re-sending it using my work address.  I receive the direct copy in a 
timely fashion, but it still doesn't appear on the mailing list and I 
don't receive any bounce...

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

* [PATCH 19/22] Class-ify ui_out_impl
  2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
                   ` (21 preceding siblings ...)
  2016-11-24 19:19 ` [PATCH 21/22] Class-ify ui_out Simon Marchi
@ 2016-11-26 15:20 ` simon.marchi
  2016-11-30 13:09   ` Pedro Alves
       [not found] ` <20161124153228.25177-20-simon.marchi@polymtl.ca>
  23 siblings, 1 reply; 71+ messages in thread
From: simon.marchi @ 2016-11-26 15:20 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This patch makes the ui_out_impl implementations an actual class
hierarchy, instead of an array of function pointers.

gdb/ChangeLog:

	* ui-out.h (class ui_out_impl_base): New class, based on now removed
	struct ui_out_impl.
	(table_begin_ftype): Remove, replace with pure virtual method in
	class ui_out_impl_base.
	(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.
	(ui_out_data): Remove.
	(ui_out_new): Change type of parameter impl, remove parameter
	data, add default value to parameter flags.
	(ui_out_impl): New function.
	(uo_field_string): Move declaration to ui-out.c.
	* ui-out.c (struct ui_out) <impl>: Change type to unique_ptr to
	ui_out_impl_base.
	<data>: Remove.
	(uo_field_string): Move declaration from ui-out.h.
	(ui_out_is_mi_like_p): Update to call virtual method.
	(uo_table_begin): Remove null check, update call to virtual
	method.
	(uo_table_body): Likewise.
	(uo_table_end): Likewise.
	(uo_table_header): Likewise.
	(uo_begin): Likewise.
	(uo_end): Likewise.
	(uo_field_int): Likewise.
	(uo_field_skip): Likewise.
	(uo_field_string): Likewise.
	(uo_field_fmt): Likewise.
	(uo_spaces): Likewise.
	(uo_text): Likewise.
	(uo_message): Likewise.
	(uo_wrap_hint): Likewise.
	(uo_flush): Likewise.
	(uo_redirect): Likewise.
	(ui_out_data): Remove.
	(ui_out_new): Change type of parameter impl, remove parameter
	data, add default value to parameter flags.  Update assignment
	to unique_ptr
	(ui_out_impl): New function.
	* cli-out.h (cli_ui_out_data): Remove, replace with class
	cli_ui_out_impl.
	(class cli_ui_out_impl): New class.
	(cli_ui_out_impl): Remove global variable.
	(cli_out_data_ctor): Remove.
	* cli-out.c (cli_out_data): Remove.
	(cli_uiout_dtor): Remove.
	(cli_table_begin): Replace with ...
	(cli_ui_out_impl::table_begin): ... this new method.
	(cli_table_body): Replace with ...
	(cli_ui_out_impl::table_body): ... this new method.
	(cli_table_end): Replace with ...
	(cli_ui_out_impl::table_end): ... this new method.
	(cli_table_header): Replace with ...
	(cli_ui_out_impl::table_header): ... this new method.
	(cli_begin): Replace with ...
	(cli_ui_out_impl::begin): ... this new method.
	(cli_end): Replace with ...
	(cli_ui_out_impl::table_end): ... this new method.
	(cli_field_int): Replace with ...
	(cli_ui_out_impl::field_int): ... this new method.
	(cli_field_skip): Replace with ...
	(cli_ui_out_impl::field_skip): ... this new method.
	(cli_field_string): Replace with ...
	(cli_ui_out_impl::field_string): ... this new method.
	(cli_field_fmt): Replace with ...
	(cli_ui_out_impl::field_fmt): ... this new method.
	(cli_spaces): Replace with ...
	(cli_ui_out_impl::spaces): ... this new method.
	(cli_text): Replace with ...
	(cli_ui_out_impl::text): ... this new method.
	(cli_message): Replace with ...
	(cli_ui_out_impl::message): ... this new method.
	(cli_wrap_hint): Replace with ...
	(cli_ui_out_impl::wrap_hint): ... this new method.
	(cli_flush): Replace with ...
	(cli_ui_out_impl::flush): ... this new method.
	(cli_redirect): Replace with ...
	(cli_ui_out_impl::redirect): ... this new method.
	(out_field_fmt): Replace with ...
	(cli_ui_out_impl::out_field_fmt): ... this new method.
	(field_separator): Replace with ...
	(cli_ui_out_impl::field_separator): ... 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): Instantiate
	(cli_field_string): Likewise.
	(cli_redirect): Likewise.
	(cli_out_data_ctor): Likewise.
	* mi/mi-out.c (UNKNOWN): Likewise.
	(mi_field_skip): Likewise.
	(mi_field_string): Likewise.
	(mi_field_fmt): Likewise.
	(mi_out_put): Likewise.
	(mi_out_data_dtor): Likewise.
	(mi_ui_out_impl_from): New function.
	* mi/mi-out.h (UNKNOWN): Likewise.
	* tui/tui-out.c (UNKNOWN): Likewise.
---
 gdb/cli-out.c     | 306 +++++++++++++++++--------------------------------
 gdb/cli-out.h     |  58 ++++++++--
 gdb/mi/mi-out.c   | 333 +++++++++++++++++++++---------------------------------
 gdb/mi/mi-out.h   |  69 ++++++++++-
 gdb/tui/tui-out.c | 158 +++++++++++---------------
 gdb/ui-out.c      |  95 +++++-----------
 gdb/ui-out.h      | 125 +++++++-------------
 7 files changed, 479 insertions(+), 665 deletions(-)

diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index e042926..93ca5ed 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -27,163 +27,107 @@
 #include "vec.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_impl::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 = 1;
   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_impl::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_impl::table_end ()
 {
-  cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
-
-  data->suppress_output = 0;
+  m_suppress_output = 0;
 }
 
 /* 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_impl::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 ());
+  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_impl::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_impl::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_impl::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);
+  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_impl::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, "");
+  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_impl::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)
@@ -210,11 +154,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 ();
@@ -222,96 +168,73 @@ 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_impl::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_impl::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_impl::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_impl::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_impl::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_impl::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_impl::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;
 }
@@ -322,66 +245,38 @@ cli_redirect (struct ui_out *uiout, struct ui_file *outstream)
    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_impl::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_impl::field_separator (void)
 {
-  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_impl.  */
 
-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_impl::cli_ui_out_impl (ui_file *stream)
+: m_suppress_output (0)
 {
   gdb_assert (stream != NULL);
 
-  self->streams.push_back (stream);
+  m_streams.push_back (stream);
+}
 
-  self->suppress_output = 0;
+cli_ui_out_impl::~cli_ui_out_impl ()
+{
 }
 
 /* Initialize private members at startup.  */
@@ -389,26 +284,33 @@ cli_out_data_ctor (cli_out_data *self, struct ui_file *stream)
 struct ui_out *
 cli_out_new (struct ui_file *stream)
 {
-  int flags = ui_source_list;
-  cli_out_data *data = new cli_out_data ();
+  cli_ui_out_impl *impl = new cli_ui_out_impl (stream);
 
-  cli_out_data_ctor (data, stream);
-  return ui_out_new (&cli_ui_out_impl, data, flags);
+  return ui_out_new (impl, ui_source_list);
 }
 
-struct ui_file *
-cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream)
+ui_file *
+cli_ui_out_impl::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.pop_back ();
-  data->streams.push_back (stream);
+  old = m_streams.back ();
+  m_streams.pop_back ();
+  m_streams.push_back (stream);
 
   return old;
 }
 
+ui_file *
+cli_out_set_stream (struct ui_out *uiout, ui_file *stream)
+{
+  cli_ui_out_impl *impl = dynamic_cast<cli_ui_out_impl *> (ui_out_impl (uiout));
+
+  gdb_assert (impl != NULL);
+
+  return impl->set_stream (stream);
+}
+
 /* CLI interface to display tab-completion matches.  */
 
 /* CLI version of displayer.crlf.  */
diff --git a/gdb/cli-out.h b/gdb/cli-out.h
index 296b8c0..aacb8c5 100644
--- a/gdb/cli-out.h
+++ b/gdb/cli-out.h
@@ -23,22 +23,58 @@
 #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_impl : public ui_out_impl_base
+{
+public:
 
-struct cli_ui_out_data
-  {
-    std::vector<ui_file *> streams;
-    int suppress_output;
-  };
+  cli_ui_out_impl (ui_file *stream);
+  virtual ~cli_ui_out_impl ();
 
-extern const struct ui_out_impl cli_ui_out_impl;
+  virtual void table_begin (int nbrofcols, int nr_rows,
+				  const char *tblid) override;
+  virtual void table_body () override;
+  virtual void table_end () override;
+  virtual void 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 begin (ui_out_type type, const char *id) override;
+  virtual void end (ui_out_type type) override;
+  virtual void field_int (int fldno, int width, ui_align align,
+			  const char *fldname, int value) override;
+  virtual void field_skip (int fldno, int width, ui_align align,
+			   const char *fldname) override;
+  virtual void field_string (int fldno, int width, ui_align align,
+			     const char *fldname, const char *string) override;
+  virtual void ATTRIBUTE_PRINTF(6,0) field_fmt (int fldno, int width,
+						ui_align align,
+						const char *fldname,
+						const char *format,
+						va_list args) override;
+  virtual void spaces (int numspaces) override;
+  virtual void text (const char *string) override;
+  virtual void ATTRIBUTE_PRINTF(2,0)
+    message (const char *format, va_list args) override;
+  virtual void wrap_hint (const char *identstring) override;
+  virtual void flush () override;
+  virtual int redirect (struct ui_file * outstream) override;
 
+  ui_file *set_stream (ui_file *stream);
 
-extern struct ui_out *cli_out_new (struct ui_file *stream);
+protected:
+
+  std::vector<ui_file *> m_streams;
+  int m_suppress_output;
+
+private:
+  void field_separator (void);
 
-extern void cli_out_data_ctor (struct cli_ui_out_data *data,
-			       struct ui_file *stream);
+  void  ATTRIBUTE_PRINTF(4, 5)
+    out_field_fmt (int fldno, const char *fldname, const char *format, ...);
+};
+
+extern struct ui_out *cli_out_new (struct ui_file *stream);
 
 extern struct ui_file *cli_out_set_stream (struct ui_out *uiout,
 					   struct ui_file *stream);
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index b7cd433..744b113 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -25,185 +25,100 @@
 #include "vec.h"
 #include <vector>
 
-struct mi_ui_out_data
-  {
-    int suppress_field_separator;
-    int suppress_output;
-    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_impl::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);
+  field_int (-1, -1, ui_left, "nr_rows", nr_rows);
+  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_impl::table_body ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
   /* 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_impl::table_end ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  data->suppress_output = 0;
-  mi_close (uiout, ui_out_type_list); /* body */
-  mi_close (uiout, ui_out_type_tuple);
+  m_suppress_output = 0;
+  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_impl::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);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  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);
+  field_int (0, 0, ui_center, "width", width);
+  field_int (0, 0, ui_center, "alignment", alignment);
+  field_string (0, 0, ui_center, "col_name", col_name.c_str ());
+  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_impl::begin (ui_out_type type, const char *id)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  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_impl::end (ui_out_type type)
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  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_impl::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);
 
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
   xsnprintf (buffer, sizeof (buffer), "%d", value);
-  mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
+  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_impl::field_skip (int fldno, int width, ui_align alignment,
+			    const char *fldname)
 {
 }
 
@@ -211,17 +126,15 @@ 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_impl::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;
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  stream = data->streams.back ();
-  field_separator (uiout);
+  ui_file *stream = m_streams.back ();
+  field_separator ();
+
   if (fldname)
     fprintf_unfiltered (stream, "%s=", fldname);
   fprintf_unfiltered (stream, "\"");
@@ -233,18 +146,16 @@ 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_impl::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;
-
-  if (data->suppress_output)
+  if (m_suppress_output)
     return;
 
-  stream = data->streams.back ();
-  field_separator (uiout);
+  ui_file *stream = m_streams.back ();
+  field_separator ();
+
   if (fldname)
     fprintf_unfiltered (stream, "%s=\"", fldname);
   else
@@ -254,125 +165,115 @@ mi_field_fmt (struct ui_out *uiout, int fldno, int width,
 }
 
 void
-mi_spaces (struct ui_out *uiout, int numspaces)
+mi_ui_out_impl::spaces (int numspaces)
 {
 }
 
 void
-mi_text (struct ui_out *uiout, const char *string)
+mi_ui_out_impl::text (const char *string)
 {
 }
 
 void
-mi_message (struct ui_out *uiout, const char *format, va_list args)
+mi_ui_out_impl::message (const char *format, va_list args)
 {
 }
 
 void
-mi_wrap_hint (struct ui_out *uiout, const char *identstring)
+mi_ui_out_impl::wrap_hint (const char *identstring)
 {
   wrap_here (identstring);
 }
 
 void
-mi_flush (struct ui_out *uiout)
+mi_ui_out_impl::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_impl::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_impl::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_impl::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_impl::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_impl::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_impl::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);
@@ -381,35 +282,25 @@ 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_impl::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_impl::mi_ui_out_impl (int mi_version, ui_file *stream)
+: m_suppress_field_separator (0),
+  m_suppress_output (0),
+  m_mi_version (mi_version)
 {
   gdb_assert (stream != NULL);
 
-  self->streams.push_back (stream);
-
-  self->suppress_field_separator = 0;
-  self->suppress_output = 0;
-  self->mi_version = mi_version;
+  m_streams.push_back (stream);
 }
 
-/* The destructor.  */
-
-static void
-mi_out_data_dtor (struct ui_out *ui_out)
+mi_ui_out_impl::~mi_ui_out_impl ()
 {
-  mi_out_data *data = (mi_out_data *) ui_out_data (ui_out);
-
-  delete data;
 }
 
 /* Initialize private members at startup.  */
@@ -417,10 +308,40 @@ mi_out_data_dtor (struct ui_out *ui_out)
 struct ui_out *
 mi_out_new (int mi_version)
 {
-  int flags = 0;
-  mi_out_data *data = new mi_out_data ();
-  struct ui_file *stream = mem_fileopen ();
+  ui_file *stream = mem_fileopen ();
+  mi_ui_out_impl *impl = new mi_ui_out_impl (mi_version, stream);
+
+  return ui_out_new (impl);
+}
+
+/* Helper to return the implementation behind UIOUT, casted to a
+   mi_ui_out_impl *.  It is an error to call this function with an ui_out that
+   is not an MI.  */
+
+static mi_ui_out_impl *
+mi_ui_out_impl_from (ui_out *uiout)
+{
+  mi_ui_out_impl *impl = dynamic_cast<mi_ui_out_impl *> (ui_out_impl (uiout));
+
+  gdb_assert (impl != NULL);
+
+  return impl;
+}
+
+int
+mi_version (ui_out *uiout)
+{
+  return mi_ui_out_impl_from (uiout)->version ();
+}
+
+void
+mi_out_put (ui_out *uiout, struct ui_file *stream)
+{
+  return mi_ui_out_impl_from (uiout)->put (stream);
+}
 
-  mi_out_data_ctor (data, mi_version, stream);
-  return ui_out_new (&mi_ui_out_impl, data, flags);
+void
+mi_out_rewind (ui_out *uiout)
+{
+  return mi_ui_out_impl_from (uiout)->rewind ();
 }
diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h
index ba18950..a45d2e3 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_impl : public ui_out_impl_base
+{
+public:
+
+  mi_ui_out_impl (int mi_version, ui_file *stream);
+  virtual ~mi_ui_out_impl ();
+
+  virtual void table_begin (int nbrofcols, int nr_rows, const char *tblid)
+    override;
+  virtual void table_body () override;
+  virtual void table_header (int width, ui_align align,
+			     const std::string &col_name,
+			     const std::string &col_hdr) override;
+  virtual void table_end () override;
+
+  /* Note: level 0 is the top-level so LEVEL is always greater than
+     zero.  */
+  virtual void begin (ui_out_type type, const char *id) override;
+  virtual void end (ui_out_type type) override;
+  virtual void field_int (int fldno, int width, ui_align align,
+			  const char *fldname, int value) override;
+  virtual void field_skip (int fldno, int width, ui_align align,
+			   const char *fldname) override;
+  virtual void field_string (int fldno, int width, ui_align align,
+			     const char *fldname, const char *string) override;
+  virtual void ATTRIBUTE_PRINTF(6,0)
+    field_fmt (int fldno, int width, ui_align align, const char *fldname,
+	       const char *format, va_list args) override;
+  virtual void spaces (int numspaces) override;
+  virtual void text (const char *string) override;
+  virtual void ATTRIBUTE_PRINTF(2,0) message (const char *format, va_list args)
+    override;
+  virtual void wrap_hint (const char *identstring) override;
+  virtual void flush () override;
+  virtual int redirect (struct ui_file * outstream) override;
+
+  virtual int is_mi_like_p () override
+  { return 1; }
+
+  /* MI-specific */
+  void rewind ();
+  void put (struct ui_file *stream);
+  /* Return the version number of the current MI.  */
+  int version ();
+
+private:
+
+  void field_separator ();
+  void open (const char *name, ui_out_type type);
+  void close (ui_out_type type);
+
+  int m_suppress_field_separator;
+  int m_suppress_output;
+  int m_mi_version;
+  std::vector<ui_file *> m_streams;
+};
+
+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/tui/tui-out.c b/gdb/tui/tui-out.c
index 4856562..70633f3 100644
--- a/gdb/tui/tui-out.c
+++ b/gdb/tui/tui-out.c
@@ -24,154 +24,122 @@
 #include "ui-out.h"
 #include "cli-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;
+class tui_ui_out_impl : public cli_ui_out_impl
+{
+public:
+
+  tui_ui_out_impl (ui_file *stream);
+
+  void field_int (int fldno, int width, ui_align align, const char *fldname,
+		  int value) override;
+  void field_string (int fldno, int width, ui_align align, const char *fldname,
+		     const char *string) override;
+  void ATTRIBUTE_PRINTF(6,0)
+    field_fmt (int fldno, int width, ui_align align, const char *fldname,
+	       const char *format, va_list args) override;
+  void text (const char *string) override;
 
-/* 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.  */
+private:
 
-static struct ui_out_impl tui_ui_out_impl;
+  int m_line;
+  int m_start_of_line;
+};
 
 /* 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_impl::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 (m_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_impl::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_impl::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 (m_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_impl::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_impl::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 (m_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_impl::field_fmt (fldno, width, align, fldname, format, args);
 }
 
-static void
-tui_text (struct ui_out *uiout, const char *string)
+void
+tui_ui_out_impl::text (const char *string)
 {
-  tui_out_data *data = (tui_out_data *) ui_out_data (uiout);
-
-  if (data->base.suppress_output)
+  if (m_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_impl::text (string);
 }
 
-struct ui_out *
-tui_out_new (struct ui_file *stream)
+tui_ui_out_impl::tui_ui_out_impl (ui_file *stream)
+: cli_ui_out_impl (stream),
+  m_line (0),
+  m_start_of_line (-1)
 {
-  int 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)
+struct 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;
+  tui_ui_out_impl *impl = new tui_ui_out_impl (stream);
+
+  return ui_out_new (impl, 0);
 }
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 1717491..78db2be 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.  */
 
@@ -175,8 +176,7 @@ struct ui_out
   {
     int flags;
     /* Specific implementation of ui-out.  */
-    const struct ui_out_impl *impl;
-    void *data;
+    std::unique_ptr<ui_out_impl_base> impl;
 
     /* Vector to store and track the ui-out levels.  */
     std::vector<std::unique_ptr<ui_out_level>> levels;
@@ -251,6 +251,10 @@ static void uo_message (struct ui_out *uiout,
 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);
+static void uo_field_string (struct ui_out *uiout, int fldno, int width,
+			     enum ui_align align, const char *fldname,
+			     const char *string);
+
 
 /* Prototypes for local functions */
 
@@ -603,7 +607,7 @@ ui_out_test_flags (struct ui_out *uiout, int mask)
 int
 ui_out_is_mi_like_p (struct ui_out *uiout)
 {
-  return uiout->impl->is_mi_like_p;
+  return uiout->impl->is_mi_like_p ();
 }
 
 /* Interface to the implementation functions.  */
@@ -613,34 +617,26 @@ 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);
+  uiout->impl->table_begin (nbrofcols, nr_rows, tblid);
 }
 
 void
 uo_table_body (struct ui_out *uiout)
 {
-  if (!uiout->impl->table_body)
-    return;
-  uiout->impl->table_body (uiout);
+  uiout->impl->table_body ();
 }
 
 void
 uo_table_end (struct ui_out *uiout)
 {
-  if (!uiout->impl->table_end)
-    return;
-  uiout->impl->table_end (uiout);
+  uiout->impl->table_end ();
 }
 
 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);
+  uiout->impl->table_header (width, align, col_name, col_hdr);
 }
 
 /* Clear the table associated with UIOUT.  */
@@ -657,18 +653,14 @@ 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);
+  uiout->impl->begin (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);
+  uiout->impl->end (type);
 }
 
 void
@@ -676,18 +668,14 @@ 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);
+  uiout->impl->field_int (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);
+  uiout->impl->field_skip (fldno, width, align, fldname);
 }
 
 void
@@ -696,9 +684,7 @@ uo_field_string (struct ui_out *uiout, int fldno, int width,
 		 const char *fldname,
 		 const char *string)
 {
-  if (!uiout->impl->field_string)
-    return;
-  uiout->impl->field_string (uiout, fldno, width, align, fldname, string);
+  uiout->impl->field_string (fldno, width, align, fldname, string);
 }
 
 void
@@ -707,26 +693,20 @@ uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align,
 	      const char *format,
 	      va_list args)
 {
-  if (!uiout->impl->field_fmt)
-    return;
-  uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args);
+  uiout->impl->field_fmt (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);
+  uiout->impl->spaces (numspaces);
 }
 
 void
 uo_text (struct ui_out *uiout,
 	 const char *string)
 {
-  if (!uiout->impl->text)
-    return;
-  uiout->impl->text (uiout, string);
+  uiout->impl->text (string);
 }
 
 void
@@ -734,33 +714,25 @@ uo_message (struct ui_out *uiout,
 	    const char *format,
 	    va_list args)
 {
-  if (!uiout->impl->message)
-    return;
-  uiout->impl->message (uiout, format, args);
+  uiout->impl->message (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);
+  uiout->impl->wrap_hint (identstring);
 }
 
 void
 uo_flush (struct ui_out *uiout)
 {
-  if (!uiout->impl->flush)
-    return;
-  uiout->impl->flush (uiout);
+  uiout->impl->flush ();
 }
 
 int
 uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
 {
-  if (!uiout->impl->redirect)
-    return -1;
-  return uiout->impl->redirect (uiout, outstream);
+  return uiout->impl->redirect (outstream);
 }
 
 /* local functions */
@@ -857,15 +829,6 @@ 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,
@@ -896,13 +859,11 @@ ui_out_query_field (struct ui_out *uiout, int colno,
 /* Initialize private members at startup.  */
 
 struct ui_out *
-ui_out_new (const struct ui_out_impl *impl, void *data,
-	    int flags)
+ui_out_new (ui_out_impl_base *impl, int flags)
 {
   struct ui_out *uiout = new ui_out ();
 
-  uiout->data = data;
-  uiout->impl = impl;
+  uiout->impl.reset (impl);
   uiout->flags = flags;
   uiout->table.flag = 0;
   uiout->table.state = TABLE_STATE_HEADERS;
@@ -914,3 +875,9 @@ ui_out_new (const struct ui_out_impl *impl, void *data,
 
   return uiout;
 }
+
+ui_out_impl_base *
+ui_out_impl (ui_out *uiout)
+{
+  return uiout->impl.get ();
+}
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index 06c05e2..17c502e 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -140,91 +140,52 @@ extern int ui_out_query_field (struct ui_out *uiout, int colno,
 
 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);
+/* Base of all ui-out implementations.  */
+
+class ui_out_impl_base
+{
+ public:
+
+  virtual ~ui_out_impl_base () {}
+
+  virtual void table_begin (int nbrofcols, int nr_rows, const char *tblid) = 0;
+  virtual void table_body () = 0;
+  virtual void table_end () = 0;
+  virtual void table_header (int width, ui_align align,
+			     const std::string &col_name,
+			     const std::string &col_hdr) = 0;
+
+  virtual void begin (ui_out_type type, const char *id) = 0;
+  virtual void end (ui_out_type type) = 0;
+  virtual void field_int (int fldno, int width, ui_align align,
+			  const char *fldname, int value) = 0;
+  virtual void field_skip (int fldno, int width, ui_align align,
+			   const char *fldname) = 0;
+  virtual void field_string (int fldno, int width, ui_align align,
+			     const char *fldname, const char *string) = 0;
+  virtual void ATTRIBUTE_PRINTF(6,0)
+    field_fmt (int fldno, int width, ui_align align, const char *fldname,
+	       const char *format, va_list args) = 0;
+  virtual void spaces (int numspaces) = 0;
+  virtual void text (const char *string) = 0;
+  virtual void ATTRIBUTE_PRINTF(2,0)
+    message (const char *format, va_list args) = 0;
+  virtual void wrap_hint (const char *identstring) = 0;
+  virtual void flush () = 0;
+  virtual int redirect (struct ui_file * outstream) = 0;
+
+  /* Set as not MI-like by default.  It is overridden in subclasses if
+     necessary.  */
+
+  virtual int is_mi_like_p ()
+  { return 0; }
+};
+
+ui_out_impl_base *ui_out_impl (ui_out *uiout);
 
 /* Create a ui_out object */
 
-extern struct ui_out *ui_out_new (const struct ui_out_impl *impl,
-				  void *data,
-				  int flags);
+extern ui_out *ui_out_new (ui_out_impl_base *impl, int flags = 0);
 
 /* Redirect the ouptut of a ui_out object temporarily.  */
 
-- 
2.8.1

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

* Re: [PATCH 07/22] Remove stale comments
  2016-11-24 18:38   ` Pedro Alves
@ 2016-11-26 15:29     ` Simon Marchi
  0 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 15:29 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:38, Pedro Alves wrote:
> On 11/24/2016 03:24 PM, Simon Marchi wrote:
>> I am pretty sure that these comments aren't true anymore.
> 
> Right, the default ui_out is gone, since:
> 
> commit 23ff98d2fed4a1eaeb815e18cd4169e5aa7aaa60
> Author:     Pedro Alves <palves@redhat.com>
> AuthorDate: Tue Jun 21 01:11:48 2016 +0100
> 
>     Delete def_uiout
> 
> Thanks,
> Pedro Alves

Thanks, I pushed it since it's pretty much isolated.

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

* Re: [PATCH 10/22] Use std::vector for mi_ui_out_data::streams
  2016-11-24 18:38   ` Pedro Alves
@ 2016-11-26 15:48     ` Simon Marchi
  0 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 15:48 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:38, Pedro Alves wrote:
> On 11/24/2016 03:26 PM, Simon Marchi wrote:
> 
>> --- a/gdb/mi/mi-out.c
>> +++ b/gdb/mi/mi-out.c
>> @@ -23,16 +23,14 @@
>>  #include "ui-out.h"
>>  #include "mi-out.h"
>>  #include "vec.h"
> 
> I think this include "vec.h" can go too.

Thanks, fixed locally.

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

* Re: [PATCH 11/22] Use std::vector for cli_ui_out_data::streams
  2016-11-24 18:41   ` Pedro Alves
@ 2016-11-26 15:51     ` Simon Marchi
  0 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 15:51 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:40, Pedro Alves wrote:
> On 11/24/2016 03:26 PM, Simon Marchi wrote:
>> @@ -406,13 +404,14 @@ cli_out_set_stream (struct ui_out *uiout, struct 
>> ui_file *stream)
>>  {
>>    cli_out_data *data = (cli_out_data *) ui_out_data (uiout);
>>    struct ui_file *old;
>> -
>> -  old = VEC_pop (ui_filep, data->streams);
>> -  VEC_quick_push (ui_filep, data->streams, stream);
>> +
>> +  old = data->streams.back ();
>> +  data->streams.pop_back ();
>> +  data->streams.push_back (stream);
> 
> back() returns a reference, so this pop/push can be just:
> 
>      data->streams.back () = stream;

Oooh thanks, fixed locally.

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

* Re: [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by  vector and iterator
  2016-11-24 18:41   ` Pedro Alves
@ 2016-11-26 16:13     ` Simon Marchi
  2016-12-01 20:22       ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 16:13 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:41, Pedro Alves wrote:
> On 11/24/2016 03:27 PM, Simon Marchi wrote:
>> Instead of keeping pointers to first, last and current ui_out_hdr in
>> ui_out_table, we can use an std::vector and an iterator.  Direct 
>> random
>> access of to vector helps make get_next_header a bit nicer by avoiding
>> iterating on all the headers.  append_header_to_list is also a bit
>> simpler.
> 
> Inserting into a vector invalidates iterators if it causes 
> reallocation.
> I think we're good because there's be some call to start_body
> or start_row before the iterator is ever dereferenced, right?
> 
> Thanks,
> Pedro Alves

start_body and start_row is the terminology introduced in a later patch, 
but you are right.  The table generation is in two phases:

1. define the headers
2. generate the body/rows

In 1, we modify the vector but don't use the iterator, whereas in 2 we 
use the iterator but don't modify the vector.  The various table state 
checks should validate that we don't try to define a new header while we 
are in phase 2, for example.

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-24 18:41   ` Pedro Alves
@ 2016-11-26 16:22     ` Simon Marchi
  2016-11-30 12:07       ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 16:22 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:41, Pedro Alves wrote:
>> -struct ui_out_level
>> +/* A level of nesting (either a list or a tuple) in a ui_out output.  
>> */
>> +
>> +class ui_out_level
>> +{
>> + public:
>> +
>> +  ui_out_level (ui_out_type type)
> 
> explicit ?

I had a discussion about this with Antoine.  Is it a good practice to 
use explicit all the time, and only omit it when there's a good reason 
why?  I initially put it on all the constructors, but decided to drop it 
after our discussion.

>> +  : m_type (type),
>> +    m_field_count (0)
>>    {
>> -    /* Count each field; the first element is for non-list fields.  
>> */
>> -    int field_count;
>> -    /* The type of this level.  */
>> -    enum ui_out_type type;
>> -  };
>> +  }
>> +
>> +  ui_out_type type (void) const
> 
> "(void)" is not necessary in C++ (and not very idiomatic).
> 
> I saw this in several places in the series.

Ok, I fixed all the instances I found.

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

* Re: [PATCH 17/22] Simplify ui-out level code
  2016-11-24 18:42   ` Pedro Alves
@ 2016-11-26 16:39     ` Simon Marchi
  2016-11-30 12:08       ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 16:39 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:42, Pedro Alves wrote:
> On 11/24/2016 03:27 PM, Simon Marchi wrote:
>>  /* Discard the current level, return the discarded level's index.
> 
> "return the..." is stale.

Indeed, both for push_level and pop_level.

>>  specified after table_body and inside a list."));
>>        /* NOTE: cagney/2001-12-08: There was a check here to ensure
>> -	 that this code was only executed when uiout->level was
>> +	 that this code was only executed when uiout->level () was
>>  	 greater than zero.  That no longer applies - this code is run
>>  	 before each table row tuple is started and at that point the
>>  	 level is zero.  */
> 
> This is talking about level zero.  Should we just delete the whole
> comment?

Yes, I think so.  I don't like this kind of comment very much, since 
they are not so relevant after some time.  After 15 years, I think we 
can assume whoever needed to see it has seen it.  I removed it locally.

>> @@ -906,11 +897,9 @@ ui_out_new (const struct ui_out_impl *impl, void 
>> *data,
>>    uiout->flags = flags;
>>    uiout->table.flag = 0;
>>    uiout->table.body_flag = 0;
>> -  uiout->level = 0;
>> 
>> -  /* Create uiout->level 0, the default level.  */
>> -  std::unique_ptr<ui_out_level> level (new ui_out_level 
>> (ui_out_type_tuple));
>> -  uiout->levels.push_back (std::move (level));
>> +  /* Create uiout->level () 0, the default level.  */
>> +  push_level (uiout, ui_out_type_tuple);
> 
> level 0 again?

Changed to:

   /* Create the ui-out level #1, the default level.  */

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

* Re: [PATCH 18/22] ui_out_table: Replace boolean flag with enum
  2016-11-24 18:42   ` Pedro Alves
@ 2016-11-26 16:47     ` Simon Marchi
  2016-11-30 12:10       ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 16:47 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:42, Pedro Alves wrote:
> On 11/24/2016 03:27 PM, Simon Marchi wrote:
>> This patch is just a little cleanup, it replaces the body_flag field 
>> of
>> ui_out_table with an enum.  It expresses more explicitly the
>> intent of the field (check that state == TABLE_STATE_HEADERS conveys
>> more what we want to do than checking for !body_flag).
> 
> Yay for avoiding the boolean trap.
> 
> 
>> @@ -271,7 +279,7 @@ ui_out_table_begin (struct ui_out *uiout, int 
>> nbrofcols,
>>  previous table_end."));
>> 
>>    uiout->table.flag = 1;
>> -  uiout->table.body_flag = 0;
>> +  uiout->table.state = ui_out_table_state::TABLE_STATE_HEADERS;
> 
> Nit: This one stood out, as none of the other places fully qualify
> the enum.
> 
> You could also consider moving the enum to within
> the table class, and/and use "enum class" to shorten the
> names, if you want to scope it.

TIL about "enum class".

In patch "Class-ify ui_out_table", I move it to the ui_out_table class.  
If that's ok with you, I'll look into making use of enum class in that 
patch.  I'll remove the "ui_out_table_state::" in this instance for 
consistency.

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

* Re: [PATCH 20/22] Class-ify ui_out_table
       [not found] ` <20161124153228.25177-20-simon.marchi@polymtl.ca>
@ 2016-11-26 17:18   ` Simon Marchi
  2016-11-30 12:30     ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-26 17:18 UTC (permalink / raw)
  To: gdb-patches

On 2016-11-24 10:32, Simon Marchi wrote:
> +  /* States (steps) of a table generation.  */
> +
> +  enum state
> +  {
> +    /* We are generating the table headers.  */
> +    TABLE_STATE_HEADERS,
> +
> +    /* We are generating the table body.  */
> +    TABLE_STATE_BODY,
> +  };

I changed the enum to:

   /* States (steps) of a table generation.  */

   enum class state
   {
     /* We are generating the table headers.  */
     HEADERS,

     /* We are generating the table body.  */
     BODY,
   };

and adjusted the references.

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-11-24 18:47   ` Pedro Alves
@ 2016-11-27  3:14     ` Simon Marchi
  2016-12-01  2:51     ` Simon Marchi
  1 sibling, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-27  3:14 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:47, Pedro Alves wrote:
> BTW, all other patches (I haven't looked at the missing ones)
> look good to me, apart from the nits I sent.

Ok, thanks.  I have pushed patches 1-6, since they are self-standing.  
I'll wait a bit for the others, I'll try to push all of them together.

I have sent the missing patch (19/22) from a third-party server (not my 
ISP's or my work's), and it seem like it got through with no problem 
this time, so all patches should be there.

Thanks,

Simon

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-26 16:22     ` Simon Marchi
@ 2016-11-30 12:07       ` Pedro Alves
  2016-11-30 12:41         ` Antoine Tremblay
  2016-11-30 20:40         ` Simon Marchi
  0 siblings, 2 replies; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 12:07 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

On 11/26/2016 04:22 PM, Simon Marchi wrote:
> On 2016-11-24 13:41, Pedro Alves wrote:
>>> -struct ui_out_level
>>> +/* A level of nesting (either a list or a tuple) in a ui_out
>>> output.  */
>>> +
>>> +class ui_out_level
>>> +{
>>> + public:
>>> +
>>> +  ui_out_level (ui_out_type type)
>>
>> explicit ?
> 
> I had a discussion about this with Antoine.  Is it a good practice to
> use explicit all the time, and only omit it when there's a good reason
> why?  

Yes, I believe so.

Let's turn the question around: why _would_ you want to support 
implicit conversion from ui_out_type to ui_out_level?
E.g, would this code make any sense?

  ui_out_level level = ui_out_type_list;
  if (level == ui_out_type_tuple)

I'd leave implicit conversions for when you're actually trying
to code a converting constructor.

> I initially put it on all the constructors, but decided to drop it
> after our discussion.

Thanks,
Pedro Alves

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

* Re: [PATCH 17/22] Simplify ui-out level code
  2016-11-26 16:39     ` Simon Marchi
@ 2016-11-30 12:08       ` Pedro Alves
  0 siblings, 0 replies; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 12:08 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

On 11/26/2016 04:39 PM, Simon Marchi wrote:
> On 2016-11-24 13:42, Pedro Alves wrote:
>> On 11/24/2016 03:27 PM, Simon Marchi wrote:
>>>  /* Discard the current level, return the discarded level's index.
>>
>> "return the..." is stale.
> 
> Indeed, both for push_level and pop_level.
> 
>>>  specified after table_body and inside a list."));
>>>        /* NOTE: cagney/2001-12-08: There was a check here to ensure
>>> -     that this code was only executed when uiout->level was
>>> +     that this code was only executed when uiout->level () was
>>>       greater than zero.  That no longer applies - this code is run
>>>       before each table row tuple is started and at that point the
>>>       level is zero.  */
>>
>> This is talking about level zero.  Should we just delete the whole
>> comment?
> 
> Yes, I think so.  I don't like this kind of comment very much, since
> they are not so relevant after some time.  After 15 years, I think we
> can assume whoever needed to see it has seen it.  I removed it locally.
> 
>>> @@ -906,11 +897,9 @@ ui_out_new (const struct ui_out_impl *impl, void
>>> *data,
>>>    uiout->flags = flags;
>>>    uiout->table.flag = 0;
>>>    uiout->table.body_flag = 0;
>>> -  uiout->level = 0;
>>>
>>> -  /* Create uiout->level 0, the default level.  */
>>> -  std::unique_ptr<ui_out_level> level (new ui_out_level
>>> (ui_out_type_tuple));
>>> -  uiout->levels.push_back (std::move (level));
>>> +  /* Create uiout->level () 0, the default level.  */
>>> +  push_level (uiout, ui_out_type_tuple);
>>
>> level 0 again?
> 
> Changed to:
> 
>   /* Create the ui-out level #1, the default level.  */

Sounds good.

Thanks,
Pedro Alves

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

* Re: [PATCH 18/22] ui_out_table: Replace boolean flag with enum
  2016-11-26 16:47     ` Simon Marchi
@ 2016-11-30 12:10       ` Pedro Alves
  0 siblings, 0 replies; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 12:10 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

On 11/26/2016 04:47 PM, Simon Marchi wrote:
> On 2016-11-24 13:42, Pedro Alves wrote:
>> On 11/24/2016 03:27 PM, Simon Marchi wrote:
>>> This patch is just a little cleanup, it replaces the body_flag field of
>>> ui_out_table with an enum.  It expresses more explicitly the
>>> intent of the field (check that state == TABLE_STATE_HEADERS conveys
>>> more what we want to do than checking for !body_flag).
>>
>> Yay for avoiding the boolean trap.
>>
>>
>>> @@ -271,7 +279,7 @@ ui_out_table_begin (struct ui_out *uiout, int
>>> nbrofcols,
>>>  previous table_end."));
>>>
>>>    uiout->table.flag = 1;
>>> -  uiout->table.body_flag = 0;
>>> +  uiout->table.state = ui_out_table_state::TABLE_STATE_HEADERS;
>>
>> Nit: This one stood out, as none of the other places fully qualify
>> the enum.
>>
>> You could also consider moving the enum to within
>> the table class, and/and use "enum class" to shorten the
>> names, if you want to scope it.
> 
> TIL about "enum class".
> 
> In patch "Class-ify ui_out_table", I move it to the ui_out_table class. 
> If that's ok with you, I'll look into making use of enum class in that
> patch.  

Ack, I'll go look at it.

> I'll remove the "ui_out_table_state::" in this instance for
> consistency.

Thanks.  This patch LGTM with that.

-- 
Pedro Alves

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

* Re: [PATCH 20/22] Class-ify ui_out_table
  2016-11-24 19:11 ` [PATCH 20/22] Class-ify ui_out_table Simon Marchi
@ 2016-11-30 12:29   ` Pedro Alves
  0 siblings, 0 replies; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 12:29 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 07:10 PM, Simon Marchi wrote:
> This patch makes a class out of the ui_out_table structure, the
> structure responsible for managing the generation of an UI table.
> 
> To simplify the ui_out_table object, I changed it so that it can only be
> used for generating a single object.  Instead of clearing the header
> list when starting a new table, we an ui_out_table when starting a
> table and delete it when we're done.  Therefore, the checks:
> 
>   if (uiout->table->flag)
>   if (!uiout->table->flag)
> 
> are respectively replaced with
> 
>   if (uiout->table != nullptr)
>   if (uiout->table == nullptr)
> 
> Note: I removed the check at the beginning of ui_out_begin, because
> there is an equivalent check at the beginning of verify_field.
> 
> gdb/ChangeLog:
> 
> 	* ui-out.c (enum ui_out_table_state): Move to class
> 	ui_out_table.
> 	(struct ui_out_table): Change to ...
> 	(class ui_out_table): ... this.
> 	<flag>: Remove.
> 	<entry_level>: Rename to ...
> 	<m_entry_level>: ... this.
> 	<columns>: Rename to ...
> 	<m_nr_cols>: ... this.
> 	<id>: Rename to ...
> 	<m_id>: ... this.
> 	<headers>: Rename to ...
> 	<m_headers>: ... this.
> 	<headers_iterator>: Rename to ...
> 	<m_headers_iterator>: ... this.
> 	<start_body, append_header, start_row, get_next_header,
> 	query_field, current_state, entry_level>: New methods.
> 	(struct ui_out) <table>: Change type to unique_ptr to
> 	ui_out_table.
> 	(append_header_to_list, get_next_header, clear_header_list,
> 	clear_table): Remove.
> 	(ui_out_table_begin): Instantiate ui_out_table object.  Update
> 	table check.
> 	(ui_out_table_body): Update table check, replace code with call
> 	to ui_out_table::start_body.
> 	(ui_out_table_end): Update table check, replace manual cleanup
> 	with assignment of uiout->table unique_ptr to nullptr.
> 	(ui_out_table_header): Update table check, replace call to
> 	append_header_to_list with call to append_header method.
> 	(ui_out_begin): Remove one table state check, update another.
> 	Replace code with call to start_row method.
> 	(verify_field): Update table checks.
> 	(ui_out_query_field): Update table check, replace code with call
> 	to query_field method.
> 	(ui_out_new): Remove table initialization code.

LGTM.

Thanks,
Pedro Alves

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

* Re: [PATCH 20/22] Class-ify ui_out_table
  2016-11-26 17:18   ` [PATCH 20/22] Class-ify ui_out_table Simon Marchi
@ 2016-11-30 12:30     ` Pedro Alves
  2016-11-30 21:48       ` [PATCH v2] " Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 12:30 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/26/2016 05:18 PM, Simon Marchi wrote:
> On 2016-11-24 10:32, Simon Marchi wrote:
>> +  /* States (steps) of a table generation.  */
>> +
>> +  enum state
>> +  {
>> +    /* We are generating the table headers.  */
>> +    TABLE_STATE_HEADERS,
>> +
>> +    /* We are generating the table body.  */
>> +    TABLE_STATE_BODY,
>> +  };
> 
> I changed the enum to:
> 
>   /* States (steps) of a table generation.  */
> 
>   enum class state
>   {
>     /* We are generating the table headers.  */
>     HEADERS,
> 
>     /* We are generating the table body.  */
>     BODY,
>   };
> 
> and adjusted the references.

I looked at your branch to see the end result, and it
looks good to me.  But please post the final result for
the archives.

Thanks,
Pedro Alves

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-30 12:07       ` Pedro Alves
@ 2016-11-30 12:41         ` Antoine Tremblay
  2016-11-30 13:27           ` Pedro Alves
  2016-11-30 20:40         ` Simon Marchi
  1 sibling, 1 reply; 71+ messages in thread
From: Antoine Tremblay @ 2016-11-30 12:41 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Simon Marchi, gdb-patches


Pedro Alves writes:

> On 11/26/2016 04:22 PM, Simon Marchi wrote:
>> On 2016-11-24 13:41, Pedro Alves wrote:
>>>> -struct ui_out_level
>>>> +/* A level of nesting (either a list or a tuple) in a ui_out
>>>> output.  */
>>>> +
>>>> +class ui_out_level
>>>> +{
>>>> + public:
>>>> +
>>>> +  ui_out_level (ui_out_type type)
>>>
>>> explicit ?
>> 
>> I had a discussion about this with Antoine.  Is it a good practice to
>> use explicit all the time, and only omit it when there's a good reason
>> why?  
>
> Yes, I believe so.
>
> Let's turn the question around: why _would_ you want to support 
> implicit conversion from ui_out_type to ui_out_level?
> E.g, would this code make any sense?
>
>   ui_out_level level = ui_out_type_list;
>   if (level == ui_out_type_tuple)
>
> I'd leave implicit conversions for when you're actually trying
> to code a converting constructor.
>
>> I initially put it on all the constructors, but decided to drop it
>> after our discussion.
>

Note that in the discussion I argued that it would be a good idea to
keep it for single argument constructors, but that I though that there
was little chance of confusion for multiple argument constructors like:

ui_out_table (int entry_level, int nr_cols, const std::string &id)

(See: https://gcc.gnu.org/codingconventions.html#Conversions)

I'm starting to think we need to document these things as the GCC coding
conventions may not be exactly what we want and reading the ML there's
more and more questions about this...

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

* Re: [PATCH 21/22] Class-ify ui_out
  2016-11-24 19:19 ` [PATCH 21/22] Class-ify ui_out Simon Marchi
@ 2016-11-30 12:46   ` Pedro Alves
  2016-11-30 21:47     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 12:46 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 07:18 PM, Simon Marchi wrote:

> -/* Create a ui_out object */
> +class ui_out_level
> +{
> + public:
>  
> -extern ui_out *ui_out_new (ui_out_impl_base *impl, int flags = 0);
> +  ui_out_level (ui_out_type type)
> +  : m_field_count (0),
> +    m_type (type)
> +  {
> +  }
> +
> +  ui_out_type
> +  type (void) const

Just a reminder: "explicit" and "(void)" in multiple places.

Otherwise LGTM.

Thanks,
Pedro Alves

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

* Re: [PATCH 19/22] Class-ify ui_out_impl
  2016-11-26 15:20 ` [PATCH 19/22] Class-ify ui_out_impl simon.marchi
@ 2016-11-30 13:09   ` Pedro Alves
  2016-11-30 22:38     ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 13:09 UTC (permalink / raw)
  To: simon.marchi, gdb-patches

On 11/26/2016 03:19 PM, simon.marchi@polymtl.ca wrote:
> From: Simon Marchi <simon.marchi@polymtl.ca>
> 
> This patch makes the ui_out_impl implementations an actual class
> hierarchy, instead of an array of function pointers.

LGTM with nits below.

> +ui_file *
> +cli_out_set_stream (struct ui_out *uiout, ui_file *stream)
> +{
> +  cli_ui_out_impl *impl = dynamic_cast<cli_ui_out_impl *> (ui_out_impl (uiout));

"dynamic_cast" is a code smell.  In this case, I think it
stems from the fact that we have separate ui_out and ui_out_impl
hierarchies.  If we had a simple hierarchy, then this function would
take a  cli_ui_out pointer as argument, or even be a
method of cli_ui_out.

Anyway, just a comment for another day.

Given the current design, this is OK.

> +
> +  gdb_assert (impl != NULL);
> +
> +  return impl->set_stream (stream);
> +}
> +
>  /* CLI interface to display tab-completion matches.  */
>  
>  /* CLI version of displayer.crlf.  */
> diff --git a/gdb/cli-out.h b/gdb/cli-out.h
> index 296b8c0..aacb8c5 100644
> --- a/gdb/cli-out.h
> +++ b/gdb/cli-out.h
> @@ -23,22 +23,58 @@
>  #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_impl : public ui_out_impl_base
> +{
> +public:
>  
> -struct cli_ui_out_data
> -  {
> -    std::vector<ui_file *> streams;
> -    int suppress_output;
> -  };
> +  cli_ui_out_impl (ui_file *stream);

explicit.

> +  virtual ~cli_ui_out_impl ();
>  
> -extern const struct ui_out_impl cli_ui_out_impl;
> +  virtual void table_begin (int nbrofcols, int nr_rows,
> +				  const char *tblid) override;
> +  virtual void table_body () override;
> +  virtual void table_end () override;
> +  virtual void 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 begin (ui_out_type type, const char *id) override;
> +  virtual void end (ui_out_type type) override;
> +  virtual void field_int (int fldno, int width, ui_align align,
> +			  const char *fldname, int value) override;
> +  virtual void field_skip (int fldno, int width, ui_align align,
> +			   const char *fldname) override;
> +  virtual void field_string (int fldno, int width, ui_align align,
> +			     const char *fldname, const char *string) override;
> +  virtual void ATTRIBUTE_PRINTF(6,0) field_fmt (int fldno, int width,
> +						ui_align align,
> +						const char *fldname,
> +						const char *format,
> +						va_list args) override;
> +  virtual void spaces (int numspaces) override;
> +  virtual void text (const char *string) override;
> +  virtual void ATTRIBUTE_PRINTF(2,0)
> +    message (const char *format, va_list args) override;
> +  virtual void wrap_hint (const char *identstring) override;
> +  virtual void flush () override;
> +  virtual int redirect (struct ui_file * outstream) override;
>  
> +  ui_file *set_stream (ui_file *stream);
>  
> -extern struct ui_out *cli_out_new (struct ui_file *stream);
> +protected:
> +
> +  std::vector<ui_file *> m_streams;
> +  int m_suppress_output;
> +
> +private:
> +  void field_separator (void);

"(void)".  Probably easier to grep the whole patch set to
find such cases and handle all of them.


> +mi_ui_out_impl::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);

FYI, it's due to names like "open" potentially conflicting
with gnulib replacing global namespace C functions with
#define open rpl_open
that I'm looking at switching to use gnulib's C++ namespace
support.  Luckily, looks like gnulib doesn't replace 
"open" currently, so you don't need to wait for that:

 $ grep -rn open | grep rpl_
 stdio.in.h:191:#   define fdopen rpl_fdopen
 stdio.in.h:264:#   define fopen rpl_fopen
 stdio.in.h:388:#   define freopen rpl_freopen
 stdio.in.h:820:#   define popen rpl_popen
 dirent.in.h:79:#   define opendir rpl_opendir
 dirent.in.h:198:#   define fdopendir rpl_fdopendir

>  void
> -mi_table_end (struct ui_out *uiout)
> +mi_ui_out_impl::table_end ()
>  {
> -  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
> -
> -  data->suppress_output = 0;
> -  mi_close (uiout, ui_out_type_list); /* body */
> -  mi_close (uiout, ui_out_type_tuple);
> +  m_suppress_output = 0;
> +  close (ui_out_type_list); /* body */
> +  close (ui_out_type_tuple);

However:

 $ grep -rn close | grep rpl_
 stdio.in.h:172:#   define fclose rpl_fclose
 dirent.in.h:131:#   define closedir rpl_closedir
 unistd.in.h:303:#   define close rpl_close


:-/

I'd like to post the gnulib namespace patch this week,
but I'm not sure I'll be able to.

> +  virtual void field_string (int fldno, int width, ui_align align,
> +			     const char *fldname, const char *string) override;
> +  virtual void ATTRIBUTE_PRINTF(6,0)
> +    field_fmt (int fldno, int width, ui_align align, const char *fldname,
> +	       const char *format, va_list args) override;

It's more usual to put the ATTRIBUTE_PRINTFs at the end of the
declaration.  Also, missing space before parens.  Something like:

  virtual void 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 spaces (int numspaces) override;
> +  virtual void text (const char *string) override;
> +  virtual void ATTRIBUTE_PRINTF(2,0) message (const char *format, va_list args)
> +    override;

Ditto.  There are other instances in the patch.  I won't point them all.

> +private:
> +
> +  void field_separator ();
> +  void open (const char *name, ui_out_type type);
> +  void close (ui_out_type type);
> +
> +  int m_suppress_field_separator;
> +  int m_suppress_output;

bool ?

> +  int m_mi_version;
> +  std::vector<ui_file *> m_streams;
> +};



> -typedef struct tui_ui_out_data tui_out_data;
> +class tui_ui_out_impl : public cli_ui_out_impl
> +{
> +public:
> +
> +  tui_ui_out_impl (ui_file *stream);

explicit.

> +
> +  void field_int (int fldno, int width, ui_align align, const char *fldname,
> +		  int value) override;
> +  void field_string (int fldno, int width, ui_align align, const char *fldname,
> +		     const char *string) override;
> +  void ATTRIBUTE_PRINTF(6,0)
> +    field_fmt (int fldno, int width, ui_align align, const char *fldname,
> +	       const char *format, va_list args) override;

attribute placement, space before parens.  

> +  void text (const char *string) override;
>  


> +  virtual int redirect (struct ui_file * outstream) = 0;
> +
> +  /* Set as not MI-like by default.  It is overridden in subclasses if
> +     necessary.  */
> +
> +  virtual int is_mi_like_p ()
> +  { return 0; }

bool ?

> +};
> +

Thanks,
Pedro Alves

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-30 12:41         ` Antoine Tremblay
@ 2016-11-30 13:27           ` Pedro Alves
  2016-11-30 13:47             ` Antoine Tremblay
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 13:27 UTC (permalink / raw)
  To: Antoine Tremblay; +Cc: Simon Marchi, gdb-patches

On 11/30/2016 12:40 PM, Antoine Tremblay wrote:

> Note that in the discussion I argued that it would be a good idea to
> keep it for single argument constructors, but that I though that there
> was little chance of confusion for multiple argument constructors like:
> 
> ui_out_table (int entry_level, int nr_cols, const std::string &id)

Yeah, unless all the arguments except the first are
defaulted, like:

ui_out_table (int entry_level, int nr_cols = 0, const std::string &id = "")

then it's effectively the same as single-argument constructor, and
allows implicit conversion from int.

There's at least one such case in the series:

  ui_out (ui_out_impl_base *impl, int flags = 0);

Maintly harmless, given the types involved, but still I'd
think it better to be explicit.

> (See: https://gcc.gnu.org/codingconventions.html#Conversions)
> 
> I'm starting to think we need to document these things as the GCC coding
> conventions may not be exactly what we want and reading the ML there's
> more and more questions about this...

In this case it looks like it's documented?

Thanks,
Pedro Alves

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

* Re: [PATCH 22/22] Introduce enum_flag type for ui_out flags
  2016-11-24 15:32 ` [PATCH 22/22] Introduce enum_flag type for ui_out flags Simon Marchi
@ 2016-11-30 13:34   ` Pedro Alves
  2016-11-30 21:32     ` Simon Marchi
  2016-12-02 22:22     ` [pushed] " Simon Marchi
  0 siblings, 2 replies; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 13:34 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 11/24/2016 03:32 PM, Simon Marchi wrote:
> This patch changes the ui_out flags to be an enum flag.

OK.

>  
>  /* flags enum */
> -enum ui_flags
> +enum ui_out_flag
>    {
> -    ui_from_tty = 1,
>      ui_source_list = 2
>    };
>  
> +DEF_ENUM_FLAGS_TYPE (ui_out_flag, ui_out_flags);

Please add an "#include common/enum-flags.h", so the file
includes what it needs instead of relying on indirect includes.

Thanks,
Pedro Alves

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-30 13:27           ` Pedro Alves
@ 2016-11-30 13:47             ` Antoine Tremblay
  2016-11-30 14:17               ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Antoine Tremblay @ 2016-11-30 13:47 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Antoine Tremblay, Simon Marchi, gdb-patches


Pedro Alves writes:

> On 11/30/2016 12:40 PM, Antoine Tremblay wrote:
>
>> Note that in the discussion I argued that it would be a good idea to
>> keep it for single argument constructors, but that I though that there
>> was little chance of confusion for multiple argument constructors like:
>> 
>> ui_out_table (int entry_level, int nr_cols, const std::string &id)
>
> Yeah, unless all the arguments except the first are
> defaulted, like:
>
> ui_out_table (int entry_level, int nr_cols = 0, const std::string &id = "")
>
> then it's effectively the same as single-argument constructor, and
> allows implicit conversion from int.
>
> There's at least one such case in the series:
>
>   ui_out (ui_out_impl_base *impl, int flags = 0);
>
> Maintly harmless, given the types involved, but still I'd
> think it better to be explicit.
>
>> (See: https://gcc.gnu.org/codingconventions.html#Conversions)
>> 
>> I'm starting to think we need to document these things as the GCC coding
>> conventions may not be exactly what we want and reading the ML there's
>> more and more questions about this...
>
> In this case it looks like it's documented?

Yes this case yes.  I was thinking of
https://sourceware.org/ml/gdb-patches/2016-11/msg00973.html

Also we allow the use of dynamic_cast while GCC doesn't...

I'm sure other things will come up ?

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-30 13:47             ` Antoine Tremblay
@ 2016-11-30 14:17               ` Pedro Alves
  2016-11-30 14:21                 ` Antoine Tremblay
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 14:17 UTC (permalink / raw)
  To: Antoine Tremblay; +Cc: Simon Marchi, gdb-patches

On 11/30/2016 01:47 PM, Antoine Tremblay wrote:
> 
> Pedro Alves writes:
> 
>> On 11/30/2016 12:40 PM, Antoine Tremblay wrote:

>> In this case it looks like it's documented?
> 
> Yes this case yes.  I was thinking of
> https://sourceware.org/ml/gdb-patches/2016-11/msg00973.html
> 

GCC does not require C++11, so it's natural their document
won't be saying anything about >= C++11 things.  Maybe they
won't mind it if we propose C++11 bits, if we want to.
(But let's leave that particular style discussion that that thread.)

> Also we allow the use of dynamic_cast while GCC doesn't...

We're already requiring exceptions, which requires (some kind of) rtti
under to hood, so allowing dynamic_cast would seem like a natural
consequence.  Not that I'd generally think that a design
relying on dynamic_cast is a sane design, TBC.

> 
> I'm sure other things will come up ?

Sure, in which case we can document them.  Here:

 https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards#C.2B-.2B--specific_coding_conventions

I had added the note about exceptions a while ago.  We can
certainly improve this while we go.

Thanks,
Pedro Alves

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-30 14:17               ` Pedro Alves
@ 2016-11-30 14:21                 ` Antoine Tremblay
  0 siblings, 0 replies; 71+ messages in thread
From: Antoine Tremblay @ 2016-11-30 14:21 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Antoine Tremblay, Simon Marchi, gdb-patches


Pedro Alves writes:

> On 11/30/2016 01:47 PM, Antoine Tremblay wrote:
>> 
>> Pedro Alves writes:
>> 
>>> On 11/30/2016 12:40 PM, Antoine Tremblay wrote:
>
>>> In this case it looks like it's documented?
>> 
>> Yes this case yes.  I was thinking of
>> https://sourceware.org/ml/gdb-patches/2016-11/msg00973.html
>> 
>
> GCC does not require C++11, so it's natural their document
> won't be saying anything about >= C++11 things.  Maybe they
> won't mind it if we propose C++11 bits, if we want to.
> (But let's leave that particular style discussion that that thread.)
>
>> Also we allow the use of dynamic_cast while GCC doesn't...
>
> We're already requiring exceptions, which requires (some kind of) rtti
> under to hood, so allowing dynamic_cast would seem like a natural
> consequence.  Not that I'd generally think that a design
> relying on dynamic_cast is a sane design, TBC.
>
>> 
>> I'm sure other things will come up ?
>
> Sure, in which case we can document them.  Here:
>
>  https://sourceware.org/gdb/wiki/Internals%20GDB-C-Coding-Standards#C.2B-.2B--specific_coding_conventions
>
> I had added the note about exceptions a while ago.  We can
> certainly improve this while we go.
>

Right, sorry like I had missed that :)

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

* Re: [PATCH 16/22] Class-ify ui_out_level
  2016-11-30 12:07       ` Pedro Alves
  2016-11-30 12:41         ` Antoine Tremblay
@ 2016-11-30 20:40         ` Simon Marchi
  1 sibling, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-30 20:40 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-30 07:06, Pedro Alves wrote:
> On 11/26/2016 04:22 PM, Simon Marchi wrote:
>> I had a discussion about this with Antoine.  Is it a good practice to
>> use explicit all the time, and only omit it when there's a good reason
>> why?
> 
> Yes, I believe so.
> 
> Let's turn the question around: why _would_ you want to support
> implicit conversion from ui_out_type to ui_out_level?
> E.g, would this code make any sense?
> 
>   ui_out_level level = ui_out_type_list;
>   if (level == ui_out_type_tuple)
> 
> I'd leave implicit conversions for when you're actually trying
> to code a converting constructor.

Ok that was my first thought as well, only omit explicit when it's a 
conscious decision to do so.  I'll go back and re-add it to my patches 
:).

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

* Re: [PATCH 22/22] Introduce enum_flag type for ui_out flags
  2016-11-30 13:34   ` Pedro Alves
@ 2016-11-30 21:32     ` Simon Marchi
  2016-12-02 22:22     ` [pushed] " Simon Marchi
  1 sibling, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-30 21:32 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-30 08:34, Pedro Alves wrote:
> On 11/24/2016 03:32 PM, Simon Marchi wrote:
>> This patch changes the ui_out flags to be an enum flag.
> 
> OK.
> 
>> 
>>  /* flags enum */
>> -enum ui_flags
>> +enum ui_out_flag
>>    {
>> -    ui_from_tty = 1,
>>      ui_source_list = 2
>>    };
>> 
>> +DEF_ENUM_FLAGS_TYPE (ui_out_flag, ui_out_flags);
> 
> Please add an "#include common/enum-flags.h", so the file
> includes what it needs instead of relying on indirect includes.

Good catch, I am not very good at remembering that.

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

* Re: [PATCH 21/22] Class-ify ui_out
  2016-11-30 12:46   ` Pedro Alves
@ 2016-11-30 21:47     ` Simon Marchi
  0 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-11-30 21:47 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Simon Marchi, gdb-patches

On 2016-11-30 07:46, Pedro Alves wrote:
> On 11/24/2016 07:18 PM, Simon Marchi wrote:
> 
>> -/* Create a ui_out object */
>> +class ui_out_level
>> +{
>> + public:
>> 
>> -extern ui_out *ui_out_new (ui_out_impl_base *impl, int flags = 0);
>> +  ui_out_level (ui_out_type type)
>> +  : m_field_count (0),
>> +    m_type (type)
>> +  {
>> +  }
>> +
>> +  ui_out_type
>> +  type (void) const
> 
> Just a reminder: "explicit" and "(void)" in multiple places.

Thanks, they are already fixed but it's good to double check.

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

* [PATCH v2] Class-ify ui_out_table
  2016-11-30 12:30     ` Pedro Alves
@ 2016-11-30 21:48       ` Simon Marchi
  2016-11-30 23:01         ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-30 21:48 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

This patch makes a class out of the ui_out_table structure, the
structure responsible for managing the generation of an UI table.

To simplify the ui_out_table object, I changed it so that it can only be
used for generating a single object.  Instead of clearing the header
list when starting a new table, we an ui_out_table when starting a
table and delete it when we're done.  Therefore, the checks:

  if (uiout->table->flag)
  if (!uiout->table->flag)

are respectively replaced with

  if (uiout->table != nullptr)
  if (uiout->table == nullptr)

Note: I removed the check at the beginning of ui_out_begin, because
there is an equivalent check at the beginning of verify_field.

New in v2: use "enum class" for ui_out_table::state and update
references.

gdb/ChangeLog:

	* ui-out.c (enum ui_out_table_state): Move to class
	ui_out_table as ui_out_table::state.
	(struct ui_out_table): Change to ...
	(class ui_out_table): ... this.
	<flag>: Remove.
	<entry_level>: Rename to ...
	<m_entry_level>: ... this.
	<columns>: Rename to ...
	<m_nr_cols>: ... this.
	<id>: Rename to ...
	<m_id>: ... this.
	<headers>: Rename to ...
	<m_headers>: ... this.
	<headers_iterator>: Rename to ...
	<m_headers_iterator>: ... this.
	<start_body, append_header, start_row, get_next_header,
	query_field, current_state, entry_level>: New methods.
	(struct ui_out) <table>: Change type to unique_ptr to
	ui_out_table.
	(append_header_to_list, get_next_header, clear_header_list,
	clear_table): Remove.
	(ui_out_table_begin): Instantiate ui_out_table object.  Update
	table check.
	(ui_out_table_body): Update table check, replace code with call
	to ui_out_table::start_body.
	(ui_out_table_end): Update table check, replace manual cleanup
	with assignment of uiout->table unique_ptr to nullptr.
	(ui_out_table_header): Update table check, replace call to
	append_header_to_list with call to append_header method.
	(ui_out_begin): Remove one table state check, update another.
	Replace code with call to start_row method.
	(verify_field): Update table checks.
	(ui_out_query_field): Update table check, replace code with call
	to query_field method.
	(ui_out_new): Remove table initialization code.
---
 gdb/ui-out.c | 313 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 154 insertions(+), 159 deletions(-)

diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 6bd5126..32cea1f 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -127,49 +127,154 @@ class ui_out_level
   int m_field_count;
 };
 
-/* States (steps) of a table generation.  */
-
-enum ui_out_table_state
-{
-  /* We are generating the table headers.  */
-  TABLE_STATE_HEADERS,
-
-  /* We are generating the table body.  */
-  TABLE_STATE_BODY,
-};
-
 /* Tables are special.  Maintain a separate structure that tracks
    their state.  At present an output can only contain a single table
    but that restriction might eventually be lifted.  */
 
-struct ui_out_table
+class ui_out_table
 {
-  /* If on, a table is being generated.  */
-  int flag;
+ public:
+
+  /* States (steps) of a table generation.  */
+
+  enum class state
+  {
+    /* We are generating the table headers.  */
+    HEADERS,
+
+    /* We are generating the table body.  */
+    BODY,
+  };
+
+  explicit ui_out_table (int entry_level, int nr_cols, const std::string &id)
+  : m_state (state::HEADERS),
+    m_entry_level (entry_level),
+    m_nr_cols (nr_cols),
+    m_id (id)
+  {
+  }
+
+  /* Start building the body of the table.  */
+
+  void start_body ()
+  {
+    if (m_state != state::HEADERS)
+      internal_error (__FILE__, __LINE__,
+		      _("extra table_body call not allowed; there must be "
+			"only one table_body after a table_begin and before a "
+			"table_end."));
+
+    /* Check if the number of defined headers matches the number of expected
+       columns.  */
+    if (m_headers.size () != m_nr_cols)
+      internal_error (__FILE__, __LINE__,
+		      _("number of headers differ from number of table "
+			"columns."));
+
+    m_state = state::BODY;
+    m_headers_iterator = m_headers.begin ();
+  }
+
+  /* Add a new header to the table.  */
+
+  void append_header (int width, ui_align alignment,
+		      const std::string &col_name, const std::string &col_hdr)
+  {
+    if (m_state != state::HEADERS)
+      internal_error (__FILE__, __LINE__,
+		    _("table header must be specified after table_begin and "
+		      "before table_body."));
 
-  ui_out_table_state state;
+    std::unique_ptr<ui_out_hdr> header (new ui_out_hdr (m_headers.size () + 1,
+							width, alignment,
+							col_name, col_hdr));
+
+    m_headers.push_back (std::move (header));
+  }
+
+  void start_row ()
+  {
+    m_headers_iterator = m_headers.begin ();
+  }
+
+  /* Extract the format information for the next header and advance
+     the header iterator.  Return false if there was no next header.  */
+
+  bool get_next_header (int *colno, int *width, ui_align *alignment,
+		       const char **col_hdr)
+  {
+    /* There may be no headers at all or we may have used all columns.  */
+    if (m_headers_iterator == m_headers.end ())
+      return false;
+
+    ui_out_hdr *hdr = m_headers_iterator->get ();
+
+    *colno = hdr->number ();
+    *width = hdr->min_width ();
+    *alignment = hdr->alignment ();
+    *col_hdr = hdr->header ().c_str ();
+
+    /* Advance the header pointer to the next entry.  */
+    m_headers_iterator++;
+
+    return true;
+  }
+
+  bool query_field (int colno, int *width, int *alignment,
+		    const char **col_name)
+  {
+    /* Column numbers are 1-based, so convert to 0-based index.  */
+    int index = colno - 1;
+
+    if (index >= 0 && index < m_headers.size ())
+      {
+        ui_out_hdr *hdr = m_headers[index].get ();
+
+        gdb_assert (colno == hdr->number ());
+
+        *width = hdr->min_width ();
+        *alignment = hdr->alignment ();
+        *col_name = hdr->name ().c_str ();
+
+        return true;
+      }
+    else
+      return false;
+  }
+
+  state current_state ()
+  {
+    return m_state;
+  }
+
+  int entry_level ()
+  {
+    return m_entry_level;
+  }
+
+ private:
+
+  state m_state;
 
   /* The level at which each entry of the table is to be found.  A row
      (a tuple) is made up of entries.  Consequently ENTRY_LEVEL is one
      above that of the table.  */
-  int entry_level;
+  int m_entry_level;
 
   /* Number of table columns (as specified in the table_begin call).  */
-  int columns;
+  int m_nr_cols;
 
   /* String identifying the table (as specified in the table_begin
      call).  */
-  std::string id;
+  std::string m_id;
 
   /* Pointers to the column headers.  */
-  std::vector<std::unique_ptr<ui_out_hdr>> headers;
+  std::vector<std::unique_ptr<ui_out_hdr>> m_headers;
 
   /* Iterator over the headers vector, used when printing successive fields.  */
-  std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator headers_iterator;
-
+  std::vector<std::unique_ptr<ui_out_hdr>>::const_iterator m_headers_iterator;
 };
 
-
 /* The ui_out structure */
 
 struct ui_out
@@ -187,7 +292,7 @@ struct ui_out
     }
 
     /* A table, if any.  At present only a single table is supported.  */
-    struct ui_out_table table;
+    std::unique_ptr<ui_out_table> table;
   };
 
 /* The current (inner most) level.  */
@@ -258,14 +363,6 @@ static void uo_field_string (struct ui_out *uiout, int fldno, int width,
 
 /* Prototypes for local functions */
 
-static void append_header_to_list (struct ui_out *uiout, int width,
-				   enum ui_align alignment,
-				   const std::string &col_name,
-				   const std::string &col_hdr);
-static int get_next_header (struct ui_out *uiout, int *colno, int *width,
-			    enum ui_align *alignment, const char **col_hdr);
-static void clear_header_list (struct ui_out *uiout);
-static void clear_table (struct ui_out *uiout);
 static void verify_field (struct ui_out *uiout, int *fldno, int *width,
 			  enum ui_align *align);
 
@@ -274,44 +371,29 @@ static void verify_field (struct ui_out *uiout, int *fldno, int *width,
 /* Mark beginning of a table.  */
 
 static void
-ui_out_table_begin (struct ui_out *uiout, int nbrofcols,
+ui_out_table_begin (struct ui_out *uiout, int nr_cols,
 		    int nr_rows, const std::string &tblid)
 {
-  if (uiout->table.flag)
+  if (uiout->table != nullptr)
     internal_error (__FILE__, __LINE__,
 		    _("tables cannot be nested; table_begin found before \
 previous table_end."));
 
-  uiout->table.flag = 1;
-  uiout->table.state = TABLE_STATE_HEADERS;
-  uiout->table.entry_level = uiout->level () + 1;
-  uiout->table.columns = nbrofcols;
-  uiout->table.id = tblid;
-
-  clear_header_list (uiout);
+  uiout->table.reset (
+    new ui_out_table (uiout->level () + 1, nr_cols, tblid));
 
-  uo_table_begin (uiout, nbrofcols, nr_rows, uiout->table.id.c_str ());
+  uo_table_begin (uiout, nr_cols, nr_rows, tblid.c_str ());
 }
 
 void
 ui_out_table_body (struct ui_out *uiout)
 {
-  if (!uiout->table.flag)
+  if (uiout->table == 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."));
 
-  if (uiout->table.state == TABLE_STATE_BODY)
-    internal_error (__FILE__, __LINE__,
-		    _("extra table_body call not allowed; there must be \
-only one table_body after a table_begin and before a table_end."));
-
-  if (uiout->table.headers.size () != uiout->table.columns)
-    internal_error (__FILE__, __LINE__,
-		    _("number of headers differ from number of table \
-columns."));
-
-  uiout->table.state = TABLE_STATE_BODY;
+  uiout->table->start_body ();
 
   uo_table_body (uiout);
 }
@@ -319,28 +401,25 @@ columns."));
 static void
 ui_out_table_end (struct ui_out *uiout)
 {
-  if (!uiout->table.flag)
+  if (uiout->table == nullptr)
     internal_error (__FILE__, __LINE__,
 		    _("misplaced table_end or missing table_begin."));
 
-  uiout->table.entry_level = 0;
-  uiout->table.state = TABLE_STATE_HEADERS;
-  uiout->table.flag = 0;
-
   uo_table_end (uiout);
-  clear_table (uiout);
+
+  uiout->table = nullptr;
 }
 
 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)
 {
-  if (!uiout->table.flag || uiout->table.state != TABLE_STATE_HEADERS)
+  if (uiout->table == nullptr)
     internal_error (__FILE__, __LINE__,
-		    _("table header must be specified after table_begin \
-and before table_body."));
+		    _("table_header outside a table is not valid; it must be "
+		      "after a table_begin and before a table_body."));
 
-  append_header_to_list (uiout, width, alignment, col_name, col_hdr);
+  uiout->table->append_header (width, alignment, col_name, col_hdr);
 
   uo_table_header (uiout, width, alignment, col_name, col_hdr);
 }
@@ -366,11 +445,6 @@ ui_out_begin (struct ui_out *uiout,
 	      enum ui_out_type type,
 	      const char *id)
 {
-  if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY)
-    internal_error (__FILE__, __LINE__,
-		    _("table header or table_body expected; lists must be \
-specified after table_body."));
-
   /* Be careful to verify the ``field'' before the new tuple/list is
      pushed onto the stack.  That way the containing list/table/row is
      verified and not the newly created tuple/list.  This verification
@@ -390,9 +464,10 @@ specified after table_body."));
 
   /* 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.state == TABLE_STATE_BODY
-      && uiout->table.entry_level == uiout->level ())
-    uiout->table.headers_iterator = uiout->table.headers.begin ();
+  if (uiout->table != nullptr
+      && uiout->table->current_state () == ui_out_table::state::BODY
+      && uiout->table->entry_level () == uiout->level ())
+    uiout->table->start_row ();
 
   uo_begin (uiout, type, id);
 }
@@ -639,15 +714,6 @@ uo_table_header (struct ui_out *uiout, int width, enum ui_align align,
   uiout->impl->table_header (width, align, col_name, col_hdr);
 }
 
-/* Clear the table associated with UIOUT.  */
-
-static void
-clear_table (struct ui_out *uiout)
-{
-  uiout->table.id.clear ();
-  clear_header_list (uiout);
-}
-
 void
 uo_begin (struct ui_out *uiout,
 	  enum ui_out_type type,
@@ -735,59 +801,6 @@ uo_redirect (struct ui_out *uiout, struct ui_file *outstream)
   return uiout->impl->redirect (outstream);
 }
 
-/* local functions */
-
-/* List of column headers manipulation routines.  */
-
-static void
-clear_header_list (struct ui_out *uiout)
-{
-  uiout->table.headers.clear ();
-  uiout->table.headers_iterator = uiout->table.headers.end ();
-}
-
-static void
-append_header_to_list (struct ui_out *uiout,
-		       int width,
-		       enum ui_align alignment,
-		       const std::string &col_name,
-		       const std::string &col_hdr)
-{
-  std::unique_ptr<ui_out_hdr> temphdr(
-    new ui_out_hdr (uiout->table.headers.size () + 1, width,
-		    alignment, col_name, col_hdr));
-
-  uiout->table.headers.push_back (std::move (temphdr));
-}
-
-/* Extract the format information for the NEXT header and advance
-   the header pointer.  Return 0 if there was no next header.  */
-
-static int
-get_next_header (struct ui_out *uiout,
-		 int *colno,
-		 int *width,
-		 enum ui_align *alignment,
-		 const char **col_hdr)
-{
-  /* There may be no headers at all or we may have used all columns.  */
-  if (uiout->table.headers_iterator == uiout->table.headers.end ())
-    return 0;
-
-  ui_out_hdr *hdr = uiout->table.headers_iterator->get ();
-
-  *colno = hdr->number ();
-  *width = hdr->min_width ();
-  *alignment = hdr->alignment ();
-  *col_hdr = hdr->header ().c_str ();
-
-  /* Advance the header pointer to the next entry.  */
-  uiout->table.headers_iterator++;
-
-  return 1;
-}
-
-
 /* Verify that the field/tuple/list is correctly positioned.  Return
    the field number and corresponding alignment (if
    available/applicable).  */
@@ -799,7 +812,8 @@ verify_field (struct ui_out *uiout, int *fldno, int *width,
   ui_out_level *current = current_level (uiout);
   const char *text;
 
-  if (uiout->table.flag && uiout->table.state != TABLE_STATE_BODY)
+  if (uiout->table != nullptr
+      && uiout->table->current_state () != ui_out_table::state::BODY)
     {
       internal_error (__FILE__, __LINE__,
 		      _("table_body missing; table fields must be \
@@ -808,9 +822,10 @@ specified after table_body and inside a list."));
 
   current->inc_field_count ();
 
-  if (uiout->table.state == TABLE_STATE_BODY
-      && uiout->table.entry_level == uiout->level ()
-      && get_next_header (uiout, fldno, width, align, &text))
+  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 (*fldno != current->field_count ())
 	internal_error (__FILE__, __LINE__,
@@ -829,26 +844,10 @@ int
 ui_out_query_field (struct ui_out *uiout, int colno,
 		    int *width, int *alignment, const char **col_name)
 {
-  if (!uiout->table.flag)
+  if (uiout->table == nullptr)
     return 0;
 
-  /* Column numbers are 1-based, so convert to 0-based index.  */
-  int index = colno - 1;
-
-  if (index >= 0 && index < uiout->table.headers.size ())
-    {
-      ui_out_hdr *hdr = uiout->table.headers[index].get ();
-
-      gdb_assert (colno == hdr->number ());
-
-      *width = hdr->min_width ();
-      *alignment = hdr->alignment ();
-      *col_name = hdr->name ().c_str ();
-
-      return 1;
-    }
-  else
-    return 0;
+  return uiout->table->query_field (colno, width, alignment, col_name);
 }
 
 /* Initialize private members at startup.  */
@@ -860,14 +859,10 @@ ui_out_new (ui_out_impl_base *impl, int flags)
 
   uiout->impl.reset (impl);
   uiout->flags = flags;
-  uiout->table.flag = 0;
-  uiout->table.state = TABLE_STATE_HEADERS;
 
   /* Create the ui-out level #1, the default level.  */
   push_level (uiout, ui_out_type_tuple);
 
-  uiout->table.headers_iterator = uiout->table.headers.end ();
-
   return uiout;
 }
 
-- 
2.10.2

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

* Re: [PATCH 19/22] Class-ify ui_out_impl
  2016-11-30 13:09   ` Pedro Alves
@ 2016-11-30 22:38     ` Simon Marchi
  2016-11-30 22:58       ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-11-30 22:38 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-30 08:09, Pedro Alves wrote:
>> +ui_file *
>> +cli_out_set_stream (struct ui_out *uiout, ui_file *stream)
>> +{
>> +  cli_ui_out_impl *impl = dynamic_cast<cli_ui_out_impl *> 
>> (ui_out_impl (uiout));
> 
> "dynamic_cast" is a code smell.  In this case, I think it
> stems from the fact that we have separate ui_out and ui_out_impl
> hierarchies.  If we had a simple hierarchy, then this function would
> take a  cli_ui_out pointer as argument, or even be a
> method of cli_ui_out.

Indeed it's not great.  This patchset is mostly about keeping the 
structure we have, but express it as C++.  So I'd argue that it uncovers 
something that already existed.  I think it makes the situation a tiny 
bit better though, as we have some type checking with dynamic_cast.  
With the static cast we have currently, if you happened to pass the 
wrong kind of object, it would probably fail catastrophically.

I'll consider working on merging ui_out and ui_out_impl_* in a single 
class hierarchy.  My first question is: what is a good pattern for the 
overlapping methods.  For example, table_begin.  We'll want to execute 
the version of the base class, which will then call the specialization.  
So we can't use the same name for both.  So, keep table_begin for the 
base class, and table_begin_impl for the derived classes?

>> +class cli_ui_out_impl : public ui_out_impl_base
>> +{
>> +public:
>> 
>> -struct cli_ui_out_data
>> -  {
>> -    std::vector<ui_file *> streams;
>> -    int suppress_output;
>> -  };
>> +  cli_ui_out_impl (ui_file *stream);
> 
> explicit.

Done.

>> +private:
>> +  void field_separator (void);
> 
> "(void)".  Probably easier to grep the whole patch set to
> find such cases and handle all of them.

Yep, that's what I did the first time I saw that comment.

>> +mi_ui_out_impl::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);
> 
> FYI, it's due to names like "open" potentially conflicting
> with gnulib replacing global namespace C functions with
> #define open rpl_open
> that I'm looking at switching to use gnulib's C++ namespace
> support.  Luckily, looks like gnulib doesn't replace
> "open" currently, so you don't need to wait for that:
> 
>  $ grep -rn open | grep rpl_
>  stdio.in.h:191:#   define fdopen rpl_fdopen
>  stdio.in.h:264:#   define fopen rpl_fopen
>  stdio.in.h:388:#   define freopen rpl_freopen
>  stdio.in.h:820:#   define popen rpl_popen
>  dirent.in.h:79:#   define opendir rpl_opendir
>  dirent.in.h:198:#   define fdopendir rpl_fdopendir
> 
>>  void
>> -mi_table_end (struct ui_out *uiout)
>> +mi_ui_out_impl::table_end ()
>>  {
>> -  mi_out_data *data = (mi_out_data *) ui_out_data (uiout);
>> -
>> -  data->suppress_output = 0;
>> -  mi_close (uiout, ui_out_type_list); /* body */
>> -  mi_close (uiout, ui_out_type_tuple);
>> +  m_suppress_output = 0;
>> +  close (ui_out_type_list); /* body */
>> +  close (ui_out_type_tuple);
> 
> However:
> 
>  $ grep -rn close | grep rpl_
>  stdio.in.h:172:#   define fclose rpl_fclose
>  dirent.in.h:131:#   define closedir rpl_closedir
>  unistd.in.h:303:#   define close rpl_close
> 
> 
> :-/
> 
> I'd like to post the gnulib namespace patch this week,
> but I'm not sure I'll be able to.

And I guess it happens to work anyway for me because both the 
declaration, definition and usages get replaced?

Should I wait for your patch to get in (I'm not particularly in a 
hurry), or we can get it in despite "close" getting replaced?

>> +  virtual void field_string (int fldno, int width, ui_align align,
>> +			     const char *fldname, const char *string) override;
>> +  virtual void ATTRIBUTE_PRINTF(6,0)
>> +    field_fmt (int fldno, int width, ui_align align, const char 
>> *fldname,
>> +	       const char *format, va_list args) override;
> 
> It's more usual to put the ATTRIBUTE_PRINTFs at the end of the
> declaration.  Also, missing space before parens.  Something like:
> 
>   virtual void field_fmt (int fldno, int width, ui_align align,
>                           const char *fldname,
>                           const char *format, va_list args) override
>     ATTRIBUTE_PRINTF (6,0);
> 
> ?

Ah, I put them there because I though it was the only place where it 
worked when applied to virtual pure functions.  But apparently, this 
works:

  98   virtual void field_fmt (int fldno, int width, ui_align align,
  99                           const char *fldname, const char *format, 
va_list args)
100     ATTRIBUTE_PRINTF(6,0) = 0;

I thought I had tried it and it didn't work, but I was wrong.  I'll fix 
them so they look like that.

>> +  virtual void spaces (int numspaces) override;
>> +  virtual void text (const char *string) override;
>> +  virtual void ATTRIBUTE_PRINTF(2,0) message (const char *format, 
>> va_list args)
>> +    override;
> 
> Ditto.  There are other instances in the patch.  I won't point them 
> all.

I'll go over all the patches and fix that.

>> +private:
>> +
>> +  void field_separator ();
>> +  void open (const char *name, ui_out_type type);
>> +  void close (ui_out_type type);
>> +
>> +  int m_suppress_field_separator;
>> +  int m_suppress_output;
> 
> bool ?

Right.  I changed it, but from what I can see MI's m_suppress_output is 
never used (as in never set to true).  If that's indeed the case, I'll 
make a separate patch to remove it in the current master code.

CLI has a m_suppress_output that is used though, I changed it as well to 
bool.

>> +  int m_mi_version;
>> +  std::vector<ui_file *> m_streams;
>> +};
> 
> 
> 
>> -typedef struct tui_ui_out_data tui_out_data;
>> +class tui_ui_out_impl : public cli_ui_out_impl
>> +{
>> +public:
>> +
>> +  tui_ui_out_impl (ui_file *stream);
> 
> explicit.

Done.

>> +
>> +  void field_int (int fldno, int width, ui_align align, const char 
>> *fldname,
>> +		  int value) override;
>> +  void field_string (int fldno, int width, ui_align align, const char 
>> *fldname,
>> +		     const char *string) override;
>> +  void ATTRIBUTE_PRINTF(6,0)
>> +    field_fmt (int fldno, int width, ui_align align, const char 
>> *fldname,
>> +	       const char *format, va_list args) override;
> 
> attribute placement, space before parens.

Done.

>> +  void text (const char *string) override;
>> 
> 
> 
>> +  virtual int redirect (struct ui_file * outstream) = 0;
>> +
>> +  /* Set as not MI-like by default.  It is overridden in subclasses 
>> if
>> +     necessary.  */
>> +
>> +  virtual int is_mi_like_p ()
>> +  { return 0; }
> 
> bool ?

Done.

Thanks for the review.  I'll try to push the small patches that were 
OK'ed without comments, and re-post a complete v2 series.

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

* Re: [PATCH 19/22] Class-ify ui_out_impl
  2016-11-30 22:38     ` Simon Marchi
@ 2016-11-30 22:58       ` Pedro Alves
  2016-12-01 19:04         ` Simon Marchi
  0 siblings, 1 reply; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 22:58 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

On 11/30/2016 10:38 PM, Simon Marchi wrote:

> I'll consider working on merging ui_out and ui_out_impl_* in a single
> class hierarchy.  My first question is: what is a good pattern for the
> overlapping methods.  For example, table_begin.  We'll want to execute
> the version of the base class, which will then call the specialization. 
> So we can't use the same name for both.  So, keep table_begin for the
> base class, and table_begin_impl for the derived classes?

Yes.  I think gold's convention is to use $method for public methods, and
do_$method for protected virtual methods that implementations
override/provide.  I've seen "do_" used for the same purpose in other
projects too.  (IIRC, gold is even stricter and requires that virtual
methods must be protected, thus mandating that design everywhere.
Grep for "this->do_".)

>> I'd like to post the gnulib namespace patch this week,
>> but I'm not sure I'll be able to.
> 
> And I guess it happens to work anyway for me because both the
> declaration, definition and usages get replaced?

Yeah, unistd.h is included in defs.h, so it most probably 
won't be an issue in practice.

> 
> Should I wait for your patch to get in (I'm not particularly in a
> hurry), or we can get it in despite "close" getting replaced?

Given the above, no need to wait.

Thanks,
Pedro Alves

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

* Re: [PATCH v2] Class-ify ui_out_table
  2016-11-30 21:48       ` [PATCH v2] " Simon Marchi
@ 2016-11-30 23:01         ` Pedro Alves
  0 siblings, 0 replies; 71+ messages in thread
From: Pedro Alves @ 2016-11-30 23:01 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches; +Cc: Simon Marchi

On 11/30/2016 09:47 PM, Simon Marchi wrote:

> gdb/ChangeLog:
> 
> 	* ui-out.c (enum ui_out_table_state): Move to class
> 	ui_out_table as ui_out_table::state.
> 	(struct ui_out_table): Change to ...
> 	(class ui_out_table): ... this.
> 	<flag>: Remove.
> 	<entry_level>: Rename to ...
> 	<m_entry_level>: ... this.
> 	<columns>: Rename to ...
> 	<m_nr_cols>: ... this.
> 	<id>: Rename to ...
> 	<m_id>: ... this.
> 	<headers>: Rename to ...
> 	<m_headers>: ... this.
> 	<headers_iterator>: Rename to ...
> 	<m_headers_iterator>: ... this.
> 	<start_body, append_header, start_row, get_next_header,
> 	query_field, current_state, entry_level>: New methods.
> 	(struct ui_out) <table>: Change type to unique_ptr to
> 	ui_out_table.
> 	(append_header_to_list, get_next_header, clear_header_list,
> 	clear_table): Remove.
> 	(ui_out_table_begin): Instantiate ui_out_table object.  Update
> 	table check.
> 	(ui_out_table_body): Update table check, replace code with call
> 	to ui_out_table::start_body.
> 	(ui_out_table_end): Update table check, replace manual cleanup
> 	with assignment of uiout->table unique_ptr to nullptr.
> 	(ui_out_table_header): Update table check, replace call to
> 	append_header_to_list with call to append_header method.
> 	(ui_out_begin): Remove one table state check, update another.
> 	Replace code with call to start_row method.
> 	(verify_field): Update table checks.
> 	(ui_out_query_field): Update table check, replace code with call
> 	to query_field method.
> 	(ui_out_new): Remove table initialization code.

OK.

Thanks,
Pedro Alves

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-11-24 18:47   ` Pedro Alves
  2016-11-27  3:14     ` Simon Marchi
@ 2016-12-01  2:51     ` Simon Marchi
  2016-12-01 21:24       ` Simon Marchi
  1 sibling, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-12-01  2:51 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-24 13:47, Pedro Alves wrote:
> BTW, all other patches (I haven't looked at the missing ones)
> look good to me, apart from the nits I sent.

I have now pushed patches 8-12 (inclusively).

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

* Re: [PATCH 19/22] Class-ify ui_out_impl
  2016-11-30 22:58       ` Pedro Alves
@ 2016-12-01 19:04         ` Simon Marchi
  2016-12-01 19:30           ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-12-01 19:04 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-30 17:57, Pedro Alves wrote:
> On 11/30/2016 10:38 PM, Simon Marchi wrote:
> 
>> I'll consider working on merging ui_out and ui_out_impl_* in a single
>> class hierarchy.  My first question is: what is a good pattern for the
>> overlapping methods.  For example, table_begin.  We'll want to execute
>> the version of the base class, which will then call the 
>> specialization.
>> So we can't use the same name for both.  So, keep table_begin for the
>> base class, and table_begin_impl for the derived classes?
> 
> Yes.  I think gold's convention is to use $method for public methods, 
> and
> do_$method for protected virtual methods that implementations
> override/provide.  I've seen "do_" used for the same purpose in other
> projects too.  (IIRC, gold is even stricter and requires that virtual
> methods must be protected, thus mandating that design everywhere.
> Grep for "this->do_".)

As I am doing this, I realize we'll need a cast anyway, it just changes 
where it is.

For example, mi_cmd_var_list_children calls "mi_version (uiout)".  The 
uiout variable is of type "ui_out *", since we don't know at compile 
time that the current_uiout will be an MI uiout.  We know it will be 
because of how the program works, but that can only be verified at 
runtime.  So in the end, instead of doing a dynamic_cast in mi_version, 
we'll have to do one in the function using the uiout.

I still think that merging ui_out and ui_out_impl is a good idea though, 
there's no good reason for them to be separate.

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

* Re: [PATCH 19/22] Class-ify ui_out_impl
  2016-12-01 19:04         ` Simon Marchi
@ 2016-12-01 19:30           ` Pedro Alves
  0 siblings, 0 replies; 71+ messages in thread
From: Pedro Alves @ 2016-12-01 19:30 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

On 12/01/2016 07:04 PM, Simon Marchi wrote:
> On 2016-11-30 17:57, Pedro Alves wrote:
>> On 11/30/2016 10:38 PM, Simon Marchi wrote:
>>
>>> I'll consider working on merging ui_out and ui_out_impl_* in a single
>>> class hierarchy.  My first question is: what is a good pattern for the
>>> overlapping methods.  For example, table_begin.  We'll want to execute
>>> the version of the base class, which will then call the specialization.
>>> So we can't use the same name for both.  So, keep table_begin for the
>>> base class, and table_begin_impl for the derived classes?
>>
>> Yes.  I think gold's convention is to use $method for public methods, and
>> do_$method for protected virtual methods that implementations
>> override/provide.  I've seen "do_" used for the same purpose in other
>> projects too.  (IIRC, gold is even stricter and requires that virtual
>> methods must be protected, thus mandating that design everywhere.
>> Grep for "this->do_".)
> 
> As I am doing this, I realize we'll need a cast anyway, it just changes
> where it is.
> 
> For example, mi_cmd_var_list_children calls "mi_version (uiout)".  The
> uiout variable is of type "ui_out *", since we don't know at compile
> time that the current_uiout will be an MI uiout.  We know it will be
> because of how the program works, but that can only be verified at
> runtime.  So in the end, instead of doing a dynamic_cast in mi_version,
> we'll have to do one in the function using the uiout.

In that case, I'd say that problem is that that code uses "current_uiout".
If we walk up the call stack, we should find the MI interpreter somewhere,
which has a handle to the MI uiout, should know its type.  If somehow one
of those was passed down, either by parameter (or by being able to access
them from some existing MI-specific global context structure, maybe the
existing "current_context"), then the problem wouldn't exist.  We'd still be
shifting the casts higher up a bit, as we still have things like
as_mi_interp, which are effectively dynamic_casts in the ui<->interp code.
That one would probably be sorted by cleaning up the "virtual" methods
of "struct interpreter" and "struct ui", e.g., by adding an
"interpreter->execute_command (....)" virtual method.  Certainly
nothing urgent to fix, but I think good to keep in mind.

So as long as we're shifting casts closer to the top level, it seems like
we're heading in the proper direction.

BTW, in code that knows what the dynamic type of a pointer should be, we
should feel free to use static_cast<derived *>.  But I'm fine with
using dynamic_cast<> as validation aid.  Just be aware that it's not
free performance-wise.

> I still think that merging ui_out and ui_out_impl is a good idea though,
> there's no good reason for them to be separate.

*nod*

Thanks,
Pedro Alves

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

* Re: [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by   vector and iterator
  2016-11-26 16:13     ` Simon Marchi
@ 2016-12-01 20:22       ` Simon Marchi
  2016-12-01 20:23         ` Pedro Alves
  0 siblings, 1 reply; 71+ messages in thread
From: Simon Marchi @ 2016-12-01 20:22 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-26 11:13, Simon Marchi wrote:
> On 2016-11-24 13:41, Pedro Alves wrote:
>> On 11/24/2016 03:27 PM, Simon Marchi wrote:
>>> Instead of keeping pointers to first, last and current ui_out_hdr in
>>> ui_out_table, we can use an std::vector and an iterator.  Direct 
>>> random
>>> access of to vector helps make get_next_header a bit nicer by 
>>> avoiding
>>> iterating on all the headers.  append_header_to_list is also a bit
>>> simpler.
>> 
>> Inserting into a vector invalidates iterators if it causes 
>> reallocation.
>> I think we're good because there's be some call to start_body
>> or start_row before the iterator is ever dereferenced, right?
>> 
>> Thanks,
>> Pedro Alves
> 
> start_body and start_row is the terminology introduced in a later
> patch, but you are right.  The table generation is in two phases:
> 
> 1. define the headers
> 2. generate the body/rows
> 
> In 1, we modify the vector but don't use the iterator, whereas in 2 we
> use the iterator but don't modify the vector.  The various table state
> checks should validate that we don't try to define a new header while
> we are in phase 2, for example.

Just to be sure, is this patch OK?

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

* Re: [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by vector and iterator
  2016-12-01 20:22       ` Simon Marchi
@ 2016-12-01 20:23         ` Pedro Alves
  0 siblings, 0 replies; 71+ messages in thread
From: Pedro Alves @ 2016-12-01 20:23 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

On 12/01/2016 08:22 PM, Simon Marchi wrote:

> Just to be sure, is this patch OK?

Yes.

Thanks,
Pedro Alves

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

* Re: [PATCH 00/22] Convert ui-out subsystem to C++
  2016-12-01  2:51     ` Simon Marchi
@ 2016-12-01 21:24       ` Simon Marchi
  0 siblings, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-12-01 21:24 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 2016-11-30 21:51, Simon Marchi wrote:
> On 2016-11-24 13:47, Pedro Alves wrote:
>> BTW, all other patches (I haven't looked at the missing ones)
>> look good to me, apart from the nits I sent.
> 
> I have now pushed patches 8-12 (inclusively).

I have now pushed 13-18 and 20 (which was not dependent on 19).

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

* [pushed] Introduce enum_flag type for ui_out flags
  2016-11-30 13:34   ` Pedro Alves
  2016-11-30 21:32     ` Simon Marchi
@ 2016-12-02 22:22     ` Simon Marchi
  1 sibling, 0 replies; 71+ messages in thread
From: Simon Marchi @ 2016-12-02 22:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

From: Simon Marchi <simon.marchi@polymtl.ca>

Here is the version I pushed.  I wanted to get rid of this patch while I rework
the last two big patches (which will become a single patch), so I cherry-picked
it and adapted it to the pre-class code.  It's obviously a bit different than
the version that was approved, but I think it's straightforward enough.

This patch changes the ui_out flags to be an enum flag.

gdb/ChangeLog:

	* ui-out.h: Include "common/enum-flags.h".
	(enum ui_flags): Rename to ...
	(enum ui_out_flag): ... this.
	(ui_out_flags): Define enum flag type.
	(ui_out_test_flags): Change type of parameter to ui_out_flags.
	(ui_out_new): Likewise.
	* ui-out.c (ui_out_test_flags): Likewise.
	(ui_out_new): Likewise.
	* cli-out.c (cli_out_new): Update variable type.
	* mi/mi-out.c (mi_out_new): Likewise.
	* tui/tui-out.c (tui_out_new): Likewise.
---
 gdb/ChangeLog     | 14 ++++++++++++++
 gdb/cli-out.c     |  2 +-
 gdb/mi/mi-out.c   |  2 +-
 gdb/tui/tui-out.c |  2 +-
 gdb/ui-out.c      |  4 ++--
 gdb/ui-out.h      | 15 ++++++++-------
 6 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 777abc7c30..4a64fca8d2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2016-12-02  Simon Marchi  <simon.marchi@polymtl.ca>
+
+	* ui-out.h: Include "common/enum-flags.h".
+	(enum ui_flags): Rename to ...
+	(enum ui_out_flag): ... this.
+	(ui_out_flags): Define enum flag type.
+	(ui_out_test_flags): Change type of parameter to ui_out_flags.
+	(ui_out_new): Likewise.
+	* ui-out.c (ui_out_test_flags): Likewise.
+	(ui_out_new): Likewise.
+	* cli-out.c (cli_out_new): Update variable type.
+	* mi/mi-out.c (mi_out_new): Likewise.
+	* tui/tui-out.c (tui_out_new): Likewise.
+
 2016-12-02  Pedro Alves  <palves@redhat.com>
 
 	* NEWS: Mention that user commands now accept an unlimited number
diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index ac19e38c3d..f5b5072e55 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -388,7 +388,7 @@ cli_out_data_ctor (cli_out_data *self, struct ui_file *stream)
 struct ui_out *
 cli_out_new (struct ui_file *stream)
 {
-  int flags = ui_source_list;
+  ui_out_flags flags = ui_source_list;
   cli_out_data *data = new cli_out_data ();
 
   cli_out_data_ctor (data, stream);
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index 6e69d7cb34..19fcf87fbf 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -393,7 +393,7 @@ mi_out_data_dtor (struct ui_out *ui_out)
 struct ui_out *
 mi_out_new (int mi_version)
 {
-  int flags = 0;
+  ui_out_flags flags = 0;
   mi_out_data *data = new mi_out_data ();
   struct ui_file *stream = mem_fileopen ();
 
diff --git a/gdb/tui/tui-out.c b/gdb/tui/tui-out.c
index 4856562343..a5f0541037 100644
--- a/gdb/tui/tui-out.c
+++ b/gdb/tui/tui-out.c
@@ -145,7 +145,7 @@ tui_text (struct ui_out *uiout, const char *string)
 struct ui_out *
 tui_out_new (struct ui_file *stream)
 {
-  int flags = 0;
+  ui_out_flags flags = 0;
 
   tui_out_data *data = new tui_out_data ();
 
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 8f745dadac..774be2cb71 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -702,7 +702,7 @@ ui_out_redirect (struct ui_out *uiout, struct ui_file *outstream)
 
 /* Test the flags against the mask given.  */
 int
-ui_out_test_flags (struct ui_out *uiout, int mask)
+ui_out_test_flags (struct ui_out *uiout, ui_out_flags mask)
 {
   return (uiout->flags & mask);
 }
@@ -923,7 +923,7 @@ ui_out_query_field (struct ui_out *uiout, int colno,
 
 struct ui_out *
 ui_out_new (const struct ui_out_impl *impl, void *data,
-	    int flags)
+	    ui_out_flags flags)
 {
   struct ui_out *uiout = new ui_out ();
 
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index 06c05e2f3a..cdf567148f 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -23,6 +23,8 @@
 #ifndef UI_OUT_H
 #define UI_OUT_H 1
 
+#include "common/enum-flags.h"
+
 /* The ui_out structure */
 
 struct ui_out;
@@ -45,12 +47,12 @@ enum ui_align
   };
 
 /* flags enum */
-enum ui_flags
+enum ui_out_flag
   {
-    ui_from_tty = 1,
-    ui_source_list = 2
+    ui_source_list = (1 << 0),
   };
 
+DEF_ENUM_FLAGS_TYPE (ui_out_flag, ui_out_flags);
 
 /* Prototypes for ui-out API.  */
 
@@ -127,7 +129,7 @@ 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, int mask);
+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,
@@ -222,9 +224,8 @@ extern void uo_field_string (struct ui_out *uiout, int fldno, int width,
 
 /* Create a ui_out object */
 
-extern struct ui_out *ui_out_new (const struct ui_out_impl *impl,
-				  void *data,
-				  int flags);
+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.  */
 
-- 
2.11.0

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

end of thread, other threads:[~2016-12-02 22:22 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-24 15:24 [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
2016-11-24 15:24 ` [PATCH 01/22] Remove unused functions and declarations Simon Marchi
2016-11-24 15:24 ` [PATCH 02/22] Rename ui_out_data to mi_ui_out_data Simon Marchi
2016-11-24 15:24 ` [PATCH 06/22] Remove verbosity from ui_out_message and friends Simon Marchi
2016-11-24 15:24 ` [PATCH 08/22] Use new/delete instead of malloc/free-based functions Simon Marchi
2016-11-24 15:24 ` [PATCH 03/22] Remove ui_out_destroy Simon Marchi
2016-11-24 15:24 ` [PATCH 09/22] Use std::vector for ui_out::levels Simon Marchi
2016-11-24 15:24 ` [PATCH 07/22] Remove stale comments Simon Marchi
2016-11-24 18:38   ` Pedro Alves
2016-11-26 15:29     ` Simon Marchi
2016-11-24 15:27 ` [PATCH 10/22] Use std::vector for mi_ui_out_data::streams Simon Marchi
2016-11-24 18:38   ` Pedro Alves
2016-11-26 15:48     ` Simon Marchi
2016-11-24 15:28 ` [PATCH 16/22] Class-ify ui_out_level Simon Marchi
2016-11-24 18:41   ` Pedro Alves
2016-11-26 16:22     ` Simon Marchi
2016-11-30 12:07       ` Pedro Alves
2016-11-30 12:41         ` Antoine Tremblay
2016-11-30 13:27           ` Pedro Alves
2016-11-30 13:47             ` Antoine Tremblay
2016-11-30 14:17               ` Pedro Alves
2016-11-30 14:21                 ` Antoine Tremblay
2016-11-30 20:40         ` Simon Marchi
2016-11-24 15:28 ` [PATCH 15/22] Class-ify ui_out_hdr Simon Marchi
2016-11-24 15:28 ` [PATCH 13/22] Replace hand-made linked list of ui_out_hdr by vector and iterator Simon Marchi
2016-11-24 18:41   ` Pedro Alves
2016-11-26 16:13     ` Simon Marchi
2016-12-01 20:22       ` Simon Marchi
2016-12-01 20:23         ` Pedro Alves
2016-11-24 15:28 ` [PATCH 12/22] Use std::string in ui_out_table Simon Marchi
2016-11-24 15:28 ` [PATCH 17/22] Simplify ui-out level code Simon Marchi
2016-11-24 18:42   ` Pedro Alves
2016-11-26 16:39     ` Simon Marchi
2016-11-30 12:08       ` Pedro Alves
2016-11-24 15:28 ` [PATCH 11/22] Use std::vector for cli_ui_out_data::streams Simon Marchi
2016-11-24 18:41   ` Pedro Alves
2016-11-26 15:51     ` Simon Marchi
2016-11-24 15:28 ` [PATCH 18/22] ui_out_table: Replace boolean flag with enum Simon Marchi
2016-11-24 18:42   ` Pedro Alves
2016-11-26 16:47     ` Simon Marchi
2016-11-30 12:10       ` Pedro Alves
2016-11-24 15:28 ` [PATCH 14/22] Use std::string for ui_out_hdr's text fields Simon Marchi
2016-11-24 15:32 ` [PATCH 22/22] Introduce enum_flag type for ui_out flags Simon Marchi
2016-11-30 13:34   ` Pedro Alves
2016-11-30 21:32     ` Simon Marchi
2016-12-02 22:22     ` [pushed] " Simon Marchi
2016-11-24 15:36 ` [PATCH 05/22] Constify wrap_here/wrap_hint code path Simon Marchi
2016-11-24 15:36 ` [PATCH 04/22] Fix return value of uo_redirect Simon Marchi
2016-11-24 16:08 ` [PATCH 00/22] Convert ui-out subsystem to C++ Simon Marchi
2016-11-24 18:46   ` Pedro Alves
2016-11-24 19:15     ` Simon Marchi
2016-11-24 20:33       ` Simon Marchi
2016-11-24 18:47   ` Pedro Alves
2016-11-27  3:14     ` Simon Marchi
2016-12-01  2:51     ` Simon Marchi
2016-12-01 21:24       ` Simon Marchi
2016-11-24 19:11 ` [PATCH 20/22] Class-ify ui_out_table Simon Marchi
2016-11-30 12:29   ` Pedro Alves
2016-11-24 19:19 ` [PATCH 21/22] Class-ify ui_out Simon Marchi
2016-11-30 12:46   ` Pedro Alves
2016-11-30 21:47     ` Simon Marchi
2016-11-26 15:20 ` [PATCH 19/22] Class-ify ui_out_impl simon.marchi
2016-11-30 13:09   ` Pedro Alves
2016-11-30 22:38     ` Simon Marchi
2016-11-30 22:58       ` Pedro Alves
2016-12-01 19:04         ` Simon Marchi
2016-12-01 19:30           ` Pedro Alves
     [not found] ` <20161124153228.25177-20-simon.marchi@polymtl.ca>
2016-11-26 17:18   ` [PATCH 20/22] Class-ify ui_out_table Simon Marchi
2016-11-30 12:30     ` Pedro Alves
2016-11-30 21:48       ` [PATCH v2] " Simon Marchi
2016-11-30 23:01         ` Pedro Alves

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