/* Language-independent diagnostic subroutines for the GNU Compiler Collection
   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/>.  */


/* This file implements the language independent aspect of diagnostic
   message module.  */

#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 "diagnostic-url.h"
#include "diagnostic-metadata.h"
#include "diagnostic-path.h"
#include "diagnostic-client-data-hooks.h"
#include "edit-context.h"
#include "selftest.h"
#include "selftest-diagnostic.h"
#include "opts.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

#define pedantic_warning_kind(DC)			\
  ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
#define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
#define permissive_error_option(DC) ((DC)->opt_permissive)

/* Prototypes.  */
static bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
			     int, const char *,
			     va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0);
static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
			       int, unsigned HOST_WIDE_INT,
			       const char *, const char *, va_list *,
			       diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0);

static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
static void real_abort (void) ATTRIBUTE_NORETURN;

/* Name of program invoked, sans directories.  */

const char *progname;

/* A diagnostic_context surrogate for stderr.  */
static diagnostic_context global_diagnostic_context;
diagnostic_context *global_dc = &global_diagnostic_context;

/* Return a malloc'd string containing MSG formatted a la printf.  The
   caller is responsible for freeing the memory.  */
char *
build_message_string (const char *msg, ...)
{
  char *str;
  va_list ap;

  va_start (ap, msg);
  str = xvasprintf (msg, ap);
  va_end (ap);

  return str;
}

/* Same as diagnostic_build_prefix, but only the source FILE is given.  */
char *
file_name_as_prefix (diagnostic_context *context, const char *f)
{
  const char *locus_cs
    = colorize_start (pp_show_color (context->printer), "locus");
  const char *locus_ce = colorize_stop (pp_show_color (context->printer));
  return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
}



/* Return the value of the getenv("COLUMNS") as an integer. If the
   value is not set to a positive integer, use ioctl to get the
   terminal width. If it fails, return INT_MAX.  */
int
get_terminal_width (void)
{
  const char * s = getenv ("COLUMNS");
  if (s != NULL) {
    int n = atoi (s);
    if (n > 0)
      return n;
  }

#ifdef TIOCGWINSZ
  struct winsize w;
  w.ws_col = 0;
  if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
    return w.ws_col;
#endif

  return INT_MAX;
}

/* Set caret_max_width to value.  */
void
diagnostic_set_caret_max_width (diagnostic_context *context, int value)
{
  /* One minus to account for the leading empty space.  */
  value = value ? value - 1 
    : (isatty (fileno (pp_buffer (context->printer)->stream))
       ? get_terminal_width () - 1: INT_MAX);
  
  if (value <= 0) 
    value = INT_MAX;

  context->caret_max_width = value;
}

/* Default implementation of final_cb.  */

static void
default_diagnostic_final_cb (diagnostic_context *context)
{
  /* Some of the errors may actually have been warnings.  */
  if (diagnostic_kind_count (context, DK_WERROR))
    {
      /* -Werror was given.  */
      if (context->warning_as_error_requested)
	pp_verbatim (context->printer,
		     _("%s: all warnings being treated as errors"),
		     progname);
      /* At least one -Werror= was given.  */
      else
	pp_verbatim (context->printer,
		     _("%s: some warnings being treated as errors"),
		     progname);
      pp_newline_and_flush (context->printer);
    }
}

/* Initialize the diagnostic message outputting machinery.  */
void
diagnostic_initialize (diagnostic_context *context, int n_opts)
{
  int i;

  /* Allocate a basic pretty-printer.  Clients will replace this a
     much more elaborated pretty-printer if they wish.  */
  context->printer = XNEW (pretty_printer);
  new (context->printer) pretty_printer ();

  memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
  context->warning_as_error_requested = false;
  context->n_opts = n_opts;
  context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
  for (i = 0; i < n_opts; i++)
    context->classify_diagnostic[i] = DK_UNSPECIFIED;
  context->show_caret = false;
  diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
  for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
    context->caret_chars[i] = '^';
  context->show_cwe = false;
  context->show_rules = false;
  context->path_format = DPF_NONE;
  context->show_path_depths = false;
  context->show_option_requested = false;
  context->abort_on_error = false;
  context->show_column = false;
  context->pedantic_errors = false;
  context->permissive = false;
  context->opt_permissive = 0;
  context->fatal_errors = false;
  context->dc_inhibit_warnings = false;
  context->dc_warn_system_headers = false;
  context->max_errors = 0;
  context->internal_error = NULL;
  diagnostic_starter (context) = default_diagnostic_starter;
  context->start_span = default_diagnostic_start_span_fn;
  diagnostic_finalizer (context) = default_diagnostic_finalizer;
  context->option_enabled = NULL;
  context->option_state = NULL;
  context->option_name = NULL;
  context->get_option_url = NULL;
  context->last_location = UNKNOWN_LOCATION;
  context->last_module = 0;
  context->x_data = NULL;
  context->lock = 0;
  context->inhibit_notes_p = false;
  context->colorize_source_p = false;
  context->show_labels_p = false;
  context->show_line_numbers_p = false;
  context->min_margin_width = 0;
  context->show_ruler_p = false;
  context->report_bug = false;

  if (const char *var = getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT"))
    {
      if (!strcmp (var, "fixits-v1"))
	context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1;
      else if (!strcmp (var, "fixits-v2"))
	context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2;
      /* Silently ignore unrecognized values.  */
    }
  context->column_unit = DIAGNOSTICS_COLUMN_UNIT_DISPLAY;
  context->column_origin = 1;
  context->tabstop = 8;
  context->escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
  context->edit_context_ptr = NULL;
  context->diagnostic_group_nesting_depth = 0;
  context->diagnostic_group_emission_count = 0;
  context->begin_group_cb = NULL;
  context->end_group_cb = NULL;
  context->final_cb = default_diagnostic_final_cb;
  context->includes_seen = NULL;
  context->m_client_data_hooks = NULL;
}

/* Maybe initialize the color support. We require clients to do this
   explicitly, since most clients don't want color.  When called
   without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT.  */

void
diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
{
  /* value == -1 is the default value.  */
  if (value < 0)
    {
      /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
	 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
	 otherwise default to -fdiagnostics-color=never, for other
	 values default to that
	 -fdiagnostics-color={never,auto,always}.  */
      if (DIAGNOSTICS_COLOR_DEFAULT == -1)
	{
	  if (!getenv ("GCC_COLORS"))
	    return;
	  value = DIAGNOSTICS_COLOR_AUTO;
	}
      else
	value = DIAGNOSTICS_COLOR_DEFAULT;
    }
  pp_show_color (context->printer)
    = colorize_init ((diagnostic_color_rule_t) value);
}

/* Initialize URL support within CONTEXT based on VALUE, handling "auto".  */

void
diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
{
  /* value == -1 is the default value.  */
  if (value < 0)
    {
      /* If DIAGNOSTICS_URLS_DEFAULT is -1, default to
	 -fdiagnostics-urls=auto if GCC_URLS or TERM_URLS is in the
	 environment, otherwise default to -fdiagnostics-urls=never,
	 for other values default to that
	 -fdiagnostics-urls={never,auto,always}.  */
      if (DIAGNOSTICS_URLS_DEFAULT == -1)
	{
	  if (!getenv ("GCC_URLS") && !getenv ("TERM_URLS"))
	    return;
	  value = DIAGNOSTICS_URL_AUTO;
	}
      else
	value = DIAGNOSTICS_URLS_DEFAULT;
    }

  context->printer->url_format
    = determine_url_format ((diagnostic_url_rule_t) value);
}

/* Create the file_cache, if not already created, and tell it how to
   translate files on input.  */
void diagnostic_initialize_input_context (diagnostic_context *context,
					  diagnostic_input_charset_callback ccb,
					  bool should_skip_bom)
{
  if (!context->m_file_cache)
    context->m_file_cache = new file_cache;
  context->m_file_cache->initialize_input_context (ccb, should_skip_bom);
}

/* Do any cleaning up required after the last diagnostic is emitted.  */

void
diagnostic_finish (diagnostic_context *context)
{
  if (context->final_cb)
    context->final_cb (context);

  diagnostic_file_cache_fini ();

  XDELETEVEC (context->classify_diagnostic);
  context->classify_diagnostic = NULL;

  /* diagnostic_initialize allocates context->printer using XNEW
     and placement-new.  */
  context->printer->~pretty_printer ();
  XDELETE (context->printer);
  context->printer = NULL;

  if (context->edit_context_ptr)
    {
      delete context->edit_context_ptr;
      context->edit_context_ptr = NULL;
    }

  if (context->includes_seen)
    {
      delete context->includes_seen;
      context->includes_seen = nullptr;
    }

  if (context->m_client_data_hooks)
    {
      delete context->m_client_data_hooks;
      context->m_client_data_hooks = NULL;
    }
}

/* Initialize DIAGNOSTIC, where the message MSG has already been
   translated.  */
void
diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
				va_list *args, rich_location *richloc,
				diagnostic_t kind)
{
  gcc_assert (richloc);
  diagnostic->message.err_no = errno;
  diagnostic->message.args_ptr = args;
  diagnostic->message.format_spec = msg;
  diagnostic->message.m_richloc = richloc;
  diagnostic->richloc = richloc;
  diagnostic->metadata = NULL;
  diagnostic->kind = kind;
  diagnostic->option_index = 0;
}

/* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
   translated.  */
void
diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
		     va_list *args, rich_location *richloc,
		     diagnostic_t kind)
{
  gcc_assert (richloc);
  diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind);
}

static const char *const diagnostic_kind_color[] = {
#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
#include "diagnostic.def"
#undef DEFINE_DIAGNOSTIC_KIND
  NULL
};

/* Get a color name for diagnostics of type KIND
   Result could be NULL.  */

const char *
diagnostic_get_color_for_kind (diagnostic_t kind)
{
  return diagnostic_kind_color[kind];
}

/* Given an expanded_location, convert the column (which is in 1-based bytes)
   to the requested units, without converting the origin.
   Return -1 if the column is invalid (<= 0).  */

static int
convert_column_unit (enum diagnostics_column_unit column_unit,
		     int tabstop,
		     expanded_location s)
{
  if (s.column <= 0)
    return -1;

  switch (column_unit)
    {
    default:
      gcc_unreachable ();

    case DIAGNOSTICS_COLUMN_UNIT_DISPLAY:
      {
	cpp_char_column_policy policy (tabstop, cpp_wcwidth);
	return location_compute_display_column (s, policy);
      }

    case DIAGNOSTICS_COLUMN_UNIT_BYTE:
      return s.column;
    }
}

/* Given an expanded_location, convert the column (which is in 1-based bytes)
   to the requested units and origin.  Return -1 if the column is
   invalid (<= 0).  */
int
diagnostic_converted_column (diagnostic_context *context, expanded_location s)
{
  int one_based_col
    = convert_column_unit (context->column_unit, context->tabstop, s);
  if (one_based_col <= 0)
    return -1;
  return one_based_col + (context->column_origin - 1);
}

/* Return a formatted line and column ':%line:%column'.  Elided if
   line == 0 or col < 0.  (A column of 0 may be valid due to the
   -fdiagnostics-column-origin option.)
   The result is a statically allocated buffer.  */

static const char *
maybe_line_and_column (int line, int col)
{
  static char result[32];

  if (line)
    {
      size_t l
	= snprintf (result, sizeof (result),
		    col >= 0 ? ":%d:%d" : ":%d", line, col);
      gcc_checking_assert (l < sizeof (result));
    }
  else
    result[0] = 0;
  return result;
}

/* Return a malloc'd string describing a location e.g. "foo.c:42:10".
   The caller is responsible for freeing the memory.  */

static char *
diagnostic_get_location_text (diagnostic_context *context,
			      expanded_location s)
{
  pretty_printer *pp = context->printer;
  const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
  const char *locus_ce = colorize_stop (pp_show_color (pp));
  const char *file = s.file ? s.file : progname;
  int line = 0;
  int col = -1;
  if (strcmp (file, special_fname_builtin ()))
    {
      line = s.line;
      if (context->show_column)
	col = diagnostic_converted_column (context, s);
    }

  const char *line_col = maybe_line_and_column (line, col);
  return build_message_string ("%s%s%s:%s", locus_cs, file,
			       line_col, locus_ce);
}

static const char *const diagnostic_kind_text[] = {
#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
#include "diagnostic.def"
#undef DEFINE_DIAGNOSTIC_KIND
  "must-not-happen"
};

/* Return a malloc'd string describing a location and the severity of the
   diagnostic, e.g. "foo.c:42:10: error: ".  The caller is responsible for
   freeing the memory.  */
char *
diagnostic_build_prefix (diagnostic_context *context,
			 const diagnostic_info *diagnostic)
{
  gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);

  const char *text = _(diagnostic_kind_text[diagnostic->kind]);
  const char *text_cs = "", *text_ce = "";
  pretty_printer *pp = context->printer;

  if (diagnostic_kind_color[diagnostic->kind])
    {
      text_cs = colorize_start (pp_show_color (pp),
				diagnostic_kind_color[diagnostic->kind]);
      text_ce = colorize_stop (pp_show_color (pp));
    }

  expanded_location s = diagnostic_expand_location (diagnostic);
  char *location_text = diagnostic_get_location_text (context, s);

  char *result = build_message_string ("%s %s%s%s", location_text,
				       text_cs, text, text_ce);
  free (location_text);
  return result;
}

/* Functions at which to stop the backtrace print.  It's not
   particularly helpful to print the callers of these functions.  */

static const char * const bt_stop[] =
{
  "main",
  "toplev::main",
  "execute_one_pass",
  "compile_file",
};

/* A callback function passed to the backtrace_full function.  */

static int
bt_callback (void *data, uintptr_t pc, const char *filename, int lineno,
	     const char *function)
{
  int *pcount = (int *) data;

  /* If we don't have any useful information, don't print
     anything.  */
  if (filename == NULL && function == NULL)
    return 0;

  /* Skip functions in diagnostic.cc.  */
  if (*pcount == 0
      && filename != NULL
      && strcmp (lbasename (filename), "diagnostic.cc") == 0)
    return 0;

  /* Print up to 20 functions.  We could make this a --param, but
     since this is only for debugging just use a constant for now.  */
  if (*pcount >= 20)
    {
      /* Returning a non-zero value stops the backtrace.  */
      return 1;
    }
  ++*pcount;

  char *alc = NULL;
  if (function != NULL)
    {
      char *str = cplus_demangle_v3 (function,
				     (DMGL_VERBOSE | DMGL_ANSI
				      | DMGL_GNU_V3 | DMGL_PARAMS));
      if (str != NULL)
	{
	  alc = str;
	  function = str;
	}

      for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i)
	{
	  size_t len = strlen (bt_stop[i]);
	  if (strncmp (function, bt_stop[i], len) == 0
	      && (function[len] == '\0' || function[len] == '('))
	    {
	      if (alc != NULL)
		free (alc);
	      /* Returning a non-zero value stops the backtrace.  */
	      return 1;
	    }
	}
    }

  fprintf (stderr, "0x%lx %s\n\t%s:%d\n",
	   (unsigned long) pc,
	   function == NULL ? "???" : function,
	   filename == NULL ? "???" : filename,
	   lineno);

  if (alc != NULL)
    free (alc);

  return 0;
}

/* A callback function passed to the backtrace_full function.  This is
   called if backtrace_full has an error.  */

static void
bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum)
{
  if (errnum < 0)
    {
      /* This means that no debug info was available.  Just quietly
	 skip printing backtrace info.  */
      return;
    }
  fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ",
	   errnum == 0 ? "" : xstrerror (errnum));
}

/* Check if we've met the maximum error limit, and if so fatally exit
   with a message.  CONTEXT is the context to check, and FLUSH
   indicates whether a diagnostic_finish call is needed.  */

void
diagnostic_check_max_errors (diagnostic_context *context, bool flush)
{
  if (!context->max_errors)
    return;

  int count = (diagnostic_kind_count (context, DK_ERROR)
	       + diagnostic_kind_count (context, DK_SORRY)
	       + diagnostic_kind_count (context, DK_WERROR));

  if (count >= context->max_errors)
    {
      fnotice (stderr,
	       "compilation terminated due to -fmax-errors=%u.\n",
	       context->max_errors);
      if (flush)
	diagnostic_finish (context);
      exit (FATAL_EXIT_CODE);
    }
}

/* Take any action which is expected to happen after the diagnostic
   is written out.  This function does not always return.  */
void
diagnostic_action_after_output (diagnostic_context *context,
				diagnostic_t diag_kind)
{
  switch (diag_kind)
    {
    case DK_DEBUG:
    case DK_NOTE:
    case DK_ANACHRONISM:
    case DK_WARNING:
      break;

    case DK_ERROR:
    case DK_SORRY:
      if (context->abort_on_error)
	real_abort ();
      if (context->fatal_errors)
	{
	  fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
	  diagnostic_finish (context);
	  exit (FATAL_EXIT_CODE);
	}
      break;

    case DK_ICE:
    case DK_ICE_NOBT:
      {
	struct backtrace_state *state = NULL;
	if (diag_kind == DK_ICE)
	  state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
	int count = 0;
	if (state != NULL)
	  backtrace_full (state, 2, bt_callback, bt_err_callback,
			  (void *) &count);

	if (context->abort_on_error)
	  real_abort ();

	if (context->report_bug)
	  fnotice (stderr, "Please submit a full bug report, "
		   "with preprocessed source.\n");
	else
	  fnotice (stderr, "Please submit a full bug report, "
		   "with preprocessed source (by using -freport-bug).\n");

	if (count > 0)
	  fnotice (stderr, "Please include the complete backtrace "
		   "with any bug report.\n");
	fnotice (stderr, "See %s for instructions.\n", bug_report_url);

	exit (ICE_EXIT_CODE);
      }

    case DK_FATAL:
      if (context->abort_on_error)
	real_abort ();
      diagnostic_finish (context);
      fnotice (stderr, "compilation terminated.\n");
      exit (FATAL_EXIT_CODE);

    default:
      gcc_unreachable ();
    }
}

