/* Dump infrastructure for optimizations and intermediate representation.
   Copyright (C) 2012-2019 Free Software Foundation, Inc.

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 "options.h"
#include "tree.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "dumpfile.h"
#include "context.h"
#include "profile-count.h"
#include "tree-cfg.h"
#include "langhooks.h"
#include "backend.h" /* for gimple.h.  */
#include "gimple.h" /* for dump_user_location_t ctor.  */
#include "rtl.h" /* for dump_user_location_t ctor.  */
#include "selftest.h"
#include "optinfo.h"
#include "dump-context.h"
#include "cgraph.h"
#include "tree-pass.h" /* for "current_pass".  */
#include "optinfo-emit-json.h"
#include "stringpool.h" /* for get_identifier.  */

/* If non-NULL, return one past-the-end of the matching SUBPART of
   the WHOLE string.  */
#define skip_leading_substring(whole,  part) \
   (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))

static dump_flags_t pflags;		      /* current dump_flags */

static void dump_loc (dump_flags_t, FILE *, location_t);

/* Current -fopt-info output stream, if any, and flags.  */
static FILE *alt_dump_file = NULL;
static dump_flags_t alt_flags;

static FILE *dump_open_alternate_stream (struct dump_file_info *);

/* These are currently used for communicating between passes.
   However, instead of accessing them directly, the passes can use
   dump_printf () for dumps.  */
FILE *dump_file = NULL;
const char *dump_file_name;
dump_flags_t dump_flags;
bool dumps_are_enabled = false;


/* Set global "dump_file" to NEW_DUMP_FILE, refreshing the "dumps_are_enabled"
   global.  */

void
set_dump_file (FILE *new_dump_file)
{
  dumpfile_ensure_any_optinfo_are_flushed ();
  dump_file = new_dump_file;
  dump_context::get ().refresh_dumps_are_enabled ();
}

/* Set "alt_dump_file" to NEW_ALT_DUMP_FILE, refreshing the "dumps_are_enabled"
   global.  */

static void
set_alt_dump_file (FILE *new_alt_dump_file)
{
  dumpfile_ensure_any_optinfo_are_flushed ();
  alt_dump_file = new_alt_dump_file;
  dump_context::get ().refresh_dumps_are_enabled ();
}

#define DUMP_FILE_INFO(suffix, swtch, dkind, num) \
  {suffix, swtch, NULL, NULL, NULL, NULL, NULL, dkind, TDF_NONE, TDF_NONE, \
   OPTGROUP_NONE, 0, 0, num, false, false}

/* Table of tree dump switches. This must be consistent with the
   TREE_DUMP_INDEX enumeration in dumpfile.h.  */
static struct dump_file_info dump_files[TDI_end] =
{
  DUMP_FILE_INFO (NULL, NULL, DK_none, 0),
  DUMP_FILE_INFO (".cgraph", "ipa-cgraph", DK_ipa, 0),
  DUMP_FILE_INFO (".type-inheritance", "ipa-type-inheritance", DK_ipa, 0),
  DUMP_FILE_INFO (".ipa-clones", "ipa-clones", DK_ipa, 0),
  DUMP_FILE_INFO (".original", "tree-original", DK_tree, 0),
  DUMP_FILE_INFO (".gimple", "tree-gimple", DK_tree, 0),
  DUMP_FILE_INFO (".nested", "tree-nested", DK_tree, 0),
  DUMP_FILE_INFO (".lto-stream-out", "ipa-lto-stream-out", DK_ipa, 0),
#define FIRST_AUTO_NUMBERED_DUMP 1
#define FIRST_ME_AUTO_NUMBERED_DUMP 4

  DUMP_FILE_INFO (NULL, "lang-all", DK_lang, 0),
  DUMP_FILE_INFO (NULL, "tree-all", DK_tree, 0),
  DUMP_FILE_INFO (NULL, "rtl-all", DK_rtl, 0),
  DUMP_FILE_INFO (NULL, "ipa-all", DK_ipa, 0),
};

/* Table of dump options. This must be consistent with the TDF_* flags
   in dumpfile.h and opt_info_options below. */
static const kv_pair<dump_flags_t> dump_options[] =
{
  {"address", TDF_ADDRESS},
  {"asmname", TDF_ASMNAME},
  {"slim", TDF_SLIM},
  {"raw", TDF_RAW},
  {"graph", TDF_GRAPH},
  {"details", (TDF_DETAILS | MSG_OPTIMIZED_LOCATIONS
               | MSG_MISSED_OPTIMIZATION
               | MSG_NOTE)},
  {"cselib", TDF_CSELIB},
  {"stats", TDF_STATS},
  {"blocks", TDF_BLOCKS},
  {"vops", TDF_VOPS},
  {"lineno", TDF_LINENO},
  {"uid", TDF_UID},
  {"stmtaddr", TDF_STMTADDR},
  {"memsyms", TDF_MEMSYMS},
  {"eh", TDF_EH},
  {"alias", TDF_ALIAS},
  {"nouid", TDF_NOUID},
  {"enumerate_locals", TDF_ENUMERATE_LOCALS},
  {"scev", TDF_SCEV},
  {"gimple", TDF_GIMPLE},
  {"folding", TDF_FOLDING},
  {"optimized", MSG_OPTIMIZED_LOCATIONS},
  {"missed", MSG_MISSED_OPTIMIZATION},
  {"note", MSG_NOTE},
  {"optall", MSG_ALL_KINDS},
  {"all", dump_flags_t (TDF_ALL_VALUES
			& ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_GRAPH
			    | TDF_STMTADDR | TDF_RHS_ONLY | TDF_NOUID
			    | TDF_ENUMERATE_LOCALS | TDF_SCEV | TDF_GIMPLE))},
  {NULL, TDF_NONE}
};

/* A subset of the dump_options table which is used for -fopt-info
   types. This must be consistent with the MSG_* flags in dumpfile.h.
 */
static const kv_pair<dump_flags_t> optinfo_verbosity_options[] =
{
  {"optimized", MSG_OPTIMIZED_LOCATIONS},
  {"missed", MSG_MISSED_OPTIMIZATION},
  {"note", MSG_NOTE},
  {"all", MSG_ALL_KINDS},
  {"internals", MSG_PRIORITY_INTERNALS},
  {NULL, TDF_NONE}
};

/* Flags used for -fopt-info groups.  */
const kv_pair<optgroup_flags_t> optgroup_options[] =
{
  {"ipa", OPTGROUP_IPA},
  {"loop", OPTGROUP_LOOP},
  {"inline", OPTGROUP_INLINE},
  {"omp", OPTGROUP_OMP},
  {"vec", OPTGROUP_VEC},
  {"optall", OPTGROUP_ALL},
  {NULL, OPTGROUP_NONE}
};

gcc::dump_manager::dump_manager ():
  m_next_dump (FIRST_AUTO_NUMBERED_DUMP),
  m_extra_dump_files (NULL),
  m_extra_dump_files_in_use (0),
  m_extra_dump_files_alloced (0),
  m_optgroup_flags (OPTGROUP_NONE),
  m_optinfo_flags (TDF_NONE),
  m_optinfo_filename (NULL)
{
}

gcc::dump_manager::~dump_manager ()
{
  free (m_optinfo_filename);
  for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
    {
      dump_file_info *dfi = &m_extra_dump_files[i];
      /* suffix, swtch, glob are statically allocated for the entries
	 in dump_files, and for statistics, but are dynamically allocated
	 for those for passes.  */
      if (dfi->owns_strings)
	{
	  XDELETEVEC (const_cast <char *> (dfi->suffix));
	  XDELETEVEC (const_cast <char *> (dfi->swtch));
	  XDELETEVEC (const_cast <char *> (dfi->glob));
	}
      /* These, if non-NULL, are always dynamically allocated.  */
      XDELETEVEC (const_cast <char *> (dfi->pfilename));
      XDELETEVEC (const_cast <char *> (dfi->alt_filename));
    }
  XDELETEVEC (m_extra_dump_files);
}

unsigned int
gcc::dump_manager::
dump_register (const char *suffix, const char *swtch, const char *glob,
	       dump_kind dkind, optgroup_flags_t optgroup_flags,
	       bool take_ownership)
{
  int num = m_next_dump++;

  size_t count = m_extra_dump_files_in_use++;

  if (count >= m_extra_dump_files_alloced)
    {
      if (m_extra_dump_files_alloced == 0)
	m_extra_dump_files_alloced = 512;
      else
	m_extra_dump_files_alloced *= 2;
      m_extra_dump_files = XRESIZEVEC (struct dump_file_info,
				       m_extra_dump_files,
				       m_extra_dump_files_alloced);

      /* Construct a new object in the space allocated above.  */
      new (m_extra_dump_files + count) dump_file_info ();
    }
  else
    {
      /* Zero out the already constructed object.  */
      m_extra_dump_files[count] = dump_file_info ();
    }

  m_extra_dump_files[count].suffix = suffix;
  m_extra_dump_files[count].swtch = swtch;
  m_extra_dump_files[count].glob = glob;
  m_extra_dump_files[count].dkind = dkind;
  m_extra_dump_files[count].optgroup_flags = optgroup_flags;
  m_extra_dump_files[count].num = num;
  m_extra_dump_files[count].owns_strings = take_ownership;

  return count + TDI_end;
}


/* Allow languages and middle-end to register their dumps before the
   optimization passes.  */

void
gcc::dump_manager::
register_dumps ()
{
  lang_hooks.register_dumps (this);
  /* If this assert fails, some FE registered more than
     FIRST_ME_AUTO_NUMBERED_DUMP - FIRST_AUTO_NUMBERED_DUMP
     dump files.  Bump FIRST_ME_AUTO_NUMBERED_DUMP accordingly.  */
  gcc_assert (m_next_dump <= FIRST_ME_AUTO_NUMBERED_DUMP);
  m_next_dump = FIRST_ME_AUTO_NUMBERED_DUMP;
  dump_files[TDI_original].num = m_next_dump++;
  dump_files[TDI_gimple].num = m_next_dump++;
  dump_files[TDI_nested].num = m_next_dump++;
}


/* Return the dump_file_info for the given phase.  */

