/* Definitions for the shared dumpfile.
   Copyright (C) 2004-2022 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/>.  */


#ifndef GCC_DUMPFILE_H
#define GCC_DUMPFILE_H 1

#include "profile-count.h"

/* An attribute for annotating formatting printing functions that use
   the dumpfile/optinfo formatting codes.  These are the pretty_printer
   format codes (see pretty-print.cc), with additional codes for middle-end
   specific entities (see dumpfile.cc).  */

#if GCC_VERSION >= 9000
#define ATTRIBUTE_GCC_DUMP_PRINTF(m, n) \
  __attribute__ ((__format__ (__gcc_dump_printf__, m ,n))) \
  ATTRIBUTE_NONNULL(m)
#else
#define ATTRIBUTE_GCC_DUMP_PRINTF(m, n) ATTRIBUTE_NONNULL(m)
#endif

/* Different tree dump places.  When you add new tree dump places,
   extend the DUMP_FILES array in dumpfile.cc.  */
enum tree_dump_index
{
  TDI_none,			/* No dump */
  TDI_cgraph,			/* dump function call graph.  */
  TDI_inheritance,		/* dump type inheritance graph.  */
  TDI_clones,			/* dump IPA cloning decisions.  */
  TDI_original,			/* dump each function before optimizing it */
  TDI_gimple,			/* dump each function after gimplifying it */
  TDI_nested,			/* dump each function after unnesting it */
  TDI_lto_stream_out,		/* dump information about lto streaming */
  TDI_profile_report,		/* dump information about profile quality */

  TDI_lang_all,			/* enable all the language dumps.  */
  TDI_tree_all,			/* enable all the GENERIC/GIMPLE dumps.  */
  TDI_rtl_all,			/* enable all the RTL dumps.  */
  TDI_ipa_all,			/* enable all the IPA dumps.  */

  TDI_end
};

/* Enum used to distinguish dump files to types.  */

enum dump_kind
{
  DK_none,
  DK_lang,
  DK_tree,
  DK_rtl,
  DK_ipa
};

/* Bit masks to control dumping. Not all values are applicable to all
   dumps. Add new ones at the end. When you define new values, extend
   the DUMP_OPTIONS array in dumpfile.cc. The TDF_* flags coexist with
   MSG_* flags (for -fopt-info) and the bit values must be chosen to
   allow that.  */
enum dump_flag : uint32_t
{
  /* Value of TDF_NONE is used just for bits filtered by TDF_KIND_MASK.  */
  TDF_NONE  = 0,

  /* Dump node addresses.  */
  TDF_ADDRESS = (1 << 0),

  /* Don't go wild following links.  */
  TDF_SLIM = (1 << 1),

  /* Don't unparse the function.  */
  TDF_RAW = (1 << 2),

  /* Show more detailed info about each pass.  */
  TDF_DETAILS = (1 << 3),

  /* Dump various statistics about each pass.  */
  TDF_STATS = (1 << 4),

  /* Display basic block boundaries.  */
  TDF_BLOCKS = (1 << 5),

  /* Display virtual operands.  */
  TDF_VOPS = (1 << 6),

  /* Display statement line numbers.  */
  TDF_LINENO = (1 << 7),

  /* Display decl UIDs.  */
  TDF_UID  = (1 << 8),

  /* Address of stmt.  */
  TDF_STMTADDR = (1 << 9),

  /* A graph dump is being emitted.  */
  TDF_GRAPH = (1 << 10),

  /* Display memory symbols in expr.
     Implies TDF_VOPS.  */
  TDF_MEMSYMS = (1 << 11),

  /* A flag to only print the RHS of a gimple stmt.  */
  TDF_RHS_ONLY = (1 << 12),

  /* Display asm names of decls.  */
  TDF_ASMNAME = (1 << 13),

  /* Display EH region number holding this gimple statement.  */
  TDF_EH  = (1 << 14),

  /* Omit UIDs from dumps.  */
  TDF_NOUID = (1 << 15),

  /* Display alias information.  */
  TDF_ALIAS = (1 << 16),