/* True if the last module or file in which a diagnostic was reported is
   different from the current one.  */

static bool
last_module_changed_p (diagnostic_context *context,
		       const line_map_ordinary *map)
{
  return context->last_module != map;
}

/* Remember the current module or file as being the last one in which we
   report a diagnostic.  */

static void
set_last_module (diagnostic_context *context, const line_map_ordinary *map)
{
  context->last_module = map;
}

/* Only dump the "In file included from..." stack once for each file.  */

static bool
includes_seen (diagnostic_context *context, const line_map_ordinary *map)
{
  /* No include path for main.  */
  if (MAIN_FILE_P (map))
    return true;

  /* Always identify C++ modules, at least for now.  */
  auto probe = map;
  if (linemap_check_ordinary (map)->reason == LC_RENAME)
    /* The module source file shows up as LC_RENAME inside LC_MODULE.  */
    probe = linemap_included_from_linemap (line_table, map);
  if (MAP_MODULE_P (probe))
    return false;

  if (!context->includes_seen)
    context->includes_seen = new hash_set<location_t, false, location_hash>;

  /* Hash the location of the #include directive to better handle files
     that are included multiple times with different macros defined.  */
  return context->includes_seen->add (linemap_included_from (map));
}

void
diagnostic_report_current_module (diagnostic_context *context, location_t where)
{
  const line_map_ordinary *map = NULL;

  if (pp_needs_newline (context->printer))
    {
      pp_newline (context->printer);
      pp_needs_newline (context->printer) = false;
    }

  if (where <= BUILTINS_LOCATION)
    return;

  linemap_resolve_location (line_table, where,
			    LRK_MACRO_DEFINITION_LOCATION,
			    &map);

  if (map && last_module_changed_p (context, map))
    {
      set_last_module (context, map);
      if (!includes_seen (context, map))
	{
	  bool first = true, need_inc = true, was_module = MAP_MODULE_P (map);
	  expanded_location s = {};
	  do
	    {
	      where = linemap_included_from (map);
	      map = linemap_included_from_linemap (line_table, map);
	      bool is_module = MAP_MODULE_P (map);
	      s.file = LINEMAP_FILE (map);
	      s.line = SOURCE_LINE (map, where);
	      int col = -1;
	      if (first && context->show_column)
		{
		  s.column = SOURCE_COLUMN (map, where);
		  col = diagnostic_converted_column (context, s);
		}
	      const char *line_col = maybe_line_and_column (s.line, col);
	      static const char *const msgs[] =
		{
		 NULL,
		 N_("                 from"),
		 N_("In file included from"),	/* 2 */
		 N_("        included from"),
		 N_("In module"),		/* 4 */
		 N_("of module"),
		 N_("In module imported at"),	/* 6 */
		 N_("imported at"),
		};

	      unsigned index = (was_module ? 6 : is_module ? 4
				: need_inc ? 2 : 0) + !first;

	      pp_verbatim (context->printer, "%s%s %r%s%s%R",
			   first ? "" : was_module ? ", " : ",\n",
			   _(msgs[index]),
			   "locus", s.file, line_col);
	      first = false, need_inc = was_module, was_module = is_module;
	    }
	  while (!includes_seen (context, map));
	  pp_verbatim (context->printer, ":");
	  pp_newline (context->printer);
	}
    }
}

/* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths,
   print the path.  */

void
diagnostic_show_any_path (diagnostic_context *context,
			  diagnostic_info *diagnostic)
{
  const diagnostic_path *path = diagnostic->richloc->get_path ();
  if (!path)
    return;

  if (context->print_path)
    context->print_path (context, path);
}

/* class diagnostic_event.  */

/* struct diagnostic_event::meaning.  */

void
diagnostic_event::meaning::dump_to_pp (pretty_printer *pp) const
{
  bool need_comma = false;
  pp_character (pp, '{');
  if (const char *verb_str = maybe_get_verb_str (m_verb))
    {
      pp_printf (pp, "verb: %qs", verb_str);
      need_comma = true;
    }
  if (const char *noun_str = maybe_get_noun_str (m_noun))
    {
      if (need_comma)
	pp_string (pp, ", ");
      pp_printf (pp, "noun: %qs", noun_str);
      need_comma = true;
    }
  if (const char *property_str = maybe_get_property_str (m_property))
    {
      if (need_comma)
	pp_string (pp, ", ");
      pp_printf (pp, "property: %qs", property_str);
      need_comma = true;
    }
  pp_character (pp, '}');
}

/* Get a string (or NULL) for V suitable for use within a SARIF
   threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8).  */

const char *
diagnostic_event::meaning::maybe_get_verb_str (enum verb v)
{
  switch (v)
    {
    default:
      gcc_unreachable ();
    case VERB_unknown:
      return NULL;
    case VERB_acquire:
      return "acquire";
    case VERB_release:
      return "release";
    case VERB_enter:
      return "enter";
    case VERB_exit:
      return "exit";
    case VERB_call:
      return "call";
    case VERB_return:
      return "return";
    case VERB_branch:
      return "branch";
    case VERB_danger:
      return "danger";
    }
}

/* Get a string (or NULL) for N suitable for use within a SARIF
   threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8).  */

const char *
diagnostic_event::meaning::maybe_get_noun_str (enum noun n)
{
  switch (n)
    {
    default:
      gcc_unreachable ();
    case NOUN_unknown:
      return NULL;
    case NOUN_taint:
      return "taint";
    case NOUN_sensitive:
      return "sensitive";
    case NOUN_function:
      return "function";
    case NOUN_lock:
      return "lock";
    case NOUN_memory:
      return "memory";
    case NOUN_resource:
      return "resource";
    }
}

/* Get a string (or NULL) for P suitable for use within a SARIF
   threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8).  */

const char *
diagnostic_event::meaning::maybe_get_property_str (enum property p)
{
  switch (p)
    {
    default:
      gcc_unreachable ();
    case PROPERTY_unknown:
      return NULL;
    case PROPERTY_true:
      return "true";
    case PROPERTY_false:
      return "false";
    }
}

/* class diagnostic_path.  */

/* Return true if the events in this path involve more than one
   function, or false if it is purely intraprocedural.  */

bool
diagnostic_path::interprocedural_p () const
{
  const unsigned num = num_events ();
  for (unsigned i = 0; i < num; i++)
    {
      if (get_event (i).get_fndecl () != get_event (0).get_fndecl ())
	return true;
      if (get_event (i).get_stack_depth () != get_event (0).get_stack_depth ())
	return true;
    }
  return false;
}

void
default_diagnostic_starter (diagnostic_context *context,
			    diagnostic_info *diagnostic)
{
  diagnostic_report_current_module (context, diagnostic_location (diagnostic));
  pp_set_prefix (context->printer, diagnostic_build_prefix (context,
							    diagnostic));
}

void
default_diagnostic_start_span_fn (diagnostic_context *context,
				  expanded_location exploc)
{
  char *text = diagnostic_get_location_text (context, exploc);
  pp_string (context->printer, text);
  free (text);
  pp_newline (context->printer);
}

void
default_diagnostic_finalizer (diagnostic_context *context,
			      diagnostic_info *diagnostic,
			      diagnostic_t)
{
  char *saved_prefix = pp_take_prefix (context->printer);
  pp_set_prefix (context->printer, NULL);
  pp_newline (context->printer);
  diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
  pp_set_prefix (context->printer, saved_prefix);
  pp_flush (context->printer);
}

/* Interface to specify diagnostic kind overrides.  Returns the
   previous setting, or DK_UNSPECIFIED if the parameters are out of
   range.  If OPTION_INDEX is zero, the new setting is for all the
   diagnostics.  */
