LCOV - code coverage report
Current view: top level - gcc/cp - error.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.0 % 2869 2526
Test Date: 2026-10-03 16:17:38 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       127668 : class deferred_printed_type
     124              : {
     125              : public:
     126       350488 :   deferred_printed_type ()
     127       350488 :   : m_tree (NULL_TREE),
     128       350488 :     m_printed_text (),
     129       350488 :     m_token_list (nullptr),
     130        21278 :     m_verbose (false), m_quote (false)
     131              :   {}
     132              : 
     133        21278 :   deferred_printed_type (tree type,
     134              :                          pp_token_list &token_list,
     135              :                          bool verbose,
     136              :                          bool quote)
     137        21278 :   : m_tree (type),
     138        21278 :     m_printed_text (),
     139        21278 :     m_token_list (&token_list),
     140        21278 :     m_verbose (verbose),
     141        21278 :     m_quote (quote)
     142              :   {
     143        21278 :     gcc_assert (type);
     144              :   }
     145              : 
     146        21278 :   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        63834 :     while (m_token_list->m_first)
     154        42556 :       m_token_list->pop_front ();
     155              : 
     156        21278 :     if (quote)
     157          388 :       m_token_list->push_back<pp_token_begin_quote> ();
     158              : 
     159              :     // TEXT is gc-allocated, so we can borrow it
     160        21278 :     m_token_list->push_back_text (label_text::borrow (text));
     161              : 
     162        21278 :     if (quote)
     163          388 :       m_token_list->push_back<pp_token_end_quote> ();
     164        21278 :   }
     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       329210 :   cxx_format_postprocessor ()
     183       329210 :   : m_type_a (), m_type_b ()
     184              :   {}
     185              : 
     186              :   std::unique_ptr<format_postprocessor>
     187       227618 :   clone() const final override
     188              :   {
     189       227618 :     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    939813853 : cxx_dump_pretty_printer::
     202              : cxx_dump_pretty_printer (int phase)
     203    939813853 :   : phase (phase)
     204              : {
     205    939813853 :   outf = dump_begin (phase, &flags);
     206    939813853 :   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    939813853 : }
     213              : 
     214    939813853 : cxx_dump_pretty_printer::
     215    939813853 : ~cxx_dump_pretty_printer ()
     216              : {
     217    939813853 :   if (outf)
     218              :     {
     219            0 :       pp_flush (this);
     220            0 :       dump_end (phase, outf);
     221              :     }
     222    939813853 : }
     223              : 
     224              : /* Return the in-scope template that's currently being parsed, or
     225              :    NULL_TREE otherwise.  */
     226              : 
     227              : static tree
     228       123655 : get_current_template ()
     229              : {
     230       123655 :   if (scope_chain && in_template_context && !current_instantiation ())
     231        16131 :     if (tree ti = get_template_info (current_scope ()))
     232              :       {
     233         4949 :         if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)) && TI_PARTIAL_INFO (ti))
     234           24 :           ti = TI_PARTIAL_INFO (ti);
     235         4949 :         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    104638272 : cp_adjust_diagnostic_info (const diagnostics::context &context,
     255              :                            diagnostics::diagnostic_info *diagnostic)
     256              : {
     257    104638272 :   if (diagnostic->m_kind == diagnostics::kind::error)
     258       123637 :     if (tree tmpl = get_current_template ())
     259              :       {
     260         4931 :         diagnostic->m_option_id = OPT_Wtemplate_body;
     261              : 
     262         4931 :         if (context.m_permissive)
     263           48 :           diagnostic->m_kind = diagnostics::kind::warning;
     264              : 
     265         4931 :         bool existed;
     266         4931 :         location_t &error_loc
     267         4931 :           = hash_map_safe_get_or_insert<true> (erroneous_templates,
     268              :                                                tmpl, &existed);
     269         4931 :         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         2369 :           error_loc = diagnostic->m_richloc->get_loc ();
     274              :       }
     275    104638272 : }
     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      9392921 : cp_seen_error ()
     282              : {
     283      9392921 :   if ((seen_error) ())
     284              :     return true;
     285              : 
     286      9369926 :   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       101592 : cxx_initialize_diagnostics (diagnostics::context *context)
     303              : {
     304       101592 :   cxx_pretty_printer *pp = new cxx_pretty_printer ();
     305       101592 :   pp->set_format_postprocessor (std::make_unique<cxx_format_postprocessor> ());
     306       101592 :   context->set_pretty_printer (std::unique_ptr<pretty_printer> (pp));
     307              : 
     308       101592 :   c_common_diagnostics_set_defaults (context);
     309       101592 :   diagnostics::text_starter (context) = cp_diagnostic_text_starter;
     310              :   /* diagnostic_finalizer is already c_diagnostic_text_finalizer.  */
     311       101592 :   context->set_format_decoder (cp_printer);
     312       101592 :   context->set_adjust_diagnostic_info_callback (cp_adjust_diagnostic_info);
     313       101592 : }
     314              : 
     315              : /* Dump an '@module' name suffix for DECL, if it's attached to an import.  */
     316              : 
     317              : static void
     318    238874807 : dump_module_suffix (cxx_pretty_printer *pp, tree decl)
     319              : {
     320    238874807 :   if (!modules_p ())
     321              :     return;
     322              : 
     323       179320 :   if (!DECL_CONTEXT (decl))
     324              :     return;
     325              : 
     326       178597 :   if (TREE_CODE (decl) != CONST_DECL
     327       178597 :       || !UNSCOPED_ENUM_P (DECL_CONTEXT (decl)))
     328              :     {
     329       178569 :       if (!DECL_NAMESPACE_SCOPE_P (decl))
     330              :         return;
     331              : 
     332        86012 :       if (TREE_CODE (decl) == NAMESPACE_DECL
     333            0 :           && !DECL_NAMESPACE_ALIAS (decl)
     334        86012 :           && (TREE_PUBLIC (decl) || !TREE_PUBLIC (CP_DECL_CONTEXT (decl))))
     335              :         return;
     336              :     }
     337              : 
     338        86040 :   int m = get_originating_module (decl, /*global=-1*/true);
     339        86040 :   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    181662446 : dump_scope (cxx_pretty_printer *pp, tree scope, int flags)
     356              : {
     357    181662446 :   int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF);
     358              : 
     359    181662446 :   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    181408714 :   if (UNSCOPED_ENUM_P (scope))
     366          231 :     scope = CP_TYPE_CONTEXT (scope);
     367              : 
     368    181408714 :   if (TREE_CODE (scope) == NAMESPACE_DECL)
     369              :     {
     370    161779925 :       if (scope != global_namespace)
     371              :         {
     372     90063931 :           dump_decl (pp, scope, f);
     373     90063931 :           pp_cxx_colon_colon (pp);
     374              :         }
     375              :     }
     376     19628789 :   else if (AGGREGATE_TYPE_P (scope)
     377     19628789 :            || SCOPED_ENUM_P (scope))
     378              :     {
     379     18917696 :       dump_type (pp, scope, f);
     380     18917696 :       pp_cxx_colon_colon (pp);
     381              :     }
     382       711093 :   else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
     383              :     {
     384       695288 :       dump_function_decl (pp, scope, f | TFF_NO_TEMPLATE_BINDINGS);
     385       695288 :       pp_cxx_colon_colon (pp);
     386              :     }
     387              : }
     388              : 
     389              : /* Dump the template ARGument under control of FLAGS.  */
     390              : 
     391              : static void
     392    158930385 : dump_template_argument (cxx_pretty_printer *pp, tree arg, int flags)
     393              : {
     394    158930385 :   if (ARGUMENT_PACK_P (arg))
     395      7509588 :     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    151420797 :   else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
     399    127730238 :     dump_type (pp, arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
     400              :   else
     401              :     {
     402     23690559 :       if (TREE_CODE (arg) == TREE_LIST)
     403            0 :         arg = TREE_VALUE (arg);
     404              : 
     405              :       /* Strip implicit conversions.  */
     406     23690630 :       while (CONVERT_EXPR_P (arg))
     407           71 :         arg = TREE_OPERAND (arg, 0);
     408              : 
     409     23690559 :       dump_expr (pp, arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
     410              :     }
     411    158930385 : }
     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    101016100 : get_non_default_template_args_count (tree args, int flags)
     418              : {
     419    101016100 :   int n = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (args));
     420              : 
     421    101016100 :   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    101016100 :       (flags & TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS) != 0
     427      5781428 :       || !flag_pretty_templates)
     428              :     return n;
     429              : 
     430      5781371 :   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      7514952 : dump_template_argument_list (cxx_pretty_printer *pp, tree args, int flags)
     438              : {
     439      7514952 :   int n = get_non_default_template_args_count (args, flags);
     440      7514952 :   int need_comma = 0;
     441      7514952 :   int i;
     442              : 
     443     29937617 :   for (i = 0; i < n; ++i)
     444              :     {
     445     14907713 :       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     14907713 :       if (need_comma
     451     14907713 :           && (!ARGUMENT_PACK_P (arg)
     452          188 :               || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
     453      7984492 :         pp_separate_with_comma (pp);
     454              : 
     455     14907713 :       dump_template_argument (pp, arg, flags);
     456     14907713 :       need_comma = 1;
     457              :     }
     458      7514952 : }
     459              : 
     460              : /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS.  */
     461              : 
     462              : static void
     463        89434 : dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags)
     464              : {
     465        89434 :   tree p;
     466        89434 :   tree a;
     467              : 
     468        89434 :   if (parm == error_mark_node)
     469              :    return;
     470              : 
     471        89434 :   p = TREE_VALUE (parm);
     472        89434 :   a = TREE_PURPOSE (parm);
     473              : 
     474        89434 :   if (TREE_CODE (p) == TYPE_DECL)
     475              :     {
     476        80904 :       if (flags & TFF_DECL_SPECIFIERS)
     477              :         {
     478        10957 :           pp_cxx_ws_string (pp, "class");
     479        10957 :           if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p)))
     480          869 :             pp_cxx_ws_string (pp, "...");
     481        10957 :           if (DECL_NAME (p))
     482        10196 :             pp_cxx_tree_identifier (pp, DECL_NAME (p));
     483              :         }
     484        69947 :       else if (DECL_NAME (p))
     485        69102 :         pp_cxx_tree_identifier (pp, DECL_NAME (p));
     486              :       else
     487          845 :         pp_cxx_canonical_template_parameter (pp, TREE_TYPE (p));
     488              :     }
     489              :   else
     490         8530 :     dump_decl (pp, p, flags | TFF_DECL_SPECIFIERS);
     491              : 
     492        89434 :   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        50209 : 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        50209 :   struct prepost_semicolon
     516              :   {
     517              :     cxx_pretty_printer *pp;
     518              :     bool need_semicolon;
     519              : 
     520        88716 :     void operator() ()
     521              :     {
     522        88716 :       if (need_semicolon)
     523        38507 :         pp_separate_with_semicolon (pp);
     524              :       else
     525              :         {
     526        50209 :           pp_cxx_whitespace (pp);
     527        50209 :           pp_string (pp, colorize_start (pp_show_color (pp), "targs"));
     528        50209 :           pp_cxx_left_bracket (pp);
     529        50209 :           pp->translate_string ("with");
     530        50209 :           pp_cxx_whitespace (pp);
     531        50209 :           need_semicolon = true;
     532              :         }
     533        88716 :     }
     534              : 
     535        50209 :     ~prepost_semicolon ()
     536              :     {
     537        50209 :       if (need_semicolon)
     538              :         {
     539        50209 :           pp_cxx_right_bracket (pp);
     540        50209 :           pp_string (pp, colorize_stop (pp_show_color (pp)));
     541              :         }
     542        50209 :     }
     543        50209 :   } semicolon_or_introducer = {pp, false};
     544              : 
     545        50209 :   int i;
     546        50209 :   tree t;
     547              : 
     548       102053 :   while (parms)
     549              :     {
     550        51844 :       tree p = TREE_VALUE (parms);
     551        51844 :       int lvl = TMPL_PARMS_DEPTH (parms);
     552        51844 :       int arg_idx = 0;
     553        51844 :       int i;
     554        51844 :       tree lvl_args = NULL_TREE;
     555              : 
     556              :       /* Don't crash if we had an invalid argument list.  */
     557       152277 :       if (TMPL_ARGS_DEPTH (args) >= lvl)
     558       103676 :         lvl_args = TMPL_ARGS_LEVEL (args, lvl);
     559              : 
     560       129108 :       for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
     561              :         {
     562        77264 :           tree arg = NULL_TREE;
     563              : 
     564              :           /* Don't crash if we had an invalid argument list.  */
     565       154522 :           if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
     566        77258 :             arg = TREE_VEC_ELT (lvl_args, arg_idx);
     567              : 
     568        77264 :           tree parm_i = TREE_VEC_ELT (p, i);
     569              :           /* If the template argument repeats the template parameter (T = T),
     570              :              skip the parameter.*/
     571        77225 :           if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM
     572         1040 :               && arg == TYPE_MAIN_VARIANT (arg)
     573         1040 :               && TREE_CODE (parm_i) == TREE_LIST
     574         1040 :               && TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL
     575         1021 :               && (TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i)))
     576              :                   == TEMPLATE_TYPE_PARM)
     577        78285 :               && (DECL_NAME (TREE_VALUE (parm_i))
     578         1021 :                   == DECL_NAME (TYPE_STUB_DECL (arg))))
     579          567 :             continue;
     580              : 
     581        76697 :           semicolon_or_introducer ();
     582        76697 :           dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER);
     583        76697 :           pp_cxx_whitespace (pp);
     584        76697 :           pp_equal (pp);
     585        76697 :           pp_cxx_whitespace (pp);
     586        76697 :           if (arg)
     587              :             {
     588        76658 :               if (ARGUMENT_PACK_P (arg))
     589         2840 :                 pp_cxx_left_brace (pp);
     590        76658 :               dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
     591        76658 :               if (ARGUMENT_PACK_P (arg))
     592         2840 :                 pp_cxx_right_brace (pp);
     593              :             }
     594              :           else
     595           39 :             pp_string (pp, M_("<missing>"));
     596              : 
     597        76697 :           ++arg_idx;
     598              :         }
     599              : 
     600        51844 :       parms = TREE_CHAIN (parms);
     601              :     }
     602              : 
     603              :   /* Don't bother with typenames for a partial instantiation.  */
     604        59499 :   if (vec_safe_is_empty (typenames) || uses_template_parms (args))
     605              :     return;
     606              : 
     607              :   /* Don't try to print typenames when we're processing a clone.  */
     608         9072 :   if (current_function_decl
     609         9072 :       && !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         9072 :   if (at_eof >= 3)
     615              :     return;
     616              : 
     617        20816 :   FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
     618              :     {
     619        12019 :       semicolon_or_introducer ();
     620        12019 :       dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
     621        12019 :       pp_cxx_whitespace (pp);
     622        12019 :       pp_equal (pp);
     623        12019 :       pp_cxx_whitespace (pp);
     624        12019 :       push_deferring_access_checks (dk_no_check);
     625        12019 :       t = tsubst (t, args, tf_none, NULL_TREE);
     626        12019 :       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        12019 :       t = strip_typedefs (t, NULL, STF_USER_VISIBLE);
     630        12019 :       dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
     631              :     }
     632        50209 : }
     633              : 
     634              : /* Dump a human-readable equivalent of the alias template
     635              :    specialization of T.  */
     636              : 
     637              : static void
     638         9199 : dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags)
     639              : {
     640         9199 :   gcc_assert (alias_template_specialization_p (t, nt_opaque));
     641              : 
     642         9199 :   tree decl = TYPE_NAME (t);
     643         9199 :   if (!(flags & TFF_UNQUALIFIED_NAME))
     644         9199 :     dump_scope (pp, CP_DECL_CONTEXT (decl), flags);
     645         9199 :   pp_cxx_tree_identifier (pp, DECL_NAME (decl));
     646         9199 :   dump_template_parms (pp, DECL_TEMPLATE_INFO (decl),
     647              :                        /*primary=*/false,
     648              :                        flags & ~TFF_TEMPLATE_HEADER);
     649         9199 : }
     650              : 
     651              : /* Dump a human-readable equivalent of TYPE.  FLAGS controls the
     652              :    format.  */
     653              : 
     654              : static void
     655    230710844 : dump_type (cxx_pretty_printer *pp, tree t, int flags)
     656              : {
     657    230710874 :   if (t == NULL_TREE)
     658              :     return;
     659              : 
     660              :   /* Don't print e.g. "struct mytypedef".  */
     661    230710860 :   if (TYPE_P (t) && typedef_variant_p (t))
     662              :     {
     663      1199887 :       tree decl = TYPE_NAME (t);
     664      1199887 :       if ((flags & TFF_CHASE_TYPEDEF)
     665      1199887 :                || DECL_SELF_REFERENCE_P (decl)
     666      2399131 :                || (!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          649 :                                     ? STF_USER_VISIBLE : 0);
     671          649 :           t = strip_typedefs (t, NULL, stf_flags);
     672              :         }
     673      1199238 :       else if (alias_template_specialization_p (t, nt_opaque))
     674              :         {
     675         9199 :           dump_alias_template_specialization (pp, t, flags);
     676         9199 :           return;
     677              :         }
     678      1190039 :       else if (same_type_p (t, TREE_TYPE (decl)))
     679              :         t = decl;
     680              :       else
     681              :         {
     682         3096 :           pp_cxx_cv_qualifier_seq (pp, t);
     683         3096 :           if (! (flags & TFF_UNQUALIFIED_NAME))
     684         3096 :             dump_scope (pp, CP_DECL_CONTEXT (decl), flags);
     685         3096 :           pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     686         3096 :           return;
     687              :         }
     688              :     }
     689              : 
     690    230698565 :   if (TYPE_PTRMEMFUNC_P (t))
     691       174938 :     goto offset_type;
     692              : 
     693    230523627 :   switch (TREE_CODE (t))
     694              :     {
     695         3993 :     case LANG_TYPE:
     696         3993 :       if (t == init_list_type_node)
     697          286 :         pp_string (pp, M_("<brace-enclosed initializer list>"));
     698         3707 :       else if (t == unknown_type_node)
     699          161 :         pp_string (pp, M_("<unresolved overloaded function type>"));
     700         3546 :       else if (REFLECTION_TYPE_P (t))
     701              :         {
     702         3546 :           pp_cxx_ws_string (pp, "std::meta::info");
     703         3546 :           pp_c_type_qualifier_list (pp, t);
     704              :         }
     705              :       else
     706              :         {
     707            0 :           pp_cxx_cv_qualifier_seq (pp, t);
     708            0 :           if (tree id = TYPE_IDENTIFIER (t))
     709            0 :             pp_cxx_tree_identifier (pp, id);
     710              :         }
     711              :       break;
     712              : 
     713           99 :     case TREE_VEC:
     714           99 :       {
     715              :         /* A list of types used for a trait.  */
     716           99 :         bool need_comma = false;
     717          229 :         for (tree arg : tree_vec_range (t))
     718              :           {
     719          130 :             if (need_comma)
     720           31 :               pp_separate_with_comma (pp);
     721          130 :             dump_type (pp, arg, flags);
     722          130 :             need_comma = true;
     723              :           }
     724              :       }
     725           99 :       break;
     726              : 
     727            0 :     case TREE_LIST:
     728              :       /* A list of function parms.  */
     729            0 :       dump_parameters (pp, t, flags);
     730            0 :       break;
     731              : 
     732          293 :     case IDENTIFIER_NODE:
     733          293 :       pp_cxx_tree_identifier (pp, t);
     734          293 :       break;
     735              : 
     736           24 :     case TREE_BINFO:
     737           24 :       dump_type (pp, BINFO_TYPE (t), flags);
     738           24 :       break;
     739              : 
     740    139818219 :     case RECORD_TYPE:
     741    139818219 :     case UNION_TYPE:
     742    139818219 :     case ENUMERAL_TYPE:
     743    139818219 :       dump_aggr_type (pp, t, flags);
     744    139818219 :       break;
     745              : 
     746      1187501 :     case TYPE_DECL:
     747      1187501 :       if (flags & TFF_CHASE_TYPEDEF)
     748              :         {
     749            0 :           dump_type (pp, DECL_ORIGINAL_TYPE (t)
     750            0 :                      ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
     751              :           break;
     752              :         }
     753              :       /* Fall through.  */
     754              : 
     755      1687427 :     case TEMPLATE_DECL:
     756      1687427 :     case NAMESPACE_DECL:
     757      1687427 :     case CONST_DECL:
     758      1687427 :       dump_decl (pp, t, flags & ~TFF_DECL_SPECIFIERS);
     759      1687427 :       break;
     760              : 
     761     59975164 :     case INTEGER_TYPE:
     762     59975164 :     case REAL_TYPE:
     763     59975164 :     case VOID_TYPE:
     764     59975164 :     case OPAQUE_TYPE:
     765     59975164 :     case BOOLEAN_TYPE:
     766     59975164 :     case COMPLEX_TYPE:
     767     59975164 :     case VECTOR_TYPE:
     768     59975164 :     case FIXED_POINT_TYPE:
     769     59975164 :       pp_type_specifier_seq (pp, t);
     770     59975164 :       break;
     771              : 
     772         1735 :     case TEMPLATE_TEMPLATE_PARM:
     773              :       /* For parameters inside template signature.  */
     774         1735 :       if (TYPE_IDENTIFIER (t))
     775         3372 :         pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     776              :       else
     777           49 :         pp_cxx_canonical_template_parameter (pp, t);
     778              :       break;
     779              : 
     780          434 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
     781          434 :       {
     782          434 :         tree args = TYPE_TI_ARGS (t);
     783          434 :         pp_cxx_cv_qualifier_seq (pp, t);
     784          868 :         pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     785          434 :         pp_cxx_begin_template_argument_list (pp);
     786          434 :         dump_template_argument_list (pp, args, flags);
     787          434 :         pp_cxx_end_template_argument_list (pp);
     788              :       }
     789          434 :       break;
     790              : 
     791       348634 :     case TEMPLATE_TYPE_PARM:
     792       348634 :       pp_cxx_cv_qualifier_seq (pp, t);
     793       348634 :       if (template_placeholder_p (t))
     794              :         {
     795           57 :           tree tmpl = TREE_TYPE (CLASS_PLACEHOLDER_TEMPLATE (t));
     796          114 :           pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (tmpl));
     797           57 :           pp_string (pp, "<...auto...>");
     798              :         }
     799       348577 :       else if (TYPE_IDENTIFIER (t))
     800       695398 :         pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
     801              :       else
     802          878 :         pp_cxx_canonical_template_parameter
     803          878 :           (pp, TEMPLATE_TYPE_PARM_INDEX (t));
     804              :       /* If this is a constrained placeholder, add the requirements.  */
     805       348634 :       if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
     806          181 :         pp_cxx_constrained_type_spec (pp, c);
     807              :       break;
     808              : 
     809              :       /* This is not always necessary for pointers and such, but doing this
     810              :          reduces code size.  */
     811     28688948 :     case ARRAY_TYPE:
     812     28688948 :     case POINTER_TYPE:
     813     28688948 :     case REFERENCE_TYPE:
     814     28688948 :     case OFFSET_TYPE:
     815     28688948 :     offset_type:
     816     28688948 :     case FUNCTION_TYPE:
     817     28688948 :     case METHOD_TYPE:
     818     28688948 :     {
     819     28688948 :       dump_type_prefix (pp, t, flags);
     820     28688948 :       dump_type_suffix (pp, t, flags);
     821     28688948 :       break;
     822              :     }
     823         3467 :     case TYPENAME_TYPE:
     824         3467 :       if (! (flags & TFF_CHASE_TYPEDEF)
     825         3467 :           && DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
     826              :         {
     827            0 :           dump_decl (pp, TYPE_NAME (t), TFF_PLAIN_IDENTIFIER);
     828            0 :           break;
     829              :         }
     830         3467 :       pp_cxx_cv_qualifier_seq (pp, t);
     831         3467 :       if (const char *tag = tag_name (get_typename_tag (t)))
     832         3438 :         pp_cxx_ws_string (pp, tag);
     833         3467 :       dump_typename (pp, t, flags);
     834         3467 :       break;
     835              : 
     836            6 :     case UNBOUND_CLASS_TEMPLATE:
     837            6 :       if (! (flags & TFF_UNQUALIFIED_NAME))
     838              :         {
     839            6 :           dump_type (pp, TYPE_CONTEXT (t), flags);
     840            6 :           pp_cxx_colon_colon (pp);
     841              :         }
     842            6 :       pp_cxx_ws_string (pp, "template");
     843            6 :       dump_type (pp, TYPE_IDENTIFIER (t), flags);
     844              :       break;
     845              : 
     846            3 :     case TYPEOF_TYPE:
     847            3 :       pp_cxx_ws_string (pp, "__typeof__");
     848            3 :       pp_cxx_whitespace (pp);
     849            3 :       pp_cxx_left_paren (pp);
     850            3 :       dump_expr (pp, TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
     851            3 :       pp_cxx_right_paren (pp);
     852            3 :       break;
     853              : 
     854           42 :     case TRAIT_TYPE:
     855           42 :       pp_cxx_trait (pp, t);
     856           42 :       break;
     857              : 
     858        38281 :     case TYPE_PACK_EXPANSION:
     859        38281 :       dump_type (pp, PACK_EXPANSION_PATTERN (t), flags);
     860        38281 :       pp_cxx_ws_string (pp, "...");
     861        38281 :       break;
     862              : 
     863            4 :     case PACK_INDEX_TYPE:
     864            4 :       dump_type (pp, PACK_INDEX_PACK (t), flags);
     865            4 :       pp_cxx_left_bracket (pp);
     866            4 :       dump_expr (pp, PACK_INDEX_INDEX (t), flags & ~TFF_EXPR_IN_PARENS);
     867            4 :       pp_cxx_right_bracket (pp);
     868            4 :       break;
     869              : 
     870           74 :     case TYPE_ARGUMENT_PACK:
     871           74 :       dump_template_argument (pp, t, flags);
     872           74 :       break;
     873              : 
     874          798 :     case DECLTYPE_TYPE:
     875          798 :       pp_cxx_ws_string (pp, "decltype");
     876          798 :       pp_cxx_whitespace (pp);
     877          798 :       pp_cxx_left_paren (pp);
     878          798 :       dump_expr (pp, DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
     879          798 :       pp_cxx_right_paren (pp);
     880          798 :       break;
     881              : 
     882       130867 :     case NULLPTR_TYPE:
     883       130867 :       pp_cxx_ws_string (pp, "std::nullptr_t");
     884       130867 :       pp_c_type_qualifier_list (pp, t);
     885       130867 :       break;
     886              : 
     887           24 :     case SPLICE_SCOPE:
     888           24 :       dump_expr (pp, SPLICE_SCOPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
     889           24 :       break;
     890              : 
     891            0 :     default:
     892            0 :       pp_unsupported_tree (pp, t);
     893              :       /* Fall through.  */
     894              : 
     895           29 :     case ERROR_MARK:
     896           29 :       pp_string (pp, M_("<type error>"));
     897           29 :       break;
     898              :     }
     899              : }
     900              : 
     901              : /* Dump a TYPENAME_TYPE. We need to notice when the context is itself
     902              :    a TYPENAME_TYPE.  */
     903              : 
     904              : static void
     905         4060 : dump_typename (cxx_pretty_printer *pp, tree t, int flags)
     906              : {
     907         4060 :   tree ctx = TYPE_CONTEXT (t);
     908              : 
     909         4060 :   if (TREE_CODE (ctx) == TYPENAME_TYPE)
     910          593 :     dump_typename (pp, ctx, flags);
     911              :   else
     912         3467 :     dump_type (pp, ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
     913         4060 :   pp_cxx_colon_colon (pp);
     914         4060 :   dump_decl (pp, TYPENAME_TYPE_FULLNAME (t), flags);
     915         4060 : }
     916              : 
     917              : /* Return the name of the supplied aggregate, or enumeral type.  */
     918              : 
     919              : const char *
     920    139997568 : class_key_or_enum_as_string (tree t)
     921              : {
     922    139997568 :   if (TREE_CODE (t) == ENUMERAL_TYPE)
     923              :     {
     924      2884189 :       if (SCOPED_ENUM_P (t))
     925              :         return "enum class";
     926              :       else
     927      1209798 :         return "enum";
     928              :     }
     929    137113379 :   else if (TREE_CODE (t) == UNION_TYPE)
     930              :     return "union";
     931    136403250 :   else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
     932     37381808 :     return "class";
     933              :   else
     934              :     return "struct";
     935              : }
     936              : 
     937              : /* Disable warnings about missing quoting in GCC diagnostics for
     938              :    the pp_verbatim call.  Their format strings deliberately don't
     939              :    follow GCC diagnostic conventions.  */
     940              : #if __GNUC__ >= 10
     941              : #pragma GCC diagnostic push
     942              : #pragma GCC diagnostic ignored "-Wformat-diag"
     943              : #endif
     944              : 
     945              : /* Print out a class declaration T under the control of FLAGS,
     946              :    in the form `class foo'.  */
     947              : 
     948              : static void
     949    139997451 : dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
     950              : {
     951    139997451 :   const char *variety = class_key_or_enum_as_string (t);
     952    139997451 :   int typdef = 0;
     953    139997451 :   int tmplate = 0;
     954              : 
     955    139997451 :   pp_cxx_cv_qualifier_seq (pp, t);
     956              : 
     957    139997451 :   if (flags & TFF_CLASS_KEY_OR_ENUM)
     958        12806 :     pp_cxx_ws_string (pp, variety);
     959              : 
     960    139997451 :   tree decl = TYPE_NAME (t);
     961              : 
     962    139997451 :   if (decl)
     963              :     {
     964    139997451 :       typdef = (!DECL_ARTIFICIAL (decl)
     965              :                 /* An alias specialization is not considered to be a
     966              :                    typedef.  */
     967    139997451 :                 && !alias_template_specialization_p (t, nt_opaque));
     968              : 
     969       344428 :       if ((typdef
     970       344428 :            && ((flags & TFF_CHASE_TYPEDEF)
     971       344428 :                || (!flag_pretty_templates && DECL_LANG_SPECIFIC (decl)
     972            0 :                    && DECL_TEMPLATE_INFO (decl))))
     973    139997451 :           || DECL_SELF_REFERENCE_P (decl))
     974              :         {
     975            0 :           t = TYPE_MAIN_VARIANT (t);
     976            0 :           decl = TYPE_NAME (t);
     977            0 :           typdef = 0;
     978              :         }
     979              : 
     980    139653023 :       tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
     981    136768945 :                 && TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
     982    235414161 :                 && (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
     983     95416710 :                     || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
     984              : 
     985    139997451 :       if (! (flags & TFF_UNQUALIFIED_NAME))
     986     89751043 :         dump_scope (pp, CP_DECL_CONTEXT (decl), flags | TFF_SCOPE);
     987    139997451 :       flags &= ~TFF_UNQUALIFIED_NAME;
     988    139997451 :       if (tmplate)
     989              :         {
     990              :           /* Because the template names are mangled, we have to locate
     991              :              the most general template, and use that name.  */
     992     93115189 :           tree tpl = TYPE_TI_TEMPLATE (t);
     993              : 
     994     93819014 :           while (DECL_TEMPLATE_INFO (tpl))
     995       703825 :             tpl = DECL_TI_TEMPLATE (tpl);
     996              :           decl = tpl;
     997              :         }
     998              :     }
     999              : 
    1000    276400514 :   if (LAMBDA_TYPE_P (t))
    1001              :     {
    1002              :       /* A lambda's "type" is essentially its signature.  */
    1003       590297 :       pp_string (pp, M_("<lambda"));
    1004       590297 :       tree const fn = lambda_function (t);
    1005       590297 :       if (fn)
    1006              :         {
    1007       590261 :           int const parm_flags
    1008       590261 :             = DECL_XOBJ_MEMBER_FUNCTION_P (fn) ? TFF_XOBJ_FUNC | flags
    1009          277 :                                                : flags;
    1010       590261 :           dump_parameters (pp, FUNCTION_FIRST_USER_PARMTYPE (fn), parm_flags);
    1011              :         }
    1012       590297 :       pp_greater (pp);
    1013              :     }
    1014    139407154 :   else if (!decl || IDENTIFIER_ANON_P (DECL_NAME (decl)))
    1015              :     {
    1016         2004 :       if (flags & TFF_CLASS_KEY_OR_ENUM)
    1017          217 :         pp_string (pp, M_("<unnamed>"));
    1018              :       else
    1019         1787 :         pp_printf (pp, M_("<unnamed %s>"), variety);
    1020              :     }
    1021              :   else
    1022    139405150 :     pp_cxx_tree_identifier (pp, DECL_NAME (decl));
    1023              : 
    1024    139997451 :   dump_module_suffix (pp, decl);
    1025              : 
    1026    139997451 :   if (tmplate)
    1027     93115189 :     dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
    1028     93115189 :                          !CLASSTYPE_USE_TEMPLATE (t),
    1029              :                          flags & ~TFF_TEMPLATE_HEADER);
    1030    139997451 : }
    1031              : 
    1032              : #if __GNUC__ >= 10
    1033              : #pragma GCC diagnostic pop
    1034              : #endif
    1035              : 
    1036              : /* Dump into the obstack the initial part of the output for a given type.
    1037              :    This is necessary when dealing with things like functions returning
    1038              :    functions.  Examples:
    1039              : 
    1040              :    return type of `int (* fee ())()': pointer -> function -> int.  Both
    1041              :    pointer (and reference and offset) and function (and member) types must
    1042              :    deal with prefix and suffix.
    1043              : 
    1044              :    Arrays must also do this for DECL nodes, like int a[], and for things like
    1045              :    int *[]&.  */
    1046              : 
    1047              : static void
    1048     59878129 : dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags)
    1049              : {
    1050     61180250 :   if (TYPE_PTRMEMFUNC_P (t))
    1051              :     {
    1052       179070 :       t = TYPE_PTRMEMFUNC_FN_TYPE (t);
    1053       179070 :       goto offset_type;
    1054              :     }
    1055              : 
    1056     61001180 :   switch (TREE_CODE (t))
    1057              :     {
    1058     30660315 :     case POINTER_TYPE:
    1059     30660315 :     case REFERENCE_TYPE:
    1060     30660315 :       {
    1061     30660315 :         tree sub = TREE_TYPE (t);
    1062              : 
    1063     30660315 :         dump_type_prefix (pp, sub, flags);
    1064     30660315 :         if (TREE_CODE (sub) == ARRAY_TYPE
    1065     30479986 :             || TREE_CODE (sub) == FUNCTION_TYPE)
    1066              :           {
    1067       459730 :             pp_cxx_whitespace (pp);
    1068       459730 :             pp_cxx_left_paren (pp);
    1069              :             /* If we're dealing with the GNU form of attributes, print this:
    1070              :                  void (__attribute__((noreturn)) *f) ();
    1071              :                If it is the standard [[]] attribute, we'll print the attribute
    1072              :                in dump_type_suffix.  */
    1073       459730 :             if (!cxx11_attribute_p (TYPE_ATTRIBUTES (sub)))
    1074       459725 :               pp_c_attributes_display (pp, TYPE_ATTRIBUTES (sub));
    1075              :           }
    1076     30660315 :         if (TYPE_PTR_P (t))
    1077     16811166 :           pp_star (pp);
    1078     13849149 :         else if (TYPE_REF_P (t))
    1079              :           {
    1080     13849149 :             if (TYPE_REF_IS_RVALUE (t))
    1081      2061926 :               pp_ampersand_ampersand (pp);
    1082              :             else
    1083     11787223 :               pp_ampersand (pp);
    1084              :           }
    1085     30660315 :         pp->set_padding (pp_before);
    1086     30660315 :         pp_cxx_cv_qualifier_seq (pp, t);
    1087              :       }
    1088     30660315 :       break;
    1089              : 
    1090       189538 :     case OFFSET_TYPE:
    1091       189538 :     offset_type:
    1092       189538 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1093       189538 :       if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
    1094              :         {
    1095        10468 :           pp_maybe_space (pp);
    1096        10468 :           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
    1097          866 :              pp_cxx_left_paren (pp);
    1098        10468 :           dump_type (pp, TYPE_OFFSET_BASETYPE (t), flags);
    1099        10468 :           pp_cxx_colon_colon (pp);
    1100              :         }
    1101       189538 :       pp_cxx_star (pp);
    1102       189538 :       pp_cxx_cv_qualifier_seq (pp, t);
    1103       189538 :       pp->set_padding (pp_before);
    1104       189538 :       break;
    1105              : 
    1106              :       /* This can be reached without a pointer when dealing with
    1107              :          templates, e.g. std::is_function.  */
    1108       521545 :     case FUNCTION_TYPE:
    1109       521545 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1110       521545 :       break;
    1111              : 
    1112       179232 :     case METHOD_TYPE:
    1113       179232 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1114       179232 :       pp_maybe_space (pp);
    1115       179232 :       pp_cxx_left_paren (pp);
    1116       179232 :       dump_aggr_type (pp, TYPE_METHOD_BASETYPE (t), flags);
    1117       179232 :       pp_cxx_colon_colon (pp);
    1118       179232 :       break;
    1119              : 
    1120       780576 :     case ARRAY_TYPE:
    1121       780576 :       dump_type_prefix (pp, TREE_TYPE (t), flags);
    1122       780576 :       break;
    1123              : 
    1124     28849013 :     case ENUMERAL_TYPE:
    1125     28849013 :     case IDENTIFIER_NODE:
    1126     28849013 :     case INTEGER_TYPE:
    1127     28849013 :     case BOOLEAN_TYPE:
    1128     28849013 :     case REAL_TYPE:
    1129     28849013 :     case RECORD_TYPE:
    1130     28849013 :     case TEMPLATE_TYPE_PARM:
    1131     28849013 :     case TEMPLATE_TEMPLATE_PARM:
    1132     28849013 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1133     28849013 :     case TREE_LIST:
    1134     28849013 :     case TYPE_DECL:
    1135     28849013 :     case TREE_VEC:
    1136     28849013 :     case UNION_TYPE:
    1137     28849013 :     case LANG_TYPE:
    1138     28849013 :     case VOID_TYPE:
    1139     28849013 :     case OPAQUE_TYPE:
    1140     28849013 :     case TYPENAME_TYPE:
    1141     28849013 :     case COMPLEX_TYPE:
    1142     28849013 :     case VECTOR_TYPE:
    1143     28849013 :     case TYPEOF_TYPE:
    1144     28849013 :     case TRAIT_TYPE:
    1145     28849013 :     case DECLTYPE_TYPE:
    1146     28849013 :     case TYPE_PACK_EXPANSION:
    1147     28849013 :     case FIXED_POINT_TYPE:
    1148     28849013 :     case NULLPTR_TYPE:
    1149     28849013 :     case PACK_INDEX_TYPE:
    1150     28849013 :     case SPLICE_SCOPE:
    1151     28849013 :       dump_type (pp, t, flags);
    1152     28849013 :       pp->set_padding (pp_before);
    1153     28849013 :       break;
    1154              : 
    1155            0 :     default:
    1156            0 :       pp_unsupported_tree (pp, t);
    1157              :       /* fall through.  */
    1158           31 :     case ERROR_MARK:
    1159           31 :       pp_string (pp, M_("<typeprefixerror>"));
    1160           31 :       break;
    1161              :     }
    1162     59878129 : }
    1163              : 
    1164              : /* Dump the suffix of type T, under control of FLAGS.  This is the part
    1165              :    which appears after the identifier (or function parms).  */
    1166              : 
    1167              : static void
    1168     28849433 : dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
    1169              : {
    1170     61180639 :   if (TYPE_PTRMEMFUNC_P (t))
    1171       179070 :     t = TYPE_PTRMEMFUNC_FN_TYPE (t);
    1172              : 
    1173     61180639 :   switch (TREE_CODE (t))
    1174              :     {
    1175     30849853 :     case POINTER_TYPE:
    1176     30849853 :     case REFERENCE_TYPE:
    1177     30849853 :     case OFFSET_TYPE:
    1178     30849853 :       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
    1179     30849853 :           || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
    1180       460596 :         pp_cxx_right_paren (pp);
    1181     30849853 :       if (TREE_CODE (t) == POINTER_TYPE)
    1182     16990236 :         flags |= TFF_POINTER;
    1183     30849853 :       dump_type_suffix (pp, TREE_TYPE (t), flags);
    1184     30849853 :       break;
    1185              : 
    1186       700777 :     case FUNCTION_TYPE:
    1187       700777 :     case METHOD_TYPE:
    1188       700777 :       {
    1189       700777 :         tree arg;
    1190       700777 :         if (TREE_CODE (t) == METHOD_TYPE)
    1191              :           /* Can only be reached through a pointer.  */
    1192       179232 :           pp_cxx_right_paren (pp);
    1193       700777 :         arg = TYPE_ARG_TYPES (t);
    1194       700777 :         if (TREE_CODE (t) == METHOD_TYPE)
    1195       179232 :           arg = TREE_CHAIN (arg);
    1196              : 
    1197              :         /* Function pointers don't have default args.  Not in standard C++,
    1198              :            anyway; they may in g++, but we'll just pretend otherwise.  */
    1199       700777 :         dump_parameters (pp, arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
    1200              : 
    1201       700777 :         pp->set_padding (pp_before);
    1202      1044369 :         pp_cxx_cv_qualifiers (pp, type_memfn_quals (t),
    1203              :                               TREE_CODE (t) == FUNCTION_TYPE
    1204              :                               && (flags & TFF_POINTER));
    1205       700777 :         dump_ref_qualifier (pp, t, flags);
    1206       700777 :         if (tx_safe_fn_type_p (t))
    1207           19 :           pp_cxx_ws_string (pp, "transaction_safe");
    1208       700777 :         dump_exception_spec (pp, TYPE_RAISES_EXCEPTIONS (t), flags);
    1209              :         /* If this is the standard [[]] attribute, print
    1210              :              void (*)() [[noreturn]];  */
    1211       700777 :         if (cxx11_attribute_p (TYPE_ATTRIBUTES (t)))
    1212              :           {
    1213            2 :             pp_space (pp);
    1214            2 :             pp_c_attributes_display (pp, TYPE_ATTRIBUTES (t));
    1215            2 :             pp->set_padding (pp_before);
    1216              :           }
    1217       700777 :         dump_type_suffix (pp, TREE_TYPE (t), flags);
    1218       700777 :         break;
    1219              :       }
    1220              : 
    1221       780576 :     case ARRAY_TYPE:
    1222       780576 :       pp_maybe_space (pp);
    1223       780576 :       pp_cxx_left_bracket (pp);
    1224       780576 :       if (tree dtype = TYPE_DOMAIN (t))
    1225              :         {
    1226       132016 :           tree max = TYPE_MAX_VALUE (dtype);
    1227              :           /* Zero-length arrays have a null upper bound in C and SIZE_MAX
    1228              :              in C++.  Handle both since the type might be constructed by
    1229              :              the middle end and end up here as a result of a warning (see
    1230              :              PR c++/97201).  */
    1231       132016 :           if (!max || integer_all_onesp (max))
    1232          651 :             pp_character (pp, '0');
    1233       131365 :           else if (tree_fits_shwi_p (max))
    1234       130807 :             pp_wide_integer (pp, tree_to_shwi (max) + 1);
    1235              :           else
    1236              :             {
    1237          558 :               STRIP_NOPS (max);
    1238          558 :               if (TREE_CODE (max) == SAVE_EXPR)
    1239            0 :                 max = TREE_OPERAND (max, 0);
    1240          558 :               if (TREE_CODE (max) == MINUS_EXPR
    1241          558 :                   || TREE_CODE (max) == PLUS_EXPR)
    1242              :                 {
    1243          486 :                   max = TREE_OPERAND (max, 0);
    1244          874 :                   while (CONVERT_EXPR_P (max))
    1245          388 :                     max = TREE_OPERAND (max, 0);
    1246              :                 }
    1247              :               else
    1248           72 :                 max = fold_build2_loc (input_location,
    1249              :                                        PLUS_EXPR, dtype, max,
    1250              :                                        build_int_cst (dtype, 1));
    1251          558 :               dump_expr (pp, max, flags & ~TFF_EXPR_IN_PARENS);
    1252              :             }
    1253              :         }
    1254       780576 :       pp_cxx_right_bracket (pp);
    1255       780576 :       dump_type_suffix (pp, TREE_TYPE (t), flags);
    1256       780576 :       break;
    1257              : 
    1258              :     case ENUMERAL_TYPE:
    1259              :     case IDENTIFIER_NODE:
    1260              :     case INTEGER_TYPE:
    1261              :     case BOOLEAN_TYPE:
    1262              :     case REAL_TYPE:
    1263              :     case RECORD_TYPE:
    1264              :     case TEMPLATE_TYPE_PARM:
    1265              :     case TEMPLATE_TEMPLATE_PARM:
    1266              :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    1267              :     case TREE_LIST:
    1268              :     case TYPE_DECL:
    1269              :     case TREE_VEC:
    1270              :     case UNION_TYPE:
    1271              :     case LANG_TYPE:
    1272              :     case VOID_TYPE:
    1273              :     case OPAQUE_TYPE:
    1274              :     case TYPENAME_TYPE:
    1275              :     case COMPLEX_TYPE:
    1276              :     case VECTOR_TYPE:
    1277              :     case TYPEOF_TYPE:
    1278              :     case TRAIT_TYPE:
    1279              :     case DECLTYPE_TYPE:
    1280              :     case TYPE_PACK_EXPANSION:
    1281              :     case FIXED_POINT_TYPE:
    1282              :     case NULLPTR_TYPE:
    1283              :     case PACK_INDEX_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     28849433 : }
    1295              : 
    1296              : static void
    1297           69 : dump_global_iord (cxx_pretty_printer *pp, tree t)
    1298              : {
    1299           69 :   const char *p = NULL;
    1300              : 
    1301           69 :   if (DECL_GLOBAL_CTOR_P (t))
    1302           69 :     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           69 :   pp_printf (pp, p, DECL_SOURCE_FILE (t));
    1309           69 : }
    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           40 : dump_omp_declare_mapper (cxx_pretty_printer *pp, tree t, int flags)
    1316              : {
    1317           40 :   pp_string (pp, "#pragma omp declare mapper");
    1318           40 :   if (t == NULL_TREE || t == error_mark_node)
    1319              :     return;
    1320           40 :   pp_space (pp);
    1321           40 :   pp_cxx_left_paren (pp);
    1322           40 :   if (OMP_DECLARE_MAPPER_ID (t))
    1323              :     {
    1324            8 :       pp_cxx_tree_identifier (pp, OMP_DECLARE_MAPPER_ID (t));
    1325            8 :       pp_colon (pp);
    1326              :     }
    1327           40 :   dump_type (pp, TREE_TYPE (t), flags);
    1328           40 :   pp_cxx_right_paren (pp);
    1329              : }
    1330              : 
    1331              : static void
    1332      1410613 : dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
    1333              : {
    1334      1410613 :   if (VAR_P (t) && DECL_NTTP_OBJECT_P (t))
    1335        14121 :     return dump_expr (pp, DECL_INITIAL (t), flags);
    1336              : 
    1337      1396492 :   if (TREE_CODE (t) == VAR_DECL
    1338        29559 :       && DECL_LANG_SPECIFIC (t)
    1339      1404262 :       && DECL_OMP_DECLARE_MAPPER_P (t))
    1340           40 :     return dump_omp_declare_mapper (pp, DECL_INITIAL (t), flags);
    1341              : 
    1342      1396452 :   if (flags & TFF_DECL_SPECIFIERS)
    1343              :     {
    1344        28243 :       if (concept_definition_p (t))
    1345          389 :         pp_cxx_ws_string (pp, "concept");
    1346        27854 :       else if (VAR_P (t) && DECL_DECLARED_CONSTEXPR_P (t))
    1347          531 :         pp_cxx_ws_string (pp, "constexpr");
    1348              : 
    1349        28243 :       if (!concept_definition_p (t))
    1350        27854 :         dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME);
    1351        28243 :       pp_maybe_space (pp);
    1352              :     }
    1353      1396452 :   if (! (flags & TFF_UNQUALIFIED_NAME)
    1354      1384575 :       && TREE_CODE (t) != PARM_DECL
    1355      2757805 :       && (!DECL_INITIAL (t)
    1356        11513 :           || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
    1357      1359699 :     dump_scope (pp, CP_DECL_CONTEXT (t), flags);
    1358      1396452 :   flags &= ~TFF_UNQUALIFIED_NAME;
    1359      1396452 :   if ((flags & TFF_DECL_SPECIFIERS)
    1360        28243 :       && DECL_TEMPLATE_PARM_P (t)
    1361      1403911 :       && TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
    1362          771 :     pp_string (pp, "...");
    1363      1396452 :   if (DECL_NAME (t))
    1364              :     {
    1365      1394455 :       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      1394443 :         dump_decl (pp, DECL_NAME (t), flags);
    1373              :     }
    1374         1997 :   else if (DECL_DECOMPOSITION_P (t))
    1375           57 :     pp_string (pp, M_("<structured bindings>"));
    1376         1940 :   else if (TREE_CODE (t) == FIELD_DECL && DECL_FIELD_IS_BASE (t))
    1377          539 :     dump_type (pp, TREE_TYPE (t), flags);
    1378              :   else
    1379         1401 :     pp_string (pp, M_("<anonymous>"));
    1380              : 
    1381      1396452 :   dump_module_suffix (pp, t);
    1382              : 
    1383      1396452 :   if (flags & TFF_DECL_SPECIFIERS)
    1384        28243 :     dump_type_suffix (pp, type, flags);
    1385              : }
    1386              : 
    1387              : class colorize_guard
    1388              : {
    1389              :   bool colorize;
    1390              :   cxx_pretty_printer *pp;
    1391              : public:
    1392     97487080 :   colorize_guard (bool _colorize, cxx_pretty_printer *pp, const char *name)
    1393     97487080 :     : colorize (_colorize && pp_show_color (pp)), pp (pp)
    1394              :   {
    1395     97487080 :     pp_string (pp, colorize_start (colorize, name));
    1396     97487080 :   }
    1397     97487080 :   ~colorize_guard ()
    1398              :   {
    1399     97487080 :     pp_string (pp, colorize_stop (colorize));
    1400     97487080 :   }
    1401              : };
    1402              : 
    1403              : /* Print an IDENTIFIER_NODE that is the name of a declaration.  */
    1404              : 
    1405              : static void
    1406    197466212 : 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    197466212 :   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    197466185 :   if (dguide_name_p (t))
    1418              :     {
    1419          879 :       dump_decl (pp, CLASSTYPE_TI_TEMPLATE (TREE_TYPE (t)),
    1420              :                  TFF_UNQUALIFIED_NAME);
    1421          879 :       return;
    1422              :     }
    1423              : 
    1424    197465306 :   const char *str = IDENTIFIER_POINTER (t);
    1425    197465306 :   if (startswith (str, "_ZGR"))
    1426              :     {
    1427           15 :       pp_cxx_ws_string (pp, "<temporary>");
    1428           15 :       return;
    1429              :     }
    1430              : 
    1431    197465291 :   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    339902202 : dump_decl (cxx_pretty_printer *pp, tree t, int flags)
    1438              : {
    1439    339903764 :   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    339903764 :   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    339903764 :   switch (TREE_CODE (t))
    1455              :     {
    1456     51619378 :     case TYPE_DECL:
    1457              :       /* Don't say 'typedef class A' */
    1458     51619378 :       if (DECL_ARTIFICIAL (t) && !DECL_SELF_REFERENCE_P (t))
    1459              :         {
    1460     50285901 :           if ((flags & TFF_DECL_SPECIFIERS)
    1461     50285901 :               && 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     50285901 :           dump_type (pp, TREE_TYPE (t), flags);
    1472     50285901 :           break;
    1473              :         }
    1474      1333477 :       if (TYPE_DECL_ALIAS_P (t)
    1475      1333477 :           && (flags & TFF_DECL_SPECIFIERS
    1476       794669 :               || flags & TFF_CLASS_KEY_OR_ENUM))
    1477              :         {
    1478          502 :           pp_cxx_ws_string (pp, "using");
    1479          502 :           if (! (flags & TFF_UNQUALIFIED_NAME))
    1480          502 :             dump_scope (pp, CP_DECL_CONTEXT (t), flags);
    1481          502 :           dump_decl (pp, DECL_NAME (t), flags);
    1482          502 :           pp_cxx_whitespace (pp);
    1483          502 :           pp_cxx_ws_string (pp, "=");
    1484          502 :           pp_cxx_whitespace (pp);
    1485          526 :           dump_type (pp, (DECL_ORIGINAL_TYPE (t)
    1486           24 :                           ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t)),
    1487              :                      flags);
    1488          502 :           break;
    1489              :         }
    1490      1332975 :       if ((flags & TFF_DECL_SPECIFIERS)
    1491      1332975 :           && !DECL_SELF_REFERENCE_P (t))
    1492        12077 :         pp_cxx_ws_string (pp, "typedef");
    1493      1344951 :       dump_simple_decl (pp, t, DECL_ORIGINAL_TYPE (t)
    1494        11976 :                         ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
    1495              :                         flags);
    1496      1332975 :       break;
    1497              : 
    1498        43680 :     case VAR_DECL:
    1499        43680 :       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        75077 :     case FIELD_DECL:
    1508        75077 :     case PARM_DECL:
    1509        75077 :       dump_simple_decl (pp, t, TREE_TYPE (t), flags);
    1510              : 
    1511              :       /* Handle variable template specializations.  */
    1512        75077 :       if (VAR_P (t)
    1513        43680 :           && DECL_LANG_SPECIFIC (t)
    1514         7770 :           && DECL_TEMPLATE_INFO (t)
    1515        78592 :           && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
    1516              :         {
    1517         2663 :           pp_cxx_begin_template_argument_list (pp);
    1518         2663 :           tree args = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t));
    1519         2663 :           dump_template_argument_list (pp, args, flags);
    1520         2663 :           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     90091836 :     case NAMESPACE_DECL:
    1530     90091836 :       if (flags & TFF_DECL_SPECIFIERS)
    1531           93 :         pp->declaration (t);
    1532              :       else
    1533              :         {
    1534     90091743 :           if (! (flags & TFF_UNQUALIFIED_NAME))
    1535     90091722 :             dump_scope (pp, CP_DECL_CONTEXT (t), flags);
    1536     90091743 :           flags &= ~TFF_UNQUALIFIED_NAME;
    1537     90091743 :           if (DECL_NAME (t) == NULL_TREE)
    1538              :             {
    1539         8913 :               if (!(pp->flags & pp_c_flag_gnu_v3))
    1540         1605 :                 pp_cxx_ws_string (pp, M_("{anonymous}"));
    1541              :               else
    1542         7308 :                 pp_cxx_ws_string (pp, M_("(anonymous namespace)"));
    1543              :             }
    1544              :           else
    1545     90082830 :             pp_cxx_tree_identifier (pp, DECL_NAME (t));
    1546              :         }
    1547              :       break;
    1548              : 
    1549          988 :     case SCOPE_REF:
    1550          988 :       dump_type (pp, TREE_OPERAND (t, 0), flags);
    1551          988 :       pp_cxx_colon_colon (pp);
    1552          988 :       dump_decl (pp, TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME);
    1553          988 :       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         1866 :     case RECORD_TYPE:
    1564         1866 :     case UNION_TYPE:
    1565         1866 :     case ENUMERAL_TYPE:
    1566         1866 :       dump_type (pp, t, flags);
    1567         1866 :       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    197466212 :       break;
    1579              : 
    1580    197466212 :     case IDENTIFIER_NODE:
    1581    197466212 :       dump_decl_name (pp, t, flags);
    1582    197466212 :       break;
    1583              : 
    1584          317 :     case OVERLOAD:
    1585          317 :       if (!OVL_SINGLE_P (t))
    1586              :         {
    1587          126 :           tree ctx = ovl_scope (t);
    1588          126 :           if (ctx != global_namespace)
    1589              :             {
    1590           73 :               if (TYPE_P (ctx))
    1591           59 :                 dump_type (pp, ctx, flags);
    1592              :               else
    1593           14 :                 dump_decl (pp, ctx, flags);
    1594           73 :               pp_cxx_colon_colon (pp);
    1595              :             }
    1596          252 :           dump_decl (pp, OVL_NAME (t), flags);
    1597          126 :           break;
    1598              :         }
    1599              : 
    1600              :       /* If there's only one function, dump that.  */
    1601    339903764 :       return dump_decl (pp, OVL_FIRST (t), flags);
    1602              : 
    1603       160158 :     case FUNCTION_DECL:
    1604       160158 :       if (! DECL_LANG_SPECIFIC (t))
    1605              :         {
    1606         1380 :           if (DECL_ABSTRACT_ORIGIN (t)
    1607         1380 :               && DECL_ABSTRACT_ORIGIN (t) != t)
    1608          151 :             dump_decl (pp, DECL_ABSTRACT_ORIGIN (t), flags);
    1609              :           else
    1610         1229 :             dump_function_name (pp, t, flags);
    1611              :         }
    1612       158778 :       else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
    1613           69 :         dump_global_iord (pp, t);
    1614              :       else
    1615       158709 :         dump_function_decl (pp, t, flags);
    1616              :       break;
    1617              : 
    1618       482275 :     case TEMPLATE_DECL:
    1619       482275 :       dump_template_decl (pp, t, flags);
    1620       482275 :       break;
    1621              : 
    1622          418 :     case CONCEPT_DECL:
    1623          418 :       dump_simple_decl (pp, t, TREE_TYPE (t), flags);
    1624          418 :       break;
    1625              : 
    1626         2363 :     case TEMPLATE_ID_EXPR:
    1627         2363 :       {
    1628         2363 :         tree name = TREE_OPERAND (t, 0);
    1629         2363 :         tree args = TREE_OPERAND (t, 1);
    1630              : 
    1631         2363 :         if (TREE_CODE (name) == SPLICE_EXPR)
    1632           14 :           dump_expr (pp, name, flags);
    1633              :         else
    1634              :           {
    1635         2900 :             if (!identifier_p (name))
    1636         1663 :               name = OVL_NAME (name);
    1637         2349 :             dump_decl (pp, name, flags);
    1638              :           }
    1639         2363 :         pp_cxx_begin_template_argument_list (pp);
    1640         2363 :         if (args == error_mark_node)
    1641            0 :           pp_string (pp, M_("<template arguments error>"));
    1642         2363 :         else if (args)
    1643         2267 :           dump_template_argument_list
    1644         2267 :             (pp, args, flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
    1645         2363 :         pp_cxx_end_template_argument_list (pp);
    1646              :       }
    1647         2363 :       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         2185 :     case CONST_DECL:
    1657         4364 :       if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
    1658         3798 :           || (DECL_INITIAL (t) &&
    1659         1613 :               TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
    1660         2143 :         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           64 :     case BASELINK:
    1705           64 :       dump_decl (pp, BASELINK_FUNCTIONS (t), flags);
    1706           64 :       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       483926 : dump_template_decl (cxx_pretty_printer *pp, tree t, int flags)
    1736              : {
    1737       483926 :   tree orig_parms = DECL_TEMPLATE_PARMS (t);
    1738       483926 :   tree parms;
    1739       483926 :   int i;
    1740              : 
    1741       483926 :   if (flags & TFF_TEMPLATE_HEADER)
    1742              :     {
    1743         8494 :       for (parms = orig_parms = nreverse (orig_parms);
    1744        17532 :            parms;
    1745         9038 :            parms = TREE_CHAIN (parms))
    1746              :         {
    1747         9038 :           tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
    1748         9038 :           int len = TREE_VEC_LENGTH (inner_parms);
    1749              : 
    1750         9038 :           if (len == 0)
    1751              :             {
    1752              :               /* Skip over the dummy template levels of a template template
    1753              :                  parm.  */
    1754          302 :               gcc_assert (TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TEMPLATE_PARM);
    1755          302 :               continue;
    1756              :             }
    1757              : 
    1758         8736 :           pp_cxx_ws_string (pp, "template");
    1759         8736 :           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         8736 :             flags |= TFF_DECL_SPECIFIERS;
    1764              : 
    1765        21473 :           for (i = 0; i < len; i++)
    1766              :             {
    1767        12737 :               if (i)
    1768         4001 :                 pp_separate_with_comma (pp);
    1769        12737 :               dump_template_parameter (pp, TREE_VEC_ELT (inner_parms, i),
    1770              :                                        flags);
    1771              :             }
    1772         8736 :           pp_cxx_end_template_argument_list (pp);
    1773         8736 :           pp_cxx_whitespace (pp);
    1774              :         }
    1775         8494 :       nreverse(orig_parms);
    1776              : 
    1777         8494 :       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
    1778              :         {
    1779              :           /* Say `template<arg> class TT' not just `template<arg> TT'.  */
    1780          308 :           pp_cxx_ws_string (pp, "class");
    1781              : 
    1782              :           /* If this is a parameter pack, print the ellipsis.  */
    1783          308 :           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         8494 :       if (flag_concepts)
    1790         7524 :         if (tree ci = get_constraints (t))
    1791         2647 :           if (check_constraint_info (ci))
    1792         2647 :             if (tree reqs = CI_TEMPLATE_REQS (ci))
    1793              :               {
    1794         2177 :                 pp_cxx_requires_clause (pp, reqs);
    1795         2177 :                 pp_cxx_whitespace (pp);
    1796              :               }
    1797              :     }
    1798              : 
    1799              : 
    1800       483926 :   if (DECL_CLASS_TEMPLATE_P (t))
    1801       341216 :     dump_type (pp, TREE_TYPE (t),
    1802       341216 :                ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
    1803       341216 :                 | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
    1804       142710 :   else if (DECL_TEMPLATE_RESULT (t)
    1805       142710 :            && (VAR_P (DECL_TEMPLATE_RESULT (t))
    1806              :                /* Alias template.  */
    1807       142535 :                || DECL_TYPE_TEMPLATE_P (t)
    1808              :                /* Concept definition.  &*/
    1809         6966 :                || TREE_CODE (DECL_TEMPLATE_RESULT (t)) == CONCEPT_DECL))
    1810       136147 :     dump_decl (pp, DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
    1811              :   else
    1812              :     {
    1813         6563 :       gcc_assert (TREE_TYPE (t));
    1814         6563 :       switch (NEXT_CODE (t))
    1815              :         {
    1816         6563 :         case METHOD_TYPE:
    1817         6563 :         case FUNCTION_TYPE:
    1818         6563 :           dump_function_decl (pp, t, flags | TFF_TEMPLATE_NAME);
    1819         6563 :           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       483926 : }
    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       419170 : find_typenames_r (tree *tp, int *walk_subtrees, void *data)
    1842              : {
    1843       419170 :   struct find_typenames_t *d = (struct find_typenames_t *)data;
    1844       419170 :   tree mv = NULL_TREE;
    1845              : 
    1846       419170 :   if (TYPE_P (*tp) && is_typedef_decl (TYPE_NAME (*tp)))
    1847              :     /* Add the type of the typedef without any additional cv-quals.  */
    1848        11865 :     mv = TREE_TYPE (TYPE_NAME (*tp));
    1849       407305 :   else if (TREE_CODE (*tp) == TYPENAME_TYPE
    1850       406719 :            || TREE_CODE (*tp) == DECLTYPE_TYPE)
    1851              :     /* Add the typename without any cv-qualifiers.  */
    1852          761 :     mv = TYPE_MAIN_VARIANT (*tp);
    1853              : 
    1854       419170 :   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         2492 :       *walk_subtrees = false;
    1859         2492 :       return NULL_TREE;
    1860              :     }
    1861              : 
    1862       416678 :   if (mv && (mv == *tp || !d->p_set->add (mv)))
    1863        12610 :     vec_safe_push (d->typenames, mv);
    1864              : 
    1865              :   return NULL_TREE;
    1866              : }
    1867              : 
    1868              : static vec<tree, va_gc> *
    1869        48558 : find_typenames (tree t)
    1870              : {
    1871        48558 :   struct find_typenames_t ft;
    1872        48558 :   ft.p_set = new hash_set<tree>;
    1873        48558 :   ft.typenames = NULL;
    1874        48558 :   cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
    1875              :                 find_typenames_r, &ft, ft.p_set);
    1876        97116 :   delete ft.p_set;
    1877        48558 :   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       845007 : dump_substitution (cxx_pretty_printer *pp,
    1887              :                    tree t, tree template_parms, tree template_args,
    1888              :                    int flags)
    1889              : {
    1890       845007 :   if (template_parms != NULL_TREE && template_args != NULL_TREE
    1891        50209 :       && !(flags & TFF_NO_TEMPLATE_BINDINGS))
    1892              :     {
    1893        50209 :       vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
    1894        50209 :       dump_template_bindings (pp, template_parms, template_args, typenames);
    1895              :     }
    1896       845007 : }
    1897              : 
    1898              : /* Dump the lambda function FN including its 'mutable' qualifier and any
    1899              :    template bindings.  */
    1900              : 
    1901              : static void
    1902        99909 : 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        99909 :   dump_type (pp, DECL_CONTEXT (fn), flags);
    1908        99909 :   if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    1909              :     /* Early escape.  */;
    1910        99870 :   else if (TREE_CODE (TREE_TYPE (fn)) == FUNCTION_TYPE)
    1911              :     {
    1912          376 :       pp->set_padding (pp_before);
    1913          376 :       pp_c_ws_string (pp, "static");
    1914              :     }
    1915        99494 :   else if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn)))
    1916        99494 :              & TYPE_QUAL_CONST))
    1917              :     {
    1918           89 :       pp->set_padding (pp_before);
    1919           89 :       pp_c_ws_string (pp, "mutable");
    1920              :     }
    1921        99909 :   dump_substitution (pp, fn, template_parms, template_args, flags);
    1922        99909 : }
    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       860560 : dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
    1931              : {
    1932       860560 :   tree fntype;
    1933       860560 :   tree parmtypes;
    1934       860560 :   tree cname = NULL_TREE;
    1935       860560 :   tree template_args = NULL_TREE;
    1936       860560 :   tree template_parms = NULL_TREE;
    1937       860560 :   int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
    1938       860560 :   int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
    1939       860560 :   tree exceptions;
    1940       860560 :   bool constexpr_p;
    1941       860560 :   tree ret = NULL_TREE;
    1942              : 
    1943       860560 :   int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME;
    1944       860560 :   flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME;
    1945       860560 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1946         6563 :     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       860560 :   exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t));
    1951              : 
    1952              :   /* Likewise for the constexpr specifier, in case t is a specialization.  */
    1953       860560 :   constexpr_p = (DECL_DECLARED_CONSTEXPR_P (t)
    1954       860560 :                  && !decl_implicit_constexpr_p (t));
    1955              : 
    1956              :   /* Pretty print template instantiations only.  */
    1957      1276046 :   if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t)
    1958       415432 :       && !(flags & TFF_NO_TEMPLATE_BINDINGS)
    1959       909170 :       && flag_pretty_templates)
    1960              :     {
    1961        48583 :       tree tmpl;
    1962              : 
    1963        48583 :       template_args = DECL_TI_ARGS (t);
    1964        48583 :       tmpl = most_general_template (t);
    1965        48583 :       if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
    1966              :         {
    1967        48558 :           template_parms = DECL_TEMPLATE_PARMS (tmpl);
    1968        48558 :           t = tmpl;
    1969              :         }
    1970              :     }
    1971              : 
    1972       963937 :   if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
    1973        99909 :     return dump_lambda_function (pp, t, template_parms, template_args, flags);
    1974              : 
    1975       760651 :   fntype = TREE_TYPE (t);
    1976       760651 :   parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
    1977              : 
    1978       760651 :   if (DECL_CLASS_SCOPE_P (t))
    1979       313466 :     cname = DECL_CONTEXT (t);
    1980              :   /* This is for partially instantiated template methods.  */
    1981       447185 :   else if (TREE_CODE (fntype) == METHOD_TYPE)
    1982            3 :     cname = TREE_TYPE (TREE_VALUE (parmtypes));
    1983              : 
    1984       760651 :   if (flags & TFF_DECL_SPECIFIERS)
    1985              :     {
    1986       144439 :       if (DECL_STATIC_FUNCTION_P (t))
    1987         3819 :         pp_cxx_ws_string (pp, "static");
    1988       140620 :       else if (DECL_VIRTUAL_P (t))
    1989         2721 :         pp_cxx_ws_string (pp, "virtual");
    1990              : 
    1991       144439 :       if (constexpr_p)
    1992              :         {
    1993       107634 :           if (DECL_IMMEDIATE_FUNCTION_P (t))
    1994          525 :             pp_cxx_ws_string (pp, "consteval");
    1995              :           else
    1996        53292 :             pp_cxx_ws_string (pp, "constexpr");
    1997              :         }
    1998              :     }
    1999              : 
    2000              :   /* Print the return type?  */
    2001       760651 :   if (show_return)
    2002       432409 :     show_return = (!DECL_CONV_FN_P (t)  && !DECL_CONSTRUCTOR_P (t)
    2003       278477 :                    && !DECL_DESTRUCTOR_P (t) && !deduction_guide_p (t));
    2004              :   if (show_return)
    2005              :     {
    2006       132242 :       ret = fndecl_declared_return_type (t);
    2007       132242 :       dump_type_prefix (pp, ret, flags);
    2008              :     }
    2009              : 
    2010              :   /* Print the function name.  */
    2011       760651 :   if (!do_outer_scope)
    2012              :     /* Nothing.  */;
    2013       760651 :   else if (cname)
    2014              :     {
    2015       313466 :       dump_type (pp, cname, flags);
    2016       313466 :       pp_cxx_colon_colon (pp);
    2017              :     }
    2018              :   else
    2019       447185 :     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       760651 :   auto cds = make_temp_override (current_dump_scope, CP_DECL_CONTEXT (t));
    2024              : 
    2025       760651 :   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       760651 :   pp->set_padding (pp_none);
    2030       760651 :   pp_cxx_function_target_version (pp, t);
    2031       760651 :   pp_cxx_maybe_whitespace (pp);
    2032       760651 :   pp_cxx_function_target_clones (pp, t);
    2033       760651 :   pp_cxx_maybe_whitespace (pp);
    2034              : 
    2035       760651 :   if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
    2036              :     {
    2037       743447 :       int const parm_flags
    2038       743447 :         = DECL_XOBJ_MEMBER_FUNCTION_P (t) ? TFF_XOBJ_FUNC | flags : flags;
    2039       743447 :       dump_parameters (pp, parmtypes, parm_flags);
    2040              : 
    2041       743447 :       if (TREE_CODE (fntype) == METHOD_TYPE)
    2042              :         {
    2043       305091 :           pp->set_padding (pp_before);
    2044       305091 :           pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
    2045       305091 :           dump_ref_qualifier (pp, fntype, flags);
    2046              :         }
    2047              : 
    2048       743447 :       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       743447 :       if (flags & TFF_EXCEPTION_SPECIFICATION)
    2055              :         {
    2056          372 :           pp->set_padding (pp_before);
    2057          372 :           dump_exception_spec (pp, exceptions, flags);
    2058              :         }
    2059              : 
    2060       743447 :       if (show_return)
    2061       132242 :         dump_type_suffix (pp, ret, flags);
    2062       611205 :       else if (deduction_guide_p (t))
    2063              :         {
    2064          681 :           pp->set_padding (pp_before);
    2065          681 :           pp_cxx_ws_string (pp, "->");
    2066          681 :           dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
    2067              :         }
    2068              : 
    2069       743447 :       if (flag_concepts)
    2070       716233 :         if (tree ci = get_constraints (t))
    2071       354650 :           if (tree reqs = CI_DECLARATOR_REQS (ci))
    2072        17711 :             pp_cxx_requires_clause (pp, reqs);
    2073              : 
    2074       743447 :       dump_substitution (pp, t, template_parms, template_args, flags);
    2075              : 
    2076      1486894 :       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        17204 :   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       760651 : }
    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      2034485 : dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags)
    2111              : {
    2112      2034485 :   int first = 1;
    2113      2034485 :   flags &= ~TFF_SCOPE;
    2114      2034485 :   pp_cxx_left_paren (pp);
    2115              : 
    2116      6316358 :   for (first = 1; parmtypes != void_list_node;
    2117      2247388 :        parmtypes = TREE_CHAIN (parmtypes))
    2118              :     {
    2119      2249531 :       if (first && flags & TFF_XOBJ_FUNC)
    2120         1635 :         pp_string (pp, "this ");
    2121              :       if (!first)
    2122       955873 :         pp_separate_with_comma (pp);
    2123      2249531 :       first = 0;
    2124      2249531 :       if (!parmtypes)
    2125              :         {
    2126         2143 :           pp_cxx_ws_string (pp, "...");
    2127         2143 :           break;
    2128              :         }
    2129              : 
    2130      2247388 :       dump_type (pp, TREE_VALUE (parmtypes), flags);
    2131              : 
    2132      2247419 :       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      2034485 :   pp_cxx_right_paren (pp);
    2142      2034485 : }
    2143              : 
    2144              : /* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */
    2145              : 
    2146              : static void
    2147      1005868 : dump_ref_qualifier (cxx_pretty_printer *pp, tree t, int flags ATTRIBUTE_UNUSED)
    2148              : {
    2149      1005868 :   if (FUNCTION_REF_QUALIFIED (t))
    2150              :     {
    2151         1636 :       pp->set_padding (pp_before);
    2152         1636 :       if (FUNCTION_RVALUE_QUALIFIED (t))
    2153          466 :         pp_cxx_ws_string (pp, "&&");
    2154              :       else
    2155         1170 :         pp_cxx_ws_string (pp, "&");
    2156              :     }
    2157      1005868 : }
    2158              : 
    2159              : /* Print an exception specification. T is the exception specification.  */
    2160              : 
    2161              : static void
    2162       701216 : dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags)
    2163              : {
    2164       708191 :   if (t && TREE_PURPOSE (t))
    2165              :     {
    2166         6877 :       pp_cxx_ws_string (pp, "noexcept");
    2167         6877 :       if (!integer_onep (TREE_PURPOSE (t)))
    2168              :         {
    2169          153 :           pp_cxx_whitespace (pp);
    2170          153 :           pp_cxx_left_paren (pp);
    2171          153 :           if (DEFERRED_NOEXCEPT_SPEC_P (t))
    2172           19 :             pp_cxx_ws_string (pp, "<uninstantiated>");
    2173              :           else
    2174          134 :             dump_expr (pp, TREE_PURPOSE (t), flags);
    2175          153 :           pp_cxx_right_paren (pp);
    2176              :         }
    2177              :     }
    2178       694339 :   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       701216 : }
    2195              : 
    2196              : /* Handle the function name for a FUNCTION_DECL node, grokking operators
    2197              :    and destructors properly.  */
    2198              : 
    2199              : static void
    2200     97487080 : 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     97487080 :   bool colorize = flags & (TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE
    2205              :                            | TFF_TEMPLATE_HEADER);
    2206              : 
    2207     97487080 :   colorize_guard g (colorize, pp, "fnname");
    2208              : 
    2209     97487080 :   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     97487080 :   if (!DECL_LANG_SPECIFIC (t))
    2217              :     {
    2218         6176 :       pp_cxx_tree_identifier (pp, name);
    2219         6176 :       return;
    2220              :     }
    2221              : 
    2222     97480904 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    2223        46453 :     t = DECL_TEMPLATE_RESULT (t);
    2224              : 
    2225              :   /* Don't let the user see __comp_ctor et al.  */
    2226     97480904 :   if (DECL_CONSTRUCTOR_P (t)
    2227     97480904 :       || DECL_DESTRUCTOR_P (t))
    2228              :     {
    2229     37992387 :       if (LAMBDA_TYPE_P (DECL_CONTEXT (t)))
    2230       269606 :         name = get_identifier ("<lambda>");
    2231     37484146 :       else if (TYPE_UNNAMED_P (DECL_CONTEXT (t)))
    2232          118 :         name = get_identifier ("<constructor>");
    2233              :       else
    2234     18741896 :         name = constructor_name (DECL_CONTEXT (t));
    2235              :     }
    2236              : 
    2237    194961808 :   if (DECL_DESTRUCTOR_P (t))
    2238              :     {
    2239      2366253 :       pp_cxx_complement (pp);
    2240      2366253 :       dump_decl (pp, name, TFF_PLAIN_IDENTIFIER);
    2241              :     }
    2242     95114651 :   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      1587346 :       pp_cxx_ws_string (pp, "operator");
    2251      1587346 :       dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
    2252              :     }
    2253              :   else
    2254     93527305 :     dump_decl (pp, name, flags);
    2255              : 
    2256     97480904 :   dump_module_suffix (pp, t);
    2257              : 
    2258     97480904 :   if (DECL_TEMPLATE_INFO (t)
    2259     75332184 :       && !(flags & TFF_TEMPLATE_NAME)
    2260     75325944 :       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
    2261    172739342 :       && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
    2262     75258413 :           || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
    2263       741286 :     dump_template_parms (pp, DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t),
    2264              :                          flags);
    2265     97487080 : }
    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     93865674 : dump_template_parms (cxx_pretty_printer *pp, tree info,
    2275              :                      int primary, int flags)
    2276              : {
    2277    187731348 :   tree args = info ? TI_ARGS (info) : NULL_TREE;
    2278              : 
    2279     93865674 :   if (primary && flags & TFF_TEMPLATE_NAME)
    2280              :     return;
    2281     93524414 :   flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
    2282     93524414 :   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     93524414 :   if (args && !primary)
    2287              :     {
    2288     93500154 :       int len, ix;
    2289     93500154 :       len = get_non_default_template_args_count (args, flags);
    2290              : 
    2291     93500154 :       args = INNERMOST_TEMPLATE_ARGS (args);
    2292    330946248 :       for (ix = 0; ix != len; ix++)
    2293              :         {
    2294    143945940 :           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    143945940 :           if (ix
    2300    143945940 :               && (!ARGUMENT_PACK_P (arg)
    2301      3375344 :                   || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
    2302     50039987 :             pp_separate_with_comma (pp);
    2303              : 
    2304    143945940 :           if (!arg)
    2305            0 :             pp_string (pp, M_("<template parameter error>"));
    2306              :           else
    2307    143945940 :             dump_template_argument (pp, arg, flags);
    2308              :         }
    2309              :     }
    2310        24260 :   else if (primary)
    2311              :     {
    2312        24254 :       tree tpl = TI_TEMPLATE (info);
    2313        24254 :       tree parms = DECL_TEMPLATE_PARMS (tpl);
    2314        24254 :       int len, ix;
    2315              : 
    2316        24254 :       parms = TREE_CODE (parms) == TREE_LIST ? TREE_VALUE (parms) : NULL_TREE;
    2317        48508 :       len = parms ? TREE_VEC_LENGTH (parms) : 0;
    2318              : 
    2319        65485 :       for (ix = 0; ix != len; ix++)
    2320              :         {
    2321        41231 :           tree parm;
    2322              : 
    2323        41231 :           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        41231 :           parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
    2330              : 
    2331        41231 :           if (ix)
    2332        16977 :             pp_separate_with_comma (pp);
    2333              : 
    2334        41231 :           dump_decl (pp, parm, flags & ~TFF_DECL_SPECIFIERS);
    2335              :         }
    2336              :     }
    2337     93524414 :   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         8173 : dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst)
    2345              : {
    2346         8173 :   const int len = call_expr_nargs (t);
    2347              : 
    2348         8173 :   pp_cxx_left_paren (pp);
    2349        16868 :   for (int i = skipfirst; i < len; ++i)
    2350              :     {
    2351         8695 :       tree arg = get_nth_callarg (t, i);
    2352         8695 :       dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
    2353         8695 :       if (i + 1 < len)
    2354         2778 :         pp_separate_with_comma (pp);
    2355              :     }
    2356         8173 :   pp_cxx_right_paren (pp);
    2357         8173 : }
    2358              : 
    2359              : /* Print out a list of initializers (subr of dump_expr).  */
    2360              : 
    2361              : static void
    2362          216 : dump_expr_list (cxx_pretty_printer *pp, tree l, int flags)
    2363              : {
    2364          244 :   while (l)
    2365              :     {
    2366          134 :       dump_expr (pp, TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
    2367          134 :       l = TREE_CHAIN (l);
    2368          134 :       if (l)
    2369           28 :         pp_separate_with_comma (pp);
    2370              :     }
    2371          216 : }
    2372              : 
    2373              : /* Print out a vector of initializers (subr of dump_expr).  */
    2374              : 
    2375              : static void
    2376         7840 : dump_expr_init_vec (cxx_pretty_printer *pp, vec<constructor_elt, va_gc> *v,
    2377              :                     int flags)
    2378              : {
    2379         7840 :   unsigned HOST_WIDE_INT idx;
    2380         7840 :   tree value;
    2381              : 
    2382        19161 :   FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
    2383              :     {
    2384        11321 :       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        11321 :         dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS);
    2404        11321 :       if (idx != v->length () - 1)
    2405         3535 :         pp_separate_with_comma (pp);
    2406              :     }
    2407         7840 : }
    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          147 : resolve_virtual_fun_from_obj_type_ref (tree ref)
    2417              : {
    2418          147 :   tree obj_type = TREE_TYPE (OBJ_TYPE_REF_TOKEN (ref));
    2419          147 :   HOST_WIDE_INT index = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (ref));
    2420          147 :   tree fun = BINFO_VIRTUALS (TYPE_BINFO (TREE_TYPE (obj_type)));
    2421          288 :   while (index)
    2422              :     {
    2423          141 :       fun = TREE_CHAIN (fun);
    2424          141 :       index -= (TARGET_VTABLE_USES_DESCRIPTORS
    2425              :                 ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
    2426              :     }
    2427              : 
    2428          147 :   return BV_FN (fun);
    2429              : }
    2430              : 
    2431              : /* Print out an expression E under control of FLAGS.  */
    2432              : 
    2433              : static void
    2434     23812469 : dump_expr (cxx_pretty_printer *pp, tree t, int flags)
    2435              : {
    2436     23834648 :   tree op;
    2437              : 
    2438     23834648 :   if (t == 0)
    2439              :     return;
    2440              : 
    2441     23834604 :   if (STATEMENT_CLASS_P (t))
    2442              :     {
    2443           15 :       pp_cxx_ws_string (pp, M_("<statement>"));
    2444           15 :       return;
    2445              :     }
    2446              : 
    2447     23834589 :   switch (TREE_CODE (t))
    2448              :     {
    2449        69964 :     case VAR_DECL:
    2450        69964 :     case PARM_DECL:
    2451        69964 :     case FIELD_DECL:
    2452        69964 :     case CONST_DECL:
    2453        69964 :     case FUNCTION_DECL:
    2454        69964 :     case TEMPLATE_DECL:
    2455        69964 :     case NAMESPACE_DECL:
    2456        69964 :     case LABEL_DECL:
    2457        69964 :     case OVERLOAD:
    2458        69964 :     case TYPE_DECL:
    2459        69964 :     case USING_DECL:
    2460        69964 :     case IDENTIFIER_NODE:
    2461        69964 :       dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
    2462              :                                     |TFF_TEMPLATE_HEADER))
    2463              :                          | TFF_NO_TEMPLATE_BINDINGS
    2464        69964 :                          | TFF_NO_FUNCTION_ARGUMENTS));
    2465        69964 :       break;
    2466              : 
    2467         6475 :     case SSA_NAME:
    2468         6475 :       if (SSA_NAME_VAR (t)
    2469         6403 :           && !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     23689589 :     case INTEGER_CST:
    2476     23689589 :       if (TYPE_PTRDATAMEM_P (TREE_TYPE (t)) && integer_all_onesp (t))
    2477              :         {
    2478              :           /* OFFSET_TYPE -1 is a null pointer to member.  */
    2479           34 :           if (flags & TFF_EXPR_IN_PARENS)
    2480           27 :             pp_cxx_left_paren (pp);
    2481           34 :           pp_cxx_left_paren (pp);
    2482           34 :           dump_type (pp, TREE_TYPE (t), flags);
    2483           34 :           pp_cxx_right_paren (pp);
    2484           34 :           pp->constant (cxx_dialect < cxx11 ? null_pointer_node : nullptr_node);
    2485           34 :           if (flags & TFF_EXPR_IN_PARENS)
    2486           27 :             pp_cxx_right_paren (pp);
    2487              :           break;
    2488              :         }
    2489              :       /* FALLTHRU */
    2490              : 
    2491     23691504 :     case VOID_CST:
    2492     23691504 :     case REAL_CST:
    2493     23691504 :     case STRING_CST:
    2494     23691504 :     case COMPLEX_CST:
    2495     23691504 :       pp->constant (t);
    2496     23691504 :       break;
    2497              : 
    2498            0 :     case USERDEF_LITERAL:
    2499            0 :       pp_cxx_userdef_literal (pp, t);
    2500            0 :       break;
    2501              : 
    2502          115 :     case THROW_EXPR:
    2503              :       /* While waiting for caret diagnostics, avoid printing
    2504              :          __cxa_allocate_exception, __cxa_throw, and the like.  */
    2505          115 :       pp_cxx_ws_string (pp, M_("<throw-expression>"));
    2506          115 :       break;
    2507              : 
    2508          676 :     case PTRMEM_CST:
    2509          676 :       pp_ampersand (pp);
    2510          676 :       dump_type (pp, PTRMEM_CST_CLASS (t), flags);
    2511          676 :       pp_cxx_colon_colon (pp);
    2512          676 :       pp_cxx_tree_identifier (pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
    2513          676 :       break;
    2514              : 
    2515          791 :     case COMPOUND_EXPR:
    2516          791 :       pp_cxx_left_paren (pp);
    2517          791 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2518          791 :       pp_separate_with_comma (pp);
    2519          791 :       dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    2520          791 :       pp_cxx_right_paren (pp);
    2521          791 :       break;
    2522              : 
    2523           61 :     case COND_EXPR:
    2524           61 :     case VEC_COND_EXPR:
    2525           61 :       pp_cxx_left_paren (pp);
    2526           61 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2527           61 :       pp_string (pp, " ? ");
    2528           61 :       dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    2529           61 :       pp_string (pp, " : ");
    2530           61 :       dump_expr (pp, TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
    2531           61 :       pp_cxx_right_paren (pp);
    2532           61 :       break;
    2533              : 
    2534          248 :     case SAVE_EXPR:
    2535          248 :       if (TREE_HAS_CONSTRUCTOR (t))
    2536              :         {
    2537            0 :           pp_cxx_ws_string (pp, "new");
    2538            0 :           pp_cxx_whitespace (pp);
    2539            0 :           dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
    2540              :         }
    2541              :       else
    2542          248 :         dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2543              :       break;
    2544              : 
    2545         8173 :     case AGGR_INIT_EXPR:
    2546         8173 :     case CALL_EXPR:
    2547         8173 :       {
    2548         8173 :         tree fn = cp_get_callee (t);
    2549         8173 :         bool skipfirst = false;
    2550              : 
    2551              :         /* Deal with internal functions.  */
    2552         8173 :         if (fn == NULL_TREE)
    2553              :           {
    2554            3 :             pp_string (pp, internal_fn_name (CALL_EXPR_IFN (t)));
    2555            3 :             dump_call_expr_args (pp, t, flags, skipfirst);
    2556            3 :             break;
    2557              :           }
    2558              : 
    2559         8170 :         if (TREE_CODE (fn) == ADDR_EXPR)
    2560         7330 :           fn = TREE_OPERAND (fn, 0);
    2561              : 
    2562              :         /* Nobody is interested in seeing the guts of vcalls.  */
    2563         8170 :         if (TREE_CODE (fn) == OBJ_TYPE_REF)
    2564          141 :           fn = resolve_virtual_fun_from_obj_type_ref (fn);
    2565              : 
    2566         8170 :         if (TREE_TYPE (fn) != NULL_TREE
    2567         7958 :             && NEXT_CODE (fn) == METHOD_TYPE
    2568        10887 :             && call_expr_nargs (t))
    2569              :           {
    2570         2714 :             tree ob = get_nth_callarg (t, 0);
    2571         2714 :             if (is_dummy_object (ob))
    2572              :               /* Don't print dummy object.  */;
    2573         2020 :             else if (TREE_CODE (ob) == ADDR_EXPR)
    2574              :               {
    2575         1373 :                 dump_expr (pp, TREE_OPERAND (ob, 0),
    2576              :                            flags | TFF_EXPR_IN_PARENS);
    2577         1373 :                 pp_cxx_dot (pp);
    2578              :               }
    2579          647 :             else if (!is_this_parameter (ob))
    2580              :               {
    2581          647 :                 dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    2582          647 :                 pp_cxx_arrow (pp);
    2583              :               }
    2584              :             skipfirst = true;
    2585              :           }
    2586         8170 :         if (flag_sanitize & SANITIZE_UNDEFINED
    2587         8170 :             && is_ubsan_builtin_p (fn))
    2588              :           {
    2589            0 :             pp_string (cxx_pp, M_("<ubsan routine call>"));
    2590            0 :             break;
    2591              :           }
    2592              : 
    2593         8170 :         if (TREE_CODE (fn) == FUNCTION_DECL
    2594         7505 :             && DECL_CONSTRUCTOR_P (fn)
    2595         9126 :             && is_dummy_object (get_nth_callarg (t, 0)))
    2596          694 :           dump_type (pp, DECL_CONTEXT (fn), flags);
    2597              :         else
    2598         7476 :           dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS);
    2599         8170 :         dump_call_expr_args (pp, t, flags, skipfirst);
    2600              :       }
    2601         8170 :       break;
    2602              : 
    2603         2221 :     case TARGET_EXPR:
    2604              :       /* Note that this only works for G++ target exprs.  If somebody
    2605              :          builds a general TARGET_EXPR, there's no way to represent that
    2606              :          it initializes anything other that the parameter slot for the
    2607              :          default argument.  Note we may have cleared out the first
    2608              :          operand in expand_expr, so don't go killing ourselves.  */
    2609         2221 :       if (TARGET_EXPR_INITIAL (t))
    2610         2221 :         dump_expr (pp, TARGET_EXPR_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
    2611              :       break;
    2612              : 
    2613          313 :     case POINTER_PLUS_EXPR:
    2614          313 :       dump_binary_op (pp, "+", t, flags);
    2615          313 :       break;
    2616              : 
    2617            2 :     case POINTER_DIFF_EXPR:
    2618            2 :       dump_binary_op (pp, "-", t, flags);
    2619            2 :       break;
    2620              : 
    2621           24 :     case INIT_EXPR:
    2622           24 :     case MODIFY_EXPR:
    2623           24 :       dump_binary_op (pp, OVL_OP_INFO (true, NOP_EXPR)->name, t, flags);
    2624           24 :       break;
    2625              : 
    2626         1894 :     case PLUS_EXPR:
    2627         1894 :     case MINUS_EXPR:
    2628         1894 :     case MULT_EXPR:
    2629         1894 :     case TRUNC_DIV_EXPR:
    2630         1894 :     case TRUNC_MOD_EXPR:
    2631         1894 :     case MIN_EXPR:
    2632         1894 :     case MAX_EXPR:
    2633         1894 :     case LSHIFT_EXPR:
    2634         1894 :     case RSHIFT_EXPR:
    2635         1894 :     case BIT_IOR_EXPR:
    2636         1894 :     case BIT_XOR_EXPR:
    2637         1894 :     case BIT_AND_EXPR:
    2638         1894 :     case TRUTH_ANDIF_EXPR:
    2639         1894 :     case TRUTH_ORIF_EXPR:
    2640         1894 :     case LT_EXPR:
    2641         1894 :     case LE_EXPR:
    2642         1894 :     case GT_EXPR:
    2643         1894 :     case GE_EXPR:
    2644         1894 :     case EQ_EXPR:
    2645         1894 :     case NE_EXPR:
    2646         1894 :     case SPACESHIP_EXPR:
    2647         1894 :       dump_binary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags);
    2648         1894 :       break;
    2649              : 
    2650           81 :     case CEIL_DIV_EXPR:
    2651           81 :     case FLOOR_DIV_EXPR:
    2652           81 :     case ROUND_DIV_EXPR:
    2653           81 :     case RDIV_EXPR:
    2654           81 :     case EXACT_DIV_EXPR:
    2655           81 :       dump_binary_op (pp, "/", t, flags);
    2656           81 :       break;
    2657              : 
    2658            0 :     case CEIL_MOD_EXPR:
    2659            0 :     case FLOOR_MOD_EXPR:
    2660            0 :     case ROUND_MOD_EXPR:
    2661            0 :       dump_binary_op (pp, "%", t, flags);
    2662            0 :       break;
    2663              : 
    2664         1901 :     case COMPONENT_REF:
    2665         1901 :       {
    2666         1901 :         tree ob = TREE_OPERAND (t, 0);
    2667         1901 :         if (INDIRECT_REF_P (ob))
    2668              :           {
    2669          875 :             ob = TREE_OPERAND (ob, 0);
    2670          875 :             if (!is_this_parameter (ob)
    2671          875 :                 && !is_dummy_object (ob))
    2672              :               {
    2673          851 :                 dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    2674          851 :                 if (TYPE_REF_P (TREE_TYPE (ob)))
    2675          237 :                   pp_cxx_dot (pp);
    2676              :                 else
    2677          614 :                   pp_cxx_arrow (pp);
    2678              :               }
    2679              :           }
    2680              :         else
    2681              :           {
    2682         1026 :             dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    2683         1026 :             if (TREE_CODE (ob) != ARROW_EXPR)
    2684         1023 :               pp_cxx_dot (pp);
    2685              :           }
    2686         1901 :         dump_expr (pp, TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
    2687              :       }
    2688         1901 :       break;
    2689              : 
    2690          289 :     case ARRAY_REF:
    2691          289 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2692          289 :       pp_cxx_left_bracket (pp);
    2693          289 :       dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    2694          289 :       pp_cxx_right_bracket (pp);
    2695          289 :       break;
    2696              : 
    2697           33 :     case OMP_ARRAY_SECTION:
    2698           33 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    2699           33 :       pp_cxx_left_bracket (pp);
    2700           33 :       dump_expr (pp, TREE_OPERAND (t, 1), flags);
    2701           33 :       pp_colon (pp);
    2702           33 :       dump_expr (pp, TREE_OPERAND (t, 2), flags);
    2703           33 :       pp_cxx_right_bracket (pp);
    2704           33 :       break;
    2705              : 
    2706            0 :     case UNARY_PLUS_EXPR:
    2707            0 :       dump_unary_op (pp, "+", t, flags);
    2708            0 :       break;
    2709              : 
    2710         4343 :     case ADDR_EXPR:
    2711         4343 :       if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
    2712         3154 :           || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
    2713              :           /* An ADDR_EXPR can have reference type.  In that case, we
    2714              :              shouldn't print the `&' doing so indicates to the user
    2715              :              that the expression has pointer type.  */
    2716         7401 :           || (TREE_TYPE (t)
    2717         3058 :               && TYPE_REF_P (TREE_TYPE (t))))
    2718         1332 :         dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2719         3011 :       else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL)
    2720            3 :         dump_unary_op (pp, "&&", t, flags);
    2721              :       else
    2722         3008 :         dump_unary_op (pp, "&", t, flags);
    2723              :       break;
    2724              : 
    2725          715 :     case INDIRECT_REF:
    2726          715 :       if (TREE_HAS_CONSTRUCTOR (t))
    2727              :         {
    2728            0 :           t = TREE_OPERAND (t, 0);
    2729            0 :           gcc_assert (TREE_CODE (t) == CALL_EXPR);
    2730            0 :           dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
    2731            0 :           dump_call_expr_args (pp, t, flags, true);
    2732              :         }
    2733          715 :       else if (is_stub_object (t))
    2734              :         {
    2735           18 :           pp_string (pp, "std::declval<");
    2736           18 :           if (lvalue_p (t)) /* T& */
    2737            0 :             dump_type (pp, TREE_TYPE (STRIP_REFERENCE_REF (t)), flags);
    2738              :           else /* T */
    2739           18 :             dump_type (pp, TREE_TYPE (t), flags);
    2740           18 :           pp_string (pp, ">()");
    2741              :         }
    2742              :       else
    2743              :         {
    2744          697 :           if (TREE_OPERAND (t,0) != NULL_TREE
    2745          697 :               && TREE_TYPE (TREE_OPERAND (t, 0))
    2746         1386 :               && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
    2747          428 :             dump_expr (pp, TREE_OPERAND (t, 0), flags);
    2748              :           else
    2749          269 :             dump_unary_op (pp, "*", t, flags);
    2750              :         }
    2751              :       break;
    2752              : 
    2753          575 :     case MEM_REF:
    2754              :       /* Delegate to the base "C" pretty printer.  */
    2755          575 :       pp->c_pretty_printer::unary_expression (t);
    2756          575 :       break;
    2757              : 
    2758            0 :     case TARGET_MEM_REF:
    2759              :       /* TARGET_MEM_REF can't appear directly from source, but can appear
    2760              :          during late GIMPLE optimizations and through late diagnostic we might
    2761              :          need to support it.  Print it as dereferencing of a pointer after
    2762              :          cast to the TARGET_MEM_REF type, with pointer arithmetics on some
    2763              :          pointer to single byte types, so
    2764              :          *(type *)((char *) ptr + step * index + index2) if all the operands
    2765              :          are present and the casts are needed.  */
    2766            0 :       pp_cxx_star (pp);
    2767            0 :       pp_cxx_left_paren (pp);
    2768            0 :       if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (t)))) == NULL_TREE
    2769            0 :           || !integer_onep (TYPE_SIZE_UNIT
    2770              :                                 (TREE_TYPE (TREE_TYPE (TMR_BASE (t))))))
    2771              :         {
    2772            0 :           if (TYPE_SIZE_UNIT (TREE_TYPE (t))
    2773            0 :               && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (t))))
    2774              :             {
    2775            0 :               pp_cxx_left_paren (pp);
    2776            0 :               dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
    2777              :             }
    2778              :           else
    2779              :             {
    2780            0 :               dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
    2781            0 :               pp_cxx_right_paren (pp);
    2782            0 :               pp_cxx_left_paren (pp);
    2783            0 :               pp_cxx_left_paren (pp);
    2784            0 :               dump_type (pp, build_pointer_type (char_type_node), flags);
    2785              :             }
    2786            0 :           pp_cxx_right_paren (pp);
    2787              :         }
    2788            0 :       else if (!same_type_p (TREE_TYPE (t),
    2789              :                              TREE_TYPE (TREE_TYPE (TMR_BASE (t)))))
    2790              :         {
    2791            0 :           dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags);
    2792            0 :           pp_cxx_right_paren (pp);
    2793            0 :           pp_cxx_left_paren (pp);
    2794              :         }
    2795            0 :       dump_expr (pp, TMR_BASE (t), flags);
    2796            0 :       if (TMR_STEP (t) && TMR_INDEX (t))
    2797              :         {
    2798            0 :           pp_cxx_ws_string (pp, "+");
    2799            0 :           dump_expr (pp, TMR_INDEX (t), flags);
    2800            0 :           pp_cxx_ws_string (pp, "*");
    2801            0 :           dump_expr (pp, TMR_STEP (t), flags);
    2802              :         }
    2803            0 :       if (TMR_INDEX2 (t))
    2804              :         {
    2805            0 :           pp_cxx_ws_string (pp, "+");
    2806            0 :           dump_expr (pp, TMR_INDEX2 (t), flags);
    2807              :         }
    2808            0 :       if (!integer_zerop (TMR_OFFSET (t)))
    2809              :         {
    2810            0 :           pp_cxx_ws_string (pp, "+");
    2811            0 :           dump_expr (pp, fold_convert (ssizetype, TMR_OFFSET (t)), flags);
    2812              :         }
    2813            0 :       pp_cxx_right_paren (pp);
    2814            0 :       break;
    2815              : 
    2816          245 :     case NEGATE_EXPR:
    2817          245 :     case BIT_NOT_EXPR:
    2818          245 :     case TRUTH_NOT_EXPR:
    2819          245 :     case PREDECREMENT_EXPR:
    2820          245 :     case PREINCREMENT_EXPR:
    2821          245 :       dump_unary_op (pp, OVL_OP_INFO (false, TREE_CODE (t))->name, t, flags);
    2822          245 :       break;
    2823              : 
    2824            0 :     case POSTDECREMENT_EXPR:
    2825            0 :     case POSTINCREMENT_EXPR:
    2826            0 :       pp_cxx_left_paren (pp);
    2827            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2828            0 :       pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name);
    2829            0 :       pp_cxx_right_paren (pp);
    2830            0 :       break;
    2831              : 
    2832         1982 :     case NON_LVALUE_EXPR:
    2833              :       /* FIXME: This is a KLUDGE workaround for a parsing problem.  There
    2834              :          should be another level of INDIRECT_REF so that I don't have to do
    2835              :          this.  */
    2836         1982 :       if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
    2837              :         {
    2838           23 :           tree next = TREE_TYPE (TREE_TYPE (t));
    2839              : 
    2840           23 :           while (TYPE_PTR_P (next))
    2841            0 :             next = TREE_TYPE (next);
    2842              : 
    2843           23 :           if (TREE_CODE (next) == FUNCTION_TYPE)
    2844              :             {
    2845            0 :               if (flags & TFF_EXPR_IN_PARENS)
    2846            0 :                 pp_cxx_left_paren (pp);
    2847            0 :               pp_cxx_star (pp);
    2848            0 :               dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    2849            0 :               if (flags & TFF_EXPR_IN_PARENS)
    2850            0 :                 pp_cxx_right_paren (pp);
    2851              :               break;
    2852              :             }
    2853              :           /* Else fall through.  */
    2854              :         }
    2855         1982 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    2856         1982 :       break;
    2857              : 
    2858        13030 :     CASE_CONVERT:
    2859        13030 :     case IMPLICIT_CONV_EXPR:
    2860        13030 :     case VIEW_CONVERT_EXPR:
    2861        13030 :     case EXCESS_PRECISION_EXPR:
    2862        13030 :       {
    2863        13030 :         tree op = TREE_OPERAND (t, 0);
    2864              : 
    2865        13030 :         if (location_wrapper_p (t))
    2866              :           {
    2867              :             dump_expr (pp, op, flags);
    2868              :             break;
    2869              :           }
    2870              : 
    2871         8518 :         tree ttype = TREE_TYPE (t);
    2872         8518 :         tree optype = TREE_TYPE (op);
    2873         8518 :         if (!optype)
    2874          154 :           optype = unknown_type_node;
    2875              : 
    2876         8518 :         if (TREE_CODE (ttype) != TREE_CODE (optype)
    2877         5779 :             && INDIRECT_TYPE_P (ttype)
    2878         5465 :             && INDIRECT_TYPE_P (optype)
    2879        13965 :             && same_type_p (TREE_TYPE (optype),
    2880              :                             TREE_TYPE (ttype)))
    2881              :           {
    2882         5399 :             if (TYPE_REF_P (ttype))
    2883              :               {
    2884         3884 :                 STRIP_NOPS (op);
    2885         3884 :                 if (TREE_CODE (op) == ADDR_EXPR)
    2886         2475 :                   dump_expr (pp, TREE_OPERAND (op, 0), flags);
    2887              :                 else
    2888         1409 :                   dump_unary_op (pp, "*", t, flags);
    2889              :               }
    2890              :             else
    2891         1515 :               dump_unary_op (pp, "&", t, flags);
    2892              :           }
    2893         3119 :         else if (!same_type_p (optype, ttype))
    2894              :           {
    2895              :             /* It is a cast, but we cannot tell whether it is a
    2896              :                reinterpret or static cast. Use the C style notation.  */
    2897         2647 :             if (flags & TFF_EXPR_IN_PARENS)
    2898         2039 :               pp_cxx_left_paren (pp);
    2899         2647 :             pp_cxx_left_paren (pp);
    2900         2647 :             dump_type (pp, TREE_TYPE (t), flags);
    2901         2647 :             pp_cxx_right_paren (pp);
    2902         2647 :             dump_expr (pp, op, flags | TFF_EXPR_IN_PARENS);
    2903         2647 :             if (flags & TFF_EXPR_IN_PARENS)
    2904         2039 :               pp_cxx_right_paren (pp);
    2905              :           }
    2906              :         else
    2907              :           dump_expr (pp, op, flags);
    2908              :         break;
    2909              :       }
    2910              : 
    2911        18217 :     case CONSTRUCTOR:
    2912        18217 :       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
    2913              :         {
    2914           18 :           tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
    2915              : 
    2916           18 :           if (integer_zerop (idx))
    2917              :             {
    2918              :               /* A NULL pointer-to-member constant.  */
    2919           14 :               pp_cxx_left_paren (pp);
    2920           14 :               pp_cxx_left_paren (pp);
    2921           14 :               dump_type (pp, TREE_TYPE (t), flags);
    2922           14 :               pp_cxx_right_paren (pp);
    2923           14 :               pp_character (pp, '0');
    2924           14 :               pp_cxx_right_paren (pp);
    2925           14 :               break;
    2926              :             }
    2927            4 :           else if (tree_fits_shwi_p (idx))
    2928              :             {
    2929            4 :               tree virtuals;
    2930            4 :               unsigned HOST_WIDE_INT n;
    2931              : 
    2932            4 :               t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
    2933            4 :               t = TYPE_METHOD_BASETYPE (t);
    2934            4 :               virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
    2935              : 
    2936            4 :               n = tree_to_shwi (idx);
    2937              : 
    2938              :               /* Map vtable index back one, to allow for the null pointer to
    2939              :                  member.  */
    2940            4 :               --n;
    2941              : 
    2942            4 :               while (n > 0 && virtuals)
    2943              :                 {
    2944            0 :                   --n;
    2945            0 :                   virtuals = TREE_CHAIN (virtuals);
    2946              :                 }
    2947            4 :               if (virtuals)
    2948              :                 {
    2949            4 :                   dump_expr (pp, BV_FN (virtuals),
    2950              :                              flags | TFF_EXPR_IN_PARENS);
    2951            4 :                   break;
    2952              :                 }
    2953              :             }
    2954              :         }
    2955        33927 :       if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
    2956          438 :         pp_string (pp, "<lambda closure object>");
    2957        18199 :       if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t))
    2958              :         {
    2959        10359 :           dump_type (pp, TREE_TYPE (t), 0);
    2960        10359 :           pp_cxx_left_paren (pp);
    2961        10359 :           pp_cxx_right_paren (pp);
    2962              :         }
    2963              :       else
    2964              :         {
    2965         7840 :           if (!BRACE_ENCLOSED_INITIALIZER_P (t))
    2966         7781 :             dump_type (pp, TREE_TYPE (t), 0);
    2967         7840 :           pp_cxx_left_brace (pp);
    2968         7840 :           dump_expr_init_vec (pp, CONSTRUCTOR_ELTS (t), flags);
    2969         7840 :           pp_cxx_right_brace (pp);
    2970              :         }
    2971              : 
    2972              :       break;
    2973              : 
    2974           25 :     case OFFSET_REF:
    2975           25 :       {
    2976           25 :         tree ob = TREE_OPERAND (t, 0);
    2977           25 :         if (is_dummy_object (ob))
    2978              :           {
    2979           22 :             t = TREE_OPERAND (t, 1);
    2980           22 :             if (TREE_CODE (t) == FUNCTION_DECL)
    2981              :               /* A::f */
    2982            0 :               dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS);
    2983           22 :             else if (BASELINK_P (t))
    2984     23834667 :               dump_expr (pp, OVL_FIRST (BASELINK_FUNCTIONS (t)),
    2985              :                          flags | TFF_EXPR_IN_PARENS);
    2986              :             else
    2987            3 :               dump_decl (pp, t, flags);
    2988              :           }
    2989              :         else
    2990              :           {
    2991            3 :             if (INDIRECT_REF_P (ob))
    2992              :               {
    2993            3 :                 dump_expr (pp, TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
    2994            3 :                 pp_cxx_arrow (pp);
    2995            3 :                 pp_cxx_star (pp);
    2996              :               }
    2997              :             else
    2998              :               {
    2999            0 :                 dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
    3000            0 :                 pp_cxx_dot (pp);
    3001            0 :                 pp_cxx_star (pp);
    3002              :               }
    3003            3 :             dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
    3004              :           }
    3005              :         break;
    3006              :       }
    3007              : 
    3008         1577 :     case TEMPLATE_PARM_INDEX:
    3009         1577 :       dump_decl (pp, TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
    3010         1577 :       break;
    3011              : 
    3012          167 :     case CAST_EXPR:
    3013          167 :       if (TREE_OPERAND (t, 0) == NULL_TREE
    3014          167 :           || TREE_CHAIN (TREE_OPERAND (t, 0)))
    3015              :         {
    3016          111 :           dump_type (pp, TREE_TYPE (t), flags);
    3017          111 :           pp_cxx_left_paren (pp);
    3018          111 :           dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
    3019          111 :           pp_cxx_right_paren (pp);
    3020              :         }
    3021              :       else
    3022              :         {
    3023           56 :           pp_cxx_left_paren (pp);
    3024           56 :           dump_type (pp, TREE_TYPE (t), flags);
    3025           56 :           pp_cxx_right_paren (pp);
    3026           56 :           pp_cxx_left_paren (pp);
    3027           56 :           dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
    3028           56 :           pp_cxx_right_paren (pp);
    3029              :         }
    3030              :       break;
    3031              : 
    3032           31 :     case STATIC_CAST_EXPR:
    3033           31 :       pp_cxx_ws_string (pp, "static_cast");
    3034           31 :       goto cast;
    3035            0 :     case REINTERPRET_CAST_EXPR:
    3036            0 :       pp_cxx_ws_string (pp, "reinterpret_cast");
    3037            0 :       goto cast;
    3038            3 :     case CONST_CAST_EXPR:
    3039            3 :       pp_cxx_ws_string (pp, "const_cast");
    3040            3 :       goto cast;
    3041            0 :     case DYNAMIC_CAST_EXPR:
    3042            0 :       pp_cxx_ws_string (pp, "dynamic_cast");
    3043           34 :     cast:
    3044           34 :       pp_cxx_begin_template_argument_list (pp);
    3045           34 :       dump_type (pp, TREE_TYPE (t), flags);
    3046           34 :       pp_cxx_end_template_argument_list (pp);
    3047           34 :       pp_cxx_left_paren (pp);
    3048           34 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3049           34 :       pp_cxx_right_paren (pp);
    3050           34 :       break;
    3051              : 
    3052            3 :     case ARROW_EXPR:
    3053            3 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3054            3 :       pp_cxx_arrow (pp);
    3055            3 :       break;
    3056              : 
    3057          190 :     case SIZEOF_EXPR:
    3058          190 :     case ALIGNOF_EXPR:
    3059          190 :       if (TREE_CODE (t) == SIZEOF_EXPR)
    3060          172 :         pp_cxx_ws_string (pp, "sizeof");
    3061           18 :       else if (ALIGNOF_EXPR_STD_P (t))
    3062           12 :         pp_cxx_ws_string (pp, "alignof");
    3063              :       else
    3064            6 :         pp_cxx_ws_string (pp, "__alignof__");
    3065          190 :       op = TREE_OPERAND (t, 0);
    3066          190 :       if (PACK_EXPANSION_P (op))
    3067              :         {
    3068           84 :           pp_string (pp, "...");
    3069           84 :           op = PACK_EXPANSION_PATTERN (op);
    3070              :         }
    3071          190 :       pp_cxx_whitespace (pp);
    3072          190 :       pp_cxx_left_paren (pp);
    3073          190 :       if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
    3074           29 :         dump_type (pp, TREE_TYPE (op), flags);
    3075          161 :       else if (TYPE_P (TREE_OPERAND (t, 0)))
    3076           98 :         dump_type (pp, op, flags);
    3077              :       else
    3078           63 :         dump_expr (pp, op, flags);
    3079          190 :       pp_cxx_right_paren (pp);
    3080          190 :       break;
    3081              : 
    3082            0 :     case AT_ENCODE_EXPR:
    3083            0 :       pp_cxx_ws_string (pp, "@encode");
    3084            0 :       pp_cxx_whitespace (pp);
    3085            0 :       pp_cxx_left_paren (pp);
    3086            0 :       dump_type (pp, TREE_OPERAND (t, 0), flags);
    3087            0 :       pp_cxx_right_paren (pp);
    3088            0 :       break;
    3089              : 
    3090           12 :     case NOEXCEPT_EXPR:
    3091           12 :       pp_cxx_ws_string (pp, "noexcept");
    3092           12 :       pp_cxx_whitespace (pp);
    3093           12 :       pp_cxx_left_paren (pp);
    3094           12 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3095           12 :       pp_cxx_right_paren (pp);
    3096           12 :       break;
    3097              : 
    3098            0 :     case REALPART_EXPR:
    3099            0 :     case IMAGPART_EXPR:
    3100            0 :       pp_cxx_ws_string (pp, OVL_OP_INFO (false, TREE_CODE (t))->name);
    3101            0 :       pp_cxx_whitespace (pp);
    3102            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3103            0 :       break;
    3104              : 
    3105            0 :     case DEFERRED_PARSE:
    3106            0 :       pp_string (pp, M_("<unparsed>"));
    3107            0 :       break;
    3108              : 
    3109            0 :     case TRY_CATCH_EXPR:
    3110            0 :     case CLEANUP_POINT_EXPR:
    3111            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3112            0 :       break;
    3113              : 
    3114            0 :     case PSEUDO_DTOR_EXPR:
    3115            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3116            0 :       pp_cxx_dot (pp);
    3117            0 :       if (TREE_OPERAND (t, 1))
    3118              :         {
    3119            0 :           dump_type (pp, TREE_OPERAND (t, 1), flags);
    3120            0 :           pp_cxx_colon_colon (pp);
    3121              :         }
    3122            0 :       pp_cxx_complement (pp);
    3123            0 :       dump_type (pp, TREE_OPERAND (t, 2), flags);
    3124            0 :       break;
    3125              : 
    3126         1456 :     case TEMPLATE_ID_EXPR:
    3127         1456 :       dump_decl (pp, t, flags);
    3128         1456 :       break;
    3129              : 
    3130           28 :     case BIND_EXPR:
    3131           28 :     case STMT_EXPR:
    3132           28 :     case EXPR_STMT:
    3133           28 :     case STATEMENT_LIST:
    3134              :       /* We don't yet have a way of dumping statements in a
    3135              :          human-readable format.  */
    3136           28 :       pp_string (pp, "({...})");
    3137           28 :       break;
    3138              : 
    3139            0 :     case LOOP_EXPR:
    3140            0 :       pp_string (pp, "while (1) { ");
    3141            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    3142            0 :       pp_cxx_right_brace (pp);
    3143            0 :       break;
    3144              : 
    3145            0 :     case EXIT_EXPR:
    3146            0 :       pp_string (pp, "if (");
    3147            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    3148            0 :       pp_string (pp, ") break; ");
    3149            0 :       break;
    3150              : 
    3151          149 :     case BASELINK:
    3152          149 :       dump_expr (pp, BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS);
    3153          149 :       break;
    3154              : 
    3155          700 :     case EMPTY_CLASS_EXPR:
    3156          700 :       dump_type (pp, TREE_TYPE (t), flags);
    3157          700 :       pp_cxx_left_paren (pp);
    3158          700 :       pp_cxx_right_paren (pp);
    3159          700 :       break;
    3160              : 
    3161            0 :     case ARGUMENT_PACK_SELECT:
    3162            0 :       dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
    3163            0 :       break;
    3164              : 
    3165          141 :     case RECORD_TYPE:
    3166          141 :     case UNION_TYPE:
    3167          141 :     case ENUMERAL_TYPE:
    3168          141 :     case REAL_TYPE:
    3169          141 :     case VOID_TYPE:
    3170          141 :     case OPAQUE_TYPE:
    3171          141 :     case BOOLEAN_TYPE:
    3172          141 :     case INTEGER_TYPE:
    3173          141 :     case COMPLEX_TYPE:
    3174          141 :     case VECTOR_TYPE:
    3175          141 :     case DECLTYPE_TYPE:
    3176          141 :       pp_type_specifier_seq (pp, t);
    3177          141 :       break;
    3178              : 
    3179            0 :     case TYPENAME_TYPE:
    3180              :       /* We get here when we want to print a dependent type as an
    3181              :          id-expression, without any disambiguator decoration.  */
    3182            0 :       pp->id_expression (t);
    3183            0 :       break;
    3184              : 
    3185           33 :     case TEMPLATE_TYPE_PARM:
    3186           33 :     case TEMPLATE_TEMPLATE_PARM:
    3187           33 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
    3188           33 :       dump_type (pp, t, flags);
    3189           33 :       break;
    3190              : 
    3191           58 :     case TRAIT_EXPR:
    3192           58 :       pp_cxx_trait (pp, t);
    3193           58 :       break;
    3194              : 
    3195            3 :     case VA_ARG_EXPR:
    3196            3 :       pp_cxx_va_arg_expression (pp, t);
    3197            3 :       break;
    3198              : 
    3199           15 :     case OFFSETOF_EXPR:
    3200           15 :       pp_cxx_offsetof_expression (pp, t);
    3201           15 :       break;
    3202              : 
    3203            0 :     case ADDRESSOF_EXPR:
    3204            0 :       pp_cxx_addressof_expression (pp, t);
    3205            0 :       break;
    3206              : 
    3207          985 :     case SCOPE_REF:
    3208          985 :       dump_decl (pp, t, flags);
    3209          985 :       break;
    3210              : 
    3211         3507 :     case EXPR_PACK_EXPANSION:
    3212         3507 :     case UNARY_LEFT_FOLD_EXPR:
    3213         3507 :     case UNARY_RIGHT_FOLD_EXPR:
    3214         3507 :     case BINARY_LEFT_FOLD_EXPR:
    3215         3507 :     case BINARY_RIGHT_FOLD_EXPR:
    3216         3507 :     case TYPEID_EXPR:
    3217         3507 :     case MEMBER_REF:
    3218         3507 :     case DOTSTAR_EXPR:
    3219         3507 :     case NEW_EXPR:
    3220         3507 :     case VEC_NEW_EXPR:
    3221         3507 :     case DELETE_EXPR:
    3222         3507 :     case VEC_DELETE_EXPR:
    3223         3507 :     case MODOP_EXPR:
    3224         3507 :     case ABS_EXPR:
    3225         3507 :     case ABSU_EXPR:
    3226         3507 :     case CONJ_EXPR:
    3227         3507 :     case VECTOR_CST:
    3228         3507 :     case FIXED_CST:
    3229         3507 :     case UNORDERED_EXPR:
    3230         3507 :     case ORDERED_EXPR:
    3231         3507 :     case UNLT_EXPR:
    3232         3507 :     case UNLE_EXPR:
    3233         3507 :     case UNGT_EXPR:
    3234         3507 :     case UNGE_EXPR:
    3235         3507 :     case UNEQ_EXPR:
    3236         3507 :     case LTGT_EXPR:
    3237         3507 :     case COMPLEX_EXPR:
    3238         3507 :     case BIT_FIELD_REF:
    3239         3507 :     case FIX_TRUNC_EXPR:
    3240         3507 :     case FLOAT_EXPR:
    3241         3507 :       pp->expression (t);
    3242         3507 :       break;
    3243              : 
    3244            0 :     case PACK_INDEX_EXPR:
    3245            0 :       pp->expression (PACK_INDEX_PACK (t));
    3246            0 :       pp_cxx_left_bracket (pp);
    3247            0 :       pp->expression (PACK_INDEX_INDEX (t));
    3248            0 :       pp_cxx_right_bracket (pp);
    3249            0 :       break;
    3250              : 
    3251            0 :     case TRUTH_AND_EXPR:
    3252            0 :     case TRUTH_OR_EXPR:
    3253            0 :     case TRUTH_XOR_EXPR:
    3254            0 :       if (flags & TFF_EXPR_IN_PARENS)
    3255            0 :         pp_cxx_left_paren (pp);
    3256            0 :       pp->expression (t);
    3257            0 :       if (flags & TFF_EXPR_IN_PARENS)
    3258            0 :         pp_cxx_right_paren (pp);
    3259              :       break;
    3260              : 
    3261            6 :     case OBJ_TYPE_REF:
    3262            6 :       dump_expr (pp, resolve_virtual_fun_from_obj_type_ref (t), flags);
    3263            6 :       break;
    3264              : 
    3265          111 :     case LAMBDA_EXPR:
    3266          111 :       pp_string (pp, M_("<lambda>"));
    3267          111 :       break;
    3268              : 
    3269           10 :     case PAREN_EXPR:
    3270           10 :       pp_cxx_left_paren (pp);
    3271           10 :       dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    3272           10 :       pp_cxx_right_paren (pp);
    3273           10 :       break;
    3274              : 
    3275            3 :     case REQUIRES_EXPR:
    3276            3 :       pp_cxx_requires_expr (cxx_pp, t);
    3277            3 :       break;
    3278              : 
    3279            0 :     case SIMPLE_REQ:
    3280            0 :       pp_cxx_simple_requirement (cxx_pp, t);
    3281            0 :       break;
    3282              : 
    3283            0 :     case TYPE_REQ:
    3284            0 :       pp_cxx_type_requirement (cxx_pp, t);
    3285            0 :       break;
    3286              : 
    3287            0 :     case COMPOUND_REQ:
    3288            0 :       pp_cxx_compound_requirement (cxx_pp, t);
    3289            0 :       break;
    3290              : 
    3291            0 :     case NESTED_REQ:
    3292            0 :       pp_cxx_nested_requirement (cxx_pp, t);
    3293            0 :       break;
    3294              : 
    3295         1007 :     case ATOMIC_CONSTR:
    3296         1007 :     case CONJ_CONSTR:
    3297         1007 :     case DISJ_CONSTR:
    3298         1007 :       {
    3299         1007 :         pp_cxx_constraint (cxx_pp, t);
    3300         1007 :         break;
    3301              :       }
    3302              : 
    3303           13 :     case PLACEHOLDER_EXPR:
    3304           13 :       pp_string (pp, M_("*this"));
    3305           13 :       break;
    3306              : 
    3307           49 :     case TREE_LIST:
    3308           49 :       dump_expr_list (pp, t, flags);
    3309           49 :       break;
    3310              : 
    3311            6 :     case NONTYPE_ARGUMENT_PACK:
    3312            6 :       {
    3313            6 :         tree args = ARGUMENT_PACK_ARGS (t);
    3314            6 :         int len = TREE_VEC_LENGTH (args);
    3315            6 :         pp_cxx_left_brace (pp);
    3316           18 :         for (int i = 0; i < len; ++i)
    3317              :           {
    3318            6 :             if (i > 0)
    3319            0 :               pp_separate_with_comma (pp);
    3320            6 :             dump_expr (pp, TREE_VEC_ELT (args, i), flags);
    3321              :           }
    3322            6 :         pp_cxx_right_brace (pp);
    3323            6 :         break;
    3324              :       }
    3325              : 
    3326            3 :     case CO_AWAIT_EXPR:
    3327            3 :       pp_cxx_ws_string (pp, "co_await");
    3328            3 :       pp_cxx_whitespace (pp);
    3329            3 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3330            3 :       break;
    3331              : 
    3332            0 :     case CO_YIELD_EXPR:
    3333            0 :       pp_cxx_ws_string (pp, "co_yield");
    3334            0 :       pp_cxx_whitespace (pp);
    3335            0 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3336            0 :       break;
    3337              : 
    3338            0 :     case CO_RETURN_EXPR:
    3339            0 :       pp_cxx_ws_string (pp, "co_return");
    3340            0 :       if (TREE_OPERAND (t, 0))
    3341              :         {
    3342            0 :           pp_cxx_whitespace (pp);
    3343            0 :           dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3344              :         }
    3345              :       break;
    3346              : 
    3347          318 :     case REFLECT_EXPR:
    3348          318 :       {
    3349          318 :         tree h = REFLECT_EXPR_HANDLE (t);
    3350          318 :         bool any;
    3351          318 :         switch (REFLECT_EXPR_KIND (t))
    3352              :           {
    3353            4 :           case REFLECT_ANNOTATION:
    3354            4 :             pp_string (pp, "^^[[=");
    3355            4 :             pp->set_padding (pp_none);
    3356            4 :             dump_expr (pp, TREE_VALUE (TREE_VALUE (h)), flags);
    3357            4 :             pp_string (pp, "]]");
    3358            4 :             break;
    3359            6 :           case REFLECT_DATA_MEMBER_SPEC:
    3360            6 :             pp_cxx_ws_string (pp, "data_member_spec");
    3361            6 :             pp_string (pp, "(^^");
    3362            6 :             pp->set_padding (pp_none);
    3363            6 :             dump_type (pp, TREE_VEC_ELT (h, 0), flags);
    3364            6 :             pp_string (pp, ",{");
    3365            6 :             any = false;
    3366            6 :             if (TREE_VEC_ELT (h, 1))
    3367              :               {
    3368            4 :                 pp_string (pp, ".name=");
    3369            4 :                 pp_doublequote (pp);
    3370            4 :                 pp->set_padding (pp_none);
    3371            4 :                 dump_decl (pp, TREE_VEC_ELT (h, 1), flags);
    3372            4 :                 pp_doublequote (pp);
    3373            4 :                 any = true;
    3374              :               }
    3375            6 :             if (TREE_VEC_ELT (h, 2))
    3376              :               {
    3377            2 :                 if (any)
    3378            2 :                   pp_comma (pp);
    3379            2 :                 pp_string (pp, ".alignment=");
    3380            2 :                 pp->set_padding (pp_none);
    3381            2 :                 dump_expr (pp, TREE_VEC_ELT (h, 2), flags);
    3382            2 :                 any = true;
    3383              :               }
    3384            6 :             if (TREE_VEC_ELT (h, 3))
    3385              :               {
    3386            2 :                 if (any)
    3387            0 :                   pp_comma (pp);
    3388            2 :                 pp_string (pp, ".bit_width=");
    3389            2 :                 pp->set_padding (pp_none);
    3390            2 :                 dump_expr (pp, TREE_VEC_ELT (h, 3), flags);
    3391            2 :                 any = true;
    3392              :               }
    3393            6 :             if (TREE_VEC_ELT (h, 4) && !integer_zerop (TREE_VEC_ELT (h, 4)))
    3394              :               {
    3395            2 :                 if (any)
    3396            2 :                   pp_comma (pp);
    3397            2 :                 pp_string (pp, ".no_unique_address=");
    3398            2 :                 pp->set_padding (pp_none);
    3399            2 :                 dump_expr (pp, TREE_VEC_ELT (h, 4), flags);
    3400            2 :                 any = true;
    3401              :               }
    3402            6 :             if (TREE_VEC_LENGTH (h) > 5)
    3403              :               {
    3404            2 :                 if (any)
    3405            2 :                   pp_comma (pp);
    3406            2 :                 pp_string (pp, ".annotations={");
    3407            2 :                 pp->set_padding (pp_none);
    3408            8 :                 for (int i = 5; i < TREE_VEC_LENGTH (h); ++i)
    3409              :                   {
    3410            6 :                     dump_expr (pp, TREE_VEC_ELT (h, i), flags);
    3411            6 :                     if (i != TREE_VEC_LENGTH (h) - 1)
    3412            4 :                       pp_comma (pp);
    3413            6 :                     pp->set_padding (pp_none);
    3414              :                   }
    3415            2 :                 pp_right_brace (pp);
    3416              :               }
    3417            6 :             pp_string (pp, "})");
    3418            6 :             break;
    3419            8 :           case REFLECT_BASE:
    3420            8 :             {
    3421            8 :               pp_cxx_ws_string (pp, "bases_of");
    3422            8 :               pp_string (pp, "(^^");
    3423            8 :               pp->set_padding (pp_none);
    3424            8 :               tree d = direct_base_derived (h);
    3425            8 :               dump_type (pp, d, flags);
    3426            8 :               pp_string (pp, ",std::meta::access_context::unchecked())[");
    3427            8 :               pp->set_padding (pp_none);
    3428            8 :               tree binfo = TYPE_BINFO (d), base_binfo;
    3429           14 :               for (unsigned i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo);
    3430              :                    i++)
    3431           14 :                 if (base_binfo == h)
    3432              :                   {
    3433            8 :                     pp_wide_integer (pp, i);
    3434            8 :                     break;
    3435              :                   }
    3436            8 :               pp_string (pp, "] {aka ");
    3437            8 :               pp->set_padding (pp_none);
    3438            8 :               dump_type (pp, BINFO_TYPE (h), flags);
    3439            8 :               pp_right_brace (pp);
    3440            8 :               break;
    3441              :             }
    3442           20 :           case REFLECT_PARM:
    3443           20 :             {
    3444           20 :               pp_cxx_ws_string (pp, "parameters_of");
    3445           20 :               pp_string (pp, "(^^");
    3446           20 :               pp->set_padding (pp_none);
    3447           20 :               h = maybe_update_function_parm (h);
    3448           20 :               dump_decl (pp, DECL_CONTEXT (h), flags);
    3449           20 :               pp_string (pp, ")[");
    3450           20 :               pp->set_padding (pp_none);
    3451           20 :               unsigned int i = 0;
    3452           20 :               for (tree arg = FUNCTION_FIRST_USER_PARM (DECL_CONTEXT (h));
    3453           24 :                    arg; arg = DECL_CHAIN (arg), ++i)
    3454           24 :                 if (arg == h)
    3455              :                   {
    3456           20 :                     pp_wide_integer (pp, i);
    3457           20 :                     break;
    3458              :                   }
    3459           20 :               pp_right_bracket (pp);
    3460           20 :               if (MULTIPLE_NAMES_PARM_P (h))
    3461              :                 break;
    3462           18 :               if (DECL_NAME (h))
    3463            2 :                 h = DECL_NAME (h);
    3464           16 :               else if (tree opn = lookup_attribute ("old parm name",
    3465           16 :                                                     DECL_ATTRIBUTES (h)))
    3466            4 :                 h = TREE_VALUE (TREE_VALUE (opn));
    3467              :               else
    3468              :                 break;
    3469            6 :               pp_string (pp, " {aka ");
    3470            6 :               dump_decl (pp, h, flags);
    3471            6 :               pp_right_brace (pp);
    3472            6 :               break;
    3473              :             }
    3474            6 :           case REFLECT_OBJECT:
    3475            6 :             pp_cxx_ws_string (pp, "std::meta::reflect_object");
    3476            6 :             pp_left_paren (pp);
    3477            6 :             pp->set_padding (pp_none);
    3478            6 :             dump_expr (pp, h, flags);
    3479            6 :             pp_right_paren (pp);
    3480            6 :             break;
    3481            8 :           case REFLECT_VALUE:
    3482            8 :             pp_cxx_ws_string (pp, "std::meta::reflect_constant");
    3483            8 :             pp_left_paren (pp);
    3484            8 :             pp->set_padding (pp_none);
    3485            8 :             dump_expr (pp, h, flags);
    3486            8 :             pp_right_paren (pp);
    3487            8 :             break;
    3488          266 :           default:
    3489          266 :             if (null_reflection_p (t))
    3490              :               {
    3491            4 :                 pp_cxx_ws_string (pp, "std::meta::info{}");
    3492            4 :                 break;
    3493              :               }
    3494          262 :             pp_string (pp, "^^");
    3495          262 :             pp->set_padding (pp_none);
    3496          262 :             if (DECL_P (h))
    3497          156 :               dump_decl (pp, h, flags);
    3498          106 :             else if (TYPE_P (h))
    3499              :               {
    3500              :                 /* For reflection we care about the difference
    3501              :                    between std::meta::info/std::nullptr_t and
    3502              :                    decltype(^^int)/decltype(nullptr).  */
    3503           82 :                 if (REFLECTION_TYPE_P (h) && !typedef_variant_p (h))
    3504              :                   {
    3505            6 :                     pp_cxx_ws_string (pp, "decltype(^^int)");
    3506            6 :                     pp_c_type_qualifier_list (pp, h);
    3507              :                   }
    3508           76 :                 else if (TREE_CODE (h) == NULLPTR_TYPE
    3509           76 :                          && !typedef_variant_p (h))
    3510              :                   {
    3511            6 :                     pp_cxx_ws_string (pp, "decltype(nullptr)");
    3512            6 :                     pp_c_type_qualifier_list (pp, h);
    3513              :                   }
    3514              :                 else
    3515           70 :                   dump_type (pp, h, flags);
    3516              :               }
    3517              :             else
    3518              :               dump_expr (pp, h, flags);
    3519              :             break;
    3520              :           }
    3521              :         break;
    3522              :       }
    3523              : 
    3524           24 :     case SPLICE_EXPR:
    3525           24 :       pp_cxx_ws_string (pp, "[:");
    3526           24 :       pp_cxx_whitespace (pp);
    3527           24 :       dump_expr (pp, TREE_OPERAND (t, 0), flags);
    3528           24 :       pp_cxx_whitespace (pp);
    3529           24 :       pp_cxx_ws_string (pp, ":]");
    3530           24 :       break;
    3531              : 
    3532              :       /*  This list is incomplete, but should suffice for now.
    3533              :           It is very important that `sorry' does not call
    3534              :           `report_error_function'.  That could cause an infinite loop.  */
    3535           12 :     default:
    3536           12 :       pp_unsupported_tree (pp, t);
    3537              :       /* Fall through.  */
    3538           50 :     case ERROR_MARK:
    3539           50 :       pp_string (pp, M_("<expression error>"));
    3540           50 :       break;
    3541              :     }
    3542              : }
    3543              : 
    3544              : static void
    3545         2314 : dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t,
    3546              :                 int flags)
    3547              : {
    3548         2314 :   pp_cxx_left_paren (pp);
    3549         2314 :   dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
    3550         2314 :   pp_cxx_whitespace (pp);
    3551         2314 :   if (opstring)
    3552         2314 :     pp_cxx_ws_string (pp, opstring);
    3553              :   else
    3554            0 :     pp_string (pp, M_("<unknown operator>"));
    3555         2314 :   pp_cxx_whitespace (pp);
    3556         2314 :   tree op1 = TREE_OPERAND (t, 1);
    3557         2314 :   if (TREE_CODE (t) == POINTER_PLUS_EXPR
    3558          313 :       && TREE_CODE (op1) == INTEGER_CST
    3559         2501 :       && tree_int_cst_sign_bit (op1))
    3560              :     /* A pointer minus an integer is represented internally as plus a very
    3561              :        large number, don't expose that to users.  */
    3562           25 :     op1 = convert (ssizetype, op1);
    3563         2314 :   dump_expr (pp, op1, flags | TFF_EXPR_IN_PARENS);
    3564         2314 :   pp_cxx_right_paren (pp);
    3565         2314 : }
    3566              : 
    3567              : static void
    3568         6449 : dump_unary_op (cxx_pretty_printer *pp, const char *opstring, tree t, int flags)
    3569              : {
    3570         6449 :   if (flags & TFF_EXPR_IN_PARENS)
    3571         4362 :     pp_cxx_left_paren (pp);
    3572         6449 :   pp_cxx_ws_string (pp, opstring);
    3573         6449 :   dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
    3574         6449 :   if (flags & TFF_EXPR_IN_PARENS)
    3575         4362 :     pp_cxx_right_paren (pp);
    3576         6449 : }
    3577              : 
    3578              : static void
    3579    247451199 : reinit_cxx_pp (void)
    3580              : {
    3581    247451199 :   pp_clear_output_area (cxx_pp);
    3582    247451199 :   cxx_pp->set_padding (pp_none);
    3583    247451199 :   pp_indentation (cxx_pp) = 0;
    3584    247451199 :   pp_needs_newline (cxx_pp) = false;
    3585    247451199 :   pp_show_color (cxx_pp) = false;
    3586    247451199 :   cxx_pp->enclosing_scope = current_function_decl;
    3587    247451199 : }
    3588              : 
    3589              : /* Same as pp_formatted_text, except the return string is a separate
    3590              :    copy and has a GGC storage duration, e.g. an indefinite lifetime.  */
    3591              : 
    3592              : inline const char *
    3593    247451663 : pp_ggc_formatted_text (pretty_printer *pp)
    3594              : {
    3595    247451663 :   return ggc_strdup (pp_formatted_text (pp));
    3596              : }
    3597              : 
    3598              : /* Exported interface to stringifying types, exprs and decls under TFF_*
    3599              :    control.  */
    3600              : 
    3601              : const char *
    3602          213 : type_as_string (tree typ, int flags)
    3603              : {
    3604          213 :   reinit_cxx_pp ();
    3605          213 :   pp_translate_identifiers (cxx_pp) = false;
    3606          213 :   dump_type (cxx_pp, typ, flags);
    3607          213 :   return pp_ggc_formatted_text (cxx_pp);
    3608              : }
    3609              : 
    3610              : const char *
    3611            0 : type_as_string_translate (tree typ, int flags)
    3612              : {
    3613            0 :   reinit_cxx_pp ();
    3614            0 :   dump_type (cxx_pp, typ, flags);
    3615            0 :   return pp_ggc_formatted_text (cxx_pp);
    3616              : }
    3617              : 
    3618              : const char *
    3619         5299 : expr_as_string (tree decl, int flags)
    3620              : {
    3621         5299 :   reinit_cxx_pp ();
    3622         5299 :   pp_translate_identifiers (cxx_pp) = false;
    3623         5299 :   dump_expr (cxx_pp, decl, flags);
    3624         5299 :   return pp_ggc_formatted_text (cxx_pp);
    3625              : }
    3626              : 
    3627              : /* Wrap decl_as_string with options appropriate for dwarf.  */
    3628              : 
    3629              : const char *
    3630     50257415 : decl_as_dwarf_string (tree decl, int flags)
    3631              : {
    3632     50257415 :   const char *name;
    3633              :   /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
    3634              :      here will be adequate to get the desired behavior.  */
    3635     50257415 :   cxx_pp->flags |= pp_c_flag_gnu_v3;
    3636     50257415 :   name = decl_as_string (decl, flags);
    3637              :   /* Subsequent calls to the pretty printer shouldn't use this style.  */
    3638     50257415 :   cxx_pp->flags &= ~pp_c_flag_gnu_v3;
    3639     50257415 :   return name;
    3640              : }
    3641              : 
    3642              : const char *
    3643     50337689 : decl_as_string (tree decl, int flags)
    3644              : {
    3645     50337689 :   reinit_cxx_pp ();
    3646     50337689 :   pp_translate_identifiers (cxx_pp) = false;
    3647     50337689 :   dump_decl (cxx_pp, decl, flags);
    3648     50337689 :   return pp_ggc_formatted_text (cxx_pp);
    3649              : }
    3650              : 
    3651              : const char *
    3652            0 : decl_as_string_translate (tree decl, int flags)
    3653              : {
    3654            0 :   reinit_cxx_pp ();
    3655            0 :   dump_decl (cxx_pp, decl, flags);
    3656            0 :   return pp_ggc_formatted_text (cxx_pp);
    3657              : }
    3658              : 
    3659              : /* Wrap lang_decl_name with options appropriate for dwarf.  */
    3660              : 
    3661              : const char *
    3662    196795439 : lang_decl_dwarf_name (tree decl, int v, bool translate)
    3663              : {
    3664    196795439 :   const char *name;
    3665              :   /* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
    3666              :      here will be adequate to get the desired behavior.  */
    3667    196795439 :   cxx_pp->flags |= pp_c_flag_gnu_v3;
    3668    196795439 :   name = lang_decl_name (decl, v, translate);
    3669              :   /* Subsequent calls to the pretty printer shouldn't use this style.  */
    3670    196795439 :   cxx_pp->flags &= ~pp_c_flag_gnu_v3;
    3671    196795439 :   return name;
    3672              : }
    3673              : 
    3674              : /* Generate the three forms of printable names for cxx_printable_name.  */
    3675              : 
    3676              : const char *
    3677    196957889 : lang_decl_name (tree decl, int v, bool translate)
    3678              : {
    3679    196957889 :   if (v >= 2)
    3680        80017 :     return (translate
    3681        80017 :             ? decl_as_string_translate (decl, TFF_DECL_SPECIFIERS)
    3682        80017 :             : decl_as_string (decl, TFF_DECL_SPECIFIERS));
    3683              : 
    3684    196877872 :   reinit_cxx_pp ();
    3685    196877872 :   pp_translate_identifiers (cxx_pp) = translate;
    3686    196877872 :   if (v == 1
    3687    196877872 :       && (DECL_CLASS_SCOPE_P (decl)
    3688        87214 :           || (DECL_NAMESPACE_SCOPE_P (decl)
    3689        85935 :               && CP_DECL_CONTEXT (decl) != global_namespace)))
    3690              :     {
    3691       159799 :       dump_type (cxx_pp, CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
    3692       159799 :       pp_cxx_colon_colon (cxx_pp);
    3693              :     }
    3694              : 
    3695    196877872 :   if (TREE_CODE (decl) == FUNCTION_DECL)
    3696     96725200 :     dump_function_name (cxx_pp, decl, TFF_PLAIN_IDENTIFIER);
    3697    100152672 :   else if ((DECL_NAME (decl) == NULL_TREE)
    3698    100152672 :            && TREE_CODE (decl) == NAMESPACE_DECL)
    3699           21 :     dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME);
    3700              :   else
    3701    100152651 :     dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
    3702              : 
    3703    196877872 :   return pp_ggc_formatted_text (cxx_pp);
    3704              : }
    3705              : 
    3706              : /* Return the location of a tree passed to %+ formats.  */
    3707              : 
    3708              : location_t
    3709      2188510 : location_of (tree t)
    3710              : {
    3711      2188510 :   if (TYPE_P (t))
    3712              :     {
    3713         4017 :       t = TYPE_MAIN_DECL (t);
    3714         4017 :       if (t == NULL_TREE)
    3715          762 :         return input_location;
    3716              :     }
    3717      2184493 :   else if (TREE_CODE (t) == OVERLOAD)
    3718           44 :     t = (OVL_FIRST (t) != conv_op_marker ? OVL_FIRST (t)
    3719            0 :          : OVL_FIRST (OVL_CHAIN (t)));
    3720              : 
    3721      2187748 :   if (DECL_P (t))
    3722      1653286 :     return DECL_SOURCE_LOCATION (t);
    3723       534462 :   if (TREE_CODE (t) == DEFERRED_PARSE)
    3724           19 :     return defparse_location (t);
    3725       534443 :   return cp_expr_loc_or_input_loc (t);
    3726              : }
    3727              : 
    3728              : /* Now the interfaces from error et al to dump_type et al. Each takes an
    3729              :    on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_
    3730              :    function.  */
    3731              : 
    3732              : static const char *
    3733       104090 : decl_to_string (tree decl, int verbose, bool show_color)
    3734              : {
    3735       104090 :   int flags = 0;
    3736              : 
    3737       104090 :   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
    3738              :       || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
    3739         4091 :     flags = TFF_CLASS_KEY_OR_ENUM;
    3740       104090 :   if (verbose)
    3741        31885 :     flags |= TFF_DECL_SPECIFIERS;
    3742        72205 :   else if (TREE_CODE (decl) == FUNCTION_DECL)
    3743        46215 :     flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
    3744       104090 :   flags |= TFF_TEMPLATE_HEADER;
    3745              : 
    3746       104090 :   reinit_cxx_pp ();
    3747       104090 :   pp_show_color (cxx_pp) = show_color;
    3748       104090 :   dump_decl (cxx_pp, decl, flags);
    3749       104090 :   return pp_ggc_formatted_text (cxx_pp);
    3750              : }
    3751              : 
    3752              : const char *
    3753        53075 : expr_to_string (tree decl)
    3754              : {
    3755        53075 :   reinit_cxx_pp ();
    3756        53075 :   dump_expr (cxx_pp, decl, 0);
    3757        53075 :   return pp_ggc_formatted_text (cxx_pp);
    3758              : }
    3759              : 
    3760              : static const char *
    3761          372 : fndecl_to_string (tree fndecl, int verbose)
    3762              : {
    3763          372 :   int flags;
    3764              : 
    3765          372 :   flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS
    3766              :     | TFF_TEMPLATE_HEADER;
    3767          372 :   if (verbose)
    3768          107 :     flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
    3769          372 :   reinit_cxx_pp ();
    3770          372 :   dump_decl (cxx_pp, fndecl, flags);
    3771          372 :   return pp_ggc_formatted_text (cxx_pp);
    3772              : }
    3773              : 
    3774              : 
    3775              : static const char *
    3776            0 : code_to_string (enum tree_code c)
    3777              : {
    3778            0 :   return get_tree_code_name (c);
    3779              : }
    3780              : 
    3781              : const char *
    3782        14468 : language_to_string (enum languages c)
    3783              : {
    3784        14468 :   switch (c)
    3785              :     {
    3786              :     case lang_c:
    3787              :       return "C";
    3788              : 
    3789           12 :     case lang_cplusplus:
    3790           12 :       return "C++";
    3791              : 
    3792            0 :     default:
    3793            0 :       gcc_unreachable ();
    3794              :     }
    3795              :   return NULL;
    3796              : }
    3797              : 
    3798              : /* Return the proper printed version of a parameter to a C++ function.  */
    3799              : 
    3800              : static const char *
    3801         1563 : parm_to_string (int p)
    3802              : {
    3803         1563 :   reinit_cxx_pp ();
    3804         1563 :   if (p < 0)
    3805           30 :     pp_string (cxx_pp, "'this'");
    3806              :   else
    3807         1533 :     pp_decimal_int (cxx_pp, p + 1);
    3808         1563 :   return pp_ggc_formatted_text (cxx_pp);
    3809              : }
    3810              : 
    3811              : static const char *
    3812          332 : op_to_string (bool assop, enum tree_code p)
    3813              : {
    3814          332 :   tree id = ovl_op_identifier (assop, p);
    3815          661 :   return id ? IDENTIFIER_POINTER (id) : M_("<unknown>");
    3816              : }
    3817              : 
    3818              : /* Return a GC-allocated representation of type TYP, with verbosity VERBOSE.
    3819              : 
    3820              :    If QUOTE is non-NULL and if *QUOTE is true, then quotes are added to the
    3821              :    string in appropriate places, and *QUOTE is written to with false
    3822              :    to suppress pp_format's trailing close quote so that e.g.
    3823              :      foo_typedef {aka underlying_foo} {enum}
    3824              :    can be printed by "%qT" as:
    3825              :      `foo_typedef' {aka `underlying_foo'} {enum}
    3826              :    rather than:
    3827              :      `foo_typedef {aka underlying_foo} {enum}'
    3828              :    When adding such quotes, if POSTPROCESSED is true (for handling %H and %I)
    3829              :    then a leading open quote will be added, whereas if POSTPROCESSED is false
    3830              :    (for handling %T) then any leading quote has already been added by
    3831              :    pp_format, or is not needed due to QUOTE being NULL (for template arguments
    3832              :    within %H and %I).
    3833              : 
    3834              :    SHOW_COLOR and HIGHLIGHT_COLOR are used to determine the colorization of
    3835              :    any quotes that are added.  */
    3836              : 
    3837              : static const char *
    3838        65547 : type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
    3839              :                 bool show_color, const char *highlight_color)
    3840              : {
    3841        65547 :   int flags = 0;
    3842        65547 :   if (verbose)
    3843        10184 :     flags |= TFF_CLASS_KEY_OR_ENUM;
    3844        65547 :   flags |= TFF_TEMPLATE_HEADER;
    3845              : 
    3846        65547 :   reinit_cxx_pp ();
    3847        65547 :   pp_show_color (cxx_pp) = show_color;
    3848              : 
    3849        65547 :   if (postprocessed && quote && *quote)
    3850              :     {
    3851        20890 :       pp_begin_quote (cxx_pp, show_color);
    3852        20890 :       if (show_color && highlight_color)
    3853            0 :         pp_string (cxx_pp, colorize_start (show_color, highlight_color));
    3854              :     }
    3855              : 
    3856        65547 :   struct obstack *ob = pp_buffer (cxx_pp)->m_obstack;
    3857        65547 :   int type_start, type_len;
    3858        65547 :   type_start = obstack_object_size (ob);
    3859              : 
    3860        65547 :   dump_type (cxx_pp, typ, flags);
    3861              : 
    3862              :   /* Remember the end of the initial dump.  */
    3863        65547 :   type_len = obstack_object_size (ob) - type_start;
    3864              : 
    3865              :   /* If we're printing a type that involves typedefs, also print the
    3866              :      stripped version.  But sometimes the stripped version looks
    3867              :      exactly the same, so we don't want it after all.  To avoid printing
    3868              :      it in that case, we play ugly obstack games.  */
    3869        65533 :   if (typ && TYPE_P (typ) && typ != TYPE_CANONICAL (typ)
    3870        71831 :       && !uses_template_parms (typ))
    3871              :     {
    3872         4523 :       int aka_start, aka_len; char *p;
    3873         4523 :       tree aka = strip_typedefs (typ, NULL, STF_USER_VISIBLE);
    3874         4523 :       if (quote && *quote)
    3875         4066 :         pp_end_quote (cxx_pp, show_color);
    3876         4523 :       pp_string (cxx_pp, " {aka");
    3877         4523 :       pp_cxx_whitespace (cxx_pp);
    3878         4523 :       if (quote && *quote)
    3879         4066 :         pp_begin_quote (cxx_pp, show_color);
    3880         4523 :       if (highlight_color)
    3881         1232 :         pp_string (cxx_pp, colorize_start (show_color, highlight_color));
    3882              :       /* And remember the start of the aka dump.  */
    3883         4523 :       aka_start = obstack_object_size (ob);
    3884         4523 :       dump_type (cxx_pp, aka, flags);
    3885         4523 :       aka_len = obstack_object_size (ob) - aka_start;
    3886         4523 :       if (quote && *quote)
    3887         4066 :         pp_end_quote (cxx_pp, show_color);
    3888         4523 :       pp_right_brace (cxx_pp);
    3889         4523 :       p = (char*)obstack_base (ob);
    3890              :       /* If they are identical, cut off the aka by unwinding the obstack.  */
    3891         4523 :       if (type_len == aka_len
    3892          948 :           && memcmp (p + type_start, p+aka_start, type_len) == 0)
    3893              :         {
    3894              :           /* We can't add a '\0' here, since we may be adding a closing quote
    3895              :              below, and it would be hidden by the '\0'.
    3896              :              Instead, manually unwind the current object within the obstack
    3897              :              so that the insertion point is at the end of the type, before
    3898              :              the "' {aka".  */
    3899          770 :           int delta = type_start + type_len - obstack_object_size (ob);
    3900          770 :           gcc_assert (delta <= 0);
    3901          770 :           obstack_blank_fast (ob, delta);
    3902          770 :         }
    3903              :       else
    3904         3753 :         if (quote)
    3905              :           /* No further closing quotes are needed.  */
    3906         3726 :           *quote = false;
    3907              :     }
    3908              : 
    3909        65520 :   if (quote && *quote)
    3910              :     {
    3911        58028 :       if (show_color && highlight_color)
    3912            0 :         pp_string (cxx_pp, colorize_stop (show_color));
    3913        58028 :       pp_end_quote (cxx_pp, show_color);
    3914        58028 :       *quote = false;
    3915              :     }
    3916        65547 :   return pp_ggc_formatted_text (cxx_pp);
    3917              : }
    3918              : 
    3919              : static const char *
    3920         4022 : args_to_string (tree p, int verbose)
    3921              : {
    3922         4022 :   int flags = 0;
    3923         4022 :   if (verbose)
    3924            0 :     flags |= TFF_CLASS_KEY_OR_ENUM;
    3925              : 
    3926         4022 :   if (p == NULL_TREE)
    3927              :     return "";
    3928              : 
    3929         3118 :   if (TYPE_P (TREE_VALUE (p)))
    3930            0 :     return type_as_string_translate (p, flags);
    3931              : 
    3932         3118 :   reinit_cxx_pp ();
    3933        10030 :   for (; p; p = TREE_CHAIN (p))
    3934              :     {
    3935         3794 :       if (null_node_p (TREE_VALUE (p)))
    3936            3 :         pp_cxx_ws_string (cxx_pp, "NULL");
    3937              :       else
    3938         3791 :         dump_type (cxx_pp, error_type (TREE_VALUE (p)), flags);
    3939         3794 :       if (TREE_CHAIN (p))
    3940          676 :         pp_separate_with_comma (cxx_pp);
    3941              :     }
    3942         3118 :   return pp_ggc_formatted_text (cxx_pp);
    3943              : }
    3944              : 
    3945              : /* Pretty-print a deduction substitution (from deduction_tsubst_fntype).  P
    3946              :    is a TREE_LIST with purpose the TEMPLATE_DECL, value the template
    3947              :    arguments.  */
    3948              : 
    3949              : static const char *
    3950         1651 : subst_to_string (tree p, bool show_color)
    3951              : {
    3952         1651 :   tree decl = TREE_PURPOSE (p);
    3953         1651 :   tree targs = TREE_VALUE (p);
    3954         1651 :   tree tparms = DECL_TEMPLATE_PARMS (decl);
    3955         1651 :   int flags = (TFF_DECL_SPECIFIERS|TFF_TEMPLATE_HEADER
    3956              :                |TFF_NO_TEMPLATE_BINDINGS);
    3957              : 
    3958         1651 :   if (p == NULL_TREE)
    3959              :     return "";
    3960              : 
    3961         1651 :   reinit_cxx_pp ();
    3962         1651 :   pp_show_color (cxx_pp) = show_color;
    3963         1651 :   dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
    3964         1651 :   dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
    3965         1651 :   return pp_ggc_formatted_text (cxx_pp);
    3966              : }
    3967              : 
    3968              : static const char *
    3969          643 : cv_to_string (tree p, int v)
    3970              : {
    3971          643 :   reinit_cxx_pp ();
    3972          643 :   cxx_pp->set_padding (v ? pp_before : pp_none);
    3973          643 :   pp_cxx_cv_qualifier_seq (cxx_pp, p);
    3974          643 :   return pp_ggc_formatted_text (cxx_pp);
    3975              : }
    3976              : 
    3977              : static const char *
    3978           67 : eh_spec_to_string (tree p, int /*v*/)
    3979              : {
    3980           67 :   int flags = 0;
    3981           67 :   reinit_cxx_pp ();
    3982           67 :   dump_exception_spec (cxx_pp, p, flags);
    3983           67 :   return pp_ggc_formatted_text (cxx_pp);
    3984              : }
    3985              : 
    3986              : /* Langhook for print_error_function.  */
    3987              : void
    3988          152 : cxx_print_error_function (diagnostics::text_sink &text_output,
    3989              :                           const char *file,
    3990              :                           const diagnostics::diagnostic_info *diagnostic)
    3991              : {
    3992          152 :   char *prefix;
    3993          152 :   if (file)
    3994          152 :     prefix = xstrdup (file);
    3995              :   else
    3996              :     prefix = NULL;
    3997          152 :   lhd_print_error_function (text_output, file, diagnostic);
    3998              : 
    3999          152 :   pp_set_prefix (text_output.get_printer (), prefix);
    4000          152 :   maybe_print_instantiation_context (text_output);
    4001          152 : }
    4002              : 
    4003              : static void
    4004       259229 : cp_diagnostic_text_starter (diagnostics::text_sink &text_output,
    4005              :                             const diagnostics::diagnostic_info *diagnostic)
    4006              : {
    4007       259229 :   pp_set_prefix (text_output.get_printer (),
    4008              :                  text_output.build_indent_prefix (true));
    4009       259229 :   text_output.report_current_module (diagnostic_location (diagnostic));
    4010       259229 :   cp_print_error_function (text_output, diagnostic);
    4011       259229 :   maybe_print_instantiation_context (text_output);
    4012       259229 :   maybe_print_constexpr_context (text_output);
    4013       259229 :   maybe_print_constraint_context (text_output);
    4014       259229 :   pp_set_prefix (text_output.get_printer (),
    4015              :                  text_output.build_prefix (*diagnostic));
    4016       259229 : }
    4017              : 
    4018              : /* Print current function onto BUFFER, in the process of reporting
    4019              :    a diagnostic message.  Called from cp_diagnostic_starter.  */
    4020              : static void
    4021       259229 : cp_print_error_function (diagnostics::text_sink &text_output,
    4022              :                          const diagnostics::diagnostic_info *diagnostic)
    4023              : {
    4024              :   /* If we are in an instantiation context, current_function_decl is likely
    4025              :      to be wrong, so just rely on print_instantiation_full_context.  */
    4026       259229 :   if (current_instantiation ())
    4027              :     return;
    4028              :   /* The above is true for constraint satisfaction also.  */
    4029       243120 :   if (current_failed_constraint)
    4030              :     return;
    4031       242837 :   diagnostics::context *const context = &text_output.get_context ();
    4032       242837 :   if (diagnostic_last_function_changed (context, diagnostic))
    4033              :     {
    4034        26320 :       pretty_printer *const pp = text_output.get_printer ();
    4035        26320 :       char *old_prefix = pp_take_prefix (pp);
    4036        26320 :       const char *file = LOCATION_FILE (diagnostic_location (diagnostic));
    4037        26320 :       tree abstract_origin = diagnostic_abstract_origin (diagnostic);
    4038        26320 :       char *new_prefix = (file && abstract_origin == NULL)
    4039        26320 :                          ? text_output.file_name_as_prefix (file) : NULL;
    4040              : 
    4041        26320 :       pp_set_prefix (pp, new_prefix);
    4042              : 
    4043        26320 :       if (current_function_decl == NULL)
    4044          983 :         pp_string (pp, _("At global scope:"));
    4045              :       else
    4046              :         {
    4047        25337 :           tree fndecl, ao;
    4048              : 
    4049        25337 :           if (abstract_origin)
    4050              :             {
    4051          404 :               ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
    4052          404 :               gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
    4053              :               fndecl = ao;
    4054              :             }
    4055              :           else
    4056              :             fndecl = current_function_decl;
    4057              : 
    4058        25337 :           pp_printf (pp, function_category (fndecl),
    4059              :                      fndecl);
    4060              : 
    4061        51312 :           while (abstract_origin)
    4062              :             {
    4063          638 :               location_t *locus;
    4064          638 :               tree block = abstract_origin;
    4065              : 
    4066          638 :               locus = &BLOCK_SOURCE_LOCATION (block);
    4067          638 :               fndecl = NULL;
    4068          638 :               block = BLOCK_SUPERCONTEXT (block);
    4069         1404 :               while (block && TREE_CODE (block) == BLOCK
    4070         1523 :                      && BLOCK_ABSTRACT_ORIGIN (block))
    4071              :                 {
    4072          362 :                   ao = BLOCK_ABSTRACT_ORIGIN (block);
    4073          362 :                   if (TREE_CODE (ao) == FUNCTION_DECL)
    4074              :                     {
    4075              :                       fndecl = ao;
    4076              :                       break;
    4077              :                     }
    4078          128 :                   else if (TREE_CODE (ao) != BLOCK)
    4079              :                     break;
    4080              : 
    4081          128 :                   block = BLOCK_SUPERCONTEXT (block);
    4082              :                 }
    4083          638 :               if (fndecl)
    4084              :                 abstract_origin = block;
    4085              :               else
    4086              :                 {
    4087          866 :                   while (block && TREE_CODE (block) == BLOCK)
    4088          462 :                     block = BLOCK_SUPERCONTEXT (block);
    4089              : 
    4090          404 :                   if (block && TREE_CODE (block) == FUNCTION_DECL)
    4091              :                     fndecl = block;
    4092              :                   abstract_origin = NULL;
    4093              :                 }
    4094              :               if (fndecl)
    4095              :                 {
    4096          638 :                   expanded_location s = expand_location (*locus);
    4097          638 :                   pp_character (pp, ',');
    4098          638 :                   pp_newline (pp);
    4099          638 :                   if (s.file != NULL)
    4100              :                     {
    4101          638 :                       if (text_output.show_column_p () && s.column != 0)
    4102          584 :                         pp_printf (pp,
    4103              :                                    G_("    inlined from %qD at %r%s:%d:%d%R"),
    4104              :                                    fndecl,
    4105              :                                    "locus", s.file, s.line, s.column);
    4106              :                       else
    4107           54 :                         pp_printf (pp,
    4108              :                                    G_("    inlined from %qD at %r%s:%d%R"),
    4109              :                                    fndecl,
    4110              :                                    "locus", s.file, s.line);
    4111              : 
    4112              :                     }
    4113              :                   else
    4114            0 :                     pp_printf (pp, G_("    inlined from %qD"),
    4115              :                                fndecl);
    4116              :                 }
    4117              :             }
    4118        25337 :           pp_character (pp, ':');
    4119              :         }
    4120        26320 :       pp_newline (pp);
    4121              : 
    4122        26320 :       diagnostic_set_last_function (context, diagnostic);
    4123        26320 :       pp->set_prefix (old_prefix);
    4124              :     }
    4125              : }
    4126              : 
    4127              : /* Returns a description of FUNCTION using standard terminology.  The
    4128              :    result is a format string of the form "In CATEGORY %qD".  */
    4129              : 
    4130              : static const char *
    4131        25337 : function_category (tree fn)
    4132              : {
    4133              :   /* We can get called from the middle-end for diagnostics of function
    4134              :      clones.  Make sure we have language specific information before
    4135              :      dereferencing it.  */
    4136        25337 :   if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn))
    4137        25337 :       && DECL_FUNCTION_MEMBER_P (fn))
    4138              :     {
    4139         3314 :       if (DECL_STATIC_FUNCTION_P (fn))
    4140              :         return G_("In static member function %qD");
    4141         3133 :       else if (DECL_COPY_CONSTRUCTOR_P (fn))
    4142              :         return G_("In copy constructor %qD");
    4143         6184 :       else if (DECL_CONSTRUCTOR_P (fn))
    4144              :         return G_("In constructor %qD");
    4145         2095 :       else if (DECL_DESTRUCTOR_P (fn))
    4146              :         return G_("In destructor %qD");
    4147         2579 :       else if (LAMBDA_FUNCTION_P (fn))
    4148              :         return G_("In lambda function");
    4149         1367 :       else if (DECL_XOBJ_MEMBER_FUNCTION_P (fn))
    4150           21 :         return G_("In explicit object member function %qD");
    4151              :       else
    4152              :         return G_("In member function %qD");
    4153              :     }
    4154              :   else
    4155              :     return G_("In function %qD");
    4156              : }
    4157              : 
    4158              : /* We expected some kind of tree but instead got T and emitted a diagnostic.
    4159              :    Print the category of T (type, expression, ...) if possible.  */
    4160              : 
    4161              : void
    4162          236 : inform_tree_category (tree t)
    4163              : {
    4164          236 :   const location_t loc = location_of (t);
    4165              : 
    4166          236 :   t = maybe_get_first_fn (t);
    4167          236 :   if (TREE_CODE (t) == TYPE_DECL)
    4168           10 :     t = TREE_TYPE (t);
    4169              : 
    4170          236 :   if (TYPE_P (t))
    4171          100 :     inform (loc, "but %qE is a type", t);
    4172          136 :   else if (EXPR_P (t))
    4173            0 :     inform (loc, "but %qE is an expression", t);
    4174          136 :   else if (DECL_DECOMPOSITION_P (t) && !DECL_DECOMP_IS_BASE (t))
    4175            2 :     inform (loc, "but %qE is a structured binding", t);
    4176          134 :   else if (VAR_P (t))
    4177           46 :     inform (loc, "but %qE is a variable", t);
    4178           88 :   else if (TREE_CODE (t) == PARM_DECL)
    4179            4 :     inform (loc, "but %qE is a parameter", t);
    4180           84 :   else if (TREE_CODE (t) == FUNCTION_DECL)
    4181           24 :     inform (loc, "but %qE is a function", t);
    4182           60 :   else if (TREE_CODE (t) == FIELD_DECL)
    4183            2 :     inform (loc, "but %qE is a data member", t);
    4184           58 :   else if (DECL_FUNCTION_TEMPLATE_P (t))
    4185           10 :     inform (loc, "but %qE is a function template", t);
    4186           48 :   else if (DECL_CLASS_TEMPLATE_P (t))
    4187            6 :     inform (loc, "but %qE is a class template", t);
    4188           42 :   else if (DECL_ALIAS_TEMPLATE_P (t))
    4189            2 :     inform (loc, "but %qE is an alias template", t);
    4190           40 :   else if (variable_template_p (t))
    4191            6 :     inform (loc, "but %qE is a variable template", t);
    4192           34 :   else if (TREE_CODE (t) == NAMESPACE_DECL)
    4193           20 :     inform (loc, "but %qE is a namespace", t);
    4194           14 :   else if (TREE_CODE (t) == CONST_DECL && !DECL_TEMPLATE_PARM_P (t))
    4195            8 :     inform (loc, "but %qE is an enumerator", t);
    4196           10 :   else if (concept_definition_p (t))
    4197            4 :     inform (loc, "but %qE is a concept", t);
    4198          236 : }
    4199              : 
    4200              : /* Disable warnings about missing quoting in GCC diagnostics for
    4201              :    the pp_verbatim calls.  Their format strings deliberately don't
    4202              :    follow GCC diagnostic conventions.  */
    4203              : #if __GNUC__ >= 10
    4204              : #pragma GCC diagnostic push
    4205              : #pragma GCC diagnostic ignored "-Wformat-diag"
    4206              : #endif
    4207              : 
    4208              : /* Report the full context of a current template instantiation,
    4209              :    onto BUFFER.  */
    4210              : static void
    4211         5981 : print_instantiation_full_context (diagnostics::text_sink &text_output)
    4212              : {
    4213         5981 :   struct tinst_level *p = current_instantiation ();
    4214         5981 :   location_t location = input_location;
    4215              : 
    4216         5981 :   if (p)
    4217              :     {
    4218         5981 :       bool show_file
    4219         5981 :         = ((!text_output.show_nesting_p ())
    4220         5981 :            || text_output.show_locations_in_nesting_p ());
    4221         5981 :       char *indent = text_output.build_indent_prefix (true);
    4222         5981 :       bool expansion_stmt_p = TREE_CODE (p->tldcl) == TEMPLATE_FOR_STMT;
    4223        12043 :       pp_verbatim (text_output.get_printer (),
    4224              :                    expansion_stmt_p
    4225              :                    ? G_("%s%s%sIn instantiation of %<template for%> "
    4226              :                         "iteration %E:\n")
    4227         5981 :                    : p->list_p ()
    4228              :                    ? G_("%s%s%sIn substitution of %qS:\n")
    4229              :                    : G_("%s%s%sIn instantiation of %q#D:\n"),
    4230              :                    indent,
    4231         5972 :                    show_file ? LOCATION_FILE (location) : "",
    4232              :                    show_file ? ": " : "",
    4233              :                    expansion_stmt_p
    4234           81 :                    ? TREE_VEC_ELT (p->targs, 0)
    4235         5981 :                    : p->get_node ());
    4236         5981 :       free (indent);
    4237         5981 :       location = p->locus;
    4238         5981 :       p = p->next;
    4239              :     }
    4240              : 
    4241         5981 :   print_instantiation_partial_context (text_output, p, location);
    4242         5981 : }
    4243              : 
    4244              : static void
    4245        14759 : print_location (diagnostics::text_sink &text_output,
    4246              :                 location_t loc)
    4247              : {
    4248        14759 :   expanded_location xloc = expand_location (loc);
    4249        14759 :   pretty_printer *const pp = text_output.get_printer ();
    4250        14759 :   if (text_output.show_column_p ())
    4251         8116 :     pp_verbatim (pp, G_("%r%s:%d:%d:%R   "),
    4252              :                  "locus", xloc.file, xloc.line, xloc.column);
    4253              :   else
    4254         6643 :     pp_verbatim (pp, G_("%r%s:%d:%R   "),
    4255              :                  "locus", xloc.file, xloc.line);
    4256        14759 : }
    4257              : 
    4258              : /* A RAII class for use when emitting a line of contextual information
    4259              :    via pp_verbatim to a diagnostics::text_sink to add before/after
    4260              :    behaviors to the pp_verbatim calls.
    4261              : 
    4262              :    If the text output has show_nesting_p (), then the ctor prints
    4263              :    leading indentation and a bullet point, and the dtor prints
    4264              :    the location on a new line, and calls diagnostic_show_locus, both
    4265              :    with indentation (and no bullet point).
    4266              : 
    4267              :    Otherwise (when the text output has !show_nesting_p), the ctor prints
    4268              :    the location as leading information on the same line, and the
    4269              :    dtor optionally calls diagnostic_show_locus.  */
    4270              : 
    4271              : class auto_context_line
    4272              : {
    4273              : public:
    4274        14795 :   auto_context_line (diagnostics::text_sink &text_output,
    4275              :                      location_t loc,
    4276              :                      bool show_locus = false)
    4277        14795 :   : m_text_output (text_output),
    4278        14795 :     m_loc (loc),
    4279        14795 :     m_show_locus (show_locus),
    4280        14795 :     m_nesting_level (text_output.get_context ().get_diagnostic_nesting_level ()),
    4281        14795 :     m_location_printed (false)
    4282              :   {
    4283        14795 :     char *indent = m_text_output.build_indent_prefix (true);
    4284        14795 :     pp_verbatim (m_text_output.get_printer (), indent);
    4285        14795 :     free (indent);
    4286        14795 :     if (m_nesting_level == 0 || !m_text_output.show_nesting_p ())
    4287              :       {
    4288        14759 :         print_location (m_text_output, m_loc);
    4289        14759 :         m_location_printed = true;
    4290              :       }
    4291        14795 :   }
    4292        14795 :   ~auto_context_line ()
    4293              :   {
    4294        14795 :     pretty_printer *const pp = m_text_output.get_printer ();
    4295        14795 :     if (m_text_output.show_nesting_p ())
    4296              :       {
    4297           47 :         if (m_text_output.show_locations_in_nesting_p ())
    4298              :           {
    4299           11 :             char *indent = m_text_output.build_indent_prefix (false);
    4300           11 :             if (!m_location_printed)
    4301              :               {
    4302            0 :                 pp_verbatim (pp, indent);
    4303            0 :                 print_location (m_text_output, m_loc);
    4304            0 :                 pp_newline (pp);
    4305            0 :                 m_location_printed = true;
    4306              :               }
    4307              : 
    4308           11 :             char *saved_prefix = pp_take_prefix (pp);
    4309           11 :             pp_set_prefix (pp, indent);
    4310           11 :             gcc_rich_location rich_loc (m_loc);
    4311           11 :             diagnostic_show_locus (&m_text_output.get_context (),
    4312           11 :                                    m_text_output.get_source_printing_options (),
    4313              :                                    &rich_loc,
    4314              :                                    diagnostics::kind::note, pp);
    4315           11 :             pp_set_prefix (pp, saved_prefix);
    4316           11 :           }
    4317              :       }
    4318        14748 :     else if (m_show_locus)
    4319              :       {
    4320         8011 :         char *saved_prefix = pp_take_prefix (pp);
    4321         8011 :         pp_set_prefix (pp, nullptr);
    4322         8011 :         gcc_rich_location rich_loc (m_loc);
    4323         8011 :         diagnostic_show_locus (&m_text_output.get_context (),
    4324         8011 :                                m_text_output.get_source_printing_options (),
    4325              :                                &rich_loc,
    4326              :                                diagnostics::kind::note, pp);
    4327         8011 :         pp_set_prefix (pp, saved_prefix);
    4328         8011 :       }
    4329        14795 :   }
    4330              : private:
    4331              :   diagnostics::text_sink &m_text_output;
    4332              :   location_t m_loc;
    4333              :   bool m_show_locus;
    4334              :   int m_nesting_level;
    4335              :   bool m_location_printed;
    4336              : };
    4337              : 
    4338              : /* Helper function of print_instantiation_partial_context() that
    4339              :    prints a single line of instantiation context.  */
    4340              : 
    4341              : static void
    4342         8031 : print_instantiation_partial_context_line (diagnostics::text_sink &text_output,
    4343              :                                           struct tinst_level *t,
    4344              :                                           location_t loc, bool recursive_p)
    4345              : {
    4346         8031 :   if (loc == UNKNOWN_LOCATION)
    4347            0 :     return;
    4348              : 
    4349         8031 :   auto_context_line sentinel (text_output, loc, true);
    4350              : 
    4351         8031 :   pretty_printer *const pp = text_output.get_printer ();
    4352              : 
    4353         8031 :   if (t != NULL)
    4354              :     {
    4355         2050 :       if (TREE_CODE (t->tldcl) == TEMPLATE_FOR_STMT)
    4356            0 :         pp_verbatim (pp,
    4357              :                      recursive_p
    4358              :                      ? G_("recursively required from %<template for%> "
    4359              :                           "iteration %E\n")
    4360              :                      : G_("required from %<template for%> iteration %E\n"),
    4361            0 :                      TREE_VEC_ELT (t->targs, 0));
    4362         2050 :       else if (t->list_p ())
    4363          820 :         pp_verbatim (pp,
    4364              :                      recursive_p
    4365              :                      ? G_("recursively required by substitution of %qS\n")
    4366              :                      : G_("required by substitution of %qS\n"),
    4367              :                      t->get_node ());
    4368              :       else
    4369         3385 :         pp_verbatim (pp,
    4370              :                      recursive_p
    4371              :                      ? G_("recursively required from %q#D\n")
    4372              :                      : G_("required from %q#D\n"),
    4373              :                      t->get_node ());
    4374              :     }
    4375              :   else
    4376              :     {
    4377        11962 :       pp_verbatim (pp,
    4378              :                    recursive_p
    4379              :                    ? G_("recursively required from here\n")
    4380              :                    : G_("required from here\n"));
    4381              :     }
    4382         8031 : }
    4383              : 
    4384              : /* Same as print_instantiation_full_context but less verbose.  */
    4385              : 
    4386              : static void
    4387         5981 : print_instantiation_partial_context (diagnostics::text_sink &text_output,
    4388              :                                      struct tinst_level *t0, location_t loc)
    4389              : {
    4390         5981 :   struct tinst_level *t;
    4391         5981 :   int n_total = 0;
    4392         5981 :   int n;
    4393         5981 :   location_t prev_loc = loc;
    4394              : 
    4395        40953 :   for (t = t0; t != NULL; t = t->next)
    4396        34972 :     if (prev_loc != t->locus)
    4397              :       {
    4398         1981 :         prev_loc = t->locus;
    4399         1981 :         n_total++;
    4400              :       }
    4401              : 
    4402         5981 :   t = t0;
    4403              : 
    4404         5981 :   if (template_backtrace_limit
    4405         5981 :       && n_total > template_backtrace_limit)
    4406              :     {
    4407            0 :       int skip = n_total - template_backtrace_limit;
    4408            0 :       int head = template_backtrace_limit / 2;
    4409              : 
    4410              :       /* Avoid skipping just 1.  If so, skip 2.  */
    4411            0 :       if (skip == 1)
    4412              :        {
    4413            0 :          skip = 2;
    4414            0 :          head = (template_backtrace_limit - 1) / 2;
    4415              :        }
    4416              : 
    4417            0 :       for (n = 0; n < head; n++)
    4418              :         {
    4419            0 :           gcc_assert (t != NULL);
    4420            0 :           if (loc != t->locus)
    4421            0 :             print_instantiation_partial_context_line (text_output, t, loc,
    4422              :                                                       /*recursive_p=*/false);
    4423            0 :           loc = t->locus;
    4424            0 :           t = t->next;
    4425              :         }
    4426            0 :       if (t != NULL && skip > 0)
    4427              :         {
    4428            0 :           auto_context_line sentinel (text_output, loc);
    4429            0 :           pp_verbatim (text_output.get_printer (),
    4430              :                        G_("[ skipping %d instantiation contexts,"
    4431              :                           " use -ftemplate-backtrace-limit=0 to disable ]\n"),
    4432              :                        skip);
    4433            0 :           do {
    4434            0 :             loc = t->locus;
    4435            0 :             t = t->next;
    4436            0 :           } while (t != NULL && --skip > 0);
    4437            0 :         }
    4438              :     }
    4439              : 
    4440         8031 :   while (t != NULL)
    4441              :     {
    4442        34972 :       while (t->next != NULL && t->locus == t->next->locus)
    4443              :         {
    4444              :           loc = t->locus;
    4445              :           t = t->next;
    4446              :         }
    4447         2050 :       print_instantiation_partial_context_line (text_output, t, loc,
    4448         2050 :                                                 t->locus == loc);
    4449         2050 :       loc = t->locus;
    4450         2050 :       t = t->next;
    4451              :     }
    4452         5981 :   print_instantiation_partial_context_line (text_output, NULL, loc,
    4453              :                                             /*recursive_p=*/false);
    4454         5981 : }
    4455              : 
    4456              : /* Called from cp_thing to print the template context for an error.  */
    4457              : static void
    4458       259381 : maybe_print_instantiation_context (diagnostics::text_sink &text_output)
    4459              : {
    4460       259381 :   if (!problematic_instantiation_changed () || current_instantiation () == 0)
    4461              :     return;
    4462              : 
    4463         5981 :   record_last_problematic_instantiation ();
    4464         5981 :   print_instantiation_full_context (text_output);
    4465              : }
    4466              : 
    4467              : /* Report what constexpr call(s) we're trying to expand, if any.  */
    4468              : 
    4469              : void
    4470       259229 : maybe_print_constexpr_context (diagnostics::text_sink &text_output)
    4471              : {
    4472       259229 :   vec<tree> call_stack = cx_error_context ();
    4473       259229 :   unsigned ix;
    4474       259229 :   tree t;
    4475              : 
    4476       523391 :   FOR_EACH_VEC_ELT (call_stack, ix, t)
    4477              :     {
    4478         4933 :       const char *s = expr_as_string (t, 0);
    4479         4933 :       pretty_printer *const pp = text_output.get_printer ();
    4480         4933 :       auto_context_line sentinel (text_output, EXPR_LOCATION (t));
    4481         4933 :       pp_verbatim (pp,
    4482              :                    G_("in %<constexpr%> expansion of %qs"),
    4483              :                    s);
    4484         4933 :       pp_newline (pp);
    4485         4933 :     }
    4486       259229 : }
    4487              : 
    4488              : 
    4489              : static void
    4490          658 : print_constrained_decl_info (diagnostics::text_sink &text_output,
    4491              :                              tree decl)
    4492              : {
    4493          658 :   auto_context_line sentinel (text_output, DECL_SOURCE_LOCATION (decl));
    4494          658 :   pretty_printer *const pp = text_output.get_printer ();
    4495          658 :   pp_verbatim (pp, G_("required by the constraints of %q#D\n"), decl);
    4496          658 : }
    4497              : 
    4498              : static void
    4499          834 : print_concept_check_info (diagnostics::text_sink &text_output,
    4500              :                           tree expr, tree map, tree args)
    4501              : {
    4502          834 :   gcc_assert (concept_check_p (expr));
    4503              : 
    4504          834 :   tree tmpl = TREE_OPERAND (expr, 0);
    4505              : 
    4506          834 :   auto_context_line sentinel (text_output, DECL_SOURCE_LOCATION (tmpl));
    4507              : 
    4508          834 :   cxx_pretty_printer *const pp
    4509          834 :     = (cxx_pretty_printer *)text_output.get_printer ();
    4510          834 :   pp_verbatim (pp, G_("required for the satisfaction of %qE"), expr);
    4511          834 :   if (map && map != error_mark_node)
    4512              :     {
    4513          816 :       tree subst_map = tsubst_parameter_mapping (map, args, tf_none, NULL_TREE);
    4514          818 :       pp_cxx_parameter_mapping (pp, (subst_map != error_mark_node
    4515              :                                      ? subst_map : map));
    4516              :     }
    4517          834 :   pp_newline (pp);
    4518          834 : }
    4519              : 
    4520              : /* Diagnose the entry point into the satisfaction error. Returns the next
    4521              :    context, if any.  */
    4522              : 
    4523              : static tree
    4524         1416 : print_constraint_context_head (diagnostics::text_sink &text_output,
    4525              :                                tree cxt, tree args)
    4526              : {
    4527         1416 :   tree src = TREE_VALUE (cxt);
    4528         1416 :   if (!src)
    4529              :     {
    4530            0 :       auto_context_line sentinel (text_output, input_location);
    4531            0 :       pretty_printer *const pp = text_output.get_printer ();
    4532            0 :       pp_verbatim (pp, G_("required for constraint satisfaction\n"));
    4533            0 :       return NULL_TREE;
    4534            0 :     }
    4535         1416 :   if (DECL_P (src))
    4536              :     {
    4537          658 :       print_constrained_decl_info (text_output, src);
    4538          658 :       return NULL_TREE;
    4539              :     }
    4540              :   else
    4541              :     {
    4542          758 :       print_concept_check_info (text_output, src, TREE_PURPOSE (cxt), args);
    4543          758 :       return TREE_CHAIN (cxt);
    4544              :     }
    4545              : }
    4546              : 
    4547              : static void
    4548          341 : print_requires_expression_info (diagnostics::text_sink &text_output,
    4549              :                                 tree constr, tree args)
    4550              : {
    4551              : 
    4552          341 :   tree expr = ATOMIC_CONSTR_EXPR (constr);
    4553          341 :   tree map = ATOMIC_CONSTR_MAP (constr);
    4554          341 :   map = tsubst_parameter_mapping (map, args, tf_none, NULL_TREE);
    4555          341 :   if (map == error_mark_node)
    4556            2 :     return;
    4557              : 
    4558          339 :   auto_context_line sentinel (text_output, cp_expr_loc_or_input_loc (expr));
    4559          339 :   cxx_pretty_printer *const pp
    4560          339 :     = static_cast <cxx_pretty_printer *> (text_output.get_printer ());
    4561              : 
    4562          339 :   tree parms = REQUIRES_EXPR_PARMS (expr);
    4563          339 :   pp_verbatim (pp, parms ? G_("in requirements with ")
    4564              :                          : G_("in requirements "));
    4565          977 :   while (parms)
    4566              :     {
    4567          299 :       pp_verbatim (pp, "%q#D", parms);
    4568          299 :       if (TREE_CHAIN (parms))
    4569           97 :         pp_separate_with_comma (pp);
    4570          299 :       parms = TREE_CHAIN (parms);
    4571              :     }
    4572          339 :   pp_cxx_parameter_mapping (pp, map);
    4573              : 
    4574          339 :   pp_verbatim (pp, "\n");
    4575          339 : }
    4576              : 
    4577              : void
    4578         1443 : maybe_print_single_constraint_context (diagnostics::text_sink &text_output,
    4579              :                                        tree failed)
    4580              : {
    4581         1443 :   if (!failed)
    4582              :     return;
    4583              : 
    4584         1443 :   tree constr = TREE_VALUE (failed);
    4585         1443 :   if (!constr || constr == error_mark_node)
    4586              :     return;
    4587         1443 :   tree cxt = CONSTR_CONTEXT (constr);
    4588         1443 :   if (!cxt)
    4589              :     return;
    4590         1416 :   tree args = TREE_PURPOSE (failed);
    4591              : 
    4592              :   /* Print the stack of requirements.  */
    4593         1416 :   cxt = print_constraint_context_head (text_output, cxt, args);
    4594         3610 :   while (cxt && !DECL_P (TREE_VALUE (cxt)))
    4595              :     {
    4596           76 :       tree expr = TREE_VALUE (cxt);
    4597           76 :       tree map = TREE_PURPOSE (cxt);
    4598           76 :       print_concept_check_info (text_output, expr, map, args);
    4599           76 :       cxt = TREE_CHAIN (cxt);
    4600              :     }
    4601              : 
    4602              :   /* For certain constraints, we can provide additional context.  */
    4603         1416 :   if (TREE_CODE (constr) == ATOMIC_CONSTR
    4604         1416 :       && TREE_CODE (ATOMIC_CONSTR_EXPR (constr)) == REQUIRES_EXPR)
    4605          341 :     print_requires_expression_info (text_output, constr, args);
    4606              : }
    4607              : 
    4608              : void
    4609       259232 : maybe_print_constraint_context (diagnostics::text_sink &text_output)
    4610              : {
    4611       259232 :   if (!current_failed_constraint)
    4612              :     return;
    4613              : 
    4614         1443 :   tree cur = current_failed_constraint;
    4615              : 
    4616              :   /* Recursively print nested contexts.  */
    4617         1443 :   current_failed_constraint = TREE_CHAIN (current_failed_constraint);
    4618         1443 :   if (current_failed_constraint)
    4619            3 :     maybe_print_constraint_context (text_output);
    4620              : 
    4621              :   /* Print this context.  */
    4622         1443 :   maybe_print_single_constraint_context (text_output, cur);
    4623              : }
    4624              : 
    4625              : /* Return true iff TYPE_A and TYPE_B are template types that are
    4626              :    meaningful to compare.  */
    4627              : 
    4628              : static bool
    4629        11672 : comparable_template_types_p (tree type_a, tree type_b)
    4630              : {
    4631        11672 :   if (!CLASS_TYPE_P (type_a))
    4632              :     return false;
    4633         1392 :   if (!CLASS_TYPE_P (type_b))
    4634              :     return false;
    4635              : 
    4636          442 :   tree tinfo_a = TYPE_TEMPLATE_INFO (type_a);
    4637          442 :   tree tinfo_b = TYPE_TEMPLATE_INFO (type_b);
    4638          442 :   if (!tinfo_a || !tinfo_b)
    4639              :     return false;
    4640              : 
    4641          279 :   return TI_TEMPLATE (tinfo_a) == TI_TEMPLATE (tinfo_b);
    4642              : }
    4643              : 
    4644              : /* Start a new line indented by SPC spaces on PP.  */
    4645              : 
    4646              : static void
    4647          228 : newline_and_indent (pretty_printer *pp, int spc)
    4648              : {
    4649          228 :   pp_newline (pp);
    4650         1248 :   for (int i = 0; i < spc; i++)
    4651          792 :     pp_space (pp);
    4652          228 : }
    4653              : 
    4654              : /* Generate a GC-allocated string for ARG, an expression or type.  */
    4655              : 
    4656              : static const char *
    4657          682 : arg_to_string (tree arg, bool verbose)
    4658              : {
    4659          682 :   if (TYPE_P (arg))
    4660          420 :     return type_to_string (arg, verbose, true, NULL, false);
    4661              :   else
    4662          262 :     return expr_to_string (arg);
    4663              : }
    4664              : 
    4665              : /* Subroutine to type_to_string_with_compare and
    4666              :    print_template_tree_comparison.
    4667              : 
    4668              :    Print a representation of ARG (an expression or type) to PP,
    4669              :    colorizing it if PP->show_color, using HIGHLIGHT_COLOR,
    4670              :    or "type-diff" if the latter is NULL.  */
    4671              : 
    4672              : static void
    4673          670 : print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose,
    4674              :                     const char *highlight_color)
    4675              : {
    4676          670 :   if (!highlight_color)
    4677           10 :     highlight_color = "type-diff";
    4678         1340 :   pp_printf (pp, "%r%s%R",
    4679              :              highlight_color,
    4680              :              (arg
    4681          670 :               ? arg_to_string (arg, verbose)
    4682              :               : G_("(no argument)")));
    4683          670 : }
    4684              : 
    4685              : /* Recursively print template TYPE_A to PP, as compared to template TYPE_B.
    4686              : 
    4687              :    The types must satisfy comparable_template_types_p.
    4688              : 
    4689              :    If INDENT is 0, then this is equivalent to type_to_string (TYPE_A), but
    4690              :    potentially colorizing/eliding in comparison with TYPE_B.
    4691              : 
    4692              :    For example given types:
    4693              :      vector<map<int,double>>
    4694              :    and
    4695              :      vector<map<int,float>>
    4696              :    then the result on PP would be:
    4697              :      vector<map<[...],double>>
    4698              :    with type elision, and:
    4699              :      vector<map<int,double>>
    4700              :    without type elision.
    4701              : 
    4702              :    In both cases the parts of TYPE that differ from PEER will be colorized
    4703              :    if pp_show_color (pp) is true.  In the above example, this would be
    4704              :    "double".
    4705              : 
    4706              :    If INDENT is non-zero, then the types are printed in a tree-like form
    4707              :    which shows both types.  In the above example, the result on PP would be:
    4708              : 
    4709              :      vector<
    4710              :        map<
    4711              :          [...],
    4712              :          [double != float]>>
    4713              : 
    4714              :    and without type-elision would be:
    4715              : 
    4716              :      vector<
    4717              :        map<
    4718              :          int,
    4719              :          [double != float]>>
    4720              : 
    4721              :    As before, the differing parts of the types are colorized if
    4722              :    pp_show_color (pp) is true ("double" and "float" in this example).
    4723              : 
    4724              :    Template arguments in which both types are using the default arguments
    4725              :    are not printed; if at least one of the two types is using a non-default
    4726              :    argument, then that argument is printed (or both arguments for the
    4727              :    tree-like print format).  */
    4728              : 
    4729              : static void
    4730          497 : print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
    4731              :                             bool verbose, int indent,
    4732              :                             const char *highlight_color_a,
    4733              :                             const char *highlight_color_b)
    4734              : {
    4735          497 :   if (indent)
    4736           85 :     newline_and_indent (pp, indent);
    4737              : 
    4738          497 :   tree tinfo_a = TYPE_TEMPLATE_INFO (type_a);
    4739          497 :   tree tinfo_b = TYPE_TEMPLATE_INFO (type_b);
    4740              : 
    4741          497 :   pp_printf (pp, "%s<",
    4742          497 :              IDENTIFIER_POINTER (DECL_NAME (TI_TEMPLATE (tinfo_a))));
    4743              : 
    4744          497 :   tree args_a = TI_ARGS (tinfo_a);
    4745          497 :   tree args_b = TI_ARGS (tinfo_b);
    4746          497 :   gcc_assert (TREE_CODE (args_a) == TREE_VEC);
    4747          497 :   gcc_assert (TREE_CODE (args_b) == TREE_VEC);
    4748          497 :   int flags = 0;
    4749          497 :   int len_a = get_non_default_template_args_count (args_a, flags);
    4750          497 :   args_a = INNERMOST_TEMPLATE_ARGS (args_a);
    4751          497 :   int len_b = get_non_default_template_args_count (args_b, flags);
    4752          497 :   args_b = INNERMOST_TEMPLATE_ARGS (args_b);
    4753              :   /* Determine the maximum range of args for which non-default template args
    4754              :      were used; beyond this, only default args (if any) were used, and so
    4755              :      they will be equal from this point onwards.
    4756              :      One of the two peers might have used default arguments within this
    4757              :      range, but the other will be using non-default arguments, and so
    4758              :      it's more readable to print both within this range, to highlight
    4759              :      the differences.  */
    4760          497 :   int len_max = MAX (len_a, len_b);
    4761          497 :   gcc_assert (TREE_CODE (args_a) == TREE_VEC);
    4762          497 :   gcc_assert (TREE_CODE (args_b) == TREE_VEC);
    4763         1224 :   for (int idx = 0; idx < len_max; idx++)
    4764              :     {
    4765          727 :       if (idx)
    4766          230 :         pp_character (pp, ',');
    4767              : 
    4768          727 :       tree arg_a = TREE_VEC_ELT (args_a, idx);
    4769          727 :       tree arg_b = TREE_VEC_ELT (args_b, idx);
    4770          727 :       if (arg_a == arg_b)
    4771              :         {
    4772          128 :           if (indent)
    4773           39 :             newline_and_indent (pp, indent + 2);
    4774              :           /* Can do elision here, printing "[...]".  */
    4775          128 :           if (flag_elide_type)
    4776          116 :             pp_string (pp, G_("[...]"));
    4777              :           else
    4778           12 :             pp_string (pp, arg_to_string (arg_a, verbose));
    4779              :         }
    4780              :       else
    4781              :         {
    4782          599 :           int new_indent = indent ? indent + 2 : 0;
    4783          599 :           if (comparable_template_types_p (arg_a, arg_b))
    4784           33 :             print_template_differences (pp, arg_a, arg_b, verbose, new_indent,
    4785              :                                         highlight_color_a, highlight_color_b);
    4786              :           else
    4787          566 :             if (indent)
    4788              :               {
    4789          104 :                 newline_and_indent (pp, indent + 2);
    4790          104 :                 pp_character (pp, '[');
    4791          104 :                 print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
    4792          104 :                 pp_string (pp, " != ");
    4793          104 :                 print_nonequal_arg (pp, arg_b, verbose, highlight_color_b);
    4794          104 :                 pp_character (pp, ']');
    4795              :               }
    4796              :             else
    4797          462 :               print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
    4798              :         }
    4799              :     }
    4800          497 :   pp_printf (pp, ">");
    4801          497 : }
    4802              : 
    4803              : /* As type_to_string, but for a template, potentially colorizing/eliding
    4804              :    in comparison with PEER.
    4805              :    For example, if TYPE is map<int,double> and PEER is map<int,int>,
    4806              :    then the resulting string would be:
    4807              :      map<[...],double>
    4808              :    with type elision, and:
    4809              :      map<int,double>
    4810              :    without type elision.
    4811              : 
    4812              :    In both cases the parts of TYPE that differ from PEER will be colorized
    4813              :    if SHOW_COLOR is true.  In the above example, this would be "double".
    4814              : 
    4815              :    Template arguments in which both types are using the default arguments
    4816              :    are not printed; if at least one of the two types is using a non-default
    4817              :    argument, then both arguments are printed.
    4818              : 
    4819              :    The resulting string is in a GC-allocated buffer.  */
    4820              : 
    4821              : static const char *
    4822          390 : type_to_string_with_compare (tree type, tree peer, bool verbose,
    4823              :                              bool show_color,
    4824              :                              const char *this_highlight_color,
    4825              :                              const char *peer_highlight_color)
    4826              : {
    4827          390 :   pretty_printer inner_pp;
    4828          390 :   pretty_printer *pp = &inner_pp;
    4829          390 :   pp_show_color (pp) = show_color;
    4830              : 
    4831          390 :   print_template_differences (pp, type, peer, verbose, 0,
    4832              :                               this_highlight_color, peer_highlight_color);
    4833          390 :   return pp_ggc_formatted_text (pp);
    4834          390 : }
    4835              : 
    4836              : /* Recursively print a tree-like comparison of TYPE_A and TYPE_B to PP,
    4837              :    indented by INDENT spaces.
    4838              : 
    4839              :    For example given types:
    4840              : 
    4841              :      vector<map<int,double>>
    4842              : 
    4843              :    and
    4844              : 
    4845              :      vector<map<double,float>>
    4846              : 
    4847              :    the output with type elision would be:
    4848              : 
    4849              :      vector<
    4850              :        map<
    4851              :          [...],
    4852              :          [double != float]>>
    4853              : 
    4854              :    and without type-elision would be:
    4855              : 
    4856              :      vector<
    4857              :        map<
    4858              :          int,
    4859              :          [double != float]>>
    4860              : 
    4861              :    TYPE_A and TYPE_B must both be comparable template types
    4862              :    (as per comparable_template_types_p).
    4863              : 
    4864              :    Template arguments in which both types are using the default arguments
    4865              :    are not printed; if at least one of the two types is using a non-default
    4866              :    argument, then both arguments are printed.  */
    4867              : 
    4868              : static void
    4869           74 : print_template_tree_comparison (pretty_printer *pp, tree type_a, tree type_b,
    4870              :                                 bool verbose, int indent,
    4871              :                                 const char *highlight_color_a,
    4872              :                                 const char *highlight_color_b)
    4873              : {
    4874            0 :   print_template_differences (pp, type_a, type_b, verbose, indent,
    4875              :                               highlight_color_a,
    4876              :                               highlight_color_b);
    4877            0 : }
    4878              : 
    4879              : /* Subroutine for use in a format_postprocessor::handle
    4880              :    implementation.  Adds a chunk to the end of
    4881              :    formatted output, so that it will be printed
    4882              :    by pp_output_formatted_text.  */
    4883              : 
    4884              : static void
    4885           74 : append_formatted_chunk (pretty_printer *pp, const char *content)
    4886              : {
    4887           74 :   output_buffer *buffer = pp_buffer (pp);
    4888           74 :   pp_formatted_chunks *chunk_array = buffer->m_cur_formatted_chunks;
    4889            0 :   chunk_array->append_formatted_chunk (buffer->m_chunk_obstack, content);
    4890            0 : }
    4891              : 
    4892              : #if __GNUC__ >= 10
    4893              : #pragma GCC diagnostic pop
    4894              : #endif
    4895              : 
    4896              : /* If we had %H and %I, and hence deferred printing them,
    4897              :    print them now, storing the result into custom_token_value
    4898              :    for the custom pp_token.  Quote them if 'q' was provided.
    4899              :    Also print the difference in tree form, adding it as
    4900              :    an additional chunk.  */
    4901              : 
    4902              : void
    4903       392934 : cxx_format_postprocessor::handle (pretty_printer *pp)
    4904              : {
    4905              :   /* If we have one of %H and %I, the other should have
    4906              :      been present.  */
    4907       392934 :   if (m_type_a.m_tree || m_type_b.m_tree)
    4908              :     {
    4909        10639 :       const bool show_highlight_colors = pp_show_highlight_colors (pp);
    4910        10639 :       const char *percent_h
    4911        10639 :         = show_highlight_colors ? highlight_colors::percent_h : nullptr;
    4912            2 :       const char *percent_i
    4913              :         = show_highlight_colors ? highlight_colors::percent_i : nullptr;
    4914              :       /* Avoid reentrancy issues by working with a copy of
    4915              :          m_type_a and m_type_b, resetting them now.  */
    4916        10639 :       deferred_printed_type type_a = std::move (m_type_a);
    4917        10639 :       deferred_printed_type type_b = std::move (m_type_b);
    4918        10639 :       m_type_a = deferred_printed_type ();
    4919        10639 :       m_type_b = deferred_printed_type ();
    4920              : 
    4921        10639 :       gcc_assert (type_a.m_token_list);
    4922        10639 :       gcc_assert (type_b.m_token_list);
    4923              : 
    4924        10639 :       bool show_color = pp_show_color (pp);
    4925              : 
    4926        10639 :       const char *type_a_text;
    4927        10639 :       const char *type_b_text;
    4928              : 
    4929        10639 :       if (comparable_template_types_p (type_a.m_tree, type_b.m_tree))
    4930              :         {
    4931          194 :           type_a_text = type_to_string_with_compare
    4932          194 :             (type_a.m_tree, type_b.m_tree,
    4933              :              type_a.m_verbose, show_color,
    4934              :              percent_h, percent_i);
    4935          194 :           type_b_text = type_to_string_with_compare
    4936          194 :             (type_b.m_tree, type_a.m_tree,
    4937              :              type_b.m_verbose, show_color,
    4938              :              percent_i, percent_h);
    4939              : 
    4940          194 :           if (flag_diagnostics_show_template_tree)
    4941              :             {
    4942           74 :               pretty_printer inner_pp;
    4943           74 :               pp_show_color (&inner_pp) = pp_show_color (pp);
    4944           74 :               print_template_tree_comparison
    4945           74 :                 (&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2,
    4946              :                  percent_h, percent_i);
    4947           74 :               append_formatted_chunk (pp, pp_ggc_formatted_text (&inner_pp));
    4948           74 :             }
    4949              :         }
    4950              :       else
    4951              :         {
    4952              :           /* If the types were not comparable (or if only one of %H/%I was
    4953              :              provided), they are printed normally, and no difference tree
    4954              :              is printed.  */
    4955        10445 :           type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose,
    4956              :                                         true, &type_a.m_quote, show_color,
    4957              :                                         percent_h);
    4958        10445 :           type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose,
    4959              :                                         true, &type_b.m_quote, show_color,
    4960              :                                         percent_i);
    4961              :         }
    4962              : 
    4963        10639 :       type_a.set_text_for_token_list (type_a_text, type_a.m_quote);
    4964        10639 :       type_b.set_text_for_token_list (type_b_text, type_b.m_quote);
    4965        10639 :    }
    4966       392934 : }
    4967              : 
    4968              : /* Subroutine for handling %H and %I, to support i18n of messages like:
    4969              : 
    4970              :     error_at (loc, "could not convert %qE from %qH to %qI",
    4971              :                expr, type_a, type_b);
    4972              : 
    4973              :    so that we can print things like:
    4974              : 
    4975              :      could not convert 'foo' from 'map<int,double>' to 'map<int,int>'
    4976              : 
    4977              :    and, with type-elision:
    4978              : 
    4979              :      could not convert 'foo' from 'map<[...],double>' to 'map<[...],int>'
    4980              : 
    4981              :    (with color-coding of the differences between the types).
    4982              : 
    4983              :    The %H and %I format codes are peers: both must be present,
    4984              :    and they affect each other.  Hence to handle them, we must
    4985              :    delay printing until we have both, deferring the printing to
    4986              :    pretty_printer's m_format_postprocessor hook.
    4987              : 
    4988              :    This is called in phase 2 of pp_format, when it is accumulating
    4989              :    a series of pp_token lists.  Since we have to interact with the
    4990              :    fiddly quoting logic for "aka", we store the pp_token_list *
    4991              :    and in the m_format_postprocessor hook we generate text for the type
    4992              :    (possibly with quotes and colors), then replace all tokens in that token list
    4993              :    (such as [BEGIN_QUOTE, END_QUOTE]) with a text token containing the
    4994              :    freshly generated text.
    4995              : 
    4996              :    We also need to stash whether a 'q' prefix was provided (the QUOTE
    4997              :    param)  so that we can add the quotes when writing out the delayed
    4998              :    chunk.  */
    4999              : 
    5000              : static void
    5001        21278 : defer_phase_2_of_type_diff (deferred_printed_type *deferred,
    5002              :                             tree type,
    5003              :                             pp_token_list &formatted_token_list,
    5004              :                             bool verbose, bool quote)
    5005              : {
    5006        21278 :   gcc_assert (deferred->m_tree == NULL_TREE);
    5007        21278 :   *deferred = deferred_printed_type (type, formatted_token_list,
    5008        21278 :                                      verbose, quote);
    5009        21278 : }
    5010              : 
    5011              : /* Implementation of pp_markup::element_quoted_type::print_type
    5012              :    for C++/ObjC++.  */
    5013              : 
    5014              : void
    5015          752 : pp_markup::element_quoted_type::print_type (pp_markup::context &ctxt)
    5016              : {
    5017          752 :   const char *highlight_color
    5018          752 :     = pp_show_highlight_colors (&ctxt.m_pp) ? m_highlight_color : nullptr;
    5019          752 :   const char *result
    5020         1504 :     = type_to_string (m_type, false, false, &ctxt.m_quoted,
    5021          752 :                       pp_show_color (&ctxt.m_pp), highlight_color);
    5022          752 :   pp_string (&ctxt.m_pp, result);
    5023          752 : }
    5024              : 
    5025              : /* Called from output_format -- during diagnostic message processing --
    5026              :    to handle C++ specific format specifier with the following meanings:
    5027              :    %A   function argument-list.
    5028              :    %C   tree code.
    5029              :    %D   declaration.
    5030              :    %E   expression.
    5031              :    %F   function declaration.
    5032              :    %H   type difference (from).
    5033              :    %I   type difference (to).
    5034              :    %L   language as used in extern "lang".
    5035              :    %O   binary operator.
    5036              :    %P   function parameter whose position is indicated by an integer.
    5037              :    %Q   assignment operator.
    5038              :    %S   substitution (template + args)
    5039              :    %T   type.
    5040              :    %V   cv-qualifier.
    5041              :    %X   exception-specification.  */
    5042              : static bool
    5043       229789 : cp_printer (pretty_printer *pp, text_info *text, const char *spec,
    5044              :             int precision, bool wide, bool set_locus, bool verbose,
    5045              :             bool *quoted, pp_token_list &formatted_token_list)
    5046              : {
    5047       229789 :   gcc_assert (pp_format_postprocessor (pp));
    5048       229789 :   cxx_format_postprocessor *postprocessor
    5049       229789 :     = static_cast <cxx_format_postprocessor *> (pp_format_postprocessor (pp));
    5050              : 
    5051       229789 :   const char *result;
    5052       229789 :   tree t = NULL;
    5053              : #define next_tree    (t = va_arg (*text->m_args_ptr, tree))
    5054              : #define next_tcode   ((enum tree_code) va_arg (*text->m_args_ptr, int))
    5055              : #define next_lang    ((enum languages) va_arg (*text->m_args_ptr, int))
    5056              : #define next_int     va_arg (*text->m_args_ptr, int)
    5057              : 
    5058       229789 :   if (precision != 0 || wide)
    5059              :     return false;
    5060              : 
    5061       229789 :   switch (*spec)
    5062              :     {
    5063         4022 :     case 'A': result = args_to_string (next_tree, verbose);     break;
    5064            0 :     case 'C': result = code_to_string (next_tcode);             break;
    5065       104108 :     case 'D':
    5066       104108 :       {
    5067       104108 :         tree temp = next_tree;
    5068       104108 :         if (VAR_P (temp)
    5069       104108 :             && DECL_HAS_DEBUG_EXPR_P (temp))
    5070              :           {
    5071           18 :             temp = DECL_DEBUG_EXPR (temp);
    5072           18 :             if (!DECL_P (temp))
    5073              :               {
    5074           18 :                 result = expr_to_string (temp);
    5075           18 :                 break;
    5076              :               }
    5077              :           }
    5078       104090 :         result = decl_to_string (temp, verbose, pp_show_color (pp));
    5079              :       }
    5080       104090 :       break;
    5081        52679 :     case 'E': result = expr_to_string (next_tree);              break;
    5082          372 :     case 'F': result = fndecl_to_string (next_tree, verbose);   break;
    5083        10639 :     case 'H':
    5084        10639 :       defer_phase_2_of_type_diff (&postprocessor->m_type_a, next_tree,
    5085              :                                   formatted_token_list, verbose, *quoted);
    5086        10639 :       return true;
    5087        10639 :     case 'I':
    5088        10639 :       defer_phase_2_of_type_diff (&postprocessor->m_type_b, next_tree,
    5089              :                                   formatted_token_list, verbose, *quoted);
    5090        10639 :       return true;
    5091           24 :     case 'L': result = language_to_string (next_lang);          break;
    5092          308 :     case 'O': result = op_to_string (false, next_tcode);        break;
    5093         1563 :     case 'P': result = parm_to_string (next_int);               break;
    5094           24 :     case 'Q': result = op_to_string (true, next_tcode);         break;
    5095         1651 :     case 'S': result = subst_to_string (next_tree, pp_show_color (pp)); break;
    5096        43050 :     case 'T':
    5097        43050 :       {
    5098        86100 :         result = type_to_string (next_tree, verbose, false, quoted,
    5099        43050 :                                  pp_show_color (pp));
    5100              :       }
    5101        43050 :       break;
    5102          643 :     case 'V': result = cv_to_string (next_tree, verbose);       break;
    5103           67 :     case 'X': result = eh_spec_to_string (next_tree, verbose);  break;
    5104              : 
    5105              :     default:
    5106              :       return false;
    5107              :     }
    5108              : 
    5109       208511 :   pp_string (pp, result);
    5110       208511 :   if (set_locus && t != NULL)
    5111         2025 :     text->set_location (0, location_of (t), SHOW_RANGE_WITH_CARET);
    5112              :   return true;
    5113              : #undef next_tree
    5114              : #undef next_tcode
    5115              : #undef next_lang
    5116              : #undef next_int
    5117              : }
    5118              : 
    5119              : /* Warn about the use of C++0x features when appropriate.  */
    5120              : void
    5121     91054485 : maybe_warn_cpp0x (cpp0x_warn_str str, location_t loc/*=input_location*/)
    5122              : {
    5123     91054485 :   if (cxx_dialect == cxx98)
    5124         4656 :     switch (str)
    5125              :       {
    5126          186 :       case CPP0X_INITIALIZER_LISTS:
    5127          186 :         pedwarn (loc, OPT_Wc__11_extensions,
    5128              :                  "extended initializer lists "
    5129              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5130          186 :         break;
    5131            0 :       case CPP0X_EXPLICIT_CONVERSION:
    5132            0 :         pedwarn (loc, OPT_Wc__11_extensions,
    5133              :                  "explicit conversion operators "
    5134              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5135            0 :         break;
    5136         1390 :       case CPP0X_VARIADIC_TEMPLATES:
    5137         1390 :         pedwarn (loc, OPT_Wc__11_extensions,
    5138              :                  "variadic templates "
    5139              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5140         1390 :         break;
    5141            6 :       case CPP0X_LAMBDA_EXPR:
    5142            6 :         pedwarn (loc, OPT_Wc__11_extensions,
    5143              :                  "lambda expressions "
    5144              :                   "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5145            6 :         break;
    5146            0 :       case CPP0X_AUTO:
    5147            0 :         pedwarn (loc, OPT_Wc__11_extensions,
    5148              :                  "C++11 auto only available with %<-std=c++11%> or "
    5149              :                  "%<-std=gnu++11%>");
    5150            0 :         break;
    5151           16 :       case CPP0X_SCOPED_ENUMS:
    5152           16 :         pedwarn (loc, OPT_Wc__11_extensions,
    5153              :                  "scoped enums only available with %<-std=c++11%> or "
    5154              :                  "%<-std=gnu++11%>");
    5155           16 :         break;
    5156          824 :       case CPP0X_DEFAULTED_DELETED:
    5157          824 :         pedwarn (loc, OPT_Wc__11_extensions,
    5158              :                  "defaulted and deleted functions "
    5159              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5160          824 :         break;
    5161         1941 :       case CPP0X_INLINE_NAMESPACES:
    5162         1941 :         if (pedantic)
    5163          581 :           pedwarn (loc, OPT_Wc__11_extensions,
    5164              :                    "inline namespaces "
    5165              :                    "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5166              :         break;
    5167            3 :       case CPP0X_OVERRIDE_CONTROLS:
    5168            3 :         pedwarn (loc, OPT_Wc__11_extensions,
    5169              :                  "override controls (override/final) "
    5170              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5171            3 :         break;
    5172          132 :       case CPP0X_NSDMI:
    5173          132 :         pedwarn (loc, OPT_Wc__11_extensions,
    5174              :                  "non-static data member initializers "
    5175              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5176          132 :         break;
    5177            4 :       case CPP0X_USER_DEFINED_LITERALS:
    5178            4 :         pedwarn (loc, OPT_Wc__11_extensions,
    5179              :                  "user-defined literals "
    5180              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5181            4 :         break;
    5182            3 :       case CPP0X_DELEGATING_CTORS:
    5183            3 :         pedwarn (loc, OPT_Wc__11_extensions,
    5184              :                  "delegating constructors "
    5185              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5186            3 :         break;
    5187            3 :       case CPP0X_INHERITING_CTORS:
    5188            3 :         pedwarn (loc, OPT_Wc__11_extensions,
    5189              :                  "inheriting constructors "
    5190              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5191            3 :         break;
    5192          148 :       case CPP0X_ATTRIBUTES:
    5193          148 :         if (pedantic)
    5194           24 :           pedwarn (loc, OPT_Wc__11_extensions,
    5195              :                    "C++11 attributes "
    5196              :                    "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5197              :         break;
    5198            0 :       case CPP0X_REF_QUALIFIER:
    5199            0 :         pedwarn (loc, OPT_Wc__11_extensions,
    5200              :                  "ref-qualifiers "
    5201              :                  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
    5202            0 :         break;
    5203            0 :       default:
    5204            0 :         gcc_unreachable ();
    5205              :       }
    5206     91054485 : }
    5207              : 
    5208              : /* Warn about the use of variadic templates when appropriate.  */
    5209              : void
    5210     15004069 : maybe_warn_variadic_templates (void)
    5211              : {
    5212     15004069 :   maybe_warn_cpp0x (CPP0X_VARIADIC_TEMPLATES);
    5213     15004069 : }
    5214              : 
    5215              : 
    5216              : /* Issue an ISO C++98 pedantic warning at LOCATION, conditional on
    5217              :    option OPTION_ID with text GMSGID.  Use this function to report
    5218              :    diagnostics for constructs that are invalid C++98, but valid
    5219              :    C++0x.  */
    5220              : bool
    5221      3892284 : pedwarn_cxx98 (location_t location,
    5222              :                diagnostics::option_id option_id,
    5223              :                const char *gmsgid, ...)
    5224              : {
    5225      3892284 :   diagnostics::diagnostic_info diagnostic;
    5226      3892284 :   va_list ap;
    5227      3892284 :   bool ret;
    5228      3892284 :   rich_location richloc (line_table, location);
    5229              : 
    5230      3892284 :   va_start (ap, gmsgid);
    5231      3892284 :   diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
    5232      3892284 :                        (cxx_dialect == cxx98
    5233              :                         ? diagnostics::kind::pedwarn
    5234              :                         : diagnostics::kind::warning));
    5235      3892284 :   diagnostic.m_option_id = option_id;
    5236      3892284 :   ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
    5237      3892284 :   va_end (ap);
    5238      7784568 :   return ret;
    5239      3892284 : }
    5240              : 
    5241              : /* Issue a diagnostic that NAME cannot be found in SCOPE.  DECL is what
    5242              :    we found when we tried to do the lookup.  LOCATION is the location of
    5243              :    the NAME identifier.  */
    5244              : 
    5245              : void
    5246          585 : qualified_name_lookup_error (tree scope, tree name,
    5247              :                              tree decl, location_t location)
    5248              : {
    5249          585 :   if (scope == error_mark_node)
    5250              :     ; /* We already complained.  */
    5251          469 :   else if (TYPE_P (scope))
    5252              :     {
    5253          269 :       if (!COMPLETE_TYPE_P (scope)
    5254          269 :           && !currently_open_class (scope))
    5255           44 :         error_at (location, "incomplete type %qT used in nested name specifier",
    5256              :                   scope);
    5257          225 :       else if (TREE_CODE (decl) == TREE_LIST)
    5258              :         {
    5259            0 :           auto_diagnostic_group d;
    5260            0 :           error_at (location, "reference to %<%T::%D%> is ambiguous",
    5261              :                     scope, name);
    5262            0 :           print_candidates (location, decl);
    5263            0 :         }
    5264              :       else
    5265              :         {
    5266          225 :           auto_diagnostic_group d;
    5267          225 :           name_hint hint;
    5268          225 :           if (SCOPED_ENUM_P (scope) && TREE_CODE (name) == IDENTIFIER_NODE)
    5269           15 :             hint = suggest_alternative_in_scoped_enum (name, scope);
    5270          225 :           if (const char *suggestion = hint.suggestion ())
    5271              :             {
    5272            9 :               gcc_rich_location richloc (location);
    5273            9 :               richloc.add_fixit_replace (suggestion);
    5274            9 :               error_at (&richloc,
    5275              :                         "%qD is not a member of %qT; did you mean %qs?",
    5276              :                         name, scope, suggestion);
    5277            9 :             }
    5278              :           else
    5279          216 :             error_at (location, "%qD is not a member of %qT", name, scope);
    5280          225 :         }
    5281              :     }
    5282          200 :   else if (scope != global_namespace)
    5283              :     {
    5284          182 :       auto_diagnostic_group d;
    5285          182 :       bool emit_fixit = true;
    5286          182 :       name_hint hint
    5287          182 :         = suggest_alternative_in_explicit_scope (location, name, scope);
    5288          182 :       if (!hint)
    5289              :         {
    5290           65 :           hint = suggest_alternatives_in_other_namespaces (location, name);
    5291              :           /* "location" is just the location of the name, not of the explicit
    5292              :              scope, and it's not easy to get at the latter, so we can't issue
    5293              :              fix-it hints for the suggestion.  */
    5294           65 :           emit_fixit = false;
    5295              :         }
    5296          182 :       if (const char *suggestion = hint.suggestion ())
    5297              :         {
    5298           58 :           gcc_rich_location richloc (location);
    5299           58 :           if (emit_fixit)
    5300           33 :             richloc.add_fixit_replace (suggestion);
    5301           58 :           error_at (&richloc, "%qD is not a member of %qD; did you mean %qs?",
    5302              :                     name, scope, suggestion);
    5303           58 :         }
    5304              :       else
    5305          124 :         error_at (location, "%qD is not a member of %qD", name, scope);
    5306          182 :     }
    5307              :   else
    5308              :     {
    5309           18 :       auto_diagnostic_group d;
    5310           18 :       name_hint hint = suggest_alternatives_for (location, name, true);
    5311           18 :       if (const char *suggestion = hint.suggestion ())
    5312              :         {
    5313            9 :           gcc_rich_location richloc (location);
    5314            9 :           richloc.add_fixit_replace (suggestion);
    5315            9 :           error_at (&richloc,
    5316              :                     "%<::%D%> has not been declared; did you mean %qs?",
    5317              :                     name, suggestion);
    5318            9 :         }
    5319              :       else
    5320            9 :         error_at (location, "%<::%D%> has not been declared", name);
    5321           18 :     }
    5322          585 : }
    5323              : 
    5324              : /* C++-specific implementation of range_label::get_text () vfunc for
    5325              :    range_label_for_type_mismatch.
    5326              : 
    5327              :    Compare with print_template_differences above.  */
    5328              : 
    5329              : label_text
    5330          437 : range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
    5331              : {
    5332          437 :   if (m_labelled_type == NULL_TREE)
    5333            0 :     return label_text::borrow (NULL);
    5334              : 
    5335          437 :   const bool verbose = false;
    5336          437 :   const bool show_color = false;
    5337              : 
    5338          437 :   const char *result;
    5339          437 :   if (m_other_type
    5340          437 :       && comparable_template_types_p (m_labelled_type, m_other_type))
    5341            2 :     result = type_to_string_with_compare (m_labelled_type, m_other_type,
    5342              :                                           verbose, show_color,
    5343              :                                           nullptr, nullptr);
    5344              :   else
    5345          435 :     result = type_to_string (m_labelled_type, verbose, true, NULL, show_color);
    5346              : 
    5347              :   /* Both of the above return GC-allocated buffers, so the caller mustn't
    5348              :      free them.  */
    5349          437 :   return label_text::borrow (result);
    5350              : }
        

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.