struct dump_file_info *
gcc::dump_manager::
get_dump_file_info (int phase) const
{
  if (phase < TDI_end)
    return &dump_files[phase];
  else if ((size_t) (phase - TDI_end) >= m_extra_dump_files_in_use)
    return NULL;
  else
    return m_extra_dump_files + (phase - TDI_end);
}

/* Locate the dump_file_info with swtch equal to SWTCH,
   or return NULL if no such dump_file_info exists.  */

struct dump_file_info *
gcc::dump_manager::
get_dump_file_info_by_switch (const char *swtch) const
{
  for (unsigned i = 0; i < m_extra_dump_files_in_use; i++)
    if (strcmp (m_extra_dump_files[i].swtch, swtch) == 0)
      return &m_extra_dump_files[i];

  /* Not found.  */
  return NULL;
}


/* Return the name of the dump file for the given phase.
   The caller is responsible for calling free on the returned
   buffer.
   If the dump is not enabled, returns NULL.  */

char *
gcc::dump_manager::
get_dump_file_name (int phase, int part) const
{
  struct dump_file_info *dfi;

  if (phase == TDI_none)
    return NULL;

  dfi = get_dump_file_info (phase);

  return get_dump_file_name (dfi, part);
}

/* Return the name of the dump file for the given dump_file_info.
   The caller is responsible for calling free on the returned
   buffer.
   If the dump is not enabled, returns NULL.  */

char *
gcc::dump_manager::
get_dump_file_name (struct dump_file_info *dfi, int part) const
{
  char dump_id[10];

  gcc_assert (dfi);

  if (dfi->pstate == 0)
    return NULL;

  /* If available, use the command line dump filename. */
  if (dfi->pfilename)
    return xstrdup (dfi->pfilename);

  if (dfi->num < 0)
    dump_id[0] = '\0';
  else
    {
      /* (null), LANG, TREE, RTL, IPA.  */
      char suffix = " ltri"[dfi->dkind];
      
      if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
	dump_id[0] = '\0';
    }

  if (part != -1)
    {
       char part_id[8];
       snprintf (part_id, sizeof (part_id), ".%i", part);
       return concat (dump_base_name, dump_id, part_id, dfi->suffix, NULL);
    }
  else
    return concat (dump_base_name, dump_id, dfi->suffix, NULL);
}

/* Open a dump file called FILENAME.  Some filenames are special and
   refer to the standard streams.  TRUNC indicates whether this is the
   first open (so the file should be truncated, rather than appended).
   An error message is emitted in the event of failure.  */

static FILE *
dump_open (const char *filename, bool trunc)
{
  if (strcmp ("stderr", filename) == 0)
    return stderr;

  if (strcmp ("stdout", filename) == 0
      || strcmp ("-", filename) == 0)
    return stdout;

  FILE *stream = fopen (filename, trunc ? "w" : "a");

  if (!stream)
    error ("could not open dump file %qs: %m", filename);
  return stream;
}

/* For a given DFI, open an alternate dump filename (which could also
   be a standard stream such as stdout/stderr). If the alternate dump
   file cannot be opened, return NULL.  */

static FILE *
dump_open_alternate_stream (struct dump_file_info *dfi)
{
  if (!dfi->alt_filename)
    return NULL;

  if (dfi->alt_stream)
    return dfi->alt_stream;

  FILE *stream = dump_open (dfi->alt_filename, dfi->alt_state < 0);

  if (stream)
    dfi->alt_state = 1;

  return stream;
}

/* Construct a dump_user_location_t from STMT (using its location and
   hotness).  */

dump_user_location_t::dump_user_location_t (const gimple *stmt)
: m_count (), m_loc (UNKNOWN_LOCATION)
{
  if (stmt)
    {
      if (stmt->bb)
	m_count = stmt->bb->count;
      m_loc = gimple_location (stmt);
    }
}

/* Construct a dump_user_location_t from an RTL instruction (using its
   location and hotness).  */

dump_user_location_t::dump_user_location_t (const rtx_insn *insn)
: m_count (), m_loc (UNKNOWN_LOCATION)
{
  if (insn)
    {
      basic_block bb = BLOCK_FOR_INSN (insn);
      if (bb)
	m_count = bb->count;
      m_loc = INSN_LOCATION (insn);
    }
}

/* Construct from a function declaration.  This one requires spelling out
   to avoid accidentally constructing from other kinds of tree.  */

dump_user_location_t
dump_user_location_t::from_function_decl (tree fndecl)
{
  gcc_assert (fndecl);

  // FIXME: profile count for function?
  return dump_user_location_t (profile_count (),
			       DECL_SOURCE_LOCATION (fndecl));
}

/* Extract the MSG_* component from DUMP_KIND and return a string for use
   as a prefix to dump messages.
   These match the strings in optinfo_verbosity_options and thus the
   "OPTIONS" within "-fopt-info-OPTIONS".  */

static const char *
kind_as_string (dump_flags_t dump_kind)
{
  switch (dump_kind & MSG_ALL_KINDS)
    {
    default:
      gcc_unreachable ();
    case MSG_OPTIMIZED_LOCATIONS:
      return "optimized";
    case MSG_MISSED_OPTIMIZATION:
      return "missed";
    case MSG_NOTE:
      return "note";
    }
}

/* Print source location on DFILE if enabled.  */

static void
dump_loc (dump_flags_t dump_kind, FILE *dfile, location_t loc)
{
  if (dump_kind)
    {
      if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
        fprintf (dfile, "%s:%d:%d: ", LOCATION_FILE (loc),
                 LOCATION_LINE (loc), LOCATION_COLUMN (loc));
      else if (current_function_decl)
        fprintf (dfile, "%s:%d:%d: ",
                 DECL_SOURCE_FILE (current_function_decl),
                 DECL_SOURCE_LINE (current_function_decl),
                 DECL_SOURCE_COLUMN (current_function_decl));
      fprintf (dfile, "%s: ", kind_as_string (dump_kind));
      /* Indentation based on scope depth.  */
      fprintf (dfile, "%*s", get_dump_scope_depth (), "");
    }
}

/* Print source location to PP if enabled.  */

static void
dump_loc (dump_flags_t dump_kind, pretty_printer *pp, location_t loc)
{
  if (dump_kind)
    {
      if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
	pp_printf (pp, "%s:%d:%d: ", LOCATION_FILE (loc),
		   LOCATION_LINE (loc), LOCATION_COLUMN (loc));
      else if (current_function_decl)
	pp_printf (pp, "%s:%d:%d: ",
		   DECL_SOURCE_FILE (current_function_decl),
		   DECL_SOURCE_LINE (current_function_decl),
		   DECL_SOURCE_COLUMN (current_function_decl));
      pp_printf (pp, "%s: ", kind_as_string (dump_kind));
      /* Indentation based on scope depth.  */
      for (unsigned i = 0; i < get_dump_scope_depth (); i++)
	pp_character (pp, ' ');
    }
}

/* Implementation of dump_context member functions.  */

/* dump_context's dtor.  */

dump_context::~dump_context ()
{
  delete m_pending;
}

void
dump_context::set_json_writer (optrecord_json_writer *writer)
{
  delete m_json_writer;
  m_json_writer = writer;
}

/* Perform cleanup activity for -fsave-optimization-record.
   Currently, the file is written out here in one go, before cleaning
   up.  */

void
dump_context::finish_any_json_writer ()
{
  if (!m_json_writer)
    return;

  m_json_writer->write ();
  delete m_json_writer;
  m_json_writer = NULL;
}

/* Update the "dumps_are_enabled" global; to be called whenever dump_file
   or alt_dump_file change, or when changing dump_context in selftests.  */

void
dump_context::refresh_dumps_are_enabled ()
{
  dumps_are_enabled = (dump_file || alt_dump_file || optinfo_enabled_p ()
		       || m_test_pp);
}

/* Determine if a message of kind DUMP_KIND and at the current scope depth
   should be printed.

   Only show messages that match FILTER both on their kind *and*
   their priority.  */

bool
dump_context::apply_dump_filter_p (dump_flags_t dump_kind,
				   dump_flags_t filter) const
{
  /* Few messages, if any, have an explicit MSG_PRIORITY.
     If DUMP_KIND does, we'll use it.
     Otherwise, generate an implicit priority value for the message based
     on the current scope depth.
     Messages at the top-level scope are MSG_PRIORITY_USER_FACING,
     whereas those in nested scopes are MSG_PRIORITY_INTERNALS.  */
  if (!(dump_kind & MSG_ALL_PRIORITIES))
    {
      dump_flags_t implicit_priority
	=  (m_scope_depth > 0
	    ? MSG_PRIORITY_INTERNALS
	    : MSG_PRIORITY_USER_FACING);
      dump_kind |= implicit_priority;
    }

  return (dump_kind & (filter & MSG_ALL_KINDS)
	  && dump_kind & (filter & MSG_ALL_PRIORITIES));
}

/* Print LOC to the appropriate dump destinations, given DUMP_KIND.
   If optinfos are enabled, begin a new optinfo.  */

void
dump_context::dump_loc (const dump_metadata_t &metadata,
			const dump_user_location_t &loc)
{
  end_any_optinfo ();

  dump_loc_immediate (metadata.get_dump_flags (), loc);

  if (optinfo_enabled_p ())
    begin_next_optinfo (metadata, loc);
}

/* As dump_loc above, but without starting a new optinfo. */

void
dump_context::dump_loc_immediate (dump_flags_t dump_kind,
				  const dump_user_location_t &loc)
{
  location_t srcloc = loc.get_location_t ();

  if (dump_file && apply_dump_filter_p (dump_kind, pflags))
    ::dump_loc (dump_kind, dump_file, srcloc);

  if (alt_dump_file && apply_dump_filter_p (dump_kind, alt_flags))
    ::dump_loc (dump_kind, alt_dump_file, srcloc);

  /* Support for temp_dump_context in selftests.  */
  if (m_test_pp && apply_dump_filter_p (dump_kind, m_test_pp_flags))
    ::dump_loc (dump_kind, m_test_pp, srcloc);
}

/* Make an item for the given dump call, equivalent to print_gimple_stmt.  */

static optinfo_item *
make_item_for_dump_gimple_stmt (gimple *stmt, int spc, dump_flags_t dump_flags)
{
  pretty_printer pp;
  pp_needs_newline (&pp) = true;
  pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);
  pp_newline (&pp);

  optinfo_item *item
    = new optinfo_item (OPTINFO_ITEM_KIND_GIMPLE, gimple_location (stmt),
			xstrdup (pp_formatted_text (&pp)));
  return item;
}

