/* Diagnostic subroutines for printing source-code
   Copyright (C) 1999-2022 Free Software Foundation, Inc.
   Contributed by Gabriel Dos Reis <gdr@codesourcery.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "version.h"
#include "demangle.h"
#include "intl.h"
#include "backtrace.h"
#include "diagnostic.h"
#include "diagnostic-color.h"
#include "gcc-rich-location.h"
#include "selftest.h"
#include "selftest-diagnostic.h"
#include "cpplib.h"

#ifdef HAVE_TERMIOS_H
# include <termios.h>
#endif

#ifdef GWINSZ_IN_SYS_IOCTL
# include <sys/ioctl.h>
#endif

/* Disable warnings about quoting issues in the pp_xxx calls below
   that (intentionally) don't follow GCC diagnostic conventions.  */
#if __GNUC__ >= 10
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wformat-diag"
#endif

/* Classes for rendering source code and diagnostics, within an
   anonymous namespace.
   The work is done by "class layout", which embeds and uses
   "class colorizer" and "class layout_range" to get things done.  */

namespace {

/* The state at a given point of the source code, assuming that we're
   in a range: which range are we in, and whether we should draw a caret at
   this point.  */

struct point_state
{
  int range_idx;
  bool draw_caret_p;
};

/* A class to inject colorization codes when printing the diagnostic locus.

   It has one kind of colorization for each of:
     - normal text
     - range 0 (the "primary location")
     - range 1
     - range 2

   The class caches the lookup of the color codes for the above.

   The class also has responsibility for tracking which of the above is
   active, filtering out unnecessary changes.  This allows
   layout::print_source_line and layout::print_annotation_line
   to simply request a colorization code for *every* character they print,
   via this class, and have the filtering be done for them here.  */

class colorizer
{
 public:
  colorizer (diagnostic_context *context,
	     diagnostic_t diagnostic_kind);
  ~colorizer ();

  void set_range (int range_idx)
  {
    /* Normally we emphasize the primary location, then alternate between
       two colors for the secondary locations.
       But if we're printing a run of events in a diagnostic path, that
       makes no sense, so print all of them with the same colorization.  */
    if (m_diagnostic_kind == DK_DIAGNOSTIC_PATH)
      set_state (0);
    else
      set_state (range_idx);
  }
  void set_normal_text () { set_state (STATE_NORMAL_TEXT); }
  void set_fixit_insert () { set_state (STATE_FIXIT_INSERT); }
  void set_fixit_delete () { set_state (STATE_FIXIT_DELETE); }

 private:
  void set_state (int state);
  void begin_state (int state);
  void finish_state (int state);
  const char *get_color_by_name (const char *);

 private:
  static const int STATE_NORMAL_TEXT = -1;
  static const int STATE_FIXIT_INSERT  = -2;
  static const int STATE_FIXIT_DELETE  = -3;

  diagnostic_context *m_context;
  diagnostic_t m_diagnostic_kind;
  int m_current_state;
  const char *m_range1;
  const char *m_range2;
  const char *m_fixit_insert;
  const char *m_fixit_delete;
  const char *m_stop_color;
};

/* In order to handle multibyte sources properly, all of this logic needs to be
   aware of the distinction between the number of bytes and the number of
   display columns occupied by a character, which are not the same for non-ASCII
   characters.  For example, the Unicode pi symbol, U+03C0, is encoded in UTF-8
   as "\xcf\x80", and thus occupies 2 bytes of space while only occupying 1
   display column when it is output.  A typical emoji, such as U+1F602 (in
   UTF-8, "\xf0\x9f\x98\x82"), requires 4 bytes and has a display width of 2.

   The below example line, which is also used for selftests below, shows how the
   display column and byte column are related:

     0000000001111111111222222   display
     1234567890123456789012345   columns
     SS_foo = P_bar.SS_fieldP;
     0000000111111111222222223   byte
     1356789012456789134567891   columns

   Here SS represents the two display columns for the U+1F602 emoji, and P
   represents the one display column for the U+03C0 pi symbol.  As an example, a
   diagnostic pointing to the final P on this line is at byte column 29 and
   display column 24.  This reflects the fact that the three extended characters
   before the final P occupy cumulatively 5 more bytes than they do display
   columns (a difference of 2 for each of the two SSs, and one for the other P).

   One or the other of the two column units is more useful depending on the
   context.  For instance, in order to output the caret at the correct location,
   we need to count display columns; in order to colorize a source line, we need
   to count the bytes.  All locations are provided to us as byte counts, which
   we augment with the display column on demand so that it can be used when
   needed.  This is not the most efficient way to do things since it requires
   looping over the whole line each time, but it should be fine for the purpose
   of outputting diagnostics.

   In order to keep straight which units (byte or display) are in use at a
   given time, the following enum lets us specify that explicitly.  */

enum column_unit {
  /* Measured in raw bytes.  */
  CU_BYTES = 0,

  /* Measured in display units.  */
  CU_DISPLAY_COLS,

  /* For arrays indexed by column_unit.  */
  CU_NUM_UNITS
};

/* Utility class to augment an exploc with the corresponding display column.  */

class exploc_with_display_col : public expanded_location
{
 public:
  exploc_with_display_col (const expanded_location &exploc,
			   const cpp_char_column_policy &policy,
			   enum location_aspect aspect)
  : expanded_location (exploc),
    m_display_col (location_compute_display_column (exploc, policy))
  {
    if (exploc.column > 0)
      {
	/* m_display_col is now the final column of the byte.
	   If escaping has happened, we may want the first column instead.  */
	if (aspect != LOCATION_ASPECT_FINISH)
	  {
	    expanded_location prev_exploc (exploc);
	    prev_exploc.column--;
	    int prev_display_col
	      = (location_compute_display_column (prev_exploc, policy));
	    m_display_col = prev_display_col + 1;
	  }
      }
  }

  int m_display_col;
};


/* A point within a layout_range; similar to an exploc_with_display_col,
   but after filtering on file.  */

class layout_point
{
 public:
  layout_point (const exploc_with_display_col &exploc)
    : m_line (exploc.line)
  {
    m_columns[CU_BYTES] = exploc.column;
    m_columns[CU_DISPLAY_COLS] = exploc.m_display_col;
  }

  linenum_type m_line;
  int m_columns[CU_NUM_UNITS];
};

/* A class for use by "class layout" below: a filtered location_range.  */

class layout_range
{
 public:
  layout_range (const exploc_with_display_col &start_exploc,
		const exploc_with_display_col &finish_exploc,
		enum range_display_kind range_display_kind,
		const exploc_with_display_col &caret_exploc,
		unsigned original_idx,
		const range_label *label);

  bool contains_point (linenum_type row, int column,
		       enum column_unit col_unit) const;
  bool intersects_line_p (linenum_type row) const;

  layout_point m_start;
  layout_point m_finish;
  enum range_display_kind m_range_display_kind;
  layout_point m_caret;
  unsigned m_original_idx;
  const range_label *m_label;
};

/* A struct for use by layout::print_source_line for telling
   layout::print_annotation_line the extents of the source line that
   it printed, so that underlines can be clipped appropriately.  Units
   are 1-based display columns.  */

struct line_bounds
{
  int m_first_non_ws_disp_col;
  int m_last_non_ws_disp_col;

  line_bounds ()
  {
    m_first_non_ws_disp_col = INT_MAX;
    m_last_non_ws_disp_col = 0;
  }
};

/* A range of contiguous source lines within a layout (e.g. "lines 5-10"
   or "line 23").  During the layout ctor, layout::calculate_line_spans
   splits the pertinent source lines into a list of disjoint line_span
   instances (e.g. lines 5-10, lines 15-20, line 23).  */

class line_span
{
public:
  line_span (linenum_type first_line, linenum_type last_line)
    : m_first_line (first_line), m_last_line (last_line)
  {
    gcc_assert (first_line <= last_line);
  }
  linenum_type get_first_line () const { return m_first_line; }
  linenum_type get_last_line () const { return m_last_line; }

  bool contains_line_p (linenum_type line) const
  {
    return line >= m_first_line && line <= m_last_line;
  }

  static int comparator (const void *p1, const void *p2)
  {
    const line_span *ls1 = (const line_span *)p1;
    const line_span *ls2 = (const line_span *)p2;
    int first_line_cmp = compare (ls1->m_first_line, ls2->m_first_line);
    if (first_line_cmp)
      return first_line_cmp;
    return compare (ls1->m_last_line, ls2->m_last_line);
  }

  linenum_type m_first_line;
  linenum_type m_last_line;
};

#if CHECKING_P

/* Selftests for line_span.  */

static void
test_line_span ()
{
  line_span line_one (1, 1);
  ASSERT_EQ (1, line_one.get_first_line ());
  ASSERT_EQ (1, line_one.get_last_line ());
  ASSERT_FALSE (line_one.contains_line_p (0));
  ASSERT_TRUE (line_one.contains_line_p (1));
  ASSERT_FALSE (line_one.contains_line_p (2));

  line_span lines_1_to_3 (1, 3);
  ASSERT_EQ (1, lines_1_to_3.get_first_line ());
  ASSERT_EQ (3, lines_1_to_3.get_last_line ());
  ASSERT_TRUE (lines_1_to_3.contains_line_p (1));
  ASSERT_TRUE (lines_1_to_3.contains_line_p (3));

  ASSERT_EQ (0, line_span::comparator (&line_one, &line_one));
  ASSERT_GT (line_span::comparator (&lines_1_to_3, &line_one), 0);
  ASSERT_LT (line_span::comparator (&line_one, &lines_1_to_3), 0);

  /* A linenum > 2^31.  */
  const linenum_type LARGEST_LINE = 0xffffffff;
  line_span largest_line (LARGEST_LINE, LARGEST_LINE);
  ASSERT_EQ (LARGEST_LINE, largest_line.get_first_line ());
  ASSERT_EQ (LARGEST_LINE, largest_line.get_last_line ());

  ASSERT_GT (line_span::comparator (&largest_line, &line_one), 0);
  ASSERT_LT (line_span::comparator (&line_one, &largest_line), 0);
}

#endif /* #if CHECKING_P */

/* A bundle of information containing how to print unicode
   characters and bytes when quoting source code.

   Provides a unified place to support escaping some subset
   of characters to some format.

   Extends char_column_policy; printing is split out to avoid
   libcpp having to know about pretty_printer.  */

struct char_display_policy : public cpp_char_column_policy
{
 public:
  char_display_policy (int tabstop,
		       int (*width_cb) (cppchar_t c),
		       void (*print_cb) (pretty_printer *pp,
					 const cpp_decoded_char &cp))
  : cpp_char_column_policy (tabstop, width_cb),
    m_print_cb (print_cb)
  {
  }

  void (*m_print_cb) (pretty_printer *pp,
		      const cpp_decoded_char &cp);
};

/* A class to control the overall layout when printing a diagnostic.

   The layout is determined within the constructor.
   It is then printed by repeatedly calling the "print_source_line",
   "print_annotation_line" and "print_any_fixits" methods.

   We assume we have disjoint ranges.  */

class layout
{
 public:
  layout (diagnostic_context *context,
	  rich_location *richloc,
	  diagnostic_t diagnostic_kind);

  bool maybe_add_location_range (const location_range *loc_range,
				 unsigned original_idx,
				 bool restrict_to_current_line_spans);

  int get_num_line_spans () const { return m_line_spans.length (); }
  const line_span *get_line_span (int idx) const { return &m_line_spans[idx]; }

  int get_linenum_width () const { return m_linenum_width; }
  int get_x_offset_display () const { return m_x_offset_display; }

  void print_gap_in_line_numbering ();
  bool print_heading_for_line_span_index_p (int line_span_idx) const;

  expanded_location get_expanded_location (const line_span *) const;

  void print_line (linenum_type row);

  void on_bad_codepoint (const char *ptr, cppchar_t ch, size_t ch_sz);

 private:
  bool will_show_line_p (linenum_type row) const;
  void print_leading_fixits (linenum_type row);
  line_bounds print_source_line (linenum_type row, const char *line,
				 int line_bytes);
  bool should_print_annotation_line_p (linenum_type row) const;
  void start_annotation_line (char margin_char = ' ') const;
  void print_annotation_line (linenum_type row, const line_bounds lbounds);
  void print_any_labels (linenum_type row);
  void print_trailing_fixits (linenum_type row);

  bool annotation_line_showed_range_p (linenum_type line, int start_column,
				       int finish_column) const;
  void show_ruler (int max_column) const;

  bool validate_fixit_hint_p (const fixit_hint *hint);

  void calculate_line_spans ();
  void calculate_linenum_width ();
  void calculate_x_offset_display ();

  void print_newline ();

  bool
  get_state_at_point (/* Inputs.  */
		      linenum_type row, int column,
		      int first_non_ws, int last_non_ws,
		      enum column_unit col_unit,
		      /* Outputs.  */
		      point_state *out_state);

  int
  get_x_bound_for_row (linenum_type row, int caret_column,
		       int last_non_ws);

  void
  move_to_column (int *column, int dest_column, bool add_left_margin);

 private:
  diagnostic_context *m_context;
  pretty_printer *m_pp;
  char_display_policy m_policy;
  location_t m_primary_loc;
  exploc_with_display_col m_exploc;
  colorizer m_colorizer;
  bool m_colorize_source_p;
  bool m_show_labels_p;
  bool m_show_line_numbers_p;
  bool m_diagnostic_path_p;
  auto_vec <layout_range> m_layout_ranges;
  auto_vec <const fixit_hint *> m_fixit_hints;
  auto_vec <line_span> m_line_spans;
  int m_linenum_width;
  int m_x_offset_display;
  bool m_escape_on_output;
};

/* Implementation of "class colorizer".  */

/* The constructor for "colorizer".  Lookup and store color codes for the
   different kinds of things we might need to print.  */

colorizer::colorizer (diagnostic_context *context,
		      diagnostic_t diagnostic_kind) :
  m_context (context),
  m_diagnostic_kind (diagnostic_kind),
  m_current_state (STATE_NORMAL_TEXT)
{
  m_range1 = get_color_by_name ("range1");
  m_range2 = get_color_by_name ("range2");
  m_fixit_insert = get_color_by_name ("fixit-insert");
  m_fixit_delete = get_color_by_name ("fixit-delete");
  m_stop_color = colorize_stop (pp_show_color (context->printer));
}

/* The destructor for "colorize".  If colorization is on, print a code to
   turn it off.  */

colorizer::~colorizer ()
{
  finish_state (m_current_state);
}

/* Update state, printing color codes if necessary if there's a state
   change.  */

void
colorizer::set_state (int new_state)
{
  if (m_current_state != new_state)
    {
      finish_state (m_current_state);
      m_current_state = new_state;
      begin_state (new_state);
    }
}

/* Turn on any colorization for STATE.  */

void
colorizer::begin_state (int state)
{
  switch (state)
    {
    case STATE_NORMAL_TEXT:
      break;

    case STATE_FIXIT_INSERT:
      pp_string (m_context->printer, m_fixit_insert);
      break;

    case STATE_FIXIT_DELETE:
      pp_string (m_context->printer, m_fixit_delete);
      break;

    case 0:
      /* Make range 0 be the same color as the "kind" text
	 (error vs warning vs note).  */
      pp_string
	(m_context->printer,
	 colorize_start (pp_show_color (m_context->printer),
			 diagnostic_get_color_for_kind (m_diagnostic_kind)));
      break;

    case 1:
      pp_string (m_context->printer, m_range1);
      break;

    case 2:
      pp_string (m_context->printer, m_range2);
      break;

    default:
      /* For ranges beyond 2, alternate between color 1 and color 2.  */
      {
	gcc_assert (state > 2);
	pp_string (m_context->printer,
		   state % 2 ? m_range1 : m_range2);
      }
      break;
    }
}

/* Turn off any colorization for STATE.  */

void
colorizer::finish_state (int state)
{
  if (state != STATE_NORMAL_TEXT)
    pp_string (m_context->printer, m_stop_color);
}

/* Get the color code for NAME (or the empty string if
   colorization is disabled).  */

const char *
colorizer::get_color_by_name (const char *name)
{
  return colorize_start (pp_show_color (m_context->printer), name);
}

/* Implementation of class layout_range.  */

/* The constructor for class layout_range.
   Initialize various layout_point fields from expanded_location
   equivalents; we've already filtered on file.  */

layout_range::layout_range (const exploc_with_display_col &start_exploc,
			    const exploc_with_display_col &finish_exploc,
			    enum range_display_kind range_display_kind,
			    const exploc_with_display_col &caret_exploc,
			    unsigned original_idx,
			    const range_label *label)
: m_start (start_exploc),
  m_finish (finish_exploc),
  m_range_display_kind (range_display_kind),
  m_caret (caret_exploc),
  m_original_idx (original_idx),
  m_label (label)
{
}

/* Is (column, row) within the given range?
   We've already filtered on the file.

   Ranges are closed (both limits are within the range).

   Example A: a single-line range:
     start:  (col=22, line=2)
     finish: (col=38, line=2)

  |00000011111111112222222222333333333344444444444
  |34567890123456789012345678901234567890123456789
--+-----------------------------------------------
01|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
02|bbbbbbbbbbbbbbbbbbbSwwwwwwwwwwwwwwwFaaaaaaaaaaa
03|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

   Example B: a multiline range with
     start:  (col=14, line=3)
     finish: (col=08, line=5)

  |00000011111111112222222222333333333344444444444
  |34567890123456789012345678901234567890123456789
--+-----------------------------------------------
01|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
02|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
03|bbbbbbbbbbbSwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
04|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
05|wwwwwFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
06|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
--+-----------------------------------------------

   Legend:
   - 'b' indicates a point *before* the range
   - 'S' indicates the start of the range
   - 'w' indicates a point within the range
   - 'F' indicates the finish of the range (which is
	 within it).
   - 'a' indicates a subsequent point *after* the range.

   COL_UNIT controls whether we check the byte column or
   the display column; one or the other is more convenient
   depending on the context.  */

bool
layout_range::contains_point (linenum_type row, int column,
			      enum column_unit col_unit) const
{
  gcc_assert (m_start.m_line <= m_finish.m_line);
  /* ...but the equivalent isn't true for the columns;
     consider example B in the comment above.  */

  if (row < m_start.m_line)
    /* Points before the first line of the range are
       outside it (corresponding to line 01 in example A
       and lines 01 and 02 in example B above).  */
    return false;

  if (row == m_start.m_line)
    /* On same line as start of range (corresponding
       to line 02 in example A and line 03 in example B).  */
    {
      if (column < m_start.m_columns[col_unit])
	/* Points on the starting line of the range, but
	   before the column in which it begins.  */
	return false;

      if (row < m_finish.m_line)
	/* This is a multiline range; the point
	   is within it (corresponds to line 03 in example B
	   from column 14 onwards) */
	return true;
      else
	{
	  /* This is a single-line range.  */
	  gcc_assert (row == m_finish.m_line);
	  return column <= m_finish.m_columns[col_unit];
	}
    }

  /* The point is in a line beyond that containing the
     start of the range: lines 03 onwards in example A,
     and lines 04 onwards in example B.  */
  gcc_assert (row > m_start.m_line);

  if (row > m_finish.m_line)
    /* The point is beyond the final line of the range
       (lines 03 onwards in example A, and lines 06 onwards
       in example B).  */
    return false;

  if (row < m_finish.m_line)
    {
      /* The point is in a line that's fully within a multiline
	 range (e.g. line 04 in example B).  */
      gcc_assert (m_start.m_line < m_finish.m_line);
      return true;
    }

  gcc_assert (row ==  m_finish.m_line);

