[62/66] Remove union tui_which_element

Message ID 20190624184841.3492-13-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey June 24, 2019, 6:48 p.m. UTC
  This removes union tui_which_element, instead moving the content
directly into tui_source_window_base.  This allows for the deletion of
a fair amount of code.  Now the TUI window hierarchy is more
type-safe.  In particular, there is never any confusion now about
which members are in use by which subtype.

2019-06-23  Tom Tromey  <tom@tromey.com>

	* tui/tui-winsource.h (tui_update_source_window_as_is)
	(tui_alloc_source_buffer, tui_line_is_displayed)
	(tui_addr_is_displayed): Change type of win_info.
	* tui/tui-winsource.c (tui_update_source_window_as_is)
	(tui_clear_source_content, tui_show_source_line)
	(tui_show_source_content, tui_source_window_base::refill)
	(tui_source_window_base::set_is_exec_point_at)
	(tui_source_window_base::set_is_exec_point_at)
	(tui_update_breakpoint_info, tui_set_exec_info_content): Update.
	(tui_alloc_source_buffer, tui_line_is_displayed)
	(tui_addr_is_displayed): Change type of win_info.  Update.
	* tui/tui-win.c (tui_resize_all, tui_adjust_win_heights)
	(tui_source_window_base::do_make_visible_with_new_height):
	Update.
	* tui/tui-source.c (tui_set_source_content)
	(tui_set_source_content_nil)
	(tui_source_window::do_scroll_vertical): Update.
	* tui/tui-layout.c (show_layout): Update.
	* tui/tui-disasm.c (tui_set_disassem_content)
	(tui_disasm_window::do_scroll_vertical): Update.
	* tui/tui-data.h (tui_win_content): Remove.
	(struct tui_gen_win_info) <content, content_size>: Remove.
	(struct tui_source_element): Add initializers and destructor.
	(union tui_which_element, struct tui_win_element): Remove.
	(struct tui_source_window_base) <content>: New field.
	(struct tui_data_window): Remove destructor.
	(tui_alloc_content, tui_free_win_content)
	(tui_free_all_source_wins_content): Don't declare.
	* tui/tui-data.c (tui_initialize_static_data): Update.
	(init_content_element, tui_alloc_content): Remove.
	(~tui_gen_win_info): Update.
	(~tui_data_window, tui_free_all_source_wins_content)
	(tui_free_win_content, free_content, free_content_elements):
	Remove.
---
 gdb/ChangeLog           |  37 +++++++++
 gdb/tui/tui-data.c      | 166 ----------------------------------------
 gdb/tui/tui-data.h      |  43 ++++-------
 gdb/tui/tui-disasm.c    |  19 ++---
 gdb/tui/tui-layout.c    |   1 -
 gdb/tui/tui-source.c    |  53 ++++++-------
 gdb/tui/tui-win.c       |  25 +++---
 gdb/tui/tui-winsource.c |  89 ++++++++++-----------
 gdb/tui/tui-winsource.h |  12 +--
 9 files changed, 144 insertions(+), 301 deletions(-)
  

Patch

diff --git a/gdb/tui/tui-data.c b/gdb/tui/tui-data.c
index 429ce1c414c..1ecf486e37f 100644
--- a/gdb/tui/tui-data.c
+++ b/gdb/tui/tui-data.c
@@ -46,18 +46,6 @@  static struct tui_layout_def layout_def = {
 static int win_resized = FALSE;
 
 
-/*********************************
-** Static function forward decls
-**********************************/
-static void free_content (tui_win_content, 
-			  int, 
-			  enum tui_win_type);
-static void free_content_elements (tui_win_content, 
-				   int, 
-				   enum tui_win_type);
-
-
-
 /*********************************
 ** PUBLIC FUNCTIONS
 **********************************/
@@ -339,43 +327,14 @@  tui_initialize_static_data ()
     win->origin.x =
     win->origin.y =
     win->viewport_height =
-    win->content_size =
     win->last_visible_line = 0;
   win->handle = NULL;
-  win->content = NULL;
   win->content_in_use = FALSE;
   win->is_visible = false;
   win->title = 0;
 }
 
 