/* Dump gimple statement GS with SPC indentation spaces and
   EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.  */

void
dump_context::dump_gimple_stmt (const dump_metadata_t &metadata,
				dump_flags_t extra_dump_flags,
				gimple *gs, int spc)
{
  optinfo_item *item
    = make_item_for_dump_gimple_stmt (gs, spc, dump_flags | extra_dump_flags);
  emit_item (item, metadata.get_dump_flags ());

  if (optinfo_enabled_p ())
    {
      optinfo &info = ensure_pending_optinfo (metadata);
      info.add_item (item);
    }
  else
    delete item;
}

/* Similar to dump_gimple_stmt, except additionally print source location.  */

void
dump_context::dump_gimple_stmt_loc (const dump_metadata_t &metadata,
				    const dump_user_location_t &loc,
				    dump_flags_t extra_dump_flags,
				    gimple *gs, int spc)
{
  dump_loc (metadata, loc);
  dump_gimple_stmt (metadata, extra_dump_flags, gs, spc);
}

/* Make an item for the given dump call, equivalent to print_gimple_expr.  */

static optinfo_item *
make_item_for_dump_gimple_expr (gimple *stmt, int spc, dump_flags_t dump_flags)
{
  dump_flags |= TDF_RHS_ONLY;
  pretty_printer pp;
  pp_needs_newline (&pp) = true;
  pp_gimple_stmt_1 (&pp, stmt, spc, dump_flags);

  optinfo_item *item
    = new optinfo_item (OPTINFO_ITEM_KIND_GIMPLE, gimple_location (stmt),
			xstrdup (pp_formatted_text (&pp)));
  return item;
}

/* Dump gimple statement GS with SPC indentation spaces and
   EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.
   Do not terminate with a newline or semicolon.  */

void
dump_context::dump_gimple_expr (const dump_metadata_t &metadata,
				dump_flags_t extra_dump_flags,
				gimple *gs, int spc)
{
  optinfo_item *item
    = make_item_for_dump_gimple_expr (gs, spc, dump_flags | extra_dump_flags);
  emit_item (item, metadata.get_dump_flags ());

  if (optinfo_enabled_p ())
    {
      optinfo &info = ensure_pending_optinfo (metadata);
      info.add_item (item);
    }
  else
    delete item;
}

/* Similar to dump_gimple_expr, except additionally print source location.  */

void
dump_context::dump_gimple_expr_loc (const dump_metadata_t &metadata,
				    const dump_user_location_t &loc,
				    dump_flags_t extra_dump_flags,
				    gimple *gs,
				    int spc)
{
  dump_loc (metadata, loc);
  dump_gimple_expr (metadata, extra_dump_flags, gs, spc);
}

/* Make an item for the given dump call, equivalent to print_generic_expr.  */

static optinfo_item *
make_item_for_dump_generic_expr (tree node, dump_flags_t dump_flags)
{
  pretty_printer pp;
  pp_needs_newline (&pp) = true;
  pp_translate_identifiers (&pp) = false;
  dump_generic_node (&pp, node, 0, dump_flags, false);

  location_t loc = UNKNOWN_LOCATION;
  if (EXPR_HAS_LOCATION (node))
    loc = EXPR_LOCATION (node);

  optinfo_item *item
    = new optinfo_item (OPTINFO_ITEM_KIND_TREE, loc,
			xstrdup (pp_formatted_text (&pp)));
  return item;
}

/* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
   DUMP_KIND is enabled.  */

void
dump_context::dump_generic_expr (const dump_metadata_t &metadata,
				 dump_flags_t extra_dump_flags,
				 tree t)
{
  optinfo_item *item
    = make_item_for_dump_generic_expr (t, dump_flags | extra_dump_flags);
  emit_item (item, metadata.get_dump_flags ());

  if (optinfo_enabled_p ())
    {
      optinfo &info = ensure_pending_optinfo (metadata);
      info.add_item (item);
    }
  else
    delete item;
}


/* Similar to dump_generic_expr, except additionally print the source
   location.  */

void
dump_context::dump_generic_expr_loc (const dump_metadata_t &metadata,
				     const dump_user_location_t &loc,
				     dump_flags_t extra_dump_flags,
				     tree t)
{
  dump_loc (metadata, loc);
  dump_generic_expr (metadata, extra_dump_flags, t);
}

/* Make an item for the given dump call.  */

static optinfo_item *
make_item_for_dump_symtab_node (symtab_node *node)
{
  location_t loc = DECL_SOURCE_LOCATION (node->decl);
  optinfo_item *item
    = new optinfo_item (OPTINFO_ITEM_KIND_SYMTAB_NODE, loc,
			xstrdup (node->dump_name ()));
  return item;
}

/* dump_pretty_printer's ctor.  */

dump_pretty_printer::dump_pretty_printer (dump_context *context,
					  dump_flags_t dump_kind)
: pretty_printer (), m_context (context), m_dump_kind (dump_kind),
  m_stashed_items ()
{
  pp_format_decoder (this) = format_decoder_cb;
}

/* Phase 3 of formatting; compare with pp_output_formatted_text.

   Emit optinfo_item instances for the various formatted chunks from phases
   1 and 2 (i.e. pp_format).

   Some chunks may already have had their items built (during decode_format).
   These chunks have been stashed into m_stashed_items; we emit them here.

   For all other purely textual chunks, they are printed into
   buffer->formatted_obstack, and then emitted as a textual optinfo_item.
   This consolidates multiple adjacent text chunks into a single text
   optinfo_item.  */

void
dump_pretty_printer::emit_items (optinfo *dest)
{
  output_buffer *buffer = pp_buffer (this);
  struct chunk_info *chunk_array = buffer->cur_chunk_array;
  const char **args = chunk_array->args;

  gcc_assert (buffer->obstack == &buffer->formatted_obstack);
  gcc_assert (buffer->line_length == 0);

  unsigned stashed_item_idx = 0;
  for (unsigned chunk = 0; args[chunk]; chunk++)
    {
      if (stashed_item_idx < m_stashed_items.length ()
	  && args[chunk] == *m_stashed_items[stashed_item_idx].buffer_ptr)
	{
	  emit_any_pending_textual_chunks (dest);
	  /* This chunk has a stashed item: use it.  */
	  emit_item (m_stashed_items[stashed_item_idx++].item, dest);
	}
      else
	/* This chunk is purely textual.  Print it (to
	   buffer->formatted_obstack), so that we can consolidate adjacent
	   chunks into one textual optinfo_item.  */
	pp_string (this, args[chunk]);
    }

  emit_any_pending_textual_chunks (dest);

  /* Ensure that we consumed all of stashed_items.  */
  gcc_assert (stashed_item_idx == m_stashed_items.length ());

  /* Deallocate the chunk structure and everything after it (i.e. the
     associated series of formatted strings).  */
  buffer->cur_chunk_array = chunk_array->prev;
  obstack_free (&buffer->chunk_obstack, chunk_array);
}

/* Subroutine of dump_pretty_printer::emit_items
   for consolidating multiple adjacent pure-text chunks into single
   optinfo_items (in phase 3).  */

void
dump_pretty_printer::emit_any_pending_textual_chunks (optinfo *dest)
{
  gcc_assert (buffer->obstack == &buffer->formatted_obstack);

  /* Don't emit an item if the pending text is empty.  */
  if (output_buffer_last_position_in_text (buffer) == NULL)
    return;

  char *formatted_text = xstrdup (pp_formatted_text (this));
  optinfo_item *item
    = new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
			formatted_text);
  emit_item (item, dest);

  /* Clear the pending text by unwinding formatted_text back to the start
     of the buffer (without deallocating).  */
  obstack_free (&buffer->formatted_obstack,
		buffer->formatted_obstack.object_base);
}

/* Emit ITEM and take ownership of it.  If DEST is non-NULL, add ITEM
   to DEST; otherwise delete ITEM.  */

void
dump_pretty_printer::emit_item (optinfo_item *item, optinfo *dest)
{
  m_context->emit_item (item, m_dump_kind);
  if (dest)
    dest->add_item (item);
  else
    delete item;
}

/* Record that ITEM (generated in phase 2 of formatting) is to be used for
   the chunk at BUFFER_PTR in phase 3 (by emit_items).  */

void
dump_pretty_printer::stash_item (const char **buffer_ptr, optinfo_item *item)
{
  gcc_assert (buffer_ptr);
  gcc_assert (item);

  m_stashed_items.safe_push (stashed_item (buffer_ptr, item));
}

/* pp_format_decoder callback for dump_pretty_printer, and thus for
   dump_printf and dump_printf_loc.

   A wrapper around decode_format, for type-safety.  */

bool
dump_pretty_printer::format_decoder_cb (pretty_printer *pp, text_info *text,
					const char *spec, int /*precision*/,
					bool /*wide*/, bool /*set_locus*/,
					bool /*verbose*/, bool */*quoted*/,
					const char **buffer_ptr)
{
  dump_pretty_printer *opp = static_cast <dump_pretty_printer *> (pp);
  return opp->decode_format (text, spec, buffer_ptr);
}

/* Format decoder for dump_pretty_printer, and thus for dump_printf and
   dump_printf_loc.

   Supported format codes (in addition to the standard pretty_printer ones)
   are:

   %C: cgraph_node *:
       Equivalent to: dump_symtab_node (MSG_*, node)
   %E: gimple *:
       Equivalent to: dump_gimple_expr (MSG_*, TDF_SLIM, stmt, 0)
   %G: gimple *:
       Equivalent to: dump_gimple_stmt (MSG_*, TDF_SLIM, stmt, 0)
   %T: tree:
       Equivalent to: dump_generic_expr (MSG_*, arg, TDF_SLIM).

   TODO: add a format code that can handle (symtab_node*) *and* both
   subclasses (presumably means teaching -Wformat about non-virtual
   subclasses).

   These format codes build optinfo_item instances, thus capturing metadata
   about the arguments being dumped, as well as the textual output.  */