diagnostic_t
diagnostic_classify_diagnostic (diagnostic_context *context,
				int option_index,
				diagnostic_t new_kind,
				location_t where)
{
  diagnostic_t old_kind;

  if (option_index < 0
      || option_index >= context->n_opts
      || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
    return DK_UNSPECIFIED;

  old_kind = context->classify_diagnostic[option_index];

  /* Handle pragmas separately, since we need to keep track of *where*
     the pragmas were.  */
  if (where != UNKNOWN_LOCATION)
    {
      int i;

      /* Record the command-line status, so we can reset it back on DK_POP. */
      if (old_kind == DK_UNSPECIFIED)
	{
	  old_kind = !context->option_enabled (option_index,
					       context->lang_mask,
					       context->option_state)
	    ? DK_IGNORED : (context->warning_as_error_requested
			    ? DK_ERROR : DK_WARNING);
	  context->classify_diagnostic[option_index] = old_kind;
	}

      for (i = context->n_classification_history - 1; i >= 0; i --)
	if (context->classification_history[i].option == option_index)
	  {
	    old_kind = context->classification_history[i].kind;
	    break;
	  }

      i = context->n_classification_history;
      context->classification_history =
	(diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
							 * sizeof (diagnostic_classification_change_t));
      context->classification_history[i].location = where;
      context->classification_history[i].option = option_index;
      context->classification_history[i].kind = new_kind;
      context->n_classification_history ++;
    }
  else
    context->classify_diagnostic[option_index] = new_kind;

  return old_kind;
}

/* Save all diagnostic classifications in a stack.  */
void
diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED)
{
  context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int));
  context->push_list[context->n_push ++] = context->n_classification_history;
}

/* Restore the topmost classification set off the stack.  If the stack
   is empty, revert to the state based on command line parameters.  */
void
diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
{
  int jump_to;
  int i;

  if (context->n_push)
    jump_to = context->push_list [-- context->n_push];
  else
    jump_to = 0;

  i = context->n_classification_history;
  context->classification_history =
    (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
						     * sizeof (diagnostic_classification_change_t));
  context->classification_history[i].location = where;
  context->classification_history[i].option = jump_to;
  context->classification_history[i].kind = DK_POP;
  context->n_classification_history ++;
}

/* Helper function for print_parseable_fixits.  Print TEXT to PP, obeying the
   escaping rules for -fdiagnostics-parseable-fixits.  */

static void
print_escaped_string (pretty_printer *pp, const char *text)
{
  gcc_assert (pp);
  gcc_assert (text);

  pp_character (pp, '"');
  for (const char *ch = text; *ch; ch++)
    {
      switch (*ch)
	{
	case '\\':
	  /* Escape backslash as two backslashes.  */
	  pp_string (pp, "\\\\");
	  break;
	case '\t':
	  /* Escape tab as "\t".  */
	  pp_string (pp, "\\t");
	  break;
	case '\n':
	  /* Escape newline as "\n".  */
	  pp_string (pp, "\\n");
	  break;
	case '"':
	  /* Escape doublequotes as \".  */
	  pp_string (pp, "\\\"");
	  break;
	default:
	  if (ISPRINT (*ch))
	    pp_character (pp, *ch);
	  else
	    /* Use octal for non-printable chars.  */
	    {
	      unsigned char c = (*ch & 0xff);
	      pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
	    }
	  break;
	}
    }
  pp_character (pp, '"');
}

/* Implementation of -fdiagnostics-parseable-fixits and
   GCC_EXTRA_DIAGNOSTIC_OUTPUT.
   Print a machine-parseable version of all fixits in RICHLOC to PP,
   using COLUMN_UNIT to express columns.
   Use TABSTOP when handling DIAGNOSTICS_COLUMN_UNIT_DISPLAY.  */

static void
print_parseable_fixits (pretty_printer *pp, rich_location *richloc,
			enum diagnostics_column_unit column_unit,
			int tabstop)
{
  gcc_assert (pp);
  gcc_assert (richloc);

  char *saved_prefix = pp_take_prefix (pp);
  pp_set_prefix (pp, NULL);

  for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
    {
      const fixit_hint *hint = richloc->get_fixit_hint (i);
      location_t start_loc = hint->get_start_loc ();
      expanded_location start_exploc = expand_location (start_loc);
      pp_string (pp, "fix-it:");
      print_escaped_string (pp, start_exploc.file);
      /* For compatibility with clang, print as a half-open range.  */
      location_t next_loc = hint->get_next_loc ();
      expanded_location next_exploc = expand_location (next_loc);
      int start_col
	= convert_column_unit (column_unit, tabstop, start_exploc);
      int next_col
	= convert_column_unit (column_unit, tabstop, next_exploc);
      pp_printf (pp, ":{%i:%i-%i:%i}:",
		 start_exploc.line, start_col,
		 next_exploc.line, next_col);
      print_escaped_string (pp, hint->get_string ());
      pp_newline (pp);
    }

  pp_set_prefix (pp, saved_prefix);
}

/* Update the inlining info in CONTEXT for a DIAGNOSTIC.  */

static void
get_any_inlining_info (diagnostic_context *context,
		       diagnostic_info *diagnostic)
{
  auto &ilocs = diagnostic->m_iinfo.m_ilocs;

  if (context->set_locations_cb)
    /* Retrieve the locations into which the expression about to be
       diagnosed has been inlined, including those of all the callers
       all the way down the inlining stack.  */
    context->set_locations_cb (context, diagnostic);
  else
    {
      /* When there's no callback use just the one location provided
	 by the caller of the diagnostic function.  */
      location_t loc = diagnostic_location (diagnostic);
      ilocs.safe_push (loc);
      diagnostic->m_iinfo.m_allsyslocs = in_system_header_at (loc);
    }
}

/* Update the kind of DIAGNOSTIC based on its location(s), including
   any of those in its inlining stack, relative to any
     #pragma GCC diagnostic
   directives recorded within CONTEXT.

   Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
   otherwise.  */

static diagnostic_t
update_effective_level_from_pragmas (diagnostic_context *context,
				     diagnostic_info *diagnostic)
{
  if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
    {
      /* Ignore the diagnostic if all the inlined locations are
	 in system headers and -Wno-system-headers is in effect.  */
      diagnostic->kind = DK_IGNORED;
      return DK_IGNORED;
    }

  if (context->n_classification_history <= 0)
    return DK_UNSPECIFIED;

  /* Iterate over the locations, checking the diagnostic disposition
     for the diagnostic at each.  If it's explicitly set as opposed
     to unspecified, update the disposition for this instance of
     the diagnostic and return it.  */
  for (location_t loc: diagnostic->m_iinfo.m_ilocs)
    {
      /* FIXME: Stupid search.  Optimize later. */
      for (int i = context->n_classification_history - 1; i >= 0; i --)
	{
	  const diagnostic_classification_change_t &hist
	    = context->classification_history[i];

	  location_t pragloc = hist.location;
	  if (!linemap_location_before_p (line_table, pragloc, loc))
	    continue;

	  if (hist.kind == (int) DK_POP)
	    {
	      /* Move on to the next region.  */
	      i = hist.option;
	      continue;
	    }

	  int option = hist.option;
	  /* The option 0 is for all the diagnostics.  */
	  if (option == 0 || option == diagnostic->option_index)
	    {
	      diagnostic_t kind = hist.kind;
	      if (kind != DK_UNSPECIFIED)
		diagnostic->kind = kind;
	      return kind;
	    }
	}
    }

  return DK_UNSPECIFIED;
}

/* Generate a URL string describing CWE.  The caller is responsible for
   freeing the string.  */

char *
get_cwe_url (int cwe)
{
  return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe);
}

/* If DIAGNOSTIC has a CWE identifier, print it.

   For example, if the diagnostic metadata associates it with CWE-119,
   " [CWE-119]" will be printed, suitably colorized, and with a URL of a
   description of the security issue.  */

static void
print_any_cwe (diagnostic_context *context,
		    const diagnostic_info *diagnostic)
{
  if (diagnostic->metadata == NULL)
    return;

  int cwe = diagnostic->metadata->get_cwe ();
  if (cwe)
    {
      pretty_printer *pp = context->printer;
      char *saved_prefix = pp_take_prefix (context->printer);
      pp_string (pp, " [");
      pp_string (pp, colorize_start (pp_show_color (pp),
				     diagnostic_kind_color[diagnostic->kind]));
      if (pp->url_format != URL_FORMAT_NONE)
	{
	  char *cwe_url = get_cwe_url (cwe);
	  pp_begin_url (pp, cwe_url);
	  free (cwe_url);
	}
      pp_printf (pp, "CWE-%i", cwe);
      pp_set_prefix (context->printer, saved_prefix);
      if (pp->url_format != URL_FORMAT_NONE)
	pp_end_url (pp);
      pp_string (pp, colorize_stop (pp_show_color (pp)));
      pp_character (pp, ']');
    }
}

/* If DIAGNOSTIC has any rules associated with it, print them.

   For example, if the diagnostic metadata associates it with a rule
   named "STR34-C", then " [STR34-C]" will be printed, suitably colorized,
   with any URL provided by the rule.  */