-/* init_content_element().
- */
-static void
-init_content_element (struct tui_win_element *element, 
-		      enum tui_win_type type)
-{
-  gdb_assert (type != EXEC_INFO_WIN);
-  gdb_assert (type != LOCATOR_WIN);
-  gdb_assert (type != CMD_WIN);
-  gdb_assert (type != DATA_ITEM_WIN);
-  gdb_assert (type != DATA_WIN);
-
-  switch (type)
-    {
-    case SRC_WIN:
-    case DISASSEM_WIN:
-      element->which_element.source.line = NULL;
-      element->which_element.source.line_or_addr.loa = LOA_LINE;
-      element->which_element.source.line_or_addr.u.line_no = 0;
-      element->which_element.source.is_exec_point = false;
-      element->which_element.source.has_break = FALSE;
-      break;
-    default:
-      break;
-    }
-}
-
 tui_win_info::tui_win_info (enum tui_win_type type)
   : tui_gen_win_info (type)
 {
@@ -389,47 +348,12 @@  tui_source_window_base::tui_source_window_base (enum tui_win_type type)
   start_line_or_addr.u.addr = 0;
 }
 
-/* Allocates the content and elements in a block.  */
-tui_win_content
-tui_alloc_content (int num_elements, enum tui_win_type type)
-{
-  tui_win_content content;
-  struct tui_win_element *element_block_ptr;
-  int i;
-
-  gdb_assert (type != EXEC_INFO_WIN);
-  gdb_assert (type != LOCATOR_WIN);
-
-  content = XNEWVEC (struct tui_win_element *, num_elements);
-
-  /*
-   * All windows, except the data window, can allocate the
-   * elements in a chunk.  The data window cannot because items
-   * can be added/removed from the data display by the user at any
-   * time.
-   */
-  if (type != DATA_WIN)
-    {
-      element_block_ptr = XNEWVEC (struct tui_win_element, num_elements);
-      for (i = 0; i < num_elements; i++)
-	{
-	  content[i] = element_block_ptr;
-	  init_content_element (content[i], type);
-	  element_block_ptr++;
-	}
-    }
-
-  return content;
-}
-
-
 tui_gen_win_info::~tui_gen_win_info ()
 {
   if (handle != NULL)
     {
       tui_delete_win (handle);
       handle = NULL;
-      tui_free_win_content (this);
     }
   xfree (title);
 }
@@ -440,103 +364,13 @@  tui_source_window_base::~tui_source_window_base ()
   delete execution_info;
 }  
 
-tui_data_window::~tui_data_window ()
-{
-  if (content != NULL)
-    {
-      regs_column_count = 1;
-      display_regs = false;
-      content = NULL;
-      content_size = 0;
-    }
-}  
-
-void
-tui_free_all_source_wins_content ()
-{
-  for (tui_source_window_base *win_info : tui_source_windows ())
-    {
-      tui_free_win_content (win_info);
-      tui_free_win_content (win_info->execution_info);
-    }
-}
-
-
-void
-tui_free_win_content (struct tui_gen_win_info *win_info)
-{
-  if (win_info->content != NULL)
-    {
-      free_content (win_info->content,
-		   win_info->content_size,
-		   win_info->type);
-      win_info->content = NULL;
-    }
-  win_info->content_size = 0;
-}
-
-
 /**********************************
 ** LOCAL STATIC FUNCTIONS        **
 **********************************/
 
 
-static void
-free_content (tui_win_content content, 
-	      int content_size, 
-	      enum tui_win_type win_type)
-{
-  if (content != NULL)
-    {
-      free_content_elements (content, content_size, win_type);
-      xfree (content);
-    }
-}
-
-
 tui_data_item_window::~tui_data_item_window ()
 {
   xfree (value);
   xfree (content);
 }
-
-/* free_content_elements().
- */
-static void
-free_content_elements (tui_win_content content, 
-		       int content_size, 
-		       enum tui_win_type type)
-{
-  if (content != NULL)
-    {
-      int i;
-
-      if (type == DISASSEM_WIN)
-	{
-	  /* Free whole source block.  */
-	  xfree (content[0]->which_element.source.line);
-	}
-      else
-	{
-	  for (i = 0; i < content_size; i++)
-	    {
-	      struct tui_win_element *element;
-
-	      element = content[i];
-	      if (element != NULL)
-		{
-		  switch (type)
-		    {
-		    case SRC_WIN:
-		      xfree (element->which_element.source.line);
-		      break;
-		    default:
-		      break;
-		    }
-		}
-	    }
-	}
-      if (type != DATA_WIN && type != DATA_ITEM_WIN)
-	xfree (content[0]);	/* Free the element block.  */
-    }
-}
diff --git a/gdb/tui/tui-data.h b/gdb/tui/tui-data.h
index f0454c5d742..147149389cf 100644
--- a/gdb/tui/tui-data.h
+++ b/gdb/tui/tui-data.h
@@ -31,11 +31,6 @@  struct tui_point
   int x, y;
 };
 