bool
dump_pretty_printer::decode_format (text_info *text, const char *spec,
				       const char **buffer_ptr)
{
  /* Various format codes that imply making an optinfo_item and stashed it
     for later use (to capture metadata, rather than plain text).  */
  switch (*spec)
    {
    case 'C':
      {
	cgraph_node *node = va_arg (*text->args_ptr, cgraph_node *);

	/* Make an item for the node, and stash it.  */
	optinfo_item *item = make_item_for_dump_symtab_node (node);
	stash_item (buffer_ptr, item);
	return true;
      }

    case 'E':
      {
	gimple *stmt = va_arg (*text->args_ptr, gimple *);

	/* Make an item for the stmt, and stash it.  */
	optinfo_item *item = make_item_for_dump_gimple_expr (stmt, 0, TDF_SLIM);
	stash_item (buffer_ptr, item);
	return true;
      }

    case 'G':
      {
	gimple *stmt = va_arg (*text->args_ptr, gimple *);

	/* Make an item for the stmt, and stash it.  */
	optinfo_item *item = make_item_for_dump_gimple_stmt (stmt, 0, TDF_SLIM);
	stash_item (buffer_ptr, item);
	return true;
      }

    case 'T':
      {
	tree t = va_arg (*text->args_ptr, tree);

	/* Make an item for the tree, and stash it.  */
	optinfo_item *item = make_item_for_dump_generic_expr (t, TDF_SLIM);
	stash_item (buffer_ptr, item);
	return true;
      }

    default:
      return false;
    }
}

/* Output a formatted message using FORMAT on appropriate dump streams.  */

void
dump_context::dump_printf_va (const dump_metadata_t &metadata, const char *format,
			      va_list *ap)
{
  dump_pretty_printer pp (this, metadata.get_dump_flags ());

  text_info text;
  text.err_no = errno;
  text.args_ptr = ap;
  text.format_spec = format;

  /* Phases 1 and 2, using pp_format.  */
  pp_format (&pp, &text);

  /* Phase 3.  */
  if (optinfo_enabled_p ())
    {
      optinfo &info = ensure_pending_optinfo (metadata);
      pp.emit_items (&info);
    }
  else
    pp.emit_items (NULL);
}

/* Similar to dump_printf, except source location is also printed, and
   dump location captured.  */

void
dump_context::dump_printf_loc_va (const dump_metadata_t &metadata,
				  const dump_user_location_t &loc,
				  const char *format, va_list *ap)
{
  dump_loc (metadata, loc);
  dump_printf_va (metadata, format, ap);
}

/* Make an item for the given dump call, equivalent to print_dec.  */

template<unsigned int N, typename C>
static optinfo_item *
make_item_for_dump_dec (const poly_int<N, C> &value)
{
  STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
  signop sgn = poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED;

  pretty_printer pp;

  if (value.is_constant ())
    pp_wide_int (&pp, value.coeffs[0], sgn);
  else
    {
      pp_character (&pp, '[');
      for (unsigned int i = 0; i < N; ++i)
	{
	  pp_wide_int (&pp, value.coeffs[i], sgn);
	  pp_character (&pp, i == N - 1 ? ']' : ',');
	}
    }

  optinfo_item *item
    = new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
			xstrdup (pp_formatted_text (&pp)));
  return item;
}

/* Output VALUE in decimal to appropriate dump streams.  */

template<unsigned int N, typename C>
void
dump_context::dump_dec (const dump_metadata_t &metadata, const poly_int<N, C> &value)
{
  optinfo_item *item = make_item_for_dump_dec (value);
  emit_item (item, metadata.get_dump_flags ());

  if (optinfo_enabled_p ())
    {
      optinfo &info = ensure_pending_optinfo (metadata);
      info.add_item (item);
    }
  else
    delete item;
}

/* Output the name of NODE on appropriate dump streams.  */

void
dump_context::dump_symtab_node (const dump_metadata_t &metadata, symtab_node *node)
{
  optinfo_item *item = make_item_for_dump_symtab_node (node);
  emit_item (item, metadata.get_dump_flags ());

  if (optinfo_enabled_p ())
    {
      optinfo &info = ensure_pending_optinfo (metadata);
      info.add_item (item);
    }
  else
    delete item;
}

/* Get the current dump scope-nesting depth.
   For use by -fopt-info (for showing nesting via indentation).  */

unsigned int
dump_context::get_scope_depth () const
{
  return m_scope_depth;
}

/* Push a nested dump scope.
   Increment the scope depth.
   Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
   destination, if any.
   Emit a "scope" optinfo if optinfos are enabled.  */

void
dump_context::begin_scope (const char *name,
			   const dump_user_location_t &user_location,
			   const dump_impl_location_t &impl_location)
{
  m_scope_depth++;

  location_t src_loc = user_location.get_location_t ();

  if (dump_file && apply_dump_filter_p (MSG_NOTE, pflags))
    ::dump_loc (MSG_NOTE, dump_file, src_loc);

  if (alt_dump_file && apply_dump_filter_p (MSG_NOTE, alt_flags))
    ::dump_loc (MSG_NOTE, alt_dump_file, src_loc);

  /* Support for temp_dump_context in selftests.  */
  if (m_test_pp && apply_dump_filter_p (MSG_NOTE, m_test_pp_flags))
    ::dump_loc (MSG_NOTE, m_test_pp, src_loc);

  pretty_printer pp;
  pp_printf (&pp, "=== %s ===\n", name);
  optinfo_item *item
    = new optinfo_item (OPTINFO_ITEM_KIND_TEXT, UNKNOWN_LOCATION,
			xstrdup (pp_formatted_text (&pp)));
  emit_item (item, MSG_NOTE);

  if (optinfo_enabled_p ())
    {
      optinfo &info
	= begin_next_optinfo (dump_metadata_t (MSG_NOTE, impl_location),
			      user_location);
      info.m_kind = OPTINFO_KIND_SCOPE;
      info.add_item (item);
      end_any_optinfo ();
    }
  else
    delete item;
}

/* Pop a nested dump scope.  */

void
dump_context::end_scope ()
{
  end_any_optinfo ();
  m_scope_depth--;

  if (m_json_writer)
    m_json_writer->pop_scope ();
}

/* Should optinfo instances be created?
   All creation of optinfos should be guarded by this predicate.
   Return true if any optinfo destinations are active.  */

bool
dump_context::optinfo_enabled_p () const
{
  return (optimization_records_enabled_p ());
}

/* Return the optinfo currently being accumulated, creating one if
   necessary.  */

optinfo &
dump_context::ensure_pending_optinfo (const dump_metadata_t &metadata)
{
  if (!m_pending)
    return begin_next_optinfo (metadata, dump_user_location_t ());
  return *m_pending;
}

/* Start a new optinfo and return it, ending any optinfo that was already
   accumulated.  */

optinfo &
dump_context::begin_next_optinfo (const dump_metadata_t &metadata,
				  const dump_user_location_t &user_loc)
{
  end_any_optinfo ();
  gcc_assert (m_pending == NULL);
  dump_location_t loc (user_loc, metadata.get_impl_location ());
  m_pending = new optinfo (loc, OPTINFO_KIND_NOTE, current_pass);
  m_pending->handle_dump_file_kind (metadata.get_dump_flags ());
  return *m_pending;
}

/* End any optinfo that has been accumulated within this context; emitting
   it to any destinations as appropriate, such as optimization records.  */

void
dump_context::end_any_optinfo ()
{
  if (m_pending)
    emit_optinfo (m_pending);
  delete m_pending;
  m_pending = NULL;
}

/* Emit the optinfo to all of the "non-immediate" destinations
   (emission to "immediate" destinations is done by
   dump_context::emit_item).  */

void
dump_context::emit_optinfo (const optinfo *info)
{
  /* -fsave-optimization-record.  */
  if (m_json_writer)
    m_json_writer->add_record (info);
}

/* Emit ITEM to all item destinations (those that don't require
   consolidation into optinfo instances).  */

void
dump_context::emit_item (optinfo_item *item, dump_flags_t dump_kind)
{
  if (dump_file && apply_dump_filter_p (dump_kind, pflags))
    fprintf (dump_file, "%s", item->get_text ());

  if (alt_dump_file && apply_dump_filter_p (dump_kind, alt_flags))
    fprintf (alt_dump_file, "%s", item->get_text ());

  /* Support for temp_dump_context in selftests.  */
  if (m_test_pp && apply_dump_filter_p (dump_kind, m_test_pp_flags))
    pp_string (m_test_pp, item->get_text ());
}

/* The current singleton dump_context, and its default.  */

dump_context *dump_context::s_current = &dump_context::s_default;
dump_context dump_context::s_default;

/* Implementation of dump_* API calls, calling into dump_context
   member functions.  */

/* Calls to the dump_* functions do non-trivial work, so they ought
   to be guarded by:
     if (dump_enabled_p ())
   Assert that they are guarded, and, if assertions are disabled,
   bail out if the calls weren't properly guarded.  */

#define VERIFY_DUMP_ENABLED_P \
  do {					\
    gcc_assert (dump_enabled_p ());	\
    if (!dump_enabled_p ())		\
      return;				\
  } while (0)

/* Dump gimple statement GS with SPC indentation spaces and
   EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.  */

void
dump_gimple_stmt (const dump_metadata_t &metadata, dump_flags_t extra_dump_flags,
		  gimple *gs, int spc)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_gimple_stmt (metadata, extra_dump_flags, gs, spc);
}

/* Similar to dump_gimple_stmt, except additionally print source location.  */

void
dump_gimple_stmt_loc (const dump_metadata_t &metadata,
		      const dump_user_location_t &loc,
		      dump_flags_t extra_dump_flags, gimple *gs, int spc)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_gimple_stmt_loc (metadata, loc, extra_dump_flags,
					     gs, spc);
}

/* Dump gimple statement GS with SPC indentation spaces and
   EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled.
   Do not terminate with a newline or semicolon.  */

void
dump_gimple_expr (const dump_metadata_t &metadata,
		  dump_flags_t extra_dump_flags,
		  gimple *gs, int spc)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_gimple_expr (metadata, extra_dump_flags, gs, spc);
}

/* Similar to dump_gimple_expr, except additionally print source location.  */

void
dump_gimple_expr_loc (const dump_metadata_t &metadata,
		      const dump_user_location_t &loc,
		      dump_flags_t extra_dump_flags, gimple *gs, int spc)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_gimple_expr_loc (metadata, loc, extra_dump_flags,
					     gs, spc);
}

/* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
   DUMP_KIND is enabled.  */

void
dump_generic_expr (const dump_metadata_t &metadata, dump_flags_t extra_dump_flags,
		   tree t)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_generic_expr (metadata, extra_dump_flags, t);
}

/* Similar to dump_generic_expr, except additionally print the source
   location.  */

void
dump_generic_expr_loc (const dump_metadata_t &metadata,
		       const dump_user_location_t &loc,
		       dump_flags_t extra_dump_flags, tree t)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_generic_expr_loc (metadata, loc, extra_dump_flags,
					      t);
}

/* Output a formatted message using FORMAT on appropriate dump streams.  */

void
dump_printf (const dump_metadata_t &metadata, const char *format, ...)
{
  VERIFY_DUMP_ENABLED_P;
  va_list ap;
  va_start (ap, format);
  dump_context::get ().dump_printf_va (metadata, format, &ap);
  va_end (ap);
}

/* Similar to dump_printf, except source location is also printed, and
   dump location captured.  */

void
dump_printf_loc (const dump_metadata_t &metadata,
		 const dump_user_location_t &loc,
		 const char *format, ...)
{
  VERIFY_DUMP_ENABLED_P;
  va_list ap;
  va_start (ap, format);
  dump_context::get ().dump_printf_loc_va (metadata, loc, format, &ap);
  va_end (ap);
}

/* Output VALUE in decimal to appropriate dump streams.  */

template<unsigned int N, typename C>
void
dump_dec (const dump_metadata_t &metadata, const poly_int<N, C> &value)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_dec (metadata, value);
}

template void dump_dec (const dump_metadata_t &metadata, const poly_uint16 &);
template void dump_dec (const dump_metadata_t &metadata, const poly_int64 &);
template void dump_dec (const dump_metadata_t &metadata, const poly_uint64 &);
template void dump_dec (const dump_metadata_t &metadata, const poly_offset_int &);
template void dump_dec (const dump_metadata_t &metadata, const poly_widest_int &);

void
dump_dec (dump_flags_t dump_kind, const poly_wide_int &value, signop sgn)
{
  VERIFY_DUMP_ENABLED_P;
  if (dump_file
      && dump_context::get ().apply_dump_filter_p (dump_kind, pflags))
    print_dec (value, dump_file, sgn);

  if (alt_dump_file
      && dump_context::get ().apply_dump_filter_p (dump_kind, alt_flags))
    print_dec (value, alt_dump_file, sgn);
}

/* Output VALUE in hexadecimal to appropriate dump streams.  */

void
dump_hex (dump_flags_t dump_kind, const poly_wide_int &value)
{
  VERIFY_DUMP_ENABLED_P;
  if (dump_file
      && dump_context::get ().apply_dump_filter_p (dump_kind, pflags))
    print_hex (value, dump_file);

  if (alt_dump_file
      && dump_context::get ().apply_dump_filter_p (dump_kind, alt_flags))
    print_hex (value, alt_dump_file);
}

/* Emit and delete the currently pending optinfo, if there is one,
   without the caller needing to know about class dump_context.  */

void
dumpfile_ensure_any_optinfo_are_flushed ()
{
  dump_context::get().end_any_optinfo ();
}

/* Output the name of NODE on appropriate dump streams.  */

void
dump_symtab_node (const dump_metadata_t &metadata, symtab_node *node)
{
  VERIFY_DUMP_ENABLED_P;
  dump_context::get ().dump_symtab_node (metadata, node);
}

/* Get the current dump scope-nesting depth.
   For use by -fopt-info (for showing nesting via indentation).  */

unsigned int
get_dump_scope_depth ()
{
  return dump_context::get ().get_scope_depth ();
}

/* Push a nested dump scope.
   Print "=== NAME ===\n" to the dumpfile, if any, and to the -fopt-info
   destination, if any.
   Emit a "scope" opinfo if optinfos are enabled.
   Increment the scope depth.  */

void
dump_begin_scope (const char *name,
		  const dump_user_location_t &user_location,
		  const dump_impl_location_t &impl_location)
{
  dump_context::get ().begin_scope (name, user_location, impl_location);
}

/* Pop a nested dump scope.  */

void
dump_end_scope ()
{
  dump_context::get ().end_scope ();
}

/* Start a dump for PHASE. Store user-supplied dump flags in
   *FLAG_PTR.  Return the number of streams opened.  Set globals
   DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
   set dump_flags appropriately for both pass dump stream and
   -fopt-info stream. */

int
gcc::dump_manager::
dump_start (int phase, dump_flags_t *flag_ptr)
{
  int count = 0;
  char *name;
  struct dump_file_info *dfi;
  FILE *stream;
  if (phase == TDI_none || !dump_phase_enabled_p (phase))
    return 0;

  dfi = get_dump_file_info (phase);
  name = get_dump_file_name (phase);
  if (name)
    {
      stream = dump_open (name, dfi->pstate < 0);
      if (stream)
        {
          dfi->pstate = 1;
          count++;
        }
      free (name);
      dfi->pstream = stream;
      set_dump_file (dfi->pstream);
      /* Initialize current dump flags. */
      pflags = dfi->pflags;
    }

  stream = dump_open_alternate_stream (dfi);
  if (stream)
    {
      dfi->alt_stream = stream;
      count++;
      set_alt_dump_file (dfi->alt_stream);
      /* Initialize current -fopt-info flags. */
      alt_flags = dfi->alt_flags;
    }

  if (flag_ptr)
    *flag_ptr = dfi->pflags;

  return count;
}

/* Finish a tree dump for PHASE and close associated dump streams.  Also
   reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS.  */

void
gcc::dump_manager::
dump_finish (int phase)
{
  struct dump_file_info *dfi;

  if (phase < 0)
    return;
  dfi = get_dump_file_info (phase);
  if (dfi->pstream && dfi->pstream != stdout && dfi->pstream != stderr)
    fclose (dfi->pstream);

  if (dfi->alt_stream && dfi->alt_stream != stdout && dfi->alt_stream != stderr)
    fclose (dfi->alt_stream);

  dfi->alt_stream = NULL;
  dfi->pstream = NULL;
  set_dump_file (NULL);
  set_alt_dump_file (NULL);
  dump_flags = TDF_NONE;
  alt_flags = TDF_NONE;
  pflags = TDF_NONE;
}

/* Begin a tree dump for PHASE. Stores any user supplied flag in
   *FLAG_PTR and returns a stream to write to. If the dump is not
   enabled, returns NULL.
   PART can be used for dump files which should be split to multiple
   parts. PART == -1 indicates dump file with no parts.
   If PART is -1, multiple calls will reopen and append to the dump file.  */

FILE *
dump_begin (int phase, dump_flags_t *flag_ptr, int part)
{
  return g->get_dumps ()->dump_begin (phase, flag_ptr, part);
}

FILE *
gcc::dump_manager::
dump_begin (int phase, dump_flags_t *flag_ptr, int part)
{
  char *name;
  struct dump_file_info *dfi;
  FILE *stream;

  if (phase == TDI_none || !dump_phase_enabled_p (phase))
    return NULL;

  name = get_dump_file_name (phase, part);
  if (!name)
    return NULL;
  dfi = get_dump_file_info (phase);

  /* We do not support re-opening of dump files with parts.  This would require
     tracking pstate per part of the dump file.  */
  stream = dump_open (name, part != -1 || dfi->pstate < 0);
  if (stream)
    dfi->pstate = 1;
  free (name);

  if (flag_ptr)
    *flag_ptr = dfi->pflags;

  /* Initialize current flags */
  pflags = dfi->pflags;
  return stream;
}

/* Returns nonzero if dump PHASE is enabled for at least one stream.
   If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
   any phase.  */

int
gcc::dump_manager::
dump_phase_enabled_p (int phase) const
{
  if (phase == TDI_tree_all)
    {
      size_t i;
      for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
	if (dump_files[i].pstate || dump_files[i].alt_state)
	  return 1;
      for (i = 0; i < m_extra_dump_files_in_use; i++)
	if (m_extra_dump_files[i].pstate || m_extra_dump_files[i].alt_state)
	  return 1;
      return 0;
    }
  else
    {
      struct dump_file_info *dfi = get_dump_file_info (phase);
      return dfi->pstate || dfi->alt_state;
    }
}

/* Returns nonzero if tree dump PHASE has been initialized.  */

int
gcc::dump_manager::
dump_initialized_p (int phase) const
{
  struct dump_file_info *dfi = get_dump_file_info (phase);
  return dfi->pstate > 0 || dfi->alt_state > 0;
}

/* Returns the switch name of PHASE.  */

const char *
dump_flag_name (int phase)
{
  return g->get_dumps ()->dump_flag_name (phase);
}

const char *
gcc::dump_manager::
dump_flag_name (int phase) const
{
  struct dump_file_info *dfi = get_dump_file_info (phase);
  return dfi->swtch;
}

/* Handle -fdump-* and -fopt-info for a pass added after
   command-line options are parsed (those from plugins and
   those from backends).

   Because the registration of plugin/backend passes happens after the
   command-line options are parsed, the options that specify single
   pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new
   passes. Therefore we currently can only enable dumping of
   new passes when the 'dump-all' flags (e.g. -fdump-tree-all)
   are specified.  This is done here.

   Similarly, the saved -fopt-info options are wired up to the new pass.  */

void
gcc::dump_manager::register_pass (opt_pass *pass)
{
  gcc_assert (pass);

  register_one_dump_file (pass);

  dump_file_info *pass_dfi = get_dump_file_info (pass->static_pass_number);
  gcc_assert (pass_dfi);

  enum tree_dump_index tdi;
  if (pass->type == SIMPLE_IPA_PASS
      || pass->type == IPA_PASS)
    tdi = TDI_ipa_all;
  else if (pass->type == GIMPLE_PASS)
    tdi = TDI_tree_all;
  else
    tdi = TDI_rtl_all;
  const dump_file_info *tdi_dfi = get_dump_file_info (tdi);
  gcc_assert (tdi_dfi);

  /* Check if dump-all flag is specified.  */
  if (tdi_dfi->pstate)
    {
      pass_dfi->pstate = tdi_dfi->pstate;
      pass_dfi->pflags = tdi_dfi->pflags;
    }

  update_dfi_for_opt_info (pass_dfi);
}