static void
print_any_rules (diagnostic_context *context,
		const diagnostic_info *diagnostic)
{
  if (diagnostic->metadata == NULL)
    return;

  for (unsigned idx = 0; idx < diagnostic->metadata->get_num_rules (); idx++)
    {
      const diagnostic_metadata::rule &rule
	= diagnostic->metadata->get_rule (idx);
      if (char *desc = rule.make_description ())
	{
	  pretty_printer *pp = context->printer;
	  char *saved_prefix = pp_take_prefix (context->printer);
	  pp_string (pp, " [");
	  pp_string (pp,
		     colorize_start (pp_show_color (pp),
				     diagnostic_kind_color[diagnostic->kind]));
	  char *url = NULL;
	  if (pp->url_format != URL_FORMAT_NONE)
	    {
	      url = rule.make_url ();
	      if (url)
		pp_begin_url (pp, url);
	    }
	  pp_string (pp, desc);
	  pp_set_prefix (context->printer, saved_prefix);
	  if (pp->url_format != URL_FORMAT_NONE)
	    if (url)
	      pp_end_url (pp);
	  free (url);
	  pp_string (pp, colorize_stop (pp_show_color (pp)));
	  pp_character (pp, ']');
	  free (desc);
	}
    }
}

/* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
   printer, e.g. " [-Werror=uninitialized]".
   Subroutine of diagnostic_report_diagnostic.  */

static void
print_option_information (diagnostic_context *context,
			  const diagnostic_info *diagnostic,
			  diagnostic_t orig_diag_kind)
{
  char *option_text;

  option_text = context->option_name (context, diagnostic->option_index,
				      orig_diag_kind, diagnostic->kind);

  if (option_text)
    {
      char *option_url = NULL;
      if (context->get_option_url
	  && context->printer->url_format != URL_FORMAT_NONE)
	option_url = context->get_option_url (context,
					      diagnostic->option_index);
      pretty_printer *pp = context->printer;
      pp_string (pp, " [");
      pp_string (pp, colorize_start (pp_show_color (pp),
				     diagnostic_kind_color[diagnostic->kind]));
      if (option_url)
	pp_begin_url (pp, option_url);
      pp_string (pp, option_text);
      if (option_url)
	{
	  pp_end_url (pp);
	  free (option_url);
	}
      pp_string (pp, colorize_stop (pp_show_color (pp)));
      pp_character (pp, ']');
      free (option_text);
    }
}

/* Returns whether a DIAGNOSTIC should be printed, and adjusts diagnostic->kind
   as appropriate for #pragma GCC diagnostic and -Werror=foo.  */

static bool
diagnostic_enabled (diagnostic_context *context,
		    diagnostic_info *diagnostic)
{
  /* Update the inlining stack for this diagnostic.  */
  get_any_inlining_info (context, diagnostic);

  /* Diagnostics with no option or -fpermissive are always enabled.  */
  if (!diagnostic->option_index
      || diagnostic->option_index == permissive_error_option (context))
    return true;

  /* This tests if the user provided the appropriate -Wfoo or
     -Wno-foo option.  */
  if (! context->option_enabled (diagnostic->option_index,
				 context->lang_mask,
				 context->option_state))
    return false;

  /* This tests for #pragma diagnostic changes.  */
  diagnostic_t diag_class
    = update_effective_level_from_pragmas (context, diagnostic);

  /* This tests if the user provided the appropriate -Werror=foo
     option.  */
  if (diag_class == DK_UNSPECIFIED
      && (context->classify_diagnostic[diagnostic->option_index]
	  != DK_UNSPECIFIED))
    diagnostic->kind
      = context->classify_diagnostic[diagnostic->option_index];

  /* This allows for future extensions, like temporarily disabling
     warnings for ranges of source code.  */
  if (diagnostic->kind == DK_IGNORED)
    return false;

  return true;
}

/* Returns whether warning OPT is enabled at LOC.  */

bool
warning_enabled_at (location_t loc, int opt)
{
  if (!diagnostic_report_warnings_p (global_dc, loc))
    return false;

  rich_location richloc (line_table, loc);
  diagnostic_info diagnostic = {};
  diagnostic.option_index = opt;
  diagnostic.richloc = &richloc;
  diagnostic.message.m_richloc = &richloc;
  diagnostic.kind = DK_WARNING;
  return diagnostic_enabled (global_dc, &diagnostic);
}

/* Report a diagnostic message (an error or a warning) as specified by
   DC.  This function is *the* subroutine in terms of which front-ends
   should implement their specific diagnostic handling modules.  The
   front-end independent format specifiers are exactly those described
   in the documentation of output_format.
   Return true if a diagnostic was printed, false otherwise.  */

bool
diagnostic_report_diagnostic (diagnostic_context *context,
			      diagnostic_info *diagnostic)
{
  location_t location = diagnostic_location (diagnostic);
  diagnostic_t orig_diag_kind = diagnostic->kind;

  /* Give preference to being able to inhibit warnings, before they
     get reclassified to something else.  */
  bool report_warning_p = true;
  if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
    {
      if (context->dc_inhibit_warnings)
	return false;
      /* Remember the result of the overall system header warning setting
	 but proceed to also check the inlining context.  */
      report_warning_p = diagnostic_report_warnings_p (context, location);
      if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
	return false;
    }

  if (diagnostic->kind == DK_PEDWARN)
    {
      diagnostic->kind = pedantic_warning_kind (context);
      /* We do this to avoid giving the message for -pedantic-errors.  */
      orig_diag_kind = diagnostic->kind;
    }

  if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
    return false;

  if (context->lock > 0)
    {
      /* If we're reporting an ICE in the middle of some other error,
	 try to flush out the previous error, then let this one
	 through.  Don't do this more than once.  */
      if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
	  && context->lock == 1)
	pp_newline_and_flush (context->printer);
      else
	error_recursion (context);
    }

  /* If the user requested that warnings be treated as errors, so be
     it.  Note that we do this before the next block so that
     individual warnings can be overridden back to warnings with
     -Wno-error=*.  */
  if (context->warning_as_error_requested
      && diagnostic->kind == DK_WARNING)
    diagnostic->kind = DK_ERROR;

  diagnostic->message.x_data = &diagnostic->x_data;

  /* Check to see if the diagnostic is enabled at the location and
     not disabled by #pragma GCC diagnostic anywhere along the inlining
     stack.  .  */
  if (!diagnostic_enabled (context, diagnostic))
    return false;

  if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
    /* Bail if the warning is not to be reported because all locations
       in the inlining stack (if there is one) are in system headers.  */
    return false;

  if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
    diagnostic_check_max_errors (context);

  context->lock++;

  if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
    {
      /* When not checking, ICEs are converted to fatal errors when an
	 error has already occurred.  This is counteracted by
	 abort_on_error.  */
      if (!CHECKING_P
	  && (diagnostic_kind_count (context, DK_ERROR) > 0
	      || diagnostic_kind_count (context, DK_SORRY) > 0)
	  && !context->abort_on_error)
	{
	  expanded_location s 
	    = expand_location (diagnostic_location (diagnostic));
	  fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
		   s.file, s.line);
	  exit (ICE_EXIT_CODE);
	}
      if (context->internal_error)
	(*context->internal_error) (context,
				    diagnostic->message.format_spec,
				    diagnostic->message.args_ptr);
    }
  if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING)
    ++diagnostic_kind_count (context, DK_WERROR);
  else
    ++diagnostic_kind_count (context, diagnostic->kind);

  /* Is this the initial diagnostic within the stack of groups?  */
  if (context->diagnostic_group_emission_count == 0)
    {
      if (context->begin_group_cb)
	context->begin_group_cb (context);
    }
  context->diagnostic_group_emission_count++;

  pp_format (context->printer, &diagnostic->message);
  (*diagnostic_starter (context)) (context, diagnostic);
  pp_output_formatted_text (context->printer);
  if (context->show_cwe)
    print_any_cwe (context, diagnostic);
  if (context->show_rules)
    print_any_rules (context, diagnostic);
  if (context->show_option_requested)
    print_option_information (context, diagnostic, orig_diag_kind);
  (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
  switch (context->extra_output_kind)
    {
    default:
      break;
    case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1:
      print_parseable_fixits (context->printer, diagnostic->richloc,
			      DIAGNOSTICS_COLUMN_UNIT_BYTE,
			      context->tabstop);
      pp_flush (context->printer);
      break;
    case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2:
      print_parseable_fixits (context->printer, diagnostic->richloc,
			      DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
			      context->tabstop);
      pp_flush (context->printer);
      break;
    }
  diagnostic_action_after_output (context, diagnostic->kind);
  diagnostic->x_data = NULL;

  if (context->edit_context_ptr)
    if (diagnostic->richloc->fixits_can_be_auto_applied_p ())
      context->edit_context_ptr->add_fixits (diagnostic->richloc);

  context->lock--;

  diagnostic_show_any_path (context, diagnostic);

  return true;
}

/* Get the number of digits in the decimal representation of VALUE.  */

int
num_digits (int value)
{
  /* Perhaps simpler to use log10 for this, but doing it this way avoids
     using floating point.  */
  gcc_assert (value >= 0);

  if (value == 0)
    return 1;

  int digits = 0;
  while (value > 0)
    {
      digits++;
      value /= 10;
    }
  return digits;
}

