LCOV - code coverage report
Current view: top level - gcc/cp - error.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.0 % 2859 2515
Test Date: 2026-05-11 19:44:49 Functions: 96.3 % 109 105
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Call-backs for C++ error reporting.
       2              :    This code is non-reentrant.
       3              :    Copyright (C) 1993-2026 Free Software Foundation, Inc.
       4              :    This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify
       7              : it under the terms of the GNU General Public License as published by
       8              : the Free Software Foundation; either version 3, or (at your option)
       9              : any later version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful,
      12              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : GNU General Public License for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #define INCLUDE_VECTOR
      21              : #include "config.h"
      22              : /* For use with name_hint.  */
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "cp-tree.h"
      26              : #include "stringpool.h"
      27              : #include "tree-diagnostic.h"
      28              : #include "diagnostics/color.h"
      29              : #include "langhooks-def.h"
      30              : #include "intl.h"
      31              : #include "cxx-pretty-print.h"
      32              : #include "tree-pretty-print.h"
      33              : #include "tree-pretty-print-markup.h"
      34              : #include "gimple-pretty-print.h"
      35              : #include "c-family/c-objc.h"
      36              : #include "ubsan.h"
      37              : #include "internal-fn.h"
      38              : #include "c-family/c-type-mismatch.h"
      39              : #include "cp-name-hint.h"
      40              : #include "attribs.h"
      41              : #include "pretty-print-format-impl.h"
      42              : #include "diagnostics/text-sink.h"
      43              : 
      44              : #define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
      45              : #define pp_separate_with_semicolon(PP) pp_cxx_separate_with (PP, ';')
      46              : 
      47              : /* cxx_pp is a C++ front-end-specific pretty printer: this is where we
      48              :    dump C++ ASTs as strings. It is mostly used only by the various
      49              :    tree -> string functions that are occasionally called from the
      50              :    debugger or by the front-end for things like
      51              :    __PRETTY_FUNCTION__.  */
      52              : static cxx_pretty_printer actual_pretty_printer;
      53              : static cxx_pretty_printer * const cxx_pp = &actual_pretty_printer;
      54              : 
      55              : /* Translate if being used for diagnostics, but not for dump files or
      56              :    __PRETTY_FUNCTION.  */
      57              : #define M_(msgid) (pp_translate_identifiers (cxx_pp) ? _(msgid) : (msgid))
      58              : 
      59              : # define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
      60              : 
      61              : static const char *args_to_string (tree, int);
      62              : static const char *code_to_string (enum tree_code);
      63              : static const char *cv_to_string (tree, int);
      64              : static const char *decl_to_string (tree, int, bool);
      65              : static const char *fndecl_to_string (tree, int);
      66              : static const char *op_to_string (bool, enum tree_code);
      67              : static const char *parm_to_string (int);
      68              : static const char *type_to_string (tree, int, bool, bool *, bool,
      69              :                                    const char * = nullptr);
      70              : 
      71              : static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int);
      72              : static void dump_type (cxx_pretty_printer *, tree, int);
      73              : static void dump_typename (cxx_pretty_printer *, tree, int);
      74              : static void dump_simple_decl (cxx_pretty_printer *, tree, tree, int);
      75              : static void dump_decl (cxx_pretty_printer *, tree, int);
      76              : static void dump_template_decl (cxx_pretty_printer *, tree, int);
      77              : static void dump_function_decl (cxx_pretty_printer *, tree, int);
      78              : static void dump_expr (cxx_pretty_printer *, tree, int);
      79              : static void dump_unary_op (cxx_pretty_printer *, const char *, tree, int);
      80              : static void dump_binary_op (cxx_pretty_printer *, const char *, tree, int);
      81              : static void dump_aggr_type (cxx_pretty_printer *, tree, int);
      82              : static void dump_type_prefix (cxx_pretty_printer *, tree, int);
      83              : static void dump_type_suffix (cxx_pretty_printer *, tree, int);
      84              : static void dump_function_name (cxx_pretty_printer *, tree, int);
      85              : static void dump_call_expr_args (cxx_pretty_printer *, tree, int, bool);
      86              : static void dump_expr_list (cxx_pretty_printer *, tree, int);
      87              : static void dump_global_iord (cxx_pretty_printer *, tree);
      88              : static void dump_parameters (cxx_pretty_printer *, tree, int);
      89              : static void dump_ref_qualifier (cxx_pretty_printer *, tree, int);
      90              : static void dump_exception_spec (cxx_pretty_printer *, tree, int);
      91              : static void dump_template_argument (cxx_pretty_printer *, tree, int);
      92              : static void dump_template_argument_list (cxx_pretty_printer *, tree, int);
      93              : static void dump_template_parameter (cxx_pretty_printer *, tree, int);
      94              : static void dump_template_bindings (cxx_pretty_printer *, tree, tree,
      95              :                                     vec<tree, va_gc> *);
      96              : static void dump_scope (cxx_pretty_printer *, tree, int);
      97              : static void dump_template_parms (cxx_pretty_printer *, tree, int, int);
      98              : static int get_non_default_template_args_count (tree, int);
      99              : static const char *function_category (tree);
     100              : static void maybe_print_constexpr_context (diagnostics::text_sink &);
     101              : static void maybe_print_instantiation_context (diagnostics::text_sink &);
     102              : static void print_instantiation_full_context (diagnostics::text_sink &);
     103              : static void print_instantiation_partial_context (diagnostics::text_sink &,
     104              :                                                  struct tinst_level *,
     105              :                                                  location_t);
     106              : static void maybe_print_constraint_context (diagnostics::text_sink &);
     107              : static void cp_diagnostic_text_starter (diagnostics::text_sink &,
     108              :                                         const diagnostics::diagnostic_info *);
     109              : static void cp_print_error_function (diagnostics::text_sink &,
     110              :                                      const diagnostics::diagnostic_info *);
     111              : 
     112              : static bool cp_printer (pretty_printer *, text_info *, const char *,
     113              :                         int, bool, bool, bool, bool *, pp_token_list &);
     114              : 
     115              : /* Color names for highlighting "%qH" vs "%qI" values,
     116              :    and ranges corresponding to them.  */
     117              : const char *const highlight_colors::percent_h = "highlight-a";
     118              : const char *const highlight_colors::percent_i = "highlight-b";
     119              : 
     120              : /* Struct for handling %H or %I, which require delaying printing the
     121              :    type until a postprocessing stage.  */
     122              : 
     123       125940 : class deferred_printed_type
     124              : {
     125              : public:
     126       340132 :   deferred_printed_type ()
     127       340132 :   : m_tree (NULL_TREE),
     128       340132 :     m_printed_text (),
     129       340132 :     m_token_list (nullptr),
     130        20990 :     m_verbose (false), m_quote (false)
     131              :   {}
     132              : 
     133        20990 :   deferred_printed_type (tree type,
     134              :                          pp_token_list &token_list,
     135              :                          bool verbose,
     136              :                          bool quote)
     137        20990 :   : m_tree (type),
     138        20990 :     m_printed_text (),
     139        20990 :     m_token_list (&token_list),
     140        20990 :     m_verbose (verbose),
     141        20990 :     m_quote (quote)
     142              :   {
     143        20990 :     gcc_assert (type);
     144              :   }
     145              : 
     146        20990 :   void set_text_for_token_list (const char *text, bool quote)
     147              :   {
     148              :     /* Replace the contents of m_token_list with a text token for TEXT,
     149              :        possibly wrapped by BEGIN_QUOTE/END_QUOTE (if QUOTE is true).
     150              :        This allows us to ignore any {BEGIN,END}_QUOTE tokens added
     151              :        by %qH and %qI, and instead use the quoting from type_to_string,
     152              :        and its logic for "aka".  */
     153        62970 :     while (m_token_list->m_first)
     154        41980 :       m_token_list->pop_front ();
     155              : 
     156        20990 :     if (quote)
     157          334 :       m_token_list->push_back<pp_token_begin_quote> ();
     158              : 
     159              :     // TEXT is gc-allocated, so we can borrow it
     160        20990 :     m_token_list->push_back_text (label_text::borrow (text));
     161              : 
     162        20990 :     if (quote)
     163          334 :       m_token_list->push_back<pp_token_end_quote> ();
     164        20990 :   }
     165              : 
     166              :   /* The tree is not GTY-marked: they are only non-NULL within a
     167              :      call to pp_format.  */
     168              :   tree m_tree;
     169              :   label_text m_printed_text;
     170              :   pp_token_list *m_token_list;
     171              :   bool m_verbose;
     172              :   bool m_quote;
     173              : };
     174              : 
     175              : /* Subclass of format_postprocessor for the C++ frontend.
     176              :    This handles the %H and %I formatting codes, printing them
     177              :    in a postprocessing phase (since they affect each other).  */
     178              : 
     179              : class cxx_format_postprocessor : public format_postprocessor
     180              : {
     181              :  public:
     182       319142 :   cxx_format_postprocessor ()
     183       319142 :   : m_type_a (), m_type_b ()
     184              :   {}
     185              : 
     186              :   std::unique_ptr<format_postprocessor>
     187       220660 :   clone() const final override
     188              :   {
     189       220660 :     return std::make_unique<cxx_format_postprocessor> ();
     190              :   }
     191              : 
     192              :   void handle (pretty_printer *pp) final override;
     193              : 
     194              :   deferred_printed_type m_type_a;
     195              :   deferred_printed_type m_type_b;
     196              : };
     197              : 
     198              : /* Constructor and destructor for cxx_dump_pretty_printer, defined here to
     199              :    avoid needing to move cxx_format_postprocessor into the header as well.  */
     200              : 
     201    884431652 : cxx_dump_pretty_printer::
     202    884431652 : cxx_dump_pretty_printer (int phase)
     203    884431652 :   : phase (phase)
     204              : {
     205    884431652 :   outf = dump_begin (phase, &flags);
     206    884431652 :   if (outf)
     207              :     {
     208            0 :       pp_format_decoder (this) = cp_printer;
     209            0 :       set_format_postprocessor (std::make_unique<cxx_format_postprocessor> ());
     210            0 :       set_output_stream (outf);
     211              :     }
     212    884431652 : }
     213              : 
     214    884431652 : cxx_dump_pretty_printer::
     215    884431652 : ~cxx_dump_pretty_printer ()
     216              : {
     217    884431652 :   if (outf)
     218              :     {
     219            0 :       pp_flush (this);
     220            0 :       dump_end (phase, outf);
     221              :     }
     222    884431652 : }
     223              : 
     224              : /* Return the in-scope template that's currently being parsed, or
     225              :    NULL_TREE otherwise.  */
     226              : 
     227              : static tree
     228        86789 : get_current_template ()
     229              : {
     230        86789 :   if (scope_chain && in_template_context && !current_instantiation ())
     231        10796 :     if (tree ti = get_template_info (current_scope ()))
     232              :       {
     233         4827 :         if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)) && TI_PARTIAL_INFO (ti))
     234           24 :           ti = TI_PARTIAL_INFO (ti);
     235         4827 :         return TI_TEMPLATE (ti);
     236              :       }
     237              : 
     238              :   return NULL_TREE;
     239              : }
     240              : 
     241              : /* A map from TEMPLATE_DECLs that we've determined to be erroneous
     242              :    at parse time to the location of the first error within.  */
     243              : 
     244              : erroneous_templates_t *erroneous_templates;
     245              : 
     246              : /* Callback function diagnostics::context::m_adjust_diagnostic_info.
     247              : 
     248              :    Errors issued when parsing a template are automatically treated like
     249              :    permerrors associated with the -Wtemplate-body flag and can be
     250              :    downgraded into warnings accordingly, in which case we'll still
     251              :    issue an error if we later need to instantiate the template.  */
     252              : 
     253              : static void
     254     97631972 : cp_adjust_diagnostic_info (const diagnostics::context &context,
     255              :                            diagnostics::diagnostic_info *diagnostic)
     256              : {
     257     97631972 :   if (diagnostic->m_kind == diagnostics::kind::error)
     258        86771 :     if (tree tmpl = get_current_template ())
     259              :       {
     260         4809 :         diagnostic->m_option_id = OPT_Wtemplate_body;
     261              : 
     262         4809 :         if (context.m_permissive)
     263           48 :           diagnostic->m_kind = diagnostics::kind::warning;
     264              : 
     265         4809 :         bool existed;
     266         4809 :         location_t &error_loc
     267         4809 :           = hash_map_safe_get_or_insert<true> (erroneous_templates,
     268              :                                                tmpl, &existed);
     269         4809 :         if (!existed)
     270              :           /* Remember that this template had a parse-time error so
     271              :              that we'll ensure a hard error has been issued upon
     272              :              its instantiation.  */
     273         2316 :           error_loc = diagnostic->m_richloc->get_loc ();
     274              :       }
     275     97631972 : }
     276              : 
     277              : /* A generalization of seen_error which also returns true if we've
     278              :    permissively downgraded an error to a warning inside a template.  */
     279              : 
     280              : bool
     281      8638295 : cp_seen_error ()
     282              : {
     283      8638295 :   if ((seen_error) ())
     284              :     return true;
     285              : 
     286      8616494 :   if (erroneous_templates)
     287           18 :     if (tree tmpl = get_current_template ())
     288           18 :       if (erroneous_templates->get (tmpl))
     289           18 :         return true;
     290              : 
     291              :   return false;
     292              : }
     293              : 
     294              : /* CONTEXT->printer is a basic pretty printer that was constructed
     295              :    presumably by diagnostic_initialize(), called early in the
     296              :    compiler's initialization process (in general_init) Before the FE
     297              :    is initialized.  This (C++) FE-specific diagnostic initializer is
     298              :    thus replacing the basic pretty printer with one that has C++-aware
     299              :    capacities.  */
     300              : 
     301              : void
     302        98482 : cxx_initialize_diagnostics (diagnostics::context *context)
     303              : {
     304        98482 :   cxx_pretty_printer *pp = new cxx_pretty_printer ();
     305        98482 :   pp->set_format_postprocessor (std::make_unique<cxx_format_postprocessor> ());
     306        98482 :   context->set_pretty_printer (std::unique_ptr<pretty_printer> (pp));
     307              : 
     308        98482 :   c_common_diagnostics_set_defaults (context);
     309        98482 :   diagnostics::text_starter (context) = cp_diagnostic_text_starter;
     310              :   /* diagnostic_finalizer is already c_diagnostic_text_finalizer.  */
     311        98482 :   context->set_format_decoder (cp_printer);
     312        98482 :   context->set_adjust_diagnostic_info_callback (cp_adjust_diagnostic_info);
     313        98482 : }
     314              : 
     315              : /* Dump an '@module' name suffix for DECL, if it's attached to an import.  */
     316              : 
     317              : static void
     318    226425938 : dump_module_suffix (cxx_pretty_printer *pp, tree decl)
     319              : {
     320    226425938 :   if (!modules_p ())
     321              :     return;
     322              : 
     323       177070 :   if (!DECL_CONTEXT (decl))
     324              :     return;
     325              : 
     326       176431 :   if (TREE_CODE (decl) != CONST_DECL
     327       176431 :       || !UNSCOPED_ENUM_P (DECL_CONTEXT (decl)))
     328              :     {
     329       176403 :       if (!DECL_NAMESPACE_SCOPE_P (decl))
     330              :         return;
     331              : 
     332        85944 :       if (TREE_CODE (decl) == NAMESPACE_DECL
     333            0 :           && !DECL_NAMESPACE_ALIAS (decl)
     334        85944 :           && (TREE_PUBLIC (decl) || !TREE_PUBLIC (CP_DECL_CONTEXT (decl))))
     335              :         return;
     336              :     }
     337              : 
     338        85972 :   int m = get_originating_module (decl, /*global=-1*/true);
     339        85972 :   if (m > 0)
     340          402 :     if (const char *n = module_name (m, false))
     341              :       {
     342          402 :         pp_character (pp, '@');
     343          402 :         pp->set_padding (pp_none);
     344          402 :         pp_string (pp, n);
     345              :       }
     346              : }
     347              : 
     348              : /* The scope of the declaration we're currently printing, to avoid redundantly
     349              :    dumping the same scope on parameter types.  */
     350              : static tree current_dump_scope;
     351              : 
     352              : /* Dump a scope, if deemed necessary.  */
     353              : 
     354              : static void
     355    174570225 : dump_scope (cxx_pretty_printer *pp, tree scope, int flags)
     356              : {
     357    174570225 :   int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF);
     358              : 
     359    174570225 :   if (scope == NULL_TREE || scope == current_dump_scope)
     360              :     return;
     361              : 
     362              :   /* Enum values within an unscoped enum will be CONST_DECL with an
     363              :      ENUMERAL_TYPE as their "scope".  Use CP_TYPE_CONTEXT of the
     364              :      ENUMERAL_TYPE, so as to print any enclosing namespace.  */
     365    174350428 :   if (UNSCOPED_ENUM_P (scope))
     366          202 :     scope = CP_TYPE_CONTEXT (scope);
     367              : 
     368    174350428 :   if (TREE_CODE (scope) == NAMESPACE_DECL)
     369              :     {
     370    156148413 :       if (scope != global_namespace)
     371              :         {
     372     87198709 :           dump_decl (pp, scope, f);
     373     87198709 :           pp_cxx_colon_colon (pp);
     374              :         }
     375              :     }
     376     18202015 :   else if (AGGREGATE_TYPE_P (scope)
     377     18202015 :            || SCOPED_ENUM_P (scope))
     378              :     {
     379     17799461 :       dump_type (pp, scope, f);
     380     17799461 :       pp_cxx_colon_colon (pp);
     381              :     }
     382       402554 :   else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
     383              :     {
     384       387874 :       dump_function_decl (pp, scope, f | TFF_NO_TEMPLATE_BINDINGS);
     385       387874 :       pp_cxx_colon_colon (pp);
     386              :     }
     387              : }
     388              : 
     389              : /* Dump the template ARGument under control of FLAGS.  */
     390              : 
     391              : static void
     392    149061797 : dump_template_argument (cxx_pretty_printer *pp, tree arg, int flags)
     393              : {
     394    149061797 :   if (ARGUMENT_PACK_P (arg))
     395      7139366 :     dump_template_argument_list (pp, ARGUMENT_PACK_ARGS (arg),
     396              :                                  /* No default args in argument packs.  */
     397              :                                  flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
     398    141922431 :   else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
     399    121204168 :     dump_type (pp, arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
     400              :   else
     401              :     {
     402     20718263 :       if (TREE_CODE (arg) == TREE_LIST)
     403            0 :         arg = TREE_VALUE (arg);
     404              : 
     405              :       /* Strip implicit conversions.  */
     406     20718323 :       while (CONVERT_EXPR_P (arg))
     407           60 :         arg = TREE_OPERAND (arg, 0);
     408              : 
     409     20718263 :       dump_expr (pp, arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
     410              :     }
     411    149061797 : }
     412              : 
     413              : /* Count the number of template arguments ARGS whose value does not
     414              :    match the (optional) default template parameter in PARAMS  */
     415              : 
     416              : static int
     417     95334819 : get_non_default_template_args_count (tree args, int flags)
     418              : {
     419     95334819 :   int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args));
     420              : 
     421     95334819 :   if (/* We use this flag when generating debug information.  We don't
     422              :          want to expand templates at this point, for this may generate
     423              :          new decls, which gets decl counts out of sync, which may in
     424              :          turn cause codegen differences between compilations with and
     425              :          without -g.  */
     426     95334819 :       (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0
     427      4123224 :       || !flag_pretty_templates)
     428              :     return n;
     429              : 
     430      4123167 :   return GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (INNERMOST_TEMPLATE_ARGS (args));
     431              : }
     432              : 
     433              : /* Dump a template-argument-list ARGS (always a TREE_VEC) under control
     434              :    of FLAGS.  */
     435              : 
     436              : static void
     437      7143059 : dump_template_argument_list (cxx_pretty_printer *pp, tree args, int flags)
     438              : {
     439      7143059 :   int n = get_non_default_template_args_count (args, flags);
     440      7143059 :   int need_comma = 0;
     441      7143059 :   int i;
     442              : 
     443     21305839 :   for (i = 0; i < n; ++i)
     444              :     {
     445     14162780 :       tree arg = TREE_VEC_ELT (args, i);
     446              : 
     447              :       /* Only print a comma if we know there is an argument coming. In
     448              :          the case of an empty template argument pack, no actual
     449              :          argument will be printed.  */
     450     14162780 :       if (need_comma
     451     14162780 :           && (!ARGUMENT_PACK_P (arg)
     452          188 :               || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
     453      7570691 :         pp_separate_with_comma (pp);
     454              : 
     455     14162780 :       dump_template_argument (pp, arg, flags);
     456     14162780 :       need_comma = 1;
     457              :     }
     458      7143059 : }
     459              : 
     460              : /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS.  */
     461              : 
     462              : static void
     463        74694 : dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags)
     464              : {
     465        74694 :   tree p;
     466        74694 :   tree a;
     467              : 
     468        74694 :   if (parm == error_mark_node)
     469              :    return;
     470              : 
     471        74694 :   p = TREE_VALUE (parm);
     472        74694 :   a = TREE_PURPOSE (parm);
     473              : 
     474        74694 :   if (TREE_CODE (p) == TYPE_DECL)
     475              :     {
     476        67480 :       if (flags & TFF_DECL_SPECIFIERS)
     477              :         {
     478        10609 :           pp_cxx_ws_string (pp, "class");
     479        10609 :           if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p)))
     480          854 :             pp_cxx_ws_string (pp, "...");
     481        10609 :           if (DECL_NAME (p))
     482         9866 :             pp_cxx_tree_identifier (pp, DECL_NAME (p));
     483              :         }
     484        56871 :       else if (DECL_NAME (p))
     485        56053 :         pp_cxx_tree_identifier (pp, DECL_NAME (p));
     486              :       else
     487          818 :         pp_cxx_canonical_template_parameter (pp, TREE_TYPE (p));
     488              :     }
     489              :   else
     490         7214 :     dump_decl (pp, p, flags | TFF_DECL_SPECIFIERS);
     491              : 
     492        74694 :   if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
     493              :     {
     494            0 :       pp_cxx_whitespace (pp);
     495            0 :       pp_equal (pp);
     496            0 :       pp_cxx_whitespace (pp);
     497            0 :       if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
     498            0 :         dump_type (pp, a, flags & ~TFF_CHASE_TYPEDEF);
     499              :       else
     500            0 :         dump_expr (pp, a, flags | TFF_EXPR_IN_PARENS);
     501              :     }
     502              : }
     503              : 
     504              : /* Dump, under control of FLAGS, a template-parameter-list binding.
     505              :    PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a
     506              :    TREE_VEC.  */
     507              : 
     508              : static void
     509        39679 : dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
     510              :                         vec<tree, va_gc> *typenames)
     511              : {
     512              :   /* Print "[with" and ']', conditional on whether anything is printed at all.
     513              :      This is tied to whether a semicolon is needed to separate multiple template
     514              :      parameters.  */
     515        39679 :   struct prepost_semicolon
     516              :   {
     517              :     cxx_pretty_printer *pp;
     518              :     bool need_semicolon;
     519              : 
     520        73007 :     void operator() ()
     521              :     {
     522        73007 :       if (need_semicolon)
     523        33328 :         pp_separate_with_semicolon (pp);
     524              :       else
     525              :         {
     526        39679 :           pp_cxx_whitespace (pp);
     527        39679 :           pp_string (pp, colorize_start (pp_show_color (pp), "targs"));
     528        39679 :           pp_cxx_left_bracket (pp);
     529        39679 :           pp->translate_string ("with");
     530        39679 :           pp_cxx_whitespace (pp);
     531        39679 :           need_semicolon = true;
     532              :         }
     533        73007 :     }
     534              : 
     535        39679 :     ~prepost_semicolon ()
     536              :     {
     537        39679 :       if (need_semicolon)
     538              :         {
     539        39679 :           pp_cxx_right_bracket (pp);
     540        39679 :           pp_string (pp, colorize_stop (pp_show_color (pp)));
     541              :         }
     542        39679 :     }
     543        39679 :   } semicolon_or_introducer = {pp, false};
     544              : 
     545        39679 :   int i;
     546        39679 :   tree t;
     547              : 
     548        80851 :   while (parms)
     549              :     {
     550        41172 :       tree p = TREE_VALUE (parms);
     551        41172 :       int lvl = TMPL_PARMS_DEPTH (parms);
     552        41172 :       int arg_idx = 0;
     553        41172 :       int i;
     554        41172 :       tree lvl_args = NULL_TREE;
     555              : 
     556              :       /* Don't crash if we had an invalid argument list.  */
     557       120545 :       if (TMPL_ARGS_DEPTH (args) >= lvl)
     558        82332 :         lvl_args = TMPL_ARGS_LEVEL (args, lvl);
     559              : 
     560       104151 :       for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
     561              :         {
     562        62979 :           tree arg = NULL_TREE;
     563              : 
     564              :           /* Don't crash if we had an invalid argument list.  */
     565       125952 :           if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
     566        62973 :             arg = TREE_VEC_ELT (lvl_args, arg_idx);
     567              : 
     568        62979 :           tree parm_i = TREE_VEC_ELT (p, i);
     569              :           /* If the template argument repeats the template parameter (T = T),
     570              :              skip the parameter.*/
     571        62944 :           if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM
     572         1032 :               && arg == TYPE_MAIN_VARIANT (arg)
     573         1032 :               && TREE_CODE (parm_i) == TREE_LIST
     574         1032 :               && TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL
     575         1013 :               && (TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i)))
     576              :                   == TEMPLATE_TYPE_PARM)
     577        63992 :               && (DECL_NAME (TREE_VALUE (parm_i))
     578         1013 :                   == DECL_NAME (TYPE_STUB_DECL (arg))))
     579          559 :             continue;
     580              : 
     581        62420 :           semicolon_or_introducer ();
     582        62420 :           dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER);
     583        62420 :           pp_cxx_whitespace (pp);
     584        62420 :           pp_equal (pp);
     585        62420 :           pp_cxx_whitespace (pp);
     586        62420 :           if (arg)
     587              :             {
     588        62385 :               if (ARGUMENT_PACK_P (arg))
     589         2235 :                 pp_cxx_left_brace (pp);
     590        62385 :               dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
     591        62385 :               if (ARGUMENT_PACK_P (arg))
     592         2235 :                 pp_cxx_right_brace (pp);
     593              :             }
     594              :           else
     595           35 :             pp_string (pp, M_("<missing>"));
     596              : 
     597        62420 :           ++arg_idx;
     598              :         }
     599              : 
     600        41172 :       parms = TREE_CHAIN (parms);
     601              :     }
     602              : 
     603              :   /* Don't bother with typenames for a partial instantiation.  */
     604        47920 :   if (vec_safe_is_empty (typenames) || uses_template_parms (args))
     605        31648 :     return;
     606              : 
     607              :   /* Don't try to print typenames when we're processing a clone.  */
     608         8031 :   if (current_function_decl
     609         8031 :       && !DECL_LANG_SPECIFIC (current_function_decl))
     610              :     return;
     611              : 
     612              :   /* Don't try to do this once cgraph starts throwing away front-end
     613              :      information.  */
     614         8031 :   if (at_eof >= 3)
     615              :     return;
     616              : 
     617        18388 :   FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
     618              :     {
     619        10587 :       semicolon_or_introducer ();
     620        10587 :       dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
     621        10587 :       pp_cxx_whitespace (pp);
     622        10587 :       pp_equal (pp);
     623        10587 :       pp_cxx_whitespace (pp);
     624        10587 :       push_deferring_access_checks (dk_no_check);
     625        10587 :       t = tsubst (t, args, tf_none, NULL_TREE);
     626        10587 :       pop_deferring_access_checks ();
     627              :       /* Strip typedefs.  We can't just use TFF_CHASE_TYPEDEF because
     628              :          pp_simple_type_specifier doesn't know about it.  */
     629        10587 :       t = strip_typedefs (t, NULL, STF_USER_VISIBLE);
     630        10587 :       dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
     631              :     }
     632        39679 : }
     633              : 
     634              : /* Dump a human-readable equivalent of the alias template
     635              :    specialization of T.  */
     636              : 
     637              : static void
     638         6704 : dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags)
     639              : {
     640         6704 :   gcc_assert (alias_template_specialization_p (t, nt_opaque));
     641              : 
     642         6704 :   tree decl = TYPE_NAME (t);
     643         6704 :   if (!(flags & TFF_UNQUALIFIED_NAME))
     644         6704 :     dump_scope (pp, CP_DECL_CONTEXT (decl), flags);
     645         6704 :   pp_cxx_tree_identifier (pp, DECL_NAME (decl));
     646         6704 :   dump_template_parms (pp, DECL_TEMPLATE_INFO (decl),
     647              :                        /*primary=*/false,
     648              :                        flags & ~TFF_TEMPLATE_HEADER);
     649         6704 : }
     650              : 
     651              : /* Dump a human-readable equivalent of TYPE.  FLAGS controls the
     652              :    format.  */
     653              : 
     654              : static void
     655    218587704 : dump_type (cxx_pretty_printer *pp, tree t, int flags)
     656              : {
     657    218587734 :   if (t == NULL_TREE)
     658              :     return;
     659              : 
     660              :   /* Don't print e.g. "struct mytypedef".  */
     661    218587720 :   if (TYPE_P (t) && typedef_variant_p (t))
     662              :     {
     663      1114608 :       tree decl = TYPE_NAME (t);
     664      1114608 :       if ((flags & TFF_CHASE_TYPEDEF)
     665      1114608 :                || DECL_SELF_REFERENCE_P (decl)
     666      2228621 :                || (!flag_pretty_templates
     667            6 :                    && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)))
     668              :         {
     669            0 :           unsigned int stf_flags = (!(pp->flags & pp_c_flag_gnu_v3)
     670          601 :                                     ? STF_USER_VISIBLE : 0);
     671          601 :           t = strip_typedefs (t, NULL, stf_flags);
     672              :         }
     673      1114007 :       else if (alias_template_specialization_p (t, nt_opaque))
     674              :         {
     675         6704 :           dump_alias_template_specialization (pp, t, flags);
     676         6704 :           return;
     677              :         }
     678      1107303 :       else if (same_type_p (t, TREE_TYPE (decl)))
     679              :         t = decl;
     680              :       else
     681              :         {
     682         3229 :           pp_cxx_cv_qualifier_seq (pp, t);
     683         3229 :           if (! (flags & TFF_UNQUALIFIED_NAME))
     684         3229 :             dump_scope (pp, CP_DECL_CONTEXT (decl), flags);
     685         3229 :           pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     686         3229 :           return;
     687              :         }
     688              :     }
     689              : 
     690    218577787 :   if (TYPE_PTRMEMFUNC_P (t))
     691       168482 :     goto offset_type;
     692              : 
     693    218409305 :   switch (TREE_CODE (t))
     694              :     {
     695          438 :     case LANG_TYPE:
     696          438 :       if (t == init_list_type_node)
     697          278 :         pp_string (pp, M_("<brace-enclosed initializer list>"));
     698          160 :       else if (t == unknown_type_node)
     699          160 :         pp_string (pp, M_("<unresolved overloaded function type>"));
     700              :       else
     701              :         {
     702            0 :           pp_cxx_cv_qualifier_seq (pp, t);
     703            0 :           if (tree id = TYPE_IDENTIFIER (t))
     704            0 :             pp_cxx_tree_identifier (pp, id);
     705              :         }
     706              :       break;
     707              : 
     708           91 :     case TREE_VEC:
     709           91 :       {
     710              :         /* A list of types used for a trait.  */
     711           91 :         bool need_comma = false;
     712          213 :         for (tree arg : tree_vec_range (t))
     713              :           {
     714          122 :             if (need_comma)
     715           31 :               pp_separate_with_comma (pp);
     716          122 :             dump_type (pp, arg, flags);
     717          122 :             need_comma = true;
     718              :           }
     719              :       }
     720           91 :       break;
     721              : 
     722            0 :     case TREE_LIST:
     723              :       /* A list of function parms.  */
     724            0 :       dump_parameters (pp, t, flags);
     725            0 :       break;
     726              : 
     727          293 :     case IDENTIFIER_NODE:
     728          293 :       pp_cxx_tree_identifier (pp, t);
     729          293 :       break;
     730              : 
     731           24 :     case TREE_BINFO:
     732           24 :       dump_type (pp, BINFO_TYPE (t), flags);
     733           24 :       break;
     734              : 
     735    133449550 :     case RECORD_TYPE:
     736    133449550 :     case UNION_TYPE:
     737    133449550 :     case ENUMERAL_TYPE:
     738    133449550 :       dump_aggr_type (pp, t, flags);
     739    133449550 :       break;
     740              : 
     741      1104632 :     case TYPE_DECL:
     742      1104632 :       if (flags & TFF_CHASE_TYPEDEF)
     743              :         {
     744            0 :           dump_type (pp, DECL_ORIGINAL_TYPE (t)
     745            0 :                      ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
     746            0 :           break;
     747              :         }
     748              :       /* Fall through.  */
     749              : 
     750      1579359 :     case TEMPLATE_DECL:
     751      1579359 :     case NAMESPACE_DECL:
     752      1579359 :     case CONST_DECL:
     753      1579359 :       dump_decl (pp, t, flags & ~TFF_DECL_SPECIFIERS);
     754      1579359 :       break;
     755              : 
     756     55689528 :     case INTEGER_TYPE:
     757     55689528 :     case REAL_TYPE:
     758     55689528 :     case VOID_TYPE:
     759     55689528 :     case OPAQUE_TYPE:
     760     55689528 :     case BOOLEAN_TYPE:
     761     55689528 :     case COMPLEX_TYPE:
     762     55689528 :     case VECTOR_TYPE:
     763     55689528 :     case FIXED_POINT_TYPE:
     764     55689528 :       pp_type_specifier_seq (pp, t);
     765     55689528 :       break;
     766              : 
     767         1575 :     case TEMPLATE_TEMPLATE_PARM:
     768              :       /* For parameters inside template signature.  */
     769         1575 :       if (TYPE_IDENTIFIER (t))
     770         3060 :         pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     771              :       else
     772           45 :         pp_cxx_canonical_template_parameter (pp, t);
     773              :       break;
     774              : 
     775          420 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
     776          420 :       {
     777          420 :         tree args = TYPE_TI_ARGS (t);
     778          420 :         pp_cxx_cv_qualifier_seq (pp, t);
     779          840 :         pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     780          420 :         pp_cxx_begin_template_argument_list (pp);
     781          420 :         dump_template_argument_list (pp, args, flags);
     782          420 :         pp_cxx_end_template_argument_list (pp);
     783              :       }
     784          420 :       break;
     785              : 
     786       237756 :     case TEMPLATE_TYPE_PARM:
     787       237756 :       pp_cxx_cv_qualifier_seq (pp, t);
     788       237756 :       if (template_placeholder_p (t))
     789              :         {
     790           57 :           tree tmpl = TREE_TYPE (CLASS_PLACEHOLDER_TEMPLATE (t));
     791          114 :           pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (tmpl));
     792           57 :           pp_string (pp, "<...auto...>");
     793              :         }
     794       237699 :       else if (TYPE_IDENTIFIER (t))
     795       473694 :         pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     796              :       else
     797          852 :         pp_cxx_canonical_template_parameter
     798          852 :           (pp, TEMPLATE_TYPE_PARM_INDEX (t));
     799              :       /* If this is a constrained placeholder, add the requirements.  */
     800       237756 :       if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
     801          180 :         pp_cxx_constrained_type_spec (pp, c);
     802              :       break;
     803              : 
     804              :       /* This is not always necessary for pointers and such, but doing this
     805              :          reduces code size.  */
     806     27455680 :     case ARRAY_TYPE:
     807     27455680 :     case POINTER_TYPE:
     808     27455680 :     case REFERENCE_TYPE:
     809     27455680 :     case OFFSET_TYPE:
     810     27455680 :     offset_type:
     811     27455680 :     case FUNCTION_TYPE:
     812     27455680 :     case METHOD_TYPE:
     813     27455680 :     {
     814     27455680 :       dump_type_prefix (pp, t, flags);
     815     27455680 :       dump_type_suffix (pp, t, flags);
     816     27455680 :       break;
     817              :     }
     818         3281 :     case TYPENAME_TYPE:
     819         3281 :       if (! (flags & TFF_CHASE_TYPEDEF)
     820         3281 :           && DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
     821              :         {
     822            0 :           dump_decl (pp, TYPE_NAME (t), TFF_PLAIN_IDENTIFIER);
     823            0 :           break;
     824              :         }
     825         3281 :       pp_cxx_cv_qualifier_seq (pp, t);
     826         3281 :       if (const char *tag = tag_name (get_typename_tag (t)))
     827         3252 :         pp_cxx_ws_string (pp, tag);
     828         3281 :       dump_typename (pp, t, flags);
     829         3281 :       break;
     830              : 
     831            6 :     case UNBOUND_CLASS_TEMPLATE:
     832            6 :       if (! (flags & TFF_UNQUALIFIED_NAME))
     833              :         {
     834            6 :           dump_type (pp, TYPE_CONTEXT (t), flags);
     835            6 :           pp_cxx_colon_colon (pp);
     836              :         }
     837            6 :       pp_cxx_ws_string (pp, "template");
     838            6 :       dump_type (pp, TYPE_IDENTIFIER (t), flags);
     839            6 :       break;
     840              : 
     841            3 :     case TYPEOF_TYPE:
     842            3 :       pp_cxx_ws_string (pp, "__typeof__");
     843            3 :       pp_cxx_whitespace (pp);
     844            3 :       pp_cxx_left_paren (pp);
     845            3 :       dump_expr (pp, TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
     846            3 :       pp_cxx_right_paren (pp);
     847            3 :       break;
     848              : 
     849           42 :     case TRAIT_TYPE:
     850           42 :       pp_cxx_trait (pp, t);
     851           42 :       break;
     852              : 
     853        33961 :     case TYPE_PACK_EXPANSION:
     854        33961 :       dump_type (pp, PACK_EXPANSION_PATTERN (t), flags);
     855        33961 :       pp_cxx_ws_string (pp, "...");
     856        33961 :       break;
     857              : 
     858            2 :     case PACK_INDEX_TYPE:
     859            2 :       dump_type (pp, PACK_INDEX_PACK (t), flags);
     860            2 :       pp_cxx_left_bracket (pp);
     861            2 :       dump_expr (pp, PACK_INDEX_INDEX (t), flags & ~TFF_EXPR_IN_PARENS);
     862            2 :       pp_cxx_right_bracket (pp);
     863            2 :       break;
     864              : 
     865           74 :     case TYPE_ARGUMENT_PACK:
     866           74 :       dump_template_argument (pp, t, flags);
     867           74 :       break;
     868              : 
     869          721 :     case DECLTYPE_TYPE:
     870          721 :       pp_cxx_ws_string (pp, "decltype");
     871          721 :       pp_cxx_whitespace (pp);
     872          721 :       pp_cxx_left_paren (pp);
     873          721 :       dump_expr (pp, DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
     874          721 :       pp_cxx_right_paren (pp);
     875          721 :       break;
     876              : 
     877       123840 :     case NULLPTR_TYPE:
     878       123840 :       pp_cxx_ws_string (pp, "std::nullptr_t");
     879       123840 :       break;
     880              : 
     881         1102 :     case META_TYPE:
     882         1102 :       pp_cxx_ws_string (pp, "std::meta::info");
     883         1102 :       break;
     884              : 
     885           12 :     case SPLICE_SCOPE:
     886           12 :       dump_expr (pp, SPLICE_SCOPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
     887           12 :       break;
     888              : 
     889            0 :     default:
     890            0 :       pp_unsupported_tree (pp, t);
     891              :       /* Fall through.  */
     892              : 
     893           29 :     case ERROR_MARK:
     894           29 :       pp_string (pp, M_("<type error>"));
     895           29 :       break;
     896              :     }
     897              : }
     898              : 
     899              : /* Dump a TYPENAME_TYPE. We need to notice when the context is itself
     900              :    a TYPENAME_TYPE.  */
     901              : 
     902              : static void
     903         3779 : dump_typename (cxx_pretty_printer *pp, tree t, int flags)
     904              : {
     905         3779 :   tree ctx = TYPE_CONTEXT (t);
     906              : 
     907         3779 :   if (TREE_CODE (ctx) == TYPENAME_TYPE)
     908          498 :     dump_typename (pp, ctx, flags);
     909              :   else
     910         3281 :     dump_type (pp, ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
     911         3779 :   pp_cxx_colon_colon (pp);
     912         3779 :   dump_decl (pp, TYPENAME_TYPE_FULLNAME (t), flags);
     913         3779 : }
     914              : 
     915              : /* Return the name of the supplied aggregate, or enumeral type.  */
     916              : 
     917              : const char *
     918    133622148 : class_key_or_enum_as_string (tree t)
     919              : {
     920    133622148 :   if (TREE_CODE (t) == ENUMERAL_TYPE)
     921              :     {
     922      2436521 :       if (SCOPED_ENUM_P (t))
     923              :         return "enum class";
     924              :       else
     925      1157197 :         return "enum";
     926              :     }
     927    131185627 :   else if (TREE_CODE (t) == UNION_TYPE)
     928              :     return "union";
     929    130505807 :   else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
     930     37365541 :     return "class";
     931              :   else
     932              :     return "struct";
     933              : }
     934              : 
     935              : /* Disable warnings about missing quoting in GCC diagnostics for
     936              :    the pp_verbatim call.  Their format strings deliberately don't
     937              :    follow GCC diagnostic conventions.  */
     938              : #if __GNUC__ >= 10
     939              : #pragma GCC diagnostic push
     940              : #pragma GCC diagnostic ignored "-Wformat-diag"
     941              : #endif
     942              : 
     943              : /* Print out a class declaration T under the control of FLAGS,
     944              :    in the form `class foo'.  */
     945              : 
     946              : static void
     947    133622039 : dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
     948              : {
     949    133622039 :   const char *variety = class_key_or_enum_as_string (t);
     950    133622039 :   int typdef = 0;
     951    133622039 :   int tmplate = 0;
     952              : 
     953    133622039 :   pp_cxx_cv_qualifier_seq (pp, t);
     954              : 
     955    133622039 :   if (flags & TFF_CLASS_KEY_OR_ENUM)
     956        11819 :     pp_cxx_ws_string (pp, variety);
     957              : 
     958    133622039 :   tree decl = TYPE_NAME (t);
     959              : 
     960    133622039 :   if (decl)
     961              :     {
     962    133622039 :       typdef = (!DECL_ARTIFICIAL (decl)
     963              :                 /* An alias specialization is not considered to be a
     964              :                    typedef.  */
     965    133622039 :                 && !alias_template_specialization_p (t, nt_opaque));
     966              : 
     967       326152 :       if ((typdef
     968       326152 :            && ((flags & TFF_CHASE_TYPEDEF)
     969       326152 :                || (!flag_pretty_templates && DECL_LANG_SPECIFIC (decl)
     970            0 :                    && DECL_TEMPLATE_INFO (decl))))
     971    133622039 :           || DECL_SELF_REFERENCE_P (decl))
     972              :         {
     973            0 :           t = TYPE_MAIN_VARIANT (t);
     974            0 :           decl = TYPE_NAME (t);
     975            0 :           typdef = 0;
     976              :         }
     977              : 
     978    133295887 :       tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
     979    130859473 :                 && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
     980    223347829 :                 && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
     981     89725790 :                     || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
     982              : 
     983    133622039 :       if (! (flags & TFF_UNQUALIFIED_NAME))
     984     85690950 :         dump_scope (pp, CP_DECL_CONTEXT (decl), flags | TFF_SCOPE);
     985    133622039 :       flags &= ~TFF_UNQUALIFIED_NAME;
     986    133622039 :       if (tmplate)
     987              :         {
     988              :           /* Because the template names are mangled, we have to locate
     989              :              the most general template, and use that name.  */
     990     88020647 :           tree tpl = TYPE_TI_TEMPLATE (t);
     991              : 
     992     88665786 :           while (DECL_TEMPLATE_INFO (tpl))
     993       645139 :             tpl = DECL_TI_TEMPLATE (tpl);
     994              :           decl = tpl;
     995              :         }
     996              :     }
     997              : 
     998    264127663 :   if (LAMBDA_TYPE_P (t))
     999              :     {
    1000              :       /* A lambda's "type" is essentially its signature.  */
    1001       298938 :       pp_string (pp, M_("<lambda"));
    1002       298938 :       tree const fn = lambda_function (t);
    1003       298938 :       if (fn)
    1004              :         {
    1005       298917 :           int const parm_flags
    1006       298917 :             = DECL_XOBJ_MEMBER_FUNCTION_P (fn) ? TFF_XOBJ_FUNC | flags
    1007          120 :                                                : flags;
    1008       298917 :           dump_parameters (pp, FUNCTION_FIRST_USER_PARMTYPE (fn), parm_flags);
    1009              :         }
    1010       298938 :       pp_greater (pp);
    1011              :     }
    1012    133323101 :   else if (!decl || IDENTIFIER_ANON_P (DECL_NAME (decl)))
    1013              :     {
    1014         1817 :       if (flags & TFF_CLASS_KEY_OR_ENUM)
    1015          214 :         pp_string (pp, M_("<unnamed>"));
    1016              :       else
    1017         1603 :         pp_printf (pp, M_("<unnamed %s>"), variety);
    1018              :     }
    1019              :   else
    1020    133321284 :     pp_cxx_tree_identifier (pp, DECL_NAME (decl));
    1021              : 
    1022    133622039 :   dump_module_suffix (pp, decl);
    1023              : 
    1024    133622039 :   if (tmplate)
    1025     88020647 :     dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
    1026     88020647 :                          !CLASSTYPE_USE_TEMPLATE (t),
    1027              :                          flags & ~TFF_TEMPLATE_HEADER);
    1028    133622039 : }
    1029              : 
    1030              : #if __GNUC__ >= 10
    1031              : #pragma GCC diagnostic pop
    1032              : #endif
    1033              : 
    1034              : /* Dump into the obstack the initial part of the output for a given type.
    1035              :    This is necessary when dealing with things like functions returning
    1036              :    functions.  Examples:
    1037              : 
    1038              :    return type of `int (* fee ())()': pointer -> function -> int.  Both
    1039              :    pointer (and reference and offset) and function (and member) types must
    1040              :    deal with prefix and suffix.
    1041              : 
    1042              :    Arrays must also do this for DECL nodes, like int a[], and for things like
    1043              :    int *[]&.  */
    1044              : 
    1045              : static void
    1046     57318849 : dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags)
    1047              : {
    1048     58560456 :   if (TYPE_PTRMEMFUNC_P (t))
    1049              :     {
    1050       172327 :       t = TYPE_PTRMEMFUNC_FN_TYPE (t);
    1051       172327 :       goto offset_type;
    1052              :     }
    1053              : 
    1054     58388129 :   switch (TREE_CODE (t))
    1055              :     {
    1056     29366517 :     case POINTER_TYPE:
    1057     29366517 :     case REFERENCE_TYPE:
    1058     29366517 :       {
    1059     29366517 :         tree sub = TREE_TYPE (t);
    1060              : 
    1061     29366517 :         dump_type_prefix (pp, sub, flags);
    1062     29366517 :         if (TREE_CODE (sub) == ARRAY_TYPE
    1063     29199560 :             || TREE_CODE (sub) == FUNCTION_TYPE)
    1064              :           {
    1065       427184 :             pp_cxx_whitespace (pp);
    1066       427184 :             pp_cxx_left_paren (pp);
    1067              :             /* If we're dealing with the GNU form of attributes, print this:
    1068              :                  void (__attribute__((noreturn)) *f) ();
    1069              :                If it is the standard [[]] attribute, we'll print the attribute
    1070              :                in dump_type_suffix.  */
    1071       427184 :             if (!cxx11_attribute_p (TYPE_ATTRIBUTES (sub)))
    1072       427179 :               pp_c_attributes_display (pp, TYPE_ATTRIBUTES (sub));
    1073              :           }
    1074     29366517 :         if (TYPE_PTR_P (t))
    1075     16199496 :           pp_star (pp);
    1076     13167021 :         else if (TYPE_REF_P (t))
    1077              :           {
    1078     13167021 :             if (TYPE_REF_IS_RVALUE (t))
    1079      1968145 :               pp_ampersand_ampersand (pp);
    1080              :             else
    1081     11198876 :               pp_ampersand (pp);
    1082              :           }
    1083     29366517 :         pp->set_padding (pp_before);
    1084     29366517 :         pp_cxx_cv_qualifier_seq (pp, t);
    1085              :       }
    1086     29366517 :       break;
    1087              : 
    1088       181489 :     case OFFSET_TYPE:
    1089       181489 :     offset_type:
    1090       181489 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1091       181489 :       if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
    1092              :         {
    1093         9162 :           pp_maybe_space (pp);
    1094         9162 :           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
    1095          436 :              pp_cxx_left_paren (pp);
    1096         9162 :           dump_type (pp, TYPE_OFFSET_BASETYPE (t), flags);
    1097         9162 :           pp_cxx_colon_colon (pp);
    1098              :         }
    1099       181489 :       pp_cxx_star (pp);
    1100       181489 :       pp_cxx_cv_qualifier_seq (pp, t);
    1101       181489 :       pp->set_padding (pp_before);
    1102       181489 :       break;
    1103              : 
    1104              :       /* This can be reached without a pointer when dealing with
    1105              :          templates, e.g. std::is_function.  */
    1106       492187 :     case FUNCTION_TYPE:
    1107       492187 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1108       492187 :       break;
    1109              : 
    1110       172489 :     case METHOD_TYPE:
    1111       172489 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1112       172489 :       pp_maybe_space (pp);
    1113       172489 :       pp_cxx_left_paren (pp);
    1114       172489 :       dump_aggr_type (pp, TYPE_METHOD_BASETYPE (t), flags);
    1115       172489 :       pp_cxx_colon_colon (pp);
    1116       172489 :       break;
    1117              : 
    1118       749420 :     case ARRAY_TYPE:
    1119       749420 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1120       749420 :       break;
    1121              : 
    1122     27598323 :     case ENUMERAL_TYPE:
    1123     27598323 :     case IDENTIFIER_NODE:
    1124     27598323 :     case INTEGER_TYPE:
    1125     27598323 :     case BOOLEAN_TYPE:
    1126     27598323 :     case REAL_TYPE:
    1127     27598323 :     case RECORD_TYPE:
    1128     27598323 :     case TEMPLATE_TYPE_PARM:
    1129     27598323 :     case TEMPLATE_TEMPLATE_PARM:
    1130     27598323 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1131     27598323 :     case TREE_LIST:
    1132     27598323 :     case TYPE_DECL:
    1133     27598323 :     case TREE_VEC:
    1134     27598323 :     case UNION_TYPE:
    1135     27598323 :     case LANG_TYPE:
    1136     27598323 :     case VOID_TYPE:
    1137     27598323 :     case OPAQUE_TYPE:
    1138     27598323 :     case TYPENAME_TYPE:
    1139     27598323 :     case COMPLEX_TYPE:
    1140     27598323 :     case VECTOR_TYPE:
    1141     27598323 :     case TYPEOF_TYPE:
    1142     27598323 :     case TRAIT_TYPE:
    1143     27598323 :     case DECLTYPE_TYPE:
    1144     27598323 :     case TYPE_PACK_EXPANSION:
    1145     27598323 :     case FIXED_POINT_TYPE:
    1146     27598323 :     case NULLPTR_TYPE:
    1147     27598323 :     case PACK_INDEX_TYPE:
    1148     27598323 :     case META_TYPE:
    1149     27598323 :     case SPLICE_SCOPE:
    1150     27598323 :       dump_type (pp, t, flags);
    1151     27598323 :       pp->set_padding (pp_before);
    1152     27598323 :       break;
    1153              : 
    1154            0 :     default:
    1155            0 :       pp_unsupported_tree (pp, t);
    1156              :       /* fall through.  */
    1157           31 :     case ERROR_MARK:
    1158           31 :       pp_string (pp, M_("<typeprefixerror>"));
    1159           31 :       break;
    1160              :     }
    1161     57318849 : }
    1162              : 
    1163              : /* Dump the suffix of type T, under control of FLAGS.  This is the part
    1164              :    which appears after the identifier (or function parms).  */
    1165              : 
    1166              : static void
    1167     27598691 : dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
    1168              : {
    1169     58560793 :   if (TYPE_PTRMEMFUNC_P (t))
    1170       172327 :     t = TYPE_PTRMEMFUNC_FN_TYPE (t);
    1171              : 
    1172     58560793 :   switch (TREE_CODE (t))
    1173              :     {
    1174     29548006 :     case POINTER_TYPE:
    1175     29548006 :     case REFERENCE_TYPE:
    1176     29548006 :     case OFFSET_TYPE:
    1177     29548006 :       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
    1178     29548006 :           || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
    1179       427620 :         pp_cxx_right_paren (pp);
    1180     29548006 :       if (TREE_CODE (t) == POINTER_TYPE)
    1181     16371823 :         flags |= TFF_POINTER;
    1182     29548006 :       dump_type_suffix (pp, TREE_TYPE (t), flags);
    1183     29548006 :       break;
    1184              : 
    1185       664676 :     case FUNCTION_TYPE:
    1186       664676 :     case METHOD_TYPE:
    1187       664676 :       {
    1188       664676 :         tree arg;
    1189       664676 :         if (TREE_CODE (t) == METHOD_TYPE)
    1190              :           /* Can only be reached through a pointer.  */
    1191       172489 :           pp_cxx_right_paren (pp);
    1192       664676 :         arg = TYPE_ARG_TYPES (t);
    1193       664676 :         if (TREE_CODE (t) == METHOD_TYPE)
    1194       172489 :           arg = TREE_CHAIN (arg);
    1195              : 
    1196              :         /* Function pointers don't have default args.  Not in standard C++,
    1197              :            anyway; they may in g++, but we'll just pretend otherwise.  */
    1198       664676 :         dump_parameters (pp, arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
    1199              : 
    1200       664676 :         pp->set_padding (pp_before);
    1201       994079 :         pp_cxx_cv_qualifiers (pp, type_memfn_quals (t),
    1202              :                               TREE_CODE (t) == FUNCTION_TYPE
    1203              :                               && (flags & TFF_POINTER));
    1204       664676 :         dump_ref_qualifier (pp, t, flags);
    1205       664676 :         if (tx_safe_fn_type_p (t))
    1206           19 :           pp_cxx_ws_string (pp, "transaction_safe");
    1207       664676 :         dump_exception_spec (pp, TYPE_RAISES_EXCEPTIONS (t), flags);
    1208              :         /* If this is the standard [[]] attribute, print
    1209              :              void (*)() [[noreturn]];  */
    1210       664676 :         if (cxx11_attribute_p (TYPE_ATTRIBUTES (t)))
    1211              :           {
    1212            2 :             pp_space (pp);
    1213            2 :             pp_c_attributes_display (pp, TYPE_ATTRIBUTES (t));
    1214            2 :             pp->set_padding (pp_before);
    1215              :           }
    1216       664676 :         dump_type_suffix (pp, TREE_TYPE (t), flags);
    1217       664676 :         break;
    1218              :       }
    1219              : 
    1220       749420 :     case ARRAY_TYPE:
    1221       749420 :       pp_maybe_space (pp);
    1222       749420 :       pp_cxx_left_bracket (pp);
    1223       749420 :       if (tree dtype = TYPE_DOMAIN (t))
    1224              :         {
    1225       121840 :           tree max = TYPE_MAX_VALUE (dtype);
    1226              :           /* Zero-length arrays have a null upper bound in C and SIZE_MAX
    1227              :              in C++.  Handle both since the type might be constructed by
    1228              :              the middle end and end up here as a result of a warning (see
    1229              :              PR c++/97201).  */
    1230       121840 :           if (!max || integer_all_onesp (max))
    1231          651 :             pp_character (pp, '0');
    1232       121189 :           else if (tree_fits_shwi_p (max))
    1233       120631 :             pp_wide_integer (pp, tree_to_shwi (max) + 1);
    1234              :           else
    1235              :             {
    1236          558 :               STRIP_NOPS (max);
    1237          558 :               if (TREE_CODE (max) == SAVE_EXPR)
    1238            0 :                 max = TREE_OPERAND (max, 0);
    1239          558 :               if (TREE_CODE (max) == MINUS_EXPR
    1240          558 :                   || TREE_CODE (max) == PLUS_EXPR)
    1241              :                 {
    1242          486 :                   max = TREE_OPERAND (max, 0);
    1243          874 :                   while (CONVERT_EXPR_P (max))
    1244          388 :                     max = TREE_OPERAND (max, 0);
    1245              :                 }
    1246              :               else
    1247           72 :                 max = fold_build2_loc (input_location,
    1248              :                                        PLUS_EXPR, dtype, max,
    1249              :                                        build_int_cst (dtype, 1));
    1250          558 :               dump_expr (pp, max, flags & ~TFF_EXPR_IN_PARENS);
    1251              :             }
    1252              :         }
    1253       749420 :       pp_cxx_right_bracket (pp);
    1254       749420 :       dump_type_suffix (pp, TREE_TYPE (t), flags);
    1255       749420 :       break;
    1256              : 
    1257              :     case ENUMERAL_TYPE:
    1258              :     case IDENTIFIER_NODE:
    1259              :     case INTEGER_TYPE:
    1260              :     case BOOLEAN_TYPE:
    1261              :     case REAL_TYPE:
    1262              :     case RECORD_TYPE:
    1263              :     case TEMPLATE_TYPE_PARM:
    1264              :     case TEMPLATE_TEMPLATE_PARM:
    1265              :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1266              :     case TREE_LIST:
    1267              :     case TYPE_DECL:
    1268              :     case TREE_VEC:
    1269              :     case UNION_TYPE:
    1270              :     case LANG_TYPE:
    1271              :     case VOID_TYPE:
    1272              :     case OPAQUE_TYPE:
    1273              :     case TYPENAME_TYPE:
    1274              :     case COMPLEX_TYPE:
    1275              :     case VECTOR_TYPE:
    1276              :     case TYPEOF_TYPE:
    1277              :     case TRAIT_TYPE:
    1278              :     case DECLTYPE_TYPE:
    1279              :     case TYPE_PACK_EXPANSION:
    1280              :     case FIXED_POINT_TYPE:
    1281              :     case NULLPTR_TYPE:
    1282              :     case PACK_INDEX_TYPE:
    1283              :     case META_TYPE:
    1284              :     case SPLICE_SCOPE:
    1285              :       break;
    1286              : 
    1287            0 :     default:
    1288            0 :       pp_unsupported_tree (pp, t);
    1289              :     case ERROR_MARK:
    1290              :       /* Don't mark it here, we should have already done in
    1291              :          dump_type_prefix.  */
    1292              :       break;
    1293              :     }
    1294     27598691 : }
    1295              : 
    1296              : static void
    1297           72 : dump_global_iord (cxx_pretty_printer *pp, tree t)
    1298              : {
    1299           72 :   const char *p = NULL;
    1300              : 
    1301           72 :   if (DECL_GLOBAL_CTOR_P (t))
    1302           72 :     p = M_("(static initializers for %s)");
    1303            0 :   else if (DECL_GLOBAL_DTOR_P (t))
    1304            0 :     p = M_("(static destructors for %s)");
    1305              :   else
    1306            0 :     gcc_unreachable ();
    1307              : 
    1308           72 :   pp_printf (pp, p, DECL_SOURCE_FILE (t));
    1309           72 : }
    1310              : 
    1311              : /* Write a representation of OpenMP "declare mapper" T to PP in a manner
    1312              :    suitable for error messages.  */
    1313              : 
    1314              : static void
    1315           48 : dump_omp_declare_mapper (cxx_pretty_printer *pp, tree t, int flags)
    1316              : {
    1317           48 :   pp_string (pp, "#pragma omp declare mapper");
    1318           48 :   if (t == NULL_TREE || t == error_mark_node)
    1319              :     return;
    1320           48 :   pp_space (pp);
    1321           48 :   pp_cxx_left_paren (pp);
    1322           48 :   if (OMP_DECLARE_MAPPER_ID (t))
    1323              :     {
    1324           12 :       pp_cxx_tree_identifier (pp, OMP_DECLARE_MAPPER_ID (t));
    1325           12 :       pp_colon (pp);
    1326              :     }
    1327           48 :   dump_type (pp, TREE_TYPE (t), flags);
    1328           48 :   pp_cxx_right_paren (pp);
    1329              : }
    1330              : 
    1331              : static void
    1332      1320838 : dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
    1333              : {
    1334      1320838 :   if (VAR_P (t) && DECL_NTTP_OBJECT_P (t))
    1335        22711 :     return dump_expr (pp, DECL_INITIAL (t), flags);
    1336              : 
    1337      1298127 :   if (TREE_CODE (t) == VAR_DECL
    1338        26320 :       && DECL_LANG_SPECIFIC (t)
    1339      1303849 :       && DECL_OMP_DECLARE_MAPPER_P (t))
    1340           48 :     return dump_omp_declare_mapper (pp, DECL_INITIAL (t), flags);
    1341              : 
    1342      1298079 :   if (flags & TFF_DECL_SPECIFIERS)
    1343              :     {
    1344        26143 :       if (concept_definition_p (t))
    1345          337 :         pp_cxx_ws_string (pp, "concept");
    1346        25806 :       else if (VAR_P (t) && DECL_DECLARED_CONSTEXPR_P (t))
    1347          510 :         pp_cxx_ws_string (pp, "constexpr");
    1348              : 
    1349        26143 :       if (!concept_definition_p (t))
    1350        25806 :         dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME);
    1351        26143 :       pp_maybe_space (pp);
    1352              :     }
    1353      1298079 :   if (! (flags & TFF_UNQUALIFIED_NAME)
    1354      1286833 :       && TREE_CODE (t) != PARM_DECL
    1355      2564600 :       && (!DECL_INITIAL (t)
    1356         9324 :           || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
    1357      1264991 :     dump_scope (pp, CP_DECL_CONTEXT (t), flags);
    1358      1298079 :   flags &= ~TFF_UNQUALIFIED_NAME;
    1359      1298079 :   if ((flags & TFF_DECL_SPECIFIERS)
    1360        26143 :       && DECL_TEMPLATE_PARM_P (t)
    1361      1304366 :       && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
    1362          503 :     pp_string (pp, "...");
    1363      1298079 :   if (DECL_NAME (t))
    1364              :     {
    1365      1296166 :       if (TREE_CODE (t) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (t))
    1366              :         {
    1367           12 :           pp_less (pp);
    1368           12 :           pp_string (pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2);
    1369           12 :           pp_string (pp, " capture>");
    1370              :         }
    1371              :       else
    1372      1296154 :         dump_decl (pp, DECL_NAME (t), flags);
    1373              :     }
    1374         1913 :   else if (DECL_DECOMPOSITION_P (t))
    1375           53 :     pp_string (pp, M_("<structured bindings>"));
    1376         1860 :   else if (TREE_CODE (t) == FIELD_DECL && DECL_FIELD_IS_BASE (t))
    1377          512 :     dump_type (pp, TREE_TYPE (t), flags);
    1378              :   else
    1379         1348 :     pp_string (pp, M_("<anonymous>"));
    1380              : 
    1381      1298079 :   dump_module_suffix (pp, t);
    1382              : 
    1383      1298079 :   if (flags & TFF_DECL_SPECIFIERS)
    1384        26143 :     dump_type_suffix (pp, type, flags);
    1385              : }
    1386              : 
    1387              : class colorize_guard
    1388              : {
    1389              :   bool colorize;
    1390              :   cxx_pretty_printer *pp;
    1391              : public:
    1392     91511930 :   colorize_guard (bool _colorize, cxx_pretty_printer *pp, const char *name)
    1393     91511930 :     : colorize (_colorize && pp_show_color (pp)), pp (pp)
    1394              :   {
    1395     91511930 :     pp_string (pp, colorize_start (colorize, name));
    1396     91511930 :   }
    1397     91511930 :   ~colorize_guard ()
    1398              :   {
    1399     91511930 :     pp_string (pp, colorize_stop (colorize));
    1400     91511930 :   }
    1401              : };
    1402              : 
    1403              : /* Print an IDENTIFIER_NODE that is the name of a declaration.  */
    1404              : 
    1405              : static void
    1406    185778475 : dump_decl_name (cxx_pretty_printer *pp, tree t, int flags)
    1407              : {
    1408              :   /* These special cases are duplicated here so that other functions
    1409              :      can feed identifiers to error and get them demangled properly.  */
    1410    185778475 :   if (IDENTIFIER_CONV_OP_P (t))
    1411              :     {
    1412           27 :       pp_cxx_ws_string (pp, "operator");
    1413              :       /* Not exactly IDENTIFIER_TYPE_VALUE.  */
    1414           27 :       dump_type (pp, TREE_TYPE (t), flags);
    1415           27 :       return;
    1416              :     }
    1417    185778448 :   if (dguide_name_p (t))
    1418              :     {
    1419          863 :       dump_decl (pp, CLASSTYPE_TI_TEMPLATE (TREE_TYPE (t)),
    1420              :                  TFF_UNQUALIFIED_NAME);
    1421          863 :       return;
    1422              :     }
    1423              : 
    1424    185777585 :   const char *str = IDENTIFIER_POINTER (t);
    1425    185777585 :   if (startswith (str, "_ZGR"))
    1426              :     {
    1427           15 :       pp_cxx_ws_string (pp, "<temporary>");
    1428           15 :       return;
    1429              :     }
    1430              : 
    1431    185777570 :   pp_cxx_tree_identifier (pp, t);
    1432              : }
    1433              : 
    1434              : /* Dump a human readable string for the decl T under control of FLAGS.  */
    1435              : 
    1436              : static void
    1437    322895786 : dump_decl (cxx_pretty_printer *pp, tree t, int flags)
    1438              : {
    1439    322897420 :   if (t == NULL_TREE)
    1440              :     return;
    1441              : 
    1442              :   /* If doing Objective-C++, give Objective-C a chance to demangle
    1443              :      Objective-C method names.  */
    1444    322897420 :   if (c_dialect_objc ())
    1445              :     {
    1446            0 :       const char *demangled = objc_maybe_printable_name (t, flags);
    1447            0 :       if (demangled)
    1448              :         {
    1449            0 :           pp_string (pp, demangled);
    1450            0 :           return;
    1451              :         }
    1452              :     }
    1453              : 
    1454    322897420 :   switch (TREE_CODE (t))
    1455              :     {
    1456     49209994 :     case TYPE_DECL:
    1457              :       /* Don't say 'typedef class A' */
    1458     49209994 :       if (DECL_ARTIFICIAL (t) && !DECL_SELF_REFERENCE_P (t))
    1459              :         {
    1460     47968219 :           if ((flags & TFF_DECL_SPECIFIERS)
    1461     47968219 :               && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
    1462              :             {
    1463              :               /* Say `class T' not just `T'.  */
    1464           60 :               pp_cxx_ws_string (pp, "class");
    1465              : 
    1466              :               /* Emit the `...' for a parameter pack.  */
    1467           60 :               if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
    1468            3 :                 pp_cxx_ws_string (pp, "...");
    1469              :             }
    1470              : 
    1471     47968219 :           dump_type (pp, TREE_TYPE (t), flags);
    1472     47968219 :           break;
    1473              :         }
    1474      1241775 :       if (TYPE_DECL_ALIAS_P (t)
    1475      1241775 :           && (flags & TFF_DECL_SPECIFIERS
    1476       741684 :               || flags & TFF_CLASS_KEY_OR_ENUM))
    1477              :         {
    1478          482 :           pp_cxx_ws_string (pp, "using");
    1479          482 :           if (! (flags & TFF_UNQUALIFIED_NAME))
    1480          482 :             dump_scope (pp, CP_DECL_CONTEXT (t), flags);
    1481          482 :           dump_decl (pp, DECL_NAME (t), flags);
    1482          482 :           pp_cxx_whitespace (pp);
    1483          482 :           pp_cxx_ws_string (pp, "=");
    1484          482 :           pp_cxx_whitespace (pp);
    1485          505 :           dump_type (pp, (DECL_ORIGINAL_TYPE (t)
    1486           23 :                           ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t)),
    1487              :                      flags);
    1488          482 :           break;
    1489              :         }
    1490      1241293 :       if ((flags & TFF_DECL_SPECIFIERS)
    1491      1241293 :           && !DECL_SELF_REFERENCE_P (t))
    1492        11443 :         pp_cxx_ws_string (pp, "typedef");
    1493      1252638 :       dump_simple_decl (pp, t, DECL_ORIGINAL_TYPE (t)
    1494        11345 :                         ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
    1495              :                         flags);
    1496      1241293 :       break;
    1497              : 
    1498        49031 :     case VAR_DECL:
    1499        49031 :       if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
    1500              :         {
    1501            0 :           pp_string (pp, M_("vtable for "));
    1502            0 :           gcc_assert (TYPE_P (DECL_CONTEXT (t)));
    1503            0 :           dump_type (pp, DECL_CONTEXT (t), flags);
    1504            0 :           break;
    1505              :         }
    1506              :       /* Fall through.  */
    1507        77202 :     case FIELD_DECL:
    1508        77202 :     case PARM_DECL:
    1509        77202 :       dump_simple_decl (pp, t, TREE_TYPE (t), flags);
    1510              : 
    1511              :       /* Handle variable template specializations.  */
    1512        77202 :       if (VAR_P (t)
    1513        49031 :           && DECL_LANG_SPECIFIC (t)
    1514         5722 :           && DECL_TEMPLATE_INFO (t)
    1515        79101 :           && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
    1516              :         {
    1517         1135 :           pp_cxx_begin_template_argument_list (pp);
    1518         1135 :           tree args = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t));
    1519         1135 :           dump_template_argument_list (pp, args, flags);
    1520         1135 :           pp_cxx_end_template_argument_list (pp);
    1521              :         }
    1522              :       break;
    1523              : 
    1524            0 :     case RESULT_DECL:
    1525            0 :       pp_string (pp, M_("<return value> "));
    1526            0 :       dump_simple_decl (pp, t, TREE_TYPE (t), flags);
    1527            0 :       break;
    1528              : 
    1529     87226112 :     case NAMESPACE_DECL:
    1530     87226112 :       if (flags & TFF_DECL_SPECIFIERS)
    1531           81 :         pp->declaration (t);
    1532              :       else
    1533              :         {
    1534     87226031 :           if (! (flags & TFF_UNQUALIFIED_NAME))
    1535     87226010 :             dump_scope (pp, CP_DECL_CONTEXT (t), flags);
    1536     87226031 :           flags &= ~TFF_UNQUALIFIED_NAME;
    1537     87226031 :           if (DECL_NAME (t) == NULL_TREE)
    1538              :             {
    1539         7412 :               if (!(pp->flags & pp_c_flag_gnu_v3))
    1540         1700 :                 pp_cxx_ws_string (pp, M_("{anonymous}"));
    1541              :               else
    1542         5712 :                 pp_cxx_ws_string (pp, M_("(anonymous namespace)"));
    1543              :             }
    1544              :           else
    1545     87218619 :             pp_cxx_tree_identifier (pp, DECL_NAME (t));
    1546              :         }
    1547              :       break;
    1548              : 
    1549          926 :     case SCOPE_REF:
    1550          926 :       dump_type (pp, TREE_OPERAND (t, 0), flags);
    1551          926 :       pp_cxx_colon_colon (pp);
    1552          926 :       dump_decl (pp, TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME);
    1553          926 :       break;
    1554              : 
    1555            0 :     case ARRAY_REF:
    1556            0 :       dump_decl (pp, TREE_OPERAND (t, 0), flags);
    1557            0 :       pp_cxx_left_bracket (pp);
    1558            0 :       dump_decl (pp, TREE_OPERAND (t, 1), flags);
    1559            0 :       pp_cxx_right_bracket (pp);
    1560            0 :       break;
    1561              : 
    1562              :       /* So that we can do dump_decl on an aggr type.  */
    1563         1654 :     case RECORD_TYPE:
    1564         1654 :     case UNION_TYPE:
    1565         1654 :     case ENUMERAL_TYPE:
    1566         1654 :       dump_type (pp, t, flags);
    1567         1654 :       break;
    1568              : 
    1569           48 :     case BIT_NOT_EXPR:
    1570              :       /* This is a pseudo destructor call which has not been folded into
    1571              :          a PSEUDO_DTOR_EXPR yet.  */
    1572           48 :       pp_cxx_complement (pp);
    1573           48 :       dump_type (pp, TREE_OPERAND (t, 0), flags);
    1574           48 :       break;
    1575              : 
    1576            0 :     case TYPE_EXPR:
    1577            0 :       gcc_unreachable ();
    1578    185778475 :       break;
    1579              : 
    1580    185778475 :     case IDENTIFIER_NODE:
    1581    185778475 :       dump_decl_name (pp, t, flags);
    1582    185778475 :       break;
    1583              : 
    1584          295 :     case OVERLOAD:
    1585          295 :       if (!OVL_SINGLE_P (t))
    1586              :         {
    1587          122 :           tree ctx = ovl_scope (t);
    1588          122 :           if (ctx != global_namespace)
    1589              :             {
    1590           69 :               if (TYPE_P (ctx))
    1591           59 :                 dump_type (pp, ctx, flags);
    1592              :               else
    1593           10 :                 dump_decl (pp, ctx, flags);
    1594           69 :               pp_cxx_colon_colon (pp);
    1595              :             }
    1596          244 :           dump_decl (pp, OVL_NAME (t), flags);
    1597          122 :           break;
    1598              :         }
    1599              : 
    1600              :       /* If there's only one function, dump that.  */
    1601    322897420 :       return dump_decl (pp, OVL_FIRST (t), flags);
    1602              : 
    1603       140477 :     case FUNCTION_DECL:
    1604       140477 :       if (! DECL_LANG_SPECIFIC (t))
    1605              :         {
    1606         1644 :           if (DECL_ABSTRACT_ORIGIN (t)
    1607         1644 :               && DECL_ABSTRACT_ORIGIN (t) != t)
    1608          313 :             dump_decl (pp, DECL_ABSTRACT_ORIGIN (t), flags);
    1609              :           else
    1610         1331 :             dump_function_name (pp, t, flags);
    1611              :         }
    1612       138833 :       else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
    1613           72 :         dump_global_iord (pp, t);
    1614              :       else
    1615       138761 :         dump_function_decl (pp, t, flags);
    1616              :       break;
    1617              : 
    1618       456981 :     case TEMPLATE_DECL:
    1619       456981 :       dump_template_decl (pp, t, flags);
    1620       456981 :       break;
    1621              : 
    1622          362 :     case CONCEPT_DECL:
    1623          362 :       dump_simple_decl (pp, t, TREE_TYPE (t), flags);
    1624          362 :       break;
    1625              : 
    1626         2234 :     case TEMPLATE_ID_EXPR:
    1627         2234 :       {
    1628         2234 :         tree name = TREE_OPERAND (t, 0);
    1629         2234 :         tree args = TREE_OPERAND (t, 1);
    1630              : 
    1631         2234 :         if (TREE_CODE (name) == SPLICE_EXPR)
    1632            7 :           dump_expr (pp, name, flags);
    1633              :         else
    1634              :           {
    1635         2761 :             if (!identifier_p (name))
    1636         1590 :               name = OVL_NAME (name);
    1637         2227 :             dump_decl (pp, name, flags);
    1638              :           }
    1639         2234 :         pp_cxx_begin_template_argument_list (pp);
    1640         2234 :         if (args == error_mark_node)
    1641            0 :           pp_string (pp, M_("<template arguments error>"));
    1642         2234 :         else if (args)
    1643         2138 :           dump_template_argument_list
    1644         2138 :             (pp, args, flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
    1645         2234 :         pp_cxx_end_template_argument_list (pp);
    1646              :       }
    1647         2234 :       break;
    1648              : 
    1649          382 :     case LABEL_DECL:
    1650          382 :       if (DECL_NAME (t))
    1651          376 :         pp_cxx_tree_identifier (pp, DECL_NAME (t));
    1652              :       else
    1653            6 :         dump_generic_node (pp, t, 0, TDF_SLIM, false);
    1654              :       break;
    1655              : 
    1656         2023 :     case CONST_DECL:
    1657         4040 :       if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
    1658         3513 :           || (DECL_INITIAL (t) &&
    1659         1490 :               TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
    1660         1981 :         dump_simple_decl (pp, t, TREE_TYPE (t), flags);
    1661           42 :       else if (DECL_NAME (t))
    1662           42 :         dump_decl (pp, DECL_NAME (t), flags);
    1663            0 :       else if (DECL_INITIAL (t))
    1664            0 :         dump_expr (pp, DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
    1665              :       else
    1666            0 :         pp_string (pp, M_("<enumerator>"));
    1667              :       break;
    1668              : 
    1669          137 :     case USING_DECL:
    1670          137 :       {
    1671          137 :         if (flags & TFF_DECL_SPECIFIERS)
    1672          131 :           pp_cxx_ws_string (pp, "using");
    1673          137 :         bool variadic = false;
    1674          137 :         if (!(flags & TFF_UNQUALIFIED_NAME))
    1675              :           {
    1676          137 :             tree scope = USING_DECL_SCOPE (t);
    1677          137 :             tree name = DECL_NAME (t);
    1678          137 :             if (PACK_EXPANSION_P (scope))
    1679              :               {
    1680            0 :                 scope = PACK_EXPANSION_PATTERN (scope);
    1681              :                 variadic = true;
    1682              :               }
    1683          137 :             if (identifier_p (name)
    1684          137 :                 && IDENTIFIER_CONV_OP_P (name)
    1685            0 :                 && PACK_EXPANSION_P (TREE_TYPE (name)))
    1686              :               {
    1687            0 :                 name = make_conv_op_name (PACK_EXPANSION_PATTERN
    1688              :                                           (TREE_TYPE (name)));
    1689            0 :                 variadic = true;
    1690              :               }
    1691          137 :             dump_type (pp, scope, flags);
    1692          137 :             pp_cxx_colon_colon (pp);
    1693              :           }
    1694          137 :         dump_decl (pp, DECL_NAME (t), flags);
    1695          137 :         if (variadic)
    1696            0 :           pp_cxx_ws_string (pp, "...");
    1697              :       }
    1698              :       break;
    1699              : 
    1700            0 :     case STATIC_ASSERT:
    1701            0 :       pp->declaration (t);
    1702            0 :       break;
    1703              : 
    1704           58 :     case BASELINK:
    1705           58 :       dump_decl (pp, BASELINK_FUNCTIONS (t), flags);
    1706           58 :       break;
    1707              : 
    1708            0 :     case TEMPLATE_TYPE_PARM:
    1709            0 :       if (flags & TFF_DECL_SPECIFIERS)
    1710            0 :         pp->declaration (t);
    1711              :       else
    1712            0 :         pp->type_id (t);
    1713              :       break;
    1714              : 
    1715            9 :     case UNBOUND_CLASS_TEMPLATE:
    1716            9 :     case TYPE_PACK_EXPANSION:
    1717            9 :     case TREE_BINFO:
    1718            9 :       dump_type (pp, t, flags);
    1719            9 :       break;
    1720              : 
    1721           30 :     default:
    1722           30 :       pp_unsupported_tree (pp, t);
    1723              :       /* Fall through.  */
    1724              : 
    1725           51 :     case ERROR_MARK:
    1726           51 :       pp_string (pp, M_("<declaration error>"));
    1727           51 :       break;
    1728              :     }
    1729              : }
    1730              : 
    1731              : /* Dump a template declaration T under control of FLAGS. This means the
    1732              :    'template <...> leaders plus the 'class X' or 'void fn(...)' part.  */
    1733              : 
    1734              : static void
    1735       458542 : dump_template_decl (cxx_pretty_printer *pp, tree t, int flags)
    1736              : {
    1737       458542 :   tree orig_parms = DECL_TEMPLATE_PARMS (t);
    1738       458542 :   tree parms;
    1739       458542 :   int i;
    1740              : 
    1741       458542 :   if (flags & TFF_TEMPLATE_HEADER)
    1742              :     {
    1743         8097 :       for (parms = orig_parms = nreverse (orig_parms);
    1744        16734 :            parms;
    1745         8637 :            parms = TREE_CHAIN (parms))
    1746              :         {
    1747         8637 :           tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
    1748         8637 :           int len = TREE_VEC_LENGTH (inner_parms);
    1749              : 
    1750         8637 :           if (len == 0)
    1751              :             {
    1752              :               /* Skip over the dummy template levels of a template template
    1753              :                  parm.  */
    1754          298 :               gcc_assert (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TEMPLATE_PARM);
    1755          298 :               continue;
    1756              :             }
    1757              : 
    1758         8339 :           pp_cxx_ws_string (pp, "template");
    1759         8339 :           pp_cxx_begin_template_argument_list (pp);
    1760              : 
    1761              :           /* If we've shown the template prefix, we'd better show the
    1762              :              parameters' and decl's type too.  */
    1763         8339 :             flags |= TFF_DECL_SPECIFIERS;
    1764              : 
    1765        20613 :           for (i = 0; i < len; i++)
    1766              :             {
    1767        12274 :               if (i)
    1768         3935 :                 pp_separate_with_comma (pp);
    1769        12274 :               dump_template_parameter (pp, TREE_VEC_ELT (inner_parms, i),
    1770              :                                        flags);
    1771              :             }
    1772         8339 :           pp_cxx_end_template_argument_list (pp);
    1773         8339 :           pp_cxx_whitespace (pp);
    1774              :         }
    1775         8097 :       nreverse(orig_parms);
    1776              : 
    1777         8097 :       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
    1778              :         {
    1779              :           /* Say `template<arg> class TT' not just `template<arg> TT'.  */
    1780          304 :           pp_cxx_ws_string (pp, "class");
    1781              : 
    1782              :           /* If this is a parameter pack, print the ellipsis.  */
    1783          304 :           if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
    1784           54 :             pp_cxx_ws_string (pp, "...");
    1785              :         }
    1786              : 
    1787              :       /* Only print the requirements if we're also printing
    1788              :          the template header.  */
    1789         8097 :       if (flag_concepts)
    1790         7135 :         if (tree ci = get_constraints (t))
    1791         2481 :           if (check_constraint_info (ci))
    1792         2481 :             if (tree reqs = CI_TEMPLATE_REQS (ci))
    1793              :               {
    1794         2014 :                 pp_cxx_requires_clause (pp, reqs);
    1795         2014 :                 pp_cxx_whitespace (pp);
    1796              :               }
    1797              :     }
    1798              : 
    1799              : 
    1800       458542 :   if (DECL_CLASS_TEMPLATE_P (t))
    1801       324587 :     dump_type (pp, TREE_TYPE (t),
    1802       324587 :                ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
    1803       324587 :                 | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
    1804       133955 :   else if (DECL_TEMPLATE_RESULT (t)
    1805       133955 :            && (VAR_P (DECL_TEMPLATE_RESULT (t))
    1806              :                /* Alias template.  */
    1807       133793 :                || DECL_TYPE_TEMPLATE_P (t)
    1808              :                /* Concept definition.  &*/
    1809         6581 :                || TREE_CODE (DECL_TEMPLATE_RESULT (t)) == CONCEPT_DECL))
    1810       127721 :     dump_decl (pp, DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
    1811              :   else
    1812              :     {
    1813         6234 :       gcc_assert (TREE_TYPE (t));
    1814         6234 :       switch (NEXT_CODE (t))
    1815              :         {
    1816         6234 :         case METHOD_TYPE:
    1817         6234 :         case FUNCTION_TYPE:
    1818         6234 :           dump_function_decl (pp, t, flags | TFF_TEMPLATE_NAME);
    1819         6234 :           break;
    1820            0 :         default:
    1821              :           /* This case can occur with some invalid code.  */
    1822            0 :           dump_type (pp, TREE_TYPE (t),
    1823            0 :                      (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
    1824              :                      | (flags & TFF_DECL_SPECIFIERS
    1825            0 :                         ? TFF_CLASS_KEY_OR_ENUM : 0));
    1826              :         }
    1827              :     }
    1828       458542 : }
    1829              : 
    1830              : /* find_typenames looks through the type of the function template T
    1831              :    and returns a vec containing any typedefs, decltypes or TYPENAME_TYPEs
    1832              :    it finds.  */
    1833              : 
    1834              : struct find_typenames_t
    1835              : {
    1836              :   hash_set<tree> *p_set;
    1837              :   vec<tree, va_gc> *typenames;
    1838              : };
    1839              : 
    1840              : static tree
    1841       315654 : find_typenames_r (tree *tp, int *walk_subtrees, void *data)
    1842              : {
    1843       315654 :   struct find_typenames_t *d = (struct find_typenames_t *)data;
    1844       315654 :   tree mv = NULL_TREE;
    1845              : 
    1846       315654 :   if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp)))
    1847              :     /* Add the type of the typedef without any additional cv-quals.  */
    1848        10437 :     mv = TREE_TYPE (TYPE_NAME (*tp));
    1849       305217 :   else if (TREE_CODE (*tp) == TYPENAME_TYPE
    1850       304680 :            || TREE_CODE (*tp) == DECLTYPE_TYPE)
    1851              :     /* Add the typename without any cv-qualifiers.  */
    1852          691 :     mv = TYPE_MAIN_VARIANT (*tp);
    1853              : 
    1854       315654 :   if (PACK_EXPANSION_P (*tp))
    1855              :     {
    1856              :       /* Don't mess with parameter packs since we don't remember
    1857              :          the pack expansion context for a particular typename.  */
    1858         1925 :       *walk_subtrees = false;
    1859         1925 :       return NULL_TREE;
    1860              :     }
    1861              : 
    1862       313729 :   if (mv && (mv == *tp || !d->p_set->add (mv)))
    1863        11112 :     vec_safe_push (d->typenames, mv);
    1864              : 
    1865              :   return NULL_TREE;
    1866              : }
    1867              : 
    1868              : static vec<tree, va_gc> *
    1869        38118 : find_typenames (tree t)
    1870              : {
    1871        38118 :   struct find_typenames_t ft;
    1872        38118 :   ft.p_set = new hash_set<tree>;
    1873        38118 :   ft.typenames = NULL;
    1874        38118 :   cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
    1875              :                 find_typenames_r, &ft, ft.p_set);
    1876        76236 :   delete ft.p_set;
    1877        38118 :   return ft.typenames;
    1878              : }
    1879              : 
    1880              : /* Output the "[with ...]" clause for a template instantiation T iff
    1881              :    TEMPLATE_PARMS, TEMPLATE_ARGS and FLAGS are suitable.  T may be NULL if
    1882              :    formatting a deduction/substitution diagnostic rather than an
    1883              :    instantiation.  */
    1884              : 
    1885              : static void
    1886       520313 : dump_substitution (cxx_pretty_printer *pp,
    1887              :                    tree t, tree template_parms, tree template_args,
    1888              :                    int flags)
    1889              : {
    1890       520313 :   if (template_parms != NULL_TREE && template_args != NULL_TREE
    1891        39679 :       && !(flags & TFF_NO_TEMPLATE_BINDINGS))
    1892              :     {
    1893        39679 :       vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
    1894        39679 :       dump_template_bindings (pp, template_parms, template_args, typenames);
    1895              :     }
    1896       520313 : }
    1897              : 
    1898              : /* Dump the lambda function FN including its 'mutable' qualifier and any
    1899              :    template bindings.  */
    1900              : 
    1901              : static void
    1902         8477 : dump_lambda_function (cxx_pretty_printer *pp,
    1903              :                       tree fn, tree template_parms, tree template_args,
    1904              :                       int flags)
    1905              : {
    1906              :   /* A lambda's signature is essentially its "type".  */
    1907         8477 :   dump_type (pp, DECL_CONTEXT (fn), flags);
    1908         8477 :   if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    1909              :     /* Early escape.  */;
    1910         8451 :   else if (TREE_CODE (TREE_TYPE (fn)) == FUNCTION_TYPE)
    1911              :     {
    1912          176 :       pp->set_padding (pp_before);
    1913          176 :       pp_c_ws_string (pp, "static");
    1914              :     }
    1915         8275 :   else if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn)))
    1916         8275 :              & TYPE_QUAL_CONST))
    1917              :     {
    1918           87 :       pp->set_padding (pp_before);
    1919           87 :       pp_c_ws_string (pp, "mutable");
    1920              :     }
    1921         8477 :   dump_substitution (pp, fn, template_parms, template_args, flags);
    1922         8477 : }
    1923              : 
    1924              : /* Pretty print a function decl. There are several ways we want to print a
    1925              :    function declaration. The TFF_ bits in FLAGS tells us how to behave.
    1926              :    As error can only apply the '#' flag once to give 0 and 1 for V, there
    1927              :    is %D which doesn't print the throw specs, and %F which does.  */
    1928              : 
    1929              : static void
    1930       532869 : dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
    1931              : {
    1932       532869 :   tree fntype;
    1933       532869 :   tree parmtypes;
    1934       532869 :   tree cname = NULL_TREE;
    1935       532869 :   tree template_args = NULL_TREE;
    1936       532869 :   tree template_parms = NULL_TREE;
    1937       532869 :   int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
    1938       532869 :   int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
    1939       532869 :   tree exceptions;
    1940       532869 :   bool constexpr_p;
    1941       532869 :   tree ret = NULL_TREE;
    1942              : 
    1943       532869 :   int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME;
    1944       532869 :   flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME;
    1945       532869 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1946         6234 :     t = DECL_TEMPLATE_RESULT (t);
    1947              : 
    1948              :   /* Save the exceptions, in case t is a specialization and we are
    1949              :      emitting an error about incompatible specifications.  */
    1950       532869 :   exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t));
    1951              : 
    1952              :   /* Likewise for the constexpr specifier, in case t is a specialization.  */
    1953       532869 :   constexpr_p = (DECL_DECLARED_CONSTEXPR_P (t)
    1954       532869 :                  && !decl_implicit_constexpr_p (t));
    1955              : 
    1956              :   /* Pretty print template instantiations only.  */
    1957       741746 :   if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)
    1958       208823 :       && !(flags & TFF_NO_TEMPLATE_BINDINGS)
    1959       571039 :       && flag_pretty_templates)
    1960              :     {
    1961        38143 :       tree tmpl;
    1962              : 
    1963        38143 :       template_args = DECL_TI_ARGS (t);
    1964        38143 :       tmpl = most_general_template (t);
    1965        38143 :       if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
    1966              :         {
    1967        38118 :           template_parms = DECL_TEMPLATE_PARMS (tmpl);
    1968        38118 :           t = tmpl;
    1969              :         }
    1970              :     }
    1971              : 
    1972       544733 :   if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
    1973         8477 :     return dump_lambda_function (pp, t, template_parms, template_args, flags);
    1974              : 
    1975       524392 :   fntype = TREE_TYPE (t);
    1976       524392 :   parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
    1977              : 
    1978       524392 :   if (DECL_CLASS_SCOPE_P (t))
    1979       146533 :     cname = DECL_CONTEXT (t);
    1980              :   /* This is for partially instantiated template methods.  */
    1981       377859 :   else if (TREE_CODE (fntype) == METHOD_TYPE)
    1982            3 :     cname = TREE_TYPE (TREE_VALUE (parmtypes));
    1983              : 
    1984       524392 :   if (flags & TFF_DECL_SPECIFIERS)
    1985              :     {
    1986       128813 :       if (DECL_STATIC_FUNCTION_P (t))
    1987         3582 :         pp_cxx_ws_string (pp, "static");
    1988       125231 :       else if (DECL_VIRTUAL_P (t))
    1989         2729 :         pp_cxx_ws_string (pp, "virtual");
    1990              : 
    1991       128813 :       if (constexpr_p)
    1992              :         {
    1993        83158 :           if (DECL_IMMEDIATE_FUNCTION_P (t))
    1994          330 :             pp_cxx_ws_string (pp, "consteval");
    1995              :           else
    1996        41249 :             pp_cxx_ws_string (pp, "constexpr");
    1997              :         }
    1998              :     }
    1999              : 
    2000              :   /* Print the return type?  */
    2001       524392 :   if (show_return)
    2002       385557 :     show_return = (!DECL_CONV_FN_P (t)  && !DECL_CONSTRUCTOR_P (t)
    2003       247446 :                    && !DECL_DESTRUCTOR_P (t) && !deduction_guide_p (t));
    2004       116868 :   if (show_return)
    2005              :     {
    2006       116868 :       ret = fndecl_declared_return_type (t);
    2007       116868 :       dump_type_prefix (pp, ret, flags);
    2008              :     }
    2009              : 
    2010              :   /* Print the function name.  */
    2011       524392 :   if (!do_outer_scope)
    2012              :     /* Nothing.  */;
    2013       524392 :   else if (cname)
    2014              :     {
    2015       146533 :       dump_type (pp, cname, flags);
    2016       146533 :       pp_cxx_colon_colon (pp);
    2017              :     }
    2018              :   else
    2019       377859 :     dump_scope (pp, CP_DECL_CONTEXT (t), flags);
    2020              : 
    2021              :   /* Name lookup for the rest of the function declarator is implicitly in the
    2022              :      scope of the function, so avoid printing redundant scope qualifiers.  */
    2023       524392 :   auto cds = make_temp_override (current_dump_scope, CP_DECL_CONTEXT (t));
    2024              : 
    2025       524392 :   dump_function_name (pp, t, dump_function_name_flags);
    2026              : 
    2027              :   /* By default we need no padding here, but if we emit target_version or
    2028              :      target_clones then we need some.  */
    2029       524392 :   pp->set_padding (pp_none);
    2030       524392 :   pp_cxx_function_target_version (pp, t);
    2031       524392 :   pp_cxx_maybe_whitespace (pp);
    2032       524392 :   pp_cxx_function_target_clones (pp, t);
    2033       524392 :   pp_cxx_maybe_whitespace (pp);
    2034              : 
    2035       524392 :   if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
    2036              :     {
    2037       510275 :       int const parm_flags
    2038       510275 :         = DECL_XOBJ_MEMBER_FUNCTION_P (t) ? TFF_XOBJ_FUNC | flags : flags;
    2039       510275 :       dump_parameters (pp, parmtypes, parm_flags);
    2040              : 
    2041       510275 :       if (TREE_CODE (fntype) == METHOD_TYPE)
    2042              :         {
    2043       139589 :           pp->set_padding (pp_before);
    2044       139589 :           pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
    2045       139589 :           dump_ref_qualifier (pp, fntype, flags);
    2046              :         }
    2047              : 
    2048       510275 :       if (tx_safe_fn_type_p (fntype))
    2049              :         {
    2050           18 :           pp->set_padding (pp_before);
    2051           18 :           pp_cxx_ws_string (pp, "transaction_safe");
    2052              :         }
    2053              : 
    2054       510275 :       if (flags & TFF_EXCEPTION_SPECIFICATION)
    2055              :         {
    2056          350 :           pp->set_padding (pp_before);
    2057          350 :           dump_exception_spec (pp, exceptions, flags);
    2058              :         }
    2059              : 
    2060       510275 :       if (show_return)
    2061       116868 :         dump_type_suffix (pp, ret, flags);
    2062       393407 :       else if (deduction_guide_p (t))
    2063              :         {
    2064          670 :           pp->set_padding (pp_before);
    2065          670 :           pp_cxx_ws_string (pp, "->");
    2066          670 :           dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
    2067              :         }
    2068              : 
    2069       510275 :       if (flag_concepts)
    2070       483303 :         if (tree ci = get_constraints (t))
    2071        50976 :           if (tree reqs = CI_DECLARATOR_REQS (ci))
    2072        13107 :             pp_cxx_requires_clause (pp, reqs);
    2073              : 
    2074       510275 :       dump_substitution (pp, t, template_parms, template_args, flags);
    2075              : 
    2076      1020550 :       if (tree base = DECL_INHERITED_CTOR_BASE (t))
    2077              :         {
    2078           71 :           pp_cxx_ws_string (pp, "[inherited from");
    2079           71 :           dump_type (pp, base, TFF_PLAIN_IDENTIFIER);
    2080           71 :           pp_character (pp, ']');
    2081              :         }
    2082              :     }
    2083        14117 :   else if (template_args)
    2084              :     {
    2085            0 :       bool need_comma = false;
    2086            0 :       int i;
    2087            0 :       pp_cxx_begin_template_argument_list (pp);
    2088            0 :       template_args = INNERMOST_TEMPLATE_ARGS (template_args);
    2089            0 :       for (i = 0; i < TREE_VEC_LENGTH (template_args); ++i)
    2090              :         {
    2091            0 :           tree arg = TREE_VEC_ELT (template_args, i);
    2092            0 :           if (need_comma)
    2093            0 :             pp_separate_with_comma (pp);
    2094            0 :           if (ARGUMENT_PACK_P (arg))
    2095            0 :             pp_cxx_left_brace (pp);
    2096            0 :           dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
    2097            0 :           if (ARGUMENT_PACK_P (arg))
    2098            0 :             pp_cxx_right_brace (pp);
    2099            0 :           need_comma = true;
    2100              :         }
    2101            0 :       pp_cxx_end_template_argument_list (pp);
    2102              :     }
    2103       524392 : }
    2104              : 
    2105              : /* Print a parameter list. If this is for a member function, the
    2106              :    member object ptr (and any other hidden args) should have
    2107              :    already been removed.  */
    2108              : 
    2109              : static void
    2110      1473868 : dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags)
    2111              : {
    2112      1473868 :   int first = 1;
    2113      1473868 :   flags &= ~TFF_SCOPE;
    2114      1473868 :   pp_cxx_left_paren (pp);
    2115              : 
    2116      4668913 :   for (first = 1; parmtypes != void_list_node;
    2117      1721177 :        parmtypes = TREE_CHAIN (parmtypes))
    2118              :     {
    2119      1723364 :       if (first && flags & TFF_XOBJ_FUNC)
    2120         1057 :         pp_string (pp, "this ");
    2121       849323 :       if (!first)
    2122       849323 :         pp_separate_with_comma (pp);
    2123      1723364 :       first = 0;
    2124      1723364 :       if (!parmtypes)
    2125              :         {
    2126         2187 :           pp_cxx_ws_string (pp, "...");
    2127         2187 :           break;
    2128              :         }
    2129              : 
    2130      1721177 :       dump_type (pp, TREE_VALUE (parmtypes), flags);
    2131              : 
    2132      1721192 :       if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
    2133              :         {
    2134            6 :           pp_cxx_whitespace (pp);
    2135            6 :           pp_equal (pp);
    2136            6 :           pp_cxx_whitespace (pp);
    2137            6 :           dump_expr (pp, TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
    2138              :         }
    2139              :     }
    2140              : 
    2141      1473868 :   pp_cxx_right_paren (pp);
    2142      1473868 : }
    2143              : 
    2144              : /* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */
    2145              : 
    2146              : static void
    2147       804265 : dump_ref_qualifier (cxx_pretty_printer *pp, tree t, int flags ATTRIBUTE_UNUSED)
    2148              : {
    2149       804265 :   if (FUNCTION_REF_QUALIFIED (t))
    2150              :     {
    2151         1293 :       pp->set_padding (pp_before);
    2152         1293 :       if (FUNCTION_RVALUE_QUALIFIED (t))
    2153          389 :         pp_cxx_ws_string (pp, "&&");
    2154              :       else
    2155          904 :         pp_cxx_ws_string (pp, "&");
    2156              :     }
    2157       804265 : }
    2158              : 
    2159              : /* Print an exception specification. T is the exception specification.  */
    2160              : 
    2161              : static void
    2162       665029 : dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags)
    2163              : {
    2164       670270 :   if (t && TREE_PURPOSE (t))
    2165              :     {
    2166         5143 :       pp_cxx_ws_string (pp, "noexcept");
    2167         5143 :       if (!integer_onep (TREE_PURPOSE (t)))
    2168              :         {
    2169           98 :           pp_cxx_whitespace (pp);
    2170           98 :           pp_cxx_left_paren (pp);
    2171           98 :           if (DEFERRED_NOEXCEPT_SPEC_P (t))
    2172            3 :             pp_cxx_ws_string (pp, "<uninstantiated>");
    2173              :           else
    2174           95 :             dump_expr (pp, TREE_PURPOSE (t), flags);
    2175           98 :           pp_cxx_right_paren (pp);
    2176              :         }
    2177              :     }
    2178       659886 :   else if (t)
    2179              :     {
    2180           98 :       pp_cxx_ws_string (pp, "throw");
    2181           98 :       pp_cxx_whitespace (pp);
    2182           98 :       pp_cxx_left_paren (pp);
    2183           98 :       if (TREE_VALUE (t) != NULL_TREE)
    2184           73 :         while (1)
    2185              :           {
    2186           61 :             dump_type (pp, TREE_VALUE (t), flags);
    2187           61 :             t = TREE_CHAIN (t);
    2188           61 :             if (!t)
    2189              :               break;
    2190           12 :             pp_separate_with_comma (pp);
    2191              :           }
    2192           98 :       pp_cxx_right_paren (pp);
    2193              :     }
    2194       665029 : }
    2195              : 
    2196              : /* Handle the function name for a FUNCTION_DECL node, grokking operators
    2197              :    and destructors properly.  */
    2198              : 
    2199              : static void
    2200     91511930 : dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
    2201              : {
    2202              :   /* Only colorize when we're printing something before the name; in
    2203              :      particular, not when printing a CALL_EXPR.  */
    2204     91511930 :   bool colorize = flags & (TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE
    2205              :                            | TFF_TEMPLATE_HEADER);
    2206              : 
    2207     91511930 :   colorize_guard g (colorize, pp, "fnname");
    2208              : 
    2209     91511930 :   tree name = DECL_NAME (t);
    2210              : 
    2211              :   /* We can get here with a decl that was synthesized by language-
    2212              :      independent machinery (e.g. coverage.cc) in which case it won't
    2213              :      have a lang_specific structure attached and DECL_CONSTRUCTOR_P
    2214              :      will crash.  In this case it is safe just to print out the
    2215              :      literal name.  */
    2216     91511930 :   if (!DECL_LANG_SPECIFIC (t))
    2217              :     {
    2218         6110 :       pp_cxx_tree_identifier (pp, name);
    2219         6110 :       return;
    2220              :     }
    2221              : 
    2222     91505820 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    2223        37052 :     t = DECL_TEMPLATE_RESULT (t);
    2224              : 
    2225              :   /* Don't let the user see __comp_ctor et al.  */
    2226     91505820 :   if (DECL_CONSTRUCTOR_P (t)
    2227     91505820 :       || DECL_DESTRUCTOR_P (t))
    2228              :     {
    2229     35663971 :       if (LAMBDA_TYPE_P (DECL_CONTEXT (t)))
    2230       196412 :         name = get_identifier ("<lambda>");
    2231     35300449 :       else if (TYPE_UNNAMED_P (DECL_CONTEXT (t)))
    2232          119 :         name = get_identifier ("<constructor>");
    2233              :       else
    2234     17650046 :         name = constructor_name (DECL_CONTEXT (t));
    2235              :     }
    2236              : 
    2237    183011640 :   if (DECL_DESTRUCTOR_P (t))
    2238              :     {
    2239      2242319 :       pp_cxx_complement (pp);
    2240      2242319 :       dump_decl (pp, name, TFF_PLAIN_IDENTIFIER);
    2241              :     }
    2242     89263501 :   else if (DECL_CONV_FN_P (t))
    2243              :     {
    2244              :       /* This cannot use the hack that the operator's return
    2245              :          type is stashed off of its name because it may be
    2246              :          used for error reporting.  In the case of conflicting
    2247              :          declarations, both will have the same name, yet
    2248              :          the types will be different, hence the TREE_TYPE field
    2249              :          of the first name will be clobbered by the second.  */
    2250      1490527 :       pp_cxx_ws_string (pp, "operator");
    2251      1490527 :       dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
    2252              :     }
    2253              :   else
    2254     87772974 :     dump_decl (pp, name, flags);
    2255              : 
    2256     91505820 :   dump_module_suffix (pp, t);
    2257              : 
    2258     91505820 :   if (DECL_TEMPLATE_INFO (t)
    2259     70528711 :       && !(flags & TFF_TEMPLATE_NAME)
    2260     70522795 :       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
    2261    161974102 :       && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
    2262     70468257 :           || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
    2263       511084 :     dump_template_parms (pp, DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t),
    2264              :                          flags);
    2265     91511930 : }
    2266              : 
    2267              : /* Dump the template parameters from the template info INFO under control of
    2268              :    FLAGS. PRIMARY indicates whether this is a primary template decl, or
    2269              :    specialization (partial or complete). For partial specializations we show
    2270              :    the specialized parameter values. For a primary template we show no
    2271              :    decoration.  */
    2272              : 
    2273              : static void
    2274     88538435 : dump_template_parms (cxx_pretty_printer *pp, tree info,
    2275              :                      int primary, int flags)
    2276              : {
    2277    177076870 :   tree args = info ? TI_ARGS (info) : NULL_TREE;
    2278              : 
    2279     88538435 :   if (primary && flags & TFF_TEMPLATE_NAME)
    2280              :     return;
    2281     88213808 :   flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
    2282     88213808 :   pp_cxx_begin_template_argument_list (pp);
    2283              : 
    2284              :   /* Be careful only to print things when we have them, so as not
    2285              :      to crash producing error messages.  */
    2286     88213808 :   if (args && !primary)
    2287              :     {
    2288     88190874 :       int len, ix;
    2289     88190874 :       len = get_non_default_template_args_count (args, flags);
    2290              : 
    2291     88190874 :       args = INNERMOST_TEMPLATE_ARGS (args);
    2292    223027432 :       for (ix = 0; ix != len; ix++)
    2293              :         {
    2294    134836558 :           tree arg = TREE_VEC_ELT (args, ix);
    2295              : 
    2296              :           /* Only print a comma if we know there is an argument coming. In
    2297              :              the case of an empty template argument pack, no actual
    2298              :              argument will be printed.  */
    2299    134836558 :           if (ix
    2300    134836558 :               && (!ARGUMENT_PACK_P (arg)
    2301      3159444 :                   || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
    2302     46260197 :             pp_separate_with_comma (pp);
    2303              : 
    2304    134836558 :           if (!arg)
    2305            0 :             pp_string (pp, M_("<template parameter error>"));
    2306              :           else
    2307    134836558 :             dump_template_argument (pp, arg, flags);
    2308              :         }
    2309              :     }
    2310        22934 :   else if (primary)
    2311              :     {
    2312        22928 :       tree tpl = TI_TEMPLATE (info);
    2313        22928 :       tree parms = DECL_TEMPLATE_PARMS (tpl);
    2314        22928 :       int len, ix;
    2315              : 
    2316        22928 :       parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
    2317        45856 :       len = parms ? TREE_VEC_LENGTH (parms) : 0;
    2318              : 
    2319        61653 :       for (ix = 0; ix != len; ix++)
    2320              :         {
    2321        38725 :           tree parm;
    2322              : 
    2323        38725 :           if (TREE_VEC_ELT (parms, ix) == error_mark_node)
    2324              :             {
    2325            0 :               pp_string (pp, M_("<template parameter error>"));
    2326            0 :               continue;
    2327              :             }
    2328              : 
    2329        38725 :           parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
    2330              : 
    2331        38725 :           if (ix)
    2332        15797 :             pp_separate_with_comma (pp);
    2333              : 
    2334        38725 :           dump_decl (pp, parm, flags & ~TFF_DECL_SPECIFIERS);
    2335              :         }
    2336              :     }
    2337     88213808 :   pp_cxx_end_template_argument_list (pp);
    2338              : }
    2339              : 
    2340              : /* Print out the arguments of CALL_EXPR T as a parenthesized list using
    2341              :    flags FLAGS.  Skip over the first argument if SKIPFIRST is true.  */
    2342              : 
    2343              : static void
    2344         5744 : dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst)
    2345              : {
    2346         5744 :   const int len = call_expr_nargs (t);
    2347              : 
    2348         5744 :   pp_cxx_left_paren (pp);
    2349        11332 :   for (int i = skipfirst; i < len; ++i)
    2350              :     {
    2351         5588 :       tree arg = get_nth_callarg (t, i);
    2352         5588 :       dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
    2353         5588 :       if (i + 1 < len)
    2354         1688 :         pp_separate_with_comma (pp);
    2355              :     }
    2356         5744 :   pp_cxx_right_paren (pp);
    2357         5744 : }
    2358              : 
    2359              : /* Print out a list of initializers (subr of dump_expr).  */
    2360              : 
    2361              : static void
    2362          206 : dump_expr_list (cxx_pretty_printer *pp, tree l, int flags)
    2363              : {
    2364          234 :   while (l)
    2365              :     {
    2366          124 :       dump_expr (pp, TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
    2367          124 :       l = TREE_CHAIN (l);
    2368          124 :       if (l)
    2369           28 :         pp_separate_with_comma (pp);
    2370              :     }
    2371          206 : }
    2372              : 
    2373              : /* Print out a vector of initializers (subr of dump_expr).  */
    2374              : 
    2375              : static void
    2376        20602 : dump_expr_init_vec (cxx_pretty_printer *pp, vec<constructor_elt, va_gc> *v,
    2377              :                     int flags)
    2378              : {
    2379        20602 :   unsigned HOST_WIDE_INT idx;
    2380        20602 :   tree value;
    2381              : 
    2382        44009 :   FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
    2383              :     {
    2384        23407 :       if (TREE_CODE (value) == RAW_DATA_CST)
    2385            0 :         for (unsigned i = 0; i < (unsigned) RAW_DATA_LENGTH (value); ++i)
    2386              :           {
    2387            0 :             if (TYPE_UNSIGNED (TREE_TYPE (value))
    2388            0 :                 || TYPE_PRECISION (TREE_TYPE (value)) > CHAR_BIT)
    2389            0 :               pp_decimal_int (pp, RAW_DATA_UCHAR_ELT (value, i));
    2390              :             else
    2391            0 :               pp_decimal_int (pp, RAW_DATA_SCHAR_ELT (value, i));
    2392            0 :             if (i == RAW_DATA_LENGTH (value) - 1U)
    2393              :               break;
    2394            0 :             else if (i == 9 && RAW_DATA_LENGTH (value) > 20)
    2395              :               {
    2396            0 :                 pp_string (pp, ", ..., ");
    2397            0 :                 i = RAW_DATA_LENGTH (value) - 11;
    2398              :               }
    2399              :             else
    2400            0 :               pp_separate_with_comma (pp);
    2401              :           }
    2402              :       else
    2403        23407 :         dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS);
    2404        23407 :       if (idx != v->length () - 1)
    2405         2832 :         pp_separate_with_comma (pp);
    2406              :     }
    2407        20602 : }
    2408              : 
    2409              : 
    2410              : /* We've gotten an indirect REFERENCE (an OBJ_TYPE_REF) to a virtual
    2411              :    function.  Resolve it to a close relative -- in the sense of static
    2412              :    type -- variant being overridden.  That is close to what was written in
    2413              :    the source code.  Subroutine of dump_expr.  */
    2414              : 
    2415              : static tree
    2416          143 : resolve_virtual_fun_from_obj_type_ref (tree ref)
    2417              : {
    2418          143 :   tree obj_type = TREE_TYPE (OBJ_TYPE_REF_TOKEN (ref));
    2419          143 :   HOST_WIDE_INT index = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref));
    2420          143 :   tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type)));
    2421          280 :   while (index)
    2422              :     {
    2423          137 :       fun = TREE_CHAIN (fun);
    2424          137 :       index -= (TARGET_VTABLE_USES_DESCRIPTORS
    2425              :                 ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
    2426              :     }
    2427              : 
    2428          143 :   return BV_FN (fun);
    2429              : }
    2430              : 
    2431              : /* Print out an expression E under control of FLAGS.  */
    2432              : 
    2433              : static void
    2434     20846283 : dump_expr (cxx_pretty_printer *pp, tree t, int flags)
    2435              : {
    2436     20865108 :   tree op;
    2437              : 
    2438     20865108 :   if (t == 0)
    2439              :     return;
    2440              : 
    2441     20865080 :   if (STATEMENT_CLASS_P (t))
    2442              :     {
    2443           15 :       pp_cxx_ws_string (pp, M_("<statement>"));
    2444           15 :       return;
    2445              :     }
    2446              : 
    2447     20865065 :   switch (TREE_CODE (t))
    2448              :     {
    2449        70519 :     case VAR_DECL:
    2450        70519 :     case PARM_DECL:
    2451        70519 :     case FIELD_DECL:
    2452        70519 :     case CONST_DECL:
    2453        70519 :     case FUNCTION_DECL:
    2454        70519 :     case TEMPLATE_DECL:
    2455        70519 :     case NAMESPACE_DECL:
    2456        70519 :     case LABEL_DECL:
    2457        70519 :     case OVERLOAD:
    2458        70519 :     case TYPE_DECL:
    2459        70519 :     case USING_DECL:
    2460        70519 :     case IDENTIFIER_NODE:
    2461        70519 :       dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
    2462              :                                     |TFF_TEMPLATE_HEADER))
    2463              :                          | TFF_NO_TEMPLATE_BINDINGS
    2464        70519 :                          | TFF_NO_FUNCTION_ARGUMENTS));
    2465        70519 :       break;
    2466              : 
    2467         6457 :     case SSA_NAME:
    2468         6457 :       if (SSA_NAME_VAR (t)
    2469         6385 :           && !DECL_ARTIFICIAL (SSA_NAME_VAR (t)))
    2470              :         dump_expr (pp, SSA_NAME_VAR (t), flags);
    2471              :       else
    2472           75 :         pp_cxx_ws_string (pp, M_("<unknown>"));
    2473              :       break;
    2474              : 
    2475     20725011 :     case VOID_CST:
    2476     20725011 :     case INTEGER_CST:
    2477     20725011 :     case REAL_CST:
    2478     20725011 :     case STRING_CST:
    2479     20725011 :     case COMPLEX_CST:
    2480     20725011 :       pp->constant (t);
    2481     20725011 :       break;
    2482              : 
    2483            0 :     case USERDEF_LITERAL:
    2484            0 :       pp_cxx_userdef_literal (pp, t);
    2485            0 :       break;
    2486              : 
    2487          115 :     case THROW_EXPR:
    2488              :       /* While waiting for caret diagnostics, avoid printing
    2489              :          __cxa_allocate_exception, __cxa_throw, and the like.  */
    2490          115 :       pp_cxx_ws_string (pp, M_("<throw-expression>"));
    2491          115 :       break;
    2492              : 
    2493          478 :     case PTRMEM_CST:
    2494          478 :       pp_ampersand (pp);
    2495          478 :       dump_type (pp, PTRMEM_CST_CLASS (t), flags);
    2496          478 :       pp_cxx_colon_colon (pp);
    2497          478 :       pp_cxx_tree_identifier (pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
    2498          478 :       break;
    2499              : 
    2500          420 :     case COMPOUND_EXPR:
    2501          420 :       pp_cxx_left_paren (pp);
    2502          420 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2503          420 :       pp_separate_with_comma (pp);
    2504          420 :       dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    2505          420 :       pp_cxx_right_paren (pp);
    2506          420 :       break;
    2507              : 
    2508           53 :     case COND_EXPR:
    2509           53 :     case VEC_COND_EXPR:
    2510           53 :       pp_cxx_left_paren (pp);
    2511           53 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2512           53 :       pp_string (pp, " ? ");
    2513           53 :       dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    2514           53 :       pp_string (pp, " : ");
    2515           53 :       dump_expr (pp, TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
    2516           53 :       pp_cxx_right_paren (pp);
    2517           53 :       break;
    2518              : 
    2519          248 :     case SAVE_EXPR:
    2520          248 :       if (TREE_HAS_CONSTRUCTOR (t))
    2521              :         {
    2522            0 :           pp_cxx_ws_string (pp, "new");
    2523            0 :           pp_cxx_whitespace (pp);
    2524            0 :           dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
    2525              :         }
    2526              :       else
    2527          248 :         dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2528              :       break;
    2529              : 
    2530         5744 :     case AGGR_INIT_EXPR:
    2531         5744 :     case CALL_EXPR:
    2532         5744 :       {
    2533         5744 :         tree fn = cp_get_callee (t);
    2534         5744 :         bool skipfirst = false;
    2535              : 
    2536              :         /* Deal with internal functions.  */
    2537         5744 :         if (fn == NULL_TREE)
    2538              :           {
    2539            3 :             pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t)));
    2540            3 :             dump_call_expr_args (pp, t, flags, skipfirst);
    2541            3 :             break;
    2542              :           }
    2543              : 
    2544         5741 :         if (TREE_CODE (fn) == ADDR_EXPR)
    2545         4952 :           fn = TREE_OPERAND (fn, 0);
    2546              : 
    2547              :         /* Nobody is interested in seeing the guts of vcalls.  */
    2548         5741 :         if (TREE_CODE (fn) == OBJ_TYPE_REF)
    2549          137 :           fn = resolve_virtual_fun_from_obj_type_ref (fn);
    2550              : 
    2551         5741 :         if (TREE_TYPE (fn) != NULL_TREE
    2552         5529 :             && NEXT_CODE (fn) == METHOD_TYPE
    2553         7823 :             && call_expr_nargs (t))
    2554              :           {
    2555         2079 :             tree ob = get_nth_callarg (t, 0);
    2556         2079 :             if (is_dummy_object (ob))
    2557              :               /* Don't print dummy object.  */;
    2558         1600 :             else if (TREE_CODE (ob) == ADDR_EXPR)
    2559              :               {
    2560         1032 :                 dump_expr (pp, TREE_OPERAND (ob, 0),
    2561              :                            flags | TFF_EXPR_IN_PARENS);
    2562         1032 :                 pp_cxx_dot (pp);
    2563              :               }
    2564          568 :             else if (!is_this_parameter (ob))
    2565              :               {
    2566          568 :                 dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    2567          568 :                 pp_cxx_arrow (pp);
    2568              :               }
    2569              :             skipfirst = true;
    2570              :           }
    2571         5741 :         if (flag_sanitize & SANITIZE_UNDEFINED
    2572         5741 :             && is_ubsan_builtin_p (fn))
    2573              :           {
    2574            0 :             pp_string (cxx_pp, M_("<ubsan routine call>"));
    2575            0 :             break;
    2576              :           }
    2577              : 
    2578         5741 :         if (TREE_CODE (fn) == FUNCTION_DECL
    2579         5122 :             && DECL_CONSTRUCTOR_P (fn)
    2580         6418 :             && is_dummy_object (get_nth_callarg (t, 0)))
    2581          479 :           dump_type (pp, DECL_CONTEXT (fn), flags);
    2582              :         else
    2583         5262 :           dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS);
    2584         5741 :         dump_call_expr_args (pp, t, flags, skipfirst);
    2585              :       }
    2586         5741 :       break;
    2587              : 
    2588         1430 :     case TARGET_EXPR:
    2589              :       /* Note that this only works for G++ target exprs.  If somebody
    2590              :          builds a general TARGET_EXPR, there's no way to represent that
    2591              :          it initializes anything other that the parameter slot for the
    2592              :          default argument.  Note we may have cleared out the first
    2593              :          operand in expand_expr, so don't go killing ourselves.  */
    2594         1430 :       if (TARGET_EXPR_INITIAL (t))
    2595         1430 :         dump_expr (pp, TARGET_EXPR_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
    2596              :       break;
    2597              : 
    2598          302 :     case POINTER_PLUS_EXPR:
    2599          302 :       dump_binary_op (pp, "+", t, flags);
    2600          302 :       break;
    2601              : 
    2602            2 :     case POINTER_DIFF_EXPR:
    2603            2 :       dump_binary_op (pp, "-", t, flags);
    2604            2 :       break;
    2605              : 
    2606           24 :     case INIT_EXPR:
    2607           24 :     case MODIFY_EXPR:
    2608           24 :       dump_binary_op (pp, OVL_OP_INFO (true, NOP_EXPR)->name, t, flags);
    2609           24 :       break;
    2610              : 
    2611         1624 :     case PLUS_EXPR:
    2612         1624 :     case MINUS_EXPR:
    2613         1624 :     case MULT_EXPR:
    2614         1624 :     case TRUNC_DIV_EXPR:
    2615         1624 :     case TRUNC_MOD_EXPR:
    2616         1624 :     case MIN_EXPR:
    2617         1624 :     case MAX_EXPR:
    2618         1624 :     case LSHIFT_EXPR:
    2619         1624 :     case RSHIFT_EXPR:
    2620         1624 :     case BIT_IOR_EXPR:
    2621         1624 :     case BIT_XOR_EXPR:
    2622         1624 :     case BIT_AND_EXPR:
    2623         1624 :     case TRUTH_ANDIF_EXPR:
    2624         1624 :     case TRUTH_ORIF_EXPR:
    2625         1624 :     case LT_EXPR:
    2626         1624 :     case LE_EXPR:
    2627         1624 :     case GT_EXPR:
    2628         1624 :     case GE_EXPR:
    2629         1624 :     case EQ_EXPR:
    2630         1624 :     case NE_EXPR:
    2631         1624 :     case SPACESHIP_EXPR:
    2632         1624 :       dump_binary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags);
    2633         1624 :       break;
    2634              : 
    2635            9 :     case CEIL_DIV_EXPR:
    2636            9 :     case FLOOR_DIV_EXPR:
    2637            9 :     case ROUND_DIV_EXPR:
    2638            9 :     case RDIV_EXPR:
    2639            9 :     case EXACT_DIV_EXPR:
    2640            9 :       dump_binary_op (pp, "/", t, flags);
    2641            9 :       break;
    2642              : 
    2643            0 :     case CEIL_MOD_EXPR:
    2644            0 :     case FLOOR_MOD_EXPR:
    2645            0 :     case ROUND_MOD_EXPR:
    2646            0 :       dump_binary_op (pp, "%", t, flags);
    2647            0 :       break;
    2648              : 
    2649         1793 :     case COMPONENT_REF:
    2650         1793 :       {
    2651         1793 :         tree ob = TREE_OPERAND (t, 0);
    2652         1793 :         if (INDIRECT_REF_P (ob))
    2653              :           {
    2654          796 :             ob = TREE_OPERAND (ob, 0);
    2655          796 :             if (!is_this_parameter (ob)
    2656          796 :                 && !is_dummy_object (ob))
    2657              :               {
    2658          772 :                 dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    2659          772 :                 if (TYPE_REF_P (TREE_TYPE (ob)))
    2660          201 :                   pp_cxx_dot (pp);
    2661              :                 else
    2662          571 :                   pp_cxx_arrow (pp);
    2663              :               }
    2664              :           }
    2665              :         else
    2666              :           {
    2667          997 :             dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    2668          997 :             if (TREE_CODE (ob) != ARROW_EXPR)
    2669          994 :               pp_cxx_dot (pp);
    2670              :           }
    2671         1793 :         dump_expr (pp, TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
    2672              :       }
    2673         1793 :       break;
    2674              : 
    2675          271 :     case ARRAY_REF:
    2676          271 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2677          271 :       pp_cxx_left_bracket (pp);
    2678          271 :       dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    2679          271 :       pp_cxx_right_bracket (pp);
    2680          271 :       break;
    2681              : 
    2682           33 :     case OMP_ARRAY_SECTION:
    2683           33 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    2684           33 :       pp_cxx_left_bracket (pp);
    2685           33 :       dump_expr (pp, TREE_OPERAND (t, 1), flags);
    2686           33 :       pp_colon (pp);
    2687           33 :       dump_expr (pp, TREE_OPERAND (t, 2), flags);
    2688           33 :       pp_cxx_right_bracket (pp);
    2689           33 :       break;
    2690              : 
    2691            0 :     case UNARY_PLUS_EXPR:
    2692            0 :       dump_unary_op (pp, "+", t, flags);
    2693            0 :       break;
    2694              : 
    2695         2427 :     case ADDR_EXPR:
    2696         2427 :       if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
    2697         1681 :           || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
    2698              :           /* An ADDR_EXPR can have reference type.  In that case, we
    2699              :              shouldn't print the `&' doing so indicates to the user
    2700              :              that the expression has pointer type.  */
    2701         4038 :           || (TREE_TYPE (t)
    2702         1611 :               && TYPE_REF_P (TREE_TYPE (t))))
    2703          841 :         dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2704         1586 :       else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL)
    2705            3 :         dump_unary_op (pp, "&&", t, flags);
    2706              :       else
    2707         1583 :         dump_unary_op (pp, "&", t, flags);
    2708              :       break;
    2709              : 
    2710          697 :     case INDIRECT_REF:
    2711          697 :       if (TREE_HAS_CONSTRUCTOR (t))
    2712              :         {
    2713            0 :           t = TREE_OPERAND (t, 0);
    2714            0 :           gcc_assert (TREE_CODE (t) == CALL_EXPR);
    2715            0 :           dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
    2716            0 :           dump_call_expr_args (pp, t, flags, true);
    2717              :         }
    2718          697 :       else if (is_stub_object (t))
    2719              :         {
    2720           18 :           pp_string (pp, "std::declval<");
    2721           18 :           if (lvalue_p (t)) /* T& */
    2722            0 :             dump_type (pp, TREE_TYPE (STRIP_REFERENCE_REF (t)), flags);
    2723              :           else /* T */
    2724           18 :             dump_type (pp, TREE_TYPE (t), flags);
    2725           18 :           pp_string (pp, ">()");
    2726              :         }
    2727              :       else
    2728              :         {
    2729          679 :           if (TREE_OPERAND (t,0) != NULL_TREE
    2730          679 :               && TREE_TYPE (TREE_OPERAND (t, 0))
    2731         1350 :               && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
    2732          413 :             dump_expr (pp, TREE_OPERAND (t, 0), flags);
    2733              :           else
    2734          266 :             dump_unary_op (pp, "*", t, flags);
    2735              :         }
    2736              :       break;
    2737              : 
    2738          576 :     case MEM_REF:
    2739              :       /* Delegate to the base "C" pretty printer.  */
    2740          576 :       pp->c_pretty_printer::unary_expression (t);
    2741          576 :       break;
    2742              : 
    2743            0 :     case TARGET_MEM_REF:
    2744              :       /* TARGET_MEM_REF can't appear directly from source, but can appear
    2745              :          during late GIMPLE optimizations and through late diagnostic we might
    2746              :          need to support it.  Print it as dereferencing of a pointer after
    2747              :          cast to the TARGET_MEM_REF type, with pointer arithmetics on some
    2748              :          pointer to single byte types, so
    2749              :          *(type *)((char *) ptr + step * index + index2) if all the operands
    2750              :          are present and the casts are needed.  */
    2751            0 :       pp_cxx_star (pp);
    2752            0 :       pp_cxx_left_paren (pp);
    2753            0 :       if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (t)))) == NULL_TREE
    2754            0 :           || !integer_onep (TYPE_SIZE_UNIT
    2755              :                                 (TREE_TYPE (TREE_TYPE (TMR_BASE (t))))))
    2756              :         {
    2757            0 :           if (TYPE_SIZE_UNIT (TREE_TYPE (t))
    2758            0 :               && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (t))))
    2759              :             {
    2760            0 :               pp_cxx_left_paren (pp);
    2761            0 :               dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
    2762              :             }
    2763              :           else
    2764              :             {
    2765            0 :               dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
    2766            0 :               pp_cxx_right_paren (pp);
    2767            0 :               pp_cxx_left_paren (pp);
    2768            0 :               pp_cxx_left_paren (pp);
    2769            0 :               dump_type (pp, build_pointer_type (char_type_node), flags);
    2770              :             }
    2771            0 :           pp_cxx_right_paren (pp);
    2772              :         }
    2773            0 :       else if (!same_type_p (TREE_TYPE (t),
    2774              :                              TREE_TYPE (TREE_TYPE (TMR_BASE (t)))))
    2775              :         {
    2776            0 :           dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
    2777            0 :           pp_cxx_right_paren (pp);
    2778            0 :           pp_cxx_left_paren (pp);
    2779              :         }
    2780            0 :       dump_expr (pp, TMR_BASE (t), flags);
    2781            0 :       if (TMR_STEP (t) && TMR_INDEX (t))
    2782              :         {
    2783            0 :           pp_cxx_ws_string (pp, "+");
    2784            0 :           dump_expr (pp, TMR_INDEX (t), flags);
    2785            0 :           pp_cxx_ws_string (pp, "*");
    2786            0 :           dump_expr (pp, TMR_STEP (t), flags);
    2787              :         }
    2788            0 :       if (TMR_INDEX2 (t))
    2789              :         {
    2790            0 :           pp_cxx_ws_string (pp, "+");
    2791            0 :           dump_expr (pp, TMR_INDEX2 (t), flags);
    2792              :         }
    2793            0 :       if (!integer_zerop (TMR_OFFSET (t)))
    2794              :         {
    2795            0 :           pp_cxx_ws_string (pp, "+");
    2796            0 :           dump_expr (pp, fold_convert (ssizetype, TMR_OFFSET (t)), flags);
    2797              :         }
    2798            0 :       pp_cxx_right_paren (pp);
    2799            0 :       break;
    2800              : 
    2801          221 :     case NEGATE_EXPR:
    2802          221 :     case BIT_NOT_EXPR:
    2803          221 :     case TRUTH_NOT_EXPR:
    2804          221 :     case PREDECREMENT_EXPR:
    2805          221 :     case PREINCREMENT_EXPR:
    2806          221 :       dump_unary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags);
    2807          221 :       break;
    2808              : 
    2809            0 :     case POSTDECREMENT_EXPR:
    2810            0 :     case POSTINCREMENT_EXPR:
    2811            0 :       pp_cxx_left_paren (pp);
    2812            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2813            0 :       pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name);
    2814            0 :       pp_cxx_right_paren (pp);
    2815            0 :       break;
    2816              : 
    2817         1607 :     case NON_LVALUE_EXPR:
    2818              :       /* FIXME: This is a KLUDGE workaround for a parsing problem.  There
    2819              :          should be another level of INDIRECT_REF so that I don't have to do
    2820              :          this.  */
    2821         1607 :       if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
    2822              :         {
    2823           21 :           tree next = TREE_TYPE (TREE_TYPE (t));
    2824              : 
    2825           21 :           while (TYPE_PTR_P (next))
    2826            0 :             next = TREE_TYPE (next);
    2827              : 
    2828           21 :           if (TREE_CODE (next) == FUNCTION_TYPE)
    2829              :             {
    2830            0 :               if (flags & TFF_EXPR_IN_PARENS)
    2831            0 :                 pp_cxx_left_paren (pp);
    2832            0 :               pp_cxx_star (pp);
    2833            0 :               dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    2834            0 :               if (flags & TFF_EXPR_IN_PARENS)
    2835            0 :                 pp_cxx_right_paren (pp);
    2836              :               break;
    2837              :             }
    2838              :           /* Else fall through.  */
    2839              :         }
    2840         1607 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2841         1607 :       break;
    2842              : 
    2843         9914 :     CASE_CONVERT:
    2844         9914 :     case IMPLICIT_CONV_EXPR:
    2845         9914 :     case VIEW_CONVERT_EXPR:
    2846         9914 :     case EXCESS_PRECISION_EXPR:
    2847         9914 :       {
    2848         9914 :         tree op = TREE_OPERAND (t, 0);
    2849              : 
    2850         9914 :         if (location_wrapper_p (t))
    2851              :           {
    2852              :             dump_expr (pp, op, flags);
    2853              :             break;
    2854              :           }
    2855              : 
    2856         5815 :         tree ttype = TREE_TYPE (t);
    2857         5815 :         tree optype = TREE_TYPE (op);
    2858         5815 :         if (!optype)
    2859          150 :           optype = unknown_type_node;
    2860              : 
    2861         5815 :         if (TREE_CODE (ttype) != TREE_CODE (optype)
    2862         3541 :             && INDIRECT_TYPE_P (ttype)
    2863         3245 :             && INDIRECT_TYPE_P (optype)
    2864         8982 :             && same_type_p (TREE_TYPE (optype),
    2865              :                             TREE_TYPE (ttype)))
    2866              :           {
    2867         3119 :             if (TYPE_REF_P (ttype))
    2868              :               {
    2869         2303 :                 STRIP_NOPS (op);
    2870         2303 :                 if (TREE_CODE (op) == ADDR_EXPR)
    2871         1546 :                   dump_expr (pp, TREE_OPERAND (op, 0), flags);
    2872              :                 else
    2873          757 :                   dump_unary_op (pp, "*", t, flags);
    2874              :               }
    2875              :             else
    2876          816 :               dump_unary_op (pp, "&", t, flags);
    2877              :           }
    2878         2696 :         else if (!same_type_p (optype, ttype))
    2879              :           {
    2880              :             /* It is a cast, but we cannot tell whether it is a
    2881              :                reinterpret or static cast. Use the C style notation.  */
    2882         2399 :             if (flags & TFF_EXPR_IN_PARENS)
    2883         1818 :               pp_cxx_left_paren (pp);
    2884         2399 :             pp_cxx_left_paren (pp);
    2885         2399 :             dump_type (pp, TREE_TYPE (t), flags);
    2886         2399 :             pp_cxx_right_paren (pp);
    2887         2399 :             dump_expr (pp, op, flags | TFF_EXPR_IN_PARENS);
    2888         2399 :             if (flags & TFF_EXPR_IN_PARENS)
    2889         1818 :               pp_cxx_right_paren (pp);
    2890              :           }
    2891              :         else
    2892              :           dump_expr (pp, op, flags);
    2893              :         break;
    2894              :       }
    2895              : 
    2896        26353 :     case CONSTRUCTOR:
    2897        26353 :       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
    2898              :         {
    2899           21 :           tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
    2900              : 
    2901           21 :           if (integer_zerop (idx))
    2902              :             {
    2903              :               /* A NULL pointer-to-member constant.  */
    2904            8 :               pp_cxx_left_paren (pp);
    2905            8 :               pp_cxx_left_paren (pp);
    2906            8 :               dump_type (pp, TREE_TYPE (t), flags);
    2907            8 :               pp_cxx_right_paren (pp);
    2908            8 :               pp_character (pp, '0');
    2909            8 :               pp_cxx_right_paren (pp);
    2910            8 :               break;
    2911              :             }
    2912           13 :           else if (tree_fits_shwi_p (idx))
    2913              :             {
    2914            4 :               tree virtuals;
    2915            4 :               unsigned HOST_WIDE_INT n;
    2916              : 
    2917            4 :               t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
    2918            4 :               t = TYPE_METHOD_BASETYPE (t);
    2919            4 :               virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
    2920              : 
    2921            4 :               n = tree_to_shwi (idx);
    2922              : 
    2923              :               /* Map vtable index back one, to allow for the null pointer to
    2924              :                  member.  */
    2925            4 :               --n;
    2926              : 
    2927            4 :               while (n > 0 && virtuals)
    2928              :                 {
    2929            0 :                   --n;
    2930            0 :                   virtuals = TREE_CHAIN (virtuals);
    2931              :                 }
    2932            4 :               if (virtuals)
    2933              :                 {
    2934            4 :                   dump_expr (pp, BV_FN (virtuals),
    2935              :                              flags | TFF_EXPR_IN_PARENS);
    2936            4 :                   break;
    2937              :                 }
    2938              :             }
    2939              :         }
    2940        50771 :       if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
    2941          423 :         pp_string (pp, "<lambda closure object>");
    2942        26341 :       if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t))
    2943              :         {
    2944         5739 :           dump_type (pp, TREE_TYPE (t), 0);
    2945         5739 :           pp_cxx_left_paren (pp);
    2946         5739 :           pp_cxx_right_paren (pp);
    2947              :         }
    2948              :       else
    2949              :         {
    2950        20602 :           if (!BRACE_ENCLOSED_INITIALIZER_P (t))
    2951        20543 :             dump_type (pp, TREE_TYPE (t), 0);
    2952        20602 :           pp_cxx_left_brace (pp);
    2953        20602 :           dump_expr_init_vec (pp, CONSTRUCTOR_ELTS (t), flags);
    2954        20602 :           pp_cxx_right_brace (pp);
    2955              :         }
    2956              : 
    2957              :       break;
    2958              : 
    2959           25 :     case OFFSET_REF:
    2960           25 :       {
    2961           25 :         tree ob = TREE_OPERAND (t, 0);
    2962           25 :         if (is_dummy_object (ob))
    2963              :           {
    2964           22 :             t = TREE_OPERAND (t, 1);
    2965           22 :             if (TREE_CODE (t) == FUNCTION_DECL)
    2966              :               /* A::f */
    2967            0 :               dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS);
    2968           22 :             else if (BASELINK_P (t))
    2969     20865127 :               dump_expr (pp, OVL_FIRST (BASELINK_FUNCTIONS (t)),
    2970              :                          flags | TFF_EXPR_IN_PARENS);
    2971              :             else
    2972            3 :               dump_decl (pp, t, flags);
    2973              :           }
    2974              :         else
    2975              :           {
    2976            3 :             if (INDIRECT_REF_P (ob))
    2977              :               {
    2978            3 :                 dump_expr (pp, TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
    2979            3 :                 pp_cxx_arrow (pp);
    2980            3 :                 pp_cxx_star (pp);
    2981              :               }
    2982              :             else
    2983              :               {
    2984            0 :                 dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    2985            0 :                 pp_cxx_dot (pp);
    2986            0 :                 pp_cxx_star (pp);
    2987              :               }
    2988            3 :             dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    2989              :           }
    2990              :         break;
    2991              :       }
    2992              : 
    2993         1461 :     case TEMPLATE_PARM_INDEX:
    2994         1461 :       dump_decl (pp, TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
    2995         1461 :       break;
    2996              : 
    2997          159 :     case CAST_EXPR:
    2998          159 :       if (TREE_OPERAND (t, 0) == NULL_TREE
    2999          159 :           || TREE_CHAIN (TREE_OPERAND (t, 0)))
    3000              :         {
    3001          111 :           dump_type (pp, TREE_TYPE (t), flags);
    3002          111 :           pp_cxx_left_paren (pp);
    3003          111 :           dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
    3004          111 :           pp_cxx_right_paren (pp);
    3005              :         }
    3006              :       else
    3007              :         {
    3008           48 :           pp_cxx_left_paren (pp);
    3009           48 :           dump_type (pp, TREE_TYPE (t), flags);
    3010           48 :           pp_cxx_right_paren (pp);
    3011           48 :           pp_cxx_left_paren (pp);
    3012           48 :           dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
    3013           48 :           pp_cxx_right_paren (pp);
    3014              :         }
    3015              :       break;
    3016              : 
    3017           31 :     case STATIC_CAST_EXPR:
    3018           31 :       pp_cxx_ws_string (pp, "static_cast");
    3019           31 :       goto cast;
    3020            0 :     case REINTERPRET_CAST_EXPR:
    3021            0 :       pp_cxx_ws_string (pp, "reinterpret_cast");
    3022            0 :       goto cast;
    3023            3 :     case CONST_CAST_EXPR:
    3024            3 :       pp_cxx_ws_string (pp, "const_cast");
    3025            3 :       goto cast;
    3026            0 :     case DYNAMIC_CAST_EXPR:
    3027            0 :       pp_cxx_ws_string (pp, "dynamic_cast");
    3028           34 :     cast:
    3029           34 :       pp_cxx_begin_template_argument_list (pp);
    3030           34 :       dump_type (pp, TREE_TYPE (t), flags);
    3031           34 :       pp_cxx_end_template_argument_list (pp);
    3032           34 :       pp_cxx_left_paren (pp);
    3033           34 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3034           34 :       pp_cxx_right_paren (pp);
    3035           34 :       break;
    3036              : 
    3037            3 :     case ARROW_EXPR:
    3038            3 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3039            3 :       pp_cxx_arrow (pp);
    3040            3 :       break;
    3041              : 
    3042          190 :     case SIZEOF_EXPR:
    3043          190 :     case ALIGNOF_EXPR:
    3044          190 :       if (TREE_CODE (t) == SIZEOF_EXPR)
    3045          172 :         pp_cxx_ws_string (pp, "sizeof");
    3046           18 :       else if (ALIGNOF_EXPR_STD_P (t))
    3047           12 :         pp_cxx_ws_string (pp, "alignof");
    3048              :       else
    3049            6 :         pp_cxx_ws_string (pp, "__alignof__");
    3050          190 :       op = TREE_OPERAND (t, 0);
    3051          190 :       if (PACK_EXPANSION_P (op))
    3052              :         {
    3053           84 :           pp_string (pp, "...");
    3054           84 :           op = PACK_EXPANSION_PATTERN (op);
    3055              :         }
    3056          190 :       pp_cxx_whitespace (pp);
    3057          190 :       pp_cxx_left_paren (pp);
    3058          190 :       if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
    3059           29 :         dump_type (pp, TREE_TYPE (op), flags);
    3060          161 :       else if (TYPE_P (TREE_OPERAND (t, 0)))
    3061           98 :         dump_type (pp, op, flags);
    3062              :       else
    3063           63 :         dump_expr (pp, op, flags);
    3064          190 :       pp_cxx_right_paren (pp);
    3065          190 :       break;
    3066              : 
    3067            0 :     case AT_ENCODE_EXPR:
    3068            0 :       pp_cxx_ws_string (pp, "@encode");
    3069            0 :       pp_cxx_whitespace (pp);
    3070            0 :       pp_cxx_left_paren (pp);
    3071            0 :       dump_type (pp, TREE_OPERAND (t, 0), flags);
    3072            0 :       pp_cxx_right_paren (pp);
    3073            0 :       break;
    3074              : 
    3075           12 :     case NOEXCEPT_EXPR:
    3076           12 :       pp_cxx_ws_string (pp, "noexcept");
    3077           12 :       pp_cxx_whitespace (pp);
    3078           12 :       pp_cxx_left_paren (pp);
    3079           12 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3080           12 :       pp_cxx_right_paren (pp);
    3081           12 :       break;
    3082              : 
    3083            0 :     case REALPART_EXPR:
    3084            0 :     case IMAGPART_EXPR:
    3085            0 :       pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name);
    3086            0 :       pp_cxx_whitespace (pp);
    3087            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3088            0 :       break;
    3089              : 
    3090            0 :     case DEFERRED_PARSE:
    3091            0 :       pp_string (pp, M_("<unparsed>"));
    3092            0 :       break;
    3093              : 
    3094            0 :     case TRY_CATCH_EXPR:
    3095            0 :     case CLEANUP_POINT_EXPR:
    3096            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3097            0 :       break;
    3098              : 
    3099            0 :     case PSEUDO_DTOR_EXPR:
    3100            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3101            0 :       pp_cxx_dot (pp);
    3102            0 :       if (TREE_OPERAND (t, 1))
    3103              :         {
    3104            0 :           dump_type (pp, TREE_OPERAND (t, 1), flags);
    3105            0 :           pp_cxx_colon_colon (pp);
    3106              :         }
    3107            0 :       pp_cxx_complement (pp);
    3108            0 :       dump_type (pp, TREE_OPERAND (t, 2), flags);
    3109            0 :       break;
    3110              : 
    3111         1380 :     case TEMPLATE_ID_EXPR:
    3112         1380 :       dump_decl (pp, t, flags);
    3113         1380 :       break;
    3114              : 
    3115           28 :     case BIND_EXPR:
    3116           28 :     case STMT_EXPR:
    3117           28 :     case EXPR_STMT:
    3118           28 :     case STATEMENT_LIST:
    3119              :       /* We don't yet have a way of dumping statements in a
    3120              :          human-readable format.  */
    3121           28 :       pp_string (pp, "({...})");
    3122           28 :       break;
    3123              : 
    3124            0 :     case LOOP_EXPR:
    3125            0 :       pp_string (pp, "while (1) { ");
    3126            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    3127            0 :       pp_cxx_right_brace (pp);
    3128            0 :       break;
    3129              : 
    3130            0 :     case EXIT_EXPR:
    3131            0 :       pp_string (pp, "if (");
    3132            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    3133            0 :       pp_string (pp, ") break; ");
    3134            0 :       break;
    3135              : 
    3136          130 :     case BASELINK:
    3137          130 :       dump_expr (pp, BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS);
    3138          130 :       break;
    3139              : 
    3140          356 :     case EMPTY_CLASS_EXPR:
    3141          356 :       dump_type (pp, TREE_TYPE (t), flags);
    3142          356 :       pp_cxx_left_paren (pp);
    3143          356 :       pp_cxx_right_paren (pp);
    3144          356 :       break;
    3145              : 
    3146            0 :     case ARGUMENT_PACK_SELECT:
    3147            0 :       dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
    3148            0 :       break;
    3149              : 
    3150           91 :     case RECORD_TYPE:
    3151           91 :     case UNION_TYPE:
    3152           91 :     case ENUMERAL_TYPE:
    3153           91 :     case REAL_TYPE:
    3154           91 :     case VOID_TYPE:
    3155           91 :     case OPAQUE_TYPE:
    3156           91 :     case BOOLEAN_TYPE:
    3157           91 :     case INTEGER_TYPE:
    3158           91 :     case COMPLEX_TYPE:
    3159           91 :     case VECTOR_TYPE:
    3160           91 :     case DECLTYPE_TYPE:
    3161           91 :       pp_type_specifier_seq (pp, t);
    3162           91 :       break;
    3163              : 
    3164            0 :     case TYPENAME_TYPE:
    3165              :       /* We get here when we want to print a dependent type as an
    3166              :          id-expression, without any disambiguator decoration.  */
    3167            0 :       pp->id_expression (t);
    3168            0 :       break;
    3169              : 
    3170           33 :     case TEMPLATE_TYPE_PARM:
    3171           33 :     case TEMPLATE_TEMPLATE_PARM:
    3172           33 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    3173           33 :       dump_type (pp, t, flags);
    3174           33 :       break;
    3175              : 
    3176           56 :     case TRAIT_EXPR:
    3177           56 :       pp_cxx_trait (pp, t);
    3178           56 :       break;
    3179              : 
    3180            3 :     case VA_ARG_EXPR:
    3181            3 :       pp_cxx_va_arg_expression (pp, t);
    3182            3 :       break;
    3183              : 
    3184           15 :     case OFFSETOF_EXPR:
    3185           15 :       pp_cxx_offsetof_expression (pp, t);
    3186           15 :       break;
    3187              : 
    3188            0 :     case ADDRESSOF_EXPR:
    3189            0 :       pp_cxx_addressof_expression (pp, t);
    3190            0 :       break;
    3191              : 
    3192          923 :     case SCOPE_REF:
    3193          923 :       dump_decl (pp, t, flags);
    3194          923 :       break;
    3195              : 
    3196         2540 :     case EXPR_PACK_EXPANSION:
    3197         2540 :     case UNARY_LEFT_FOLD_EXPR:
    3198         2540 :     case UNARY_RIGHT_FOLD_EXPR:
    3199         2540 :     case BINARY_LEFT_FOLD_EXPR:
    3200         2540 :     case BINARY_RIGHT_FOLD_EXPR:
    3201         2540 :     case TYPEID_EXPR:
    3202         2540 :     case MEMBER_REF:
    3203         2540 :     case DOTSTAR_EXPR:
    3204         2540 :     case NEW_EXPR:
    3205         2540 :     case VEC_NEW_EXPR:
    3206         2540 :     case DELETE_EXPR:
    3207         2540 :     case VEC_DELETE_EXPR:
    3208         2540 :     case MODOP_EXPR:
    3209         2540 :     case ABS_EXPR:
    3210         2540 :     case ABSU_EXPR:
    3211         2540 :     case CONJ_EXPR:
    3212         2540 :     case VECTOR_CST:
    3213         2540 :     case FIXED_CST:
    3214         2540 :     case UNORDERED_EXPR:
    3215         2540 :     case ORDERED_EXPR:
    3216         2540 :     case UNLT_EXPR:
    3217         2540 :     case UNLE_EXPR:
    3218         2540 :     case UNGT_EXPR:
    3219         2540 :     case UNGE_EXPR:
    3220         2540 :     case UNEQ_EXPR:
    3221         2540 :     case LTGT_EXPR:
    3222         2540 :     case COMPLEX_EXPR:
    3223         2540 :     case BIT_FIELD_REF:
    3224         2540 :     case FIX_TRUNC_EXPR:
    3225         2540 :     case FLOAT_EXPR:
    3226         2540 :       pp->expression (t);
    3227         2540 :       break;
    3228              : 
    3229            0 :     case PACK_INDEX_EXPR:
    3230            0 :       pp->expression (PACK_INDEX_PACK (t));
    3231            0 :       pp_cxx_left_bracket (pp);
    3232            0 :       pp->expression (PACK_INDEX_INDEX (t));
    3233            0 :       pp_cxx_right_bracket (pp);
    3234            0 :       break;
    3235              : 
    3236            0 :     case TRUTH_AND_EXPR:
    3237            0 :     case TRUTH_OR_EXPR:
    3238            0 :     case TRUTH_XOR_EXPR:
    3239            0 :       if (flags & TFF_EXPR_IN_PARENS)
    3240            0 :         pp_cxx_left_paren (pp);
    3241            0 :       pp->expression (t);
    3242            0 :       if (flags & TFF_EXPR_IN_PARENS)
    3243            0 :         pp_cxx_right_paren (pp);
    3244              :       break;
    3245              : 
    3246            6 :     case OBJ_TYPE_REF:
    3247            6 :       dump_expr (pp, resolve_virtual_fun_from_obj_type_ref (t), flags);
    3248            6 :       break;
    3249              : 
    3250           84 :     case LAMBDA_EXPR:
    3251           84 :       pp_string (pp, M_("<lambda>"));
    3252           84 :       break;
    3253              : 
    3254           10 :     case PAREN_EXPR:
    3255           10 :       pp_cxx_left_paren (pp);
    3256           10 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    3257           10 :       pp_cxx_right_paren (pp);
    3258           10 :       break;
    3259              : 
    3260            3 :     case REQUIRES_EXPR:
    3261            3 :       pp_cxx_requires_expr (cxx_pp, t);
    3262            3 :       break;
    3263              : 
    3264            0 :     case SIMPLE_REQ:
    3265            0 :       pp_cxx_simple_requirement (cxx_pp, t);
    3266            0 :       break;
    3267              : 
    3268            0 :     case TYPE_REQ:
    3269            0 :       pp_cxx_type_requirement (cxx_pp, t);
    3270            0 :       break;
    3271              : 
    3272            0 :     case COMPOUND_REQ:
    3273            0 :       pp_cxx_compound_requirement (cxx_pp, t);
    3274            0 :       break;
    3275              : 
    3276            0 :     case NESTED_REQ:
    3277            0 :       pp_cxx_nested_requirement (cxx_pp, t);
    3278            0 :       break;
    3279              : 
    3280          945 :     case ATOMIC_CONSTR:
    3281          945 :     case CONJ_CONSTR:
    3282          945 :     case DISJ_CONSTR:
    3283          945 :       {
    3284          945 :         pp_cxx_constraint (cxx_pp, t);
    3285          945 :         break;
    3286              :       }
    3287              : 
    3288           13 :     case PLACEHOLDER_EXPR:
    3289           13 :       pp_string (pp, M_("*this"));
    3290           13 :       break;
    3291              : 
    3292           47 :     case TREE_LIST:
    3293           47 :       dump_expr_list (pp, t, flags);
    3294           47 :       break;
    3295              : 
    3296            6 :     case NONTYPE_ARGUMENT_PACK:
    3297            6 :       {
    3298            6 :         tree args = ARGUMENT_PACK_ARGS (t);
    3299            6 :         int len = TREE_VEC_LENGTH (args);
    3300            6 :         pp_cxx_left_brace (pp);
    3301           12 :         for (int i = 0; i < len; ++i)
    3302              :           {
    3303            6 :             if (i > 0)
    3304            0 :               pp_separate_with_comma (pp);
    3305            6 :             dump_expr (pp, TREE_VEC_ELT (args, i), flags);
    3306              :           }
    3307            6 :         pp_cxx_right_brace (pp);
    3308            6 :         break;
    3309              :       }
    3310              : 
    3311            3 :     case CO_AWAIT_EXPR:
    3312            3 :       pp_cxx_ws_string (pp, "co_await");
    3313            3 :       pp_cxx_whitespace (pp);
    3314            3 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3315            3 :       break;
    3316              : 
    3317            0 :     case CO_YIELD_EXPR:
    3318            0 :       pp_cxx_ws_string (pp, "co_yield");
    3319            0 :       pp_cxx_whitespace (pp);
    3320            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3321            0 :       break;
    3322              : 
    3323            0 :     case CO_RETURN_EXPR:
    3324            0 :       pp_cxx_ws_string (pp, "co_return");
    3325            0 :       if (TREE_OPERAND (t, 0))
    3326              :         {
    3327            0 :           pp_cxx_whitespace (pp);
    3328            0 :           dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3329              :         }
    3330              :       break;
    3331              : 
    3332          121 :     case REFLECT_EXPR:
    3333          121 :       {
    3334          121 :         tree h = REFLECT_EXPR_HANDLE (t);
    3335          121 :         bool any;
    3336          121 :         switch (REFLECT_EXPR_KIND (t))
    3337              :           {
    3338            2 :           case REFLECT_ANNOTATION:
    3339            2 :             pp_string (pp, "^^[[=");
    3340            2 :             pp->set_padding (pp_none);
    3341            2 :             dump_expr (pp, TREE_VALUE (TREE_VALUE (h)), flags);
    3342            2 :             pp_string (pp, "]]");
    3343            2 :             break;
    3344            3 :           case REFLECT_DATA_MEMBER_SPEC:
    3345            3 :             pp_cxx_ws_string (pp, "data_member_spec");
    3346            3 :             pp_string (pp, "(^^");
    3347            3 :             pp->set_padding (pp_none);
    3348            3 :             dump_type (pp, TREE_VEC_ELT (h, 0), flags);
    3349            3 :             pp_string (pp, ",{");
    3350            3 :             any = false;
    3351            3 :             if (TREE_VEC_ELT (h, 1))
    3352              :               {
    3353            2 :                 pp_string (pp, ".name=");
    3354            2 :                 pp_doublequote (pp);
    3355            2 :                 pp->set_padding (pp_none);
    3356            2 :                 dump_decl (pp, TREE_VEC_ELT (h, 1), flags);
    3357            2 :                 pp_doublequote (pp);
    3358            2 :                 any = true;
    3359              :               }
    3360            3 :             if (TREE_VEC_ELT (h, 2))
    3361              :               {
    3362            1 :                 if (any)
    3363            1 :                   pp_comma (pp);
    3364            1 :                 pp_string (pp, ".alignment=");
    3365            1 :                 pp->set_padding (pp_none);
    3366            1 :                 dump_expr (pp, TREE_VEC_ELT (h, 2), flags);
    3367            1 :                 any = true;
    3368              :               }
    3369            3 :             if (TREE_VEC_ELT (h, 3))
    3370              :               {
    3371            1 :                 if (any)
    3372            0 :                   pp_comma (pp);
    3373            1 :                 pp_string (pp, ".bit_width=");
    3374            1 :                 pp->set_padding (pp_none);
    3375            1 :                 dump_expr (pp, TREE_VEC_ELT (h, 3), flags);
    3376            1 :                 any = true;
    3377              :               }
    3378            3 :             if (TREE_VEC_ELT (h, 4) && !integer_zerop (TREE_VEC_ELT (h, 4)))
    3379              :               {
    3380            1 :                 if (any)
    3381            1 :                   pp_comma (pp);
    3382            1 :                 pp_string (pp, ".no_unique_address=");
    3383            1 :                 pp->set_padding (pp_none);
    3384            1 :                 dump_expr (pp, TREE_VEC_ELT (h, 4), flags);
    3385            1 :                 any = true;
    3386              :               }
    3387            3 :             if (TREE_VEC_LENGTH (h) > 5)
    3388              :               {
    3389            1 :                 if (any)
    3390            1 :                   pp_comma (pp);
    3391            1 :                 pp_string (pp, ".annotations={");
    3392            1 :                 pp->set_padding (pp_none);
    3393            4 :                 for (int i = 5; i < TREE_VEC_LENGTH (h); ++i)
    3394              :                   {
    3395            3 :                     dump_expr (pp, TREE_VEC_ELT (h, i), flags);
    3396            3 :                     if (i != TREE_VEC_LENGTH (h) - 1)
    3397            2 :                       pp_comma (pp);
    3398            3 :                     pp->set_padding (pp_none);
    3399              :                   }
    3400            1 :                 pp_right_brace (pp);
    3401              :               }
    3402            3 :             pp_string (pp, "})");
    3403            3 :             break;
    3404            4 :           case REFLECT_BASE:
    3405            4 :             {
    3406            4 :               pp_cxx_ws_string (pp, "bases_of");
    3407            4 :               pp_string (pp, "(^^");
    3408            4 :               pp->set_padding (pp_none);
    3409            4 :               tree d = direct_base_derived (h);
    3410            4 :               dump_type (pp, d, flags);
    3411            4 :               pp_string (pp, ",std::meta::access_context::unchecked())[");
    3412            4 :               pp->set_padding (pp_none);
    3413            4 :               tree binfo = TYPE_BINFO (d), base_binfo;
    3414            7 :               for (unsigned i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo);
    3415              :                    i++)
    3416            7 :                 if (base_binfo == h)
    3417              :                   {
    3418            4 :                     pp_wide_integer (pp, i);
    3419            4 :                     break;
    3420              :                   }
    3421            4 :               pp_string (pp, "] {aka ");
    3422            4 :               pp->set_padding (pp_none);
    3423            4 :               dump_type (pp, BINFO_TYPE (h), flags);
    3424            4 :               pp_right_brace (pp);
    3425            4 :               break;
    3426              :             }
    3427            4 :           case REFLECT_PARM:
    3428            4 :             {
    3429            4 :               pp_cxx_ws_string (pp, "parameters_of");
    3430            4 :               pp_string (pp, "(^^");
    3431            4 :               pp->set_padding (pp_none);
    3432            4 :               h = maybe_update_function_parm (h);
    3433            4 :               dump_decl (pp, DECL_CONTEXT (h), flags);
    3434            4 :               pp_string (pp, ")[");
    3435            4 :               pp->set_padding (pp_none);
    3436            4 :               unsigned int i = 0;
    3437            4 :               for (tree arg = FUNCTION_FIRST_USER_PARM (DECL_CONTEXT (h));
    3438            6 :                    arg; arg = DECL_CHAIN (arg), ++i)
    3439            6 :                 if (arg == h)
    3440              :                   {
    3441            4 :                     pp_wide_integer (pp, i);
    3442            4 :                     break;
    3443              :                   }
    3444            4 :               pp_right_bracket (pp);
    3445            4 :               if (MULTIPLE_NAMES_PARM_P (h))
    3446              :                 break;
    3447            3 :               if (DECL_NAME (h))
    3448            1 :                 h = DECL_NAME (h);
    3449            2 :               else if (tree opn = lookup_attribute ("old parm name",
    3450            2 :                                                     DECL_ATTRIBUTES (h)))
    3451            2 :                 h = TREE_VALUE (TREE_VALUE (opn));
    3452              :               else
    3453              :                 break;
    3454            3 :               pp_string (pp, " {aka ");
    3455            3 :               dump_decl (pp, h, flags);
    3456            3 :               pp_right_brace (pp);
    3457            3 :               break;
    3458              :             }
    3459            3 :           case REFLECT_OBJECT:
    3460            3 :             pp_cxx_ws_string (pp, "std::meta::reflect_object");
    3461            3 :             pp_left_paren (pp);
    3462            3 :             pp->set_padding (pp_none);
    3463            3 :             dump_expr (pp, h, flags);
    3464            3 :             pp_right_paren (pp);
    3465            3 :             break;
    3466            4 :           case REFLECT_VALUE:
    3467            4 :             pp_cxx_ws_string (pp, "std::meta::reflect_constant");
    3468            4 :             pp_left_paren (pp);
    3469            4 :             pp->set_padding (pp_none);
    3470            4 :             dump_expr (pp, h, flags);
    3471            4 :             pp_right_paren (pp);
    3472            4 :             break;
    3473          101 :           default:
    3474          101 :             pp_string (pp, "^^");
    3475          101 :             pp->set_padding (pp_none);
    3476          101 :             if (DECL_P (h))
    3477           76 :               dump_decl (pp, h, flags);
    3478           25 :             else if (TYPE_P (h))
    3479           21 :               dump_type (pp, h, flags);
    3480              :             else
    3481              :               dump_expr (pp, h, flags);
    3482              :             break;
    3483              :           }
    3484              :         break;
    3485              :       }
    3486              : 
    3487           12 :     case SPLICE_EXPR:
    3488           12 :       pp_cxx_ws_string (pp, "[:");
    3489           12 :       pp_cxx_whitespace (pp);
    3490           12 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3491           12 :       pp_cxx_whitespace (pp);
    3492           12 :       pp_cxx_ws_string (pp, ":]");
    3493           12 :       break;
    3494              : 
    3495              :       /*  This list is incomplete, but should suffice for now.
    3496              :           It is very important that `sorry' does not call
    3497              :           `report_error_function'.  That could cause an infinite loop.  */
    3498           12 :     default:
    3499           12 :       pp_unsupported_tree (pp, t);
    3500              :       /* Fall through.  */
    3501           48 :     case ERROR_MARK:
    3502           48 :       pp_string (pp, M_("<expression error>"));
    3503           48 :       break;
    3504              :     }
    3505              : }
    3506              : 
    3507              : static void
    3508         1961 : dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t,
    3509              :                 int flags)
    3510              : {
    3511         1961 :   pp_cxx_left_paren (pp);
    3512         1961 :   dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    3513         1961 :   pp_cxx_whitespace (pp);
    3514         1961 :   if (opstring)
    3515         1961 :     pp_cxx_ws_string (pp, opstring);
    3516              :   else
    3517            0 :     pp_string (pp, M_("<unknown operator>"));
    3518         1961 :   pp_cxx_whitespace (pp);
    3519         1961 :   tree op1 = TREE_OPERAND (t, 1);
    3520         1961 :   if (TREE_CODE (t) == POINTER_PLUS_EXPR
    3521          302 :       && TREE_CODE (op1) == INTEGER_CST
    3522         2137 :       && tree_int_cst_sign_bit (op1))
    3523              :     /* A pointer minus an integer is represented internally as plus a very
    3524              :        large number, don't expose that to users.  */
    3525           25 :     op1 = convert (ssizetype, op1);
    3526         1961 :   dump_expr (pp, op1, flags | TFF_EXPR_IN_PARENS);
    3527         1961 :   pp_cxx_right_paren (pp);
    3528         1961 : }
    3529              : 
    3530              : static void
    3531         3646 : dump_unary_op (cxx_pretty_printer *pp, const char *opstring, tree t, int flags)
    3532              : {
    3533         3646 :   if (flags & TFF_EXPR_IN_PARENS)
    3534         2231 :     pp_cxx_left_paren (pp);
    3535         3646 :   pp_cxx_ws_string (pp, opstring);
    3536         3646 :   dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    3537         3646 :   if (flags & TFF_EXPR_IN_PARENS)
    3538         2231 :     pp_cxx_right_paren (pp);
    3539         3646 : }
    3540              : 
    3541              : static void
    3542    233661671 : reinit_cxx_pp (void)
    3543              : {
    3544    233661671 :   pp_clear_output_area (cxx_pp);
    3545    233661671 :   cxx_pp->set_padding (pp_none);
    3546    233661671 :   pp_indentation (cxx_pp) = 0;
    3547    233661671 :   pp_needs_newline (cxx_pp) = false;
    3548    233661671 :   pp_show_color (cxx_pp) = false;
    3549    233661671 :   cxx_pp->enclosing_scope = current_function_decl;
    3550    233661671 : }
    3551              : 
    3552              : /* Same as pp_formatted_text, except the return string is a separate
    3553              :    copy and has a GGC storage duration, e.g. an indefinite lifetime.  */
    3554              : 
    3555              : inline const char *
    3556    233662081 : pp_ggc_formatted_text (pretty_printer *pp)
    3557              : {
    3558    233662081 :   return ggc_strdup (pp_formatted_text (pp));
    3559              : }
    3560              : 
    3561              : /* Exported interface to stringifying types, exprs and decls under TFF_*
    3562              :    control.  */
    3563              : 
    3564              : const char *
    3565          213 : type_as_string (tree typ, int flags)
    3566              : {
    3567          213 :   reinit_cxx_pp ();
    3568          213 :   pp_translate_identifiers (cxx_pp) = false;
    3569          213 :   dump_type (cxx_pp, typ, flags);
    3570          213 :   return pp_ggc_formatted_text (cxx_pp);
    3571              : }
    3572              : 
    3573              : const char *
    3574            0 : type_as_string_translate (tree typ, int flags)
    3575              : {
    3576            0 :   reinit_cxx_pp ();
    3577            0 :   dump_type (cxx_pp, typ, flags);
    3578            0 :   return pp_ggc_formatted_text (cxx_pp);
    3579              : }
    3580              : 
    3581              : const char *
    3582         3972 : expr_as_string (tree decl, int flags)
    3583              : {
    3584         3972 :   reinit_cxx_pp ();
    3585         3972 :   pp_translate_identifiers (cxx_pp) = false;
    3586         3972 :   dump_expr (cxx_pp, decl, flags);
    3587         3972 :   return pp_ggc_formatted_text (cxx_pp);
    3588              : }
    3589              : 
    3590              : /* Wrap decl_as_string with options appropriate for dwarf.  */
    3591              : 
    3592              : const char *
    3593     47941481 : decl_as_dwarf_string (tree decl, int flags)
    3594              : {
    3595     47941481 :   const char *name;
    3596              :   /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
    3597              :      here will be adequate to get the desired behavior.  */
    3598     47941481 :   cxx_pp->flags |= pp_c_flag_gnu_v3;
    3599     47941481 :   name = decl_as_string (decl, flags);
    3600              :   /* Subsequent calls to the pretty printer shouldn't use this style.  */
    3601     47941481 :   cxx_pp->flags &= ~pp_c_flag_gnu_v3;
    3602     47941481 :   return name;
    3603              : }
    3604              : 
    3605              : const char *
    3606     48008163 : decl_as_string (tree decl, int flags)
    3607              : {
    3608     48008163 :   reinit_cxx_pp ();
    3609     48008163 :   pp_translate_identifiers (cxx_pp) = false;
    3610     48008163 :   dump_decl (cxx_pp, decl, flags);
    3611     48008163 :   return pp_ggc_formatted_text (cxx_pp);
    3612              : }
    3613              : 
    3614              : const char *
    3615            0 : decl_as_string_translate (tree decl, int flags)
    3616              : {
    3617            0 :   reinit_cxx_pp ();
    3618            0 :   dump_decl (cxx_pp, decl, flags);
    3619            0 :   return pp_ggc_formatted_text (cxx_pp);
    3620              : }
    3621              : 
    3622              : /* Wrap lang_decl_name with options appropriate for dwarf.  */
    3623              : 
    3624              : const char *
    3625    185348174 : lang_decl_dwarf_name (tree decl, int v, bool translate)
    3626              : {
    3627    185348174 :   const char *name;
    3628              :   /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
    3629              :      here will be adequate to get the desired behavior.  */
    3630    185348174 :   cxx_pp->flags |= pp_c_flag_gnu_v3;
    3631    185348174 :   name = lang_decl_name (decl, v, translate);
    3632              :   /* Subsequent calls to the pretty printer shouldn't use this style.  */
    3633    185348174 :   cxx_pp->flags &= ~pp_c_flag_gnu_v3;
    3634    185348174 :   return name;
    3635              : }
    3636              : 
    3637              : /* Generate the three forms of printable names for cxx_printable_name.  */
    3638              : 
    3639              : const char *
    3640    185495337 : lang_decl_name (tree decl, int v, bool translate)
    3641              : {
    3642    185495337 :   if (v >= 2)
    3643        66425 :     return (translate
    3644        66425 :             ? decl_as_string_translate (decl, TFF_DECL_SPECIFIERS)
    3645        66425 :             : decl_as_string (decl, TFF_DECL_SPECIFIERS));
    3646              : 
    3647    185428912 :   reinit_cxx_pp ();
    3648    185428912 :   pp_translate_identifiers (cxx_pp) = translate;
    3649    185428912 :   if (v == 1
    3650    185428912 :       && (DECL_CLASS_SCOPE_P (decl)
    3651        84986 :           || (DECL_NAMESPACE_SCOPE_P (decl)
    3652        83707 :               && CP_DECL_CONTEXT (decl) != global_namespace)))
    3653              :     {
    3654       151796 :       dump_type (cxx_pp, CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
    3655       151796 :       pp_cxx_colon_colon (cxx_pp);
    3656              :     }
    3657              : 
    3658    185428912 :   if (TREE_CODE (decl) == FUNCTION_DECL)
    3659     90986207 :     dump_function_name (cxx_pp, decl, TFF_PLAIN_IDENTIFIER);
    3660     94442705 :   else if ((DECL_NAME (decl) == NULL_TREE)
    3661     94442705 :            && TREE_CODE (decl) == NAMESPACE_DECL)
    3662           21 :     dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME);
    3663              :   else
    3664     94442684 :     dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
    3665              : 
    3666    185428912 :   return pp_ggc_formatted_text (cxx_pp);
    3667              : }
    3668              : 
    3669              : /* Return the location of a tree passed to %+ formats.  */
    3670              : 
    3671              : location_t
    3672      1990097 : location_of (tree t)
    3673              : {
    3674      1990097 :   if (TYPE_P (t))
    3675              :     {
    3676         3889 :       t = TYPE_MAIN_DECL (t);
    3677         3889 :       if (t == NULL_TREE)
    3678          696 :         return input_location;
    3679              :     }
    3680      1986208 :   else if (TREE_CODE (t) == OVERLOAD)
    3681           39 :     t = (OVL_FIRST (t) != conv_op_marker ? OVL_FIRST (t)
    3682            0 :          : OVL_FIRST (OVL_CHAIN (t)));
    3683              : 
    3684      1989401 :   if (DECL_P (t))
    3685      1495765 :     return DECL_SOURCE_LOCATION (t);
    3686       493636 :   if (TREE_CODE (t) == DEFERRED_PARSE)
    3687           22 :     return defparse_location (t);
    3688       493614 :   return cp_expr_loc_or_input_loc (t);
    3689              : }
    3690              : 
    3691              : /* Now the interfaces from error et al to dump_type et al. Each takes an
    3692              :    on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_
    3693              :    function.  */
    3694              : 
    3695              : static const char *
    3696        99524 : decl_to_string (tree decl, int verbose, bool show_color)
    3697              : {
    3698        99524 :   int flags = 0;
    3699              : 
    3700        99524 :   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
    3701              :       || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
    3702         3768 :     flags = TFF_CLASS_KEY_OR_ENUM;
    3703        99524 :   if (verbose)
    3704        30397 :     flags |= TFF_DECL_SPECIFIERS;
    3705        69127 :   else if (TREE_CODE (decl) == FUNCTION_DECL)
    3706        44243 :     flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
    3707        99524 :   flags |= TFF_TEMPLATE_HEADER;
    3708              : 
    3709        99524 :   reinit_cxx_pp ();
    3710        99524 :   pp_show_color (cxx_pp) = show_color;
    3711        99524 :   dump_decl (cxx_pp, decl, flags);
    3712        99524 :   return pp_ggc_formatted_text (cxx_pp);
    3713              : }
    3714              : 
    3715              : const char *
    3716        50418 : expr_to_string (tree decl)
    3717              : {
    3718        50418 :   reinit_cxx_pp ();
    3719        50418 :   dump_expr (cxx_pp, decl, 0);
    3720        50418 :   return pp_ggc_formatted_text (cxx_pp);
    3721              : }
    3722              : 
    3723              : static const char *
    3724          350 : fndecl_to_string (tree fndecl, int verbose)
    3725              : {
    3726          350 :   int flags;
    3727              : 
    3728          350 :   flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS
    3729              :     | TFF_TEMPLATE_HEADER;
    3730          350 :   if (verbose)
    3731           91 :     flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
    3732          350 :   reinit_cxx_pp ();
    3733          350 :   dump_decl (cxx_pp, fndecl, flags);
    3734          350 :   return pp_ggc_formatted_text (cxx_pp);
    3735              : }
    3736              : 
    3737              : 
    3738              : static const char *
    3739            0 : code_to_string (enum tree_code c)
    3740              : {
    3741            0 :   return get_tree_code_name (c);
    3742              : }
    3743              : 
    3744              : const char *
    3745        14402 : language_to_string (enum languages c)
    3746              : {
    3747        14402 :   switch (c)
    3748              :     {
    3749              :     case lang_c:
    3750              :       return "C";
    3751              : 
    3752           12 :     case lang_cplusplus:
    3753           12 :       return "C++";
    3754              : 
    3755            0 :     default:
    3756            0 :       gcc_unreachable ();
    3757              :     }
    3758              :   return NULL;
    3759              : }
    3760              : 
    3761              : /* Return the proper printed version of a parameter to a C++ function.  */
    3762              : 
    3763              : static const char *
    3764         1538 : parm_to_string (int p)
    3765              : {
    3766         1538 :   reinit_cxx_pp ();
    3767         1538 :   if (p < 0)
    3768           28 :     pp_string (cxx_pp, "'this'");
    3769              :   else
    3770         1510 :     pp_decimal_int (cxx_pp, p + 1);
    3771         1538 :   return pp_ggc_formatted_text (cxx_pp);
    3772              : }
    3773              : 
    3774              : static const char *
    3775          321 : op_to_string (bool assop, enum tree_code p)
    3776              : {
    3777          321 :   tree id = ovl_op_identifier (assop, p);
    3778          639 :   return id ? IDENTIFIER_POINTER (id) : M_("<unknown>");
    3779              : }
    3780              : 
    3781              : /* Return a GC-allocated representation of type TYP, with verbosity VERBOSE.
    3782              : 
    3783              :    If QUOTE is non-NULL and if *QUOTE is true, then quotes are added to the
    3784              :    string in appropriate places, and *QUOTE is written to with false
    3785              :    to suppress pp_format's trailing close quote so that e.g.
    3786              :      foo_typedef {aka underlying_foo} {enum}
    3787              :    can be printed by "%qT" as:
    3788              :      `foo_typedef' {aka `underlying_foo'} {enum}
    3789              :    rather than:
    3790              :      `foo_typedef {aka underlying_foo} {enum}'
    3791              :    When adding such quotes, if POSTPROCESSED is true (for handling %H and %I)
    3792              :    then a leading open quote will be added, whereas if POSTPROCESSED is false
    3793              :    (for handling %T) then any leading quote has already been added by
    3794              :    pp_format, or is not needed due to QUOTE being NULL (for template arguments
    3795              :    within %H and %I).
    3796              : 
    3797              :    SHOW_COLOR and HIGHLIGHT_COLOR are used to determine the colorization of
    3798              :    any quotes that are added.  */
    3799              : 
    3800              : static const char *
    3801        63326 : type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
    3802              :                 bool show_color, const char *highlight_color)
    3803              : {
    3804        63326 :   int flags = 0;
    3805        63326 :   if (verbose)
    3806         9515 :     flags |= TFF_CLASS_KEY_OR_ENUM;
    3807        63326 :   flags |= TFF_TEMPLATE_HEADER;
    3808              : 
    3809        63326 :   reinit_cxx_pp ();
    3810        63326 :   pp_show_color (cxx_pp) = show_color;
    3811              : 
    3812        63326 :   if (postprocessed && quote && *quote)
    3813              :     {
    3814        20656 :       pp_begin_quote (cxx_pp, show_color);
    3815        20656 :       if (show_color && highlight_color)
    3816            0 :         pp_string (cxx_pp, colorize_start (show_color, highlight_color));
    3817              :     }
    3818              : 
    3819        63326 :   struct obstack *ob = pp_buffer (cxx_pp)->m_obstack;
    3820        63326 :   int type_start, type_len;
    3821        63326 :   type_start = obstack_object_size (ob);
    3822              : 
    3823        63326 :   dump_type (cxx_pp, typ, flags);
    3824              : 
    3825              :   /* Remember the end of the initial dump.  */
    3826        63326 :   type_len = obstack_object_size (ob) - type_start;
    3827              : 
    3828              :   /* If we're printing a type that involves typedefs, also print the
    3829              :      stripped version.  But sometimes the stripped version looks
    3830              :      exactly the same, so we don't want it after all.  To avoid printing
    3831              :      it in that case, we play ugly obstack games.  */
    3832        63312 :   if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ)
    3833        69415 :       && !uses_template_parms (typ))
    3834              :     {
    3835         4359 :       int aka_start, aka_len; char *p;
    3836         4359 :       tree aka = strip_typedefs (typ, NULL, STF_USER_VISIBLE);
    3837         4359 :       if (quote && *quote)
    3838         3906 :         pp_end_quote (cxx_pp, show_color);
    3839         4359 :       pp_string (cxx_pp, " {aka");
    3840         4359 :       pp_cxx_whitespace (cxx_pp);
    3841         4359 :       if (quote && *quote)
    3842         3906 :         pp_begin_quote (cxx_pp, show_color);
    3843         4359 :       if (highlight_color)
    3844         1197 :         pp_string (cxx_pp, colorize_start (show_color, highlight_color));
    3845              :       /* And remember the start of the aka dump.  */
    3846         4359 :       aka_start = obstack_object_size (ob);
    3847         4359 :       dump_type (cxx_pp, aka, flags);
    3848         4359 :       aka_len = obstack_object_size (ob) - aka_start;
    3849         4359 :       if (quote && *quote)
    3850         3906 :         pp_end_quote (cxx_pp, show_color);
    3851         4359 :       pp_right_brace (cxx_pp);
    3852         4359 :       p = (char*)obstack_base (ob);
    3853              :       /* If they are identical, cut off the aka by unwinding the obstack.  */
    3854         4359 :       if (type_len == aka_len
    3855          939 :           && memcmp (p + type_start, p+aka_start, type_len) == 0)
    3856              :         {
    3857              :           /* We can't add a '\0' here, since we may be adding a closing quote
    3858              :              below, and it would be hidden by the '\0'.
    3859              :              Instead, manually unwind the current object within the obstack
    3860              :              so that the insertion point is at the end of the type, before
    3861              :              the "' {aka".  */
    3862          761 :           int delta = type_start + type_len - obstack_object_size (ob);
    3863          761 :           gcc_assert (delta <= 0);
    3864          761 :           obstack_blank_fast (ob, delta);
    3865          761 :         }
    3866              :       else
    3867         3598 :         if (quote)
    3868              :           /* No further closing quotes are needed.  */
    3869         3571 :           *quote = false;
    3870              :     }
    3871              : 
    3872        63299 :   if (quote && *quote)
    3873              :     {
    3874        56092 :       if (show_color && highlight_color)
    3875            0 :         pp_string (cxx_pp, colorize_stop (show_color));
    3876        56092 :       pp_end_quote (cxx_pp, show_color);
    3877        56092 :       *quote = false;
    3878              :     }
    3879        63326 :   return pp_ggc_formatted_text (cxx_pp);
    3880              : }
    3881              : 
    3882              : static const char *
    3883         3913 : args_to_string (tree p, int verbose)
    3884              : {
    3885         3913 :   int flags = 0;
    3886         3913 :   if (verbose)
    3887            0 :     flags |= TFF_CLASS_KEY_OR_ENUM;
    3888              : 
    3889         3913 :   if (p == NULL_TREE)
    3890              :     return "";
    3891              : 
    3892         3052 :   if (TYPE_P (TREE_VALUE (p)))
    3893            0 :     return type_as_string_translate (p, flags);
    3894              : 
    3895         3052 :   reinit_cxx_pp ();
    3896         9828 :   for (; p; p = TREE_CHAIN (p))
    3897              :     {
    3898         3724 :       if (null_node_p (TREE_VALUE (p)))
    3899            3 :         pp_cxx_ws_string (cxx_pp, "NULL");
    3900              :       else
    3901         3721 :         dump_type (cxx_pp, error_type (TREE_VALUE (p)), flags);
    3902         3724 :       if (TREE_CHAIN (p))
    3903          672 :         pp_separate_with_comma (cxx_pp);
    3904              :     }
    3905         3052 :   return pp_ggc_formatted_text (cxx_pp);
    3906              : }
    3907              : 
    3908              : /* Pretty-print a deduction substitution (from deduction_tsubst_fntype).  P
    3909              :    is a TREE_LIST with purpose the TEMPLATE_DECL, value the template
    3910              :    arguments.  */
    3911              : 
    3912              : static const char *
    3913         1561 : subst_to_string (tree p, bool show_color)
    3914              : {
    3915         1561 :   tree decl = TREE_PURPOSE (p);
    3916         1561 :   tree targs = TREE_VALUE (p);
    3917         1561 :   tree tparms = DECL_TEMPLATE_PARMS (decl);
    3918         1561 :   int flags = (TFF_DECL_SPECIFIERS|TFF_TEMPLATE_HEADER
    3919              :                |TFF_NO_TEMPLATE_BINDINGS);
    3920              : 
    3921         1561 :   if (p == NULL_TREE)
    3922              :     return "";
    3923              : 
    3924         1561 :   reinit_cxx_pp ();
    3925         1561 :   pp_show_color (cxx_pp) = show_color;
    3926         1561 :   dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
    3927         1561 :   dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
    3928         1561 :   return pp_ggc_formatted_text (cxx_pp);
    3929              : }
    3930              : 
    3931              : static const char *
    3932          639 : cv_to_string (tree p, int v)
    3933              : {
    3934          639 :   reinit_cxx_pp ();
    3935          639 :   cxx_pp->set_padding (v ? pp_before : pp_none);
    3936          639 :   pp_cxx_cv_qualifier_seq (cxx_pp, p);
    3937          639 :   return pp_ggc_formatted_text (cxx_pp);
    3938              : }
    3939              : 
    3940              : static const char *
    3941            3 : eh_spec_to_string (tree p, int /*v*/)
    3942              : {
    3943            3 :   int flags = 0;
    3944            3 :   reinit_cxx_pp ();
    3945            3 :   dump_exception_spec (cxx_pp, p, flags);
    3946            3 :   return pp_ggc_formatted_text (cxx_pp);
    3947              : }
    3948              : 
    3949              : /* Langhook for print_error_function.  */
    3950              : void
    3951          119 : cxx_print_error_function (diagnostics::text_sink &text_output,
    3952              :                           const char *file,
    3953              :                           const diagnostics::diagnostic_info *diagnostic)
    3954              : {
    3955          119 :   char *prefix;
    3956          119 :   if (file)
    3957          119 :     prefix = xstrdup (file);
    3958              :   else
    3959              :     prefix = NULL;
    3960          119 :   lhd_print_error_function (text_output, file, diagnostic);
    3961              : 
    3962          119 :   pp_set_prefix (text_output.get_printer (), prefix);
    3963          119 :   maybe_print_instantiation_context (text_output);
    3964          119 : }
    3965              : 
    3966              : static void
    3967       243717 : cp_diagnostic_text_starter (diagnostics::text_sink &text_output,
    3968              :                             const diagnostics::diagnostic_info *diagnostic)
    3969              : {
    3970       243717 :   pp_set_prefix (text_output.get_printer (),
    3971              :                  text_output.build_indent_prefix (true));
    3972       243717 :   text_output.report_current_module (diagnostic_location (diagnostic));
    3973       243717 :   cp_print_error_function (text_output, diagnostic);
    3974       243717 :   maybe_print_instantiation_context (text_output);
    3975       243717 :   maybe_print_constexpr_context (text_output);
    3976       243717 :   maybe_print_constraint_context (text_output);
    3977       243717 :   pp_set_prefix (text_output.get_printer (),
    3978              :                  text_output.build_prefix (*diagnostic));
    3979       243717 : }
    3980              : 
    3981              : /* Print current function onto BUFFER, in the process of reporting
    3982              :    a diagnostic message.  Called from cp_diagnostic_starter.  */
    3983              : static void
    3984       243717 : cp_print_error_function (diagnostics::text_sink &text_output,
    3985              :                          const diagnostics::diagnostic_info *diagnostic)
    3986              : {
    3987              :   /* If we are in an instantiation context, current_function_decl is likely
    3988              :      to be wrong, so just rely on print_instantiation_full_context.  */
    3989       243717 :   if (current_instantiation ())
    3990              :     return;
    3991              :   /* The above is true for constraint satisfaction also.  */
    3992       229151 :   if (current_failed_constraint)
    3993              :     return;
    3994       228883 :   diagnostics::context *const context = &text_output.get_context ();
    3995       228883 :   if (diagnostic_last_function_changed (context, diagnostic))
    3996              :     {
    3997        25500 :       pretty_printer *const pp = text_output.get_printer ();
    3998        25500 :       char *old_prefix = pp_take_prefix (pp);
    3999        25500 :       const char *file = LOCATION_FILE (diagnostic_location (diagnostic));
    4000        25500 :       tree abstract_origin = diagnostic_abstract_origin (diagnostic);
    4001        25500 :       char *new_prefix = (file && abstract_origin == NULL)
    4002        25500 :                          ? text_output.file_name_as_prefix (file) : NULL;
    4003              : 
    4004        25500 :       pp_set_prefix (pp, new_prefix);
    4005              : 
    4006        25500 :       if (current_function_decl == NULL)
    4007          929 :         pp_string (pp, _("At global scope:"));
    4008              :       else
    4009              :         {
    4010        24571 :           tree fndecl, ao;
    4011              : 
    4012        24571 :           if (abstract_origin)
    4013              :             {
    4014          388 :               ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
    4015          388 :               gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
    4016              :               fndecl = ao;
    4017              :             }
    4018              :           else
    4019              :             fndecl = current_function_decl;
    4020              : 
    4021        24571 :           pp_printf (pp, function_category (fndecl),
    4022              :                      fndecl);
    4023              : 
    4024        49737 :           while (abstract_origin)
    4025              :             {
    4026          595 :               location_t *locus;
    4027          595 :               tree block = abstract_origin;
    4028              : 
    4029          595 :               locus = &BLOCK_SOURCE_LOCATION (block);
    4030          595 :               fndecl = NULL;
    4031          595 :               block = BLOCK_SUPERCONTEXT (block);
    4032         1317 :               while (block && TREE_CODE (block) == BLOCK
    4033         1435 :                      && BLOCK_ABSTRACT_ORIGIN (block))
    4034              :                 {
    4035          334 :                   ao = BLOCK_ABSTRACT_ORIGIN (block);
    4036          334 :                   if (TREE_CODE (ao) == FUNCTION_DECL)
    4037              :                     {
    4038              :                       fndecl = ao;
    4039              :                       break;
    4040              :                     }
    4041          127 :                   else if (TREE_CODE (ao) != BLOCK)
    4042              :                     break;
    4043              : 
    4044          127 :                   block = BLOCK_SUPERCONTEXT (block);
    4045              :                 }
    4046          595 :               if (fndecl)
    4047              :                 abstract_origin = block;
    4048              :               else
    4049              :                 {
    4050          834 :                   while (block && TREE_CODE (block) == BLOCK)
    4051          446 :                     block = BLOCK_SUPERCONTEXT (block);
    4052              : 
    4053          388 :                   if (block && TREE_CODE (block) == FUNCTION_DECL)
    4054              :                     fndecl = block;
    4055              :                   abstract_origin = NULL;
    4056              :                 }
    4057              :               if (fndecl)
    4058              :                 {
    4059          595 :                   expanded_location s = expand_location (*locus);
    4060          595 :                   pp_character (pp, ',');
    4061          595 :                   pp_newline (pp);
    4062          595 :                   if (s.file != NULL)
    4063              :                     {
    4064          595 :                       if (text_output.show_column_p () && s.column != 0)
    4065          541 :                         pp_printf (pp,
    4066              :                                    G_("    inlined from %qD at %r%s:%d:%d%R"),
    4067              :                                    fndecl,
    4068              :                                    "locus", s.file, s.line, s.column);
    4069              :                       else
    4070           54 :                         pp_printf (pp,
    4071              :                                    G_("    inlined from %qD at %r%s:%d%R"),
    4072              :                                    fndecl,
    4073              :                                    "locus", s.file, s.line);
    4074              : 
    4075              :                     }
    4076              :                   else
    4077            0 :                     pp_printf (pp, G_("    inlined from %qD"),
    4078              :                                fndecl);
    4079              :                 }
    4080              :             }
    4081        24571 :           pp_character (pp, ':');
    4082              :         }
    4083        25500 :       pp_newline (pp);
    4084              : 
    4085        25500 :       diagnostic_set_last_function (context, diagnostic);
    4086        25500 :       pp->set_prefix (old_prefix);
    4087              :     }
    4088              : }
    4089              : 
    4090              : /* Returns a description of FUNCTION using standard terminology.  The
    4091              :    result is a format string of the form "In CATEGORY %qD".  */
    4092              : 
    4093              : static const char *
    4094        24571 : function_category (tree fn)
    4095              : {
    4096              :   /* We can get called from the middle-end for diagnostics of function
    4097              :      clones.  Make sure we have language specific information before
    4098              :      dereferencing it.  */
    4099        24571 :   if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn))
    4100        24571 :       && DECL_FUNCTION_MEMBER_P (fn))
    4101              :     {
    4102         3146 :       if (DECL_STATIC_FUNCTION_P (fn))
    4103              :         return G_("In static member function %qD");
    4104         3010 :       else if (DECL_COPY_CONSTRUCTOR_P (fn))
    4105              :         return G_("In copy constructor %qD");
    4106         5938 :       else if (DECL_CONSTRUCTOR_P (fn))
    4107              :         return G_("In constructor %qD");
    4108         1989 :       else if (DECL_DESTRUCTOR_P (fn))
    4109              :         return G_("In destructor %qD");
    4110         2428 :       else if (LAMBDA_FUNCTION_P (fn))
    4111              :         return G_("In lambda function");
    4112         1309 :       else if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    4113           14 :         return G_("In explicit object member function %qD");
    4114              :       else
    4115              :         return G_("In member function %qD");
    4116              :     }
    4117              :   else
    4118              :     return G_("In function %qD");
    4119              : }
    4120              : 
    4121              : /* We expected some kind of tree but instead got T and emitted a diagnostic.
    4122              :    Print the category of T (type, expression, ...) if possible.  */
    4123              : 
    4124              : void
    4125          117 : inform_tree_category (tree t)
    4126              : {
    4127          117 :   const location_t loc = location_of (t);
    4128              : 
    4129          117 :   t = maybe_get_first_fn (t);
    4130          117 :   if (TREE_CODE (t) == TYPE_DECL)
    4131            5 :     t = TREE_TYPE (t);
    4132              : 
    4133          117 :   if (TYPE_P (t))
    4134           50 :     inform (loc, "but %qE is a type", t);
    4135           67 :   else if (EXPR_P (t))
    4136            0 :     inform (loc, "but %qE is an expression", t);
    4137           67 :   else if (DECL_DECOMPOSITION_P (t) && !DECL_DECOMP_IS_BASE (t))
    4138            1 :     inform (loc, "but %qE is a structured binding", t);
    4139           66 :   else if (VAR_P (t))
    4140           23 :     inform (loc, "but %qE is a variable", t);
    4141           43 :   else if (TREE_CODE (t) == PARM_DECL)
    4142            2 :     inform (loc, "but %qE is a parameter", t);
    4143           41 :   else if (TREE_CODE (t) == FUNCTION_DECL)
    4144           11 :     inform (loc, "but %qE is a function", t);
    4145           30 :   else if (TREE_CODE (t) == FIELD_DECL)
    4146            1 :     inform (loc, "but %qE is a data member", t);
    4147           29 :   else if (DECL_FUNCTION_TEMPLATE_P (t))
    4148            5 :     inform (loc, "but %qE is a function template", t);
    4149           24 :   else if (DECL_CLASS_TEMPLATE_P (t))
    4150            3 :     inform (loc, "but %qE is a class template", t);
    4151           21 :   else if (DECL_ALIAS_TEMPLATE_P (t))
    4152            1 :     inform (loc, "but %qE is an alias template", t);
    4153           20 :   else if (variable_template_p (t))
    4154            3 :     inform (loc, "but %qE is a variable template", t);
    4155           17 :   else if (TREE_CODE (t) == NAMESPACE_DECL)
    4156           10 :     inform (loc, "but %qE is a namespace", t);
    4157            7 :   else if (TREE_CODE (t) == CONST_DECL && !DECL_TEMPLATE_PARM_P (t))
    4158            4 :     inform (loc, "but %qE is an enumerator", t);
    4159            5 :   else if (concept_definition_p (t))
    4160            2 :     inform (loc, "but %qE is a concept", t);
    4161          117 : }
    4162              : 
    4163              : /* Disable warnings about missing quoting in GCC diagnostics for
    4164              :    the pp_verbatim calls.  Their format strings deliberately don't
    4165              :    follow GCC diagnostic conventions.  */
    4166              : #if __GNUC__ >= 10
    4167              : #pragma GCC diagnostic push
    4168              : #pragma GCC diagnostic ignored "-Wformat-diag"
    4169              : #endif
    4170              : 
    4171              : /* Report the full context of a current template instantiation,
    4172              :    onto BUFFER.  */
    4173              : static void
    4174         5359 : print_instantiation_full_context (diagnostics::text_sink &text_output)
    4175              : {
    4176         5359 :   struct tinst_level *p = current_instantiation ();
    4177         5359 :   location_t location = input_location;
    4178              : 
    4179         5359 :   if (p)
    4180              :     {
    4181         5359 :       bool show_file
    4182         5359 :         = ((!text_output.show_nesting_p ())
    4183         5359 :            || text_output.show_locations_in_nesting_p ());
    4184         5359 :       char *indent = text_output.build_indent_prefix (true);
    4185         5359 :       bool expansion_stmt_p = TREE_CODE (p->tldcl) == TEMPLATE_FOR_STMT;
    4186        10799 :       pp_verbatim (text_output.get_printer (),
    4187              :                    expansion_stmt_p
    4188              :                    ? G_("%s%s%sIn instantiation of %<template for%> "
    4189              :                         "iteration %E:\n")
    4190         5359 :                    : p->list_p ()
    4191              :                    ? G_("%s%s%sIn substitution of %qS:\n")
    4192              :                    : G_("%s%s%sIn instantiation of %q#D:\n"),
    4193              :                    indent,
    4194         5350 :                    show_file ? LOCATION_FILE (location) : "",
    4195              :                    show_file ? ": " : "",
    4196              :                    expansion_stmt_p
    4197           81 :                    ? TREE_VEC_ELT (p->targs, 0)
    4198         5359 :                    : p->get_node ());
    4199         5359 :       free (indent);
    4200         5359 :       location = p->locus;
    4201         5359 :       p = p->next;
    4202              :     }
    4203              : 
    4204         5359 :   print_instantiation_partial_context (text_output, p, location);
    4205         5359 : }
    4206              : 
    4207              : static void
    4208        12211 : print_location (diagnostics::text_sink &text_output,
    4209              :                 location_t loc)
    4210              : {
    4211        12211 :   expanded_location xloc = expand_location (loc);
    4212        12211 :   pretty_printer *const pp = text_output.get_printer ();
    4213        12211 :   if (text_output.show_column_p ())
    4214         7316 :     pp_verbatim (pp, G_("%r%s:%d:%d:%R   "),
    4215              :                  "locus", xloc.file, xloc.line, xloc.column);
    4216              :   else
    4217         4895 :     pp_verbatim (pp, G_("%r%s:%d:%R   "),
    4218              :                  "locus", xloc.file, xloc.line);
    4219        12211 : }
    4220              : 
    4221              : /* A RAII class for use when emitting a line of contextual information
    4222              :    via pp_verbatim to a diagnostics::text_sink to add before/after
    4223              :    behaviors to the pp_verbatim calls.
    4224              : 
    4225              :    If the text output has show_nesting_p (), then the ctor prints
    4226              :    leading indentation and a bullet point, and the dtor prints
    4227              :    the location on a new line, and calls diagnostic_show_locus, both
    4228              :    with indentation (and no bullet point).
    4229              : 
    4230              :    Otherwise (when the text output has !show_nesting_p), the ctor prints
    4231              :    the location as leading information on the same line, and the
    4232              :    dtor optionally calls diagnostic_show_locus.  */
    4233              : 
    4234              : class auto_context_line
    4235              : {
    4236              : public:
    4237        12247 :   auto_context_line (diagnostics::text_sink &text_output,
    4238              :                      location_t loc,
    4239              :                      bool show_locus = false)
    4240        12247 :   : m_text_output (text_output),
    4241        12247 :     m_loc (loc),
    4242        12247 :     m_show_locus (show_locus),
    4243        12247 :     m_nesting_level (text_output.get_context ().get_diagnostic_nesting_level ()),
    4244        12247 :     m_location_printed (false)
    4245              :   {
    4246        12247 :     char *indent = m_text_output.build_indent_prefix (true);
    4247        12247 :     pp_verbatim (m_text_output.get_printer (), indent);
    4248        12247 :     free (indent);
    4249        12247 :     if (m_nesting_level == 0 || !m_text_output.show_nesting_p ())
    4250              :       {
    4251        12211 :         print_location (m_text_output, m_loc);
    4252        12211 :         m_location_printed = true;
    4253              :       }
    4254        12247 :   }
    4255        12247 :   ~auto_context_line ()
    4256              :   {
    4257        12247 :     pretty_printer *const pp = m_text_output.get_printer ();
    4258        12247 :     if (m_text_output.show_nesting_p ())
    4259              :       {
    4260           47 :         if (m_text_output.show_locations_in_nesting_p ())
    4261              :           {
    4262           11 :             char *indent = m_text_output.build_indent_prefix (false);
    4263           11 :             if (!m_location_printed)
    4264              :               {
    4265            0 :                 pp_verbatim (pp, indent);
    4266            0 :                 print_location (m_text_output, m_loc);
    4267            0 :                 pp_newline (pp);
    4268            0 :                 m_location_printed = true;
    4269              :               }
    4270              : 
    4271           11 :             char *saved_prefix = pp_take_prefix (pp);
    4272           11 :             pp_set_prefix (pp, indent);
    4273           11 :             gcc_rich_location rich_loc (m_loc);
    4274           11 :             diagnostic_show_locus (&m_text_output.get_context (),
    4275           11 :                                    m_text_output.get_source_printing_options (),
    4276              :                                    &rich_loc,
    4277              :                                    diagnostics::kind::note, pp);
    4278           11 :             pp_set_prefix (pp, saved_prefix);
    4279           11 :           }
    4280              :       }
    4281        12200 :     else if (m_show_locus)
    4282              :       {
    4283         7118 :         char *saved_prefix = pp_take_prefix (pp);
    4284         7118 :         pp_set_prefix (pp, nullptr);
    4285         7118 :         gcc_rich_location rich_loc (m_loc);
    4286         7118 :         diagnostic_show_locus (&m_text_output.get_context (),
    4287         7118 :                                m_text_output.get_source_printing_options (),
    4288              :                                &rich_loc,
    4289              :                                diagnostics::kind::note, pp);
    4290         7118 :         pp_set_prefix (pp, saved_prefix);
    4291         7118 :       }
    4292        12247 :   }
    4293              : private:
    4294              :   diagnostics::text_sink &m_text_output;
    4295              :   location_t m_loc;
    4296              :   bool m_show_locus;
    4297              :   int m_nesting_level;
    4298              :   bool m_location_printed;
    4299              : };
    4300              : 
    4301              : /* Helper function of print_instantiation_partial_context() that
    4302              :    prints a single line of instantiation context.  */
    4303              : 
    4304              : static void
    4305         7138 : print_instantiation_partial_context_line (diagnostics::text_sink &text_output,
    4306              :                                           struct tinst_level *t,
    4307              :                                           location_t loc, bool recursive_p)
    4308              : {
    4309         7138 :   if (loc == UNKNOWN_LOCATION)
    4310            0 :     return;
    4311              : 
    4312         7138 :   auto_context_line sentinel (text_output, loc, true);
    4313              : 
    4314         7138 :   pretty_printer *const pp = text_output.get_printer ();
    4315              : 
    4316         7138 :   if (t != NULL)
    4317              :     {
    4318         1779 :       if (TREE_CODE (t->tldcl) == TEMPLATE_FOR_STMT)
    4319            0 :         pp_verbatim (pp,
    4320              :                      recursive_p
    4321              :                      ? G_("recursively required from %<template for%> "
    4322              :                           "iteration %E\n")
    4323              :                      : G_("required from %<template for%> iteration %E\n"),
    4324            0 :                      TREE_VEC_ELT (t->targs, 0));
    4325         1779 :       else if (t->list_p ())
    4326          768 :         pp_verbatim (pp,
    4327              :                      recursive_p
    4328              :                      ? G_("recursively required by substitution of %qS\n")
    4329              :                      : G_("required by substitution of %qS\n"),
    4330              :                      t->get_node ());
    4331              :       else
    4332         2886 :         pp_verbatim (pp,
    4333              :                      recursive_p
    4334              :                      ? G_("recursively required from %q#D\n")
    4335              :                      : G_("required from %q#D\n"),
    4336              :                      t->get_node ());
    4337              :     }
    4338              :   else
    4339              :     {
    4340        10718 :       pp_verbatim (pp,
    4341              :                    recursive_p
    4342              :                    ? G_("recursively required from here\n")
    4343              :                    : G_("required from here\n"));
    4344              :     }
    4345         7138 : }
    4346              : 
    4347              : /* Same as print_instantiation_full_context but less verbose.  */
    4348              : 
    4349              : static void
    4350         5359 : print_instantiation_partial_context (diagnostics::text_sink &text_output,
    4351              :                                      struct tinst_level *t0, location_t loc)
    4352              : {
    4353         5359 :   struct tinst_level *t;
    4354         5359 :   int n_total = 0;
    4355         5359 :   int n;
    4356         5359 :   location_t prev_loc = loc;
    4357              : 
    4358        40060 :   for (t = t0; t != NULL; t = t->next)
    4359        34701 :     if (prev_loc != t->locus)
    4360              :       {
    4361         1713 :         prev_loc = t->locus;
    4362         1713 :         n_total++;
    4363              :       }
    4364              : 
    4365         5359 :   t = t0;
    4366              : 
    4367         5359 :   if (template_backtrace_limit
    4368         5359 :       && n_total > template_backtrace_limit)
    4369              :     {
    4370            0 :       int skip = n_total - template_backtrace_limit;
    4371            0 :       int head = template_backtrace_limit / 2;
    4372              : 
    4373              :       /* Avoid skipping just 1.  If so, skip 2.  */
    4374            0 :       if (skip == 1)
    4375              :        {
    4376            0 :          skip = 2;
    4377            0 :          head = (template_backtrace_limit - 1) / 2;
    4378              :        }
    4379              : 
    4380            0 :       for (n = 0; n < head; n++)
    4381              :         {
    4382            0 :           gcc_assert (t != NULL);
    4383            0 :           if (loc != t->locus)
    4384            0 :             print_instantiation_partial_context_line (text_output, t, loc,
    4385              :                                                       /*recursive_p=*/false);
    4386            0 :           loc = t->locus;
    4387            0 :           t = t->next;
    4388              :         }
    4389            0 :       if (t != NULL && skip > 0)
    4390              :         {
    4391            0 :           auto_context_line sentinel (text_output, loc);
    4392            0 :           pp_verbatim (text_output.get_printer (),
    4393              :                        G_("[ skipping %d instantiation contexts,"
    4394              :                           " use -ftemplate-backtrace-limit=0 to disable ]\n"),
    4395              :                        skip);
    4396            0 :           do {
    4397            0 :             loc = t->locus;
    4398            0 :             t = t->next;
    4399            0 :           } while (t != NULL && --skip > 0);
    4400            0 :         }
    4401              :     }
    4402              : 
    4403         7138 :   while (t != NULL)
    4404              :     {
    4405        34701 :       while (t->next != NULL && t->locus == t->next->locus)
    4406              :         {
    4407              :           loc = t->locus;
    4408              :           t = t->next;
    4409              :         }
    4410         1779 :       print_instantiation_partial_context_line (text_output, t, loc,
    4411         1779 :                                                 t->locus == loc);
    4412         1779 :       loc = t->locus;
    4413         1779 :       t = t->next;
    4414              :     }
    4415         5359 :   print_instantiation_partial_context_line (text_output, NULL, loc,
    4416              :                                             /*recursive_p=*/false);
    4417         5359 : }
    4418              : 
    4419              : /* Called from cp_thing to print the template context for an error.  */
    4420              : static void
    4421       243836 : maybe_print_instantiation_context (diagnostics::text_sink &text_output)
    4422              : {
    4423       243836 :   if (!problematic_instantiation_changed () || current_instantiation () == 0)
    4424       238477 :     return;
    4425              : 
    4426         5359 :   record_last_problematic_instantiation ();
    4427         5359 :   print_instantiation_full_context (text_output);
    4428              : }
    4429              : 
    4430              : /* Report what constexpr call(s) we're trying to expand, if any.  */
    4431              : 
    4432              : void
    4433       243717 : maybe_print_constexpr_context (diagnostics::text_sink &text_output)
    4434              : {
    4435       243717 :   vec<tree> call_stack = cx_error_context ();
    4436       243717 :   unsigned ix;
    4437       243717 :   tree t;
    4438              : 
    4439       247116 :   FOR_EACH_VEC_ELT (call_stack, ix, t)
    4440              :     {
    4441         3399 :       const char *s = expr_as_string (t, 0);
    4442         3399 :       pretty_printer *const pp = text_output.get_printer ();
    4443         3399 :       auto_context_line sentinel (text_output, EXPR_LOCATION (t));
    4444         3399 :       pp_verbatim (pp,
    4445              :                    G_("in %<constexpr%> expansion of %qs"),
    4446              :                    s);
    4447         3399 :       pp_newline (pp);
    4448         3399 :     }
    4449       243717 : }
    4450              : 
    4451              : 
    4452              : static void
    4453          603 : print_constrained_decl_info (diagnostics::text_sink &text_output,
    4454              :                              tree decl)
    4455              : {
    4456          603 :   auto_context_line sentinel (text_output, DECL_SOURCE_LOCATION (decl));
    4457          603 :   pretty_printer *const pp = text_output.get_printer ();
    4458          603 :   pp_verbatim (pp, G_("required by the constraints of %q#D\n"), decl);
    4459          603 : }
    4460              : 
    4461              : static void
    4462          789 : print_concept_check_info (diagnostics::text_sink &text_output,
    4463              :                           tree expr, tree map, tree args)
    4464              : {
    4465          789 :   gcc_assert (concept_check_p (expr));
    4466              : 
    4467          789 :   tree tmpl = TREE_OPERAND (expr, 0);
    4468              : 
    4469          789 :   auto_context_line sentinel (text_output, DECL_SOURCE_LOCATION (tmpl));
    4470              : 
    4471          789 :   cxx_pretty_printer *const pp
    4472          789 :     = (cxx_pretty_printer *)text_output.get_printer ();
    4473          789 :   pp_verbatim (pp, G_("required for the satisfaction of %qE"), expr);
    4474          789 :   if (map && map != error_mark_node)
    4475              :     {
    4476          771 :       tree subst_map = tsubst_parameter_mapping (map, args, tf_none, NULL_TREE);
    4477          773 :       pp_cxx_parameter_mapping (pp, (subst_map != error_mark_node
    4478              :                                      ? subst_map : map));
    4479              :     }
    4480          789 :   pp_newline (pp);
    4481          789 : }
    4482              : 
    4483              : /* Diagnose the entry point into the satisfaction error. Returns the next
    4484              :    context, if any.  */
    4485              : 
    4486              : static tree
    4487         1324 : print_constraint_context_head (diagnostics::text_sink &text_output,
    4488              :                                tree cxt, tree args)
    4489              : {
    4490         1324 :   tree src = TREE_VALUE (cxt);
    4491         1324 :   if (!src)
    4492              :     {
    4493            0 :       auto_context_line sentinel (text_output, input_location);
    4494            0 :       pretty_printer *const pp = text_output.get_printer ();
    4495            0 :       pp_verbatim (pp, G_("required for constraint satisfaction\n"));
    4496            0 :       return NULL_TREE;
    4497            0 :     }
    4498         1324 :   if (DECL_P (src))
    4499              :     {
    4500          603 :       print_constrained_decl_info (text_output, src);
    4501          603 :       return NULL_TREE;
    4502              :     }
    4503              :   else
    4504              :     {
    4505          721 :       print_concept_check_info (text_output, src, TREE_PURPOSE (cxt), args);
    4506          721 :       return TREE_CHAIN (cxt);
    4507              :     }
    4508              : }
    4509              : 
    4510              : static void
    4511          320 : print_requires_expression_info (diagnostics::text_sink &text_output,
    4512              :                                 tree constr, tree args)
    4513              : {
    4514              : 
    4515          320 :   tree expr = ATOMIC_CONSTR_EXPR (constr);
    4516          320 :   tree map = ATOMIC_CONSTR_MAP (constr);
    4517          320 :   map = tsubst_parameter_mapping (map, args, tf_none, NULL_TREE);
    4518          320 :   if (map == error_mark_node)
    4519            2 :     return;
    4520              : 
    4521          318 :   auto_context_line sentinel (text_output, cp_expr_loc_or_input_loc (expr));
    4522          318 :   cxx_pretty_printer *const pp
    4523          318 :     = static_cast <cxx_pretty_printer *> (text_output.get_printer ());
    4524              : 
    4525          318 :   tree parms = TREE_OPERAND (expr, 0);
    4526          318 :   pp_verbatim (pp, parms ? G_("in requirements with ")
    4527              :                          : G_("in requirements "));
    4528          923 :   while (parms)
    4529              :     {
    4530          287 :       pp_verbatim (pp, "%q#D", parms);
    4531          287 :       if (TREE_CHAIN (parms))
    4532           97 :         pp_separate_with_comma (pp);
    4533          287 :       parms = TREE_CHAIN (parms);
    4534              :     }
    4535          318 :   pp_cxx_parameter_mapping (pp, map);
    4536              : 
    4537          318 :   pp_verbatim (pp, "\n");
    4538          318 : }
    4539              : 
    4540              : void
    4541         1351 : maybe_print_single_constraint_context (diagnostics::text_sink &text_output,
    4542              :                                        tree failed)
    4543              : {
    4544         1351 :   if (!failed)
    4545              :     return;
    4546              : 
    4547         1351 :   tree constr = TREE_VALUE (failed);
    4548         1351 :   if (!constr || constr == error_mark_node)
    4549              :     return;
    4550         1351 :   tree cxt = CONSTR_CONTEXT (constr);
    4551         1351 :   if (!cxt)
    4552              :     return;
    4553         1324 :   tree args = TREE_PURPOSE (failed);
    4554              : 
    4555              :   /* Print the stack of requirements.  */
    4556         1324 :   cxt = print_constraint_context_head (text_output, cxt, args);
    4557         3374 :   while (cxt && !DECL_P (TREE_VALUE (cxt)))
    4558              :     {
    4559           68 :       tree expr = TREE_VALUE (cxt);
    4560           68 :       tree map = TREE_PURPOSE (cxt);
    4561           68 :       print_concept_check_info (text_output, expr, map, args);
    4562           68 :       cxt = TREE_CHAIN (cxt);
    4563              :     }
    4564              : 
    4565              :   /* For certain constraints, we can provide additional context.  */
    4566         1324 :   if (TREE_CODE (constr) == ATOMIC_CONSTR
    4567         1324 :       && TREE_CODE (ATOMIC_CONSTR_EXPR (constr)) == REQUIRES_EXPR)
    4568          320 :     print_requires_expression_info (text_output, constr, args);
    4569              : }
    4570              : 
    4571              : void
    4572       243720 : maybe_print_constraint_context (diagnostics::text_sink &text_output)
    4573              : {
    4574       243720 :   if (!current_failed_constraint)
    4575              :     return;
    4576              : 
    4577         1351 :   tree cur = current_failed_constraint;
    4578              : 
    4579              :   /* Recursively print nested contexts.  */
    4580         1351 :   current_failed_constraint = TREE_CHAIN (current_failed_constraint);
    4581         1351 :   if (current_failed_constraint)
    4582            3 :     maybe_print_constraint_context (text_output);
    4583              : 
    4584              :   /* Print this context.  */
    4585         1351 :   maybe_print_single_constraint_context (text_output, cur);
    4586              : }
    4587              : 
    4588              : /* Return true iff TYPE_A and TYPE_B are template types that are
    4589              :    meaningful to compare.  */
    4590              : 
    4591              : static bool
    4592        11474 : comparable_template_types_p (tree type_a, tree type_b)
    4593              : {
    4594        11474 :   if (!CLASS_TYPE_P (type_a))
    4595              :     return false;
    4596         1331 :   if (!CLASS_TYPE_P (type_b))
    4597              :     return false;
    4598              : 
    4599          412 :   tree tinfo_a = TYPE_TEMPLATE_INFO (type_a);
    4600          412 :   tree tinfo_b = TYPE_TEMPLATE_INFO (type_b);
    4601          412 :   if (!tinfo_a || !tinfo_b)
    4602              :     return false;
    4603              : 
    4604          251 :   return TI_TEMPLATE (tinfo_a) == TI_TEMPLATE (tinfo_b);
    4605              : }
    4606              : 
    4607              : /* Start a new line indented by SPC spaces on PP.  */
    4608              : 
    4609              : static void
    4610          228 : newline_and_indent (pretty_printer *pp, int spc)
    4611              : {
    4612          228 :   pp_newline (pp);
    4613         1020 :   for (int i = 0; i < spc; i++)
    4614          792 :     pp_space (pp);
    4615          228 : }
    4616              : 
    4617              : /* Generate a GC-allocated string for ARG, an expression or type.  */
    4618              : 
    4619              : static const char *
    4620          628 : arg_to_string (tree arg, bool verbose)
    4621              : {
    4622          628 :   if (TYPE_P (arg))
    4623          366 :     return type_to_string (arg, verbose, true, NULL, false);
    4624              :   else
    4625          262 :     return expr_to_string (arg);
    4626              : }
    4627              : 
    4628              : /* Subroutine to type_to_string_with_compare and
    4629              :    print_template_tree_comparison.
    4630              : 
    4631              :    Print a representation of ARG (an expression or type) to PP,
    4632              :    colorizing it if PP->show_color, using HIGHLIGHT_COLOR,
    4633              :    or "type-diff" if the latter is NULL.  */
    4634              : 
    4635              : static void
    4636          616 : print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose,
    4637              :                     const char *highlight_color)
    4638              : {
    4639          616 :   if (!highlight_color)
    4640           10 :     highlight_color = "type-diff";
    4641         1232 :   pp_printf (pp, "%r%s%R",
    4642              :              highlight_color,
    4643              :              (arg
    4644          616 :               ? arg_to_string (arg, verbose)
    4645              :               : G_("(no argument)")));
    4646          616 : }
    4647              : 
    4648              : /* Recursively print template TYPE_A to PP, as compared to template TYPE_B.
    4649              : 
    4650              :    The types must satisfy comparable_template_types_p.
    4651              : 
    4652              :    If INDENT is 0, then this is equivalent to type_to_string (TYPE_A), but
    4653              :    potentially colorizing/eliding in comparison with TYPE_B.
    4654              : 
    4655              :    For example given types:
    4656              :      vector<map<int,double>>
    4657              :    and
    4658              :      vector<map<int,float>>
    4659              :    then the result on PP would be:
    4660              :      vector<map<[...],double>>
    4661              :    with type elision, and:
    4662              :      vector<map<int,double>>
    4663              :    without type elision.
    4664              : 
    4665              :    In both cases the parts of TYPE that differ from PEER will be colorized
    4666              :    if pp_show_color (pp) is true.  In the above example, this would be
    4667              :    "double".
    4668              : 
    4669              :    If INDENT is non-zero, then the types are printed in a tree-like form
    4670              :    which shows both types.  In the above example, the result on PP would be:
    4671              : 
    4672              :      vector<
    4673              :        map<
    4674              :          [...],
    4675              :          [double != float]>>
    4676              : 
    4677              :    and without type-elision would be:
    4678              : 
    4679              :      vector<
    4680              :        map<
    4681              :          int,
    4682              :          [double != float]>>
    4683              : 
    4684              :    As before, the differing parts of the types are colorized if
    4685              :    pp_show_color (pp) is true ("double" and "float" in this example).
    4686              : 
    4687              :    Template arguments in which both types are using the default arguments
    4688              :    are not printed; if at least one of the two types is using a non-default
    4689              :    argument, then that argument is printed (or both arguments for the
    4690              :    tree-like print format).  */
    4691              : 
    4692              : static void
    4693          443 : print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
    4694              :                             bool verbose, int indent,
    4695              :                             const char *highlight_color_a,
    4696              :                             const char *highlight_color_b)
    4697              : {
    4698          443 :   if (indent)
    4699           85 :     newline_and_indent (pp, indent);
    4700              : 
    4701          443 :   tree tinfo_a = TYPE_TEMPLATE_INFO (type_a);
    4702          443 :   tree tinfo_b = TYPE_TEMPLATE_INFO (type_b);
    4703              : 
    4704          443 :   pp_printf (pp, "%s<",
    4705          443 :              IDENTIFIER_POINTER (DECL_NAME (TI_TEMPLATE (tinfo_a))));
    4706              : 
    4707          443 :   tree args_a = TI_ARGS (tinfo_a);
    4708          443 :   tree args_b = TI_ARGS (tinfo_b);
    4709          443 :   gcc_assert (TREE_CODE (args_a) == TREE_VEC);
    4710          443 :   gcc_assert (TREE_CODE (args_b) == TREE_VEC);
    4711          443 :   int flags = 0;
    4712          443 :   int len_a = get_non_default_template_args_count (args_a, flags);
    4713          443 :   args_a = INNERMOST_TEMPLATE_ARGS (args_a);
    4714          443 :   int len_b = get_non_default_template_args_count (args_b, flags);
    4715          443 :   args_b = INNERMOST_TEMPLATE_ARGS (args_b);
    4716              :   /* Determine the maximum range of args for which non-default template args
    4717              :      were used; beyond this, only default args (if any) were used, and so
    4718              :      they will be equal from this point onwards.
    4719              :      One of the two peers might have used default arguments within this
    4720              :      range, but the other will be using non-default arguments, and so
    4721              :      it's more readable to print both within this range, to highlight
    4722              :      the differences.  */
    4723          443 :   int len_max = MAX (len_a, len_b);
    4724          443 :   gcc_assert (TREE_CODE (args_a) == TREE_VEC);
    4725          443 :   gcc_assert (TREE_CODE (args_b) == TREE_VEC);
    4726         1116 :   for (int idx = 0; idx < len_max; idx++)
    4727              :     {
    4728          673 :       if (idx)
    4729          230 :         pp_character (pp, ',');
    4730              : 
    4731          673 :       tree arg_a = TREE_VEC_ELT (args_a, idx);
    4732          673 :       tree arg_b = TREE_VEC_ELT (args_b, idx);
    4733          673 :       if (arg_a == arg_b)
    4734              :         {
    4735          128 :           if (indent)
    4736           39 :             newline_and_indent (pp, indent + 2);
    4737              :           /* Can do elision here, printing "[...]".  */
    4738          128 :           if (flag_elide_type)
    4739          116 :             pp_string (pp, G_("[...]"));
    4740              :           else
    4741           12 :             pp_string (pp, arg_to_string (arg_a, verbose));
    4742              :         }
    4743              :       else
    4744              :         {
    4745          545 :           int new_indent = indent ? indent + 2 : 0;
    4746          545 :           if (comparable_template_types_p (arg_a, arg_b))
    4747           33 :             print_template_differences (pp, arg_a, arg_b, verbose, new_indent,
    4748              :                                         highlight_color_a, highlight_color_b);
    4749              :           else
    4750          512 :             if (indent)
    4751              :               {
    4752          104 :                 newline_and_indent (pp, indent + 2);
    4753          104 :                 pp_character (pp, '[');
    4754          104 :                 print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
    4755          104 :                 pp_string (pp, " != ");
    4756          104 :                 print_nonequal_arg (pp, arg_b, verbose, highlight_color_b);
    4757          104 :                 pp_character (pp, ']');
    4758              :               }
    4759              :             else
    4760          408 :               print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
    4761              :         }
    4762              :     }
    4763          443 :   pp_printf (pp, ">");
    4764          443 : }
    4765              : 
    4766              : /* As type_to_string, but for a template, potentially colorizing/eliding
    4767              :    in comparison with PEER.
    4768              :    For example, if TYPE is map<int,double> and PEER is map<int,int>,
    4769              :    then the resulting string would be:
    4770              :      map<[...],double>
    4771              :    with type elision, and:
    4772              :      map<int,double>
    4773              :    without type elision.
    4774              : 
    4775              :    In both cases the parts of TYPE that differ from PEER will be colorized
    4776              :    if SHOW_COLOR is true.  In the above example, this would be "double".
    4777              : 
    4778              :    Template arguments in which both types are using the default arguments
    4779              :    are not printed; if at least one of the two types is using a non-default
    4780              :    argument, then both arguments are printed.
    4781              : 
    4782              :    The resulting string is in a GC-allocated buffer.  */
    4783              : 
    4784              : static const char *
    4785          336 : type_to_string_with_compare (tree type, tree peer, bool verbose,
    4786              :                              bool show_color,
    4787              :                              const char *this_highlight_color,
    4788              :                              const char *peer_highlight_color)
    4789              : {
    4790          336 :   pretty_printer inner_pp;
    4791          336 :   pretty_printer *pp = &inner_pp;
    4792          336 :   pp_show_color (pp) = show_color;
    4793              : 
    4794          336 :   print_template_differences (pp, type, peer, verbose, 0,
    4795              :                               this_highlight_color, peer_highlight_color);
    4796          336 :   return pp_ggc_formatted_text (pp);
    4797          336 : }
    4798              : 
    4799              : /* Recursively print a tree-like comparison of TYPE_A and TYPE_B to PP,
    4800              :    indented by INDENT spaces.
    4801              : 
    4802              :    For example given types:
    4803              : 
    4804              :      vector<map<int,double>>
    4805              : 
    4806              :    and
    4807              : 
    4808              :      vector<map<double,float>>
    4809              : 
    4810              :    the output with type elision would be:
    4811              : 
    4812              :      vector<
    4813              :        map<
    4814              :          [...],
    4815              :          [double != float]>>
    4816              : 
    4817              :    and without type-elision would be:
    4818              : 
    4819              :      vector<
    4820              :        map<
    4821              :          int,
    4822              :          [double != float]>>
    4823              : 
    4824              :    TYPE_A and TYPE_B must both be comparable template types
    4825              :    (as per comparable_template_types_p).
    4826              : 
    4827              :    Template arguments in which both types are using the default arguments
    4828              :    are not printed; if at least one of the two types is using a non-default
    4829              :    argument, then both arguments are printed.  */
    4830              : 
    4831              : static void
    4832           74 : print_template_tree_comparison (pretty_printer *pp, tree type_a, tree type_b,
    4833              :                                 bool verbose, int indent,
    4834              :                                 const char *highlight_color_a,
    4835              :                                 const char *highlight_color_b)
    4836              : {
    4837            0 :   print_template_differences (pp, type_a, type_b, verbose, indent,
    4838              :                               highlight_color_a,
    4839              :                               highlight_color_b);
    4840            0 : }
    4841              : 
    4842              : /* Subroutine for use in a format_postprocessor::handle
    4843              :    implementation.  Adds a chunk to the end of
    4844              :    formatted output, so that it will be printed
    4845              :    by pp_output_formatted_text.  */
    4846              : 
    4847              : static void
    4848           74 : append_formatted_chunk (pretty_printer *pp, const char *content)
    4849              : {
    4850           74 :   output_buffer *buffer = pp_buffer (pp);
    4851           74 :   pp_formatted_chunks *chunk_array = buffer->m_cur_formatted_chunks;
    4852            0 :   chunk_array->append_formatted_chunk (buffer->m_chunk_obstack, content);
    4853            0 : }
    4854              : 
    4855              : #if __GNUC__ >= 10
    4856              : #pragma GCC diagnostic pop
    4857              : #endif
    4858              : 
    4859              : /* If we had %H and %I, and hence deferred printing them,
    4860              :    print them now, storing the result into custom_token_value
    4861              :    for the custom pp_token.  Quote them if 'q' was provided.
    4862              :    Also print the difference in tree form, adding it as
    4863              :    an additional chunk.  */
    4864              : 
    4865              : void
    4866       366739 : cxx_format_postprocessor::handle (pretty_printer *pp)
    4867              : {
    4868              :   /* If we have one of %H and %I, the other should have
    4869              :      been present.  */
    4870       366739 :   if (m_type_a.m_tree || m_type_b.m_tree)
    4871              :     {
    4872        10495 :       const bool show_highlight_colors = pp_show_highlight_colors (pp);
    4873        10495 :       const char *percent_h
    4874        10495 :         = show_highlight_colors ? highlight_colors::percent_h : nullptr;
    4875            2 :       const char *percent_i
    4876              :         = show_highlight_colors ? highlight_colors::percent_i : nullptr;
    4877              :       /* Avoid reentrancy issues by working with a copy of
    4878              :          m_type_a and m_type_b, resetting them now.  */
    4879        10495 :       deferred_printed_type type_a = std::move (m_type_a);
    4880        10495 :       deferred_printed_type type_b = std::move (m_type_b);
    4881        10495 :       m_type_a = deferred_printed_type ();
    4882        10495 :       m_type_b = deferred_printed_type ();
    4883              : 
    4884        10495 :       gcc_assert (type_a.m_token_list);
    4885        10495 :       gcc_assert (type_b.m_token_list);
    4886              : 
    4887        10495 :       bool show_color = pp_show_color (pp);
    4888              : 
    4889        10495 :       const char *type_a_text;
    4890        10495 :       const char *type_b_text;
    4891              : 
    4892        10495 :       if (comparable_template_types_p (type_a.m_tree, type_b.m_tree))
    4893              :         {
    4894          167 :           type_a_text = type_to_string_with_compare
    4895          167 :             (type_a.m_tree, type_b.m_tree,
    4896              :              type_a.m_verbose, show_color,
    4897              :              percent_h, percent_i);
    4898          167 :           type_b_text = type_to_string_with_compare
    4899          167 :             (type_b.m_tree, type_a.m_tree,
    4900              :              type_b.m_verbose, show_color,
    4901              :              percent_i, percent_h);
    4902              : 
    4903          167 :           if (flag_diagnostics_show_template_tree)
    4904              :             {
    4905           74 :               pretty_printer inner_pp;
    4906           74 :               pp_show_color (&inner_pp) = pp_show_color (pp);
    4907           74 :               print_template_tree_comparison
    4908           74 :                 (&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2,
    4909              :                  percent_h, percent_i);
    4910           74 :               append_formatted_chunk (pp, pp_ggc_formatted_text (&inner_pp));
    4911           74 :             }
    4912              :         }
    4913              :       else
    4914              :         {
    4915              :           /* If the types were not comparable (or if only one of %H/%I was
    4916              :              provided), they are printed normally, and no difference tree
    4917              :              is printed.  */
    4918        10328 :           type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose,
    4919              :                                         true, &type_a.m_quote, show_color,
    4920              :                                         percent_h);
    4921        10328 :           type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose,
    4922              :                                         true, &type_b.m_quote, show_color,
    4923              :                                         percent_i);
    4924              :         }
    4925              : 
    4926        10495 :       type_a.set_text_for_token_list (type_a_text, type_a.m_quote);
    4927        10495 :       type_b.set_text_for_token_list (type_b_text, type_b.m_quote);
    4928        10495 :    }
    4929       366739 : }
    4930              : 
    4931              : /* Subroutine for handling %H and %I, to support i18n of messages like:
    4932              : 
    4933              :     error_at (loc, "could not convert %qE from %qH to %qI",
    4934              :                expr, type_a, type_b);
    4935              : 
    4936              :    so that we can print things like:
    4937              : 
    4938              :      could not convert 'foo' from 'map<int,double>' to 'map<int,int>'
    4939              : 
    4940              :    and, with type-elision:
    4941              : 
    4942              :      could not convert 'foo' from 'map<[...],double>' to 'map<[...],int>'
    4943              : 
    4944              :    (with color-coding of the differences between the types).
    4945              : 
    4946              :    The %H and %I format codes are peers: both must be present,
    4947              :    and they affect each other.  Hence to handle them, we must
    4948              :    delay printing until we have both, deferring the printing to
    4949              :    pretty_printer's m_format_postprocessor hook.
    4950              : 
    4951              :    This is called in phase 2 of pp_format, when it is accumulating
    4952              :    a series of pp_token lists.  Since we have to interact with the
    4953              :    fiddly quoting logic for "aka", we store the pp_token_list *
    4954              :    and in the m_format_postprocessor hook we generate text for the type
    4955              :    (possibly with quotes and colors), then replace all tokens in that token list
    4956              :    (such as [BEGIN_QUOTE, END_QUOTE]) with a text token containing the
    4957              :    freshly generated text.
    4958              : 
    4959              :    We also need to stash whether a 'q' prefix was provided (the QUOTE
    4960              :    param)  so that we can add the quotes when writing out the delayed
    4961              :    chunk.  */
    4962              : 
    4963              : static void
    4964        20990 : defer_phase_2_of_type_diff (deferred_printed_type *deferred,
    4965              :                             tree type,
    4966              :                             pp_token_list &formatted_token_list,
    4967              :                             bool verbose, bool quote)
    4968              : {
    4969        20990 :   gcc_assert (deferred->m_tree == NULL_TREE);
    4970        41980 :   *deferred = deferred_printed_type (type, formatted_token_list,
    4971        20990 :                                      verbose, quote);
    4972        20990 : }
    4973              : 
    4974              : /* Implementation of pp_markup::element_quoted_type::print_type
    4975              :    for C++/ObjC++.  */
    4976              : 
    4977              : void
    4978          752 : pp_markup::element_quoted_type::print_type (pp_markup::context &ctxt)
    4979              : {
    4980          752 :   const char *highlight_color
    4981          752 :     = pp_show_highlight_colors (&ctxt.m_pp) ? m_highlight_color : nullptr;
    4982          752 :   const char *result
    4983         1504 :     = type_to_string (m_type, false, false, &ctxt.m_quoted,
    4984          752 :                       pp_show_color (&ctxt.m_pp), highlight_color);
    4985          752 :   pp_string (&ctxt.m_pp, result);
    4986          752 : }
    4987              : 
    4988              : /* Called from output_format -- during diagnostic message processing --
    4989              :    to handle C++ specific format specifier with the following meanings:
    4990              :    %A   function argument-list.
    4991              :    %C   tree code.
    4992              :    %D   declaration.
    4993              :    %E   expression.
    4994              :    %F   function declaration.
    4995              :    %H   type difference (from).
    4996              :    %I   type difference (to).
    4997              :    %L   language as used in extern "lang".
    4998              :    %O   binary operator.
    4999              :    %P   function parameter whose position is indicated by an integer.
    5000              :    %Q   assignment operator.
    5001              :    %S   substitution (template + args)
    5002              :    %T   type.
    5003              :    %V   cv-qualifier.
    5004              :    %X   exception-specification.  */
    5005              : static bool
    5006       220025 : cp_printer (pretty_printer *pp, text_info *text, const char *spec,
    5007              :             int precision, bool wide, bool set_locus, bool verbose,
    5008              :             bool *quoted, pp_token_list &formatted_token_list)
    5009              : {
    5010       220025 :   gcc_assert (pp_format_postprocessor (pp));
    5011       220025 :   cxx_format_postprocessor *postprocessor
    5012       220025 :     = static_cast <cxx_format_postprocessor *> (pp_format_postprocessor (pp));
    5013              : 
    5014       220025 :   const char *result;
    5015       220025 :   tree t = NULL;
    5016              : #define next_tree    (t = va_arg (*text->m_args_ptr, tree))
    5017              : #define next_tcode   ((enum tree_code) va_arg (*text->m_args_ptr, int))
    5018              : #define next_lang    ((enum languages) va_arg (*text->m_args_ptr, int))
    5019              : #define next_int     va_arg (*text->m_args_ptr, int)
    5020              : 
    5021       220025 :   if (precision != 0 || wide)
    5022              :     return false;
    5023              : 
    5024       220025 :   switch (*spec)
    5025              :     {
    5026         3913 :     case 'A': result = args_to_string (next_tree, verbose);     break;
    5027            0 :     case 'C': result = code_to_string (next_tcode);             break;
    5028        99548 :     case 'D':
    5029        99548 :       {
    5030        99548 :         tree temp = next_tree;
    5031        99548 :         if (VAR_P (temp)
    5032        99548 :             && DECL_HAS_DEBUG_EXPR_P (temp))
    5033              :           {
    5034           24 :             temp = DECL_DEBUG_EXPR (temp);
    5035           24 :             if (!DECL_P (temp))
    5036              :               {
    5037           24 :                 result = expr_to_string (temp);
    5038           24 :                 break;
    5039              :               }
    5040              :           }
    5041        99524 :         result = decl_to_string (temp, verbose, pp_show_color (pp));
    5042              :       }
    5043        99524 :       break;
    5044        50021 :     case 'E': result = expr_to_string (next_tree);              break;
    5045          350 :     case 'F': result = fndecl_to_string (next_tree, verbose);   break;
    5046        10495 :     case 'H':
    5047        20990 :       defer_phase_2_of_type_diff (&postprocessor->m_type_a, next_tree,
    5048        10495 :                                   formatted_token_list, verbose, *quoted);
    5049        10495 :       return true;
    5050        10495 :     case 'I':
    5051        20990 :       defer_phase_2_of_type_diff (&postprocessor->m_type_b, next_tree,
    5052        10495 :                                   formatted_token_list, verbose, *quoted);
    5053        10495 :       return true;
    5054           24 :     case 'L': result = language_to_string (next_lang);          break;
    5055          297 :     case 'O': result = op_to_string (false, next_tcode);        break;
    5056         1538 :     case 'P': result = parm_to_string (next_int);               break;
    5057           24 :     case 'Q': result = op_to_string (true, next_tcode);         break;
    5058         1561 :     case 'S': result = subst_to_string (next_tree, pp_show_color (pp)); break;
    5059        41117 :     case 'T':
    5060        41117 :       {
    5061        82234 :         result = type_to_string (next_tree, verbose, false, quoted,
    5062        41117 :                                  pp_show_color (pp));
    5063              :       }
    5064        41117 :       break;
    5065          639 :     case 'V': result = cv_to_string (next_tree, verbose);       break;
    5066            3 :     case 'X': result = eh_spec_to_string (next_tree, verbose);  break;
    5067              : 
    5068              :     default:
    5069              :       return false;
    5070              :     }
    5071              : 
    5072       199035 :   pp_string (pp, result);
    5073       199035 :   if (set_locus && t != NULL)
    5074         1774 :     text->set_location (0, location_of (t), SHOW_RANGE_WITH_CARET);
    5075              :   return true;
    5076              : #undef next_tree
    5077              : #undef next_tcode
    5078              : #undef next_lang
    5079              : #undef next_int
    5080              : }
    5081              : 
    5082              : /* Warn about the use of C++0x features when appropriate.  */
    5083              : void
    5084     83967659 : maybe_warn_cpp0x (cpp0x_warn_str str, location_t loc/*=input_location*/)
    5085              : {
    5086     83967659 :   if (cxx_dialect == cxx98)
    5087         4273 :     switch (str)
    5088              :       {
    5089          186 :       case CPP0X_INITIALIZER_LISTS:
    5090          186 :         pedwarn (loc, OPT_Wc__11_extensions,
    5091              :                  "extended initializer lists "
    5092              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5093          186 :         break;
    5094            0 :       case CPP0X_EXPLICIT_CONVERSION:
    5095            0 :         pedwarn (loc, OPT_Wc__11_extensions,
    5096              :                  "explicit conversion operators "
    5097              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5098            0 :         break;
    5099         1390 :       case CPP0X_VARIADIC_TEMPLATES:
    5100         1390 :         pedwarn (loc, OPT_Wc__11_extensions,
    5101              :                  "variadic templates "
    5102              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5103         1390 :         break;
    5104            6 :       case CPP0X_LAMBDA_EXPR:
    5105            6 :         pedwarn (loc, OPT_Wc__11_extensions,
    5106              :                  "lambda expressions "
    5107              :                   "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5108            6 :         break;
    5109            0 :       case CPP0X_AUTO:
    5110            0 :         pedwarn (loc, OPT_Wc__11_extensions,
    5111              :                  "C++11 auto only available with %<-std=c++11%> or "
    5112              :                  "%<-std=gnu++11%>");
    5113            0 :         break;
    5114           16 :       case CPP0X_SCOPED_ENUMS:
    5115           16 :         pedwarn (loc, OPT_Wc__11_extensions,
    5116              :                  "scoped enums only available with %<-std=c++11%> or "
    5117              :                  "%<-std=gnu++11%>");
    5118           16 :         break;
    5119          493 :       case CPP0X_DEFAULTED_DELETED:
    5120          493 :         pedwarn (loc, OPT_Wc__11_extensions,
    5121              :                  "defaulted and deleted functions "
    5122              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5123          493 :         break;
    5124         1891 :       case CPP0X_INLINE_NAMESPACES:
    5125         1891 :         if (pedantic)
    5126          581 :           pedwarn (loc, OPT_Wc__11_extensions,
    5127              :                    "inline namespaces "
    5128              :                    "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5129              :         break;
    5130            3 :       case CPP0X_OVERRIDE_CONTROLS:
    5131            3 :         pedwarn (loc, OPT_Wc__11_extensions,
    5132              :                  "override controls (override/final) "
    5133              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5134            3 :         break;
    5135          132 :       case CPP0X_NSDMI:
    5136          132 :         pedwarn (loc, OPT_Wc__11_extensions,
    5137              :                  "non-static data member initializers "
    5138              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5139          132 :         break;
    5140            4 :       case CPP0X_USER_DEFINED_LITERALS:
    5141            4 :         pedwarn (loc, OPT_Wc__11_extensions,
    5142              :                  "user-defined literals "
    5143              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5144            4 :         break;
    5145            3 :       case CPP0X_DELEGATING_CTORS:
    5146            3 :         pedwarn (loc, OPT_Wc__11_extensions,
    5147              :                  "delegating constructors "
    5148              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5149            3 :         break;
    5150            3 :       case CPP0X_INHERITING_CTORS:
    5151            3 :         pedwarn (loc, OPT_Wc__11_extensions,
    5152              :                  "inheriting constructors "
    5153              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5154            3 :         break;
    5155          146 :       case CPP0X_ATTRIBUTES:
    5156          146 :         if (pedantic)
    5157           24 :           pedwarn (loc, OPT_Wc__11_extensions,
    5158              :                    "C++11 attributes "
    5159              :                    "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5160              :         break;
    5161            0 :       case CPP0X_REF_QUALIFIER:
    5162            0 :         pedwarn (loc, OPT_Wc__11_extensions,
    5163              :                  "ref-qualifiers "
    5164              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5165            0 :         break;
    5166            0 :       default:
    5167            0 :         gcc_unreachable ();
    5168              :       }
    5169     83967659 : }
    5170              : 
    5171              : /* Warn about the use of variadic templates when appropriate.  */
    5172              : void
    5173     13896249 : maybe_warn_variadic_templates (void)
    5174              : {
    5175     13896249 :   maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES);
    5176     13896249 : }
    5177              : 
    5178              : 
    5179              : /* Issue an ISO C++98 pedantic warning at LOCATION, conditional on
    5180              :    option OPTION_ID with text GMSGID.  Use this function to report
    5181              :    diagnostics for constructs that are invalid C++98, but valid
    5182              :    C++0x.  */
    5183              : bool
    5184      3647116 : pedwarn_cxx98 (location_t location,
    5185              :                diagnostics::option_id option_id,
    5186              :                const char *gmsgid, ...)
    5187              : {
    5188      3647116 :   diagnostics::diagnostic_info diagnostic;
    5189      3647116 :   va_list ap;
    5190      3647116 :   bool ret;
    5191      3647116 :   rich_location richloc (line_table, location);
    5192              : 
    5193      3647116 :   va_start (ap, gmsgid);
    5194      3647116 :   diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
    5195      3647116 :                        (cxx_dialect == cxx98
    5196              :                         ? diagnostics::kind::pedwarn
    5197              :                         : diagnostics::kind::warning));
    5198      3647116 :   diagnostic.m_option_id = option_id;
    5199      3647116 :   ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
    5200      3647116 :   va_end (ap);
    5201      7294232 :   return ret;
    5202      3647116 : }
    5203              : 
    5204              : /* Issue a diagnostic that NAME cannot be found in SCOPE.  DECL is what
    5205              :    we found when we tried to do the lookup.  LOCATION is the location of
    5206              :    the NAME identifier.  */
    5207              : 
    5208              : void
    5209          557 : qualified_name_lookup_error (tree scope, tree name,
    5210              :                              tree decl, location_t location)
    5211              : {
    5212          557 :   if (scope == error_mark_node)
    5213              :     ; /* We already complained.  */
    5214          442 :   else if (TYPE_P (scope))
    5215              :     {
    5216          249 :       if (!COMPLETE_TYPE_P (scope)
    5217          249 :           && !currently_open_class (scope))
    5218           41 :         error_at (location, "incomplete type %qT used in nested name specifier",
    5219              :                   scope);
    5220          208 :       else if (TREE_CODE (decl) == TREE_LIST)
    5221              :         {
    5222            0 :           auto_diagnostic_group d;
    5223            0 :           error_at (location, "reference to %<%T::%D%> is ambiguous",
    5224              :                     scope, name);
    5225            0 :           print_candidates (location, decl);
    5226            0 :         }
    5227              :       else
    5228              :         {
    5229          208 :           auto_diagnostic_group d;
    5230          208 :           name_hint hint;
    5231          208 :           if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE)
    5232           15 :             hint = suggest_alternative_in_scoped_enum (name, scope);
    5233          208 :           if (const char *suggestion = hint.suggestion ())
    5234              :             {
    5235            9 :               gcc_rich_location richloc (location);
    5236            9 :               richloc.add_fixit_replace (suggestion);
    5237            9 :               error_at (&richloc,
    5238              :                         "%qD is not a member of %qT; did you mean %qs?",
    5239              :                         name, scope, suggestion);
    5240            9 :             }
    5241              :           else
    5242          199 :             error_at (location, "%qD is not a member of %qT", name, scope);
    5243          208 :         }
    5244              :     }
    5245          193 :   else if (scope != global_namespace)
    5246              :     {
    5247          175 :       auto_diagnostic_group d;
    5248          175 :       bool emit_fixit = true;
    5249          175 :       name_hint hint
    5250          175 :         = suggest_alternative_in_explicit_scope (location, name, scope);
    5251          175 :       if (!hint)
    5252              :         {
    5253           59 :           hint = suggest_alternatives_in_other_namespaces (location, name);
    5254              :           /* "location" is just the location of the name, not of the explicit
    5255              :              scope, and it's not easy to get at the latter, so we can't issue
    5256              :              fix-it hints for the suggestion.  */
    5257           59 :           emit_fixit = false;
    5258              :         }
    5259          175 :       if (const char *suggestion = hint.suggestion ())
    5260              :         {
    5261           54 :           gcc_rich_location richloc (location);
    5262           54 :           if (emit_fixit)
    5263           33 :             richloc.add_fixit_replace (suggestion);
    5264           54 :           error_at (&richloc, "%qD is not a member of %qD; did you mean %qs?",
    5265              :                     name, scope, suggestion);
    5266           54 :         }
    5267              :       else
    5268          121 :         error_at (location, "%qD is not a member of %qD", name, scope);
    5269          175 :     }
    5270              :   else
    5271              :     {
    5272           18 :       auto_diagnostic_group d;
    5273           18 :       name_hint hint = suggest_alternatives_for (location, name, true);
    5274           18 :       if (const char *suggestion = hint.suggestion ())
    5275              :         {
    5276            9 :           gcc_rich_location richloc (location);
    5277            9 :           richloc.add_fixit_replace (suggestion);
    5278            9 :           error_at (&richloc,
    5279              :                     "%<::%D%> has not been declared; did you mean %qs?",
    5280              :                     name, suggestion);
    5281            9 :         }
    5282              :       else
    5283            9 :         error_at (location, "%<::%D%> has not been declared", name);
    5284           18 :     }
    5285          557 : }
    5286              : 
    5287              : /* C++-specific implementation of range_label::get_text () vfunc for
    5288              :    range_label_for_type_mismatch.
    5289              : 
    5290              :    Compare with print_template_differences above.  */
    5291              : 
    5292              : label_text
    5293          437 : range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
    5294              : {
    5295          437 :   if (m_labelled_type == NULL_TREE)
    5296            0 :     return label_text::borrow (NULL);
    5297              : 
    5298          437 :   const bool verbose = false;
    5299          437 :   const bool show_color = false;
    5300              : 
    5301          437 :   const char *result;
    5302          437 :   if (m_other_type
    5303          437 :       && comparable_template_types_p (m_labelled_type, m_other_type))
    5304            2 :     result = type_to_string_with_compare (m_labelled_type, m_other_type,
    5305              :                                           verbose, show_color,
    5306              :                                           nullptr, nullptr);
    5307              :   else
    5308          435 :     result = type_to_string (m_labelled_type, verbose, true, NULL, show_color);
    5309              : 
    5310              :   /* Both of the above return GC-allocated buffers, so the caller mustn't
    5311              :      free them.  */
    5312          437 :   return label_text::borrow (result);
    5313              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.