/* 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[] =
{
  {"none", TDF_NONE},
  {"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;
}

/* Helper routine to parse -<dump format>[=filename]
   and return the corresponding dump flag.  If POS_P is non-NULL,
   assign start of filename into *POS_P.  */

dump_flags_t
parse_dump_option (const char *option_value, const char **pos_p)
{
  const char *ptr;
  dump_flags_t flags;

  ptr = option_value;
  if (pos_p)
    *pos_p = NULL;

  /* 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 (pos_p)
	    *pos_p = ptr + 1;
	  break;
	}
      else
      {
	warning (0, "ignoring unknown option %q.*s",
		 length, ptr);
	flags = TDF_ERROR;
      }
    found:
      ptr = end_ptr;
  }

  return flags;
}

/* 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;
  dump_flags_t flags = TDF_NONE;

  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;

  const char *filename;
  flags = parse_dump_option (option_value, &filename);
  if (filename)
    {
      if (dfi->pfilename)
  free (CONST_CAST (char *, dfi->pfilename));
      dfi->pfilename = xstrdup (filename);
    }

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