/* Given a partial pathname as input, return another pathname that
   shares no directory elements with the pathname of __FILE__.  This
   is used by fancy_abort() to print `internal compiler error in expr.cc'
   instead of `internal compiler error in ../../GCC/gcc/expr.cc'.  */

const char *
trim_filename (const char *name)
{
  static const char this_file[] = __FILE__;
  const char *p = name, *q = this_file;

  /* First skip any "../" in each filename.  This allows us to give a proper
     reference to a file in a subdirectory.  */
  while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
    p += 3;

  while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
    q += 3;

  /* Now skip any parts the two filenames have in common.  */
  while (*p == *q && *p != 0 && *q != 0)
    p++, q++;

  /* Now go backwards until the previous directory separator.  */
  while (p > name && !IS_DIR_SEPARATOR (p[-1]))
    p--;

  return p;
}

/* Standard error reporting routines in increasing order of severity.
   All of these take arguments like printf.  */

/* Text to be emitted verbatim to the error message stream; this
   produces no prefix and disables line-wrapping.  Use rarely.  */
void
verbatim (const char *gmsgid, ...)
{
  text_info text;
  va_list ap;

  va_start (ap, gmsgid);
  text.err_no = errno;
  text.args_ptr = &ap;
  text.format_spec = _(gmsgid);
  text.x_data = NULL;
  pp_format_verbatim (global_dc->printer, &text);
  pp_newline_and_flush (global_dc->printer);
  va_end (ap);
}

/* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT.  */
void
diagnostic_append_note (diagnostic_context *context,
                        location_t location,
                        const char * gmsgid, ...)
{
  diagnostic_info diagnostic;
  va_list ap;
  rich_location richloc (line_table, location);

  va_start (ap, gmsgid);
  diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
  if (context->inhibit_notes_p)
    {
      va_end (ap);
      return;
    }
  char *saved_prefix = pp_take_prefix (context->printer);
  pp_set_prefix (context->printer,
                 diagnostic_build_prefix (context, &diagnostic));
  pp_format (context->printer, &diagnostic.message);
  pp_output_formatted_text (context->printer);
  pp_destroy_prefix (context->printer);
  pp_set_prefix (context->printer, saved_prefix);
  pp_newline (context->printer);
  diagnostic_show_locus (context, &richloc, DK_NOTE);
  va_end (ap);
}

/* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
   permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
   and internal_error_no_backtrace, as documented and defined below.  */
static bool
diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
		 int opt, const char *gmsgid,
		 va_list *ap, diagnostic_t kind)
{
  diagnostic_info diagnostic;
  if (kind == DK_PERMERROR)
    {
      diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
			   permissive_error_kind (global_dc));
      diagnostic.option_index = permissive_error_option (global_dc);
    }
  else
    {
      diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind);
      if (kind == DK_WARNING || kind == DK_PEDWARN)
	diagnostic.option_index = opt;
    }
  diagnostic.metadata = metadata;
  return diagnostic_report_diagnostic (global_dc, &diagnostic);
}

/* Implement inform_n, warning_n, and error_n, as documented and
   defined below.  */
static bool
diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata,
		   int opt, unsigned HOST_WIDE_INT n,
		   const char *singular_gmsgid,
		   const char *plural_gmsgid,
		   va_list *ap, diagnostic_t kind)
{
  diagnostic_info diagnostic;
  unsigned long gtn;

  if (sizeof n <= sizeof gtn)
    gtn = n;
  else
    /* Use the largest number ngettext can handle, otherwise
       preserve the six least significant decimal digits for
       languages where the plural form depends on them.  */
    gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU;

  const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn);
  diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind);
  if (kind == DK_WARNING)
    diagnostic.option_index = opt;
  diagnostic.metadata = metadata;
  return diagnostic_report_diagnostic (global_dc, &diagnostic);
}

/* Wrapper around diagnostic_impl taking a variable argument list.  */

bool
emit_diagnostic (diagnostic_t kind, location_t location, int opt,
		 const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, location);
  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind);
  va_end (ap);
  return ret;
}

/* As above, but for rich_location *.  */

bool
emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
		 const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind);
  va_end (ap);
  return ret;
}

/* Wrapper around diagnostic_impl taking a va_list parameter.  */

bool
emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
			const char *gmsgid, va_list *ap)
{
  rich_location richloc (line_table, location);
  return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
}

/* An informative note at LOCATION.  Use this for additional details on an error
   message.  */
void
inform (location_t location, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, location);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
  va_end (ap);
}

/* Same as "inform" above, but at RICHLOC.  */
void
inform (rich_location *richloc, const char *gmsgid, ...)
{
  gcc_assert (richloc);

  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
  va_end (ap);
}

/* An informative note at LOCATION.  Use this for additional details on an
   error message.  */
void
inform_n (location_t location, unsigned HOST_WIDE_INT n,
	  const char *singular_gmsgid, const char *plural_gmsgid, ...)
{
  va_list ap;
  va_start (ap, plural_gmsgid);
  auto_diagnostic_group d;
  rich_location richloc (line_table, location);
  diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
		     &ap, DK_NOTE);
  va_end (ap);
}

/* A warning at INPUT_LOCATION.  Use this for code which is correct according
   to the relevant language specification but is likely to be buggy anyway.
   Returns true if the warning was printed, false if it was inhibited.  */
bool
warning (int opt, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, input_location);
  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
  va_end (ap);
  return ret;
}

/* A warning at LOCATION.  Use this for code which is correct according to the
   relevant language specification but is likely to be buggy anyway.
   Returns true if the warning was printed, false if it was inhibited.  */

bool
warning_at (location_t location, int opt, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, location);
  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
  va_end (ap);
  return ret;
}

/* Same as "warning at" above, but using RICHLOC.  */

bool
warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
{
  gcc_assert (richloc);

  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
  va_end (ap);
  return ret;
}

/* Same as "warning at" above, but using METADATA.  */

bool
warning_meta (rich_location *richloc,
	      const diagnostic_metadata &metadata,
	      int opt, const char *gmsgid, ...)
{
  gcc_assert (richloc);

  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  bool ret
    = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap,
		       DK_WARNING);
  va_end (ap);
  return ret;
}

/* Same as warning_n plural variant below, but using RICHLOC.  */

bool
warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
	   const char *singular_gmsgid, const char *plural_gmsgid, ...)
{
  gcc_assert (richloc);

  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, plural_gmsgid);
  bool ret = diagnostic_n_impl (richloc, NULL, opt, n,
				singular_gmsgid, plural_gmsgid,
				&ap, DK_WARNING);
  va_end (ap);
  return ret;
}

/* A warning at LOCATION.  Use this for code which is correct according to the
   relevant language specification but is likely to be buggy anyway.
   Returns true if the warning was printed, false if it was inhibited.  */

bool
warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
	   const char *singular_gmsgid, const char *plural_gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, plural_gmsgid);
  rich_location richloc (line_table, location);
  bool ret = diagnostic_n_impl (&richloc, NULL, opt, n,
				singular_gmsgid, plural_gmsgid,
				&ap, DK_WARNING);
  va_end (ap);
  return ret;
}

/* A "pedantic" warning at LOCATION: issues a warning unless
   -pedantic-errors was given on the command line, in which case it
   issues an error.  Use this for diagnostics required by the relevant
   language standard, if you have chosen not to make them errors.

   Note that these diagnostics are issued independent of the setting
   of the -Wpedantic command-line switch.  To get a warning enabled
   only with that switch, use either "if (pedantic) pedwarn
   (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)".  To get a
   pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".

   Returns true if the warning was printed, false if it was inhibited.  */

bool
pedwarn (location_t location, int opt, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, location);
  bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
  va_end (ap);
  return ret;
}

/* Same as pedwarn above, but using RICHLOC.  */

bool
pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...)
{
  gcc_assert (richloc);

  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
  va_end (ap);
  return ret;
}

/* A "permissive" error at LOCATION: issues an error unless
   -fpermissive was given on the command line, in which case it issues
   a warning.  Use this for things that really should be errors but we
   want to support legacy code.

   Returns true if the warning was printed, false if it was inhibited.  */

bool
permerror (location_t location, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, location);
  bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
  va_end (ap);
  return ret;
}

/* Same as "permerror" above, but at RICHLOC.  */

bool
permerror (rich_location *richloc, const char *gmsgid, ...)
{
  gcc_assert (richloc);

  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
  va_end (ap);
  return ret;
}

/* A hard error: the code is definitely ill-formed, and an object file
   will not be produced.  */
void
error (const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, input_location);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
  va_end (ap);
}

/* A hard error: the code is definitely ill-formed, and an object file
   will not be produced.  */
void
error_n (location_t location, unsigned HOST_WIDE_INT n,
	 const char *singular_gmsgid, const char *plural_gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, plural_gmsgid);
  rich_location richloc (line_table, location);
  diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
		     &ap, DK_ERROR);
  va_end (ap);
}