  return column <= m_finish.m_columns[col_unit];
}

/* Does this layout_range contain any part of line ROW?  */

bool
layout_range::intersects_line_p (linenum_type row) const
{
  gcc_assert (m_start.m_line <= m_finish.m_line);
  if (row < m_start.m_line)
    return false;
  if (row > m_finish.m_line)
    return false;
  return true;
}

#if CHECKING_P

/* Default for when we don't care what the tab expansion is set to.  */
static const int def_tabstop = 8;

static cpp_char_column_policy def_policy ()
{
  return cpp_char_column_policy (def_tabstop, cpp_wcwidth);
}

/* Create some expanded locations for testing layout_range.  The filename
   member of the explocs is set to the empty string.  This member will only be
   inspected by the calls to location_compute_display_column() made from the
   layout_point constructors.  That function will check for an empty filename
   argument and not attempt to open it, rather treating the non-existent data
   as if the display width were the same as the byte count.  Tests exercising a
   real difference between byte count and display width are performed later,
   e.g. in test_diagnostic_show_locus_one_liner_utf8().  */

static layout_range
make_range (int start_line, int start_col, int end_line, int end_col)
{
  const expanded_location start_exploc
    = {"", start_line, start_col, NULL, false};
  const expanded_location finish_exploc
    = {"", end_line, end_col, NULL, false};
  return layout_range (exploc_with_display_col (start_exploc, def_policy (),
						LOCATION_ASPECT_START),
		       exploc_with_display_col (finish_exploc, def_policy (),
						LOCATION_ASPECT_FINISH),
		       SHOW_RANGE_WITHOUT_CARET,
		       exploc_with_display_col (start_exploc, def_policy (),
						LOCATION_ASPECT_CARET),
		       0, NULL);
}

/* Selftests for layout_range::contains_point and
   layout_range::intersects_line_p.  */

/* Selftest for layout_range, where the layout_range
   is a range with start==end i.e. a single point.  */

static void
test_layout_range_for_single_point ()
{
  layout_range point = make_range (7, 10, 7, 10);

  /* Tests for layout_range::contains_point.  */

  for (int i = 0; i != CU_NUM_UNITS; ++i)
    {
      const enum column_unit col_unit = (enum column_unit) i;

      /* Before the line.  */
      ASSERT_FALSE (point.contains_point (6, 1, col_unit));

      /* On the line, but before start.  */
      ASSERT_FALSE (point.contains_point (7, 9, col_unit));

      /* At the point.  */
      ASSERT_TRUE (point.contains_point (7, 10, col_unit));

      /* On the line, after the point.  */
      ASSERT_FALSE (point.contains_point (7, 11, col_unit));

      /* After the line.  */
      ASSERT_FALSE (point.contains_point (8, 1, col_unit));
    }

  /* Tests for layout_range::intersects_line_p.  */
  ASSERT_FALSE (point.intersects_line_p (6));
  ASSERT_TRUE (point.intersects_line_p (7));
  ASSERT_FALSE (point.intersects_line_p (8));
}

/* Selftest for layout_range, where the layout_range
   is the single-line range shown as "Example A" above.  */

static void
test_layout_range_for_single_line ()
{
  layout_range example_a = make_range (2, 22, 2, 38);

  /* Tests for layout_range::contains_point.  */

  for (int i = 0; i != CU_NUM_UNITS; ++i)
    {
      const enum column_unit col_unit = (enum column_unit) i;

      /* Before the line.  */
      ASSERT_FALSE (example_a.contains_point (1, 1, col_unit));

      /* On the line, but before start.  */
      ASSERT_FALSE (example_a.contains_point (2, 21, col_unit));

      /* On the line, at the start.  */
      ASSERT_TRUE (example_a.contains_point (2, 22, col_unit));

      /* On the line, within the range.  */
      ASSERT_TRUE (example_a.contains_point (2, 23, col_unit));

      /* On the line, at the end.  */
      ASSERT_TRUE (example_a.contains_point (2, 38, col_unit));

      /* On the line, after the end.  */
      ASSERT_FALSE (example_a.contains_point (2, 39, col_unit));

      /* After the line.  */
      ASSERT_FALSE (example_a.contains_point (2, 39, col_unit));
    }

  /* Tests for layout_range::intersects_line_p.  */
  ASSERT_FALSE (example_a.intersects_line_p (1));
  ASSERT_TRUE (example_a.intersects_line_p (2));
  ASSERT_FALSE (example_a.intersects_line_p (3));
}

/* Selftest for layout_range, where the layout_range
   is the multi-line range shown as "Example B" above.  */

static void
test_layout_range_for_multiple_lines ()
{
  layout_range example_b = make_range (3, 14, 5, 8);

  /* Tests for layout_range::contains_point.  */

  for (int i = 0; i != CU_NUM_UNITS; ++i)
    {
      const enum column_unit col_unit = (enum column_unit) i;

      /* Before first line.  */
      ASSERT_FALSE (example_b.contains_point (1, 1, col_unit));

      /* On the first line, but before start.  */
      ASSERT_FALSE (example_b.contains_point (3, 13, col_unit));

      /* At the start.  */
      ASSERT_TRUE (example_b.contains_point (3, 14, col_unit));

      /* On the first line, within the range.  */
      ASSERT_TRUE (example_b.contains_point (3, 15, col_unit));

      /* On an interior line.
	 The column number should not matter; try various boundary
	 values.  */
      ASSERT_TRUE (example_b.contains_point (4, 1, col_unit));
      ASSERT_TRUE (example_b.contains_point (4, 7, col_unit));
      ASSERT_TRUE (example_b.contains_point (4, 8, col_unit));
      ASSERT_TRUE (example_b.contains_point (4, 9, col_unit));
      ASSERT_TRUE (example_b.contains_point (4, 13, col_unit));
      ASSERT_TRUE (example_b.contains_point (4, 14, col_unit));
      ASSERT_TRUE (example_b.contains_point (4, 15, col_unit));

      /* On the final line, before the end.  */
      ASSERT_TRUE (example_b.contains_point (5, 7, col_unit));

      /* On the final line, at the end.  */
      ASSERT_TRUE (example_b.contains_point (5, 8, col_unit));

      /* On the final line, after the end.  */
      ASSERT_FALSE (example_b.contains_point (5, 9, col_unit));

      /* After the line.  */
      ASSERT_FALSE (example_b.contains_point (6, 1, col_unit));
    }

  /* Tests for layout_range::intersects_line_p.  */
  ASSERT_FALSE (example_b.intersects_line_p (2));
  ASSERT_TRUE (example_b.intersects_line_p (3));
  ASSERT_TRUE (example_b.intersects_line_p (4));
  ASSERT_TRUE (example_b.intersects_line_p (5));
  ASSERT_FALSE (example_b.intersects_line_p (6));
}

#endif /* #if CHECKING_P */

/* Given a source line LINE of length LINE_BYTES bytes, determine the length
   (still in bytes, not display cols) without any trailing whitespace.  */

static int
get_line_bytes_without_trailing_whitespace (const char *line, int line_bytes)
{
  int result = line_bytes;
  while (result > 0)
    {
      char ch = line[result - 1];
      if (ch == ' ' || ch == '\t' || ch == '\r')
	result--;
      else
	break;
    }
  gcc_assert (result >= 0);
  gcc_assert (result <= line_bytes);
  gcc_assert (result == 0 ||
	      (line[result - 1] != ' '
	       && line[result -1] != '\t'
	       && line[result -1] != '\r'));
  return result;
}

#if CHECKING_P

/* A helper function for testing get_line_bytes_without_trailing_whitespace.  */

static void
assert_eq (const char *line, int expected_bytes)
{
  int actual_value
    = get_line_bytes_without_trailing_whitespace (line, strlen (line));
  ASSERT_EQ (actual_value, expected_bytes);
}

/* Verify that get_line_bytes_without_trailing_whitespace is sane for
   various inputs.  It is not required to handle newlines.  */

static void
test_get_line_bytes_without_trailing_whitespace ()
{
  assert_eq ("", 0);
  assert_eq (" ", 0);
  assert_eq ("\t", 0);
  assert_eq ("\r", 0);
  assert_eq ("hello world", 11);
  assert_eq ("hello world     ", 11);
  assert_eq ("hello world     \t\t  ", 11);
  assert_eq ("hello world\r", 11);
}

#endif /* #if CHECKING_P */

/* Helper function for layout's ctor, for sanitizing locations relative
   to the primary location within a diagnostic.

   Compare LOC_A and LOC_B to see if it makes sense to print underlines
   connecting their expanded locations.  Doing so is only guaranteed to
   make sense if the locations share the same macro expansion "history"
   i.e. they can be traced through the same macro expansions, eventually
   reaching an ordinary map.

   This may be too strong a condition, but it effectively sanitizes
   PR c++/70105, which has an example of printing an expression where the
   final location of the expression is in a different macro, which
   erroneously was leading to hundreds of lines of irrelevant source
   being printed.  */

static bool
compatible_locations_p (location_t loc_a, location_t loc_b)
{
  if (IS_ADHOC_LOC (loc_a))
    loc_a = get_location_from_adhoc_loc (line_table, loc_a);
  if (IS_ADHOC_LOC (loc_b))
    loc_b = get_location_from_adhoc_loc (line_table, loc_b);

  /* If either location is one of the special locations outside of a
     linemap, they are only compatible if they are equal.  */
  if (loc_a < RESERVED_LOCATION_COUNT
      || loc_b < RESERVED_LOCATION_COUNT)
    return loc_a == loc_b;

  const line_map *map_a = linemap_lookup (line_table, loc_a);
  linemap_assert (map_a);

  const line_map *map_b = linemap_lookup (line_table, loc_b);
  linemap_assert (map_b);

  /* Are they within the same map?  */
  if (map_a == map_b)
    {
      /* Are both within the same macro expansion?  */
      if (linemap_macro_expansion_map_p (map_a))
	{
	  /* If so, then they're only compatible if either both are
	     from the macro definition, or both from the macro arguments.  */
	  bool loc_a_from_defn
	    = linemap_location_from_macro_definition_p (line_table, loc_a);
	  bool loc_b_from_defn
	    = linemap_location_from_macro_definition_p (line_table, loc_b);
	  if (loc_a_from_defn != loc_b_from_defn)
	    return false;

	  /* Expand each location towards the spelling location, and
	     recurse.  */
	  const line_map_macro *macro_map = linemap_check_macro (map_a);
	  location_t loc_a_toward_spelling
	    = linemap_macro_map_loc_unwind_toward_spelling (line_table,
							    macro_map,
							    loc_a);
	  location_t loc_b_toward_spelling
	    = linemap_macro_map_loc_unwind_toward_spelling (line_table,
							    macro_map,
							    loc_b);
	  return compatible_locations_p (loc_a_toward_spelling,
					 loc_b_toward_spelling);
	}

      /* Otherwise they are within the same ordinary map.  */
      return true;
    }
  else
    {
      /* Within different maps.  */

      /* If either is within a macro expansion, they are incompatible.  */
      if (linemap_macro_expansion_map_p (map_a)
	  || linemap_macro_expansion_map_p (map_b))
	return false;

      /* Within two different ordinary maps; they are compatible iff they
	 are in the same file.  */
      const line_map_ordinary *ord_map_a = linemap_check_ordinary (map_a);
      const line_map_ordinary *ord_map_b = linemap_check_ordinary (map_b);
      return ord_map_a->to_file == ord_map_b->to_file;
    }
}

/* Comparator for sorting fix-it hints.  */

static int
fixit_cmp (const void *p_a, const void *p_b)
{
  const fixit_hint * hint_a = *static_cast<const fixit_hint * const *> (p_a);
  const fixit_hint * hint_b = *static_cast<const fixit_hint * const *> (p_b);
  return hint_a->get_start_loc () - hint_b->get_start_loc ();
}

/* Callbacks for use when not escaping the source.  */

/* The default callback for char_column_policy::m_width_cb is cpp_wcwidth.  */

/* Callback for char_display_policy::m_print_cb for printing source chars
   when not escaping the source.  */

static void
default_print_decoded_ch (pretty_printer *pp,
			  const cpp_decoded_char &decoded_ch)
{
  for (const char *ptr = decoded_ch.m_start_byte;
       ptr != decoded_ch.m_next_byte; ptr++)
    {
      if (*ptr == '\0' || *ptr == '\r')
	{
	  pp_space (pp);
	  continue;
	}

      pp_character (pp, *ptr);
    }
}

/* Callbacks for use with DIAGNOSTICS_ESCAPE_FORMAT_BYTES.  */

static const int width_per_escaped_byte = 4;

/* Callback for char_column_policy::m_width_cb for determining the
   display width when escaping with DIAGNOSTICS_ESCAPE_FORMAT_BYTES.  */

static int
escape_as_bytes_width (cppchar_t ch)
{
  if (ch < 0x80 && ISPRINT (ch))
    return cpp_wcwidth (ch);
  else
    {
      if (ch <=   0x7F) return 1 * width_per_escaped_byte;
      if (ch <=  0x7FF) return 2 * width_per_escaped_byte;
      if (ch <= 0xFFFF) return 3 * width_per_escaped_byte;
      return 4 * width_per_escaped_byte;
    }
}

/* Callback for char_display_policy::m_print_cb for printing source chars
   when escaping with DIAGNOSTICS_ESCAPE_FORMAT_BYTES.  */

static void
escape_as_bytes_print (pretty_printer *pp,
		       const cpp_decoded_char &decoded_ch)
{
  if (!decoded_ch.m_valid_ch)
    {
      for (const char *iter = decoded_ch.m_start_byte;
	   iter != decoded_ch.m_next_byte; ++iter)
	{
	  char buf[16];
	  sprintf (buf, "<%02x>", (unsigned char)*iter);
	  pp_string (pp, buf);
	}
      return;
    }

  cppchar_t ch = decoded_ch.m_ch;
  if (ch < 0x80 && ISPRINT (ch))
    pp_character (pp, ch);
  else
    {
      for (const char *iter = decoded_ch.m_start_byte;
	   iter < decoded_ch.m_next_byte; ++iter)
	{
	  char buf[16];
	  sprintf (buf, "<%02x>", (unsigned char)*iter);
	  pp_string (pp, buf);
	}
    }
}

/* Callbacks for use with DIAGNOSTICS_ESCAPE_FORMAT_UNICODE.  */

/* Callback for char_column_policy::m_width_cb for determining the
   display width when escaping with DIAGNOSTICS_ESCAPE_FORMAT_UNICODE.  */

static int
escape_as_unicode_width (cppchar_t ch)
{
  if (ch < 0x80 && ISPRINT (ch))
    return cpp_wcwidth (ch);
  else
    {
      // Width of "<U+%04x>"
      if (ch > 0xfffff)
	return 10;
      else if (ch > 0xffff)
	return 9;
      else
	return 8;
    }
}

/* Callback for char_display_policy::m_print_cb for printing source chars
   when escaping with DIAGNOSTICS_ESCAPE_FORMAT_UNICODE.  */

static void
escape_as_unicode_print (pretty_printer *pp,
			 const cpp_decoded_char &decoded_ch)
{
  if (!decoded_ch.m_valid_ch)
    {
      escape_as_bytes_print (pp, decoded_ch);
      return;
    }

  cppchar_t ch = decoded_ch.m_ch;
  if (ch < 0x80 && ISPRINT (ch))
    pp_character (pp, ch);
  else
    {
      char buf[16];
      sprintf (buf, "<U+%04X>", ch);
      pp_string (pp, buf);
    }
}

/* Populate a char_display_policy based on DC and RICHLOC.  */

static char_display_policy
make_policy (const diagnostic_context &dc,
	     const rich_location &richloc)
{
  /* The default is to not escape non-ASCII bytes.  */
  char_display_policy result
    (dc.tabstop, cpp_wcwidth, default_print_decoded_ch);

  /* If the diagnostic suggests escaping non-ASCII bytes, then
     use policy from user-supplied options.  */
  if (richloc.escape_on_output_p ())
    {
      result.m_undecoded_byte_width = width_per_escaped_byte;
      switch (dc.escape_format)
	{
	default:
	  gcc_unreachable ();
	case DIAGNOSTICS_ESCAPE_FORMAT_UNICODE:
	  result.m_width_cb = escape_as_unicode_width;
	  result.m_print_cb = escape_as_unicode_print;
	  break;
	case DIAGNOSTICS_ESCAPE_FORMAT_BYTES:
	  result.m_width_cb = escape_as_bytes_width;
	  result.m_print_cb = escape_as_bytes_print;
	  break;
	}
    }

  return result;
}

/* Implementation of class layout.  */

/* Constructor for class layout.

   Filter the ranges from the rich_location to those that we can
   sanely print, populating m_layout_ranges and m_fixit_hints.
   Determine the range of lines that we will print, splitting them
   up into an ordered list of disjoint spans of contiguous line numbers.
   Determine m_x_offset_display, to ensure that the primary caret
   will fit within the max_width provided by the diagnostic_context.  */

layout::layout (diagnostic_context * context,
		rich_location *richloc,
		diagnostic_t diagnostic_kind)
: m_context (context),
  m_pp (context->printer),
  m_policy (make_policy (*context, *richloc)),
  m_primary_loc (richloc->get_range (0)->m_loc),
  m_exploc (richloc->get_expanded_location (0), m_policy,
	    LOCATION_ASPECT_CARET),
  m_colorizer (context, diagnostic_kind),
  m_colorize_source_p (context->colorize_source_p),
  m_show_labels_p (context->show_labels_p),
  m_show_line_numbers_p (context->show_line_numbers_p),
  m_diagnostic_path_p (diagnostic_kind == DK_DIAGNOSTIC_PATH),
  m_layout_ranges (richloc->get_num_locations ()),
  m_fixit_hints (richloc->get_num_fixit_hints ()),
  m_line_spans (1 + richloc->get_num_locations ()),
  m_linenum_width (0),
  m_x_offset_display (0),
  m_escape_on_output (richloc->escape_on_output_p ())
{
  for (unsigned int idx = 0; idx < richloc->get_num_locations (); idx++)
    {
      /* This diagnostic printer can only cope with "sufficiently sane" ranges.
	 Ignore any ranges that are awkward to handle.  */
      const location_range *loc_range = richloc->get_range (idx);
      maybe_add_location_range (loc_range, idx, false);
    }

  /* Populate m_fixit_hints, filtering to only those that are in the
     same file.  */
  for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++)
    {
      const fixit_hint *hint = richloc->get_fixit_hint (i);
      if (validate_fixit_hint_p (hint))
	m_fixit_hints.safe_push (hint);
    }

  /* Sort m_fixit_hints.  */
  m_fixit_hints.qsort (fixit_cmp);

  /* Populate the indicated members.  */
  calculate_line_spans ();
  calculate_linenum_width ();
  calculate_x_offset_display ();

  if (context->show_ruler_p)
    show_ruler (m_x_offset_display + m_context->caret_max_width);
}


/* Attempt to add LOC_RANGE to m_layout_ranges, filtering them to
   those that we can sanely print.

   ORIGINAL_IDX is the index of LOC_RANGE within its rich_location,
   (for use as extrinsic state by label ranges FIXME).

   If RESTRICT_TO_CURRENT_LINE_SPANS is true, then LOC_RANGE is also
   filtered against this layout instance's current line spans: it
   will only be added if the location is fully within the lines
   already specified by other locations.

   Return true iff LOC_RANGE was added.  */

bool
layout::maybe_add_location_range (const location_range *loc_range,
				  unsigned original_idx,
				  bool restrict_to_current_line_spans)
{
  gcc_assert (loc_range);

  /* Split the "range" into caret and range information.  */
  source_range src_range = get_range_from_loc (line_table, loc_range->m_loc);

  /* Expand the various locations.  */
  expanded_location start
    = linemap_client_expand_location_to_spelling_point
    (src_range.m_start, LOCATION_ASPECT_START);
  expanded_location finish
    = linemap_client_expand_location_to_spelling_point
    (src_range.m_finish, LOCATION_ASPECT_FINISH);
  expanded_location caret
    = linemap_client_expand_location_to_spelling_point
    (loc_range->m_loc, LOCATION_ASPECT_CARET);

  /* If any part of the range isn't in the same file as the primary
     location of this diagnostic, ignore the range.  */
  if (start.file != m_exploc.file)
    return false;
  if (finish.file != m_exploc.file)
    return false;
  if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET)
    if (caret.file != m_exploc.file)
      return false;

  /* Sanitize the caret location for non-primary ranges.  */
  if (m_layout_ranges.length () > 0)
    if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET)
      if (!compatible_locations_p (loc_range->m_loc, m_primary_loc))
	/* Discard any non-primary ranges that can't be printed
	   sanely relative to the primary location.  */
	return false;

  /* Everything is now known to be in the correct source file,
     but it may require further sanitization.  */
  layout_range ri (exploc_with_display_col (start, m_policy,
					    LOCATION_ASPECT_START),
		   exploc_with_display_col (finish, m_policy,
					    LOCATION_ASPECT_FINISH),
		   loc_range->m_range_display_kind,
		   exploc_with_display_col (caret, m_policy,
					    LOCATION_ASPECT_CARET),
		   original_idx, loc_range->m_label);

  /* If we have a range that finishes before it starts (perhaps
     from something built via macro expansion), printing the
     range is likely to be nonsensical.  Also, attempting to do so
     breaks assumptions within the printing code  (PR c/68473).
     Similarly, don't attempt to print ranges if one or both ends
     of the range aren't sane to print relative to the
     primary location (PR c++/70105).  */
  if (start.line > finish.line
      || !compatible_locations_p (src_range.m_start, m_primary_loc)
      || !compatible_locations_p (src_range.m_finish, m_primary_loc))
    {
      /* Is this the primary location?  */
      if (m_layout_ranges.length () == 0)
	{
	  /* We want to print the caret for the primary location, but
	     we must sanitize away m_start and m_finish.  */
	  ri.m_start = ri.m_caret;
	  ri.m_finish = ri.m_caret;
	}
      else
	/* This is a non-primary range; ignore it.  */
	return false;
    }

  /* Potentially filter to just the lines already specified by other
     locations.  This is for use by gcc_rich_location::add_location_if_nearby.
     The layout ctor doesn't use it, and can't because m_line_spans
     hasn't been set up at that point.  */
  if (restrict_to_current_line_spans)
    {
      if (!will_show_line_p (start.line))
	return false;
      if (!will_show_line_p (finish.line))
	return false;
      if (loc_range->m_range_display_kind == SHOW_RANGE_WITH_CARET)
	if (!will_show_line_p (caret.line))
	  return false;
    }

  /* Passed all the tests; add the range to m_layout_ranges so that
     it will be printed.  */
  m_layout_ranges.safe_push (ri);
  return true;
}

/* Return true iff ROW is within one of the line spans for this layout.  */

bool
layout::will_show_line_p (linenum_type row) const
{
  for (int line_span_idx = 0; line_span_idx < get_num_line_spans ();
       line_span_idx++)
    {
      const line_span *line_span = get_line_span (line_span_idx);
      if (line_span->contains_line_p (row))
	return true;
    }
  return false;
}

/* Print a line showing a gap in the line numbers, for showing the boundary
   between two line spans.  */

void
layout::print_gap_in_line_numbering ()
{
  gcc_assert (m_show_line_numbers_p);

  pp_emit_prefix (m_pp);

  for (int i = 0; i < m_linenum_width + 1; i++)
    pp_character (m_pp, '.');

  pp_newline (m_pp);
}

/* Return true iff we should print a heading when starting the
   line span with the given index.  */

bool
layout::print_heading_for_line_span_index_p (int line_span_idx) const
{
  /* We print a heading for every change of line span, hence for every
     line span after the initial one.  */
  if (line_span_idx > 0)
    return true;

  /* We also do it for the initial span if the primary location of the
     diagnostic is in a different span.  */
  if (m_exploc.line > (int)get_line_span (0)->m_last_line)
    return true;

  return false;
}

/* Get an expanded_location for the first location of interest within
   the given line_span.
   Used when printing a heading to indicate a new line span.  */

expanded_location
layout::get_expanded_location (const line_span *line_span) const
{
  /* Whenever possible, use the caret location.  */
  if (line_span->contains_line_p (m_exploc.line))
    return m_exploc;

  /* Otherwise, use the start of the first range that's present
     within the line_span.  */
  for (unsigned int i = 0; i < m_layout_ranges.length (); i++)
    {
      const layout_range *lr = &m_layout_ranges[i];
      if (line_span->contains_line_p (lr->m_start.m_line))
	{
	  expanded_location exploc = m_exploc;
	  exploc.line = lr->m_start.m_line;
	  exploc.column = lr->m_start.m_columns[CU_BYTES];
	  return exploc;
	}
    }

  /* Otherwise, use the location of the first fixit-hint present within
     the line_span.  */
  for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
    {
      const fixit_hint *hint = m_fixit_hints[i];
      location_t loc = hint->get_start_loc ();
      expanded_location exploc = expand_location (loc);
      if (line_span->contains_line_p (exploc.line))
	return exploc;
    }

  /* It should not be possible to have a line span that didn't
     contain any of the layout_range or fixit_hint instances.  */
  gcc_unreachable ();
  return m_exploc;
}

/* Determine if HINT is meaningful to print within this layout.  */

bool
layout::validate_fixit_hint_p (const fixit_hint *hint)
{
  if (LOCATION_FILE (hint->get_start_loc ()) != m_exploc.file)
    return false;
  if (LOCATION_FILE (hint->get_next_loc ()) != m_exploc.file)
    return false;

  return true;
}

/* Determine the range of lines affected by HINT.
   This assumes that HINT has already been filtered by
   validate_fixit_hint_p, and so affects the correct source file.  */