/* Finish a tree dump for PHASE. STREAM is the stream created by
   dump_begin.  */

void
dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
{
  if (stream != stderr && stream != stdout)
    fclose (stream);
}

/* Enable all tree dumps with FLAGS on FILENAME.  Return number of
   enabled tree dumps.  */

int
gcc::dump_manager::
dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename)
{
  int n = 0;
  size_t i;

  for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
    {
      if (dump_files[i].dkind == dkind)
        {
          const char *old_filename = dump_files[i].pfilename;
          dump_files[i].pstate = -1;
          dump_files[i].pflags |= flags;
          n++;
          /* Override the existing filename.  */
          if (filename)
            {
              dump_files[i].pfilename = xstrdup (filename);
              /* Since it is a command-line provided file, which is
                 common to all the phases, use it in append mode.  */
              dump_files[i].pstate = 1;
            }
          if (old_filename && filename != old_filename)
            free (CONST_CAST (char *, old_filename));
        }
    }

  for (i = 0; i < m_extra_dump_files_in_use; i++)
    {
      if (m_extra_dump_files[i].dkind == dkind)
        {
          const char *old_filename = m_extra_dump_files[i].pfilename;
          m_extra_dump_files[i].pstate = -1;
          m_extra_dump_files[i].pflags |= flags;
          n++;
          /* Override the existing filename.  */
          if (filename)
            {
              m_extra_dump_files[i].pfilename = xstrdup (filename);
              /* Since it is a command-line provided file, which is
                 common to all the phases, use it in append mode.  */
              m_extra_dump_files[i].pstate = 1;
            }
          if (old_filename && filename != old_filename)
            free (CONST_CAST (char *, old_filename));
        }
    }

  return n;
}

/* Enable -fopt-info dumps on all dump files matching OPTGROUP_FLAGS.
   Enable dumps with FLAGS on FILENAME.  Return the number of enabled
   dumps.  */

int
gcc::dump_manager::
opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags,
			const char *filename)
{
  int n = 0;

  m_optgroup_flags = optgroup_flags;
  m_optinfo_flags = flags;
  m_optinfo_filename = xstrdup (filename);

  for (size_t i = TDI_none + 1; i < (size_t) TDI_end; i++)
    if (update_dfi_for_opt_info (&dump_files[i]))
      n++;

  for (size_t i = 0; i < m_extra_dump_files_in_use; i++)
    if (update_dfi_for_opt_info (&m_extra_dump_files[i]))
      n++;

  return n;
}

/* Use the saved -fopt-info options to update DFI.
   Return true if the dump is enabled.  */

bool
gcc::dump_manager::update_dfi_for_opt_info (dump_file_info *dfi) const
{
  gcc_assert (dfi);

  if (!(dfi->optgroup_flags & m_optgroup_flags))
    return false;

  const char *old_filename = dfi->alt_filename;
  /* Since this file is shared among different passes, it
     should be opened in append mode.  */
  dfi->alt_state = 1;
  dfi->alt_flags |= m_optinfo_flags;
  /* Override the existing filename.  */
  if (m_optinfo_filename)
    dfi->alt_filename = xstrdup (m_optinfo_filename);
  if (old_filename && m_optinfo_filename != old_filename)
    free (CONST_CAST (char *, old_filename));

  return true;
}

/* Parse ARG as a dump switch. Return nonzero if it is, and store the
   relevant details in the dump_files array.  */

int
gcc::dump_manager::
dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
{
  const char *option_value;
  const char *ptr;
  dump_flags_t flags;

  if (doglob && !dfi->glob)
    return 0;

  option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
  if (!option_value)
    return 0;

  if (*option_value && *option_value != '-' && *option_value != '=')
    return 0;

  ptr = option_value;

  /* Retain "user-facing" and "internals" messages, but filter out
     those from an opt_problem being re-emitted at the top level
     (MSG_PRIORITY_REEMITTED), so as to avoid duplicate messages
     messing up scan-tree-dump-times" in DejaGnu tests.  */
  flags = MSG_PRIORITY_USER_FACING | MSG_PRIORITY_INTERNALS;

  while (*ptr)
    {
      const struct kv_pair<dump_flags_t> *option_ptr;
      const char *end_ptr;
      const char *eq_ptr;
      unsigned length;

      while (*ptr == '-')
	ptr++;
      end_ptr = strchr (ptr, '-');
      eq_ptr = strchr (ptr, '=');

      if (eq_ptr && !end_ptr)
        end_ptr = eq_ptr;

      if (!end_ptr)
	end_ptr = ptr + strlen (ptr);
      length = end_ptr - ptr;

      for (option_ptr = dump_options; option_ptr->name; option_ptr++)
	if (strlen (option_ptr->name) == length
	    && !memcmp (option_ptr->name, ptr, length))
          {
            flags |= option_ptr->value;
	    goto found;
          }

      if (*ptr == '=')
        {
          /* Interpret rest of the argument as a dump filename.  This
             filename overrides other command line filenames.  */
          if (dfi->pfilename)
            free (CONST_CAST (char *, dfi->pfilename));
          dfi->pfilename = xstrdup (ptr + 1);
          break;
        }
      else
        warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
                 length, ptr, dfi->swtch);
    found:;
      ptr = end_ptr;
    }

  dfi->pstate = -1;
  dfi->pflags |= flags;

  /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
     known dumps.  */
  if (dfi->suffix == NULL)
    dump_enable_all (dfi->dkind, dfi->pflags, dfi->pfilename);

  return 1;
}

int
gcc::dump_manager::
dump_switch_p (const char *arg)
{
  size_t i;
  int any = 0;

  for (i = TDI_none + 1; i != TDI_end; i++)
    any |= dump_switch_p_1 (arg, &dump_files[i], false);

  /* Don't glob if we got a hit already */
  if (!any)
    for (i = TDI_none + 1; i != TDI_end; i++)
      any |= dump_switch_p_1 (arg, &dump_files[i], true);

  for (i = 0; i < m_extra_dump_files_in_use; i++)
    any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], false);

  if (!any)
    for (i = 0; i < m_extra_dump_files_in_use; i++)
      any |= dump_switch_p_1 (arg, &m_extra_dump_files[i], true);


  return any;
}

/* Parse ARG as a -fopt-info switch and store flags, optgroup_flags
   and filename.  Return non-zero if it is a recognized switch.  */

static int
opt_info_switch_p_1 (const char *arg, dump_flags_t *flags,
		     optgroup_flags_t *optgroup_flags, char **filename)
{
  const char *option_value;
  const char *ptr;

  option_value = arg;
  ptr = option_value;

  *filename = NULL;

  /* Default to filtering out "internals" messages, and retaining
     "user-facing" messages, and those from an opt_problem being
     re-emitted at the top level.  */
  *flags = MSG_PRIORITY_USER_FACING | MSG_PRIORITY_REEMITTED;

  *optgroup_flags = OPTGROUP_NONE;

  if (!ptr)
    return 1;       /* Handle '-fopt-info' without any additional options.  */

  while (*ptr)
    {
      const char *end_ptr;
      const char *eq_ptr;
      unsigned length;

      while (*ptr == '-')
	ptr++;
      end_ptr = strchr (ptr, '-');
      eq_ptr = strchr (ptr, '=');

      if (eq_ptr && (!end_ptr || eq_ptr < end_ptr))
        end_ptr = eq_ptr;
      else if (!end_ptr)
	end_ptr = ptr + strlen (ptr);
      length = end_ptr - ptr;

      for (const kv_pair<dump_flags_t> *option_ptr = optinfo_verbosity_options;
	   option_ptr->name; option_ptr++)
	if (strlen (option_ptr->name) == length
	    && !memcmp (option_ptr->name, ptr, length))
          {
            *flags |= option_ptr->value;
	    goto found;
          }

      for (const kv_pair<optgroup_flags_t> *option_ptr = optgroup_options;
	   option_ptr->name; option_ptr++)
	if (strlen (option_ptr->name) == length
	    && !memcmp (option_ptr->name, ptr, length))
          {
            *optgroup_flags |= option_ptr->value;
	    goto found;
          }

      if (*ptr == '=')
        {
          /* Interpret rest of the argument as a dump filename.  This
             filename overrides other command line filenames.  */
          *filename = xstrdup (ptr + 1);
          break;
        }
      else
        {
          warning (0, "unknown option %q.*s in %<-fopt-info-%s%>",
                   length, ptr, arg);
          return 0;
        }
    found:;
      ptr = end_ptr;
    }

  return 1;
}

/* Return non-zero if ARG is a recognized switch for
   -fopt-info. Return zero otherwise.  */

int
opt_info_switch_p (const char *arg)
{
  dump_flags_t flags;
  optgroup_flags_t optgroup_flags;
  char *filename;
  static char *file_seen = NULL;
  gcc::dump_manager *dumps = g->get_dumps ();

  if (!opt_info_switch_p_1 (arg, &flags, &optgroup_flags, &filename))
    return 0;

  if (!filename)
    filename = xstrdup ("stderr");

  /* Bail out if a different filename has been specified.  */
  if (file_seen && strcmp (file_seen, filename))
    {
      warning (0, "ignoring possibly conflicting option %<-fopt-info-%s%>",
               arg);
      return 1;
    }

  file_seen = xstrdup (filename);
  if (!(flags & MSG_ALL_KINDS))
    flags |= MSG_OPTIMIZED_LOCATIONS;
  if (!optgroup_flags)
    optgroup_flags = OPTGROUP_ALL;

  return dumps->opt_info_enable_passes (optgroup_flags, flags, filename);
}

/* Print basic block on the dump streams.  */

void
dump_basic_block (dump_flags_t dump_kind, basic_block bb, int indent)
{
  if (dump_file
      && dump_context::get ().apply_dump_filter_p (dump_kind, pflags))
    dump_bb (dump_file, bb, indent, TDF_DETAILS);
  if (alt_dump_file
      && dump_context::get ().apply_dump_filter_p (dump_kind, alt_flags))
    dump_bb (alt_dump_file, bb, indent, TDF_DETAILS);
}

/* Dump FUNCTION_DECL FN as tree dump PHASE.  */

void
dump_function (int phase, tree fn)
{
  FILE *stream;
  dump_flags_t flags;

  stream = dump_begin (phase, &flags);
  if (stream)
    {
      dump_function_to_file (fn, stream, flags);
      dump_end (phase, stream);
    }
}

