Line data Source code
1 : /* Implementation of subroutines for the GNU C++ pretty-printer.
2 : Copyright (C) 2003-2026 Free Software Foundation, Inc.
3 : Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "cp-tree.h"
25 : #include "cxx-pretty-print.h"
26 : #include "tree-pretty-print.h"
27 :
28 : static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
29 : static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
30 : static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
31 : static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
32 : static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
33 : static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
34 : static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
35 : static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
36 : static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
37 : static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
38 : static void pp_cxx_unary_left_fold_expression (cxx_pretty_printer *, tree);
39 : static void pp_cxx_unary_right_fold_expression (cxx_pretty_printer *, tree);
40 : static void pp_cxx_binary_fold_expression (cxx_pretty_printer *, tree);
41 : static void pp_cxx_concept_definition (cxx_pretty_printer *, tree);
42 :
43 :
44 : static inline void
45 187154254 : pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
46 : {
47 187154254 : const char *p = pp_last_position_in_text (pp);
48 :
49 187154254 : if (p != NULL && *p == c)
50 29019460 : pp_cxx_whitespace (pp);
51 187154254 : pp_character (pp, c);
52 187154254 : pp->set_padding (pp_none);
53 187154254 : }
54 :
55 : #define pp_cxx_expression_list(PP, T) \
56 : pp_c_expression_list (PP, T)
57 : #define pp_cxx_space_for_pointer_operator(PP, T) \
58 : pp_c_space_for_pointer_operator (PP, T)
59 : #define pp_cxx_init_declarator(PP, T) \
60 : pp_c_init_declarator (PP, T)
61 : #define pp_cxx_call_argument_list(PP, T) \
62 : pp_c_call_argument_list (PP, T)
63 :
64 : void
65 111352278 : pp_cxx_colon_colon (cxx_pretty_printer *pp)
66 : {
67 111352278 : pp_colon_colon (pp);
68 111352278 : pp->set_padding (pp_none);
69 111352278 : }
70 :
71 : void
72 93577127 : pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
73 : {
74 93577127 : pp_cxx_nonconsecutive_character (pp, '<');
75 93577127 : }
76 :
77 : void
78 93577127 : pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
79 : {
80 93577127 : pp_cxx_nonconsecutive_character (pp, '>');
81 93577127 : }
82 :
83 : void
84 59069540 : pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
85 : {
86 59069540 : pp_separate_with (pp, c);
87 59069540 : pp->set_padding (pp_none);
88 59069540 : }
89 :
90 : /* Expressions. */
91 :
92 : /* conversion-function-id:
93 : operator conversion-type-id
94 :
95 : conversion-type-id:
96 : type-specifier-seq conversion-declarator(opt)
97 :
98 : conversion-declarator:
99 : ptr-operator conversion-declarator(opt) */
100 :
101 : static inline void
102 0 : pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
103 : {
104 0 : pp_cxx_ws_string (pp, "operator");
105 0 : pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
106 0 : }
107 :
108 : static inline void
109 28880 : pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
110 : {
111 28880 : pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
112 28880 : pp_cxx_begin_template_argument_list (pp);
113 28880 : pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
114 28880 : pp_cxx_end_template_argument_list (pp);
115 28880 : }
116 :
117 : /* Prints the unqualified part of the id-expression T.
118 :
119 : unqualified-id:
120 : identifier
121 : operator-function-id
122 : conversion-function-id
123 : ~ class-name
124 : template-id */
125 :
126 : static void
127 62636724 : pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
128 : {
129 62689279 : enum tree_code code = TREE_CODE (t);
130 62689279 : switch (code)
131 : {
132 0 : case RESULT_DECL:
133 0 : pp->translate_string ("<return-value>");
134 0 : break;
135 :
136 : case OVERLOAD:
137 61810944 : t = OVL_FIRST (t);
138 : /* FALLTHRU */
139 61810944 : case VAR_DECL:
140 61810944 : case PARM_DECL:
141 61810944 : case CONST_DECL:
142 61810944 : case TYPE_DECL:
143 61810944 : case FUNCTION_DECL:
144 61810944 : case NAMESPACE_DECL:
145 61810944 : case FIELD_DECL:
146 61810944 : case LABEL_DECL:
147 61810944 : case USING_DECL:
148 61810944 : case TEMPLATE_DECL:
149 61810944 : t = DECL_NAME (t);
150 : /* FALLTHRU */
151 :
152 61810944 : case IDENTIFIER_NODE:
153 61810944 : if (t == NULL)
154 51 : pp->translate_string ("<unnamed>");
155 61849197 : else if (IDENTIFIER_CONV_OP_P (t))
156 0 : pp_cxx_conversion_function_id (pp, t);
157 : else
158 61849197 : pp_cxx_tree_identifier (pp, t);
159 : break;
160 :
161 5111 : case TEMPLATE_ID_EXPR:
162 5111 : pp_cxx_template_id (pp, t);
163 5111 : break;
164 :
165 0 : case BASELINK:
166 0 : pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
167 0 : break;
168 :
169 782255 : case RECORD_TYPE:
170 782255 : case UNION_TYPE:
171 782255 : case ENUMERAL_TYPE:
172 782255 : case TYPENAME_TYPE:
173 782255 : case UNBOUND_CLASS_TEMPLATE:
174 782255 : pp_cxx_unqualified_id (pp, TYPE_NAME (t));
175 782255 : if (tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (t))
176 7348 : if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)))
177 : {
178 7325 : pp_cxx_begin_template_argument_list (pp);
179 7325 : tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti));
180 7325 : pp_cxx_template_argument_list (pp, args);
181 7325 : pp_cxx_end_template_argument_list (pp);
182 : }
183 : break;
184 :
185 0 : case BIT_NOT_EXPR:
186 0 : pp_cxx_complement (pp);
187 0 : pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
188 0 : break;
189 :
190 31135 : case TEMPLATE_TYPE_PARM:
191 31135 : case TEMPLATE_TEMPLATE_PARM:
192 31135 : if (template_placeholder_p (t))
193 : {
194 0 : t = TREE_TYPE (CLASS_PLACEHOLDER_TEMPLATE (t));
195 0 : pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
196 0 : pp_string (pp, "<...auto...>");
197 : }
198 31135 : else if (TYPE_IDENTIFIER (t))
199 31025 : pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
200 : else
201 110 : pp_cxx_canonical_template_parameter (pp, t);
202 : break;
203 :
204 21530 : case TEMPLATE_PARM_INDEX:
205 21530 : pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
206 21530 : break;
207 :
208 0 : case BOUND_TEMPLATE_TEMPLATE_PARM:
209 0 : pp_cxx_cv_qualifier_seq (pp, t);
210 0 : pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
211 0 : pp_cxx_begin_template_argument_list (pp);
212 0 : pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
213 0 : pp_cxx_end_template_argument_list (pp);
214 0 : break;
215 :
216 0 : default:
217 0 : pp_unsupported_tree (pp, t);
218 0 : break;
219 : }
220 62636724 : }
221 :
222 : /* Pretty-print out the token sequence ":: template" in template codes
223 : where it is needed to "inline declare" the (following) member as
224 : a template. This situation arises when SCOPE of T is dependent
225 : on template parameters. */
226 :
227 : static inline void
228 1858631 : pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
229 : {
230 1858631 : if (TREE_CODE (t) == TEMPLATE_ID_EXPR
231 1858631 : && TYPE_P (scope) && dependent_type_p (scope))
232 0 : pp_cxx_ws_string (pp, "template");
233 1858631 : }
234 :
235 : /* nested-name-specifier:
236 : ::
237 : type-name ::
238 : namespace-name ::
239 : computed-type-specifier ::
240 : nested-name-specifier identifier ::
241 : nested-name-specifier template(opt) simple-template-id :: */
242 :
243 : static void
244 1865834 : pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
245 : {
246 : /* FIXME: When diagnosing references to concepts (especially as types?)
247 : we end up adding too many '::' to the name. This is partially due
248 : to the fact that pp->enclosing_namespace is null. */
249 1865834 : if (t == global_namespace)
250 : {
251 313 : pp_cxx_colon_colon (pp);
252 : }
253 1865521 : else if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
254 : {
255 1006102 : tree scope = get_containing_scope (t);
256 1006102 : pp_cxx_nested_name_specifier (pp, scope);
257 1006102 : pp_cxx_template_keyword_if_needed (pp, scope, t);
258 : /* This is a computed-type-specifier. */
259 1006102 : if (TREE_CODE (t) == PACK_INDEX_TYPE || TREE_CODE (t) == DECLTYPE_TYPE)
260 3 : pp->type_id (t);
261 : else
262 1006099 : pp_cxx_unqualified_id (pp, t);
263 1006102 : pp_cxx_colon_colon (pp);
264 : }
265 1865834 : }
266 :
267 : /* qualified-id:
268 : nested-name-specifier template(opt) unqualified-id */
269 :
270 : static void
271 853274 : pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
272 : {
273 853274 : switch (TREE_CODE (t))
274 : {
275 : /* A pointer-to-member is always qualified. */
276 0 : case PTRMEM_CST:
277 0 : pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
278 0 : pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
279 0 : break;
280 :
281 : /* In Standard C++, functions cannot possibly be used as
282 : nested-name-specifiers. However, there are situations where
283 : is "makes sense" to output the surrounding function name for the
284 : purpose of emphasizing on the scope kind. Just printing the
285 : function name might not be sufficient as it may be overloaded; so,
286 : we decorate the function with its signature too.
287 : FIXME: This is probably the wrong pretty-printing for conversion
288 : functions and some function templates. */
289 : case OVERLOAD:
290 57 : t = OVL_FIRST (t);
291 : /* FALLTHRU */
292 57 : case FUNCTION_DECL:
293 57 : if (DECL_FUNCTION_MEMBER_P (t))
294 15 : pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
295 57 : pp_cxx_unqualified_id
296 114 : (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
297 57 : pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
298 57 : break;
299 :
300 259 : case OFFSET_REF:
301 259 : case SCOPE_REF:
302 259 : pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
303 259 : pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
304 259 : break;
305 :
306 852958 : default:
307 852958 : {
308 852958 : tree scope = get_containing_scope (t);
309 852958 : if (scope != pp->enclosing_scope)
310 : {
311 852529 : pp_cxx_nested_name_specifier (pp, scope);
312 852529 : pp_cxx_template_keyword_if_needed (pp, scope, t);
313 : }
314 852958 : pp_cxx_unqualified_id (pp, t);
315 : }
316 852958 : break;
317 : }
318 853274 : }
319 :
320 : /* Given a value e of ENUMERAL_TYPE:
321 : Print out the first ENUMERATOR id with value e, if one is found,
322 : (including nested names but excluding the enum name if unscoped)
323 : else print out the value as a C-style cast (type-id)value. */
324 :
325 : static void
326 774455 : pp_cxx_enumeration_constant (cxx_pretty_printer *pp, tree e)
327 : {
328 774455 : tree type = TREE_TYPE (e);
329 774455 : tree value = NULL_TREE;
330 :
331 : /* Find the name of this constant. */
332 774455 : if ((pp->flags & pp_c_flag_gnu_v3) == 0)
333 3360 : for (value = TYPE_VALUES (type); value != NULL_TREE;
334 1856 : value = TREE_CHAIN (value))
335 3358 : if (tree_int_cst_equal (DECL_INITIAL (TREE_VALUE (value)), e))
336 : break;
337 :
338 1504 : if (value != NULL_TREE)
339 : {
340 1502 : if (!ENUM_IS_SCOPED (type))
341 442 : type = get_containing_scope (type);
342 1502 : pp_cxx_nested_name_specifier (pp, type);
343 1502 : pp->id_expression (TREE_PURPOSE (value));
344 : }
345 : else
346 : {
347 : /* Value must have been cast. */
348 772953 : pp_c_type_cast (pp, type);
349 772953 : pp_c_integer_constant (pp, e);
350 : }
351 774455 : }
352 :
353 :
354 : void
355 23692973 : cxx_pretty_printer::constant (tree t)
356 : {
357 23692973 : switch (TREE_CODE (t))
358 : {
359 979 : case STRING_CST:
360 979 : {
361 979 : const bool in_parens = PAREN_STRING_LITERAL_P (t);
362 979 : if (in_parens)
363 8 : pp_cxx_left_paren (this);
364 979 : c_pretty_printer::constant (t);
365 979 : if (in_parens)
366 8 : pp_cxx_right_paren (this);
367 : }
368 : break;
369 :
370 23690670 : case INTEGER_CST:
371 23690670 : if (NULLPTR_TYPE_P (TREE_TYPE (t)))
372 : {
373 39 : pp_string (this, "nullptr");
374 39 : break;
375 : }
376 23690631 : else if (TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
377 : {
378 774455 : pp_cxx_enumeration_constant (this, t);
379 774455 : break;
380 : }
381 : /* fall through. */
382 :
383 22917500 : default:
384 22917500 : c_pretty_printer::constant (t);
385 22917500 : break;
386 : }
387 23692973 : }
388 :
389 : /* id-expression:
390 : unqualified-id
391 : qualified-id */
392 :
393 : void
394 59986202 : cxx_pretty_printer::id_expression (tree t)
395 : {
396 59986202 : if (TREE_CODE (t) == OVERLOAD)
397 59986202 : t = OVL_FIRST (t);
398 59986202 : if (DECL_P (t) && DECL_CONTEXT (t))
399 77976 : pp_cxx_qualified_id (this, t);
400 : else
401 59908226 : pp_cxx_unqualified_id (this, t);
402 59986202 : }
403 :
404 : /* user-defined literal:
405 : literal ud-suffix */
406 :
407 : void
408 0 : pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
409 : {
410 0 : pp->constant (USERDEF_LITERAL_VALUE (t));
411 0 : pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
412 0 : }
413 :
414 :
415 : /* primary-expression:
416 : literal
417 : this
418 : :: identifier
419 : :: operator-function-id
420 : :: qualifier-id
421 : ( expression )
422 : id-expression
423 :
424 : GNU Extensions:
425 : __builtin_va_arg ( assignment-expression , type-id )
426 : __builtin_offsetof ( type-id, offsetof-expression )
427 : __builtin_addressof ( expression )
428 :
429 : __builtin_is_virtual_base_of ( type-id , type-id )
430 :
431 : __has_nothrow_assign ( type-id )
432 : __has_nothrow_constructor ( type-id )
433 : __has_nothrow_copy ( type-id )
434 : __has_trivial_assign ( type-id )
435 : __has_trivial_constructor ( type-id )
436 : __has_trivial_copy ( type-id )
437 : __has_unique_object_representations ( type-id )
438 : __has_trivial_destructor ( type-id )
439 : __has_virtual_destructor ( type-id )
440 : __is_abstract ( type-id )
441 : __is_base_of ( type-id , type-id )
442 : __is_class ( type-id )
443 : __is_empty ( type-id )
444 : __is_enum ( type-id )
445 : __is_literal_type ( type-id )
446 : __is_pod ( type-id )
447 : __is_polymorphic ( type-id )
448 : __is_std_layout ( type-id )
449 : __is_trivial ( type-id )
450 : __is_union ( type-id ) */
451 :
452 : void
453 35235 : cxx_pretty_printer::primary_expression (tree t)
454 : {
455 35235 : switch (TREE_CODE (t))
456 : {
457 58 : case VOID_CST:
458 58 : case INTEGER_CST:
459 58 : case REAL_CST:
460 58 : case COMPLEX_CST:
461 58 : case STRING_CST:
462 58 : constant (t);
463 58 : break;
464 :
465 0 : case USERDEF_LITERAL:
466 0 : pp_cxx_userdef_literal (this, t);
467 0 : break;
468 :
469 13 : case BASELINK:
470 13 : t = BASELINK_FUNCTIONS (t);
471 : /* FALLTHRU */
472 6050 : case VAR_DECL:
473 6050 : case PARM_DECL:
474 6050 : case FIELD_DECL:
475 6050 : case FUNCTION_DECL:
476 6050 : case OVERLOAD:
477 6050 : case CONST_DECL:
478 6050 : case TEMPLATE_DECL:
479 6050 : id_expression (t);
480 6050 : break;
481 :
482 21530 : case RESULT_DECL:
483 21530 : case TEMPLATE_TYPE_PARM:
484 21530 : case TEMPLATE_TEMPLATE_PARM:
485 21530 : case TEMPLATE_PARM_INDEX:
486 21530 : pp_cxx_unqualified_id (this, t);
487 21530 : break;
488 :
489 0 : case STMT_EXPR:
490 0 : pp_cxx_left_paren (this);
491 0 : statement (STMT_EXPR_STMT (t));
492 0 : pp_cxx_right_paren (this);
493 0 : break;
494 :
495 66 : case TRAIT_EXPR:
496 66 : pp_cxx_trait (this, t);
497 66 : break;
498 :
499 0 : case VA_ARG_EXPR:
500 0 : pp_cxx_va_arg_expression (this, t);
501 0 : break;
502 :
503 0 : case OFFSETOF_EXPR:
504 0 : pp_cxx_offsetof_expression (this, t);
505 0 : break;
506 :
507 0 : case ADDRESSOF_EXPR:
508 0 : pp_cxx_addressof_expression (this, t);
509 0 : break;
510 :
511 398 : case REQUIRES_EXPR:
512 398 : pp_cxx_requires_expr (this, t);
513 398 : break;
514 :
515 7133 : default:
516 7133 : c_pretty_printer::primary_expression (t);
517 7133 : break;
518 : }
519 35235 : }
520 :
521 : /* postfix-expression:
522 : primary-expression
523 : postfix-expression [ expression ]
524 : postfix-expression ( expression-list(opt) )
525 : simple-type-specifier ( expression-list(opt) )
526 : typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
527 : typename ::(opt) nested-name-specifier template(opt)
528 : template-id ( expression-list(opt) )
529 : postfix-expression . template(opt) ::(opt) id-expression
530 : postfix-expression -> template(opt) ::(opt) id-expression
531 : postfix-expression . pseudo-destructor-name
532 : postfix-expression -> pseudo-destructor-name
533 : postfix-expression ++
534 : postfix-expression --
535 : dynamic_cast < type-id > ( expression )
536 : static_cast < type-id > ( expression )
537 : reinterpret_cast < type-id > ( expression )
538 : const_cast < type-id > ( expression )
539 : typeid ( expression )
540 : typeid ( type-id ) */
541 :
542 : void
543 23325 : cxx_pretty_printer::postfix_expression (tree t)
544 : {
545 23327 : enum tree_code code = TREE_CODE (t);
546 :
547 23327 : switch (code)
548 : {
549 9496 : case AGGR_INIT_EXPR:
550 9496 : case CALL_EXPR:
551 9496 : {
552 9496 : tree fun = cp_get_callee (t);
553 9496 : tree saved_scope = enclosing_scope;
554 9496 : bool skipfirst = false;
555 9496 : tree arg;
556 :
557 9496 : if (TREE_CODE (fun) == ADDR_EXPR)
558 2 : fun = TREE_OPERAND (fun, 0);
559 :
560 : /* In templates, where there is no way to tell whether a given
561 : call uses an actual member function. So the parser builds
562 : FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
563 : instantiation time. */
564 9496 : if (TREE_CODE (fun) != FUNCTION_DECL)
565 : ;
566 14 : else if (DECL_OBJECT_MEMBER_FUNCTION_P (fun))
567 : {
568 2 : tree object = (code == AGGR_INIT_EXPR
569 4 : ? (AGGR_INIT_VIA_CTOR_P (t)
570 2 : ? AGGR_INIT_EXPR_SLOT (t)
571 0 : : AGGR_INIT_EXPR_ARG (t, 0))
572 2 : : CALL_EXPR_ARG (t, 0));
573 :
574 2 : while (TREE_CODE (object) == NOP_EXPR)
575 0 : object = TREE_OPERAND (object, 0);
576 :
577 2 : if (TREE_CODE (object) == ADDR_EXPR)
578 0 : object = TREE_OPERAND (object, 0);
579 :
580 2 : if (!TYPE_PTR_P (TREE_TYPE (object)))
581 : {
582 2 : postfix_expression (object);
583 2 : pp_cxx_dot (this);
584 : }
585 : else
586 : {
587 0 : postfix_expression (object);
588 0 : pp_cxx_arrow (this);
589 : }
590 2 : skipfirst = true;
591 2 : enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
592 : }
593 :
594 9496 : postfix_expression (fun);
595 9496 : enclosing_scope = saved_scope;
596 9496 : pp_cxx_left_paren (this);
597 9496 : if (code == AGGR_INIT_EXPR)
598 : {
599 2 : aggr_init_expr_arg_iterator iter;
600 6 : FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
601 : {
602 2 : if (skipfirst)
603 : skipfirst = false;
604 : else
605 : {
606 0 : expression (arg);
607 0 : if (more_aggr_init_expr_args_p (&iter))
608 0 : pp_cxx_separate_with (this, ',');
609 : }
610 : }
611 : }
612 : else
613 : {
614 9494 : call_expr_arg_iterator iter;
615 23550 : FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
616 : {
617 4562 : if (skipfirst)
618 : skipfirst = false;
619 : else
620 : {
621 4562 : expression (arg);
622 4562 : if (more_call_expr_args_p (&iter))
623 11 : pp_cxx_separate_with (this, ',');
624 : }
625 : }
626 : }
627 9496 : pp_cxx_right_paren (this);
628 : }
629 9498 : if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
630 : {
631 2 : pp_cxx_separate_with (this, ',');
632 2 : postfix_expression (AGGR_INIT_EXPR_SLOT (t));
633 : }
634 : break;
635 :
636 5346 : case BASELINK:
637 5346 : case VAR_DECL:
638 5346 : case PARM_DECL:
639 5346 : case FIELD_DECL:
640 5346 : case FUNCTION_DECL:
641 5346 : case OVERLOAD:
642 5346 : case CONST_DECL:
643 5346 : case TEMPLATE_DECL:
644 5346 : case RESULT_DECL:
645 5346 : primary_expression (t);
646 5346 : break;
647 :
648 0 : case DYNAMIC_CAST_EXPR:
649 0 : case STATIC_CAST_EXPR:
650 0 : case REINTERPRET_CAST_EXPR:
651 0 : case CONST_CAST_EXPR:
652 0 : if (code == DYNAMIC_CAST_EXPR)
653 0 : pp_cxx_ws_string (this, "dynamic_cast");
654 0 : else if (code == STATIC_CAST_EXPR)
655 0 : pp_cxx_ws_string (this, "static_cast");
656 0 : else if (code == REINTERPRET_CAST_EXPR)
657 0 : pp_cxx_ws_string (this, "reinterpret_cast");
658 : else
659 0 : pp_cxx_ws_string (this, "const_cast");
660 0 : pp_cxx_begin_template_argument_list (this);
661 0 : type_id (TREE_TYPE (t));
662 0 : pp_cxx_end_template_argument_list (this);
663 0 : pp_left_paren (this);
664 0 : expression (TREE_OPERAND (t, 0));
665 0 : pp_right_paren (this);
666 0 : break;
667 :
668 0 : case BIT_CAST_EXPR:
669 0 : pp_cxx_ws_string (this, "__builtin_bit_cast");
670 0 : pp_left_paren (this);
671 0 : type_id (TREE_TYPE (t));
672 0 : pp_comma (this);
673 0 : expression (TREE_OPERAND (t, 0));
674 0 : pp_right_paren (this);
675 0 : break;
676 :
677 0 : case EMPTY_CLASS_EXPR:
678 0 : type_id (TREE_TYPE (t));
679 0 : pp_left_paren (this);
680 0 : pp_right_paren (this);
681 0 : break;
682 :
683 3 : case TYPEID_EXPR:
684 3 : pp_cxx_typeid_expression (this, t);
685 3 : break;
686 :
687 0 : case PSEUDO_DTOR_EXPR:
688 0 : postfix_expression (TREE_OPERAND (t, 0));
689 0 : pp_cxx_dot (this);
690 0 : if (TREE_OPERAND (t, 1))
691 : {
692 0 : pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
693 0 : pp_cxx_colon_colon (this);
694 : }
695 0 : pp_complement (this);
696 0 : pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
697 0 : break;
698 :
699 0 : case ARROW_EXPR:
700 0 : postfix_expression (TREE_OPERAND (t, 0));
701 0 : pp_cxx_arrow (this);
702 0 : break;
703 :
704 8482 : default:
705 8482 : c_pretty_printer::postfix_expression (t);
706 8482 : break;
707 : }
708 23325 : }
709 :
710 : /* new-expression:
711 : ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
712 : ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
713 :
714 : new-placement:
715 : ( expression-list )
716 :
717 : new-type-id:
718 : type-specifier-seq new-declarator(opt)
719 :
720 : new-declarator:
721 : ptr-operator new-declarator(opt)
722 : direct-new-declarator
723 :
724 : direct-new-declarator
725 : [ expression ]
726 : direct-new-declarator [ constant-expression ]
727 :
728 : new-initializer:
729 : ( expression-list(opt) ) */
730 :
731 : static void
732 45 : pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
733 : {
734 45 : enum tree_code code = TREE_CODE (t);
735 45 : tree type = TREE_OPERAND (t, 1);
736 45 : tree init = TREE_OPERAND (t, 2);
737 45 : switch (code)
738 : {
739 45 : case NEW_EXPR:
740 45 : case VEC_NEW_EXPR:
741 45 : if (NEW_EXPR_USE_GLOBAL (t))
742 43 : pp_cxx_colon_colon (pp);
743 45 : pp_cxx_ws_string (pp, "new");
744 45 : if (TREE_OPERAND (t, 0))
745 : {
746 43 : pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
747 43 : pp_space (pp);
748 : }
749 45 : if (TREE_CODE (type) == ARRAY_REF)
750 0 : type = build_cplus_array_type
751 0 : (TREE_OPERAND (type, 0),
752 : build_index_type (fold_build2_loc (input_location,
753 : MINUS_EXPR, integer_type_node,
754 0 : TREE_OPERAND (type, 1),
755 : integer_one_node)));
756 45 : pp->type_id (type);
757 45 : if (init)
758 : {
759 0 : pp_left_paren (pp);
760 0 : if (TREE_CODE (init) == TREE_LIST)
761 0 : pp_c_expression_list (pp, init);
762 0 : else if (init == void_node)
763 : ; /* OK, empty initializer list. */
764 : else
765 0 : pp->expression (init);
766 0 : pp_right_paren (pp);
767 : }
768 : break;
769 :
770 0 : default:
771 0 : pp_unsupported_tree (pp, t);
772 : }
773 45 : }
774 :
775 : /* delete-expression:
776 : ::(opt) delete cast-expression
777 : ::(opt) delete [ ] cast-expression */
778 :
779 : static void
780 15 : pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
781 : {
782 15 : enum tree_code code = TREE_CODE (t);
783 15 : switch (code)
784 : {
785 15 : case DELETE_EXPR:
786 15 : case VEC_DELETE_EXPR:
787 15 : if (DELETE_EXPR_USE_GLOBAL (t))
788 0 : pp_cxx_colon_colon (pp);
789 15 : pp_cxx_ws_string (pp, "delete");
790 15 : pp_space (pp);
791 15 : if (code == VEC_DELETE_EXPR
792 15 : || DELETE_EXPR_USE_VEC (t))
793 : {
794 6 : pp_left_bracket (pp);
795 6 : pp_right_bracket (pp);
796 6 : pp_space (pp);
797 : }
798 15 : pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
799 15 : break;
800 :
801 0 : default:
802 0 : pp_unsupported_tree (pp, t);
803 : }
804 15 : }
805 :
806 : /* unary-expression:
807 : postfix-expression
808 : ++ cast-expression
809 : -- cast-expression
810 : unary-operator cast-expression
811 : sizeof unary-expression
812 : sizeof ( type-id )
813 : sizeof ... ( identifier )
814 : new-expression
815 : delete-expression
816 : reflect-expression
817 :
818 : unary-operator: one of
819 : * & + - !
820 :
821 : GNU extensions:
822 : __alignof__ unary-expression
823 : __alignof__ ( type-id ) */
824 :
825 : void
826 5921 : cxx_pretty_printer::unary_expression (tree t)
827 : {
828 5930 : enum tree_code code = TREE_CODE (t);
829 5930 : switch (code)
830 : {
831 0 : case NEW_EXPR:
832 0 : case VEC_NEW_EXPR:
833 0 : pp_cxx_new_expression (this, t);
834 0 : break;
835 :
836 0 : case DELETE_EXPR:
837 0 : case VEC_DELETE_EXPR:
838 0 : pp_cxx_delete_expression (this, t);
839 0 : break;
840 :
841 169 : case SIZEOF_EXPR:
842 169 : if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
843 : {
844 77 : pp_cxx_ws_string (this, "sizeof");
845 77 : pp_cxx_ws_string (this, "...");
846 77 : pp_cxx_whitespace (this);
847 77 : pp_cxx_left_paren (this);
848 77 : if (TYPE_P (TREE_OPERAND (t, 0)))
849 69 : type_id (TREE_OPERAND (t, 0));
850 : else
851 8 : unary_expression (TREE_OPERAND (t, 0));
852 77 : pp_cxx_right_paren (this);
853 77 : break;
854 : }
855 : /* Fall through */
856 :
857 92 : case ALIGNOF_EXPR:
858 92 : if (code == SIZEOF_EXPR)
859 92 : pp_cxx_ws_string (this, "sizeof");
860 8 : else if (ALIGNOF_EXPR_STD_P (t))
861 8 : pp_cxx_ws_string (this, "alignof");
862 : else
863 0 : pp_cxx_ws_string (this, "__alignof__");
864 100 : pp_cxx_whitespace (this);
865 100 : if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
866 : {
867 0 : pp_cxx_left_paren (this);
868 0 : type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
869 0 : pp_cxx_right_paren (this);
870 : }
871 100 : else if (TYPE_P (TREE_OPERAND (t, 0)))
872 : {
873 91 : pp_cxx_left_paren (this);
874 91 : type_id (TREE_OPERAND (t, 0));
875 91 : pp_cxx_right_paren (this);
876 : }
877 : else
878 9 : unary_expression (TREE_OPERAND (t, 0));
879 : break;
880 :
881 0 : case AT_ENCODE_EXPR:
882 0 : pp_cxx_ws_string (this, "@encode");
883 0 : pp_cxx_whitespace (this);
884 0 : pp_cxx_left_paren (this);
885 0 : type_id (TREE_OPERAND (t, 0));
886 0 : pp_cxx_right_paren (this);
887 0 : break;
888 :
889 0 : case NOEXCEPT_EXPR:
890 0 : pp_cxx_ws_string (this, "noexcept");
891 0 : pp_cxx_whitespace (this);
892 0 : pp_cxx_left_paren (this);
893 0 : expression (TREE_OPERAND (t, 0));
894 0 : pp_cxx_right_paren (this);
895 0 : break;
896 :
897 3 : case UNARY_PLUS_EXPR:
898 3 : pp_plus (this);
899 3 : pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
900 3 : break;
901 :
902 0 : case REFLECT_EXPR:
903 0 : {
904 0 : pp_cxx_ws_string (this, "^^");
905 0 : tree h = REFLECT_EXPR_HANDLE (t);
906 0 : if (DECL_P (h))
907 0 : declaration (h);
908 0 : else if (TYPE_P (h))
909 0 : type_id (h);
910 : else
911 0 : expression (h);
912 : }
913 : break;
914 :
915 5750 : default:
916 5750 : c_pretty_printer::unary_expression (t);
917 5750 : break;
918 : }
919 5921 : }
920 :
921 : /* cast-expression:
922 : unary-expression
923 : ( type-id ) cast-expression */
924 :
925 : static void
926 2371 : pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
927 : {
928 2371 : switch (TREE_CODE (t))
929 : {
930 107 : case CAST_EXPR:
931 107 : case IMPLICIT_CONV_EXPR:
932 107 : pp->type_id (TREE_TYPE (t));
933 107 : pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
934 107 : break;
935 :
936 2264 : default:
937 2264 : pp_c_cast_expression (pp, t);
938 2264 : break;
939 : }
940 2371 : }
941 :
942 : /* pm-expression:
943 : cast-expression
944 : pm-expression .* cast-expression
945 : pm-expression ->* cast-expression */
946 :
947 : static void
948 2275 : pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
949 : {
950 2275 : switch (TREE_CODE (t))
951 : {
952 : /* Handle unfortunate OFFSET_REF overloading here. */
953 0 : case OFFSET_REF:
954 0 : if (TYPE_P (TREE_OPERAND (t, 0)))
955 : {
956 0 : pp_cxx_qualified_id (pp, t);
957 0 : break;
958 : }
959 : /* Fall through. */
960 9 : case MEMBER_REF:
961 9 : case DOTSTAR_EXPR:
962 9 : pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
963 9 : if (TREE_CODE (t) == MEMBER_REF)
964 3 : pp_cxx_arrow (pp);
965 : else
966 6 : pp_cxx_dot (pp);
967 9 : pp_star(pp);
968 9 : pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
969 9 : break;
970 :
971 :
972 2266 : default:
973 2266 : pp_cxx_cast_expression (pp, t);
974 2266 : break;
975 : }
976 2275 : }
977 :
978 : /* multiplicative-expression:
979 : pm-expression
980 : multiplicative-expression * pm-expression
981 : multiplicative-expression / pm-expression
982 : multiplicative-expression % pm-expression */
983 :
984 : void
985 2257 : cxx_pretty_printer::multiplicative_expression (tree e)
986 : {
987 2257 : enum tree_code code = TREE_CODE (e);
988 2257 : switch (code)
989 : {
990 72 : case MULT_EXPR:
991 72 : case TRUNC_DIV_EXPR:
992 72 : case TRUNC_MOD_EXPR:
993 72 : case EXACT_DIV_EXPR:
994 72 : case RDIV_EXPR:
995 72 : multiplicative_expression (TREE_OPERAND (e, 0));
996 72 : pp_space (this);
997 72 : if (code == MULT_EXPR)
998 7 : pp_star (this);
999 65 : else if (code != TRUNC_MOD_EXPR)
1000 65 : pp_slash (this);
1001 : else
1002 0 : pp_modulo (this);
1003 72 : pp_space (this);
1004 72 : pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
1005 72 : break;
1006 :
1007 2185 : default:
1008 2185 : pp_cxx_pm_expression (this, e);
1009 2185 : break;
1010 : }
1011 2257 : }
1012 :
1013 : /* conditional-expression:
1014 : logical-or-expression
1015 : logical-or-expression ? expression : assignment-expression */
1016 :
1017 : void
1018 21 : cxx_pretty_printer::conditional_expression (tree e)
1019 : {
1020 21 : if (TREE_CODE (e) == COND_EXPR)
1021 : {
1022 0 : pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1023 0 : pp_space (this);
1024 0 : pp_question (this);
1025 0 : pp_space (this);
1026 0 : expression (TREE_OPERAND (e, 1));
1027 0 : pp_space (this);
1028 0 : assignment_expression (TREE_OPERAND (e, 2));
1029 : }
1030 : else
1031 21 : pp_c_logical_or_expression (this, e);
1032 21 : }
1033 :
1034 : /* Pretty-print a compound assignment operator token as indicated by T. */
1035 :
1036 : static void
1037 12 : pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
1038 : {
1039 12 : const char *op;
1040 :
1041 12 : switch (TREE_CODE (t))
1042 : {
1043 : case NOP_EXPR:
1044 : op = "=";
1045 : break;
1046 :
1047 3 : case PLUS_EXPR:
1048 3 : op = "+=";
1049 3 : break;
1050 :
1051 0 : case MINUS_EXPR:
1052 0 : op = "-=";
1053 0 : break;
1054 :
1055 0 : case TRUNC_DIV_EXPR:
1056 0 : op = "/=";
1057 0 : break;
1058 :
1059 1 : case TRUNC_MOD_EXPR:
1060 1 : op = "%=";
1061 1 : break;
1062 :
1063 0 : default:
1064 0 : op = get_tree_code_name (TREE_CODE (t));
1065 0 : break;
1066 : }
1067 :
1068 12 : pp_cxx_ws_string (pp, op);
1069 12 : }
1070 :
1071 :
1072 : /* assignment-expression:
1073 : conditional-expression
1074 : logical-or-expression assignment-operator assignment-expression
1075 : throw-expression
1076 :
1077 : throw-expression:
1078 : throw assignment-expression(opt)
1079 :
1080 : assignment-operator: one of
1081 : = *= /= %= += -= >>= <<= &= ^= |= */
1082 :
1083 : void
1084 21 : cxx_pretty_printer::assignment_expression (tree e)
1085 : {
1086 33 : switch (TREE_CODE (e))
1087 : {
1088 0 : case MODIFY_EXPR:
1089 0 : case INIT_EXPR:
1090 0 : pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1091 0 : pp_space (this);
1092 0 : pp_equal (this);
1093 0 : pp_space (this);
1094 0 : assignment_expression (TREE_OPERAND (e, 1));
1095 0 : break;
1096 :
1097 0 : case THROW_EXPR:
1098 0 : pp_cxx_ws_string (this, "throw");
1099 0 : if (TREE_OPERAND (e, 0))
1100 0 : assignment_expression (TREE_OPERAND (e, 0));
1101 : break;
1102 :
1103 12 : case MODOP_EXPR:
1104 12 : pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1105 12 : pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1106 12 : assignment_expression (TREE_OPERAND (e, 2));
1107 12 : break;
1108 :
1109 21 : default:
1110 21 : conditional_expression (e);
1111 21 : break;
1112 : }
1113 21 : }
1114 :
1115 : void
1116 67509 : cxx_pretty_printer::expression (tree t)
1117 : {
1118 67532 : switch (TREE_CODE (t))
1119 : {
1120 1332 : case STRING_CST:
1121 1332 : case VOID_CST:
1122 1332 : case INTEGER_CST:
1123 1332 : case REAL_CST:
1124 1332 : case COMPLEX_CST:
1125 1332 : constant (t);
1126 1332 : break;
1127 :
1128 0 : case USERDEF_LITERAL:
1129 0 : pp_cxx_userdef_literal (this, t);
1130 0 : break;
1131 :
1132 0 : case RESULT_DECL:
1133 0 : pp_cxx_unqualified_id (this, t);
1134 0 : break;
1135 :
1136 : #if 0
1137 : case OFFSET_REF:
1138 : #endif
1139 259 : case SCOPE_REF:
1140 259 : case PTRMEM_CST:
1141 259 : pp_cxx_qualified_id (this, t);
1142 259 : break;
1143 :
1144 : case OVERLOAD:
1145 22 : t = OVL_FIRST (t);
1146 : /* FALLTHRU */
1147 22 : case VAR_DECL:
1148 22 : if (DECL_NTTP_OBJECT_P (t))
1149 : {
1150 : /* Print the type followed by the CONSTRUCTOR value of the
1151 : NTTP object. */
1152 11 : simple_type_specifier (cv_unqualified (TREE_TYPE (t)));
1153 11 : expression (DECL_INITIAL (t));
1154 11 : break;
1155 : }
1156 : /* FALLTHRU */
1157 21306 : case PARM_DECL:
1158 21306 : case FIELD_DECL:
1159 21306 : case CONST_DECL:
1160 21306 : case FUNCTION_DECL:
1161 21306 : case BASELINK:
1162 21306 : case TEMPLATE_DECL:
1163 21306 : case TEMPLATE_TYPE_PARM:
1164 21306 : case TEMPLATE_PARM_INDEX:
1165 21306 : case TEMPLATE_TEMPLATE_PARM:
1166 21306 : case STMT_EXPR:
1167 21306 : case REQUIRES_EXPR:
1168 21306 : primary_expression (t);
1169 21306 : break;
1170 :
1171 9059 : case CALL_EXPR:
1172 9059 : case DYNAMIC_CAST_EXPR:
1173 9059 : case STATIC_CAST_EXPR:
1174 9059 : case REINTERPRET_CAST_EXPR:
1175 9059 : case CONST_CAST_EXPR:
1176 : #if 0
1177 : case MEMBER_REF:
1178 : #endif
1179 9059 : case EMPTY_CLASS_EXPR:
1180 9059 : case TYPEID_EXPR:
1181 9059 : case PSEUDO_DTOR_EXPR:
1182 9059 : case AGGR_INIT_EXPR:
1183 9059 : case ARROW_EXPR:
1184 9059 : postfix_expression (t);
1185 9059 : break;
1186 :
1187 45 : case NEW_EXPR:
1188 45 : case VEC_NEW_EXPR:
1189 45 : pp_cxx_new_expression (this, t);
1190 45 : break;
1191 :
1192 15 : case DELETE_EXPR:
1193 15 : case VEC_DELETE_EXPR:
1194 15 : pp_cxx_delete_expression (this, t);
1195 15 : break;
1196 :
1197 6 : case SIZEOF_EXPR:
1198 6 : case ALIGNOF_EXPR:
1199 6 : case NOEXCEPT_EXPR:
1200 6 : case UNARY_PLUS_EXPR:
1201 6 : case REFLECT_EXPR:
1202 6 : unary_expression (t);
1203 6 : break;
1204 :
1205 93 : case CAST_EXPR:
1206 93 : case IMPLICIT_CONV_EXPR:
1207 93 : pp_cxx_cast_expression (this, t);
1208 93 : break;
1209 :
1210 9 : case OFFSET_REF:
1211 9 : case MEMBER_REF:
1212 9 : case DOTSTAR_EXPR:
1213 9 : pp_cxx_pm_expression (this, t);
1214 9 : break;
1215 :
1216 72 : case MULT_EXPR:
1217 72 : case TRUNC_DIV_EXPR:
1218 72 : case TRUNC_MOD_EXPR:
1219 72 : case EXACT_DIV_EXPR:
1220 72 : case RDIV_EXPR:
1221 72 : multiplicative_expression (t);
1222 72 : break;
1223 :
1224 0 : case COND_EXPR:
1225 0 : conditional_expression (t);
1226 0 : break;
1227 :
1228 12 : case MODIFY_EXPR:
1229 12 : case INIT_EXPR:
1230 12 : case THROW_EXPR:
1231 12 : case MODOP_EXPR:
1232 12 : assignment_expression (t);
1233 12 : break;
1234 :
1235 0 : case MUST_NOT_THROW_EXPR:
1236 0 : expression (TREE_OPERAND (t, 0));
1237 0 : break;
1238 :
1239 3432 : case EXPR_PACK_EXPANSION:
1240 3432 : expression (PACK_EXPANSION_PATTERN (t));
1241 3432 : pp_cxx_ws_string (this, "...");
1242 3432 : break;
1243 :
1244 0 : case PACK_INDEX_EXPR:
1245 0 : expression (PACK_INDEX_PACK (t));
1246 0 : pp_cxx_left_bracket (this);
1247 0 : expression (PACK_INDEX_INDEX (t));
1248 0 : pp_cxx_right_bracket (this);
1249 0 : break;
1250 :
1251 335 : case UNARY_LEFT_FOLD_EXPR:
1252 335 : pp_cxx_unary_left_fold_expression (this, t);
1253 335 : break;
1254 :
1255 3581 : case UNARY_RIGHT_FOLD_EXPR:
1256 3581 : pp_cxx_unary_right_fold_expression (this, t);
1257 3581 : break;
1258 :
1259 2 : case BINARY_LEFT_FOLD_EXPR:
1260 2 : case BINARY_RIGHT_FOLD_EXPR:
1261 2 : pp_cxx_binary_fold_expression (this, t);
1262 2 : break;
1263 :
1264 23769 : case TEMPLATE_ID_EXPR:
1265 23769 : pp_cxx_template_id (this, t);
1266 23769 : break;
1267 :
1268 7 : case NONTYPE_ARGUMENT_PACK:
1269 7 : {
1270 7 : tree args = ARGUMENT_PACK_ARGS (t);
1271 7 : int i, len = TREE_VEC_LENGTH (args);
1272 7 : pp_cxx_left_brace (this);
1273 34 : for (i = 0; i < len; ++i)
1274 : {
1275 20 : if (i > 0)
1276 13 : pp_cxx_separate_with (this, ',');
1277 20 : expression (TREE_VEC_ELT (args, i));
1278 : }
1279 7 : pp_cxx_right_brace (this);
1280 : }
1281 7 : break;
1282 :
1283 15 : case LAMBDA_EXPR:
1284 15 : pp_cxx_ws_string (this, "<lambda>");
1285 15 : break;
1286 :
1287 469 : case TRAIT_EXPR:
1288 469 : pp_cxx_trait (this, t);
1289 469 : break;
1290 :
1291 0 : case ATOMIC_CONSTR:
1292 0 : case CONJ_CONSTR:
1293 0 : case DISJ_CONSTR:
1294 0 : pp_cxx_constraint (this, t);
1295 0 : break;
1296 :
1297 0 : case PAREN_EXPR:
1298 0 : pp_cxx_left_paren (this);
1299 0 : expression (TREE_OPERAND (t, 0));
1300 0 : pp_cxx_right_paren (this);
1301 0 : break;
1302 :
1303 154 : case VIEW_CONVERT_EXPR:
1304 154 : if (TREE_CODE (TREE_OPERAND (t, 0)) == TEMPLATE_PARM_INDEX)
1305 : {
1306 : /* Strip const VIEW_CONVERT_EXPR wrappers for class NTTPs. */
1307 12 : expression (TREE_OPERAND (t, 0));
1308 12 : break;
1309 : }
1310 : /* FALLTHRU */
1311 3691 : default:
1312 3691 : c_pretty_printer::expression (t);
1313 3691 : break;
1314 : }
1315 67509 : }
1316 :
1317 :
1318 : /* Declarations. */
1319 :
1320 : /* function-specifier:
1321 : inline
1322 : virtual
1323 : explicit */
1324 :
1325 : void
1326 250 : cxx_pretty_printer::function_specifier (tree t)
1327 : {
1328 250 : switch (TREE_CODE (t))
1329 : {
1330 0 : case FUNCTION_DECL:
1331 0 : if (DECL_VIRTUAL_P (t))
1332 0 : pp_cxx_ws_string (this, "virtual");
1333 0 : else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1334 0 : pp_cxx_ws_string (this, "explicit");
1335 : else
1336 0 : c_pretty_printer::function_specifier (t);
1337 :
1338 250 : default:
1339 250 : break;
1340 : }
1341 250 : }
1342 :
1343 : /* decl-specifier-seq:
1344 : decl-specifier-seq(opt) decl-specifier
1345 :
1346 : decl-specifier:
1347 : storage-class-specifier
1348 : type-specifier
1349 : function-specifier
1350 : friend
1351 : typedef */
1352 :
1353 : void
1354 250 : cxx_pretty_printer::declaration_specifiers (tree t)
1355 : {
1356 467 : switch (TREE_CODE (t))
1357 : {
1358 217 : case VAR_DECL:
1359 217 : case PARM_DECL:
1360 217 : case CONST_DECL:
1361 217 : case FIELD_DECL:
1362 217 : storage_class_specifier (t);
1363 217 : declaration_specifiers (TREE_TYPE (t));
1364 217 : break;
1365 :
1366 0 : case TYPE_DECL:
1367 0 : pp_cxx_ws_string (this, "typedef");
1368 0 : declaration_specifiers (TREE_TYPE (t));
1369 0 : break;
1370 :
1371 0 : case FUNCTION_DECL:
1372 : /* Constructors don't have return types. And conversion functions
1373 : do not have a type-specifier in their return types. */
1374 0 : if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1375 0 : function_specifier (t);
1376 0 : else if (DECL_IOBJ_MEMBER_FUNCTION_P (t))
1377 0 : declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1378 : else
1379 0 : c_pretty_printer::declaration_specifiers (t);
1380 : break;
1381 250 : default:
1382 250 : c_pretty_printer::declaration_specifiers (t);
1383 250 : break;
1384 : }
1385 250 : }
1386 :
1387 : /* simple-type-specifier:
1388 : ::(opt) nested-name-specifier(opt) type-name
1389 : ::(opt) nested-name-specifier(opt) template(opt) template-id
1390 : decltype-specifier
1391 : char
1392 : wchar_t
1393 : bool
1394 : short
1395 : int
1396 : long
1397 : signed
1398 : unsigned
1399 : float
1400 : double
1401 : void */
1402 :
1403 : void
1404 120772924 : cxx_pretty_printer::simple_type_specifier (tree t)
1405 : {
1406 120772924 : switch (TREE_CODE (t))
1407 : {
1408 775033 : case RECORD_TYPE:
1409 775033 : case UNION_TYPE:
1410 775033 : case ENUMERAL_TYPE:
1411 775033 : pp_cxx_qualified_id (this, t);
1412 775033 : break;
1413 :
1414 31054 : case TEMPLATE_TYPE_PARM:
1415 31054 : case TEMPLATE_TEMPLATE_PARM:
1416 31054 : case TEMPLATE_PARM_INDEX:
1417 31054 : case BOUND_TEMPLATE_TEMPLATE_PARM:
1418 31054 : pp_cxx_unqualified_id (this, t);
1419 31054 : if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
1420 31048 : if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
1421 206 : pp_cxx_constrained_type_spec (this, c);
1422 : break;
1423 :
1424 5313 : case TYPENAME_TYPE:
1425 5313 : pp_cxx_ws_string (this, "typename");
1426 5313 : pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1427 5313 : pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
1428 5313 : break;
1429 :
1430 4967 : case DECLTYPE_TYPE:
1431 4967 : pp_cxx_ws_string (this, "decltype");
1432 4967 : pp_cxx_left_paren (this);
1433 4967 : this->expression (DECLTYPE_TYPE_EXPR (t));
1434 4967 : pp_cxx_right_paren (this);
1435 4967 : break;
1436 :
1437 26 : case NULLPTR_TYPE:
1438 26 : pp_cxx_ws_string (this, "std::nullptr_t");
1439 26 : break;
1440 :
1441 6 : case TRAIT_TYPE:
1442 6 : pp_cxx_trait (this, t);
1443 6 : break;
1444 :
1445 0 : case LANG_TYPE:
1446 0 : if (REFLECTION_TYPE_P (t))
1447 : {
1448 0 : pp_cxx_ws_string (this, "std::meta::info");
1449 0 : break;
1450 : }
1451 119956525 : gcc_fallthrough ();
1452 :
1453 119956525 : default:
1454 119956525 : c_pretty_printer::simple_type_specifier (t);
1455 119956525 : break;
1456 : }
1457 120772924 : }
1458 :
1459 : /* type-specifier-seq:
1460 : type-specifier type-specifier-seq(opt)
1461 :
1462 : type-specifier:
1463 : simple-type-specifier
1464 : class-specifier
1465 : enum-specifier
1466 : elaborated-type-specifier
1467 : cv-qualifier */
1468 :
1469 : static void
1470 60786216 : pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1471 : {
1472 60786216 : switch (TREE_CODE (t))
1473 : {
1474 35528 : case TEMPLATE_DECL:
1475 35528 : case TEMPLATE_TYPE_PARM:
1476 35528 : case TEMPLATE_TEMPLATE_PARM:
1477 35528 : case TYPE_DECL:
1478 35528 : case BOUND_TEMPLATE_TEMPLATE_PARM:
1479 35528 : case DECLTYPE_TYPE:
1480 35528 : case NULLPTR_TYPE:
1481 35528 : pp_cxx_cv_qualifier_seq (pp, t);
1482 35528 : pp->simple_type_specifier (t);
1483 35528 : break;
1484 :
1485 0 : case METHOD_TYPE:
1486 0 : pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1487 0 : pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1488 0 : pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1489 0 : break;
1490 :
1491 1554 : case RECORD_TYPE:
1492 1554 : if (TYPE_PTRMEMFUNC_P (t))
1493 : {
1494 3 : tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1495 3 : pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1496 3 : pp_cxx_whitespace (pp);
1497 3 : pp_cxx_ptr_operator (pp, t);
1498 3 : break;
1499 : }
1500 : /* fall through */
1501 :
1502 1563 : case OFFSET_TYPE:
1503 1563 : if (TYPE_PTRDATAMEM_P (t))
1504 : {
1505 12 : pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1506 12 : pp_cxx_whitespace (pp);
1507 12 : pp_cxx_ptr_operator (pp, t);
1508 12 : break;
1509 : }
1510 : /* fall through */
1511 :
1512 60750673 : default:
1513 60750673 : if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1514 60750673 : pp_c_specifier_qualifier_list (pp, t);
1515 : }
1516 60786216 : }
1517 :
1518 : /* ptr-operator:
1519 : * cv-qualifier-seq(opt)
1520 : &
1521 : ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1522 :
1523 : static void
1524 15 : pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1525 : {
1526 15 : if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1527 0 : t = TREE_TYPE (t);
1528 15 : switch (TREE_CODE (t))
1529 : {
1530 0 : case REFERENCE_TYPE:
1531 0 : case POINTER_TYPE:
1532 0 : if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1533 0 : pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1534 0 : pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1535 0 : if (TYPE_PTR_P (t))
1536 : {
1537 0 : pp_star (pp);
1538 0 : pp_cxx_cv_qualifier_seq (pp, t);
1539 : }
1540 : else
1541 0 : pp_ampersand (pp);
1542 : break;
1543 :
1544 3 : case RECORD_TYPE:
1545 3 : if (TYPE_PTRMEMFUNC_P (t))
1546 : {
1547 3 : pp_cxx_left_paren (pp);
1548 3 : pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1549 3 : pp_star (pp);
1550 3 : break;
1551 : }
1552 : /* FALLTHRU */
1553 12 : case OFFSET_TYPE:
1554 12 : if (TYPE_PTRMEM_P (t))
1555 : {
1556 12 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1557 3 : pp_cxx_left_paren (pp);
1558 12 : pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1559 12 : pp_star (pp);
1560 12 : pp_cxx_cv_qualifier_seq (pp, t);
1561 12 : break;
1562 : }
1563 : /* fall through. */
1564 :
1565 0 : default:
1566 0 : pp_unsupported_tree (pp, t);
1567 0 : break;
1568 : }
1569 15 : }
1570 :
1571 : static inline tree
1572 0 : pp_cxx_implicit_parameter_type (tree mf)
1573 : {
1574 0 : return class_of_this_parm (TREE_TYPE (mf));
1575 : }
1576 :
1577 : /*
1578 : parameter-declaration:
1579 : decl-specifier-seq declarator
1580 : decl-specifier-seq declarator = assignment-expression
1581 : decl-specifier-seq abstract-declarator(opt)
1582 : decl-specifier-seq abstract-declarator(opt) assignment-expression */
1583 :
1584 : static inline void
1585 247 : pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1586 : {
1587 247 : pp->declaration_specifiers (t);
1588 247 : if (TYPE_P (t))
1589 30 : pp->abstract_declarator (t);
1590 : else
1591 217 : pp->declarator (t);
1592 247 : }
1593 :
1594 : /* parameter-declaration-clause:
1595 : parameter-declaration-list(opt) ...(opt)
1596 : parameter-declaration-list , ...
1597 :
1598 : parameter-declaration-list:
1599 : parameter-declaration
1600 : parameter-declaration-list , parameter-declaration */
1601 :
1602 : static void
1603 82 : pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1604 : {
1605 82 : gcc_assert (FUNC_OR_METHOD_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL);
1606 82 : tree types, args;
1607 82 : if (TYPE_P (t))
1608 : {
1609 82 : types = TYPE_ARG_TYPES (t);
1610 82 : args = NULL_TREE;
1611 : }
1612 : else
1613 : {
1614 0 : types = FUNCTION_FIRST_USER_PARMTYPE (t);
1615 0 : args = FUNCTION_FIRST_USER_PARM (t);
1616 : }
1617 82 : bool abstract = !args || (pp->flags & pp_c_flag_abstract);
1618 :
1619 : /* Skip artificial parameter for non-static member functions. */
1620 82 : if (TREE_CODE (t) == METHOD_TYPE)
1621 18 : types = TREE_CHAIN (types);
1622 :
1623 82 : bool first = true;
1624 82 : pp_cxx_left_paren (pp);
1625 194 : for (; types != void_list_node; types = TREE_CHAIN (types))
1626 : {
1627 63 : if (!first)
1628 12 : pp_cxx_separate_with (pp, ',');
1629 63 : first = false;
1630 63 : if (!types)
1631 : {
1632 33 : pp_cxx_ws_string (pp, "...");
1633 33 : break;
1634 : }
1635 60 : pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1636 30 : if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1637 : {
1638 0 : pp_cxx_whitespace (pp);
1639 0 : pp_equal (pp);
1640 0 : pp_cxx_whitespace (pp);
1641 0 : pp->assignment_expression (TREE_PURPOSE (types));
1642 : }
1643 0 : if (!abstract)
1644 0 : args = TREE_CHAIN (args);
1645 : }
1646 82 : pp_cxx_right_paren (pp);
1647 82 : }
1648 :
1649 : /* exception-specification:
1650 : throw ( type-id-list(opt) )
1651 :
1652 : type-id-list
1653 : type-id
1654 : type-id-list , type-id */
1655 :
1656 : static void
1657 25 : pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1658 : {
1659 25 : tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1660 25 : bool need_comma = false;
1661 :
1662 25 : if (ex_spec == NULL)
1663 : return;
1664 0 : if (TREE_PURPOSE (ex_spec))
1665 : {
1666 0 : pp_cxx_ws_string (pp, "noexcept");
1667 0 : pp_cxx_whitespace (pp);
1668 0 : pp_cxx_left_paren (pp);
1669 0 : if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1670 0 : pp_cxx_ws_string (pp, "<uninstantiated>");
1671 : else
1672 0 : pp->expression (TREE_PURPOSE (ex_spec));
1673 0 : pp_cxx_right_paren (pp);
1674 0 : return;
1675 : }
1676 0 : pp_cxx_ws_string (pp, "throw");
1677 0 : pp_cxx_left_paren (pp);
1678 0 : for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1679 : {
1680 0 : tree type = TREE_VALUE (ex_spec);
1681 0 : tree argpack = NULL_TREE;
1682 0 : int i, len = 1;
1683 :
1684 0 : if (ARGUMENT_PACK_P (type))
1685 : {
1686 0 : argpack = ARGUMENT_PACK_ARGS (type);
1687 0 : len = TREE_VEC_LENGTH (argpack);
1688 : }
1689 :
1690 0 : for (i = 0; i < len; ++i)
1691 : {
1692 0 : if (argpack)
1693 0 : type = TREE_VEC_ELT (argpack, i);
1694 :
1695 0 : if (need_comma)
1696 0 : pp_cxx_separate_with (pp, ',');
1697 : else
1698 : need_comma = true;
1699 :
1700 0 : pp->type_id (type);
1701 : }
1702 : }
1703 0 : pp_cxx_right_paren (pp);
1704 : }
1705 :
1706 : /* direct-declarator:
1707 : declarator-id
1708 : direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1709 : exception-specification(opt)
1710 : direct-declaration [ constant-expression(opt) ]
1711 : ( declarator ) */
1712 :
1713 : void
1714 217 : cxx_pretty_printer::direct_declarator (tree t)
1715 : {
1716 217 : switch (TREE_CODE (t))
1717 : {
1718 217 : case VAR_DECL:
1719 217 : case PARM_DECL:
1720 217 : case CONST_DECL:
1721 217 : case FIELD_DECL:
1722 217 : if (DECL_NAME (t))
1723 : {
1724 217 : pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1725 :
1726 217 : if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1727 434 : || template_parameter_pack_p (t))
1728 : /* A function parameter pack or non-type template
1729 : parameter pack. */
1730 0 : pp_cxx_ws_string (this, "...");
1731 :
1732 217 : id_expression (DECL_NAME (t));
1733 : }
1734 217 : abstract_declarator (TREE_TYPE (t));
1735 217 : break;
1736 :
1737 0 : case FUNCTION_DECL:
1738 0 : pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1739 0 : expression (t);
1740 0 : pp_cxx_parameter_declaration_clause (this, t);
1741 :
1742 0 : if (DECL_IOBJ_MEMBER_FUNCTION_P (t))
1743 : {
1744 0 : set_padding (pp_before);
1745 0 : pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1746 : }
1747 :
1748 0 : pp_cxx_exception_specification (this, TREE_TYPE (t));
1749 0 : break;
1750 :
1751 : case TYPENAME_TYPE:
1752 : case TEMPLATE_DECL:
1753 : case TEMPLATE_TYPE_PARM:
1754 : case TEMPLATE_PARM_INDEX:
1755 : case TEMPLATE_TEMPLATE_PARM:
1756 : break;
1757 :
1758 0 : default:
1759 0 : c_pretty_printer::direct_declarator (t);
1760 0 : break;
1761 : }
1762 217 : }
1763 :
1764 : /* declarator:
1765 : direct-declarator
1766 : ptr-operator declarator */
1767 :
1768 : void
1769 217 : cxx_pretty_printer::declarator (tree t)
1770 : {
1771 217 : direct_declarator (t);
1772 :
1773 : // Print a requires clause.
1774 217 : if (flag_concepts)
1775 217 : if (tree ci = get_constraints (t))
1776 0 : if (tree reqs = CI_DECLARATOR_REQS (ci))
1777 0 : pp_cxx_requires_clause (this, reqs);
1778 217 : }
1779 :
1780 : /* ctor-initializer:
1781 : : mem-initializer-list
1782 :
1783 : mem-initializer-list:
1784 : mem-initializer
1785 : mem-initializer , mem-initializer-list
1786 :
1787 : mem-initializer:
1788 : mem-initializer-id ( expression-list(opt) )
1789 :
1790 : mem-initializer-id:
1791 : ::(opt) nested-name-specifier(opt) class-name
1792 : identifier */
1793 :
1794 : static void
1795 0 : pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1796 : {
1797 0 : t = TREE_OPERAND (t, 0);
1798 0 : pp_cxx_whitespace (pp);
1799 0 : pp_colon (pp);
1800 0 : pp_cxx_whitespace (pp);
1801 0 : for (; t; t = TREE_CHAIN (t))
1802 : {
1803 0 : tree purpose = TREE_PURPOSE (t);
1804 0 : bool is_pack = PACK_EXPANSION_P (purpose);
1805 :
1806 0 : if (is_pack)
1807 0 : pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1808 : else
1809 0 : pp->primary_expression (purpose);
1810 0 : pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1811 0 : if (is_pack)
1812 0 : pp_cxx_ws_string (pp, "...");
1813 0 : if (TREE_CHAIN (t))
1814 0 : pp_cxx_separate_with (pp, ',');
1815 : }
1816 0 : }
1817 :
1818 : /* function-definition:
1819 : decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1820 : decl-specifier-seq(opt) declarator function-try-block */
1821 :
1822 : static void
1823 0 : pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1824 : {
1825 0 : tree saved_scope = pp->enclosing_scope;
1826 0 : pp->declaration_specifiers (t);
1827 0 : pp->declarator (t);
1828 0 : pp_needs_newline (pp) = true;
1829 0 : pp->enclosing_scope = DECL_CONTEXT (t);
1830 0 : if (DECL_SAVED_TREE (t))
1831 0 : pp->statement (DECL_SAVED_TREE (t));
1832 : else
1833 0 : pp_cxx_semicolon (pp);
1834 0 : pp_newline_and_flush (pp);
1835 0 : pp->enclosing_scope = saved_scope;
1836 0 : }
1837 :
1838 : /* abstract-declarator:
1839 : ptr-operator abstract-declarator(opt)
1840 : direct-abstract-declarator */
1841 :
1842 : void
1843 8381 : cxx_pretty_printer::abstract_declarator (tree t)
1844 : {
1845 : /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1846 : or a pointer-to-data-member of array type:
1847 :
1848 : void (X::*)()
1849 : int (X::*)[5]
1850 :
1851 : but not for a pointer-to-data-member of non-array type:
1852 :
1853 : int X::*
1854 :
1855 : so be mindful of that. */
1856 18 : if (TYPE_PTRMEMFUNC_P (t)
1857 8396 : || (TYPE_PTRDATAMEM_P (t)
1858 12 : && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
1859 6 : pp_cxx_right_paren (this);
1860 8375 : else if (INDIRECT_TYPE_P (t))
1861 : {
1862 5632 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1863 5632 : || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1864 75 : pp_cxx_right_paren (this);
1865 5632 : t = TREE_TYPE (t);
1866 : }
1867 8381 : direct_abstract_declarator (t);
1868 8381 : }
1869 :
1870 : /* direct-abstract-declarator:
1871 : direct-abstract-declarator(opt) ( parameter-declaration-clause )
1872 : cv-qualifier-seq(opt) exception-specification(opt)
1873 : direct-abstract-declarator(opt) [ constant-expression(opt) ]
1874 : ( abstract-declarator ) */
1875 :
1876 : void
1877 8540 : cxx_pretty_printer::direct_abstract_declarator (tree t)
1878 : {
1879 8555 : switch (TREE_CODE (t))
1880 : {
1881 0 : case REFERENCE_TYPE:
1882 0 : abstract_declarator (t);
1883 0 : break;
1884 :
1885 512 : case RECORD_TYPE:
1886 512 : if (TYPE_PTRMEMFUNC_P (t))
1887 3 : direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1888 : break;
1889 :
1890 12 : case OFFSET_TYPE:
1891 12 : if (TYPE_PTRDATAMEM_P (t))
1892 12 : direct_abstract_declarator (TREE_TYPE (t));
1893 : break;
1894 :
1895 25 : case METHOD_TYPE:
1896 25 : case FUNCTION_TYPE:
1897 25 : pp_cxx_parameter_declaration_clause (this, t);
1898 25 : direct_abstract_declarator (TREE_TYPE (t));
1899 25 : if (TREE_CODE (t) == METHOD_TYPE)
1900 : {
1901 3 : set_padding (pp_before);
1902 3 : pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1903 : }
1904 25 : pp_cxx_exception_specification (this, t);
1905 25 : break;
1906 :
1907 : case TYPENAME_TYPE:
1908 : case TEMPLATE_TYPE_PARM:
1909 : case TEMPLATE_TEMPLATE_PARM:
1910 : case BOUND_TEMPLATE_TEMPLATE_PARM:
1911 : case UNBOUND_CLASS_TEMPLATE:
1912 : case DECLTYPE_TYPE:
1913 : break;
1914 :
1915 3094 : default:
1916 3094 : c_pretty_printer::direct_abstract_declarator (t);
1917 3094 : break;
1918 : }
1919 8540 : }
1920 :
1921 : /* type-id:
1922 : type-specifier-seq abstract-declarator(opt) */
1923 :
1924 : void
1925 831648 : cxx_pretty_printer::type_id (tree t)
1926 : {
1927 831648 : pp_flags saved_flags = flags;
1928 831648 : flags |= pp_c_flag_abstract;
1929 :
1930 831648 : switch (TREE_CODE (t))
1931 : {
1932 810899 : case TYPE_DECL:
1933 810899 : case UNION_TYPE:
1934 810899 : case RECORD_TYPE:
1935 810899 : case ENUMERAL_TYPE:
1936 810899 : case TYPENAME_TYPE:
1937 810899 : case BOUND_TEMPLATE_TEMPLATE_PARM:
1938 810899 : case UNBOUND_CLASS_TEMPLATE:
1939 810899 : case TEMPLATE_TEMPLATE_PARM:
1940 810899 : case TEMPLATE_TYPE_PARM:
1941 810899 : case TEMPLATE_PARM_INDEX:
1942 810899 : case TEMPLATE_DECL:
1943 810899 : case TYPEOF_TYPE:
1944 810899 : case TRAIT_TYPE:
1945 810899 : case DECLTYPE_TYPE:
1946 810899 : case NULLPTR_TYPE:
1947 810899 : case TEMPLATE_ID_EXPR:
1948 810899 : case OFFSET_TYPE:
1949 810899 : pp_cxx_type_specifier_seq (this, t);
1950 810899 : if (TYPE_PTRMEM_P (t))
1951 15 : abstract_declarator (t);
1952 : break;
1953 :
1954 12457 : case TYPE_PACK_EXPANSION:
1955 12457 : type_id (PACK_EXPANSION_PATTERN (t));
1956 12457 : pp_cxx_ws_string (this, "...");
1957 12457 : break;
1958 :
1959 2 : case PACK_INDEX_TYPE:
1960 2 : type_id (PACK_INDEX_PACK (t));
1961 2 : pp_cxx_left_bracket (this);
1962 2 : expression (PACK_INDEX_INDEX (t));
1963 2 : pp_cxx_right_bracket (this);
1964 2 : break;
1965 :
1966 182 : case TYPE_ARGUMENT_PACK:
1967 182 : {
1968 182 : tree args = ARGUMENT_PACK_ARGS (t);
1969 182 : int len = TREE_VEC_LENGTH (args);
1970 182 : pp_cxx_left_brace (this);
1971 654 : for (int i = 0; i < len; ++i)
1972 : {
1973 290 : if (i > 0)
1974 129 : pp_cxx_separate_with (this, ',');
1975 290 : type_id (TREE_VEC_ELT (args, i));
1976 : }
1977 182 : pp_cxx_right_brace (this);
1978 : }
1979 182 : break;
1980 :
1981 0 : case LANG_TYPE:
1982 0 : if (REFLECTION_TYPE_P (t))
1983 : {
1984 0 : pp_cxx_type_specifier_seq (this, t);
1985 0 : break;
1986 : }
1987 8108 : gcc_fallthrough ();
1988 :
1989 8108 : default:
1990 8108 : c_pretty_printer::type_id (t);
1991 8108 : break;
1992 : }
1993 :
1994 831648 : flags = saved_flags;
1995 831648 : }
1996 :
1997 : /* template-argument-list:
1998 : template-argument ...(opt)
1999 : template-argument-list, template-argument ...(opt)
2000 :
2001 : template-argument:
2002 : assignment-expression
2003 : type-id
2004 : template-name */
2005 :
2006 : static void
2007 36592 : pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
2008 : {
2009 36592 : int i;
2010 36592 : bool need_comma = false;
2011 :
2012 36592 : if (t == NULL)
2013 : return;
2014 93179 : for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
2015 : {
2016 56587 : tree arg = TREE_VEC_ELT (t, i);
2017 56587 : tree argpack = NULL_TREE;
2018 56587 : int idx, len = 1;
2019 :
2020 56587 : if (ARGUMENT_PACK_P (arg))
2021 : {
2022 12387 : argpack = ARGUMENT_PACK_ARGS (arg);
2023 12387 : len = TREE_VEC_LENGTH (argpack);
2024 : }
2025 :
2026 113212 : for (idx = 0; idx < len; idx++)
2027 : {
2028 56625 : if (argpack)
2029 12425 : arg = TREE_VEC_ELT (argpack, idx);
2030 :
2031 56625 : if (need_comma)
2032 20204 : pp_cxx_separate_with (pp, ',');
2033 : else
2034 : need_comma = true;
2035 :
2036 56625 : if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
2037 6 : && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
2038 39417 : pp->type_id (arg);
2039 : else
2040 17208 : pp->expression (arg);
2041 : }
2042 : }
2043 : }
2044 :
2045 :
2046 : static void
2047 0 : pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
2048 : {
2049 0 : t = DECL_EXPR_DECL (t);
2050 0 : pp_cxx_type_specifier_seq (pp, t);
2051 0 : if (TYPE_P (t))
2052 0 : pp->abstract_declarator (t);
2053 : else
2054 0 : pp->declarator (t);
2055 0 : }
2056 :
2057 : /* Statements. */
2058 :
2059 : void
2060 0 : cxx_pretty_printer::statement (tree t)
2061 : {
2062 0 : switch (TREE_CODE (t))
2063 : {
2064 0 : case CTOR_INITIALIZER:
2065 0 : pp_cxx_ctor_initializer (this, t);
2066 0 : break;
2067 :
2068 0 : case USING_STMT:
2069 0 : pp_cxx_ws_string (this, "using");
2070 0 : pp_cxx_ws_string (this, "namespace");
2071 0 : if (DECL_CONTEXT (t))
2072 0 : pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
2073 0 : pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
2074 0 : break;
2075 :
2076 0 : case USING_DECL:
2077 0 : pp_cxx_ws_string (this, "using");
2078 0 : pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
2079 0 : pp_cxx_unqualified_id (this, DECL_NAME (t));
2080 0 : break;
2081 :
2082 : case EH_SPEC_BLOCK:
2083 : break;
2084 :
2085 : /* try-block:
2086 : try compound-statement handler-seq */
2087 0 : case TRY_BLOCK:
2088 0 : pp_maybe_newline_and_indent (this, 0);
2089 0 : pp_cxx_ws_string (this, "try");
2090 0 : pp_newline_and_indent (this, 3);
2091 0 : statement (TRY_STMTS (t));
2092 0 : pp_newline_and_indent (this, -3);
2093 0 : if (CLEANUP_P (t))
2094 : ;
2095 : else
2096 0 : statement (TRY_HANDLERS (t));
2097 : break;
2098 :
2099 : /*
2100 : handler-seq:
2101 : handler handler-seq(opt)
2102 :
2103 : handler:
2104 : catch ( exception-declaration ) compound-statement
2105 :
2106 : exception-declaration:
2107 : type-specifier-seq declarator
2108 : type-specifier-seq abstract-declarator
2109 : ... */
2110 0 : case HANDLER:
2111 0 : pp_cxx_ws_string (this, "catch");
2112 0 : pp_cxx_left_paren (this);
2113 0 : pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
2114 0 : pp_cxx_right_paren (this);
2115 0 : pp_indentation (this) += 3;
2116 0 : pp_needs_newline (this) = true;
2117 0 : statement (HANDLER_BODY (t));
2118 0 : pp_indentation (this) -= 3;
2119 0 : pp_needs_newline (this) = true;
2120 0 : break;
2121 :
2122 : /* selection-statement:
2123 : if ( expression ) statement
2124 : if ( expression ) statement else statement */
2125 0 : case IF_STMT:
2126 0 : pp_cxx_ws_string (this, "if");
2127 0 : pp_cxx_whitespace (this);
2128 0 : pp_cxx_left_paren (this);
2129 0 : expression (IF_COND (t));
2130 0 : pp_cxx_right_paren (this);
2131 0 : pp_newline_and_indent (this, 2);
2132 0 : statement (THEN_CLAUSE (t));
2133 0 : pp_newline_and_indent (this, -2);
2134 0 : if (ELSE_CLAUSE (t))
2135 : {
2136 0 : tree else_clause = ELSE_CLAUSE (t);
2137 0 : pp_cxx_ws_string (this, "else");
2138 0 : if (TREE_CODE (else_clause) == IF_STMT)
2139 0 : pp_cxx_whitespace (this);
2140 : else
2141 0 : pp_newline_and_indent (this, 2);
2142 0 : statement (else_clause);
2143 0 : if (TREE_CODE (else_clause) != IF_STMT)
2144 0 : pp_newline_and_indent (this, -2);
2145 : }
2146 : break;
2147 :
2148 0 : case RANGE_FOR_STMT:
2149 0 : pp_cxx_ws_string (this, "for");
2150 0 : pp_space (this);
2151 0 : pp_cxx_left_paren (this);
2152 0 : if (RANGE_FOR_INIT_STMT (t))
2153 : {
2154 0 : statement (RANGE_FOR_INIT_STMT (t));
2155 0 : pp_needs_newline (this) = false;
2156 0 : pp_cxx_whitespace (this);
2157 : }
2158 0 : statement (RANGE_FOR_DECL (t));
2159 0 : pp_space (this);
2160 0 : pp_needs_newline (this) = false;
2161 0 : pp_colon (this);
2162 0 : pp_space (this);
2163 0 : statement (RANGE_FOR_EXPR (t));
2164 0 : pp_cxx_right_paren (this);
2165 0 : pp_newline_and_indent (this, 3);
2166 0 : statement (FOR_BODY (t));
2167 0 : pp_indentation (this) -= 3;
2168 0 : pp_needs_newline (this) = true;
2169 0 : break;
2170 :
2171 0 : case TEMPLATE_FOR_STMT:
2172 0 : pp_cxx_ws_string (this, "template for");
2173 0 : pp_space (this);
2174 0 : pp_cxx_left_paren (this);
2175 0 : if (TEMPLATE_FOR_INIT_STMT (t))
2176 : {
2177 0 : statement (TEMPLATE_FOR_INIT_STMT (t));
2178 0 : pp_needs_newline (this) = false;
2179 0 : pp_cxx_whitespace (this);
2180 : }
2181 0 : statement (TEMPLATE_FOR_DECL (t));
2182 0 : pp_space (this);
2183 0 : pp_needs_newline (this) = false;
2184 0 : pp_colon (this);
2185 0 : pp_space (this);
2186 0 : statement (TEMPLATE_FOR_EXPR (t));
2187 0 : pp_cxx_right_paren (this);
2188 0 : pp_newline_and_indent (this, 3);
2189 0 : statement (TEMPLATE_FOR_BODY (t));
2190 0 : pp_indentation (this) -= 3;
2191 0 : pp_needs_newline (this) = true;
2192 0 : break;
2193 :
2194 : /* expression-statement:
2195 : expression(opt) ; */
2196 0 : case EXPR_STMT:
2197 0 : expression (EXPR_STMT_EXPR (t));
2198 0 : pp_cxx_semicolon (this);
2199 0 : pp_needs_newline (this) = true;
2200 0 : break;
2201 :
2202 0 : case CLEANUP_STMT:
2203 0 : pp_cxx_ws_string (this, "try");
2204 0 : pp_newline_and_indent (this, 2);
2205 0 : statement (CLEANUP_BODY (t));
2206 0 : pp_newline_and_indent (this, -2);
2207 0 : pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2208 0 : pp_newline_and_indent (this, 2);
2209 0 : statement (CLEANUP_EXPR (t));
2210 0 : pp_newline_and_indent (this, -2);
2211 0 : break;
2212 :
2213 0 : case STATIC_ASSERT:
2214 0 : declaration (t);
2215 0 : break;
2216 :
2217 0 : case OMP_DEPOBJ:
2218 0 : pp_cxx_ws_string (this, "#pragma omp depobj");
2219 0 : pp_space (this);
2220 0 : pp_cxx_left_paren (this);
2221 0 : expression (OMP_DEPOBJ_DEPOBJ (t));
2222 0 : pp_cxx_right_paren (this);
2223 0 : if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
2224 : {
2225 0 : if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
2226 0 : dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t),
2227 0 : pp_indentation (this), TDF_NONE);
2228 : else
2229 0 : switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2230 : {
2231 0 : case OMP_CLAUSE_DEPEND_IN:
2232 0 : pp_cxx_ws_string (this, " update(in)");
2233 0 : break;
2234 0 : case OMP_CLAUSE_DEPEND_INOUT:
2235 0 : pp_cxx_ws_string (this, " update(inout)");
2236 0 : break;
2237 0 : case OMP_CLAUSE_DEPEND_OUT:
2238 0 : pp_cxx_ws_string (this, " update(out)");
2239 0 : break;
2240 0 : case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2241 0 : pp_cxx_ws_string (this, " update(mutexinoutset)");
2242 0 : break;
2243 0 : case OMP_CLAUSE_DEPEND_INOUTSET:
2244 0 : pp_cxx_ws_string (this, " update(inoutset)");
2245 0 : break;
2246 0 : case OMP_CLAUSE_DEPEND_LAST:
2247 0 : pp_cxx_ws_string (this, " destroy");
2248 0 : break;
2249 : default:
2250 : break;
2251 : }
2252 : }
2253 0 : pp_needs_newline (this) = true;
2254 0 : break;
2255 :
2256 0 : default:
2257 0 : c_pretty_printer::statement (t);
2258 0 : break;
2259 : }
2260 0 : }
2261 :
2262 : /* original-namespace-definition:
2263 : namespace identifier { namespace-body }
2264 :
2265 : As an edge case, we also handle unnamed namespace definition here. */
2266 :
2267 : static void
2268 87 : pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2269 : {
2270 87 : pp_cxx_ws_string (pp, "namespace");
2271 87 : if (DECL_CONTEXT (t))
2272 87 : pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2273 87 : if (DECL_NAME (t))
2274 87 : pp_cxx_unqualified_id (pp, t);
2275 87 : pp_cxx_whitespace (pp);
2276 87 : pp_cxx_left_brace (pp);
2277 : /* We do not print the namespace-body. */
2278 87 : pp_cxx_whitespace (pp);
2279 87 : pp_cxx_right_brace (pp);
2280 87 : }
2281 :
2282 : /* namespace-alias:
2283 : identifier
2284 :
2285 : namespace-alias-definition:
2286 : namespace identifier = qualified-namespace-specifier ;
2287 :
2288 : qualified-namespace-specifier:
2289 : ::(opt) nested-name-specifier(opt) namespace-name */
2290 :
2291 : static void
2292 6 : pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2293 : {
2294 6 : pp_cxx_ws_string (pp, "namespace");
2295 6 : if (DECL_CONTEXT (t))
2296 6 : pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2297 6 : pp_cxx_unqualified_id (pp, t);
2298 6 : pp_cxx_whitespace (pp);
2299 6 : pp_equal (pp);
2300 6 : pp_cxx_whitespace (pp);
2301 6 : if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2302 6 : pp_cxx_nested_name_specifier (pp,
2303 6 : DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2304 6 : pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2305 6 : pp_cxx_semicolon (pp);
2306 6 : }
2307 :
2308 : /* simple-declaration:
2309 : decl-specifier-seq(opt) init-declarator-list(opt) */
2310 :
2311 : static void
2312 0 : pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2313 : {
2314 0 : pp->declaration_specifiers (t);
2315 0 : pp_cxx_init_declarator (pp, t);
2316 0 : pp_cxx_semicolon (pp);
2317 0 : pp_needs_newline (pp) = true;
2318 0 : }
2319 :
2320 : /*
2321 : template-parameter-list:
2322 : template-parameter
2323 : template-parameter-list , template-parameter */
2324 :
2325 : static inline void
2326 0 : pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2327 : {
2328 0 : const int n = TREE_VEC_LENGTH (t);
2329 0 : int i;
2330 0 : for (i = 0; i < n; ++i)
2331 : {
2332 0 : if (i)
2333 0 : pp_cxx_separate_with (pp, ',');
2334 0 : pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2335 : }
2336 0 : }
2337 :
2338 : /* template-parameter:
2339 : type-parameter
2340 : parameter-declaration
2341 :
2342 : type-parameter:
2343 : class ...(opt) identifier(opt)
2344 : class identifier(opt) = type-id
2345 : typename identifier(opt)
2346 : typename ...(opt) identifier(opt) = type-id
2347 : template < template-parameter-list > class ...(opt) identifier(opt)
2348 : template < template-parameter-list > class identifier(opt) = template-name */
2349 :
2350 : static void
2351 0 : pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2352 : {
2353 0 : tree parameter = TREE_VALUE (t);
2354 0 : switch (TREE_CODE (parameter))
2355 : {
2356 0 : case TYPE_DECL:
2357 0 : pp_cxx_ws_string (pp, "class");
2358 0 : if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parameter)))
2359 0 : pp_cxx_ws_string (pp, "...");
2360 0 : if (DECL_NAME (parameter))
2361 0 : pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2362 : /* FIXME: Check if we should print also default argument. */
2363 : break;
2364 :
2365 0 : case PARM_DECL:
2366 0 : pp_cxx_parameter_declaration (pp, parameter);
2367 0 : break;
2368 :
2369 : case TEMPLATE_DECL:
2370 : break;
2371 :
2372 0 : default:
2373 0 : pp_unsupported_tree (pp, t);
2374 0 : break;
2375 : }
2376 0 : }
2377 :
2378 : /* Pretty-print a template parameter in the canonical form
2379 : "template-parameter-<level>-<position in parameter list>". */
2380 :
2381 : void
2382 1882 : pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2383 : {
2384 1882 : const enum tree_code code = TREE_CODE (parm);
2385 :
2386 : /* Brings type template parameters to the canonical forms. */
2387 1882 : if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2388 1882 : || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2389 1004 : parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2390 :
2391 1882 : pp_cxx_begin_template_argument_list (pp);
2392 1882 : pp->translate_string ("template-parameter-");
2393 1882 : pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2394 1882 : pp_minus (pp);
2395 1882 : pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2396 1882 : pp_cxx_end_template_argument_list (pp);
2397 1882 : }
2398 :
2399 : /* Print a constrained-type-specifier. */
2400 :
2401 : void
2402 387 : pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2403 : {
2404 387 : pp_cxx_whitespace (pp);
2405 387 : pp_cxx_left_bracket (pp);
2406 387 : pp->translate_string ("requires");
2407 387 : pp_cxx_whitespace (pp);
2408 387 : if (c == error_mark_node)
2409 : {
2410 0 : pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
2411 0 : return;
2412 : }
2413 387 : tree t = TREE_OPERAND (c, 0);
2414 387 : tree a = TREE_OPERAND (c, 1);
2415 387 : pp->id_expression (t);
2416 387 : pp_cxx_begin_template_argument_list (pp);
2417 387 : pp_cxx_ws_string (pp, "<placeholder>");
2418 387 : pp_cxx_separate_with (pp, ',');
2419 387 : tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2420 990 : for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i)
2421 216 : TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1);
2422 387 : pp_cxx_template_argument_list (pp, args);
2423 387 : ggc_free (args);
2424 387 : pp_cxx_end_template_argument_list (pp);
2425 387 : pp_cxx_right_bracket (pp);
2426 : }
2427 :
2428 : /*
2429 : template-declaration:
2430 : export(opt) template < template-parameter-list > declaration
2431 :
2432 : Concept extensions:
2433 :
2434 : template-declaration:
2435 : export(opt) template < template-parameter-list >
2436 : requires-clause(opt) declaration */
2437 :
2438 : static void
2439 0 : pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2440 : {
2441 0 : tree tmpl = most_general_template (t);
2442 0 : tree level;
2443 :
2444 0 : pp_maybe_newline_and_indent (pp, 0);
2445 0 : for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2446 : {
2447 0 : pp_cxx_ws_string (pp, "template");
2448 0 : pp_cxx_begin_template_argument_list (pp);
2449 0 : pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2450 0 : pp_cxx_end_template_argument_list (pp);
2451 0 : pp_newline_and_indent (pp, 3);
2452 : }
2453 :
2454 0 : if (flag_concepts)
2455 0 : if (tree ci = get_constraints (t))
2456 0 : if (tree reqs = CI_TEMPLATE_REQS (ci))
2457 : {
2458 0 : pp_cxx_requires_clause (pp, reqs);
2459 0 : pp_newline_and_indent (pp, 6);
2460 : }
2461 :
2462 0 : if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2463 0 : pp_cxx_function_definition (pp, t);
2464 0 : else if (TREE_CODE (t) == CONCEPT_DECL)
2465 0 : pp_cxx_concept_definition (pp, t);
2466 : else
2467 0 : pp_cxx_simple_declaration (pp, t);
2468 0 : }
2469 :
2470 : static void
2471 0 : pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2472 : {
2473 0 : pp_unsupported_tree (pp, t);
2474 0 : }
2475 :
2476 : static void
2477 0 : pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2478 : {
2479 0 : pp_unsupported_tree (pp, t);
2480 0 : }
2481 :
2482 : static void
2483 0 : pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t)
2484 : {
2485 0 : pp_cxx_unqualified_id (pp, DECL_NAME (t));
2486 0 : pp_cxx_whitespace (pp);
2487 0 : pp_cxx_ws_string (pp, "=");
2488 0 : pp_cxx_whitespace (pp);
2489 0 : pp->expression (DECL_INITIAL (t));
2490 0 : pp_cxx_semicolon (pp);
2491 0 : }
2492 :
2493 : /*
2494 : declaration:
2495 : block-declaration
2496 : function-definition
2497 : template-declaration
2498 : explicit-instantiation
2499 : explicit-specialization
2500 : linkage-specification
2501 : namespace-definition
2502 :
2503 : block-declaration:
2504 : simple-declaration
2505 : asm-definition
2506 : namespace-alias-definition
2507 : using-declaration
2508 : using-directive
2509 : static_assert-declaration */
2510 : void
2511 93 : cxx_pretty_printer::declaration (tree t)
2512 : {
2513 93 : if (TREE_CODE (t) == STATIC_ASSERT)
2514 : {
2515 0 : pp_cxx_ws_string (this, "static_assert");
2516 0 : pp_cxx_left_paren (this);
2517 0 : expression (STATIC_ASSERT_CONDITION (t));
2518 0 : pp_cxx_separate_with (this, ',');
2519 0 : expression (STATIC_ASSERT_MESSAGE (t));
2520 0 : pp_cxx_right_paren (this);
2521 : }
2522 93 : else if (!DECL_LANG_SPECIFIC (t))
2523 0 : pp_cxx_simple_declaration (this, t);
2524 93 : else if (DECL_USE_TEMPLATE (t))
2525 0 : switch (DECL_USE_TEMPLATE (t))
2526 : {
2527 0 : case 1:
2528 0 : pp_cxx_template_declaration (this, t);
2529 0 : break;
2530 :
2531 0 : case 2:
2532 0 : pp_cxx_explicit_specialization (this, t);
2533 0 : break;
2534 :
2535 0 : case 3:
2536 0 : pp_cxx_explicit_instantiation (this, t);
2537 0 : break;
2538 :
2539 : default:
2540 : break;
2541 : }
2542 93 : else switch (TREE_CODE (t))
2543 : {
2544 0 : case FIELD_DECL:
2545 0 : case VAR_DECL:
2546 0 : case TYPE_DECL:
2547 0 : pp_cxx_simple_declaration (this, t);
2548 0 : break;
2549 :
2550 0 : case FUNCTION_DECL:
2551 0 : if (DECL_SAVED_TREE (t))
2552 0 : pp_cxx_function_definition (this, t);
2553 : else
2554 0 : pp_cxx_simple_declaration (this, t);
2555 : break;
2556 :
2557 93 : case NAMESPACE_DECL:
2558 93 : if (DECL_NAMESPACE_ALIAS (t))
2559 6 : pp_cxx_namespace_alias_definition (this, t);
2560 : else
2561 87 : pp_cxx_original_namespace_definition (this, t);
2562 : break;
2563 :
2564 0 : default:
2565 0 : pp_unsupported_tree (this, t);
2566 0 : break;
2567 : }
2568 93 : }
2569 :
2570 : static void
2571 3 : pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2572 : {
2573 3 : t = TREE_OPERAND (t, 0);
2574 3 : pp_cxx_ws_string (pp, "typeid");
2575 3 : pp_cxx_left_paren (pp);
2576 3 : if (TYPE_P (t))
2577 3 : pp->type_id (t);
2578 : else
2579 0 : pp->expression (t);
2580 3 : pp_cxx_right_paren (pp);
2581 3 : }
2582 :
2583 : void
2584 3 : pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2585 : {
2586 3 : pp_cxx_ws_string (pp, "va_arg");
2587 3 : pp_cxx_left_paren (pp);
2588 3 : pp->assignment_expression (TREE_OPERAND (t, 0));
2589 3 : pp_cxx_separate_with (pp, ',');
2590 3 : pp->type_id (TREE_TYPE (t));
2591 3 : pp_cxx_right_paren (pp);
2592 3 : }
2593 :
2594 : static bool
2595 45 : pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2596 : {
2597 45 : switch (TREE_CODE (t))
2598 : {
2599 15 : case ARROW_EXPR:
2600 15 : if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2601 15 : && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2602 : {
2603 15 : pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2604 15 : pp_cxx_separate_with (pp, ',');
2605 15 : return true;
2606 : }
2607 : return false;
2608 24 : case COMPONENT_REF:
2609 24 : if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2610 : return false;
2611 24 : if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2612 9 : pp_cxx_dot (pp);
2613 24 : pp->expression (TREE_OPERAND (t, 1));
2614 24 : return true;
2615 6 : case ARRAY_REF:
2616 6 : if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2617 : return false;
2618 6 : pp_left_bracket (pp);
2619 6 : pp->expression (TREE_OPERAND (t, 1));
2620 6 : pp_right_bracket (pp);
2621 6 : return true;
2622 : default:
2623 : return false;
2624 : }
2625 : }
2626 :
2627 : void
2628 15 : pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2629 : {
2630 15 : pp_cxx_ws_string (pp, "offsetof");
2631 15 : pp_cxx_left_paren (pp);
2632 15 : if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2633 0 : pp->expression (TREE_OPERAND (t, 0));
2634 15 : pp_cxx_right_paren (pp);
2635 15 : }
2636 :
2637 : void
2638 0 : pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2639 : {
2640 0 : pp_cxx_ws_string (pp, "__builtin_addressof");
2641 0 : pp_cxx_left_paren (pp);
2642 0 : pp->expression (TREE_OPERAND (t, 0));
2643 0 : pp_cxx_right_paren (pp);
2644 0 : }
2645 :
2646 : static char const*
2647 3918 : get_fold_operator (tree t)
2648 : {
2649 3918 : ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2650 : FOLD_EXPR_OP (t));
2651 3918 : return info->name;
2652 : }
2653 :
2654 : void
2655 335 : pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2656 : {
2657 335 : char const* op = get_fold_operator (t);
2658 335 : tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2659 335 : pp_cxx_left_paren (pp);
2660 335 : pp_cxx_ws_string (pp, "...");
2661 335 : pp_cxx_ws_string (pp, op);
2662 335 : pp->expression (expr);
2663 335 : pp_cxx_right_paren (pp);
2664 335 : }
2665 :
2666 : void
2667 3581 : pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2668 : {
2669 3581 : char const* op = get_fold_operator (t);
2670 3581 : tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2671 3581 : pp_cxx_left_paren (pp);
2672 3581 : pp->expression (expr);
2673 3581 : pp_space (pp);
2674 3581 : pp_cxx_ws_string (pp, op);
2675 3581 : pp_cxx_ws_string (pp, "...");
2676 3581 : pp_cxx_right_paren (pp);
2677 3581 : }
2678 :
2679 : void
2680 2 : pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2681 : {
2682 2 : char const* op = get_fold_operator (t);
2683 2 : tree t1 = TREE_OPERAND (t, 1);
2684 2 : tree t2 = TREE_OPERAND (t, 2);
2685 2 : if (t1 == FOLD_EXPR_PACK (t))
2686 2 : t1 = PACK_EXPANSION_PATTERN (t1);
2687 : else
2688 0 : t2 = PACK_EXPANSION_PATTERN (t2);
2689 2 : pp_cxx_left_paren (pp);
2690 2 : pp->expression (t1);
2691 2 : pp_cxx_ws_string (pp, op);
2692 2 : pp_cxx_ws_string (pp, "...");
2693 2 : pp_cxx_ws_string (pp, op);
2694 2 : pp->expression (t2);
2695 2 : pp_cxx_right_paren (pp);
2696 2 : }
2697 :
2698 : void
2699 641 : pp_cxx_trait (cxx_pretty_printer *pp, tree t)
2700 : {
2701 641 : cp_trait_kind kind;
2702 641 : tree type1, type2;
2703 641 : if (TREE_CODE (t) == TRAIT_EXPR)
2704 : {
2705 593 : kind = TRAIT_EXPR_KIND (t);
2706 593 : type1 = TRAIT_EXPR_TYPE1 (t);
2707 593 : type2 = TRAIT_EXPR_TYPE2 (t);
2708 : }
2709 : else
2710 : {
2711 48 : kind = TRAIT_TYPE_KIND (t);
2712 48 : type1 = TRAIT_TYPE_TYPE1 (t);
2713 48 : type2 = TRAIT_TYPE_TYPE2 (t);
2714 : }
2715 :
2716 641 : switch (kind)
2717 : {
2718 : #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2719 : case CPTK_##CODE: \
2720 : pp_cxx_ws_string (pp, NAME); \
2721 : break;
2722 : #include "cp-trait.def"
2723 : #undef DEFTRAIT
2724 : }
2725 :
2726 641 : if (kind == CPTK_TYPE_PACK_ELEMENT)
2727 : {
2728 9 : pp_cxx_begin_template_argument_list (pp);
2729 9 : pp->expression (type1);
2730 : }
2731 : else
2732 : {
2733 632 : pp_cxx_left_paren (pp);
2734 632 : if (TYPE_P (type1))
2735 536 : pp->type_id (type1);
2736 : else
2737 96 : pp->expression (type1);
2738 : }
2739 641 : if (type2)
2740 : {
2741 388 : if (TREE_CODE (type2) != TREE_VEC)
2742 : {
2743 345 : pp_cxx_separate_with (pp, ',');
2744 345 : pp->type_id (type2);
2745 : }
2746 : else
2747 86 : for (tree arg : tree_vec_range (type2))
2748 : {
2749 43 : pp_cxx_separate_with (pp, ',');
2750 43 : pp->type_id (arg);
2751 : }
2752 : }
2753 641 : if (kind == CPTK_TYPE_PACK_ELEMENT)
2754 9 : pp_cxx_end_template_argument_list (pp);
2755 : else
2756 632 : pp_cxx_right_paren (pp);
2757 641 : }
2758 :
2759 : // requires-clause:
2760 : // 'requires' logical-or-expression
2761 : void
2762 19888 : pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2763 : {
2764 19888 : if (!t)
2765 : return;
2766 19888 : pp->set_padding (pp_before);
2767 19888 : pp_cxx_ws_string (pp, "requires");
2768 19888 : pp_space (pp);
2769 19888 : pp->expression (t);
2770 : }
2771 :
2772 : /* requirement:
2773 : simple-requirement
2774 : compound-requirement
2775 : type-requirement
2776 : nested-requirement */
2777 : static void
2778 408 : pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2779 : {
2780 408 : switch (TREE_CODE (t))
2781 : {
2782 242 : case SIMPLE_REQ:
2783 242 : pp_cxx_simple_requirement (pp, t);
2784 242 : break;
2785 :
2786 17 : case TYPE_REQ:
2787 17 : pp_cxx_type_requirement (pp, t);
2788 17 : break;
2789 :
2790 104 : case COMPOUND_REQ:
2791 104 : pp_cxx_compound_requirement (pp, t);
2792 104 : break;
2793 :
2794 45 : case NESTED_REQ:
2795 45 : pp_cxx_nested_requirement (pp, t);
2796 45 : break;
2797 :
2798 0 : default:
2799 0 : gcc_unreachable ();
2800 : }
2801 408 : }
2802 :
2803 : // requirement-list:
2804 : // requirement
2805 : // requirement-list ';' requirement[opt]
2806 : //
2807 : static void
2808 401 : pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2809 : {
2810 809 : for (; t; t = TREE_CHAIN (t))
2811 408 : pp_cxx_requirement (pp, TREE_VALUE (t));
2812 401 : }
2813 :
2814 : // requirement-body:
2815 : // '{' requirement-list '}'
2816 : static void
2817 401 : pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2818 : {
2819 401 : pp_cxx_left_brace (pp);
2820 401 : pp_cxx_requirement_list (pp, t);
2821 401 : pp_cxx_right_brace (pp);
2822 401 : }
2823 :
2824 : // requires-expression:
2825 : // 'requires' requirement-parameter-list requirement-body
2826 : void
2827 401 : pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2828 : {
2829 401 : pp_string (pp, "requires");
2830 401 : if (tree parms = REQUIRES_EXPR_PARMS (t))
2831 : {
2832 173 : bool first = true;
2833 173 : pp_cxx_left_paren (pp);
2834 563 : for (; parms; parms = TREE_CHAIN (parms))
2835 : {
2836 217 : if (!first)
2837 44 : pp_cxx_separate_with (pp, ',' );
2838 217 : first = false;
2839 217 : pp_cxx_parameter_declaration (pp, parms);
2840 : }
2841 173 : pp_cxx_right_paren (pp);
2842 173 : pp_cxx_whitespace (pp);
2843 : }
2844 401 : pp_cxx_requirement_body (pp, REQUIRES_EXPR_REQS (t));
2845 401 : }
2846 :
2847 : /* simple-requirement:
2848 : expression ';' */
2849 : void
2850 242 : pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2851 : {
2852 242 : pp->expression (TREE_OPERAND (t, 0));
2853 242 : pp_cxx_semicolon (pp);
2854 242 : }
2855 :
2856 : /* type-requirement:
2857 : typename type-name ';' */
2858 : void
2859 17 : pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2860 : {
2861 17 : pp->type_id (TREE_OPERAND (t, 0));
2862 17 : pp_cxx_semicolon (pp);
2863 17 : }
2864 :
2865 : /* compound-requirement:
2866 : '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2867 : void
2868 104 : pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2869 : {
2870 104 : pp_cxx_left_brace (pp);
2871 104 : pp->expression (TREE_OPERAND (t, 0));
2872 104 : pp_cxx_right_brace (pp);
2873 :
2874 104 : if (TREE_OPERAND (t, 2) == boolean_true_node)
2875 0 : pp_cxx_ws_string (pp, "noexcept");
2876 104 : else if (TREE_OPERAND (t, 2) != boolean_false_node)
2877 : {
2878 0 : pp_cxx_ws_string (pp, "noexcept(");
2879 0 : pp->expression (TREE_OPERAND (t, 2));
2880 0 : pp_cxx_right_paren (pp);
2881 : }
2882 :
2883 104 : if (tree type = TREE_OPERAND (t, 1))
2884 : {
2885 92 : pp_cxx_whitespace (pp);
2886 92 : pp_cxx_ws_string (pp, "->");
2887 92 : pp->type_id (type);
2888 : }
2889 104 : pp_cxx_semicolon (pp);
2890 104 : }
2891 :
2892 : /* nested requirement:
2893 : 'requires' constraint-expression */
2894 : void
2895 45 : pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2896 : {
2897 45 : pp_cxx_ws_string (pp, "requires");
2898 45 : pp->expression (TREE_OPERAND (t, 0));
2899 45 : pp_cxx_semicolon (pp);
2900 45 : }
2901 :
2902 : /* Output the "[with ...]" clause for a parameter mapping of an atomic
2903 : constraint. */
2904 :
2905 : void
2906 2055 : pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map)
2907 : {
2908 2055 : pp_cxx_whitespace (pp);
2909 2055 : pp_cxx_left_bracket (pp);
2910 2055 : pp->translate_string ("with");
2911 2055 : pp_cxx_whitespace (pp);
2912 :
2913 6712 : for (tree p = map; p; p = TREE_CHAIN (p))
2914 : {
2915 2602 : tree parm = TREE_VALUE (p);
2916 2602 : tree arg = TREE_PURPOSE (p);
2917 :
2918 2602 : if (TYPE_P (parm))
2919 2469 : pp->type_id (parm);
2920 133 : else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2921 122 : pp_cxx_tree_identifier (pp, name);
2922 : else
2923 11 : pp->translate_string ("<unnamed>");
2924 :
2925 2602 : pp_cxx_whitespace (pp);
2926 2602 : pp_equal (pp);
2927 2602 : pp_cxx_whitespace (pp);
2928 :
2929 2602 : if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2930 2466 : pp->type_id (arg);
2931 : else
2932 136 : pp->expression (arg);
2933 :
2934 2602 : if (TREE_CHAIN (p) != NULL_TREE)
2935 547 : pp_cxx_separate_with (pp, ';');
2936 : }
2937 :
2938 2055 : pp_cxx_right_bracket (pp);
2939 2055 : }
2940 :
2941 : void
2942 1007 : pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t)
2943 : {
2944 : /* Emit the expression. */
2945 1007 : pp->expression (ATOMIC_CONSTR_EXPR (t));
2946 :
2947 : /* Emit the parameter mapping. */
2948 1007 : tree map = ATOMIC_CONSTR_MAP (t);
2949 1007 : if (map && map != error_mark_node)
2950 900 : pp_cxx_parameter_mapping (pp, map);
2951 1007 : }
2952 :
2953 : void
2954 0 : pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2955 : {
2956 0 : pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2957 0 : pp_string (pp, " /\\ ");
2958 0 : pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2959 0 : }
2960 :
2961 : void
2962 0 : pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2963 : {
2964 0 : pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2965 0 : pp_string (pp, " \\/ ");
2966 0 : pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2967 0 : }
2968 :
2969 : void
2970 1007 : pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2971 : {
2972 1007 : if (t == error_mark_node)
2973 0 : return pp->expression (t);
2974 :
2975 1007 : switch (TREE_CODE (t))
2976 : {
2977 1007 : case ATOMIC_CONSTR:
2978 1007 : pp_cxx_atomic_constraint (pp, t);
2979 1007 : break;
2980 :
2981 0 : case CONJ_CONSTR:
2982 0 : pp_cxx_conjunction (pp, t);
2983 0 : break;
2984 :
2985 0 : case DISJ_CONSTR:
2986 0 : pp_cxx_disjunction (pp, t);
2987 0 : break;
2988 :
2989 0 : case EXPR_PACK_EXPANSION:
2990 0 : pp->expression (TREE_OPERAND (t, 0));
2991 0 : break;
2992 :
2993 0 : default:
2994 0 : gcc_unreachable ();
2995 : }
2996 : }
2997 :
2998 :
2999 : typedef c_pretty_print_fn pp_fun;
3000 :
3001 : /* Initialization of a C++ pretty-printer object. */
3002 :
3003 203184 : cxx_pretty_printer::cxx_pretty_printer ()
3004 : : c_pretty_printer (),
3005 203184 : enclosing_scope (global_namespace)
3006 : {
3007 203184 : type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
3008 203184 : parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
3009 203184 : }
3010 :
3011 : /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
3012 :
3013 : std::unique_ptr<pretty_printer>
3014 227164 : cxx_pretty_printer::clone () const
3015 : {
3016 227164 : return std::make_unique<cxx_pretty_printer> (*this);
3017 : }
|