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

source code of gcc/cp/error.cc