  /* Enumerate locals by uid.  */
  TDF_ENUMERATE_LOCALS = (1 << 17),

  /* Dump cselib details.  */
  TDF_CSELIB = (1 << 18),

  /* Dump SCEV details.  */
  TDF_SCEV = (1 << 19),

  /* Dump in GIMPLE FE syntax.  */
  TDF_GIMPLE = (1 << 20),

  /* Dump folding details.  */
  TDF_FOLDING = (1 << 21),

  /* MSG_* flags for expressing the kinds of message to
     be emitted by -fopt-info.  */

  /* -fopt-info optimized sources.  */
  MSG_OPTIMIZED_LOCATIONS = (1 << 22),

  /* Missed opportunities.  */
  MSG_MISSED_OPTIMIZATION = (1 << 23),

  /* General optimization info.  */
  MSG_NOTE = (1 << 24),

  /* Mask for selecting MSG_-kind flags.  */
  MSG_ALL_KINDS = (MSG_OPTIMIZED_LOCATIONS
		   | MSG_MISSED_OPTIMIZATION
		   | MSG_NOTE),

  /* MSG_PRIORITY_* flags for expressing the priority levels of message
     to be emitted by -fopt-info, and filtering on them.
     By default, messages at the top-level dump scope are "user-facing",
     whereas those that are in nested scopes are implicitly "internals".
     This behavior can be overridden for a given dump message by explicitly
     specifying one of the MSG_PRIORITY_* flags.

     By default, dump files show both kinds of message, whereas -fopt-info
     only shows "user-facing" messages, and requires the "-internals"
     sub-option of -fopt-info to show the internal messages.  */

  /* Implicitly supplied for messages at the top-level dump scope.  */
  MSG_PRIORITY_USER_FACING = (1 << 25),

  /* Implicitly supplied for messages within nested dump scopes.  */
  MSG_PRIORITY_INTERNALS = (1 << 26),

  /* Supplied when an opt_problem generated in a nested scope is re-emitted
     at the top-level.   We want to default to showing these in -fopt-info
     output, but to *not* show them in dump files, as the message would be
     shown twice, messing up "scan-tree-dump-times" in DejaGnu tests.  */
  MSG_PRIORITY_REEMITTED = (1 << 27),

  /* Mask for selecting MSG_PRIORITY_* flags.  */
  MSG_ALL_PRIORITIES = (MSG_PRIORITY_USER_FACING
			| MSG_PRIORITY_INTERNALS
			| MSG_PRIORITY_REEMITTED),

  /* All -fdump- flags.  */
  TDF_ALL_VALUES = (1 << 28) - 1,

  /* Dumping for -fcompare-debug.  */
  TDF_COMPARE_DEBUG = (1 << 28),

  /* Dump a GIMPLE value which means wrapping certain things with _Literal.  */
  TDF_GIMPLE_VAL = (1 << 29),

  /* For error.  */
  TDF_ERROR = ((uint32_t)1 << 30),
};

/* Dump flags type.  */

typedef enum dump_flag dump_flags_t;

static inline dump_flags_t
operator| (dump_flags_t lhs, dump_flags_t rhs)
{
  return (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
			| (std::underlying_type<dump_flags_t>::type)rhs);
}

static inline dump_flags_t
operator& (dump_flags_t lhs, dump_flags_t rhs)
{
  return (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
			& (std::underlying_type<dump_flags_t>::type)rhs);
}

static inline dump_flags_t
operator~ (dump_flags_t flags)
{
  return (dump_flags_t)~((std::underlying_type<dump_flags_t>::type)flags);
}

static inline dump_flags_t &
operator|= (dump_flags_t &lhs, dump_flags_t rhs)
{
  lhs = (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
		       | (std::underlying_type<dump_flags_t>::type)rhs);
  return lhs;
}

static inline dump_flags_t &
operator&= (dump_flags_t &lhs, dump_flags_t rhs)
{
  lhs = (dump_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
		       & (std::underlying_type<dump_flags_t>::type)rhs);
  return lhs;
}

/* Flags to control high-level -fopt-info dumps.  Usually these flags
   define a group of passes.  An optimization pass can be part of
   multiple groups.  */