-struct tui_win_element;
-
-/* This describes the content of the window.  */
-typedef struct tui_win_element **tui_win_content;
-
 /* Generic window information.  */
 struct tui_gen_win_info
 {
@@ -75,10 +70,6 @@  struct tui_gen_win_info
   int height = 0;
   /* Origin of window.  */
   struct tui_point origin = {0, 0};
-  /* Content of window.  */
-  tui_win_content content = nullptr;
-  /* Size of content (# of elements).  */
-  int content_size = 0;
   /* Can it be used, or is it already used?  */
   int content_in_use = FALSE;
   /* Viewport height.  */
@@ -172,10 +163,21 @@  struct tui_layout_def
 /* Elements in the Source/Disassembly Window.  */
 struct tui_source_element
 {
-  char *line;
+  tui_source_element ()
+  {
+    line_or_addr.loa = LOA_LINE;
+    line_or_addr.u.line_no = 0;
+  }
+
+  ~tui_source_element ()
+  {
+    xfree (line);
+  }
+
+  char *line = nullptr;
   struct tui_line_or_address line_or_addr;
-  bool is_exec_point;
-  int has_break;
+  bool is_exec_point = false;
+  int has_break = 0;
 };
 
 
@@ -200,17 +202,6 @@  struct tui_source_element
 
 typedef char tui_exec_info_content[TUI_EXECINFO_SIZE];
 
-/* An content element in a window.  */
-union tui_which_element
-{
-  struct tui_source_element source;	/* The source elements.  */
-};
-
-struct tui_win_element
-{
-  union tui_which_element which_element;
-};
-
 /* Execution info window class.  */
 
 struct tui_exec_info_window : public tui_gen_win_info
@@ -410,6 +401,8 @@  public:
 
   /* Architecture associated with code at this location.  */
   struct gdbarch *gdbarch = nullptr;
+
+  std::vector<tui_source_element> content;
 };
 
 /* A TUI source window.  */
@@ -461,7 +454,6 @@  struct tui_data_window : public tui_win_info
   {
   }
 
-  ~tui_data_window () override;
   DISABLE_COPY_AND_ASSIGN (tui_data_window);
 
   void clear_detail () override;
@@ -551,9 +543,6 @@  extern struct tui_win_info *tui_win_list[MAX_MAJOR_WINDOWS];
 
 /* Data Manipulation Functions.  */
 extern void tui_initialize_static_data (void);
-extern tui_win_content tui_alloc_content (int, enum tui_win_type);
-extern void tui_free_win_content (struct tui_gen_win_info *);
-extern void tui_free_all_source_wins_content (void);
 extern struct tui_win_info *tui_partial_win_by_name (const char *);
 extern enum tui_layout_type tui_current_layout (void);
 extern void tui_set_current_layout_to (enum tui_layout_type);
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index 6b88d96a9db..d3d53d7c607 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -219,27 +219,23 @@  tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc)
   line = (char*) alloca (insn_pos + insn_size + 1);
 
   /* Now construct each line.  */
+  TUI_DISASM_WIN->content.resize (max_lines);
   for (i = 0; i < max_lines; i++)
     {
-      struct tui_win_element *element;
-      struct tui_source_element *src;
       int cur_len;
 
-      element = TUI_DISASM_WIN->content[i];
-      src = &element->which_element.source;
+      tui_source_element *src = &TUI_DISASM_WIN->content[i];
       strcpy (line, asm_lines[i].addr_string);
       cur_len = strlen (line);
       memset (line + cur_len, ' ', insn_pos - cur_len);
       strcpy (line + insn_pos, asm_lines[i].insn);
 
       /* Now copy the line taking the offset into account.  */
+      xfree (src->line);
       if (strlen (line) > offset)
-	{
-	  strncpy (src->line, &line[offset], line_width);
-	  src->line[line_width] = '\0';
-	}
+	src->line = xstrndup (&line[offset], line_width);
       else
-        src->line[0] = '\0';
+	src->line = xstrdup ("");
 
       src->line_or_addr.loa = LOA_ADDRESS;
       src->line_or_addr.u.addr = asm_lines[i].addr;
@@ -254,7 +250,6 @@  tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc)
       xfree (asm_lines[i].addr_string);
       xfree (asm_lines[i].insn);
     }
