LCOV - code coverage report
Current view: top level - gcc/cp - error.cc (source / functions) Hit Total Coverage
Test: gcc.info Lines: 2195 2509 87.5 %
Date: 2023-07-19 08:18:47 Functions: 95 100 95.0 %

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

Generated by: LCOV version 1.16