static line_span
get_line_span_for_fixit_hint (const fixit_hint *hint)
{
  gcc_assert (hint);

  int start_line = LOCATION_LINE (hint->get_start_loc ());

  /* For line-insertion fix-it hints, add the previous line to the
     span, to give the user more context on the proposed change.  */
  if (hint->ends_with_newline_p ())
    if (start_line > 1)
      start_line--;

  return line_span (start_line,
		    LOCATION_LINE (hint->get_next_loc ()));
}

/* We want to print the pertinent source code at a diagnostic.  The
   rich_location can contain multiple locations.  This will have been
   filtered into m_exploc (the caret for the primary location) and
   m_layout_ranges, for those ranges within the same source file.

   We will print a subset of the lines within the source file in question,
   as a collection of "spans" of lines.

   This function populates m_line_spans with an ordered, disjoint list of
   the line spans of interest.

   Printing a gap between line spans takes one line, so, when printing
   line numbers, we allow a gap of up to one line between spans when
   merging, since it makes more sense to print the source line rather than a
   "gap-in-line-numbering" line.  When not printing line numbers, it's
   better to be more explicit about what's going on, so keeping them as
   separate spans is preferred.

   For example, if the primary range is on lines 8-10, with secondary ranges
   covering lines 5-6 and lines 13-15:

     004
     005                   |RANGE 1
     006                   |RANGE 1
     007
     008  |PRIMARY RANGE
     009  |PRIMARY CARET
     010  |PRIMARY RANGE
     011
     012
     013                                |RANGE 2
     014                                |RANGE 2
     015                                |RANGE 2
     016

   With line numbering on, we want two spans: lines 5-10 and lines 13-15.

   With line numbering off (with span headers), we want three spans: lines 5-6,
   lines 8-10, and lines 13-15.  */

void
layout::calculate_line_spans ()
{
  /* This should only be called once, by the ctor.  */
  gcc_assert (m_line_spans.length () == 0);

  /* Populate tmp_spans with individual spans, for each of
     m_exploc, and for m_layout_ranges.  */
  auto_vec<line_span> tmp_spans (1 + m_layout_ranges.length ());
  tmp_spans.safe_push (line_span (m_exploc.line, m_exploc.line));
  for (unsigned int i = 0; i < m_layout_ranges.length (); i++)
    {
      const layout_range *lr = &m_layout_ranges[i];
      gcc_assert (lr->m_start.m_line <= lr->m_finish.m_line);
      tmp_spans.safe_push (line_span (lr->m_start.m_line,
				      lr->m_finish.m_line));
    }

  /* Also add spans for any fix-it hints, in case they cover other lines.  */
  for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
    {
      const fixit_hint *hint = m_fixit_hints[i];
      gcc_assert (hint);
      tmp_spans.safe_push (get_line_span_for_fixit_hint (hint));
    }

  /* Sort them.  */
  tmp_spans.qsort(line_span::comparator);

  /* Now iterate through tmp_spans, copying into m_line_spans, and
     combining where possible.  */
  gcc_assert (tmp_spans.length () > 0);
  m_line_spans.safe_push (tmp_spans[0]);
  for (unsigned int i = 1; i < tmp_spans.length (); i++)
    {
      line_span *current = &m_line_spans[m_line_spans.length () - 1];
      const line_span *next = &tmp_spans[i];
      gcc_assert (next->m_first_line >= current->m_first_line);
      const int merger_distance = m_show_line_numbers_p ? 1 : 0;
      if ((linenum_arith_t)next->m_first_line
	  <= (linenum_arith_t)current->m_last_line + 1 + merger_distance)
	{
	  /* We can merge them. */
	  if (next->m_last_line > current->m_last_line)
	    current->m_last_line = next->m_last_line;
	}
      else
	{
	  /* No merger possible.  */
	  m_line_spans.safe_push (*next);
	}
    }

  /* Verify the result, in m_line_spans.  */
  gcc_assert (m_line_spans.length () > 0);
  for (unsigned int i = 1; i < m_line_spans.length (); i++)
    {
      const line_span *prev = &m_line_spans[i - 1];
      const line_span *next = &m_line_spans[i];
      /* The individual spans must be sane.  */
      gcc_assert (prev->m_first_line <= prev->m_last_line);
      gcc_assert (next->m_first_line <= next->m_last_line);
      /* The spans must be ordered.  */
      gcc_assert (prev->m_first_line < next->m_first_line);
      /* There must be a gap of at least one line between separate spans.  */
      gcc_assert ((prev->m_last_line + 1) < next->m_first_line);
    }
}

/* Determine how many display columns need to be reserved for line numbers,
   based on the largest line number that will be needed, and populate
   m_linenum_width.  */

void
layout::calculate_linenum_width ()
{
  gcc_assert (m_line_spans.length () > 0);
  const line_span *last_span = &m_line_spans[m_line_spans.length () - 1];
  int highest_line = last_span->m_last_line;
  if (highest_line < 0)
    highest_line = 0;
  m_linenum_width = num_digits (highest_line);
  /* If we're showing jumps in the line-numbering, allow at least 3 chars.  */
  if (m_line_spans.length () > 1)
    m_linenum_width = MAX (m_linenum_width, 3);
  /* If there's a minimum margin width, apply it (subtracting 1 for the space
     after the line number.  */
  m_linenum_width = MAX (m_linenum_width, m_context->min_margin_width - 1);
}

/* Calculate m_x_offset_display, which improves readability in case the source
   line of interest is longer than the user's display.  All lines output will be
   shifted to the left (so that their beginning is no longer displayed) by
   m_x_offset_display display columns, so that the caret is in a reasonable
   location.  */

void
layout::calculate_x_offset_display ()
{
  m_x_offset_display = 0;

  const int max_width = m_context->caret_max_width;
  if (!max_width)
    {
      /* Nothing to do, the width is not capped.  */
      return;
    }

  const char_span line = location_get_source_line (m_exploc.file,
						   m_exploc.line);
  if (!line)
    {
      /* Nothing to do, we couldn't find the source line.  */
      return;
    }
  int caret_display_column = m_exploc.m_display_col;
  const int line_bytes
    = get_line_bytes_without_trailing_whitespace (line.get_buffer (),
						  line.length ());
  int eol_display_column
    = cpp_display_width (line.get_buffer (), line_bytes, m_policy);
  if (caret_display_column > eol_display_column
      || !caret_display_column)
    {
      /* This does not make sense, so don't try to do anything in this case.  */
      return;
    }

  /* Adjust caret and eol positions to include the left margin.  If we are
     outputting line numbers, then the left margin is equal to m_linenum_width
     plus three for the " | " which follows it.  Otherwise the left margin width
     is equal to 1, because layout::print_source_line() will prefix each line
     with a space.  */
  const int source_display_cols = eol_display_column;
  int left_margin_size = 1;
  if (m_show_line_numbers_p)
      left_margin_size = m_linenum_width + 3;
  caret_display_column += left_margin_size;
  eol_display_column += left_margin_size;

  if (eol_display_column <= max_width)
    {
      /* Nothing to do, everything fits in the display.  */
      return;
    }

  /* The line is too long for the display.  Calculate an offset such that the
     caret is not too close to the right edge of the screen.  It will be
     CARET_LINE_MARGIN display columns from the right edge, unless it is closer
     than that to the end of the source line anyway.  */
  int right_margin_size = CARET_LINE_MARGIN;
  right_margin_size = MIN (eol_display_column - caret_display_column,
			   right_margin_size);
  if (right_margin_size + left_margin_size >= max_width)
    {
      /* The max_width is very small, so anything we try to do will not be very
	 effective; just punt in this case and output with no offset.  */
      return;
    }
  const int max_caret_display_column = max_width - right_margin_size;
  if (caret_display_column > max_caret_display_column)
    {
      m_x_offset_display = caret_display_column - max_caret_display_column;
      /* Make sure we don't offset the line into oblivion.  */
      static const int min_cols_visible = 2;
      if (source_display_cols - m_x_offset_display < min_cols_visible)
	m_x_offset_display = 0;
    }
}

/* Print line ROW of source code, potentially colorized at any ranges, and
   return the line bounds.  LINE is the source line (not necessarily
   0-terminated) and LINE_BYTES is its length in bytes.  In order to handle both
   colorization and tab expansion, this function tracks the line position in
   both byte and display column units.  */

line_bounds
layout::print_source_line (linenum_type row, const char *line, int line_bytes)
{
  m_colorizer.set_normal_text ();

  pp_emit_prefix (m_pp);
  if (m_show_line_numbers_p)
    {
      int width = num_digits (row);
      for (int i = 0; i < m_linenum_width - width; i++)
	pp_space (m_pp);
      pp_printf (m_pp, "%i | ", row);
    }
  else
    pp_space (m_pp);

  /* We will stop printing the source line at any trailing whitespace.  */
  line_bytes = get_line_bytes_without_trailing_whitespace (line,
							   line_bytes);

  /* This object helps to keep track of which display column we are at, which is
     necessary for computing the line bounds in display units, for doing
     tab expansion, and for implementing m_x_offset_display.  */
  cpp_display_width_computation dw (line, line_bytes, m_policy);

  /* Skip the first m_x_offset_display display columns.  In case the leading
     portion that will be skipped ends with a character with wcwidth > 1, then
     it is possible we skipped too much, so account for that by padding with
     spaces.  Note that this does the right thing too in case a tab was the last
     character to be skipped over; the tab is effectively replaced by the
     correct number of trailing spaces needed to offset by the desired number of
     display columns.  */
  for (int skipped_display_cols = dw.advance_display_cols (m_x_offset_display);
       skipped_display_cols > m_x_offset_display; --skipped_display_cols)
    pp_space (m_pp);

  /* Print the line and compute the line_bounds.  */
  line_bounds lbounds;
  while (!dw.done ())
    {
      /* Assuming colorization is enabled for the caret and underline
	 characters, we may also colorize the associated characters
	 within the source line.

	 For frontends that generate range information, we color the
	 associated characters in the source line the same as the
	 carets and underlines in the annotation line, to make it easier
	 for the reader to see the pertinent code.

	 For frontends that only generate carets, we don't colorize the
	 characters above them, since this would look strange (e.g.
	 colorizing just the first character in a token).  */
      if (m_colorize_source_p)
	{
	  bool in_range_p;
	  point_state state;
	  const int start_byte_col = dw.bytes_processed () + 1;
	  in_range_p = get_state_at_point (row, start_byte_col,
					   0, INT_MAX,
					   CU_BYTES,
					   &state);
	  if (in_range_p)
	    m_colorizer.set_range (state.range_idx);
	  else
	    m_colorizer.set_normal_text ();
	}

      /* Get the display width of the next character to be output, expanding
	 tabs and replacing some control bytes with spaces as necessary.  */
      const char *c = dw.next_byte ();
      const int start_disp_col = dw.display_cols_processed () + 1;
      cpp_decoded_char cp;
      const int this_display_width = dw.process_next_codepoint (&cp);
      if (*c == '\t')
	{
	  /* The returned display width is the number of spaces into which the
	     tab should be expanded.  */
	  for (int i = 0; i != this_display_width; ++i)
	    pp_space (m_pp);
	  continue;
	}

      /* We have a (possibly multibyte) character to output; update the line
	 bounds if it is not whitespace.  */
      if (*c != ' ')
	{
	  lbounds.m_last_non_ws_disp_col = dw.display_cols_processed ();
	  if (lbounds.m_first_non_ws_disp_col == INT_MAX)
	    lbounds.m_first_non_ws_disp_col = start_disp_col;
	}

      /* Output the character.  */
      m_policy.m_print_cb (m_pp, cp);
      c = dw.next_byte ();
    }
  print_newline ();
  return lbounds;
}

/* Determine if we should print an annotation line for ROW.
   i.e. if any of m_layout_ranges contains ROW.  */

bool
layout::should_print_annotation_line_p (linenum_type row) const
{
  layout_range *range;
  int i;
  FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
    {
      if (range->m_range_display_kind == SHOW_LINES_WITHOUT_RANGE)
	return false;
      if (range->intersects_line_p (row))
	return true;
    }
  return false;
}

/* Begin an annotation line.  If m_show_line_numbers_p, print the left
   margin, which is empty for annotation lines.  Otherwise, do nothing.  */

void
layout::start_annotation_line (char margin_char) const
{
  pp_emit_prefix (m_pp);
  if (m_show_line_numbers_p)
    {
      /* Print the margin.  If MARGIN_CHAR != ' ', then print up to 3
	 of it, right-aligned, padded with spaces.  */
      int i;
      for (i = 0; i < m_linenum_width - 3; i++)
	pp_space (m_pp);
      for (; i < m_linenum_width; i++)
	pp_character (m_pp, margin_char);
      pp_string (m_pp, " |");
    }
}

/* Print a line consisting of the caret/underlines for the given
   source line.  */

void
layout::print_annotation_line (linenum_type row, const line_bounds lbounds)
{
  int x_bound = get_x_bound_for_row (row, m_exploc.m_display_col,
				     lbounds.m_last_non_ws_disp_col);

  start_annotation_line ();
  pp_space (m_pp);

  for (int column = 1 + m_x_offset_display; column < x_bound; column++)
    {
      bool in_range_p;
      point_state state;
      in_range_p = get_state_at_point (row, column,
				       lbounds.m_first_non_ws_disp_col,
				       lbounds.m_last_non_ws_disp_col,
				       CU_DISPLAY_COLS,
				       &state);
      if (in_range_p)
	{
	  /* Within a range.  Draw either the caret or an underline.  */
	  m_colorizer.set_range (state.range_idx);
	  if (state.draw_caret_p)
	    {
	      /* Draw the caret.  */
	      char caret_char;
	      if (state.range_idx < rich_location::STATICALLY_ALLOCATED_RANGES)
		caret_char = m_context->caret_chars[state.range_idx];
	      else
		caret_char = '^';
	      pp_character (m_pp, caret_char);
	    }
	  else
	    pp_character (m_pp, '~');
	}
      else
	{
	  /* Not in a range.  */
	  m_colorizer.set_normal_text ();
	  pp_character (m_pp, ' ');
	}
    }
  print_newline ();
}

/* A version of label_text that can live inside a vec.
   Requires manual cleanup via maybe_free.  */

struct pod_label_text
{
  pod_label_text ()
  : m_buffer (NULL), m_caller_owned (false)
  {}

  pod_label_text (label_text &&other)
  : m_buffer (const_cast<char*> (other.get ())),
    m_caller_owned (other.is_owner ())
  {
    other.release ();
  }

  void maybe_free ()
  {
    if (m_caller_owned)
      free (m_buffer);
  }

  char *m_buffer;
  bool m_caller_owned;
};

/* Implementation detail of layout::print_any_labels.

   A label within the given row of source.  */

class line_label
{
public:
  line_label (const cpp_char_column_policy &policy,
	      int state_idx, int column,
	      label_text text)
  : m_state_idx (state_idx), m_column (column),
    m_text (std::move (text)), m_label_line (0), m_has_vbar (true)
  {
    const int bytes = strlen (m_text.m_buffer);
    m_display_width = cpp_display_width (m_text.m_buffer, bytes, policy);
  }

  /* Sorting is primarily by column, then by state index.  */
  static int comparator (const void *p1, const void *p2)
  {
    const line_label *ll1 = (const line_label *)p1;
    const line_label *ll2 = (const line_label *)p2;
    int column_cmp = compare (ll1->m_column, ll2->m_column);
    if (column_cmp)
      return column_cmp;
    /* Order by reverse state index, so that labels are printed
       in order of insertion into the rich_location when the
       sorted list is walked backwards.  */
    return -compare (ll1->m_state_idx, ll2->m_state_idx);
  }

  int m_state_idx;
  int m_column;
  pod_label_text m_text;
  size_t m_display_width;
  int m_label_line;
  bool m_has_vbar;
};

/* Print any labels in this row.  */
void
layout::print_any_labels (linenum_type row)
{
  int i;
  auto_vec<line_label> labels;

  /* Gather the labels that are to be printed into "labels".  */
  {
    layout_range *range;
    FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
      {
	/* Most ranges don't have labels, so reject this first.  */
	if (range->m_label == NULL)
	  continue;

	/* The range's caret must be on this line.  */
	if (range->m_caret.m_line != row)
	  continue;

	/* Reject labels that aren't fully visible due to clipping
	   by m_x_offset_display.  */
	const int disp_col = range->m_caret.m_columns[CU_DISPLAY_COLS];
	if (disp_col <= m_x_offset_display)
	  continue;

	label_text text;
	text = range->m_label->get_text (range->m_original_idx);

	/* Allow for labels that return NULL from their get_text
	   implementation (so e.g. such labels can control their own
	   visibility).  */
	if (text.get () == NULL)
	  continue;

	labels.safe_push (line_label (m_policy, i, disp_col, std::move (text)));
      }
  }

  /* Bail out if there are no labels on this row.  */
  if (labels.length () == 0)
    return;

  /* Sort them.  */
  labels.qsort(line_label::comparator);

  /* Figure out how many "label lines" we need, and which
     one each label is printed in.

     For example, if the labels aren't too densely packed,
     we can fit them on the same line, giving two "label lines":

       foo + bar
       ~~~   ~~~
       |     |        : label line 0
       l0    l1       : label line 1

     If they would touch each other or overlap, then we need
     additional "label lines":

       foo + bar
       ~~~   ~~~
       |     |             : label line 0
       |     label 1       : label line 1
       label 0             : label line 2

     Place the final label on label line 1, and work backwards, adding
     label lines as needed.

     If multiple labels are at the same place, put them on separate
     label lines:

       foo + bar
           ^               : label line 0
           |               : label line 1
           label 0         : label line 2
           label 1         : label line 3.  */

  int max_label_line = 1;
  {
    int next_column = INT_MAX;
    line_label *label;
    FOR_EACH_VEC_ELT_REVERSE (labels, i, label)
      {
	/* Would this label "touch" or overlap the next label?  */
	if (label->m_column + label->m_display_width >= (size_t)next_column)
	  {
	    max_label_line++;

	    /* If we've already seen labels with the same column, suppress the
	       vertical bar for subsequent ones in this backwards iteration;
	       hence only the one with the highest label_line has m_has_vbar set.  */
	    if (label->m_column == next_column)
	      label->m_has_vbar = false;
	  }

	label->m_label_line = max_label_line;
	next_column = label->m_column;
      }
  }

  /* Print the "label lines".  For each label within the line, print
     either a vertical bar ('|') for the labels that are lower down, or the
     labels themselves once we've reached their line.  */
  {
    for (int label_line = 0; label_line <= max_label_line; label_line++)
      {
	start_annotation_line ();
	pp_space (m_pp);
	int column = 1 + m_x_offset_display;
	line_label *label;
	FOR_EACH_VEC_ELT (labels, i, label)
	  {
	    if (label_line > label->m_label_line)
	      /* We've printed all the labels for this label line.  */
	      break;

	    if (label_line == label->m_label_line)
	      {
		gcc_assert (column <= label->m_column);
		move_to_column (&column, label->m_column, true);
		/* Colorize the text, unless it's for events in a
		   diagnostic_path.  */
		if (!m_diagnostic_path_p)
		  m_colorizer.set_range (label->m_state_idx);
		pp_string (m_pp, label->m_text.m_buffer);
		m_colorizer.set_normal_text ();
		column += label->m_display_width;
	      }
	    else if (label->m_has_vbar)
	      {
		gcc_assert (column <= label->m_column);
		move_to_column (&column, label->m_column, true);
		m_colorizer.set_range (label->m_state_idx);
		pp_character (m_pp, '|');
		m_colorizer.set_normal_text ();
		column++;
	      }
	  }
	print_newline ();
      }
    }

  /* Clean up.  */
  {
    line_label *label;
    FOR_EACH_VEC_ELT (labels, i, label)
      label->m_text.maybe_free ();
  }
}

/* If there are any fixit hints inserting new lines before source line ROW,
   print them.

   They are printed on lines of their own, before the source line
   itself, with a leading '+'.  */

void
layout::print_leading_fixits (linenum_type row)
{
  for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
    {
      const fixit_hint *hint = m_fixit_hints[i];

      if (!hint->ends_with_newline_p ())
	/* Not a newline fixit; print it in print_trailing_fixits.  */
	continue;

      gcc_assert (hint->insertion_p ());

      if (hint->affects_line_p (m_exploc.file, row))
	{
	  /* Printing the '+' with normal colorization
	     and the inserted line with "insert" colorization
	     helps them stand out from each other, and from
	     the surrounding text.  */
	  m_colorizer.set_normal_text ();
	  start_annotation_line ('+');
	  pp_character (m_pp, '+');
	  m_colorizer.set_fixit_insert ();
	  /* Print all but the trailing newline of the fix-it hint.
	     We have to print the newline separately to avoid
	     getting additional pp prefixes printed.  */
	  for (size_t i = 0; i < hint->get_length () - 1; i++)
	    pp_character (m_pp, hint->get_string ()[i]);
	  m_colorizer.set_normal_text ();
	  pp_newline (m_pp);
	}
    }
}

/* Subroutine of layout::print_trailing_fixits.

   Determine if the annotation line printed for LINE contained
   the exact range from START_COLUMN to FINISH_COLUMN (in display units).  */

bool
layout::annotation_line_showed_range_p (linenum_type line, int start_column,
					int finish_column) const
{
  layout_range *range;
  int i;
  FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
    if (range->m_start.m_line == line
	&& range->m_start.m_columns[CU_DISPLAY_COLS] == start_column
	&& range->m_finish.m_line == line
	&& range->m_finish.m_columns[CU_DISPLAY_COLS] == finish_column)
      return true;
  return false;
}

