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