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