/* Classes for printing trailing fix-it hints i.e. those that
   don't add new lines.

   For insertion, these can look like:

     new_text

   For replacement, these can look like:

     ------------- : underline showing affected range
     new_text

   For deletion, these can look like:

     ------------- : underline showing affected range

   This can become confusing if they overlap, and so we need
   to do some preprocessing to decide what to print.
   We use the list of fixit_hint instances affecting the line
   to build a list of "correction" instances, and print the
   latter.

   For example, consider a set of fix-its for converting
   a C-style cast to a C++ const_cast.

   Given:

   ..000000000111111111122222222223333333333.
   ..123456789012345678901234567890123456789.
     foo *f = (foo *)ptr->field;
                          ^~~~~

   and the fix-it hints:
     - replace col 10 (the open paren) with "const_cast<"
     - replace col 16 (the close paren) with "> ("
     - insert ")" before col 27

   then we would get odd-looking output:

     foo *f = (foo *)ptr->field;
                          ^~~~~
              -
              const_cast<
                    -
                    > (        )

   It would be better to detect when fixit hints are going to
   overlap (those that require new lines), and to consolidate
   the printing of such fixits, giving something like:

     foo *f = (foo *)ptr->field;
                          ^~~~~
              -----------------
              const_cast<foo *> (ptr->field)

   This works by detecting when the printing would overlap, and
   effectively injecting no-op replace hints into the gaps between
   such fix-its, so that the printing joins up.

   In the above example, the overlap of:
     - replace col 10 (the open paren) with "const_cast<"
   and:
     - replace col 16 (the close paren) with "> ("
   is fixed by injecting a no-op:
     - replace cols 11-15 with themselves ("foo *")
   and consolidating these, making:
     - replace cols 10-16 with "const_cast<" + "foo *" + "> ("
   i.e.:
     - replace cols 10-16 with "const_cast<foo *> ("

   This overlaps with the final fix-it hint:
     - insert ")" before col 27
   and so we repeat the consolidation process, by injecting
   a no-op:
     - replace cols 17-26 with themselves ("ptr->field")
   giving:
     - replace cols 10-26 with "const_cast<foo *> (" + "ptr->field" + ")"
   i.e.:
     - replace cols 10-26 with "const_cast<foo *> (ptr->field)"

   and is thus printed as desired.  */

/* A range of (byte or display) columns within a line.  */

class column_range
{
public:
  column_range (int start_, int finish_) : start (start_), finish (finish_)
  {
    /* We must have either a range, or an insertion.  */
    gcc_assert (start <= finish || finish == start - 1);
  }

  bool operator== (const column_range &other) const
  {
    return start == other.start && finish == other.finish;
  }

  int start;
  int finish;
};

/* Get the range of bytes or display columns that HINT would affect.  */
static column_range
get_affected_range (const cpp_char_column_policy &policy,
		    const fixit_hint *hint, enum column_unit col_unit)
{
  expanded_location exploc_start = expand_location (hint->get_start_loc ());
  expanded_location exploc_finish = expand_location (hint->get_next_loc ());
  --exploc_finish.column;

  int start_column;
  int finish_column;
  if (col_unit == CU_DISPLAY_COLS)
    {
      start_column = location_compute_display_column (exploc_start, policy);
      if (hint->insertion_p ())
	finish_column = start_column - 1;
      else
	finish_column = location_compute_display_column (exploc_finish, policy);
    }
  else
    {
      start_column = exploc_start.column;
      finish_column = exploc_finish.column;
    }
  return column_range (start_column, finish_column);
}

/* Get the range of display columns that would be printed for HINT.  */

static column_range
get_printed_columns (const cpp_char_column_policy &policy,
		     const fixit_hint *hint)
{
  expanded_location exploc = expand_location (hint->get_start_loc ());
  int start_column = location_compute_display_column (exploc, policy);
  int hint_width = cpp_display_width (hint->get_string (), hint->get_length (),
				      policy);
  int final_hint_column = start_column + hint_width - 1;
  if (hint->insertion_p ())
    {
      return column_range (start_column, final_hint_column);
    }
  else
    {
      exploc = expand_location (hint->get_next_loc ());
      --exploc.column;
      int finish_column = location_compute_display_column (exploc, policy);
      return column_range (start_column,
			   MAX (finish_column, final_hint_column));
    }
}

/* A correction on a particular line.
   This describes a plan for how to print one or more fixit_hint
   instances that affected the line, potentially consolidating hints
   into corrections to make the result easier for the user to read.  */

class correction
{
public:
  correction (column_range affected_bytes,
	      column_range affected_columns,
	      column_range printed_columns,
	      const char *new_text, size_t new_text_len,
	      const cpp_char_column_policy &policy)
  : m_affected_bytes (affected_bytes),
    m_affected_columns (affected_columns),
    m_printed_columns (printed_columns),
    m_text (xstrdup (new_text)),
    m_byte_length (new_text_len),
    m_policy (policy),
    m_alloc_sz (new_text_len + 1)
  {
    compute_display_cols ();
  }

  ~correction () { free (m_text); }

  bool insertion_p () const
  {
    return m_affected_bytes.start == m_affected_bytes.finish + 1;
  }

  void ensure_capacity (size_t len);
  void ensure_terminated ();

  void compute_display_cols ()
  {
    m_display_cols = cpp_display_width (m_text, m_byte_length, m_policy);
  }

  void overwrite (int dst_offset, const char_span &src_span)
  {
    gcc_assert (dst_offset >= 0);
    gcc_assert (dst_offset + src_span.length () < m_alloc_sz);
    memcpy (m_text + dst_offset, src_span.get_buffer (),
	    src_span.length ());
  }

  /* If insert, then start: the column before which the text
     is to be inserted, and finish is offset by the length of
     the replacement.
     If replace, then the range of columns affected.  */
  column_range m_affected_bytes;
  column_range m_affected_columns;

  /* If insert, then start: the column before which the text
     is to be inserted, and finish is offset by the length of
     the replacement.
     If replace, then the range of columns affected.  */
  column_range m_printed_columns;

  /* The text to be inserted/used as replacement.  */
  char *m_text;
  size_t m_byte_length; /* Not including null-terminator.  */
  int m_display_cols;
  const cpp_char_column_policy &m_policy;
  size_t m_alloc_sz;
};

/* Ensure that m_text can hold a string of length LEN
   (plus 1 for 0-termination).  */

void
correction::ensure_capacity (size_t len)
{
  /* Allow 1 extra byte for 0-termination.  */
  if (m_alloc_sz < (len + 1))
    {
      size_t new_alloc_sz = (len + 1) * 2;
      m_text = (char *)xrealloc (m_text, new_alloc_sz);
      m_alloc_sz = new_alloc_sz;
    }
}

/* Ensure that m_text is 0-terminated.  */

void
correction::ensure_terminated ()
{
  /* 0-terminate the buffer.  */
  gcc_assert (m_byte_length < m_alloc_sz);
  m_text[m_byte_length] = '\0';
}

/* A list of corrections affecting a particular line.
   This is used by layout::print_trailing_fixits for planning
   how to print the fix-it hints affecting the line.  */

class line_corrections
{
public:
  line_corrections (const char_display_policy &policy,
		    const char *filename,
		    linenum_type row)
  : m_policy (policy), m_filename (filename), m_row (row)
  {}
  ~line_corrections ();

  void add_hint (const fixit_hint *hint);

  const char_display_policy &m_policy;
  const char *m_filename;
  linenum_type m_row;
  auto_vec <correction *> m_corrections;
};

/* struct line_corrections.  */

line_corrections::~line_corrections ()
{
  unsigned i;
  correction *c;
  FOR_EACH_VEC_ELT (m_corrections, i, c)
    delete c;
}

/* A struct wrapping a particular source line, allowing
   run-time bounds-checking of accesses in a checked build.  */

class source_line
{
public:
  source_line (const char *filename, int line);

  char_span as_span () { return char_span (chars, width); }

  const char *chars;
  int width;
};

/* source_line's ctor.  */

source_line::source_line (const char *filename, int line)
{
  char_span span = location_get_source_line (filename, line);
  chars = span.get_buffer ();
  width = span.length ();
}

/* Add HINT to the corrections for this line.
   Attempt to consolidate nearby hints so that they will not
   overlap with printed.  */

void
line_corrections::add_hint (const fixit_hint *hint)
{
  column_range affected_bytes = get_affected_range (m_policy, hint, CU_BYTES);
  column_range affected_columns = get_affected_range (m_policy, hint,
						      CU_DISPLAY_COLS);
  column_range printed_columns = get_printed_columns (m_policy, hint);

  /* Potentially consolidate.  */
  if (!m_corrections.is_empty ())
    {
      correction *last_correction
	= m_corrections[m_corrections.length () - 1];

      /* The following consolidation code assumes that the fix-it hints
	 have been sorted by start (done within layout's ctor).  */
      gcc_assert (affected_bytes.start
		  >= last_correction->m_affected_bytes.start);
      gcc_assert (printed_columns.start
		  >= last_correction->m_printed_columns.start);

      if (printed_columns.start <= last_correction->m_printed_columns.finish)
	{
	  /* We have two hints for which the printed forms of the hints
	     would touch or overlap, so we need to consolidate them to avoid
	     confusing the user.
	     Attempt to inject a "replace" correction from immediately
	     after the end of the last hint to immediately before the start
	     of the next hint.  */
	  column_range between (last_correction->m_affected_bytes.finish + 1,
				affected_bytes.start - 1);

	  /* Try to read the source.  */
	  source_line line (m_filename, m_row);
	  if (line.chars && between.finish < line.width)
	    {
	      /* Consolidate into the last correction:
		 add a no-op "replace" of the "between" text, and
		 add the text from the new hint.  */
	      int old_byte_len = last_correction->m_byte_length;
	      gcc_assert (old_byte_len >= 0);
	      int between_byte_len = between.finish + 1 - between.start;
	      gcc_assert (between_byte_len >= 0);
	      int new_byte_len
		= old_byte_len + between_byte_len + hint->get_length ();
	      gcc_assert (new_byte_len >= 0);
	      last_correction->ensure_capacity (new_byte_len);
	      last_correction->overwrite
		(old_byte_len,
		 line.as_span ().subspan (between.start - 1,
					  between.finish + 1 - between.start));
	      last_correction->overwrite (old_byte_len + between_byte_len,
					  char_span (hint->get_string (),
						     hint->get_length ()));
	      last_correction->m_byte_length = new_byte_len;
	      last_correction->ensure_terminated ();
	      last_correction->m_affected_bytes.finish
		= affected_bytes.finish;
	      last_correction->m_affected_columns.finish
		= affected_columns.finish;
	      int prev_display_cols = last_correction->m_display_cols;
	      last_correction->compute_display_cols ();
	      last_correction->m_printed_columns.finish
		+= last_correction->m_display_cols - prev_display_cols;
	      return;
	    }
	}
    }

  /* If no consolidation happened, add a new correction instance.  */
  m_corrections.safe_push (new correction (affected_bytes,
					   affected_columns,
					   printed_columns,
					   hint->get_string (),
					   hint->get_length (),
					   m_policy));
}

/* If there are any fixit hints on source line ROW, print them.
   They are printed in order, attempting to combine them onto lines, but
   starting new lines if necessary.
   Fix-it hints that insert new lines are handled separately,
   in layout::print_leading_fixits.  */

void
layout::print_trailing_fixits (linenum_type row)
{
  /* Build a list of correction instances for the line,
     potentially consolidating hints (for the sake of readability).  */
  line_corrections corrections (m_policy, m_exploc.file, row);
  for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
    {
      const fixit_hint *hint = m_fixit_hints[i];

      /* Newline fixits are handled by layout::print_leading_fixits.  */
      if (hint->ends_with_newline_p ())
	continue;

      if (hint->affects_line_p (m_exploc.file, row))
	corrections.add_hint (hint);
    }

  /* Now print the corrections.  */
  unsigned i;
  correction *c;
  int column = m_x_offset_display;

  if (!corrections.m_corrections.is_empty ())
    start_annotation_line ();

  FOR_EACH_VEC_ELT (corrections.m_corrections, i, c)
    {
      /* For now we assume each fixit hint can only touch one line.  */
      if (c->insertion_p ())
	{
	  /* This assumes the insertion just affects one line.  */
	  int start_column = c->m_printed_columns.start;
	  move_to_column (&column, start_column, true);
	  m_colorizer.set_fixit_insert ();
	  pp_string (m_pp, c->m_text);
	  m_colorizer.set_normal_text ();
	  column += c->m_display_cols;
	}
      else
	{
	  /* If the range of the replacement wasn't printed in the
	     annotation line, then print an extra underline to
	     indicate exactly what is being replaced.
	     Always show it for removals.  */
	  int start_column = c->m_affected_columns.start;
	  int finish_column = c->m_affected_columns.finish;
	  if (!annotation_line_showed_range_p (row, start_column,
					       finish_column)
	      || c->m_byte_length == 0)
	    {
	      move_to_column (&column, start_column, true);
	      m_colorizer.set_fixit_delete ();
	      for (; column <= finish_column; column++)
		pp_character (m_pp, '-');
	      m_colorizer.set_normal_text ();
	    }
	  /* Print the replacement text.  REPLACE also covers
	     removals, so only do this extra work (potentially starting
	     a new line) if we have actual replacement text.  */
	  if (c->m_byte_length > 0)
	    {
	      move_to_column (&column, start_column, true);
	      m_colorizer.set_fixit_insert ();
	      pp_string (m_pp, c->m_text);
	      m_colorizer.set_normal_text ();
	      column += c->m_display_cols;
	    }
	}
    }

  /* Add a trailing newline, if necessary.  */
  move_to_column (&column, 0, false);
}

/* Disable any colorization and emit a newline.  */

void
layout::print_newline ()
{
  m_colorizer.set_normal_text ();
  pp_newline (m_pp);
}

/* Return true if (ROW/COLUMN) is within a range of the layout.
   If it returns true, OUT_STATE is written to, with the
   range index, and whether we should draw the caret at
   (ROW/COLUMN) (as opposed to an underline).  COL_UNIT controls
   whether all inputs and outputs are in bytes or display column units.  */

bool
layout::get_state_at_point (/* Inputs.  */
			    linenum_type row, int column,
			    int first_non_ws, int last_non_ws,
			    enum column_unit col_unit,
			    /* Outputs.  */
			    point_state *out_state)
{
  layout_range *range;
  int i;
  FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
    {
      if (range->m_range_display_kind == SHOW_LINES_WITHOUT_RANGE)
	/* Bail out early, so that such ranges don't affect underlining or
	   source colorization.  */
	continue;

      if (range->contains_point (row, column, col_unit))
	{
	  out_state->range_idx = i;

	  /* Are we at the range's caret?  is it visible? */
	  out_state->draw_caret_p = false;
	  if (range->m_range_display_kind == SHOW_RANGE_WITH_CARET
	      && row == range->m_caret.m_line
	      && column == range->m_caret.m_columns[col_unit])
	    out_state->draw_caret_p = true;

	  /* Within a multiline range, don't display any underline
	     in any leading or trailing whitespace on a line.
	     We do display carets, however.  */
	  if (!out_state->draw_caret_p)
	    if (column < first_non_ws || column > last_non_ws)
	      return false;

	  /* We are within a range.  */
	  return true;
	}
    }

  return false;
}

/* Helper function for use by layout::print_line when printing the
   annotation line under the source line.
   Get the display column beyond the rightmost one that could contain a caret
   or range marker, given that we stop rendering at trailing whitespace.
   ROW is the source line within the given file.
   CARET_COLUMN is the display column of range 0's caret.
   LAST_NON_WS_COLUMN is the last display column containing a non-whitespace
   character of source (as determined when printing the source line).  */

int
layout::get_x_bound_for_row (linenum_type row, int caret_column,
			     int last_non_ws_column)
{
  int result = caret_column + 1;

  layout_range *range;
  int i;
  FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
    {
      if (row >= range->m_start.m_line)
	{
	  if (range->m_finish.m_line == row)
	    {
	      /* On the final line within a range; ensure that
		 we render up to the end of the range.  */
	      const int disp_col = range->m_finish.m_columns[CU_DISPLAY_COLS];
	      if (result <= disp_col)
		result = disp_col + 1;
	    }
	  else if (row < range->m_finish.m_line)
	    {
	      /* Within a multiline range; ensure that we render up to the
		 last non-whitespace column.  */
	      if (result <= last_non_ws_column)
		result = last_non_ws_column + 1;
	    }
	}
    }

  return result;
}

/* Given *COLUMN as an x-coordinate, print spaces to position
   successive output at DEST_COLUMN, printing a newline if necessary,
   and updating *COLUMN.  If ADD_LEFT_MARGIN, then print the (empty)
   left margin after any newline.  */

void
layout::move_to_column (int *column, int dest_column, bool add_left_margin)
{
  /* Start a new line if we need to.  */
  if (*column > dest_column)
    {
      print_newline ();
      if (add_left_margin)
	start_annotation_line ();
      *column = m_x_offset_display;
    }

  while (*column < dest_column)
    {
      pp_space (m_pp);
      (*column)++;
    }
}

/* For debugging layout issues, render a ruler giving column numbers
   (after the 1-column indent).  */

void
layout::show_ruler (int max_column) const
{
  /* Hundreds.  */
  if (max_column > 99)
    {
      start_annotation_line ();
      pp_space (m_pp);
      for (int column = 1 + m_x_offset_display; column <= max_column; column++)
	if (column % 10 == 0)
	  pp_character (m_pp, '0' + (column / 100) % 10);
	else
	  pp_space (m_pp);
      pp_newline (m_pp);
    }

  /* Tens.  */
  start_annotation_line ();
  pp_space (m_pp);
  for (int column = 1 + m_x_offset_display; column <= max_column; column++)
    if (column % 10 == 0)
      pp_character (m_pp, '0' + (column / 10) % 10);
    else
      pp_space (m_pp);
  pp_newline (m_pp);

  /* Units.  */
  start_annotation_line ();
  pp_space (m_pp);
  for (int column = 1 + m_x_offset_display; column <= max_column; column++)
    pp_character (m_pp, '0' + (column % 10));
  pp_newline (m_pp);
}

/* Print leading fix-its (for new lines inserted before the source line)
   then the source line, followed by an annotation line
   consisting of any caret/underlines, then any fixits.
   If the source line can't be read, print nothing.  */
void
layout::print_line (linenum_type row)
{
  char_span line = location_get_source_line (m_exploc.file, row);
  if (!line)
    return;

  print_leading_fixits (row);
  const line_bounds lbounds
    = print_source_line (row, line.get_buffer (), line.length ());
  if (should_print_annotation_line_p (row))
    print_annotation_line (row, lbounds);
  if (m_show_labels_p)
    print_any_labels (row);
  print_trailing_fixits (row);
}

} /* End of anonymous namespace.  */

/* If LOC is within the spans of lines that will already be printed for
   this gcc_rich_location, then add it as a secondary location and return true.

   Otherwise return false.  */

bool
gcc_rich_location::add_location_if_nearby (location_t loc,
					   bool restrict_to_current_line_spans,
					   const range_label *label)
{
  /* Use the layout location-handling logic to sanitize LOC,
     filtering it to the current line spans within a temporary
     layout instance.  */
  layout layout (global_dc, this, DK_ERROR);
  location_range loc_range;
  loc_range.m_loc = loc;
  loc_range.m_range_display_kind = SHOW_RANGE_WITHOUT_CARET;
  if (!layout.maybe_add_location_range (&loc_range, 0,
					restrict_to_current_line_spans))
    return false;

  add_range (loc, SHOW_RANGE_WITHOUT_CARET, label);
  return true;
}

/* Print the physical source code corresponding to the location of
   this diagnostic, with additional annotations.  */

void
diagnostic_show_locus (diagnostic_context * context,
		       rich_location *richloc,
		       diagnostic_t diagnostic_kind)
{
  location_t loc = richloc->get_loc ();
  /* Do nothing if source-printing has been disabled.  */
  if (!context->show_caret)
    return;

  /* Don't attempt to print source for UNKNOWN_LOCATION and for builtins.  */
  if (loc <= BUILTINS_LOCATION)
    return;

  /* Don't print the same source location twice in a row, unless we have
     fix-it hints, or multiple locations, or a label.  */
  if (loc == context->last_location
      && richloc->get_num_fixit_hints () == 0
      && richloc->get_num_locations () == 1
      && richloc->get_range (0)->m_label == NULL)
    return;

  context->last_location = loc;

  layout layout (context, richloc, diagnostic_kind);
  for (int line_span_idx = 0; line_span_idx < layout.get_num_line_spans ();
       line_span_idx++)
    {
      const line_span *line_span = layout.get_line_span (line_span_idx);
      if (context->show_line_numbers_p)
	{
	  /* With line numbers, we should show whenever the line-numbering
	     "jumps".  */
	  if (line_span_idx > 0)
	    layout.print_gap_in_line_numbering ();
	}
      else
	{
	  /* Without line numbers, we print headings for some line spans.  */
	  if (layout.print_heading_for_line_span_index_p (line_span_idx))
	    {
	      expanded_location exploc
		= layout.get_expanded_location (line_span);
	      context->start_span (context, exploc);
	    }
	}
      /* Iterate over the lines within this span (using linenum_arith_t to
	 avoid overflow with 0xffffffff causing an infinite loop).  */
      linenum_arith_t last_line = line_span->get_last_line ();
      for (linenum_arith_t row = line_span->get_first_line ();
	   row <= last_line; row++)
	layout.print_line (row);
    }
}

#if CHECKING_P