/* Print information from the combine pass on dump_file.  */

void
print_combine_total_stats (void)
{
  if (dump_file)
    dump_combine_total_stats (dump_file);
}

/* Enable RTL dump for all the RTL passes.  */

bool
enable_rtl_dump_file (void)
{
  gcc::dump_manager *dumps = g->get_dumps ();
  int num_enabled =
    dumps->dump_enable_all (DK_rtl, dump_flags_t (TDF_DETAILS) | TDF_BLOCKS,
			    NULL);
  return num_enabled > 0;
}

#if CHECKING_P

namespace selftest {

/* temp_dump_context's ctor.  Temporarily override the dump_context
   (to forcibly enable optinfo-generation).  */

temp_dump_context::temp_dump_context (bool forcibly_enable_optinfo,
				      bool forcibly_enable_dumping,
				      dump_flags_t test_pp_flags)
: m_context (),
  m_saved (&dump_context ().get ())
{
  dump_context::s_current = &m_context;
  if (forcibly_enable_optinfo)
    m_context.set_json_writer (new optrecord_json_writer ());
  /* Conditionally enable the test dump, so that we can verify both the
     dump_enabled_p and the !dump_enabled_p cases in selftests.  */
  if (forcibly_enable_dumping)
    {
      m_context.m_test_pp = &m_pp;
      m_context.m_test_pp_flags = test_pp_flags;
    }

  dump_context::get ().refresh_dumps_are_enabled ();
}

/* temp_dump_context's dtor.  Restore the saved dump_context.  */

temp_dump_context::~temp_dump_context ()
{
  m_context.set_json_writer (NULL);

  dump_context::s_current = m_saved;

  dump_context::get ().refresh_dumps_are_enabled ();
}

/* 0-terminate the text dumped so far, and return it.  */

const char *
temp_dump_context::get_dumped_text ()
{
  return pp_formatted_text (&m_pp);
}

/* Verify that IMPL_LOC is within EXPECTED_FILE at EXPECTED_LINE,
   from EXPECTED_FUNCTION, using LOC for the location of any failure,
   provided that the build compiler is sufficiently recent.  */

static void
assert_impl_location_eq (const location &loc ATTRIBUTE_UNUSED,
			 const dump_impl_location_t &impl_loc ATTRIBUTE_UNUSED,
			 const char *expected_file ATTRIBUTE_UNUSED,
			 int expected_line ATTRIBUTE_UNUSED,
			 const char *expected_function ATTRIBUTE_UNUSED)
{
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
  ASSERT_STR_CONTAINS_AT (loc, impl_loc.m_file, expected_file);
  ASSERT_EQ_AT (loc, impl_loc.m_line, expected_line);
  ASSERT_STR_CONTAINS_AT (loc, impl_loc.m_function, expected_function);
#endif
}

/* Verify that IMPL_LOC is within EXPECTED_FILE at EXPECTED_LINE,
   from EXPECTED_FUNCTION, provided that the build compiler is
   sufficiently recent.  */

#define ASSERT_IMPL_LOCATION_EQ(IMPL_LOC, EXPECTED_FILE, EXPECTED_LINE, \
				EXPECTED_FUNCTION)			\
  SELFTEST_BEGIN_STMT							\
    assert_impl_location_eq (SELFTEST_LOCATION, IMPL_LOC,		\
			     EXPECTED_FILE, EXPECTED_LINE,		\
			     EXPECTED_FUNCTION);			\
  SELFTEST_END_STMT

/* Verify that the dump_location_t constructors capture the source location
   at which they were called (provided that the build compiler is sufficiently
   recent).  */

static void
test_impl_location ()
{
  /* Default ctor.  */
  {
    dump_location_t loc;
    const int expected_line = __LINE__ - 1;
    ASSERT_IMPL_LOCATION_EQ (loc.get_impl_location (),
			     "dumpfile.c", expected_line, "test_impl_location");
  }

  /* Constructing from a gimple.  */
  {
    dump_location_t loc ((gimple *)NULL);
    const int expected_line = __LINE__ - 1;
    ASSERT_IMPL_LOCATION_EQ (loc.get_impl_location (),
			     "dumpfile.c", expected_line, "test_impl_location");
  }

  /* Constructing from an rtx_insn.  */
  {
    dump_location_t loc ((rtx_insn *)NULL);
    const int expected_line = __LINE__ - 1;
    ASSERT_IMPL_LOCATION_EQ (loc.get_impl_location (),
			     "dumpfile.c", expected_line, "test_impl_location");
  }
}

/* Verify that the text dumped so far in CONTEXT equals
   EXPECTED_TEXT, using LOC for the location of any failure.
   As a side-effect, the internal buffer is 0-terminated.  */

void
verify_dumped_text (const location &loc,
		    temp_dump_context *context,
		    const char *expected_text)
{
  gcc_assert (context);
  ASSERT_STREQ_AT (loc, context->get_dumped_text (),
		   expected_text);
}

/* Verify that ITEM has the expected values.  */

void
verify_item (const location &loc,
	     const optinfo_item *item,
	     enum optinfo_item_kind expected_kind,
	     location_t expected_location,
	     const char *expected_text)
{
  ASSERT_EQ_AT (loc, item->get_kind (), expected_kind);
  ASSERT_EQ_AT (loc, item->get_location (), expected_location);
  ASSERT_STREQ_AT (loc, item->get_text (), expected_text);
}

/* Verify that calls to the dump_* API are captured and consolidated into
   optimization records. */