/* Same as above, but use location LOC instead of input_location.  */
void
error_at (location_t loc, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, loc);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
  va_end (ap);
}

/* Same as above, but use RICH_LOC.  */

void
error_at (rich_location *richloc, const char *gmsgid, ...)
{
  gcc_assert (richloc);

  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
  va_end (ap);
}

/* "Sorry, not implemented."  Use for a language feature which is
   required by the relevant specification but not implemented by GCC.
   An object file will not be produced.  */
void
sorry (const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, input_location);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
  va_end (ap);
}

/* Same as above, but use location LOC instead of input_location.  */
void
sorry_at (location_t loc, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, loc);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
  va_end (ap);
}

/* Return true if an error or a "sorry" has been seen.  Various
   processing is disabled after errors.  */
bool
seen_error (void)
{
  return errorcount || sorrycount;
}

/* An error which is severe enough that we make no attempt to
   continue.  Do not use this for internal consistency checks; that's
   internal_error.  Use of this function should be rare.  */
void
fatal_error (location_t loc, const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, loc);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL);
  va_end (ap);

  gcc_unreachable ();
}

/* An internal consistency check has failed.  We make no attempt to
   continue.  */
void
internal_error (const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, input_location);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE);
  va_end (ap);

  gcc_unreachable ();
}

/* Like internal_error, but no backtrace will be printed.  Used when
   the internal error does not happen at the current location, but happened
   somewhere else.  */
void
internal_error_no_backtrace (const char *gmsgid, ...)
{
  auto_diagnostic_group d;
  va_list ap;
  va_start (ap, gmsgid);
  rich_location richloc (line_table, input_location);
  diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT);
  va_end (ap);

  gcc_unreachable ();
}

/* Special case error functions.  Most are implemented in terms of the
   above, or should be.  */

/* Print a diagnostic MSGID on FILE.  This is just fprintf, except it
   runs its second argument through gettext.  */
void
fnotice (FILE *file, const char *cmsgid, ...)
{
  va_list ap;

  va_start (ap, cmsgid);
  vfprintf (file, _(cmsgid), ap);
  va_end (ap);
}

/* Inform the user that an error occurred while trying to report some
   other error.  This indicates catastrophic internal inconsistencies,
   so give up now.  But do try to flush out the previous error.
   This mustn't use internal_error, that will cause infinite recursion.  */

static void
error_recursion (diagnostic_context *context)
{
  if (context->lock < 3)
    pp_newline_and_flush (context->printer);

  fnotice (stderr,
	   "internal compiler error: error reporting routines re-entered.\n");

  /* Call diagnostic_action_after_output to get the "please submit a bug
     report" message.  */
  diagnostic_action_after_output (context, DK_ICE);

  /* Do not use gcc_unreachable here; that goes through internal_error
     and therefore would cause infinite recursion.  */
  real_abort ();
}

/* Report an internal compiler error in a friendly manner.  This is
   the function that gets called upon use of abort() in the source
   code generally, thanks to a special macro.  */

void
fancy_abort (const char *file, int line, const char *function)
{
  /* If fancy_abort is called before the diagnostic subsystem is initialized,
     internal_error will crash internally in a way that prevents a
     useful message reaching the user.
     This can happen with libgccjit in the case of gcc_assert failures
     that occur outside of the libgccjit mutex that guards the rest of
     gcc's state, including global_dc (when global_dc may not be
     initialized yet, or might be in use by another thread).
     Handle such cases as gracefully as possible by falling back to a
     minimal abort handler that only relies on i18n.  */
  if (global_dc->printer == NULL)
    {
      /* Print the error message.  */
      fnotice (stderr, diagnostic_kind_text[DK_ICE]);
      fnotice (stderr, "in %s, at %s:%d", function, trim_filename (file), line);
      fputc ('\n', stderr);

      /* Attempt to print a backtrace.  */
      struct backtrace_state *state
	= backtrace_create_state (NULL, 0, bt_err_callback, NULL);
      int count = 0;
      if (state != NULL)
	backtrace_full (state, 2, bt_callback, bt_err_callback,
			(void *) &count);

      /* We can't call warn_if_plugins or emergency_dump_function as these
	 rely on GCC state that might not be initialized, or might be in
	 use by another thread.  */

      /* Abort the process.  */
      real_abort ();
    }

  internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
}

/* class auto_diagnostic_group.  */

/* Constructor: "push" this group into global_dc.  */

auto_diagnostic_group::auto_diagnostic_group ()
{
  global_dc->diagnostic_group_nesting_depth++;
}

/* Destructor: "pop" this group from global_dc.  */

auto_diagnostic_group::~auto_diagnostic_group ()
{
  if (--global_dc->diagnostic_group_nesting_depth == 0)
    {
      /* Handle the case where we've popped the final diagnostic group.
	 If any diagnostics were emitted, give the context a chance
	 to do something.  */
      if (global_dc->diagnostic_group_emission_count > 0)
	{
	  if (global_dc->end_group_cb)
	    global_dc->end_group_cb (global_dc);
	}
      global_dc->diagnostic_group_emission_count = 0;
    }
}

/* Set the output format for CONTEXT to FORMAT, using BASE_FILE_NAME for
   file-based output formats.  */

void
diagnostic_output_format_init (diagnostic_context *context,
			       const char *base_file_name,
			       enum diagnostics_output_format format)
{
  switch (format)
    {
    default:
      gcc_unreachable ();
    case DIAGNOSTICS_OUTPUT_FORMAT_TEXT:
      /* The default; do nothing.  */
      break;

    case DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR:
      diagnostic_output_format_init_json_stderr (context);
      break;

    case DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE:
      diagnostic_output_format_init_json_file (context, base_file_name);
      break;

    case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR:
      diagnostic_output_format_init_sarif_stderr (context);
      break;

    case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE:
      diagnostic_output_format_init_sarif_file (context, base_file_name);
      break;
    }
}

/* Implementation of diagnostic_path::num_events vfunc for
   simple_diagnostic_path: simply get the number of events in the vec.  */

unsigned
simple_diagnostic_path::num_events () const
{
  return m_events.length ();
}

/* Implementation of diagnostic_path::get_event vfunc for
   simple_diagnostic_path: simply return the event in the vec.  */

const diagnostic_event &
simple_diagnostic_path::get_event (int idx) const
{
  return *m_events[idx];
}

/* Add an event to this path at LOC within function FNDECL at
   stack depth DEPTH.

   Use m_context's printer to format FMT, as the text of the new
   event.

   Return the id of the new event.  */

diagnostic_event_id_t
simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
				   const char *fmt, ...)
{
  pretty_printer *pp = m_event_pp;
  pp_clear_output_area (pp);

  text_info ti;
  rich_location rich_loc (line_table, UNKNOWN_LOCATION);

  va_list ap;

  va_start (ap, fmt);

  ti.format_spec = _(fmt);
  ti.args_ptr = &ap;
  ti.err_no = 0;
  ti.x_data = NULL;
  ti.m_richloc = &rich_loc;

  pp_format (pp, &ti);
  pp_output_formatted_text (pp);

  va_end (ap);

  simple_diagnostic_event *new_event
    = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
  m_events.safe_push (new_event);

  pp_clear_output_area (pp);

  return diagnostic_event_id_t (m_events.length () - 1);
}

/* struct simple_diagnostic_event.  */

/* simple_diagnostic_event's ctor.  */

simple_diagnostic_event::simple_diagnostic_event (location_t loc,
						  tree fndecl,
						  int depth,
						  const char *desc)
: m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc))
{
}

/* simple_diagnostic_event's dtor.  */

simple_diagnostic_event::~simple_diagnostic_event ()
{
  free (m_desc);
}

/* Print PATH by emitting a dummy "note" associated with it.  */

DEBUG_FUNCTION
void debug (diagnostic_path *path)
{
  rich_location richloc (line_table, UNKNOWN_LOCATION);
  richloc.set_path (path);
  inform (&richloc, "debug path");
}

/* Really call the system 'abort'.  This has to go right at the end of
   this file, so that there are no functions after it that call abort
   and get the system abort instead of our macro.  */
#undef abort
static void
real_abort (void)
{
  abort ();
}

#if CHECKING_P

namespace selftest {

/* Helper function for test_print_escaped_string.  */

static void
assert_print_escaped_string (const location &loc, const char *expected_output,
			     const char *input)
{
  pretty_printer pp;
  print_escaped_string (&pp, input);
  ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
}

#define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
    assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)

/* Tests of print_escaped_string.  */

static void
test_print_escaped_string ()
{
  /* Empty string.  */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");

  /* Non-empty string.  */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");

  /* Various things that need to be escaped:  */
  /* Backslash.  */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
				     "before\\after");
  /* Tab.  */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
				     "before\tafter");
  /* Newline.  */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
				     "before\nafter");
  /* Double quote.  */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
				     "before\"after");

  /* Non-printable characters: BEL: '\a': 0x07 */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
				     "before\aafter");
  /* Non-printable characters: vertical tab: '\v': 0x0b */
  ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
				     "before\vafter");
}

