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