namespace selftest {

/* Selftests for diagnostic_show_locus.  */

/* Verify that cpp_display_width correctly handles escaping.  */

static void
test_display_widths ()
{
  gcc_rich_location richloc (UNKNOWN_LOCATION);

  /* U+03C0 "GREEK SMALL LETTER PI".  */
  const char *pi = "\xCF\x80";
  /* U+1F642 "SLIGHTLY SMILING FACE".  */
  const char *emoji = "\xF0\x9F\x99\x82";
  /* Stray trailing byte of a UTF-8 character.  */
  const char *stray = "\xBF";
  /* U+10FFFF.  */
  const char *max_codepoint = "\xF4\x8F\xBF\xBF";

  /* No escaping.  */
  {
    test_diagnostic_context dc;
    char_display_policy policy (make_policy (dc, richloc));
    ASSERT_EQ (cpp_display_width (pi, strlen (pi), policy), 1);
    ASSERT_EQ (cpp_display_width (emoji, strlen (emoji), policy), 2);
    ASSERT_EQ (cpp_display_width (stray, strlen (stray), policy), 1);
    /* Don't check width of U+10FFFF; it's in a private use plane.  */
  }

  richloc.set_escape_on_output (true);

  {
    test_diagnostic_context dc;
    dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
    char_display_policy policy (make_policy (dc, richloc));
    ASSERT_EQ (cpp_display_width (pi, strlen (pi), policy), 8);
    ASSERT_EQ (cpp_display_width (emoji, strlen (emoji), policy), 9);
    ASSERT_EQ (cpp_display_width (stray, strlen (stray), policy), 4);
    ASSERT_EQ (cpp_display_width (max_codepoint, strlen (max_codepoint),
				  policy),
	       strlen ("<U+10FFFF>"));
  }

  {
    test_diagnostic_context dc;
    dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_BYTES;
    char_display_policy policy (make_policy (dc, richloc));
    ASSERT_EQ (cpp_display_width (pi, strlen (pi), policy), 8);
    ASSERT_EQ (cpp_display_width (emoji, strlen (emoji), policy), 16);
    ASSERT_EQ (cpp_display_width (stray, strlen (stray), policy), 4);
    ASSERT_EQ (cpp_display_width (max_codepoint, strlen (max_codepoint),
				  policy),
	       16);
  }
}

/* For precise tests of the layout, make clear where the source line will
   start.  test_left_margin sets the total byte count from the left side of the
   screen to the start of source lines, after the line number and the separator,
   which consists of the three characters " | ".  */
static const int test_linenum_sep = 3;
static const int test_left_margin = 7;

/* Helper function for test_layout_x_offset_display_utf8().  */
static void
test_offset_impl (int caret_byte_col, int max_width,
		  int expected_x_offset_display,
		  int left_margin = test_left_margin)
{
  test_diagnostic_context dc;
  dc.caret_max_width = max_width;
  /* diagnostic_context::min_margin_width sets the minimum space reserved for
     the line number plus one space after.  */
  dc.min_margin_width = left_margin - test_linenum_sep + 1;
  dc.show_line_numbers_p = true;
  rich_location richloc (line_table,
			 linemap_position_for_column (line_table,
						      caret_byte_col));
  layout test_layout (&dc, &richloc, DK_ERROR);
  ASSERT_EQ (left_margin - test_linenum_sep,
	     test_layout.get_linenum_width ());
  ASSERT_EQ (expected_x_offset_display,
	     test_layout.get_x_offset_display ());
}

/* Test that layout::calculate_x_offset_display() works.  */
static void
test_layout_x_offset_display_utf8 (const line_table_case &case_)
{

  const char *content
    = "This line is very long, so that we can use it to test the logic for "
      "clipping long lines.  Also this: \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a "
      "pair of emojis that occupies 8 bytes and 4 display columns, starting at "
      "column #102.\n";

  /* Number of bytes in the line, subtracting one to remove the newline.  */
  const int line_bytes = strlen (content) - 1;

  /* Number of display columns occupied by the line; each of the 2 emojis
     takes up 2 fewer display columns than it does bytes.  */
  const int line_display_cols = line_bytes - 2*2;

  /* The column of the first emoji.  Byte or display is the same as there are
     no multibyte characters earlier on the line.  */
  const int emoji_col = 102;

  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);

  linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);

  location_t line_end = linemap_position_for_column (line_table, line_bytes);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end));
  ASSERT_EQ (1, LOCATION_LINE (line_end));
  ASSERT_EQ (line_bytes, LOCATION_COLUMN (line_end));

  char_span lspan = location_get_source_line (tmp.get_filename (), 1);
  ASSERT_EQ (line_display_cols,
	     cpp_display_width (lspan.get_buffer (), lspan.length (),
				def_policy ()));
  ASSERT_EQ (line_display_cols,
	     location_compute_display_column (expand_location (line_end),
					      def_policy ()));
  ASSERT_EQ (0, memcmp (lspan.get_buffer () + (emoji_col - 1),
			"\xf0\x9f\x98\x82\xf0\x9f\x98\x82", 8));

  /* (caret_byte, max_width, expected_x_offset_display, [left_margin])  */

  /* No constraint on the width -> no offset.  */
  test_offset_impl (emoji_col, 0, 0);

  /* Caret is before the beginning -> no offset.  */
  test_offset_impl (0, 100, 0);

  /* Caret is past the end of the line -> no offset.  */
  test_offset_impl (line_bytes+1, 100, 0);

  /* Line fits in the display -> no offset.  */
  test_offset_impl (line_bytes, line_display_cols + test_left_margin, 0);
  test_offset_impl (emoji_col, line_display_cols + test_left_margin, 0);

  /* Line is too long for the display but caret location is OK
     anyway -> no offset.  */
  static const int small_width = 24;
  test_offset_impl (1, small_width, 0);

  /* Width constraint is very small -> no offset.  */
  test_offset_impl (emoji_col, CARET_LINE_MARGIN, 0);

  /* Line would be offset, but due to large line numbers, offsetting
     would remove the whole line -> no offset.  */
  static const int huge_left_margin = 100;
  test_offset_impl (emoji_col, huge_left_margin, 0, huge_left_margin);

  /* Line is the same length as the display, but the line number makes it too
     long, so offset is required.  Caret is at the end so padding on the right
     is not in effect.  */
  for (int excess = 1; excess <= 3; ++excess)
    test_offset_impl (line_bytes, line_display_cols + test_left_margin - excess,
		      excess);

  /* Line is much too long for the display, caret is near the end ->
     offset should be such that the line fits in the display and caret
     remains the same distance from the end that it was.  */
  for (int caret_offset = 0, max_offset = MIN (CARET_LINE_MARGIN, 10);
       caret_offset <= max_offset; ++caret_offset)
    test_offset_impl (line_bytes - caret_offset, small_width,
		      line_display_cols + test_left_margin - small_width);

  /* As previous case but caret is closer to the middle; now we want it to end
     up CARET_LINE_MARGIN bytes from the end.  */
  ASSERT_GT (line_display_cols - emoji_col, CARET_LINE_MARGIN);
  test_offset_impl (emoji_col, small_width,
		    emoji_col + test_left_margin
		    - (small_width - CARET_LINE_MARGIN));

  /* Test that the source line is offset as expected when printed.  */
  {
    test_diagnostic_context dc;
    dc.caret_max_width = small_width - 6;
    dc.min_margin_width = test_left_margin - test_linenum_sep + 1;
    dc.show_line_numbers_p = true;
    dc.show_ruler_p = true;
    rich_location richloc (line_table,
			   linemap_position_for_column (line_table,
							emoji_col));
    layout test_layout (&dc, &richloc, DK_ERROR);
    test_layout.print_line (1);
    ASSERT_STREQ ("     |         1         \n"
		  "     |         1         \n"
		  "     | 234567890123456789\n"
		  "   1 | \xf0\x9f\x98\x82\xf0\x9f\x98\x82 is a pair of emojis "
		  "that occupies 8 bytes and 4 display columns, starting at "
		  "column #102.\n"
		  "     | ^\n\n",
		  pp_formatted_text (dc.printer));
  }

  /* Similar to the previous example, but now the offset called for would split
     the first emoji in the middle of the UTF-8 sequence.  Check that we replace
     it with a padding space in this case.  */
  {
    test_diagnostic_context dc;
    dc.caret_max_width = small_width - 5;
    dc.min_margin_width = test_left_margin - test_linenum_sep + 1;
    dc.show_line_numbers_p = true;
    dc.show_ruler_p = true;
    rich_location richloc (line_table,
			   linemap_position_for_column (line_table,
							emoji_col + 2));
    layout test_layout (&dc, &richloc, DK_ERROR);
    test_layout.print_line (1);
    ASSERT_STREQ ("     |        1         1 \n"
		  "     |        1         2 \n"
		  "     | 3456789012345678901\n"
		  "   1 |  \xf0\x9f\x98\x82 is a pair of emojis "
		  "that occupies 8 bytes and 4 display columns, starting at "
		  "column #102.\n"
		  "     |  ^\n\n",
		  pp_formatted_text (dc.printer));
  }

}

static void
test_layout_x_offset_display_tab (const line_table_case &case_)
{
  const char *content
    = "This line is very long, so that we can use it to test the logic for "
      "clipping long lines.  Also this: `\t' is a tab that occupies 1 byte and "
      "a variable number of display columns, starting at column #103.\n";

  /* Number of bytes in the line, subtracting one to remove the newline.  */
  const int line_bytes = strlen (content) - 1;

 /* The column where the tab begins.  Byte or display is the same as there are
    no multibyte characters earlier on the line.  */
  const int tab_col = 103;

  /* Effective extra size of the tab beyond what a single space would have taken
     up, indexed by tabstop.  */
  static const int num_tabstops = 11;
  int extra_width[num_tabstops];
  for (int tabstop = 1; tabstop != num_tabstops; ++tabstop)
    {
      const int this_tab_size = tabstop - (tab_col - 1) % tabstop;
      extra_width[tabstop] = this_tab_size - 1;
    }
  /* Example of this calculation: if tabstop is 10, the tab starting at column
     #103 has to expand into 8 spaces, covering columns 103-110, so that the
     next character is at column #111.  So it takes up 7 more columns than
     a space would have taken up.  */
  ASSERT_EQ (7, extra_width[10]);

  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);

  linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);

  location_t line_end = linemap_position_for_column (line_table, line_bytes);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* Check that cpp_display_width handles the tabs as expected.  */
  char_span lspan = location_get_source_line (tmp.get_filename (), 1);
  ASSERT_EQ ('\t', *(lspan.get_buffer () + (tab_col - 1)));
  for (int tabstop = 1; tabstop != num_tabstops; ++tabstop)
    {
      cpp_char_column_policy policy (tabstop, cpp_wcwidth);
      ASSERT_EQ (line_bytes + extra_width[tabstop],
		 cpp_display_width (lspan.get_buffer (), lspan.length (),
				    policy));
      ASSERT_EQ (line_bytes + extra_width[tabstop],
		 location_compute_display_column (expand_location (line_end),
						  policy));
    }

  /* Check that the tab is expanded to the expected number of spaces.  */
  rich_location richloc (line_table,
			 linemap_position_for_column (line_table,
						      tab_col + 1));
  for (int tabstop = 1; tabstop != num_tabstops; ++tabstop)
    {
      test_diagnostic_context dc;
      dc.tabstop = tabstop;
      layout test_layout (&dc, &richloc, DK_ERROR);
      test_layout.print_line (1);
      const char *out = pp_formatted_text (dc.printer);
      ASSERT_EQ (NULL, strchr (out, '\t'));
      const char *left_quote = strchr (out, '`');
      const char *right_quote = strchr (out, '\'');
      ASSERT_NE (NULL, left_quote);
      ASSERT_NE (NULL, right_quote);
      ASSERT_EQ (right_quote - left_quote, extra_width[tabstop] + 2);
    }

  /* Check that the line is offset properly and that the tab is broken up
     into the expected number of spaces when it is the last character skipped
     over.  */
  for (int tabstop = 1; tabstop != num_tabstops; ++tabstop)
    {
      test_diagnostic_context dc;
      dc.tabstop = tabstop;
      static const int small_width = 24;
      dc.caret_max_width = small_width - 4;
      dc.min_margin_width = test_left_margin - test_linenum_sep + 1;
      dc.show_line_numbers_p = true;
      layout test_layout (&dc, &richloc, DK_ERROR);
      test_layout.print_line (1);

      /* We have arranged things so that two columns will be printed before
	 the caret.  If the tab results in more than one space, this should
	 produce two spaces in the output; otherwise, it will be a single space
	 preceded by the opening quote before the tab character.  */
      const char *output1
	= "   1 |   ' is a tab that occupies 1 byte and a variable number of "
	  "display columns, starting at column #103.\n"
	  "     |   ^\n\n";
      const char *output2
	= "   1 | ` ' is a tab that occupies 1 byte and a variable number of "
	  "display columns, starting at column #103.\n"
	  "     |   ^\n\n";
      const char *expected_output = (extra_width[tabstop] ? output1 : output2);
      ASSERT_STREQ (expected_output, pp_formatted_text (dc.printer));
    }
}


/* Verify that diagnostic_show_locus works sanely on UNKNOWN_LOCATION.  */

static void
test_diagnostic_show_locus_unknown_location ()
{
  test_diagnostic_context dc;
  rich_location richloc (line_table, UNKNOWN_LOCATION);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ ("", pp_formatted_text (dc.printer));
}

/* Verify that diagnostic_show_locus works sanely for various
   single-line cases.

   All of these work on the following 1-line source file:
     .0000000001111111
     .1234567890123456
     "foo = bar.field;\n"
   which is set up by test_diagnostic_show_locus_one_liner and calls
   them.  */

/* Just a caret.  */

static void
test_one_liner_simple_caret ()
{
  test_diagnostic_context dc;
  location_t caret = linemap_position_for_column (line_table, 10);
  rich_location richloc (line_table, caret);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		"          ^\n",
		pp_formatted_text (dc.printer));
}

/* Caret and range.  */

static void
test_one_liner_caret_and_range ()
{
  test_diagnostic_context dc;
  location_t caret = linemap_position_for_column (line_table, 10);
  location_t start = linemap_position_for_column (line_table, 7);
  location_t finish = linemap_position_for_column (line_table, 15);
  location_t loc = make_location (caret, start, finish);
  rich_location richloc (line_table, loc);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		"       ~~~^~~~~~\n",
		pp_formatted_text (dc.printer));
}

/* Multiple ranges and carets.  */

static void
test_one_liner_multiple_carets_and_ranges ()
{
  test_diagnostic_context dc;
  location_t foo
    = make_location (linemap_position_for_column (line_table, 2),
		     linemap_position_for_column (line_table, 1),
		     linemap_position_for_column (line_table, 3));
  dc.caret_chars[0] = 'A';

  location_t bar
    = make_location (linemap_position_for_column (line_table, 8),
		     linemap_position_for_column (line_table, 7),
		     linemap_position_for_column (line_table, 9));
  dc.caret_chars[1] = 'B';

  location_t field
    = make_location (linemap_position_for_column (line_table, 13),
		     linemap_position_for_column (line_table, 11),
		     linemap_position_for_column (line_table, 15));
  dc.caret_chars[2] = 'C';

  rich_location richloc (line_table, foo);
  richloc.add_range (bar, SHOW_RANGE_WITH_CARET);
  richloc.add_range (field, SHOW_RANGE_WITH_CARET);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		" ~A~   ~B~ ~~C~~\n",
		pp_formatted_text (dc.printer));
}

/* Insertion fix-it hint: adding an "&" to the front of "bar.field". */

static void
test_one_liner_fixit_insert_before ()
{
  test_diagnostic_context dc;
  location_t caret = linemap_position_for_column (line_table, 7);
  rich_location richloc (line_table, caret);
  richloc.add_fixit_insert_before ("&");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		"       ^\n"
		"       &\n",
		pp_formatted_text (dc.printer));
}

/* Insertion fix-it hint: adding a "[0]" after "foo". */

static void
test_one_liner_fixit_insert_after ()
{
  test_diagnostic_context dc;
  location_t start = linemap_position_for_column (line_table, 1);
  location_t finish = linemap_position_for_column (line_table, 3);
  location_t foo = make_location (start, start, finish);
  rich_location richloc (line_table, foo);
  richloc.add_fixit_insert_after ("[0]");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		" ^~~\n"
		"    [0]\n",
		pp_formatted_text (dc.printer));
}

/* Removal fix-it hint: removal of the ".field".
   Also verify the interaction of pp_set_prefix with rulers and
   fix-it hints.  */

static void
test_one_liner_fixit_remove ()
{
  location_t start = linemap_position_for_column (line_table, 10);
  location_t finish = linemap_position_for_column (line_table, 15);
  location_t dot = make_location (start, start, finish);
  rich_location richloc (line_table, dot);
  richloc.add_fixit_remove ();

  /* Normal.  */
  {
    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  "          ^~~~~~\n"
		  "          ------\n",
		  pp_formatted_text (dc.printer));
  }

  /* Test of adding a prefix.  */
  {
    test_diagnostic_context dc;
    pp_prefixing_rule (dc.printer) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
    pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:"));
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("TEST PREFIX: foo = bar.field;\n"
		  "TEST PREFIX:          ^~~~~~\n"
		  "TEST PREFIX:          ------\n",
		  pp_formatted_text (dc.printer));
  }

  /* Normal, with ruler.  */
  {
    test_diagnostic_context dc;
    dc.show_ruler_p = true;
    dc.caret_max_width = 104;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("          0         0         0         0         0         0         0         0         0         1    \n"
		  "          1         2         3         4         5         6         7         8         9         0    \n"
		  " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n"
		  " foo = bar.field;\n"
		  "          ^~~~~~\n"
		  "          ------\n",
		  pp_formatted_text (dc.printer));
  }

  /* Test of adding a prefix, with ruler.  */
  {
    test_diagnostic_context dc;
    dc.show_ruler_p = true;
    dc.caret_max_width = 50;
    pp_prefixing_rule (dc.printer) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
    pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:"));
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("TEST PREFIX:          1         2         3         4         5\n"
		  "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n"
		  "TEST PREFIX: foo = bar.field;\n"
		  "TEST PREFIX:          ^~~~~~\n"
		  "TEST PREFIX:          ------\n",
		  pp_formatted_text (dc.printer));
  }

  /* Test of adding a prefix, with ruler and line numbers.  */
  {
    test_diagnostic_context dc;
    dc.show_ruler_p = true;
    dc.caret_max_width = 50;
    dc.show_line_numbers_p = true;
    pp_prefixing_rule (dc.printer) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
    pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:"));
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("TEST PREFIX:      |          1         2         3         4         5\n"
		  "TEST PREFIX:      | 12345678901234567890123456789012345678901234567890\n"
		  "TEST PREFIX:    1 | foo = bar.field;\n"
		  "TEST PREFIX:      |          ^~~~~~\n"
		  "TEST PREFIX:      |          ------\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Replace fix-it hint: replacing "field" with "m_field". */

static void
test_one_liner_fixit_replace ()
{
  test_diagnostic_context dc;
  location_t start = linemap_position_for_column (line_table, 11);
  location_t finish = linemap_position_for_column (line_table, 15);
  location_t field = make_location (start, start, finish);
  rich_location richloc (line_table, field);
  richloc.add_fixit_replace ("m_field");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		"           ^~~~~\n"
		"           m_field\n",
		pp_formatted_text (dc.printer));
}

/* Replace fix-it hint: replacing "field" with "m_field",
   but where the caret was elsewhere.  */

static void
test_one_liner_fixit_replace_non_equal_range ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 5);
  location_t start = linemap_position_for_column (line_table, 11);
  location_t finish = linemap_position_for_column (line_table, 15);
  rich_location richloc (line_table, equals);
  source_range range;
  range.m_start = start;
  range.m_finish = finish;
  richloc.add_fixit_replace (range, "m_field");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  /* The replacement range is not indicated in the annotation line, so
     it should be indicated via an additional underline.  */
  ASSERT_STREQ (" foo = bar.field;\n"
		"     ^\n"
		"           -----\n"
		"           m_field\n",
		pp_formatted_text (dc.printer));
}

/* Replace fix-it hint: replacing "field" with "m_field",
   where the caret was elsewhere, but where a secondary range
   exactly covers "field".  */

static void
test_one_liner_fixit_replace_equal_secondary_range ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 5);
  location_t start = linemap_position_for_column (line_table, 11);
  location_t finish = linemap_position_for_column (line_table, 15);
  rich_location richloc (line_table, equals);
  location_t field = make_location (start, start, finish);
  richloc.add_range (field);
  richloc.add_fixit_replace (field, "m_field");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  /* The replacement range is indicated in the annotation line,
     so it shouldn't be indicated via an additional underline.  */
  ASSERT_STREQ (" foo = bar.field;\n"
		"     ^     ~~~~~\n"
		"           m_field\n",
		pp_formatted_text (dc.printer));
}

/* Verify that we can use ad-hoc locations when adding fixits to a
   rich_location.  */

static void
test_one_liner_fixit_validation_adhoc_locations ()
{
  /* Generate a range that's too long to be packed, so must
     be stored as an ad-hoc location (given the defaults
     of 5 bits or 0 bits of packed range); 41 columns > 2**5.  */
  const location_t c7 = linemap_position_for_column (line_table, 7);
  const location_t c47 = linemap_position_for_column (line_table, 47);
  const location_t loc = make_location (c7, c7, c47);

  if (c47 > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  ASSERT_TRUE (IS_ADHOC_LOC (loc));

  /* Insert.  */
  {
    rich_location richloc (line_table, loc);
    richloc.add_fixit_insert_before (loc, "test");
    /* It should not have been discarded by the validator.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  "       ^~~~~~~~~~                               \n"
		  "       test\n",
		  pp_formatted_text (dc.printer));
  }

  /* Remove.  */
  {
    rich_location richloc (line_table, loc);
    source_range range = source_range::from_locations (loc, c47);
    richloc.add_fixit_remove (range);
    /* It should not have been discarded by the validator.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  "       ^~~~~~~~~~                               \n"
		  "       -----------------------------------------\n",
		  pp_formatted_text (dc.printer));
  }

  /* Replace.  */
  {
    rich_location richloc (line_table, loc);
    source_range range = source_range::from_locations (loc, c47);
    richloc.add_fixit_replace (range, "test");
    /* It should not have been discarded by the validator.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  "       ^~~~~~~~~~                               \n"
		  "       test\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Test of consolidating insertions at the same location.  */

static void
test_one_liner_many_fixits_1 ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 5);
  rich_location richloc (line_table, equals);
  for (int i = 0; i < 19; i++)
    richloc.add_fixit_insert_before ("a");
  ASSERT_EQ (1, richloc.get_num_fixit_hints ());
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		"     ^\n"
		"     aaaaaaaaaaaaaaaaaaa\n",
		pp_formatted_text (dc.printer));
}

/* Ensure that we can add an arbitrary number of fix-it hints to a
   rich_location, even if they are not consolidated.  */

static void
test_one_liner_many_fixits_2 ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 5);
  rich_location richloc (line_table, equals);
  for (int i = 0; i < 19; i++)
    {
      location_t loc = linemap_position_for_column (line_table, (i * 2) + 1);
      richloc.add_fixit_insert_before (loc, "a");
    }
  ASSERT_EQ (19, richloc.get_num_fixit_hints ());
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar.field;\n"
		"     ^\n"
		" a a a a a a a a a a a a a a a a a a a\n",
		pp_formatted_text (dc.printer));
}

/* Test of labeling the ranges within a rich_location.  */

