/* 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 ();
}

/* 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 (text), m_label_line (0), m_has_vbar (true)
  {
    const int bytes = strlen (text.m_buffer);
    m_display_width = cpp_display_width (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;
  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.m_buffer == NULL)
	  continue;

	labels.safe_push (line_label (m_policy, i, disp_col, 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\r\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 \r bytes.  */
  location_t nul_loc
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 7);
  location_t r_loc
    = linemap_position_for_line_and_column (line_table, ord_map, 1, 11);
  gcc_rich_location richloc (nul_loc);
  richloc.add_range (r_loc);

  {
    test_diagnostic_context dc;
    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
    ASSERT_STREQ (" before \1\2\3 \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+000D><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><0d><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
