/* Dump infrastructure for optimizations and intermediate representation.
   Copyright (C) 2012-2018 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)
        end_ptr = eq_ptr;

      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 */