/* Tests of print_parseable_fixits.  */

/* Verify that print_parseable_fixits emits the empty string if there
   are no fixits.  */

static void
test_print_parseable_fixits_none ()
{
  pretty_printer pp;
  rich_location richloc (line_table, UNKNOWN_LOCATION);

  print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
  ASSERT_STREQ ("", pp_formatted_text (&pp));
}

/* Verify that print_parseable_fixits does the right thing if there
   is an insertion fixit hint.  */

static void
test_print_parseable_fixits_insert ()
{
  pretty_printer pp;
  rich_location richloc (line_table, UNKNOWN_LOCATION);

  linemap_add (line_table, LC_ENTER, false, "test.c", 0);
  linemap_line_start (line_table, 5, 100);
  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  location_t where = linemap_position_for_column (line_table, 10);
  richloc.add_fixit_insert_before (where, "added content");

  print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
  ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
		pp_formatted_text (&pp));
}

/* Verify that print_parseable_fixits does the right thing if there
   is an removal fixit hint.  */

static void
test_print_parseable_fixits_remove ()
{
  pretty_printer pp;
  rich_location richloc (line_table, UNKNOWN_LOCATION);

  linemap_add (line_table, LC_ENTER, false, "test.c", 0);
  linemap_line_start (line_table, 5, 100);
  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  source_range where;
  where.m_start = linemap_position_for_column (line_table, 10);
  where.m_finish = linemap_position_for_column (line_table, 20);
  richloc.add_fixit_remove (where);

  print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
  ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
		pp_formatted_text (&pp));
}

/* Verify that print_parseable_fixits does the right thing if there
   is an replacement fixit hint.  */

static void
test_print_parseable_fixits_replace ()
{
  pretty_printer pp;
  rich_location richloc (line_table, UNKNOWN_LOCATION);

  linemap_add (line_table, LC_ENTER, false, "test.c", 0);
  linemap_line_start (line_table, 5, 100);
  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  source_range where;
  where.m_start = linemap_position_for_column (line_table, 10);
  where.m_finish = linemap_position_for_column (line_table, 20);
  richloc.add_fixit_replace (where, "replacement");

  print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
  ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
		pp_formatted_text (&pp));
}

/* Verify that print_parseable_fixits correctly handles
   DIAGNOSTICS_COLUMN_UNIT_BYTE vs DIAGNOSTICS_COLUMN_UNIT_COLUMN.  */

static void
test_print_parseable_fixits_bytes_vs_display_columns ()
{
  line_table_test ltt;
  rich_location richloc (line_table, UNKNOWN_LOCATION);

  /* 1-based byte offsets:     12345677778888999900001234567.  */
  const char *const content = "smile \xf0\x9f\x98\x82 colour\n";
  /* 1-based display cols:     123456[......7-8.....]9012345.  */
  const int tabstop = 8;

  temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
  const char *const fname = tmp.get_filename ();

  linemap_add (line_table, LC_ENTER, false, fname, 0);
  linemap_line_start (line_table, 1, 100);
  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  source_range where;
  where.m_start = linemap_position_for_column (line_table, 12);
  where.m_finish = linemap_position_for_column (line_table, 17);
  richloc.add_fixit_replace (where, "color");

  /* Escape fname.  */
  pretty_printer tmp_pp;
  print_escaped_string (&tmp_pp, fname);
  char *escaped_fname = xstrdup (pp_formatted_text (&tmp_pp));

  const int buf_len = strlen (escaped_fname) + 100;
  char *const expected = XNEWVEC (char, buf_len);

  {
    pretty_printer pp;
    print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE,
			    tabstop);
    snprintf (expected, buf_len,
	      "fix-it:%s:{1:12-1:18}:\"color\"\n", escaped_fname);
    ASSERT_STREQ (expected, pp_formatted_text (&pp));
  }
  {
    pretty_printer pp;
    print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
			    tabstop);
    snprintf (expected, buf_len,
	      "fix-it:%s:{1:10-1:16}:\"color\"\n", escaped_fname);
    ASSERT_STREQ (expected, pp_formatted_text (&pp));
  }

  XDELETEVEC (expected);
  free (escaped_fname);
}

/* Verify that
     diagnostic_get_location_text (..., SHOW_COLUMN)
   generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
   colorization disabled.  */

static void
assert_location_text (const char *expected_loc_text,
		      const char *filename, int line, int column,
		      bool show_column,
		      int origin = 1,
		      enum diagnostics_column_unit column_unit
			= DIAGNOSTICS_COLUMN_UNIT_BYTE)
{
  test_diagnostic_context dc;
  dc.show_column = show_column;
  dc.column_unit = column_unit;
  dc.column_origin = origin;

  expanded_location xloc;
  xloc.file = filename;
  xloc.line = line;
  xloc.column = column;
  xloc.data = NULL;
  xloc.sysp = false;

  char *actual_loc_text = diagnostic_get_location_text (&dc, xloc);
  ASSERT_STREQ (expected_loc_text, actual_loc_text);
  free (actual_loc_text);
}

/* Verify that diagnostic_get_location_text works as expected.  */

static void
test_diagnostic_get_location_text ()
{
  const char *old_progname = progname;
  progname = "PROGNAME";
  assert_location_text ("PROGNAME:", NULL, 0, 0, true);
  assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
  assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
  assert_location_text ("foo.c:42:9:", "foo.c", 42, 10, true, 0);
  assert_location_text ("foo.c:42:1010:", "foo.c", 42, 10, true, 1001);
  for (int origin = 0; origin != 2; ++origin)
    assert_location_text ("foo.c:42:", "foo.c", 42, 0, true, origin);
  assert_location_text ("foo.c:", "foo.c", 0, 10, true);
  assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
  assert_location_text ("foo.c:", "foo.c", 0, 10, false);

  maybe_line_and_column (INT_MAX, INT_MAX);
  maybe_line_and_column (INT_MIN, INT_MIN);

  {
    /* In order to test display columns vs byte columns, we need to create a
       file for location_get_source_line() to read.  */

    const char *const content = "smile \xf0\x9f\x98\x82\n";
    const int line_bytes = strlen (content) - 1;
    const int def_tabstop = 8;
    const cpp_char_column_policy policy (def_tabstop, cpp_wcwidth);
    const int display_width = cpp_display_width (content, line_bytes, policy);
    ASSERT_EQ (line_bytes - 2, display_width);
    temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
    const char *const fname = tmp.get_filename ();
    const int buf_len = strlen (fname) + 16;
    char *const expected = XNEWVEC (char, buf_len);

    snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes);
    assert_location_text (expected, fname, 1, line_bytes, true,
			  1, DIAGNOSTICS_COLUMN_UNIT_BYTE);

    snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes - 1);
    assert_location_text (expected, fname, 1, line_bytes, true,
			  0, DIAGNOSTICS_COLUMN_UNIT_BYTE);

    snprintf (expected, buf_len, "%s:1:%d:", fname, display_width);
    assert_location_text (expected, fname, 1, line_bytes, true,
			  1, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);

    snprintf (expected, buf_len, "%s:1:%d:", fname, display_width - 1);
    assert_location_text (expected, fname, 1, line_bytes, true,
			  0, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);

    XDELETEVEC (expected);
  }


  progname = old_progname;
}

/* Selftest for num_digits.  */

static void
test_num_digits ()
{
  ASSERT_EQ (1, num_digits (0));
  ASSERT_EQ (1, num_digits (9));
  ASSERT_EQ (2, num_digits (10));
  ASSERT_EQ (2, num_digits (99));
  ASSERT_EQ (3, num_digits (100));
  ASSERT_EQ (3, num_digits (999));
  ASSERT_EQ (4, num_digits (1000));
  ASSERT_EQ (4, num_digits (9999));
  ASSERT_EQ (5, num_digits (10000));
  ASSERT_EQ (5, num_digits (99999));
  ASSERT_EQ (6, num_digits (100000));
  ASSERT_EQ (6, num_digits (999999));
  ASSERT_EQ (7, num_digits (1000000));
  ASSERT_EQ (7, num_digits (9999999));
  ASSERT_EQ (8, num_digits (10000000));
  ASSERT_EQ (8, num_digits (99999999));
}

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

void
c_diagnostic_cc_tests ()
{
  test_print_escaped_string ();
  test_print_parseable_fixits_none ();
  test_print_parseable_fixits_insert ();
  test_print_parseable_fixits_remove ();
  test_print_parseable_fixits_replace ();
  test_print_parseable_fixits_bytes_vs_display_columns ();
  test_diagnostic_get_location_text ();
  test_num_digits ();

}

} // namespace selftest

#endif /* #if CHECKING_P */

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