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