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