static void
test_one_liner_labels ()
{
  location_t foo
    = make_location (linemap_position_for_column (line_table, 1),
		     linemap_position_for_column (line_table, 1),
		     linemap_position_for_column (line_table, 3));
  location_t bar
    = make_location (linemap_position_for_column (line_table, 7),
		     linemap_position_for_column (line_table, 7),
		     linemap_position_for_column (line_table, 9));
  location_t field
    = make_location (linemap_position_for_column (line_table, 11),
		     linemap_position_for_column (line_table, 11),
		     linemap_position_for_column (line_table, 15));

  /* Example where all the labels fit on one line.  */
  {
    text_range_label label0 ("0");
    text_range_label label1 ("1");
    text_range_label label2 ("2");
    gcc_rich_location richloc (foo, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);

    {
      test_diagnostic_context dc;
      diagnostic_show_locus (&dc, &richloc, DK_ERROR);
      ASSERT_STREQ (" foo = bar.field;\n"
		    " ^~~   ~~~ ~~~~~\n"
		    " |     |   |\n"
		    " 0     1   2\n",
		    pp_formatted_text (dc.printer));
    }

    /* Verify that we can disable label-printing.  */
    {
      test_diagnostic_context dc;
      dc.show_labels_p = false;
      diagnostic_show_locus (&dc, &richloc, DK_ERROR);
      ASSERT_STREQ (" foo = bar.field;\n"
		    " ^~~   ~~~ ~~~~~\n",
		    pp_formatted_text (dc.printer));
    }
  }

  /* Example where the labels need extra lines.  */
  {
    text_range_label label0 ("label 0");
    text_range_label label1 ("label 1");
    text_range_label label2 ("label 2");
    gcc_rich_location richloc (foo, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  " ^~~   ~~~ ~~~~~\n"
		  " |     |   |\n"
		  " |     |   label 2\n"
		  " |     label 1\n"
		  " label 0\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of boundary conditions: label 0 and 1 have just enough clearance,
     but label 1 just touches label 2.  */
  {
    text_range_label label0 ("aaaaa");
    text_range_label label1 ("bbbb");
    text_range_label label2 ("c");
    gcc_rich_location richloc (foo, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  " ^~~   ~~~ ~~~~~\n"
		  " |     |   |\n"
		  " |     |   c\n"
		  " aaaaa bbbb\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of out-of-order ranges (thus requiring a sort).  */
  {
    text_range_label label0 ("0");
    text_range_label label1 ("1");
    text_range_label label2 ("2");
    gcc_rich_location richloc (field, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label2);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  " ~~~   ~~~ ^~~~~\n"
		  " |     |   |\n"
		  " 2     1   0\n",
		  pp_formatted_text (dc.printer));
  }

  /* Ensure we don't ICE if multiple ranges with labels are on
     the same point.  */
  {
    text_range_label label0 ("label 0");
    text_range_label label1 ("label 1");
    text_range_label label2 ("label 2");
    gcc_rich_location richloc (bar, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label2);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  "       ^~~\n"
		  "       |\n"
		  "       label 0\n"
		  "       label 1\n"
		  "       label 2\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of out-of-order ranges (thus requiring a sort), where
     they overlap, and there are multiple ranges on the same point.  */
  {
    text_range_label label_0a ("label 0a");
    text_range_label label_1a ("label 1a");
    text_range_label label_2a ("label 2a");
    text_range_label label_0b ("label 0b");
    text_range_label label_1b ("label 1b");
    text_range_label label_2b ("label 2b");
    text_range_label label_0c ("label 0c");
    text_range_label label_1c ("label 1c");
    text_range_label label_2c ("label 2c");
    gcc_rich_location richloc (field, &label_0a);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label_1a);
    richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label_2a);

    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label_0b);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label_1b);
    richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label_2b);

    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label_0c);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label_1c);
    richloc.add_range (foo, SHOW_RANGE_WITHOUT_CARET, &label_2c);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  " ~~~   ~~~ ^~~~~\n"
		  " |     |   |\n"
		  " |     |   label 0a\n"
		  " |     |   label 0b\n"
		  " |     |   label 0c\n"
		  " |     label 1a\n"
		  " |     label 1b\n"
		  " |     label 1c\n"
		  " label 2a\n"
		  " label 2b\n"
		  " label 2c\n",
		  pp_formatted_text (dc.printer));
  }

  /* Verify that a NULL result from range_label::get_text is
     handled gracefully.  */
  {
    text_range_label label (NULL);
    gcc_rich_location richloc (bar, &label);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" foo = bar.field;\n"
		  "       ^~~\n",
		  pp_formatted_text (dc.printer));
   }

  /* TODO: example of formatted printing (needs to be in
     gcc-rich-location.cc due to Makefile.in issues).  */
}

/* Run the various one-liner tests.  */

static void
test_diagnostic_show_locus_one_liner (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
     ....................0000000001111111.
     ....................1234567890123456.  */
  const char *content = "foo = bar.field;\n";
  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);

  linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);

  location_t line_end = linemap_position_for_column (line_table, 16);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end));
  ASSERT_EQ (1, LOCATION_LINE (line_end));
  ASSERT_EQ (16, LOCATION_COLUMN (line_end));

  test_one_liner_simple_caret ();
  test_one_liner_caret_and_range ();
  test_one_liner_multiple_carets_and_ranges ();
  test_one_liner_fixit_insert_before ();
  test_one_liner_fixit_insert_after ();
  test_one_liner_fixit_remove ();
  test_one_liner_fixit_replace ();
  test_one_liner_fixit_replace_non_equal_range ();
  test_one_liner_fixit_replace_equal_secondary_range ();
  test_one_liner_fixit_validation_adhoc_locations ();
  test_one_liner_many_fixits_1 ();
  test_one_liner_many_fixits_2 ();
  test_one_liner_labels ();
}

/* Version of all one-liner tests exercising multibyte awareness.  For
   simplicity we stick to using two multibyte characters in the test, U+1F602
   == "\xf0\x9f\x98\x82", which uses 4 bytes and 2 display columns, and U+03C0
   == "\xcf\x80", which uses 2 bytes and 1 display column.  Note: all of the
   below asserts would be easier to read if we used UTF-8 directly in the
   string constants, but it seems better not to demand the host compiler
   support this, when it isn't otherwise necessary.  Instead, whenever an
   extended character appears in a string, we put a line break after it so that
   all succeeding characters can appear visually at the correct display column.

   All of these work on the following 1-line source file:

     .0000000001111111111222222   display
     .1234567890123456789012345   columns
     "SS_foo = P_bar.SS_fieldP;\n"
     .0000000111111111222222223   byte
     .1356789012456789134567891   columns

   which is set up by test_diagnostic_show_locus_one_liner and calls
   them.  Here SS represents the two display columns for the U+1F602 emoji and
   P represents the one display column for the U+03C0 pi symbol.  */

/* Just a caret.  */

static void
test_one_liner_simple_caret_utf8 ()
{
  test_diagnostic_context dc;
  location_t caret = linemap_position_for_column (line_table, 18);
  rich_location richloc (line_table, caret);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"               ^\n",
		pp_formatted_text (dc.printer));
}

/* Caret and range.  */
static void
test_one_liner_caret_and_range_utf8 ()
{
  test_diagnostic_context dc;
  location_t caret = linemap_position_for_column (line_table, 18);
  location_t start = linemap_position_for_column (line_table, 12);
  location_t finish = linemap_position_for_column (line_table, 30);
  location_t loc = make_location (caret, start, finish);
  rich_location richloc (line_table, loc);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"          ~~~~~^~~~~~~~~~\n",
		pp_formatted_text (dc.printer));
}

/* Multiple ranges and carets.  */

static void
test_one_liner_multiple_carets_and_ranges_utf8 ()
{
  test_diagnostic_context dc;
  location_t foo
    = make_location (linemap_position_for_column (line_table, 7),
		     linemap_position_for_column (line_table, 1),
		     linemap_position_for_column (line_table, 8));
  dc.caret_chars[0] = 'A';

  location_t bar
    = make_location (linemap_position_for_column (line_table, 16),
		     linemap_position_for_column (line_table, 12),
		     linemap_position_for_column (line_table, 17));
  dc.caret_chars[1] = 'B';

  location_t field
    = make_location (linemap_position_for_column (line_table, 26),
		     linemap_position_for_column (line_table, 19),
		     linemap_position_for_column (line_table, 30));
  dc.caret_chars[2] = 'C';
  rich_location richloc (line_table, foo);
  richloc.add_range (bar, SHOW_RANGE_WITH_CARET);
  richloc.add_range (field, SHOW_RANGE_WITH_CARET);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		" ~~~~A~   ~~~B~ ~~~~~C~~~\n",
		pp_formatted_text (dc.printer));
}

/* Insertion fix-it hint: adding an "&" to the front of "P_bar.field". */

static void
test_one_liner_fixit_insert_before_utf8 ()
{
  test_diagnostic_context dc;
  location_t caret = linemap_position_for_column (line_table, 12);
  rich_location richloc (line_table, caret);
  richloc.add_fixit_insert_before ("&");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"          ^\n"
		"          &\n",
		pp_formatted_text (dc.printer));
}

/* Insertion fix-it hint: adding a "[0]" after "SS_foo". */

static void
test_one_liner_fixit_insert_after_utf8 ()
{
  test_diagnostic_context dc;
  location_t start = linemap_position_for_column (line_table, 1);
  location_t finish = linemap_position_for_column (line_table, 8);
  location_t foo = make_location (start, start, finish);
  rich_location richloc (line_table, foo);
  richloc.add_fixit_insert_after ("[0]");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		" ^~~~~~\n"
		"       [0]\n",
		pp_formatted_text (dc.printer));
}

/* Removal fix-it hint: removal of the ".SS_fieldP". */

static void
test_one_liner_fixit_remove_utf8 ()
{
  test_diagnostic_context dc;
  location_t start = linemap_position_for_column (line_table, 18);
  location_t finish = linemap_position_for_column (line_table, 30);
  location_t dot = make_location (start, start, finish);
  rich_location richloc (line_table, dot);
  richloc.add_fixit_remove ();
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"               ^~~~~~~~~~\n"
		"               ----------\n",
		pp_formatted_text (dc.printer));
}

/* Replace fix-it hint: replacing "SS_fieldP" with "m_SSfieldP". */

static void
test_one_liner_fixit_replace_utf8 ()
{
  test_diagnostic_context dc;
  location_t start = linemap_position_for_column (line_table, 19);
  location_t finish = linemap_position_for_column (line_table, 30);
  location_t field = make_location (start, start, finish);
  rich_location richloc (line_table, field);
  richloc.add_fixit_replace ("m_\xf0\x9f\x98\x82_field\xcf\x80");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"                ^~~~~~~~~\n"
		"                m_\xf0\x9f\x98\x82"
				    "_field\xcf\x80\n",
		pp_formatted_text (dc.printer));
}

/* Replace fix-it hint: replacing "SS_fieldP" with "m_SSfieldP",
   but where the caret was elsewhere.  */

static void
test_one_liner_fixit_replace_non_equal_range_utf8 ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 10);
  location_t start = linemap_position_for_column (line_table, 19);
  location_t finish = linemap_position_for_column (line_table, 30);
  rich_location richloc (line_table, equals);
  source_range range;
  range.m_start = start;
  range.m_finish = finish;
  richloc.add_fixit_replace (range, "m_\xf0\x9f\x98\x82_field\xcf\x80");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  /* The replacement range is not indicated in the annotation line, so
     it should be indicated via an additional underline.  */
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"        ^\n"
		"                ---------\n"
		"                m_\xf0\x9f\x98\x82"
				    "_field\xcf\x80\n",
		pp_formatted_text (dc.printer));
}

/* Replace fix-it hint: replacing "SS_fieldP" with "m_SSfieldP",
   where the caret was elsewhere, but where a secondary range
   exactly covers "field".  */

static void
test_one_liner_fixit_replace_equal_secondary_range_utf8 ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 10);
  location_t start = linemap_position_for_column (line_table, 19);
  location_t finish = linemap_position_for_column (line_table, 30);
  rich_location richloc (line_table, equals);
  location_t field = make_location (start, start, finish);
  richloc.add_range (field);
  richloc.add_fixit_replace (field, "m_\xf0\x9f\x98\x82_field\xcf\x80");
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  /* The replacement range is indicated in the annotation line,
     so it shouldn't be indicated via an additional underline.  */
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"        ^       ~~~~~~~~~\n"
		"                m_\xf0\x9f\x98\x82"
				    "_field\xcf\x80\n",
		pp_formatted_text (dc.printer));
}

/* Verify that we can use ad-hoc locations when adding fixits to a
   rich_location.  */

static void
test_one_liner_fixit_validation_adhoc_locations_utf8 ()
{
  /* Generate a range that's too long to be packed, so must
     be stored as an ad-hoc location (given the defaults
     of 5 bits or 0 bits of packed range); 41 columns > 2**5.  */
  const location_t c12 = linemap_position_for_column (line_table, 12);
  const location_t c52 = linemap_position_for_column (line_table, 52);
  const location_t loc = make_location (c12, c12, c52);

  if (c52 > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  ASSERT_TRUE (IS_ADHOC_LOC (loc));

  /* Insert.  */
  {
    rich_location richloc (line_table, loc);
    richloc.add_fixit_insert_before (loc, "test");
    /* It should not have been discarded by the validator.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" \xf0\x9f\x98\x82"
		     "_foo = \xcf\x80"
			     "_bar.\xf0\x9f\x98\x82"
				    "_field\xcf\x80"
					   ";\n"
		  "          ^~~~~~~~~~~~~~~~                     \n"
		  "          test\n",
		pp_formatted_text (dc.printer));
  }

  /* Remove.  */
  {
    rich_location richloc (line_table, loc);
    source_range range = source_range::from_locations (loc, c52);
    richloc.add_fixit_remove (range);
    /* It should not have been discarded by the validator.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" \xf0\x9f\x98\x82"
		     "_foo = \xcf\x80"
			     "_bar.\xf0\x9f\x98\x82"
				    "_field\xcf\x80"
					   ";\n"
		  "          ^~~~~~~~~~~~~~~~                     \n"
		  "          -------------------------------------\n",
		pp_formatted_text (dc.printer));
  }

  /* Replace.  */
  {
    rich_location richloc (line_table, loc);
    source_range range = source_range::from_locations (loc, c52);
    richloc.add_fixit_replace (range, "test");
    /* It should not have been discarded by the validator.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" \xf0\x9f\x98\x82"
		     "_foo = \xcf\x80"
			     "_bar.\xf0\x9f\x98\x82"
				    "_field\xcf\x80"
					   ";\n"
		  "          ^~~~~~~~~~~~~~~~                     \n"
		  "          test\n",
		pp_formatted_text (dc.printer));
  }
}

/* Test of consolidating insertions at the same location.  */

static void
test_one_liner_many_fixits_1_utf8 ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 10);
  rich_location richloc (line_table, equals);
  for (int i = 0; i < 19; i++)
    richloc.add_fixit_insert_before (i & 1 ? "@" : "\xcf\x80");
  ASSERT_EQ (1, richloc.get_num_fixit_hints ());
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"        ^\n"
		"        \xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@"
		"\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80@\xcf\x80\n",
		pp_formatted_text (dc.printer));
}

/* Ensure that we can add an arbitrary number of fix-it hints to a
   rich_location, even if they are not consolidated.  */

static void
test_one_liner_many_fixits_2_utf8 ()
{
  test_diagnostic_context dc;
  location_t equals = linemap_position_for_column (line_table, 10);
  rich_location richloc (line_table, equals);
  const int nlocs = 19;
  int locs[nlocs] = {1, 5, 7, 9, 11, 14, 16, 18, 23, 25, 27, 29, 32,
		     34, 36, 38, 40, 42, 44};
  for (int i = 0; i != nlocs; ++i)
    {
      location_t loc = linemap_position_for_column (line_table, locs[i]);
      richloc.add_fixit_insert_before (loc, i & 1 ? "@" : "\xcf\x80");
    }

  ASSERT_EQ (nlocs, richloc.get_num_fixit_hints ());
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" \xf0\x9f\x98\x82"
		   "_foo = \xcf\x80"
			   "_bar.\xf0\x9f\x98\x82"
				  "_field\xcf\x80"
					 ";\n"
		"        ^\n"
		" \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @  \xcf\x80 @"
		" \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80 @ \xcf\x80\n",
		pp_formatted_text (dc.printer));
}

/* Test of labeling the ranges within a rich_location.  */

static void
test_one_liner_labels_utf8 ()
{
  location_t foo
    = make_location (linemap_position_for_column (line_table, 1),
		     linemap_position_for_column (line_table, 1),
		     linemap_position_for_column (line_table, 8));
  location_t bar
    = make_location (linemap_position_for_column (line_table, 12),
		     linemap_position_for_column (line_table, 12),
		     linemap_position_for_column (line_table, 17));
  location_t field
    = make_location (linemap_position_for_column (line_table, 19),
		     linemap_position_for_column (line_table, 19),
		     linemap_position_for_column (line_table, 30));

  /* Example where all the labels fit on one line.  */
  {
    /* These three labels contain multibyte characters such that their byte
       lengths are respectively (12, 10, 18), but their display widths are only
       (6, 5, 9).  All three fit on the line when considering the display
       widths, but not when considering the byte widths, so verify that we do
       indeed put them all on one line.  */
    text_range_label label0
      ("\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80");
    text_range_label label1
      ("\xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80");
    text_range_label label2
      ("\xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80"
       "\xcf\x80");
    gcc_rich_location richloc (foo, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);

    {
      test_diagnostic_context dc;
      diagnostic_show_locus (&dc, &richloc, DK_ERROR);
      ASSERT_STREQ (" \xf0\x9f\x98\x82"
		       "_foo = \xcf\x80"
			       "_bar.\xf0\x9f\x98\x82"
				      "_field\xcf\x80"
					     ";\n"
		    " ^~~~~~   ~~~~~ ~~~~~~~~~\n"
		    " |        |     |\n"
		    " \xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80\xcf\x80"
			   "   \xf0\x9f\x98\x82\xf0\x9f\x98\x82\xcf\x80"
				   " \xf0\x9f\x98\x82\xcf\x80\xf0\x9f\x98\x82"
					 "\xf0\x9f\x98\x82\xcf\x80\xcf\x80\n",
		    pp_formatted_text (dc.printer));
    }

  }

  /* Example where the labels need extra lines.  */
  {
    text_range_label label0 ("label 0\xf0\x9f\x98\x82");
    text_range_label label1 ("label 1\xcf\x80");
    text_range_label label2 ("label 2\xcf\x80");
    gcc_rich_location richloc (foo, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);

    ASSERT_STREQ (" \xf0\x9f\x98\x82"
		     "_foo = \xcf\x80"
			     "_bar.\xf0\x9f\x98\x82"
				    "_field\xcf\x80"
					   ";\n"
		  " ^~~~~~   ~~~~~ ~~~~~~~~~\n"
		  " |        |     |\n"
		  " |        |     label 2\xcf\x80\n"
		  " |        label 1\xcf\x80\n"
		  " label 0\xf0\x9f\x98\x82\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of boundary conditions: label 0 and 1 have just enough clearance,
     but label 1 just touches label 2.  */
  {
    text_range_label label0 ("aaaaa\xf0\x9f\x98\x82\xcf\x80");
    text_range_label label1 ("bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82");
    text_range_label label2 ("c");
    gcc_rich_location richloc (foo, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);

    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" \xf0\x9f\x98\x82"
		     "_foo = \xcf\x80"
			     "_bar.\xf0\x9f\x98\x82"
				    "_field\xcf\x80"
					   ";\n"
		  " ^~~~~~   ~~~~~ ~~~~~~~~~\n"
		  " |        |     |\n"
		  " |        |     c\n"
		  " aaaaa\xf0\x9f\x98\x82\xcf\x80"
			   " bb\xf0\x9f\x98\x82\xf0\x9f\x98\x82\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of escaping the source lines.  */
  {
    text_range_label label0 ("label 0\xf0\x9f\x98\x82");
    text_range_label label1 ("label 1\xcf\x80");
    text_range_label label2 ("label 2\xcf\x80");
    gcc_rich_location richloc (foo, &label0);
    richloc.add_range (bar, SHOW_RANGE_WITHOUT_CARET, &label1);
    richloc.add_range (field, SHOW_RANGE_WITHOUT_CARET, &label2);
    richloc.set_escape_on_output (true);

    {
      test_diagnostic_context dc;
      dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
      diagnostic_show_locus (&dc, &richloc, DK_ERROR);
      ASSERT_STREQ (" <U+1F602>_foo = <U+03C0>_bar.<U+1F602>_field<U+03C0>;\n"
		    " ^~~~~~~~~~~~~   ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~\n"
		    " |               |            |\n"
		    " |               |            label 2\xcf\x80\n"
		    " |               label 1\xcf\x80\n"
		    " label 0\xf0\x9f\x98\x82\n",
		    pp_formatted_text (dc.printer));
    }
    {
      test_diagnostic_context dc;
      dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_BYTES;
      diagnostic_show_locus (&dc, &richloc, DK_ERROR);
      ASSERT_STREQ
	(" <f0><9f><98><82>_foo = <cf><80>_bar.<f0><9f><98><82>_field<cf><80>;\n"
	 " ^~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
	 " |                      |            |\n"
	 " |                      |            label 2\xcf\x80\n"
	 " |                      label 1\xcf\x80\n"
	 " label 0\xf0\x9f\x98\x82\n",
	 pp_formatted_text (dc.printer));
    }
  }
}

/* Make sure that colorization codes don't interrupt a multibyte
   sequence, which would corrupt it.  */
static void
test_one_liner_colorized_utf8 ()
{
  test_diagnostic_context dc;
  dc.colorize_source_p = true;
  diagnostic_color_init (&dc, DIAGNOSTICS_COLOR_YES);
  const location_t pi = linemap_position_for_column (line_table, 12);
  rich_location richloc (line_table, pi);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);

  /* In order to avoid having the test depend on exactly how the colorization
     was effected, just confirm there are two pi characters in the output.  */
  const char *result = pp_formatted_text (dc.printer);
  const char *null_term = result + strlen (result);
  const char *first_pi = strstr (result, "\xcf\x80");
  ASSERT_TRUE (first_pi && first_pi <= null_term - 2);
  ASSERT_STR_CONTAINS (first_pi + 2, "\xcf\x80");
}

/* Run the various one-liner tests.  */

static void
test_diagnostic_show_locus_one_liner_utf8 (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.  */
  const char *content
    /* Display columns.
       0000000000000000000000011111111111111111111111111111112222222222222
       1111111122222222345678900000000123456666666677777777890123444444445  */
    = "\xf0\x9f\x98\x82_foo = \xcf\x80_bar.\xf0\x9f\x98\x82_field\xcf\x80;\n";
    /* 0000000000000000000001111111111111111111222222222222222222222233333
       1111222233334444567890122223333456789999000011112222345678999900001
       Byte columns.  */
  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);

  linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);

  location_t line_end = linemap_position_for_column (line_table, 31);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end));
  ASSERT_EQ (1, LOCATION_LINE (line_end));
  ASSERT_EQ (31, LOCATION_COLUMN (line_end));

  char_span lspan = location_get_source_line (tmp.get_filename (), 1);
  ASSERT_EQ (25, cpp_display_width (lspan.get_buffer (), lspan.length (),
				    def_policy ()));
  ASSERT_EQ (25, location_compute_display_column (expand_location (line_end),
						  def_policy ()));

  test_one_liner_simple_caret_utf8 ();
  test_one_liner_caret_and_range_utf8 ();
  test_one_liner_multiple_carets_and_ranges_utf8 ();
  test_one_liner_fixit_insert_before_utf8 ();
  test_one_liner_fixit_insert_after_utf8 ();
  test_one_liner_fixit_remove_utf8 ();
  test_one_liner_fixit_replace_utf8 ();
  test_one_liner_fixit_replace_non_equal_range_utf8 ();
  test_one_liner_fixit_replace_equal_secondary_range_utf8 ();
  test_one_liner_fixit_validation_adhoc_locations_utf8 ();
  test_one_liner_many_fixits_1_utf8 ();
  test_one_liner_many_fixits_2_utf8 ();
  test_one_liner_labels_utf8 ();
  test_one_liner_colorized_utf8 ();
}