enum optgroup_flag
{
  OPTGROUP_NONE = 0,

  /* IPA optimization passes */
  OPTGROUP_IPA  = (1 << 1),

  /* Loop optimization passes */
  OPTGROUP_LOOP = (1 << 2),

  /* Inlining passes */
  OPTGROUP_INLINE = (1 << 3),

  /* OMP (Offloading and Multi Processing) transformations */
  OPTGROUP_OMP = (1 << 4),

  /* Vectorization passes */
  OPTGROUP_VEC = (1 << 5),

  /* All other passes */
  OPTGROUP_OTHER = (1 << 6),

  OPTGROUP_ALL = (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE
		  | OPTGROUP_OMP | OPTGROUP_VEC | OPTGROUP_OTHER)
};

typedef enum optgroup_flag optgroup_flags_t;

static inline optgroup_flags_t
operator| (optgroup_flags_t lhs, optgroup_flags_t rhs)
{
  return (optgroup_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
			    | (std::underlying_type<dump_flags_t>::type)rhs);
}

static inline optgroup_flags_t &
operator|= (optgroup_flags_t &lhs, optgroup_flags_t rhs)
{
  lhs = (optgroup_flags_t)((std::underlying_type<dump_flags_t>::type)lhs
			   | (std::underlying_type<dump_flags_t>::type)rhs);
  return lhs;
}

/* Define a tree dump switch.  */
struct dump_file_info
{
  /* Suffix to give output file.  */
  const char *suffix;
  /* Command line dump switch.  */
  const char *swtch;
  /* Command line glob.  */
  const char *glob;
  /* Filename for the pass-specific stream.  */
  const char *pfilename;
  /* Filename for the -fopt-info stream.  */
  const char *alt_filename;
  /* Pass-specific dump stream.  */
  FILE *pstream;
  /* -fopt-info stream.  */
  FILE *alt_stream;
  /* Dump kind.  */
  dump_kind dkind;
  /* Dump flags.  */
  dump_flags_t pflags;
  /* A pass flags for -fopt-info.  */
  dump_flags_t alt_flags;
  /* Flags for -fopt-info given by a user.  */
  optgroup_flags_t optgroup_flags;
  /* State of pass-specific stream.  */
  int pstate;
  /* State of the -fopt-info stream.  */
  int alt_state;
  /* Dump file number.  */
  int num;
  /* Fields "suffix", "swtch", "glob" can be const strings,
     or can be dynamically allocated, needing free.  */
  bool owns_strings;
  /* When a given dump file is being initialized, this flag is set to true
     if the corresponding TDF_graph dump file has also been initialized.  */
  bool graph_dump_initialized;
};

/* A class for describing where in the user's source that a dump message
   relates to, with various constructors for convenience.
   In particular, this lets us associate dump messages
   with hotness information (e.g. from PGO), allowing them to
   be prioritized by code hotness.  */

class dump_user_location_t
{
 public:
  /* Default constructor, analogous to UNKNOWN_LOCATION.  */
  dump_user_location_t () : m_count (), m_loc (UNKNOWN_LOCATION) {}

  /* Construct from a gimple statement (using its location and hotness).  */
  dump_user_location_t (const gimple *stmt);

  /* Construct from an RTL instruction (using its location and hotness).  */
  dump_user_location_t (const rtx_insn *insn);

  /* Construct from a location_t.  This one is deprecated (since it doesn't
     capture hotness information); it thus needs to be spelled out.  */
  static dump_user_location_t
  from_location_t (location_t loc)
  {
    return dump_user_location_t (profile_count (), loc);
  }

  /* Construct from a function declaration.  This one requires spelling out
     to avoid accidentally constructing from other kinds of tree.  */
  static dump_user_location_t
  from_function_decl (tree fndecl);

  profile_count get_count () const { return m_count; }
  location_t get_location_t () const { return m_loc; }

 private:
  /* Private ctor from count and location, for use by from_location_t.  */
  dump_user_location_t (profile_count count, location_t loc)
    : m_count (count), m_loc (loc)
  {}

