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

source code of gcc/cp/cxx-pretty-print.cc