static void
test_capture_of_dump_calls (const line_table_case &case_)
{
  /* Generate a location_t for testing.  */
  line_table_test ltt (case_);
  linemap_add (line_table, LC_ENTER, false, "test.txt", 0);
  linemap_line_start (line_table, 5, 100);
  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
  location_t decl_loc = linemap_position_for_column (line_table, 8);
  location_t stmt_loc = linemap_position_for_column (line_table, 10);
  if (stmt_loc > LINE_MAP_MAX_LOCATION_WITH_COLS)
    return;

  dump_user_location_t loc = dump_user_location_t::from_location_t (stmt_loc);

  gimple *stmt = gimple_build_return (NULL);
  gimple_set_location (stmt, stmt_loc);

  tree test_decl = build_decl (decl_loc, FUNCTION_DECL,
			       get_identifier ("test_decl"),
			       build_function_type_list (void_type_node,
							 NULL_TREE));

  symbol_table_test tmp_symtab;

  cgraph_node *node = cgraph_node::get_create (test_decl);
  gcc_assert (node);

  /* Run all tests twice, with and then without optinfo enabled, to ensure
     that immediate destinations vs optinfo-based destinations both
     work, independently of each other, with no leaks.  */
  for (int i = 0 ; i < 2; i++)
    {
      bool with_optinfo = (i == 0);

      /* Test of dump_printf.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_printf (MSG_NOTE, "int: %i str: %s", 42, "foo");
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "int: 42 str: foo");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 1);
	    ASSERT_IS_TEXT (info->get_item (0), "int: 42 str: foo");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* Test of dump_printf with %T.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_printf (MSG_NOTE, "tree: %T", integer_zero_node);
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "tree: 0");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 2);
	    ASSERT_IS_TEXT (info->get_item (0), "tree: ");
	    ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* Test of dump_printf with %E.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_printf (MSG_NOTE, "gimple: %E", stmt);
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "gimple: return;");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 2);
	    ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
	    ASSERT_IS_GIMPLE (info->get_item (1), stmt_loc, "return;");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* Test of dump_printf with %G.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_printf (MSG_NOTE, "gimple: %G", stmt);
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "gimple: return;\n");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 2);
	    ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
	    ASSERT_IS_GIMPLE (info->get_item (1), stmt_loc, "return;\n");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* Test of dump_printf with %C.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_printf (MSG_NOTE, "node: %C", node);
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "node: test_decl/0");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 2);
	    ASSERT_IS_TEXT (info->get_item (0), "node: ");
	    ASSERT_IS_SYMTAB_NODE (info->get_item (1), decl_loc, "test_decl/0");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* dump_print_loc with multiple format codes.  This tests various
	 things:
	 - intermingling of text, format codes handled by the base
	 pretty_printer, and dump-specific format codes
	 - multiple dump-specific format codes: some consecutive, others
	 separated by text, trailing text after the final one.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_printf_loc (MSG_NOTE, loc, "before %T and %T"
			 " %i consecutive %E%E after\n",
			 integer_zero_node, test_decl, 42, stmt, stmt);

	ASSERT_DUMPED_TEXT_EQ (tmp,
			       "test.txt:5:10: note: before 0 and test_decl"
			       " 42 consecutive return;return; after\n");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 8);
	    ASSERT_IS_TEXT (info->get_item (0), "before ");
	    ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
	    ASSERT_IS_TEXT (info->get_item (2), " and ");
	    ASSERT_IS_TREE (info->get_item (3), UNKNOWN_LOCATION, "test_decl");
	    ASSERT_IS_TEXT (info->get_item (4), " 42 consecutive ");
	    ASSERT_IS_GIMPLE (info->get_item (5), stmt_loc, "return;");
	    ASSERT_IS_GIMPLE (info->get_item (6), stmt_loc, "return;");
	    ASSERT_IS_TEXT (info->get_item (7), " after\n");
	    /* We don't ASSERT_IMPL_LOCATION_EQ here, to avoid having to
	       enforce at which exact line the multiline dump_printf_loc
	       occurred.  */
	  }
      }

      /* Tree, via dump_generic_expr.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_printf_loc (MSG_NOTE, loc, "test of tree: ");
	const int expected_impl_line = __LINE__ - 1;
	dump_generic_expr (MSG_NOTE, TDF_SLIM, integer_zero_node);

	ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: test of tree: 0");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_location_t (), stmt_loc);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 2);
	    ASSERT_IS_TEXT (info->get_item (0), "test of tree: ");
	    ASSERT_IS_TREE (info->get_item (1), UNKNOWN_LOCATION, "0");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* Tree, via dump_generic_expr_loc.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_generic_expr_loc (MSG_NOTE, loc, TDF_SLIM, integer_one_node);
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: 1");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_location_t (), stmt_loc);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 1);
	    ASSERT_IS_TREE (info->get_item (0), UNKNOWN_LOCATION, "1");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* Gimple.  */
      {
	/* dump_gimple_stmt_loc.  */
	{
	  temp_dump_context tmp (with_optinfo, true,
				 MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	  dump_gimple_stmt_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
	  const int expected_impl_line = __LINE__ - 1;

	  ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: return;\n");
	  if (with_optinfo)
	    {
	      optinfo *info = tmp.get_pending_optinfo ();
	      ASSERT_TRUE (info != NULL);
	      ASSERT_EQ (info->num_items (), 1);
	      ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;\n");
	      ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				       "dumpfile.c", expected_impl_line,
				       "test_capture_of_dump_calls");
	    }
	}

	/* dump_gimple_stmt.  */
	{
	  temp_dump_context tmp (with_optinfo, true,
				 MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	  dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 2);
	  const int expected_impl_line = __LINE__ - 1;

	  ASSERT_DUMPED_TEXT_EQ (tmp, "return;\n");
	  if (with_optinfo)
	    {
	      optinfo *info = tmp.get_pending_optinfo ();
	      ASSERT_TRUE (info != NULL);
	      ASSERT_EQ (info->num_items (), 1);
	      ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;\n");
	      ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				       "dumpfile.c", expected_impl_line,
				       "test_capture_of_dump_calls");
	    }
	}

	/* dump_gimple_expr_loc.  */
	{
	  temp_dump_context tmp (with_optinfo, true,
				 MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	  dump_gimple_expr_loc (MSG_NOTE, loc, TDF_SLIM, stmt, 2);
	  const int expected_impl_line = __LINE__ - 1;

	  ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: note: return;");
	  if (with_optinfo)
	    {
	      optinfo *info = tmp.get_pending_optinfo ();
	      ASSERT_TRUE (info != NULL);
	      ASSERT_EQ (info->num_items (), 1);
	      ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;");
	      ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				       "dumpfile.c", expected_impl_line,
				       "test_capture_of_dump_calls");
	    }
	}

	/* dump_gimple_expr.  */
	{
	  temp_dump_context tmp (with_optinfo, true,
				 MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	  dump_gimple_expr (MSG_NOTE, TDF_SLIM, stmt, 2);
	  const int expected_impl_line = __LINE__ - 1;

	  ASSERT_DUMPED_TEXT_EQ (tmp, "return;");
	  if (with_optinfo)
	    {
	      optinfo *info = tmp.get_pending_optinfo ();
	      ASSERT_TRUE (info != NULL);
	      ASSERT_EQ (info->num_items (), 1);
	      ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;");
	      ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				       "dumpfile.c", expected_impl_line,
				       "test_capture_of_dump_calls");
	    }
	}
      }

      /* symtab_node.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_symtab_node (MSG_NOTE, node);
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "test_decl/0");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
	    ASSERT_EQ (info->num_items (), 1);
	    ASSERT_IS_SYMTAB_NODE (info->get_item (0), decl_loc, "test_decl/0");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* poly_int.  */
      {
	temp_dump_context tmp (with_optinfo, true,
			       MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
	dump_dec (MSG_NOTE, poly_int64 (42));
	const int expected_impl_line = __LINE__ - 1;

	ASSERT_DUMPED_TEXT_EQ (tmp, "42");
	if (with_optinfo)
	  {
	    optinfo *info = tmp.get_pending_optinfo ();
	    ASSERT_TRUE (info != NULL);
	    ASSERT_EQ (info->num_items (), 1);
	    ASSERT_IS_TEXT (info->get_item (0), "42");
	    ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				     "dumpfile.c", expected_impl_line,
				     "test_capture_of_dump_calls");
	  }
      }

      /* Scopes.  Test with all 4 combinations of
	 filtering by MSG_PRIORITY_USER_FACING
	 and/or filtering by MSG_PRIORITY_INTERNALS.  */
      for (int j = 0; j < 3; j++)
	{
	  dump_flags_t dump_filter = MSG_ALL_KINDS;
	  if (j % 2)
	    dump_filter |= MSG_PRIORITY_USER_FACING;
	  if (j / 2)
	    dump_filter |= MSG_PRIORITY_INTERNALS;

	  temp_dump_context tmp (with_optinfo, true, dump_filter);
	  /* Emit various messages, mostly with implicit priority.  */
	  dump_printf_loc (MSG_NOTE, stmt, "msg 1\n");
	  dump_printf_loc (MSG_NOTE | MSG_PRIORITY_INTERNALS, stmt,
			   "explicitly internal msg\n");
	  {
	    AUTO_DUMP_SCOPE ("outer scope", stmt);
	    dump_printf_loc (MSG_NOTE, stmt, "msg 2\n");
	    {
	      AUTO_DUMP_SCOPE ("middle scope", stmt);
	      dump_printf_loc (MSG_NOTE, stmt, "msg 3\n");
	      {
		AUTO_DUMP_SCOPE ("inner scope", stmt);
		dump_printf_loc (MSG_NOTE, stmt, "msg 4\n");
		dump_printf_loc (MSG_NOTE | MSG_PRIORITY_USER_FACING, stmt,
				 "explicitly user-facing msg\n");
	      }
	      dump_printf_loc (MSG_NOTE, stmt, "msg 5\n");
	    }
	    dump_printf_loc (MSG_NOTE, stmt, "msg 6\n");
	  }
	  dump_printf_loc (MSG_NOTE, stmt, "msg 7\n");
	  const int expected_impl_line = __LINE__ - 1;

	  switch (dump_filter & MSG_ALL_PRIORITIES)
	    {
	    default:
	      gcc_unreachable ();
	    case 0:
	      ASSERT_DUMPED_TEXT_EQ (tmp, "");
	      break;
	    case MSG_PRIORITY_USER_FACING:
	      ASSERT_DUMPED_TEXT_EQ
		(tmp,
		 "test.txt:5:10: note: msg 1\n"
		 "test.txt:5:10: note:    explicitly user-facing msg\n"
		 "test.txt:5:10: note: msg 7\n");
	      break;
	    case MSG_PRIORITY_INTERNALS:
	      ASSERT_DUMPED_TEXT_EQ
		(tmp,
		 "test.txt:5:10: note: explicitly internal msg\n"
		 "test.txt:5:10: note:  === outer scope ===\n"
		 "test.txt:5:10: note:  msg 2\n"
		 "test.txt:5:10: note:   === middle scope ===\n"
		 "test.txt:5:10: note:   msg 3\n"
		 "test.txt:5:10: note:    === inner scope ===\n"
		 "test.txt:5:10: note:    msg 4\n"
		 "test.txt:5:10: note:   msg 5\n"
		 "test.txt:5:10: note:  msg 6\n");
	      break;
	    case MSG_ALL_PRIORITIES:
	      ASSERT_DUMPED_TEXT_EQ
		(tmp,
		 "test.txt:5:10: note: msg 1\n"
		 "test.txt:5:10: note: explicitly internal msg\n"
		 "test.txt:5:10: note: === outer scope ===\n"
		 "test.txt:5:10: note:  msg 2\n"
		 "test.txt:5:10: note:  === middle scope ===\n"
		 "test.txt:5:10: note:   msg 3\n"
		 "test.txt:5:10: note:   === inner scope ===\n"
		 "test.txt:5:10: note:    msg 4\n"
		 "test.txt:5:10: note:    explicitly user-facing msg\n"
		 "test.txt:5:10: note:   msg 5\n"
		 "test.txt:5:10: note:  msg 6\n"
		 "test.txt:5:10: note: msg 7\n");
	      break;
	    }
	  if (with_optinfo)
	    {
	      optinfo *info = tmp.get_pending_optinfo ();
	      ASSERT_TRUE (info != NULL);
	      ASSERT_EQ (info->num_items (), 1);
	      ASSERT_IS_TEXT (info->get_item (0), "msg 7\n");
	      ASSERT_IMPL_LOCATION_EQ (info->get_impl_location (),
				       "dumpfile.c", expected_impl_line,
				       "test_capture_of_dump_calls");
	    }
	}
    }

  /* Verify that MSG_* affects optinfo->get_kind (); we tested MSG_NOTE
     above.  */
  {
    /* MSG_OPTIMIZED_LOCATIONS.  */
    {
      temp_dump_context tmp (true, true, MSG_ALL_KINDS);
      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc, "test");
      ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
		 OPTINFO_KIND_SUCCESS);
    }

    /* MSG_MISSED_OPTIMIZATION.  */
    {
      temp_dump_context tmp (true, true, MSG_ALL_KINDS);
      dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc, "test");
      ASSERT_EQ (tmp.get_pending_optinfo ()->get_kind (),
		 OPTINFO_KIND_FAILURE);
    }
  }

  /* Verify that MSG_* affect AUTO_DUMP_SCOPE and the dump calls.  */
  {
    temp_dump_context tmp (false, true,
			   MSG_OPTIMIZED_LOCATIONS | MSG_ALL_PRIORITIES);
    dump_printf_loc (MSG_NOTE, stmt, "msg 1\n");
    {
      AUTO_DUMP_SCOPE ("outer scope", stmt);
      dump_printf_loc (MSG_NOTE, stmt, "msg 2\n");
      {
	AUTO_DUMP_SCOPE ("middle scope", stmt);
	dump_printf_loc (MSG_NOTE, stmt, "msg 3\n");
	{
	  AUTO_DUMP_SCOPE ("inner scope", stmt);
	  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt, "msg 4\n");
	}
	dump_printf_loc (MSG_NOTE, stmt, "msg 5\n");
      }
      dump_printf_loc (MSG_NOTE, stmt, "msg 6\n");
    }
    dump_printf_loc (MSG_NOTE, stmt, "msg 7\n");

    ASSERT_DUMPED_TEXT_EQ (tmp, "test.txt:5:10: optimized:    msg 4\n");
  }
}

static void
test_pr87025 ()
{
  dump_user_location_t loc
    = dump_user_location_t::from_location_t (UNKNOWN_LOCATION);

  temp_dump_context tmp (true, true,
			 MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
  {
    AUTO_DUMP_SCOPE ("outer scope", loc);
    dump_printf (MSG_NOTE, "msg1\n");
  }
}

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

void
dumpfile_c_tests ()
{
  test_impl_location ();
  for_each_line_table_case (test_capture_of_dump_calls);
  test_pr87025 ();
}

} // namespace selftest

#endif /* CHECKING_P */