  profile_count m_count;
  location_t m_loc;
};

/* A class for identifying where in the compiler's own source
   (or a plugin) that a dump message is being emitted from.  */

class dump_impl_location_t
{
public:
  dump_impl_location_t (
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
			const char *file = __builtin_FILE (),
			int line = __builtin_LINE (),
			const char *function = __builtin_FUNCTION ()
#else
			const char *file = __FILE__,
			int line = __LINE__,
			const char *function = NULL
#endif
  )
  : m_file (file), m_line (line), m_function (function)
  {}

  const char *m_file;
  int m_line;
  const char *m_function;
};

/* A bundle of metadata for describing a dump message:
   (a) the dump_flags
   (b) the source location within the compiler/plugin.

   The constructors use default parameters so that (b) gets sets up
   automatically.

   Hence you can pass in e.g. MSG_NOTE, and the dump call
   will automatically record where in GCC's source code the
   dump was emitted from.  */

class dump_metadata_t
{
 public:
  dump_metadata_t (dump_flags_t dump_flags,
		   const dump_impl_location_t &impl_location
		     = dump_impl_location_t ())
  : m_dump_flags (dump_flags),
    m_impl_location (impl_location)
  {
  }

  dump_flags_t get_dump_flags () const { return m_dump_flags; }

  const dump_impl_location_t &
  get_impl_location () const { return m_impl_location; }

 private:
  dump_flags_t m_dump_flags;
  dump_impl_location_t m_impl_location;
};

/* A bundle of information for describing the location of a dump message:
   (a) the source location and hotness within the user's code, together with
   (b) the source location within the compiler/plugin.

   The constructors use default parameters so that (b) gets sets up
   automatically.

   The upshot is that you can pass in e.g. a gimple * to dump_printf_loc,
   and the dump call will automatically record where in GCC's source
   code the dump was emitted from.  */

class dump_location_t
{
 public:
  /* Default constructor, analogous to UNKNOWN_LOCATION.  */
  dump_location_t (const dump_impl_location_t &impl_location
		     = dump_impl_location_t ())
  : m_user_location (dump_user_location_t ()),
    m_impl_location (impl_location)
  {
  }

  /* Construct from a gimple statement (using its location and hotness).  */
  dump_location_t (const gimple *stmt,
		   const dump_impl_location_t &impl_location
		     = dump_impl_location_t ())
  : m_user_location (dump_user_location_t (stmt)),
    m_impl_location (impl_location)
  {
  }

  /* Construct from an RTL instruction (using its location and hotness).  */
  dump_location_t (const rtx_insn *insn,
		   const dump_impl_location_t &impl_location
		   = dump_impl_location_t ())
  : m_user_location (dump_user_location_t (insn)),
    m_impl_location (impl_location)
  {
  }

  /* Construct from a dump_user_location_t.  */
  dump_location_t (const dump_user_location_t &user_location,
		   const dump_impl_location_t &impl_location
		     = dump_impl_location_t ())
  : m_user_location (user_location),
    m_impl_location (impl_location)
  {
  }

  /* Construct from a location_t.  This one is deprecated (since it doesn't
     capture hotness information), and thus requires spelling out.  */
  static dump_location_t
  from_location_t (location_t loc,
		   const dump_impl_location_t &impl_location
		     = dump_impl_location_t ())
  {
    return dump_location_t (dump_user_location_t::from_location_t (loc),
			    impl_location);
  }

  const dump_user_location_t &
  get_user_location () const { return m_user_location; }

  const dump_impl_location_t &
  get_impl_location () const { return m_impl_location; }

  location_t get_location_t () const
  {
    return m_user_location.get_location_t ();
  }

  profile_count get_count () const { return m_user_location.get_count (); }

 private:
  dump_user_location_t m_user_location;
  dump_impl_location_t m_impl_location;
};

/* In dumpfile.cc */
extern FILE *dump_begin (int, dump_flags_t *, int part=-1);
extern void dump_end (int, FILE *);
extern int opt_info_switch_p (const char *);
extern const char *dump_flag_name (int);
extern const kv_pair<optgroup_flags_t> optgroup_options[];
extern dump_flags_t
parse_dump_option (const char *, const char **);