-  TUI_DISASM_WIN->content_size = i;
   return TUI_SUCCESS;
 }
 
@@ -371,12 +366,12 @@  tui_get_low_disassembly_address (struct gdbarch *gdbarch,
 void
 tui_disasm_window::do_scroll_vertical (int num_to_scroll)
 {
-  if (content != NULL)
+  if (!content.empty ())
     {
       CORE_ADDR pc;
       struct tui_line_or_address val;
 
-      pc = content[0]->which_element.source.line_or_addr.u.addr;
+      pc = content[0].line_or_addr.u.addr;
       if (num_to_scroll >= 0)
 	num_to_scroll++;
       else
diff --git a/gdb/tui/tui-layout.c b/gdb/tui/tui-layout.c
index ad99ec9abd9..9dbb5995998 100644
--- a/gdb/tui/tui-layout.c
+++ b/gdb/tui/tui-layout.c
@@ -81,7 +81,6 @@  show_layout (enum tui_layout_type layout)
       /* Since the new layout may cause changes in window size, we
          should free the content and reallocate on next display of
          source/asm.  */
-      tui_free_all_source_wins_content ();
       tui_clear_source_windows ();
       if (layout == SRC_DATA_COMMAND 
 	  || layout == DISASSEM_DATA_COMMAND)
diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c
index fd89d98ba16..4f82cbab2db 100644
--- a/gdb/tui/tui-source.c
+++ b/gdb/tui/tui-source.c
@@ -176,10 +176,11 @@  tui_set_source_content (struct symtab *s,
 	  cur_line_no = src->start_line_or_addr.u.line_no = line_no;
 
 	  const char *iter = srclines.c_str ();
+	  TUI_SRC_WIN->content.resize (nlines);
 	  while (cur_line < nlines)
 	    {
-	      struct tui_win_element *element
-		= TUI_SRC_WIN->content[cur_line];
+	      struct tui_source_element *element
+		= &TUI_SRC_WIN->content[cur_line];
 
 	      std::string text;
 	      if (*iter != '\0')
@@ -189,25 +190,20 @@  tui_set_source_content (struct symtab *s,
 
 	      /* Set whether element is the execution point
 		 and whether there is a break point on it.  */
-	      element->which_element.source.line_or_addr.loa =
-		LOA_LINE;
-	      element->which_element.source.line_or_addr.u.line_no =
-		cur_line_no;
-	      element->which_element.source.is_exec_point =
-		(filename_cmp (locator->full_name,
-			       symtab_to_fullname (s)) == 0
-		 && cur_line_no == locator->line_no);
-
-	      xfree (TUI_SRC_WIN->content[cur_line]
-		     ->which_element.source.line);
-	      TUI_SRC_WIN->content[cur_line]
-		->which_element.source.line
+	      element->line_or_addr.loa = LOA_LINE;
+	      element->line_or_addr.u.line_no = cur_line_no;
+	      element->is_exec_point
+		= (filename_cmp (locator->full_name,
+				 symtab_to_fullname (s)) == 0
+		   && cur_line_no == locator->line_no);
+
+	      xfree (TUI_SRC_WIN->content[cur_line].line);
+	      TUI_SRC_WIN->content[cur_line].line
 		= xstrdup (text.c_str ());
 
 	      cur_line++;
 	      cur_line_no++;
 	    }
-	  TUI_SRC_WIN->content_size = nlines;
 	  ret = TUI_SUCCESS;
 	}
     }
@@ -234,21 +230,21 @@  tui_set_source_content_nil (struct tui_source_window_base *win_info,
 
   /* Set to empty each line in the window, except for the one which
      contains the message.  */
-  while (curr_line < win_info->content_size)
+  while (curr_line < win_info->content.size ())
     {
       /* Set the information related to each displayed line to null:
          i.e. the line number is 0, there is no bp, it is not where
          the program is stopped.  */
 
-      struct tui_win_element *element = win_info->content[curr_line];
+      struct tui_source_element *element = &win_info->content[curr_line];
 
-      element->which_element.source.line_or_addr.loa = LOA_LINE;
-      element->which_element.source.line_or_addr.u.line_no = 0;
-      element->which_element.source.is_exec_point = false;
-      element->which_element.source.has_break = FALSE;
+      element->line_or_addr.loa = LOA_LINE;
+      element->line_or_addr.u.line_no = 0;
+      element->is_exec_point = false;
+      element->has_break = FALSE;
 
       /* Set the contents of the line to blank.  */
-      element->which_element.source.line[0] = (char) 0;
+      element->line[0] = (char) 0;
 
       /* If the current line is in the middle of the screen, then we
          want to display the 'no source available' message in it.
@@ -269,8 +265,8 @@  tui_set_source_content_nil (struct tui_source_window_base *win_info,
 	    xpos = (line_width - 1) / 2 - warning_length;
 
 	  src_line = xstrprintf ("%s%s", n_spaces (xpos), warning_string);
-	  xfree (element->which_element.source.line);
-	  element->which_element.source.line = src_line;
+	  xfree (element->line);
+	  element->line = src_line;
 	}
 
       curr_line++;
@@ -306,7 +302,7 @@  tui_source_is_displayed (const char *fullname)
 void
 tui_source_window::do_scroll_vertical (int num_to_scroll)
 {
-  if (content != NULL)
+  if (!content.empty ())
     {
       struct tui_line_or_address l;
       struct symtab *s;
@@ -318,13 +314,12 @@  tui_source_window::do_scroll_vertical (int num_to_scroll)
 	s = cursal.symtab;
 
       l.loa = LOA_LINE;
-      l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no
+      l.u.line_no = content[0].line_or_addr.u.line_no
 	+ num_to_scroll;
       if (l.u.line_no > s->nlines)
 	/* line = s->nlines - win_info->content_size + 1; */
 	/* elz: fix for dts 23398.  */
-	l.u.line_no
-	  = content[0]->which_element.source.line_or_addr.u.line_no;
+	l.u.line_no = content[0].line_or_addr.u.line_no;
       if (l.u.line_no <= 0)
 	l.u.line_no = 1;
 
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index f88ec970781..4763184b211 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -616,7 +616,7 @@  tui_resize_all (void)
 	  make_invisible_and_set_new_height (TUI_CMD_WIN, new_height);
 	  first_win->make_visible_with_new_height ();
 	  TUI_CMD_WIN->make_visible_with_new_height ();
-	  if (src_win->content_size <= 0)
+	  if (src_win->content.empty ())
 	    tui_erase_source_content (src_win, EMPTY_SOURCE_PROMPT);
 	  break;
 	default:
@@ -681,7 +681,7 @@  tui_resize_all (void)
 	  first_win->make_visible_with_new_height ();
 	  second_win->make_visible_with_new_height ();
 	  TUI_CMD_WIN->make_visible_with_new_height ();
-	  if (src_win->content_size <= 0)
+	  if (src_win->content.empty ())
 	    tui_erase_source_content (src_win, EMPTY_SOURCE_PROMPT);
 	  break;
 	}
@@ -1127,11 +1127,14 @@  tui_adjust_win_heights (struct tui_win_info *primary_win_info,
 	      win_info->make_visible_with_new_height ();
 	      primary_win_info->make_visible_with_new_height ();
 	      if ((src_win_info->type == SRC_WIN
-		   || src_win_info->type == DISASSEM_WIN)
-		  && src_win_info->content_size <= 0)
-		tui_erase_source_content
-		  ((tui_source_window_base *) src_win_info,
-		   EMPTY_SOURCE_PROMPT);
+		   || src_win_info->type == DISASSEM_WIN))
+		{
+		  tui_source_window_base *src_base
+		    = (tui_source_window_base *) src_win_info;
+		  if (src_base->content.empty ())
+		    tui_erase_source_content (src_base,
+					      EMPTY_SOURCE_PROMPT);
+		}
 	    }
 	  else
 	    {
@@ -1236,9 +1239,9 @@  tui_adjust_win_heights (struct tui_win_info *primary_win_info,
 	      TUI_CMD_WIN->make_visible_with_new_height ();
 	      second_win->make_visible_with_new_height ();
 	      first_win->make_visible_with_new_height ();
-	      if (src1 != nullptr && src1->content_size <= 0)
+	      if (src1 != nullptr && src1->content.empty ())
 		tui_erase_source_content (src1, EMPTY_SOURCE_PROMPT);
-	      if (second_win->content_size <= 0)
+	      if (second_win->content.empty ())
 		tui_erase_source_content (second_win, EMPTY_SOURCE_PROMPT);
 	    }
 	}
@@ -1319,16 +1322,14 @@  tui_win_info::make_visible_with_new_height ()
 void
 tui_source_window_base::do_make_visible_with_new_height ()
 {
-  tui_free_win_content (execution_info);
   tui_make_visible (execution_info);
-  if (content != NULL)
+  if (!content.empty ())
     {
       struct tui_line_or_address line_or_addr;
       struct symtab_and_line cursal
 	= get_current_source_symtab_and_line ();
 
       line_or_addr = start_line_or_addr;
-      tui_free_win_content (this);
       tui_update_source_window (this, gdbarch,
 				cursal.symtab, line_or_addr, TRUE);
     }
diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
index b11feff2a4d..93c6253fd65 100644
--- a/gdb/tui/tui-winsource.c
+++ b/gdb/tui/tui-winsource.c
@@ -113,7 +113,7 @@  tui_update_source_window_as_is (struct tui_source_window_base *win_info,
 	  symtab_and_line sal;
 
 	  sal.line = line_or_addr.u.line_no +
-	    (win_info->content_size - 2);
+	    (win_info->content.size () - 2);
 	  sal.symtab = s;
 	  sal.pspace = SYMTAB_PSPACE (s);
 	  set_current_source_symtab_and_line (sal);
@@ -213,12 +213,12 @@  tui_clear_source_content (struct tui_source_window_base *win_info,
 
       win_info->content_in_use = FALSE;
       tui_erase_source_content (win_info, display_prompt);
-      for (i = 0; i < win_info->content_size; i++)
+      for (i = 0; i < win_info->content.size (); i++)
 	{
-	  struct tui_win_element *element = win_info->content[i];
+	  struct tui_source_element *element = &win_info->content[i];
 
-	  element->which_element.source.has_break = FALSE;
-	  element->which_element.source.is_exec_point = false;
+	  element->has_break = FALSE;
+	  element->is_exec_point = false;
 	}
     }
 }
@@ -266,19 +266,19 @@  tui_erase_source_content (struct tui_source_window_base *win_info,
 
 /* Redraw the complete line of a source or disassembly window.  */
 static void
-tui_show_source_line (struct tui_win_info *win_info, int lineno)
+tui_show_source_line (struct tui_source_window_base *win_info, int lineno)
 {
-  struct tui_win_element *line;
+  struct tui_source_element *line;
   int x;
 
-  line = win_info->content[lineno - 1];
-  if (line->which_element.source.is_exec_point)
+  line = &win_info->content[lineno - 1];
+  if (line->is_exec_point)
     tui_set_reverse_mode (win_info->handle, true);
 
   wmove (win_info->handle, lineno, 1);
-  tui_puts (line->which_element.source.line,
+  tui_puts (line->line,
 	    win_info->handle);
-  if (line->which_element.source.is_exec_point)
+  if (line->is_exec_point)
     tui_set_reverse_mode (win_info->handle, false);
 
   /* Clear to end of line but stop before the border.  */
@@ -293,11 +293,11 @@  tui_show_source_line (struct tui_win_info *win_info, int lineno)
 void
 tui_show_source_content (struct tui_source_window_base *win_info)
 {
-  if (win_info->content_size > 0)
+  if (!win_info->content.empty ())
     {
       int lineno;
 
-      for (lineno = 1; lineno <= win_info->content_size; lineno++)
+      for (lineno = 1; lineno <= win_info->content.size (); lineno++)
         tui_show_source_line (win_info, lineno);
     }
   else
@@ -324,8 +324,7 @@  tui_source_window_base::refill ()
     }
 
   tui_update_source_window_as_is (this, gdbarch, s,
-				  content[0]
-				    ->which_element.source.line_or_addr,
+				  content[0].line_or_addr,
 				  FALSE);
 }
 
@@ -334,7 +333,7 @@  tui_source_window_base::refill ()
 void
 tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
 {
-  if (content != NULL)
+  if (!content.empty ())
     {
       int offset = horizontal_offset + num_to_scroll;
       if (offset < 0)
@@ -355,11 +354,11 @@  tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
   int i;
 
   i = 0;
-  while (i < content_size)
+  while (i < content.size ())
     {
       bool new_state;
       struct tui_line_or_address content_loa =
-	content[i]->which_element.source.line_or_addr;
+	content[i].line_or_addr;
 
       gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
       gdb_assert (content_loa.loa == LOA_LINE
@@ -370,10 +369,10 @@  tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
         new_state = true;
       else
 	new_state = false;
-      if (new_state != content[i]->which_element.source.is_exec_point)
+      if (new_state != content[i].is_exec_point)
         {
           changed = true;
-          content[i]->which_element.source.is_exec_point = new_state;
+          content[i].is_exec_point = new_state;
           tui_show_source_line (this, i + 1);
         }
       i++;
@@ -405,21 +404,21 @@  tui_update_all_breakpoint_info ()
    refreshed.  */
 
 int
-tui_update_breakpoint_info (struct tui_win_info *win, 
+tui_update_breakpoint_info (struct tui_source_window_base *win, 
 			    int current_only)
 {
   int i;
   int need_refresh = 0;
   tui_source_window_base *src = (tui_source_window_base *) win;
 
-  for (i = 0; i < win->content_size; i++)
+  for (i = 0; i < win->content.size (); i++)
     {
       struct breakpoint *bp;
       extern struct breakpoint *breakpoint_chain;
       int mode;
       struct tui_source_element *line;
 
-      line = &win->content[i]->which_element.source;
+      line = &win->content[i];
       if (current_only && !line->is_exec_point)
          continue;
 
@@ -493,20 +492,20 @@  tui_set_exec_info_content (struct tui_source_window_base *win_info)
 	= win_info->execution_info->maybe_allocate_content (win_info->height);
 
       tui_update_breakpoint_info (win_info, 1);
-      for (int i = 0; i < win_info->content_size; i++)
+      for (int i = 0; i < win_info->content.size (); i++)
 	{
 	  tui_exec_info_content &element = content[i];
-	  struct tui_win_element *src_element;
+	  struct tui_source_element *src_element;
 	  int mode;
 
-	  src_element = win_info->content[i];
+	  src_element = &win_info->content[i];
 
 	  memset (element, ' ', sizeof (tui_exec_info_content));
 	  element[TUI_EXECINFO_SIZE - 1] = 0;
 
 	  /* Now update the exec info content based upon the state
 	     of each line as indicated by the source content.  */
-	  mode = src_element->which_element.source.has_break;
+	  mode = src_element->has_break;
 	  if (mode & TUI_BP_HIT)
 	    element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
 	  else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
@@ -517,7 +516,7 @@  tui_set_exec_info_content (struct tui_source_window_base *win_info)
 	  else if (mode & TUI_BP_DISABLED)
 	    element[TUI_BP_BREAK_POS] = '-';
 
-	  if (src_element->which_element.source.is_exec_point)
+	  if (src_element->is_exec_point)
 	    element[TUI_EXEC_POS] = '>';
 	}
     }
@@ -532,7 +531,7 @@  tui_show_exec_info_content (struct tui_source_window_base *win_info)
 
   werase (exec_info->handle);
   exec_info->refresh_window ();
-  for (int cur_line = 1; (cur_line <= win_info->content_size); cur_line++)
+  for (int cur_line = 1; cur_line <= win_info->content.size (); cur_line++)
     mvwaddstr (exec_info->handle,
 	       cur_line,
 	       0,
@@ -567,7 +566,7 @@  tui_update_exec_info (struct tui_source_window_base *win_info)
 }
 
 void
-tui_alloc_source_buffer (struct tui_win_info *win_info)
+tui_alloc_source_buffer (struct tui_source_window_base *win_info)
 {
   int i, line_width, max_lines;
 
@@ -577,13 +576,11 @@  tui_alloc_source_buffer (struct tui_win_info *win_info)
   line_width = win_info->width - 2 + 1;
 
   /* Allocate the buffer for the source lines.  */
-  if (win_info->content == NULL)
+  win_info->content.resize (max_lines);
+  for (i = 0; i < max_lines; i++)
     {
-      /* Allocate the content list.  */
-      win_info->content = tui_alloc_content (max_lines, SRC_WIN);
-      for (i = 0; i < max_lines; i++)
-	win_info->content[i]->which_element.source.line
-	  = (char *) xmalloc (line_width);
+      if (win_info->content[i].line == nullptr)
+	win_info->content[i].line = (char *) xmalloc (line_width);
     }
 }
 
@@ -592,7 +589,7 @@  tui_alloc_source_buffer (struct tui_win_info *win_info)
    in the current source window.  */
 int
 tui_line_is_displayed (int line, 
-		       struct tui_win_info *win_info,
+		       struct tui_source_window_base *win_info,
 		       int check_threshold)
 {
   int is_displayed = FALSE;
@@ -603,14 +600,12 @@  tui_line_is_displayed (int line,
   else
     threshold = 0;
   i = 0;
-  while (i < win_info->content_size - threshold
+  while (i < win_info->content.size () - threshold
 	 && !is_displayed)
     {
       is_displayed
-	= win_info->content[i]
-	    ->which_element.source.line_or_addr.loa == LOA_LINE
-	  && win_info->content[i]
-	       ->which_element.source.line_or_addr.u.line_no == line;
+	= win_info->content[i].line_or_addr.loa == LOA_LINE
+	  && win_info->content[i].line_or_addr.u.line_no == line;
       i++;
     }
 
@@ -622,7 +617,7 @@  tui_line_is_displayed (int line,
    in the current source window.  */
 int
 tui_addr_is_displayed (CORE_ADDR addr, 
-		       struct tui_win_info *win_info,
+		       struct tui_source_window_base *win_info,
 		       int check_threshold)
 {
   int is_displayed = FALSE;
@@ -633,14 +628,12 @@  tui_addr_is_displayed (CORE_ADDR addr,
   else
     threshold = 0;
   i = 0;
-  while (i < win_info->content_size - threshold
+  while (i < win_info->content.size () - threshold
 	 && !is_displayed)
     {
       is_displayed
-	= win_info->content[i]
-	    ->which_element.source.line_or_addr.loa == LOA_ADDRESS
-	  && win_info->content[i]
-	       ->which_element.source.line_or_addr.u.addr == addr;
+	= win_info->content[i].line_or_addr.loa == LOA_ADDRESS
+	  && win_info->content[i].line_or_addr.u.addr == addr;
       i++;
     }
 
diff --git a/gdb/tui/tui-winsource.h b/gdb/tui/tui-winsource.h
index f914c0aaf14..adf4af45359 100644
--- a/gdb/tui/tui-winsource.h
+++ b/gdb/tui/tui-winsource.h
@@ -34,7 +34,7 @@  extern void tui_update_all_breakpoint_info (void);
 /* Scan the source window and the breakpoints to update the hasBreak
    information for each line.  Returns 1 if something changed and the
    execution window must be refreshed.  */
-extern int tui_update_breakpoint_info (struct tui_win_info *win,
+extern int tui_update_breakpoint_info (struct tui_source_window_base *win,
 				       int current_only);
 
 /* Function to display the "main" routine.  */
@@ -59,12 +59,12 @@  extern void tui_erase_exec_info_content (struct tui_source_window_base *);
 extern void tui_clear_exec_info_content (struct tui_source_window_base *);
 extern void tui_update_exec_info (struct tui_source_window_base *);
 
-extern void tui_alloc_source_buffer (struct tui_win_info *);
-extern int tui_line_is_displayed (int, 
-				  struct tui_win_info *, 
+extern void tui_alloc_source_buffer (struct tui_source_window_base *);
+extern int tui_line_is_displayed (int,
+				  struct tui_source_window_base *,
 				  int);
-extern int tui_addr_is_displayed (CORE_ADDR, 
-				  struct tui_win_info *, 
+extern int tui_addr_is_displayed (CORE_ADDR,
+				  struct tui_source_window_base *,
 				  int);