/* Verify that gcc_rich_location::add_location_if_nearby works.  */

static void
test_add_location_if_nearby (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
     ...000000000111111111122222222223333333333.
     ...123456789012345678901234567890123456789.  */
  const char *content
    = ("struct same_line { double x; double y; ;\n" /* line 1.  */
       "struct different_line\n"                    /* line 2.  */
       "{\n"                                        /* line 3.  */
       "  double x;\n"                              /* line 4.  */
       "  double y;\n"                              /* line 5.  */
       ";\n");                                      /* line 6.  */
  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);

  const line_map_ordinary *ord_map
    = linemap_check_ordinary (linemap_add (line_table, LC_ENTER, false,
					   tmp.get_filename (), 0));

  linemap_line_start (line_table, 1, 100);

  const location_t final_line_end
    = linemap_position_for_line_and_column (line_table, ord_map, 6, 7);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (final_line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* Test of add_location_if_nearby on the same line as the
     primary location.  */
  {
    const location_t missing_close_brace_1_39
      = linemap_position_for_line_and_column (line_table, ord_map, 1, 39);
    const location_t matching_open_brace_1_18
      = linemap_position_for_line_and_column (line_table, ord_map, 1, 18);
    gcc_rich_location richloc (missing_close_brace_1_39);
    bool added = richloc.add_location_if_nearby (matching_open_brace_1_18);
    ASSERT_TRUE (added);
    ASSERT_EQ (2, richloc.get_num_locations ());
    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" struct same_line { double x; double y; ;\n"
		  "                  ~                    ^\n",
		  pp_formatted_text (dc.printer));
  }

  /* Test of add_location_if_nearby on a different line to the
     primary location.  */
  {
    const location_t missing_close_brace_6_1
      = linemap_position_for_line_and_column (line_table, ord_map, 6, 1);
    const location_t matching_open_brace_3_1
      = linemap_position_for_line_and_column (line_table, ord_map, 3, 1);
    gcc_rich_location richloc (missing_close_brace_6_1);
    bool added = richloc.add_location_if_nearby (matching_open_brace_3_1);
    ASSERT_FALSE (added);
    ASSERT_EQ (1, richloc.get_num_locations ());
  }
}

/* Verify that we print fixits even if they only affect lines
   outside those covered by the ranges in the rich_location.  */

static void
test_diagnostic_show_locus_fixit_lines (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
     ...000000000111111111122222222223333333333.
     ...123456789012345678901234567890123456789.  */
  const char *content
    = ("struct point { double x; double y; };\n" /* line 1.  */
       "struct point origin = {x: 0.0,\n"        /* line 2.  */
       "                       y\n"              /* line 3.  */
       "\n"                                      /* line 4.  */
       "\n"                                      /* line 5.  */
       "                        : 0.0};\n");     /* line 6.  */
  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);

  const line_map_ordinary *ord_map
    = linemap_check_ordinary (linemap_add (line_table, LC_ENTER, false,
					   tmp.get_filename (), 0));

  linemap_line_start (line_table, 1, 100);

  const location_t final_line_end
    = linemap_position_for_line_and_column (line_table, ord_map, 6, 36);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (final_line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* A pair of tests for modernizing the initializers to C99-style.  */

  /* The one-liner case (line 2).  */
  {
    test_diagnostic_context dc;
    const location_t x
      = linemap_position_for_line_and_column (line_table, ord_map, 2, 24);
    const location_t colon
      = linemap_position_for_line_and_column (line_table, ord_map, 2, 25);
    rich_location richloc (line_table, colon);
    richloc.add_fixit_insert_before (x, ".");
    richloc.add_fixit_replace (colon, "=");
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" struct point origin = {x: 0.0,\n"
		  "                         ^\n"
		  "                        .=\n",
		  pp_formatted_text (dc.printer));
  }

  /* The multiline case.  The caret for the rich_location is on line 6;
     verify that insertion fixit on line 3 is still printed (and that
     span starts are printed due to the gap between the span at line 3
     and that at line 6).  */
  {
    test_diagnostic_context dc;
    const location_t y
      = linemap_position_for_line_and_column (line_table, ord_map, 3, 24);
    const location_t colon
      = linemap_position_for_line_and_column (line_table, ord_map, 6, 25);
    rich_location richloc (line_table, colon);
    richloc.add_fixit_insert_before (y, ".");
    richloc.add_fixit_replace (colon, "=");
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("FILENAME:3:24:\n"
		  "                        y\n"
		  "                        .\n"
		  "FILENAME:6:25:\n"
		  "                         : 0.0};\n"
		  "                         ^\n"
		  "                         =\n",
		  pp_formatted_text (dc.printer));
  }

  /* As above, but verify the behavior of multiple line spans
     with line-numbering enabled.  */
  {
    const location_t y
      = linemap_position_for_line_and_column (line_table, ord_map, 3, 24);
    const location_t colon
      = linemap_position_for_line_and_column (line_table, ord_map, 6, 25);
    rich_location richloc (line_table, colon);
    richloc.add_fixit_insert_before (y, ".");
    richloc.add_fixit_replace (colon, "=");
    test_diagnostic_context dc;
    dc.show_line_numbers_p = true;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("    3 |                        y\n"
		  "      |                        .\n"
		  "......\n"
		  "    6 |                         : 0.0};\n"
		  "      |                         ^\n"
		  "      |                         =\n",
		  pp_formatted_text (dc.printer));
  }
}


/* Verify that fix-it hints are appropriately consolidated.

   If any fix-it hints in a rich_location involve locations beyond
   LINE_MAP_MAX_LOCATION_WITH_COLS, then we can't reliably apply
   the fix-it as a whole, so there should be none.

   Otherwise, verify that consecutive "replace" and "remove" fix-its
   are merged, and that other fix-its remain separate.   */

static void
test_fixit_consolidation (const line_table_case &case_)
{
  line_table_test ltt (case_);

  linemap_add (line_table, LC_ENTER, false, "test.c", 1);

  const location_t c10 = linemap_position_for_column (line_table, 10);
  const location_t c15 = linemap_position_for_column (line_table, 15);
  const location_t c16 = linemap_position_for_column (line_table, 16);
  const location_t c17 = linemap_position_for_column (line_table, 17);
  const location_t c20 = linemap_position_for_column (line_table, 20);
  const location_t c21 = linemap_position_for_column (line_table, 21);
  const location_t caret = c10;

  /* Insert + insert. */
  {
    rich_location richloc (line_table, caret);
    richloc.add_fixit_insert_before (c10, "foo");
    richloc.add_fixit_insert_before (c15, "bar");

    if (c15 > LINE_MAP_MAX_LOCATION_WITH_COLS)
      /* Bogus column info for 2nd fixit, so no fixits.  */
      ASSERT_EQ (0, richloc.get_num_fixit_hints ());
    else
      /* They should not have been merged.  */
      ASSERT_EQ (2, richloc.get_num_fixit_hints ());
  }

  /* Insert + replace. */
  {
    rich_location richloc (line_table, caret);
    richloc.add_fixit_insert_before (c10, "foo");
    richloc.add_fixit_replace (source_range::from_locations (c15, c17),
			       "bar");

    if (c17 > LINE_MAP_MAX_LOCATION_WITH_COLS)
      /* Bogus column info for 2nd fixit, so no fixits.  */
      ASSERT_EQ (0, richloc.get_num_fixit_hints ());
    else
      /* They should not have been merged.  */
      ASSERT_EQ (2, richloc.get_num_fixit_hints ());
  }

  /* Replace + non-consecutive insert. */
  {
    rich_location richloc (line_table, caret);
    richloc.add_fixit_replace (source_range::from_locations (c10, c15),
			       "bar");
    richloc.add_fixit_insert_before (c17, "foo");

    if (c17 > LINE_MAP_MAX_LOCATION_WITH_COLS)
      /* Bogus column info for 2nd fixit, so no fixits.  */
      ASSERT_EQ (0, richloc.get_num_fixit_hints ());
    else
      /* They should not have been merged.  */
      ASSERT_EQ (2, richloc.get_num_fixit_hints ());
  }

  /* Replace + non-consecutive replace. */
  {
    rich_location richloc (line_table, caret);
    richloc.add_fixit_replace (source_range::from_locations (c10, c15),
			       "foo");
    richloc.add_fixit_replace (source_range::from_locations (c17, c20),
			       "bar");

    if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
      /* Bogus column info for 2nd fixit, so no fixits.  */
      ASSERT_EQ (0, richloc.get_num_fixit_hints ());
    else
      /* They should not have been merged.  */
      ASSERT_EQ (2, richloc.get_num_fixit_hints ());
  }

  /* Replace + consecutive replace. */
  {
    rich_location richloc (line_table, caret);
    richloc.add_fixit_replace (source_range::from_locations (c10, c15),
			       "foo");
    richloc.add_fixit_replace (source_range::from_locations (c16, c20),
			       "bar");

    if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
      /* Bogus column info for 2nd fixit, so no fixits.  */
      ASSERT_EQ (0, richloc.get_num_fixit_hints ());
    else
      {
	/* They should have been merged into a single "replace".  */
	ASSERT_EQ (1, richloc.get_num_fixit_hints ());
	const fixit_hint *hint = richloc.get_fixit_hint (0);
	ASSERT_STREQ ("foobar", hint->get_string ());
	ASSERT_EQ (c10, hint->get_start_loc ());
	ASSERT_EQ (c21, hint->get_next_loc ());
      }
  }

  /* Replace + consecutive removal. */
  {
    rich_location richloc (line_table, caret);
    richloc.add_fixit_replace (source_range::from_locations (c10, c15),
			       "foo");
    richloc.add_fixit_remove (source_range::from_locations (c16, c20));

    if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
      /* Bogus column info for 2nd fixit, so no fixits.  */
      ASSERT_EQ (0, richloc.get_num_fixit_hints ());
    else
      {
	/* They should have been merged into a single replace, with the
	   range extended to cover that of the removal.  */
	ASSERT_EQ (1, richloc.get_num_fixit_hints ());
	const fixit_hint *hint = richloc.get_fixit_hint (0);
	ASSERT_STREQ ("foo", hint->get_string ());
	ASSERT_EQ (c10, hint->get_start_loc ());
	ASSERT_EQ (c21, hint->get_next_loc ());
      }
  }

  /* Consecutive removals. */
  {
    rich_location richloc (line_table, caret);
    richloc.add_fixit_remove (source_range::from_locations (c10, c15));
    richloc.add_fixit_remove (source_range::from_locations (c16, c20));

    if (c20 > LINE_MAP_MAX_LOCATION_WITH_COLS)
      /* Bogus column info for 2nd fixit, so no fixits.  */
      ASSERT_EQ (0, richloc.get_num_fixit_hints ());
    else
      {
	/* They should have been merged into a single "replace-with-empty".  */
	ASSERT_EQ (1, richloc.get_num_fixit_hints ());
	const fixit_hint *hint = richloc.get_fixit_hint (0);
	ASSERT_STREQ ("", hint->get_string ());
	ASSERT_EQ (c10, hint->get_start_loc ());
	ASSERT_EQ (c21, hint->get_next_loc ());
      }
  }
}

/* Verify that the line_corrections machinery correctly prints
   overlapping fixit-hints.  */

static void
test_overlapped_fixit_printing (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
     ...000000000111111111122222222223333333333.
     ...123456789012345678901234567890123456789.  */
  const char *content
    = ("  foo *f = (foo *)ptr->field;\n");
  temp_source_file tmp (SELFTEST_LOCATION, ".C", content);
  line_table_test ltt (case_);

  const line_map_ordinary *ord_map
    = linemap_check_ordinary (linemap_add (line_table, LC_ENTER, false,
					   tmp.get_filename (), 0));

  linemap_line_start (line_table, 1, 100);

  const location_t final_line_end
    = linemap_position_for_line_and_column (line_table, ord_map, 6, 36);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (final_line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* A test for converting a C-style cast to a C++-style cast.  */
  const location_t open_paren
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 12);
  const location_t close_paren
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 18);
  const location_t expr_start
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 19);
  const location_t expr_finish
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 28);
  const location_t expr = make_location (expr_start, expr_start, expr_finish);

  /* Various examples of fix-it hints that aren't themselves consolidated,
     but for which the *printing* may need consolidation.  */

  /* Example where 3 fix-it hints are printed as one.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_replace (open_paren, "const_cast<");
    richloc.add_fixit_replace (close_paren, "> (");
    richloc.add_fixit_insert_after (")");

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   foo *f = (foo *)ptr->field;\n"
		  "                   ^~~~~~~~~~\n"
		  "            -----------------\n"
		  "            const_cast<foo *> (ptr->field)\n",
		  pp_formatted_text (dc.printer));

    /* Unit-test the line_corrections machinery.  */
    char_display_policy policy (make_policy (dc, richloc));
    ASSERT_EQ (3, richloc.get_num_fixit_hints ());
    const fixit_hint *hint_0 = richloc.get_fixit_hint (0);
    ASSERT_EQ (column_range (12, 12),
	       get_affected_range (policy, hint_0, CU_BYTES));
    ASSERT_EQ (column_range (12, 12),
	       get_affected_range (policy, hint_0, CU_DISPLAY_COLS));
    ASSERT_EQ (column_range (12, 22), get_printed_columns (policy, hint_0));
    const fixit_hint *hint_1 = richloc.get_fixit_hint (1);
    ASSERT_EQ (column_range (18, 18),
	       get_affected_range (policy, hint_1, CU_BYTES));
    ASSERT_EQ (column_range (18, 18),
	       get_affected_range (policy, hint_1, CU_DISPLAY_COLS));
    ASSERT_EQ (column_range (18, 20), get_printed_columns (policy, hint_1));
    const fixit_hint *hint_2 = richloc.get_fixit_hint (2);
    ASSERT_EQ (column_range (29, 28),
	       get_affected_range (policy, hint_2, CU_BYTES));
    ASSERT_EQ (column_range (29, 28),
	       get_affected_range (policy, hint_2, CU_DISPLAY_COLS));
    ASSERT_EQ (column_range (29, 29), get_printed_columns (policy, hint_2));

    /* Add each hint in turn to a line_corrections instance,
       and verify that they are consolidated into one correction instance
       as expected.  */
    line_corrections lc (policy, tmp.get_filename (), 1);

    /* The first replace hint by itself.  */
    lc.add_hint (hint_0);
    ASSERT_EQ (1, lc.m_corrections.length ());
    ASSERT_EQ (column_range (12, 12), lc.m_corrections[0]->m_affected_bytes);
    ASSERT_EQ (column_range (12, 12), lc.m_corrections[0]->m_affected_columns);
    ASSERT_EQ (column_range (12, 22), lc.m_corrections[0]->m_printed_columns);
    ASSERT_STREQ ("const_cast<", lc.m_corrections[0]->m_text);

    /* After the second replacement hint, they are printed together
       as a replacement (along with the text between them).  */
    lc.add_hint (hint_1);
    ASSERT_EQ (1, lc.m_corrections.length ());
    ASSERT_STREQ ("const_cast<foo *> (", lc.m_corrections[0]->m_text);
    ASSERT_EQ (column_range (12, 18), lc.m_corrections[0]->m_affected_bytes);
    ASSERT_EQ (column_range (12, 18), lc.m_corrections[0]->m_affected_columns);
    ASSERT_EQ (column_range (12, 30), lc.m_corrections[0]->m_printed_columns);

    /* After the final insertion hint, they are all printed together
       as a replacement (along with the text between them).  */
    lc.add_hint (hint_2);
    ASSERT_STREQ ("const_cast<foo *> (ptr->field)",
		  lc.m_corrections[0]->m_text);
    ASSERT_EQ (1, lc.m_corrections.length ());
    ASSERT_EQ (column_range (12, 28), lc.m_corrections[0]->m_affected_bytes);
    ASSERT_EQ (column_range (12, 28), lc.m_corrections[0]->m_affected_columns);
    ASSERT_EQ (column_range (12, 41), lc.m_corrections[0]->m_printed_columns);
  }

  /* Example where two are consolidated during printing.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_replace (open_paren, "CAST (");
    richloc.add_fixit_replace (close_paren, ") (");
    richloc.add_fixit_insert_after (")");

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   foo *f = (foo *)ptr->field;\n"
		  "                   ^~~~~~~~~~\n"
		  "            -\n"
		  "            CAST (-\n"
		  "                  ) (        )\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example where none are consolidated during printing.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_replace (open_paren, "CST (");
    richloc.add_fixit_replace (close_paren, ") (");
    richloc.add_fixit_insert_after (")");

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   foo *f = (foo *)ptr->field;\n"
		  "                   ^~~~~~~~~~\n"
		  "            -\n"
		  "            CST ( -\n"
		  "                  ) (        )\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of deletion fix-it hints.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_insert_before (open_paren, "(bar *)");
    source_range victim = {open_paren, close_paren};
    richloc.add_fixit_remove (victim);

    /* This case is actually handled by fixit-consolidation,
       rather than by line_corrections.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   foo *f = (foo *)ptr->field;\n"
		  "                   ^~~~~~~~~~\n"
		  "            -------\n"
		  "            (bar *)\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of deletion fix-it hints that would overlap.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_insert_before (open_paren, "(longer *)");
    source_range victim = {expr_start, expr_finish};
    richloc.add_fixit_remove (victim);

    /* These fixits are not consolidated.  */
    ASSERT_EQ (2, richloc.get_num_fixit_hints ());

    /* But the corrections are.  */
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   foo *f = (foo *)ptr->field;\n"
		  "                   ^~~~~~~~~~\n"
		  "            -----------------\n"
		  "            (longer *)(foo *)\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of insertion fix-it hints that would overlap.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_insert_before (open_paren, "LONGER THAN THE CAST");
    richloc.add_fixit_insert_after (close_paren, "TEST");

    /* The first insertion is long enough that if printed naively,
       it would overlap with the second.
       Verify that they are printed as a single replacement.  */
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   foo *f = (foo *)ptr->field;\n"
		  "                   ^~~~~~~~~~\n"
		  "            -------\n"
		  "            LONGER THAN THE CAST(foo *)TEST\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Multibyte-aware version of preceding tests.  See comments above
   test_one_liner_simple_caret_utf8() too, we use the same two multibyte
   characters here.  */