/* Global variables used to communicate with passes.  */
extern FILE *dump_file;
extern dump_flags_t dump_flags;
extern const char *dump_file_name;

extern bool dumps_are_enabled;

extern void set_dump_file (FILE *new_dump_file);

/* Return true if any of the dumps is enabled, false otherwise. */
static inline bool
dump_enabled_p (void)
{
  return dumps_are_enabled;
}

/* The following API calls (which *don't* take a "FILE *")
   write the output to zero or more locations.

   Some destinations are written to immediately as dump_* calls
   are made; for others, the output is consolidated into an "optinfo"
   instance (with its own metadata), and only emitted once the optinfo
   is complete.

   The destinations are:

   (a) the "immediate" destinations:
       (a.1) the active dump_file, if any
       (a.2) the -fopt-info destination, if any
   (b) the "optinfo" destinations, if any:
       (b.1) as optimization records

   dump_* (MSG_*) --> dumpfile.cc --> items --> (a.1) dump_file
                                       |   `-> (a.2) alt_dump_file
                                       |
                                       `--> (b) optinfo
                                                `---> optinfo destinations
                                                      (b.1) optimization records

   For optinfos, the dump_*_loc mark the beginning of an optinfo
   instance: all subsequent dump_* calls are consolidated into
   that optinfo, until the next dump_*_loc call (or a change in
   dump scope, or a call to dumpfile_ensure_any_optinfo_are_flushed).

   A group of dump_* calls should be guarded by:

     if (dump_enabled_p ())

   to minimize the work done for the common case where dumps
   are disabled.  */

extern void dump_printf (const dump_metadata_t &, const char *, ...)
  ATTRIBUTE_GCC_DUMP_PRINTF (2, 3);

extern void dump_printf_loc (const dump_metadata_t &, const dump_user_location_t &,
			     const char *, ...)
  ATTRIBUTE_GCC_DUMP_PRINTF (3, 4);
extern void dump_function (int phase, tree fn);
extern void dump_basic_block (dump_flags_t, basic_block, int);
extern void dump_generic_expr_loc (const dump_metadata_t &,
				   const dump_user_location_t &,
				   dump_flags_t, tree);
extern void dump_generic_expr (const dump_metadata_t &, dump_flags_t, tree);
extern void dump_gimple_stmt_loc (const dump_metadata_t &,
				  const dump_user_location_t &,
				  dump_flags_t, gimple *, int);
extern void dump_gimple_stmt (const dump_metadata_t &, dump_flags_t, gimple *, int);
extern void dump_gimple_expr_loc (const dump_metadata_t &,
				  const dump_user_location_t &,
				  dump_flags_t, gimple *, int);
extern void dump_gimple_expr (const dump_metadata_t &, dump_flags_t, gimple *, int);
extern void dump_symtab_node (const dump_metadata_t &, symtab_node *);

template<unsigned int N, typename C>
void dump_dec (const dump_metadata_t &, const poly_int<N, C> &);
extern void dump_dec (dump_flags_t, const poly_wide_int &, signop);
extern void dump_hex (dump_flags_t, const poly_wide_int &);

extern void dumpfile_ensure_any_optinfo_are_flushed ();

/* Managing nested scopes, so that dumps can express the call chain
   leading to a dump message.  */

extern unsigned int get_dump_scope_depth ();
extern void dump_begin_scope (const char *name,
			      const dump_user_location_t &user_location,
			      const dump_impl_location_t &impl_location);
extern void dump_end_scope ();

/* Implementation detail of the AUTO_DUMP_SCOPE macro below.

   A RAII-style class intended to make it easy to emit dump
   information about entering and exiting a collection of nested
   function calls.  */

class auto_dump_scope
{
 public:
  auto_dump_scope (const char *name,
		   const dump_user_location_t &user_location,
		   const dump_impl_location_t &impl_location
		   = dump_impl_location_t ())
  {
    if (dump_enabled_p ())
      dump_begin_scope (name, user_location, impl_location);
  }
  ~auto_dump_scope ()
  {
    if (dump_enabled_p ())
      dump_end_scope ();
  }
};

