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