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