/* A macro for calling:
     dump_begin_scope (NAME, USER_LOC);
   via an RAII object, thus printing "=== MSG ===\n" to the dumpfile etc,
   and then calling
     dump_end_scope ();
   once the object goes out of scope, thus capturing the nesting of
   the scopes.

   These scopes affect dump messages within them: dump messages at the
   top level implicitly default to MSG_PRIORITY_USER_FACING, whereas those
   in a nested scope implicitly default to MSG_PRIORITY_INTERNALS.  */

#define AUTO_DUMP_SCOPE(NAME, USER_LOC) \
  auto_dump_scope scope (NAME, USER_LOC)

extern void dump_function (int phase, tree fn);
extern void print_combine_total_stats (void);
extern bool enable_rtl_dump_file (void);

/* In tree-dump.cc  */
extern void dump_node (const_tree, dump_flags_t, FILE *);

/* In combine.cc  */
extern void dump_combine_total_stats (FILE *);
/* In cfghooks.cc  */
extern void dump_bb (FILE *, basic_block, int, dump_flags_t);

class opt_pass;

namespace gcc {

/* A class for managing all of the various dump files used by the
   optimization passes.  */

class dump_manager
{
public:

  dump_manager ();
  ~dump_manager ();

  /* Register a dumpfile.

     TAKE_OWNERSHIP determines whether callee takes ownership of strings
     SUFFIX, SWTCH, and GLOB. */
  unsigned int
  dump_register (const char *suffix, const char *swtch, const char *glob,
		 dump_kind dkind, optgroup_flags_t optgroup_flags,
		 bool take_ownership);

  /* Allow languages and middle-end to register their dumps before the
     optimization passes.  */
  void
  register_dumps ();

  /* Return the dump_file_info for the given phase.  */
  struct dump_file_info *
  get_dump_file_info (int phase) const;

  struct dump_file_info *
  get_dump_file_info_by_switch (const char *swtch) const;

  /* Return the name of the dump file for the given phase.
     If the dump is not enabled, returns NULL.  */
  char *
  get_dump_file_name (int phase, int part = -1) const;

  char *
  get_dump_file_name (struct dump_file_info *dfi, int part = -1) const;

  void
  dump_switch_p (const char *arg);

  /* 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
  dump_start (int phase, dump_flags_t *flag_ptr);

  /* Finish a tree dump for PHASE and close associated dump streams.  Also
     reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS.  */
  void
  dump_finish (int phase);

  FILE *
  dump_begin (int phase, dump_flags_t *flag_ptr, int part);

  /* Returns nonzero if tree dump PHASE has been initialized.  */
  int
  dump_initialized_p (int phase) const;

  /* Returns the switch name of PHASE.  */
  const char *
  dump_flag_name (int phase) const;

  void register_pass (opt_pass *pass);

private:

  int
  dump_phase_enabled_p (int phase) const;

  int
  dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob);

  int
  dump_enable_all (dump_kind dkind, dump_flags_t flags, const char *filename);

  int
  opt_info_enable_passes (optgroup_flags_t optgroup_flags, dump_flags_t flags,
			  const char *filename);

  bool update_dfi_for_opt_info (dump_file_info *dfi) const;

private:

  /* Dynamically registered dump files and switches.  */
  int m_next_dump;
  struct dump_file_info *m_extra_dump_files;
  size_t m_extra_dump_files_in_use;
  size_t m_extra_dump_files_alloced;

  /* Stored values from -fopt-info, for handling passes created after
     option-parsing (by backends and by plugins).  */
  optgroup_flags_t m_optgroup_flags;
  dump_flags_t m_optinfo_flags;
  char *m_optinfo_filename;

  /* Grant access to dump_enable_all.  */
  friend bool ::enable_rtl_dump_file (void);

  /* Grant access to opt_info_enable_passes.  */
  friend int ::opt_info_switch_p (const char *arg);

}; // class dump_manager

} // namespace gcc

#endif /* GCC_DUMPFILE_H */
