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

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.