static void
test_overlapped_fixit_printing_utf8 (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.  */

  const char *content
    /* Display columns.
       00000000000000000000000111111111111111111111111222222222222222223
       12344444444555555556789012344444444555555556789012345678999999990  */
    = "  f\xf0\x9f\x98\x82 *f = (f\xf0\x9f\x98\x82 *)ptr->field\xcf\x80;\n";
    /* 00000000000000000000011111111111111111111112222222222333333333333
       12344445555666677778901234566667777888899990123456789012333344445
       Byte columns.  */

  temp_source_file tmp (SELFTEST_LOCATION, ".C", content);
  line_table_test ltt (case_);

  const line_map_ordinary *ord_map
    = linemap_check_ordinary (linemap_add (line_table, LC_ENTER, false,
					   tmp.get_filename (), 0));

  linemap_line_start (line_table, 1, 100);

  const location_t final_line_end
    = linemap_position_for_line_and_column (line_table, ord_map, 6, 50);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (final_line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* A test for converting a C-style cast to a C++-style cast.  */
  const location_t open_paren
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 14);
  const location_t close_paren
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 22);
  const location_t expr_start
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 23);
  const location_t expr_finish
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 34);
  const location_t expr = make_location (expr_start, expr_start, expr_finish);

  /* Various examples of fix-it hints that aren't themselves consolidated,
     but for which the *printing* may need consolidation.  */

  /* Example where 3 fix-it hints are printed as one.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_replace (open_paren, "const_cast<");
    richloc.add_fixit_replace (close_paren, "> (");
    richloc.add_fixit_insert_after (")");

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   f\xf0\x9f\x98\x82"
			" *f = (f\xf0\x9f\x98\x82"
				  " *)ptr->field\xcf\x80"
						";\n"
		  "                   ^~~~~~~~~~~\n"
		  "            ------------------\n"
		  "            const_cast<f\xf0\x9f\x98\x82"
					    " *> (ptr->field\xcf\x80"
							    ")\n",
		  pp_formatted_text (dc.printer));

    /* Unit-test the line_corrections machinery.  */
    char_display_policy policy (make_policy (dc, richloc));
    ASSERT_EQ (3, richloc.get_num_fixit_hints ());
    const fixit_hint *hint_0 = richloc.get_fixit_hint (0);
    ASSERT_EQ (column_range (14, 14),
	       get_affected_range (policy, hint_0, CU_BYTES));
    ASSERT_EQ (column_range (12, 12),
	       get_affected_range (policy, hint_0, CU_DISPLAY_COLS));
    ASSERT_EQ (column_range (12, 22), get_printed_columns (policy, hint_0));
    const fixit_hint *hint_1 = richloc.get_fixit_hint (1);
    ASSERT_EQ (column_range (22, 22),
	       get_affected_range (policy, hint_1, CU_BYTES));
    ASSERT_EQ (column_range (18, 18),
	       get_affected_range (policy, hint_1, CU_DISPLAY_COLS));
    ASSERT_EQ (column_range (18, 20), get_printed_columns (policy, hint_1));
    const fixit_hint *hint_2 = richloc.get_fixit_hint (2);
    ASSERT_EQ (column_range (35, 34),
	       get_affected_range (policy, hint_2, CU_BYTES));
    ASSERT_EQ (column_range (30, 29),
	       get_affected_range (policy, hint_2, CU_DISPLAY_COLS));
    ASSERT_EQ (column_range (30, 30), get_printed_columns (policy, hint_2));

    /* Add each hint in turn to a line_corrections instance,
       and verify that they are consolidated into one correction instance
       as expected.  */
    line_corrections lc (policy, tmp.get_filename (), 1);

    /* The first replace hint by itself.  */
    lc.add_hint (hint_0);
    ASSERT_EQ (1, lc.m_corrections.length ());
    ASSERT_EQ (column_range (14, 14), lc.m_corrections[0]->m_affected_bytes);
    ASSERT_EQ (column_range (12, 12), lc.m_corrections[0]->m_affected_columns);
    ASSERT_EQ (column_range (12, 22), lc.m_corrections[0]->m_printed_columns);
    ASSERT_STREQ ("const_cast<", lc.m_corrections[0]->m_text);

    /* After the second replacement hint, they are printed together
       as a replacement (along with the text between them).  */
    lc.add_hint (hint_1);
    ASSERT_EQ (1, lc.m_corrections.length ());
    ASSERT_STREQ ("const_cast<f\xf0\x9f\x98\x82 *> (",
		  lc.m_corrections[0]->m_text);
    ASSERT_EQ (column_range (14, 22), lc.m_corrections[0]->m_affected_bytes);
    ASSERT_EQ (column_range (12, 18), lc.m_corrections[0]->m_affected_columns);
    ASSERT_EQ (column_range (12, 30), lc.m_corrections[0]->m_printed_columns);

    /* After the final insertion hint, they are all printed together
       as a replacement (along with the text between them).  */
    lc.add_hint (hint_2);
    ASSERT_STREQ ("const_cast<f\xf0\x9f\x98\x82 *> (ptr->field\xcf\x80)",
		  lc.m_corrections[0]->m_text);
    ASSERT_EQ (1, lc.m_corrections.length ());
    ASSERT_EQ (column_range (14, 34), lc.m_corrections[0]->m_affected_bytes);
    ASSERT_EQ (column_range (12, 29), lc.m_corrections[0]->m_affected_columns);
    ASSERT_EQ (column_range (12, 42), lc.m_corrections[0]->m_printed_columns);
  }

  /* Example where two are consolidated during printing.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_replace (open_paren, "CAST (");
    richloc.add_fixit_replace (close_paren, ") (");
    richloc.add_fixit_insert_after (")");

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   f\xf0\x9f\x98\x82"
			" *f = (f\xf0\x9f\x98\x82"
				  " *)ptr->field\xcf\x80"
						";\n"
		  "                   ^~~~~~~~~~~\n"
		  "            -\n"
		  "            CAST (-\n"
		  "                  ) (         )\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example where none are consolidated during printing.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_replace (open_paren, "CST (");
    richloc.add_fixit_replace (close_paren, ") (");
    richloc.add_fixit_insert_after (")");

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   f\xf0\x9f\x98\x82"
			" *f = (f\xf0\x9f\x98\x82"
				  " *)ptr->field\xcf\x80"
						";\n"
		  "                   ^~~~~~~~~~~\n"
		  "            -\n"
		  "            CST ( -\n"
		  "                  ) (         )\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of deletion fix-it hints.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_insert_before (open_paren, "(bar\xf0\x9f\x98\x82 *)");
    source_range victim = {open_paren, close_paren};
    richloc.add_fixit_remove (victim);

    /* This case is actually handled by fixit-consolidation,
       rather than by line_corrections.  */
    ASSERT_EQ (1, richloc.get_num_fixit_hints ());

    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   f\xf0\x9f\x98\x82"
			" *f = (f\xf0\x9f\x98\x82"
				  " *)ptr->field\xcf\x80"
						";\n"
		  "                   ^~~~~~~~~~~\n"
		  "            -------\n"
		  "            (bar\xf0\x9f\x98\x82"
				    " *)\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of deletion fix-it hints that would overlap.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_insert_before (open_paren, "(long\xf0\x9f\x98\x82 *)");
    source_range victim = {expr_start, expr_finish};
    richloc.add_fixit_remove (victim);

    /* These fixits are not consolidated.  */
    ASSERT_EQ (2, richloc.get_num_fixit_hints ());

    /* But the corrections are.  */
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   f\xf0\x9f\x98\x82"
			" *f = (f\xf0\x9f\x98\x82"
				  " *)ptr->field\xcf\x80"
						";\n"
		  "                   ^~~~~~~~~~~\n"
		  "            ------------------\n"
		  "            (long\xf0\x9f\x98\x82"
				     " *)(f\xf0\x9f\x98\x82"
					    " *)\n",
		  pp_formatted_text (dc.printer));
  }

  /* Example of insertion fix-it hints that would overlap.  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, expr);
    richloc.add_fixit_insert_before
      (open_paren, "L\xf0\x9f\x98\x82NGER THAN THE CAST");
    richloc.add_fixit_insert_after (close_paren, "TEST");

    /* The first insertion is long enough that if printed naively,
       it would overlap with the second.
       Verify that they are printed as a single replacement.  */
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("   f\xf0\x9f\x98\x82"
			" *f = (f\xf0\x9f\x98\x82"
				  " *)ptr->field\xcf\x80"
						";\n"
		  "                   ^~~~~~~~~~~\n"
		  "            -------\n"
		  "            L\xf0\x9f\x98\x82"
				 "NGER THAN THE CAST(f\xf0\x9f\x98\x82"
						       " *)TEST\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Verify that the line_corrections machinery correctly prints
   overlapping fixit-hints that have been added in the wrong
   order.
   Adapted from PR c/81405 seen on gcc.dg/init-excess-1.c*/

static void
test_overlapped_fixit_printing_2 (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
     ...000000000111111111122222222223333333333.
     ...123456789012345678901234567890123456789.  */
  const char *content
    = ("int a5[][0][0] = { 1, 2 };\n");
  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);

  const line_map_ordinary *ord_map
    = linemap_check_ordinary (linemap_add (line_table, LC_ENTER, false,
					   tmp.get_filename (), 0));

  linemap_line_start (line_table, 1, 100);

  const location_t final_line_end
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 100);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  if (final_line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  const location_t col_1
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 1);
  const location_t col_20
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 20);
  const location_t col_21
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 21);
  const location_t col_23
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 23);
  const location_t col_25
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 25);

  /* Two insertions, in the wrong order.  */
  {
    test_diagnostic_context dc;

    rich_location richloc (line_table, col_20);
    richloc.add_fixit_insert_before (col_23, "{");
    richloc.add_fixit_insert_before (col_21, "}");

    /* These fixits should be accepted; they can't be consolidated.  */
    char_display_policy policy (make_policy (dc, richloc));
    ASSERT_EQ (2, richloc.get_num_fixit_hints ());
    const fixit_hint *hint_0 = richloc.get_fixit_hint (0);
    ASSERT_EQ (column_range (23, 22),
	       get_affected_range (policy, hint_0, CU_BYTES));
    ASSERT_EQ (column_range (23, 23), get_printed_columns (policy, hint_0));
    const fixit_hint *hint_1 = richloc.get_fixit_hint (1);
    ASSERT_EQ (column_range (21, 20),
	       get_affected_range (policy, hint_1, CU_BYTES));
    ASSERT_EQ (column_range (21, 21), get_printed_columns (policy, hint_1));

    /* Verify that they're printed correctly.  */
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" int a5[][0][0] = { 1, 2 };\n"
		  "                    ^\n"
		  "                     } {\n",
		  pp_formatted_text (dc.printer));
  }

  /* Various overlapping insertions, some occurring "out of order"
     (reproducing the fix-it hints from PR c/81405).  */
  {
    test_diagnostic_context dc;
    rich_location richloc (line_table, col_20);

    richloc.add_fixit_insert_before (col_20, "{{");
    richloc.add_fixit_insert_before (col_21, "}}");
    richloc.add_fixit_insert_before (col_23, "{");
    richloc.add_fixit_insert_before (col_21, "}");
    richloc.add_fixit_insert_before (col_23, "{{");
    richloc.add_fixit_insert_before (col_25, "}");
    richloc.add_fixit_insert_before (col_21, "}");
    richloc.add_fixit_insert_before (col_1, "{");
    richloc.add_fixit_insert_before (col_25, "}");
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" int a5[][0][0] = { 1, 2 };\n"
		  "                    ^\n"
		  " {                  -----\n"
		  "                    {{1}}}}, {{{2 }}\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Insertion fix-it hint: adding a "break;" on a line by itself.  */

static void
test_fixit_insert_containing_newline (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
     .........................0000000001111111.
     .........................1234567890123456.  */
  const char *old_content = ("    case 'a':\n" /* line 1. */
			     "      x = a;\n"  /* line 2. */
			     "    case 'b':\n" /* line 3. */
			     "      x = b;\n");/* line 4. */

  temp_source_file tmp (SELFTEST_LOCATION, ".c", old_content);
  line_table_test ltt (case_);
  linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 3);

  location_t case_start = linemap_position_for_column (line_table, 5);
  location_t case_finish = linemap_position_for_column (line_table, 13);
  location_t case_loc = make_location (case_start, case_start, case_finish);
  location_t line_start = linemap_position_for_column (line_table, 1);

  if (case_finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* Add a "break;" on a line by itself before line 3 i.e. before
     column 1 of line 3. */
  {
    rich_location richloc (line_table, case_loc);
    richloc.add_fixit_insert_before (line_start, "      break;\n");

    /* Without line numbers.  */
    {
      test_diagnostic_context dc;
      diagnostic_show_locus (&dc, &richloc, DK_ERROR);
      ASSERT_STREQ ("       x = a;\n"
		    "+      break;\n"
		    "     case 'b':\n"
		    "     ^~~~~~~~~\n",
		    pp_formatted_text (dc.printer));
    }

    /* With line numbers.  */
    {
      test_diagnostic_context dc;
      dc.show_line_numbers_p = true;
      diagnostic_show_locus (&dc, &richloc, DK_ERROR);
      ASSERT_STREQ ("    2 |       x = a;\n"
		    "  +++ |+      break;\n"
		    "    3 |     case 'b':\n"
		    "      |     ^~~~~~~~~\n",
		    pp_formatted_text (dc.printer));
    }
  }

  /* Verify that attempts to add text with a newline fail when the
     insertion point is *not* at the start of a line.  */
  {
    rich_location richloc (line_table, case_loc);
    richloc.add_fixit_insert_before (case_start, "break;\n");
    ASSERT_TRUE (richloc.seen_impossible_fixit_p ());
    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("     case 'b':\n"
		  "     ^~~~~~~~~\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Insertion fix-it hint: adding a "#include <stdio.h>\n" to the top
   of the file, where the fix-it is printed in a different line-span
   to the primary range of the diagnostic.  */

static void
test_fixit_insert_containing_newline_2 (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
     .........................0000000001111111.
     .........................1234567890123456.  */
  const char *old_content = ("test (int ch)\n"  /* line 1. */
			     "{\n"              /* line 2. */
			     " putchar (ch);\n" /* line 3. */
			     "}\n");            /* line 4. */

  temp_source_file tmp (SELFTEST_LOCATION, ".c", old_content);
  line_table_test ltt (case_);

  const line_map_ordinary *ord_map = linemap_check_ordinary
    (linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 0));
  linemap_line_start (line_table, 1, 100);

  /* The primary range is the "putchar" token.  */
  location_t putchar_start
    = linemap_position_for_line_and_column (line_table, ord_map, 3, 2);
  location_t putchar_finish
    = linemap_position_for_line_and_column (line_table, ord_map, 3, 8);
  location_t putchar_loc
    = make_location (putchar_start, putchar_start, putchar_finish);
  rich_location richloc (line_table, putchar_loc);

  /* Add a "#include <stdio.h>" on a line by itself at the top of the file.  */
  location_t file_start
     = linemap_position_for_line_and_column (line_table, ord_map,  1, 1);
  richloc.add_fixit_insert_before (file_start, "#include <stdio.h>\n");

  if (putchar_finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  {
    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("FILENAME:1:1:\n"
		  "+#include <stdio.h>\n"
		  " test (int ch)\n"
		  "FILENAME:3:2:\n"
		  "  putchar (ch);\n"
		  "  ^~~~~~~\n",
		  pp_formatted_text (dc.printer));
  }

  /* With line-numbering, the line spans are close enough to be
     consolidated, since it makes little sense to skip line 2.  */
  {
    test_diagnostic_context dc;
    dc.show_line_numbers_p = true;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("  +++ |+#include <stdio.h>\n"
		  "    1 | test (int ch)\n"
		  "    2 | {\n"
		  "    3 |  putchar (ch);\n"
		  "      |  ^~~~~~~\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Replacement fix-it hint containing a newline.
   This will fail, as newlines are only supported when inserting at the
   beginning of a line.  */

static void
test_fixit_replace_containing_newline (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
    .........................0000000001111.
    .........................1234567890123.  */
  const char *old_content = "foo = bar ();\n";

  temp_source_file tmp (SELFTEST_LOCATION, ".c", old_content);
  line_table_test ltt (case_);
  linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);

  /* Replace the " = " with "\n  = ", as if we were reformatting an
     overly long line.  */
  location_t start = linemap_position_for_column (line_table, 4);
  location_t finish = linemap_position_for_column (line_table, 6);
  location_t loc = linemap_position_for_column (line_table, 13);
  rich_location richloc (line_table, loc);
  source_range range = source_range::from_locations (start, finish);
  richloc.add_fixit_replace (range, "\n =");

  /* Arbitrary newlines are not yet supported within fix-it hints, so
     the fix-it should not be displayed.  */
  ASSERT_TRUE (richloc.seen_impossible_fixit_p ());

  if (finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  test_diagnostic_context dc;
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar ();\n"
		"             ^\n",
		pp_formatted_text (dc.printer));
}

/* Fix-it hint, attempting to delete a newline.
   This will fail, as we currently only support fix-it hints that
   affect one line at a time.  */

static void
test_fixit_deletion_affecting_newline (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.
    ..........................0000000001111.
    ..........................1234567890123.  */
  const char *old_content = ("foo = bar (\n"
			     "      );\n");

  temp_source_file tmp (SELFTEST_LOCATION, ".c", old_content);
  line_table_test ltt (case_);
  const line_map_ordinary *ord_map = linemap_check_ordinary
    (linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 0));
  linemap_line_start (line_table, 1, 100);

  /* Attempt to delete the " (\n...)".  */
  location_t start
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 10);
  location_t caret
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 11);
  location_t finish
    = linemap_position_for_line_and_column (line_table, ord_map, 2, 7);
  location_t loc = make_location (caret, start, finish);
  rich_location richloc (line_table, loc);
  richloc. add_fixit_remove ();

  /* Fix-it hints that affect more than one line are not yet supported, so
     the fix-it should not be displayed.  */
  ASSERT_TRUE (richloc.seen_impossible_fixit_p ());

  if (finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  test_diagnostic_context dc;
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" foo = bar (\n"
		"          ~^\n"
		"       );\n"
		"       ~    \n",
		pp_formatted_text (dc.printer));
}

static void
test_tab_expansion (const line_table_case &case_)
{
  /* Create a tempfile and write some text to it.  This example uses a tabstop
     of 8, as the column numbers attempt to indicate:

    .....................000.01111111111.22222333333  display
    .....................123.90123456789.56789012345  columns  */
  const char *content = "  \t   This: `\t' is a tab.\n";
  /* ....................000 00000011111 11111222222  byte
     ....................123 45678901234 56789012345  columns  */

  const int tabstop = 8;
  cpp_char_column_policy policy (tabstop, cpp_wcwidth);
  const int first_non_ws_byte_col = 7;
  const int right_quote_byte_col = 15;
  const int last_byte_col = 25;
  ASSERT_EQ (35, cpp_display_width (content, last_byte_col, policy));

  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  line_table_test ltt (case_);
  linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);

  /* Don't attempt to run the tests if column data might be unavailable.  */
  location_t line_end = linemap_position_for_column (line_table, last_byte_col);
  if (line_end > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* Check that the leading whitespace with mixed tabs and spaces is expanded
     into 11 spaces.  Recall that print_line() also puts one space before
     everything too.  */
  {
    test_diagnostic_context dc;
    dc.tabstop = tabstop;
    rich_location richloc (line_table,
			   linemap_position_for_column (line_table,
							first_non_ws_byte_col));
    layout test_layout (&dc, &richloc, DK_ERROR);
    test_layout.print_line (1);
    ASSERT_STREQ ("            This: `      ' is a tab.\n"
		  "            ^\n",
		  pp_formatted_text (dc.printer));
  }

  /* Confirm the display width was tracked correctly across the internal tab
     as well.  */
  {
    test_diagnostic_context dc;
    dc.tabstop = tabstop;
    rich_location richloc (line_table,
			   linemap_position_for_column (line_table,
							right_quote_byte_col));
    layout test_layout (&dc, &richloc, DK_ERROR);
    test_layout.print_line (1);
    ASSERT_STREQ ("            This: `      ' is a tab.\n"
		  "                         ^\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Verify that the escaping machinery can cope with a variety of different
   invalid bytes.  */

static void
test_escaping_bytes_1 (const line_table_case &case_)
{
  const char content[] = "before\0\1\2\3\v\x80\xff""after\n";
  const size_t sz = sizeof (content);
  temp_source_file tmp (SELFTEST_LOCATION, ".c", content, sz);
  line_table_test ltt (case_);
  const line_map_ordinary *ord_map = linemap_check_ordinary
    (linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 0));
  linemap_line_start (line_table, 1, 100);

  location_t finish
    = linemap_position_for_line_and_column (line_table, ord_map, 1,
					    strlen (content));

  if (finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* Locations of the NUL and \v bytes.  */
  location_t nul_loc
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 7);
  location_t v_loc
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 11);
  gcc_rich_location richloc (nul_loc);
  richloc.add_range (v_loc);

  {
    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" before \1\2\3\v\x80\xff""after\n"
		  "       ^   ~\n",
		  pp_formatted_text (dc.printer));
  }
  richloc.set_escape_on_output (true);
  {
    test_diagnostic_context dc;
    dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ
      (" before<U+0000><U+0001><U+0002><U+0003><U+000B><80><ff>after\n"
       "       ^~~~~~~~                        ~~~~~~~~\n",
       pp_formatted_text (dc.printer));
  }
  {
    test_diagnostic_context dc;
    dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_BYTES;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" before<00><01><02><03><0b><80><ff>after\n"
		  "       ^~~~            ~~~~\n",
		  pp_formatted_text (dc.printer));
  }
}

/* As above, but verify that we handle the initial byte of a line
   correctly.  */

static void
test_escaping_bytes_2 (const line_table_case &case_)
{
  const char content[]  = "\0after\n";
  const size_t sz = sizeof (content);
  temp_source_file tmp (SELFTEST_LOCATION, ".c", content, sz);
  line_table_test ltt (case_);
  const line_map_ordinary *ord_map = linemap_check_ordinary
    (linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 0));
  linemap_line_start (line_table, 1, 100);

  location_t finish
    = linemap_position_for_line_and_column (line_table, ord_map, 1,
					    strlen (content));

  if (finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  /* Location of the NUL byte.  */
  location_t nul_loc
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 1);
  gcc_rich_location richloc (nul_loc);

  {
    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ ("  after\n"
		  " ^\n",
		  pp_formatted_text (dc.printer));
  }
  richloc.set_escape_on_output (true);
  {
    test_diagnostic_context dc;
    dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" <U+0000>after\n"
		  " ^~~~~~~~\n",
		  pp_formatted_text (dc.printer));
  }
  {
    test_diagnostic_context dc;
    dc.escape_format = DIAGNOSTICS_ESCAPE_FORMAT_BYTES;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" <00>after\n"
		  " ^~~~\n",
		  pp_formatted_text (dc.printer));
  }
}

/* Verify that line numbers are correctly printed for the case of
   a multiline range in which the width of the line numbers changes
   (e.g. from "9" to "10").  */

static void
test_line_numbers_multiline_range ()
{
  /* Create a tempfile and write some text to it.  */
  pretty_printer pp;
  for (int i = 0; i < 20; i++)
    /* .........0000000001111111.
   .............1234567890123456.  */
    pp_printf (&pp, "this is line %i\n", i + 1);
  temp_source_file tmp (SELFTEST_LOCATION, ".txt", pp_formatted_text (&pp));
  line_table_test ltt;

  const line_map_ordinary *ord_map = linemap_check_ordinary
    (linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 0));
  linemap_line_start (line_table, 1, 100);

  /* Create a multi-line location, starting at the "line" of line 9, with
     a caret on the "is" of line 10, finishing on the "this" line 11.  */

  location_t start
    = linemap_position_for_line_and_column (line_table, ord_map, 9, 9);
  location_t caret
    = linemap_position_for_line_and_column (line_table, ord_map, 10, 6);
  location_t finish
    = linemap_position_for_line_and_column (line_table, ord_map, 11, 4);
  location_t loc = make_location (caret, start, finish);

  test_diagnostic_context dc;
  dc.show_line_numbers_p = true;
  dc.min_margin_width = 0;
  gcc_rich_location richloc (loc);
  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
  ASSERT_STREQ (" 9 | this is line 9\n"
		"   |         ~~~~~~\n"
		"10 | this is line 10\n"
		"   | ~~~~~^~~~~~~~~~\n"
		"11 | this is line 11\n"
		"   | ~~~~  \n",
		pp_formatted_text (dc.printer));
}

/* Run all of the selftests within this file.  */

void
diagnostic_show_locus_cc_tests ()
{
  test_line_span ();

  test_layout_range_for_single_point ();
  test_layout_range_for_single_line ();
  test_layout_range_for_multiple_lines ();

  test_display_widths ();

  for_each_line_table_case (test_layout_x_offset_display_utf8);
  for_each_line_table_case (test_layout_x_offset_display_tab);

  test_get_line_bytes_without_trailing_whitespace ();

  test_diagnostic_show_locus_unknown_location ();

  for_each_line_table_case (test_diagnostic_show_locus_one_liner);
  for_each_line_table_case (test_diagnostic_show_locus_one_liner_utf8);
  for_each_line_table_case (test_add_location_if_nearby);
  for_each_line_table_case (test_diagnostic_show_locus_fixit_lines);
  for_each_line_table_case (test_fixit_consolidation);
  for_each_line_table_case (test_overlapped_fixit_printing);
  for_each_line_table_case (test_overlapped_fixit_printing_utf8);
  for_each_line_table_case (test_overlapped_fixit_printing_2);
  for_each_line_table_case (test_fixit_insert_containing_newline);
  for_each_line_table_case (test_fixit_insert_containing_newline_2);
  for_each_line_table_case (test_fixit_replace_containing_newline);
  for_each_line_table_case (test_fixit_deletion_affecting_newline);
  for_each_line_table_case (test_tab_expansion);
  for_each_line_table_case (test_escaping_bytes_1);
  for_each_line_table_case (test_escaping_bytes_2);

  test_line_numbers_multiline_range ();
}

} // namespace selftest

#endif /* #if CHECKING_P */

#if __GNUC__ >= 10
#  pragma GCC diagnostic pop
#endif
