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>
5 This file is part of GCC.
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
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
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/>. */
23 #include "coretypes.h"
25 #include "cxx-pretty-print.h"
26 #include "tree-pretty-print.h"
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
);
44 pp_cxx_nonconsecutive_character (cxx_pretty_printer
*pp
, int c
)
46 const char *p
= pp_last_position_in_text (pp
);
48 if (p
!= NULL
&& *p
== c
)
49 pp_cxx_whitespace (pp
);
51 pp
->padding
= pp_none
;
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)
64 pp_cxx_colon_colon (cxx_pretty_printer
*pp
)
67 pp
->padding
= pp_none
;
71 pp_cxx_begin_template_argument_list (cxx_pretty_printer
*pp
)
73 pp_cxx_nonconsecutive_character (pp
, '<');
77 pp_cxx_end_template_argument_list (cxx_pretty_printer
*pp
)
79 pp_cxx_nonconsecutive_character (pp
, '>');
83 pp_cxx_separate_with (cxx_pretty_printer
*pp
, int c
)
85 pp_separate_with (pp
, c
);
86 pp
->padding
= pp_none
;
92 is_destructor_name (tree name
)
94 return name
== complete_dtor_identifier
95 || name
== base_dtor_identifier
96 || name
== deleting_dtor_identifier
;
99 /* conversion-function-id:
100 operator conversion-type-id
103 type-specifier-seq conversion-declarator(opt)
105 conversion-declarator:
106 ptr-operator conversion-declarator(opt) */
109 pp_cxx_conversion_function_id (cxx_pretty_printer
*pp
, tree t
)
111 pp_cxx_ws_string (pp
, "operator");
112 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
116 pp_cxx_template_id (cxx_pretty_printer
*pp
, tree t
)
118 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 0));
119 pp_cxx_begin_template_argument_list (pp
);
120 pp_cxx_template_argument_list (pp
, TREE_OPERAND (t
, 1));
121 pp_cxx_end_template_argument_list (pp
);
124 /* Prints the unqualified part of the id-expression T.
129 conversion-function-id
134 pp_cxx_unqualified_id (cxx_pretty_printer
*pp
, tree t
)
136 enum tree_code code
= TREE_CODE (t
);
140 pp
->translate_string ("<return-value>");
159 case IDENTIFIER_NODE
:
161 pp
->translate_string ("<unnamed>");
162 else if (IDENTIFIER_CONV_OP_P (t
))
163 pp_cxx_conversion_function_id (pp
, t
);
166 if (is_destructor_name (t
))
169 /* FIXME: Why is this necessary? */
171 t
= constructor_name (TREE_TYPE (t
));
173 pp_cxx_tree_identifier (pp
, t
);
177 case TEMPLATE_ID_EXPR
:
178 pp_cxx_template_id (pp
, t
);
182 pp_cxx_unqualified_id (pp
, BASELINK_FUNCTIONS (t
));
189 case UNBOUND_CLASS_TEMPLATE
:
190 pp_cxx_unqualified_id (pp
, TYPE_NAME (t
));
191 if (CLASS_TYPE_P (t
) && CLASSTYPE_USE_TEMPLATE (t
))
193 pp_cxx_begin_template_argument_list (pp
);
194 pp_cxx_template_argument_list (pp
, INNERMOST_TEMPLATE_ARGS
195 (CLASSTYPE_TI_ARGS (t
)));
196 pp_cxx_end_template_argument_list (pp
);
201 pp_cxx_complement (pp
);
202 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 0));
205 case TEMPLATE_TYPE_PARM
:
206 case TEMPLATE_TEMPLATE_PARM
:
207 if (TYPE_IDENTIFIER (t
))
208 pp_cxx_unqualified_id (pp
, TYPE_IDENTIFIER (t
));
210 pp_cxx_canonical_template_parameter (pp
, t
);
213 case TEMPLATE_PARM_INDEX
:
214 pp_cxx_unqualified_id (pp
, TEMPLATE_PARM_DECL (t
));
217 case BOUND_TEMPLATE_TEMPLATE_PARM
:
218 pp_cxx_cv_qualifier_seq (pp
, t
);
219 pp_cxx_unqualified_id (pp
, TYPE_IDENTIFIER (t
));
220 pp_cxx_begin_template_argument_list (pp
);
221 pp_cxx_template_argument_list (pp
, TYPE_TI_ARGS (t
));
222 pp_cxx_end_template_argument_list (pp
);
226 pp_unsupported_tree (pp
, t
);
231 /* Pretty-print out the token sequence ":: template" in template codes
232 where it is needed to "inline declare" the (following) member as
233 a template. This situation arises when SCOPE of T is dependent
234 on template parameters. */
237 pp_cxx_template_keyword_if_needed (cxx_pretty_printer
*pp
, tree scope
, tree t
)
239 if (TREE_CODE (t
) == TEMPLATE_ID_EXPR
240 && TYPE_P (scope
) && dependent_type_p (scope
))
241 pp_cxx_ws_string (pp
, "template");
244 /* nested-name-specifier:
245 class-or-namespace-name :: nested-name-specifier(opt)
246 class-or-namespace-name :: template nested-name-specifier */
249 pp_cxx_nested_name_specifier (cxx_pretty_printer
*pp
, tree t
)
251 if (!SCOPE_FILE_SCOPE_P (t
) && t
!= pp
->enclosing_scope
)
253 tree scope
= get_containing_scope (t
);
254 pp_cxx_nested_name_specifier (pp
, scope
);
255 pp_cxx_template_keyword_if_needed (pp
, scope
, t
);
256 pp_cxx_unqualified_id (pp
, t
);
257 pp_cxx_colon_colon (pp
);
262 nested-name-specifier template(opt) unqualified-id */
265 pp_cxx_qualified_id (cxx_pretty_printer
*pp
, tree t
)
267 switch (TREE_CODE (t
))
269 /* A pointer-to-member is always qualified. */
271 pp_cxx_nested_name_specifier (pp
, PTRMEM_CST_CLASS (t
));
272 pp_cxx_unqualified_id (pp
, PTRMEM_CST_MEMBER (t
));
275 /* In Standard C++, functions cannot possibly be used as
276 nested-name-specifiers. However, there are situations where
277 is "makes sense" to output the surrounding function name for the
278 purpose of emphasizing on the scope kind. Just printing the
279 function name might not be sufficient as it may be overloaded; so,
280 we decorate the function with its signature too.
281 FIXME: This is probably the wrong pretty-printing for conversion
282 functions and some function templates. */
287 if (DECL_FUNCTION_MEMBER_P (t
))
288 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
289 pp_cxx_unqualified_id
290 (pp
, DECL_CONSTRUCTOR_P (t
) ? DECL_CONTEXT (t
) : t
);
291 pp_cxx_parameter_declaration_clause (pp
, TREE_TYPE (t
));
296 pp_cxx_nested_name_specifier (pp
, TREE_OPERAND (t
, 0));
297 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 1));
302 tree scope
= get_containing_scope (t
);
303 if (scope
!= pp
->enclosing_scope
)
305 pp_cxx_nested_name_specifier (pp
, scope
);
306 pp_cxx_template_keyword_if_needed (pp
, scope
, t
);
308 pp_cxx_unqualified_id (pp
, t
);
316 cxx_pretty_printer::constant (tree t
)
318 switch (TREE_CODE (t
))
322 const bool in_parens
= PAREN_STRING_LITERAL_P (t
);
324 pp_cxx_left_paren (this);
325 c_pretty_printer::constant (t
);
327 pp_cxx_right_paren (this);
332 if (NULLPTR_TYPE_P (TREE_TYPE (t
)))
334 pp_string (this, "nullptr");
340 c_pretty_printer::constant (t
);
350 cxx_pretty_printer::id_expression (tree t
)
352 if (TREE_CODE (t
) == OVERLOAD
)
354 if (DECL_P (t
) && DECL_CONTEXT (t
))
355 pp_cxx_qualified_id (this, t
);
357 pp_cxx_unqualified_id (this, t
);
360 /* user-defined literal:
364 pp_cxx_userdef_literal (cxx_pretty_printer
*pp
, tree t
)
366 pp
->constant (USERDEF_LITERAL_VALUE (t
));
367 pp
->id_expression (USERDEF_LITERAL_SUFFIX_ID (t
));
371 /* primary-expression:
375 :: operator-function-id
381 __builtin_va_arg ( assignment-expression , type-id )
382 __builtin_offsetof ( type-id, offsetof-expression )
383 __builtin_addressof ( expression )
385 __has_nothrow_assign ( type-id )
386 __has_nothrow_constructor ( type-id )
387 __has_nothrow_copy ( type-id )
388 __has_trivial_assign ( type-id )
389 __has_trivial_constructor ( type-id )
390 __has_trivial_copy ( type-id )
391 __has_unique_object_representations ( type-id )
392 __has_trivial_destructor ( type-id )
393 __has_virtual_destructor ( type-id )
394 __is_abstract ( type-id )
395 __is_base_of ( type-id , type-id )
396 __is_class ( type-id )
397 __is_empty ( type-id )
398 __is_enum ( type-id )
399 __is_literal_type ( type-id )
401 __is_polymorphic ( type-id )
402 __is_std_layout ( type-id )
403 __is_trivial ( type-id )
404 __is_union ( type-id ) */
407 cxx_pretty_printer::primary_expression (tree t
)
409 switch (TREE_CODE (t
))
419 case USERDEF_LITERAL
:
420 pp_cxx_userdef_literal (this, t
);
424 t
= BASELINK_FUNCTIONS (t
);
437 case TEMPLATE_TYPE_PARM
:
438 case TEMPLATE_TEMPLATE_PARM
:
439 case TEMPLATE_PARM_INDEX
:
440 pp_cxx_unqualified_id (this, t
);
444 pp_cxx_left_paren (this);
445 statement (STMT_EXPR_STMT (t
));
446 pp_cxx_right_paren (this);
450 pp_cxx_trait_expression (this, t
);
454 pp_cxx_va_arg_expression (this, t
);
458 pp_cxx_offsetof_expression (this, t
);
462 pp_cxx_addressof_expression (this, t
);
466 pp_cxx_requires_expr (this, t
);
470 c_pretty_printer::primary_expression (t
);
475 /* postfix-expression:
477 postfix-expression [ expression ]
478 postfix-expression ( expression-list(opt) )
479 simple-type-specifier ( expression-list(opt) )
480 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
481 typename ::(opt) nested-name-specifier template(opt)
482 template-id ( expression-list(opt) )
483 postfix-expression . template(opt) ::(opt) id-expression
484 postfix-expression -> template(opt) ::(opt) id-expression
485 postfix-expression . pseudo-destructor-name
486 postfix-expression -> pseudo-destructor-name
487 postfix-expression ++
488 postfix-expression --
489 dynamic_cast < type-id > ( expression )
490 static_cast < type-id > ( expression )
491 reinterpret_cast < type-id > ( expression )
492 const_cast < type-id > ( expression )
493 typeid ( expression )
494 typeid ( type-id ) */
497 cxx_pretty_printer::postfix_expression (tree t
)
499 enum tree_code code
= TREE_CODE (t
);
506 tree fun
= cp_get_callee (t
);
507 tree saved_scope
= enclosing_scope
;
508 bool skipfirst
= false;
511 if (TREE_CODE (fun
) == ADDR_EXPR
)
512 fun
= TREE_OPERAND (fun
, 0);
514 /* In templates, where there is no way to tell whether a given
515 call uses an actual member function. So the parser builds
516 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
517 instantiation time. */
518 if (TREE_CODE (fun
) != FUNCTION_DECL
)
520 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun
))
522 tree object
= (code
== AGGR_INIT_EXPR
523 ? (AGGR_INIT_VIA_CTOR_P (t
)
524 ? AGGR_INIT_EXPR_SLOT (t
)
525 : AGGR_INIT_EXPR_ARG (t
, 0))
526 : CALL_EXPR_ARG (t
, 0));
528 while (TREE_CODE (object
) == NOP_EXPR
)
529 object
= TREE_OPERAND (object
, 0);
531 if (TREE_CODE (object
) == ADDR_EXPR
)
532 object
= TREE_OPERAND (object
, 0);
534 if (!TYPE_PTR_P (TREE_TYPE (object
)))
536 postfix_expression (object
);
541 postfix_expression (object
);
545 enclosing_scope
= strip_pointer_operator (TREE_TYPE (object
));
548 postfix_expression (fun
);
549 enclosing_scope
= saved_scope
;
550 pp_cxx_left_paren (this);
551 if (code
== AGGR_INIT_EXPR
)
553 aggr_init_expr_arg_iterator iter
;
554 FOR_EACH_AGGR_INIT_EXPR_ARG (arg
, iter
, t
)
561 if (more_aggr_init_expr_args_p (&iter
))
562 pp_cxx_separate_with (this, ',');
568 call_expr_arg_iterator iter
;
569 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
576 if (more_call_expr_args_p (&iter
))
577 pp_cxx_separate_with (this, ',');
581 pp_cxx_right_paren (this);
583 if (code
== AGGR_INIT_EXPR
&& AGGR_INIT_VIA_CTOR_P (t
))
585 pp_cxx_separate_with (this, ',');
586 postfix_expression (AGGR_INIT_EXPR_SLOT (t
));
599 primary_expression (t
);
602 case DYNAMIC_CAST_EXPR
:
603 case STATIC_CAST_EXPR
:
604 case REINTERPRET_CAST_EXPR
:
605 case CONST_CAST_EXPR
:
606 if (code
== DYNAMIC_CAST_EXPR
)
607 pp_cxx_ws_string (this, "dynamic_cast");
608 else if (code
== STATIC_CAST_EXPR
)
609 pp_cxx_ws_string (this, "static_cast");
610 else if (code
== REINTERPRET_CAST_EXPR
)
611 pp_cxx_ws_string (this, "reinterpret_cast");
613 pp_cxx_ws_string (this, "const_cast");
614 pp_cxx_begin_template_argument_list (this);
615 type_id (TREE_TYPE (t
));
616 pp_cxx_end_template_argument_list (this);
617 pp_left_paren (this);
618 expression (TREE_OPERAND (t
, 0));
619 pp_right_paren (this);
622 case EMPTY_CLASS_EXPR
:
623 type_id (TREE_TYPE (t
));
624 pp_left_paren (this);
625 pp_right_paren (this);
629 pp_cxx_typeid_expression (this, t
);
632 case PSEUDO_DTOR_EXPR
:
633 postfix_expression (TREE_OPERAND (t
, 0));
635 if (TREE_OPERAND (t
, 1))
637 pp_cxx_qualified_id (this, TREE_OPERAND (t
, 1));
638 pp_cxx_colon_colon (this);
640 pp_complement (this);
641 pp_cxx_unqualified_id (this, TREE_OPERAND (t
, 2));
645 postfix_expression (TREE_OPERAND (t
, 0));
650 c_pretty_printer::postfix_expression (t
);
656 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
657 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
663 type-specifier-seq new-declarator(opt)
666 ptr-operator new-declarator(opt)
667 direct-new-declarator
669 direct-new-declarator
671 direct-new-declarator [ constant-expression ]
674 ( expression-list(opt) ) */
677 pp_cxx_new_expression (cxx_pretty_printer
*pp
, tree t
)
679 enum tree_code code
= TREE_CODE (t
);
680 tree type
= TREE_OPERAND (t
, 1);
681 tree init
= TREE_OPERAND (t
, 2);
686 if (NEW_EXPR_USE_GLOBAL (t
))
687 pp_cxx_colon_colon (pp
);
688 pp_cxx_ws_string (pp
, "new");
689 if (TREE_OPERAND (t
, 0))
691 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
694 if (TREE_CODE (type
) == ARRAY_REF
)
695 type
= build_cplus_array_type
696 (TREE_OPERAND (type
, 0),
697 build_index_type (fold_build2_loc (input_location
,
698 MINUS_EXPR
, integer_type_node
,
699 TREE_OPERAND (type
, 1),
705 if (TREE_CODE (init
) == TREE_LIST
)
706 pp_c_expression_list (pp
, init
);
707 else if (init
== void_node
)
708 ; /* OK, empty initializer list. */
710 pp
->expression (init
);
716 pp_unsupported_tree (pp
, t
);
720 /* delete-expression:
721 ::(opt) delete cast-expression
722 ::(opt) delete [ ] cast-expression */
725 pp_cxx_delete_expression (cxx_pretty_printer
*pp
, tree t
)
727 enum tree_code code
= TREE_CODE (t
);
731 case VEC_DELETE_EXPR
:
732 if (DELETE_EXPR_USE_GLOBAL (t
))
733 pp_cxx_colon_colon (pp
);
734 pp_cxx_ws_string (pp
, "delete");
736 if (code
== VEC_DELETE_EXPR
737 || DELETE_EXPR_USE_VEC (t
))
739 pp_left_bracket (pp
);
740 pp_right_bracket (pp
);
743 pp_c_cast_expression (pp
, TREE_OPERAND (t
, 0));
747 pp_unsupported_tree (pp
, t
);
755 unary-operator cast-expression
756 sizeof unary-expression
758 sizeof ... ( identifier )
762 unary-operator: one of
766 __alignof__ unary-expression
767 __alignof__ ( type-id ) */
770 cxx_pretty_printer::unary_expression (tree t
)
772 enum tree_code code
= TREE_CODE (t
);
777 pp_cxx_new_expression (this, t
);
781 case VEC_DELETE_EXPR
:
782 pp_cxx_delete_expression (this, t
);
786 if (PACK_EXPANSION_P (TREE_OPERAND (t
, 0)))
788 pp_cxx_ws_string (this, "sizeof");
789 pp_cxx_ws_string (this, "...");
790 pp_cxx_whitespace (this);
791 pp_cxx_left_paren (this);
792 if (TYPE_P (TREE_OPERAND (t
, 0)))
793 type_id (TREE_OPERAND (t
, 0));
795 unary_expression (TREE_OPERAND (t
, 0));
796 pp_cxx_right_paren (this);
802 pp_cxx_ws_string (this, code
== SIZEOF_EXPR
? "sizeof" : "__alignof__");
803 pp_cxx_whitespace (this);
804 if (TREE_CODE (t
) == SIZEOF_EXPR
&& SIZEOF_EXPR_TYPE_P (t
))
806 pp_cxx_left_paren (this);
807 type_id (TREE_TYPE (TREE_OPERAND (t
, 0)));
808 pp_cxx_right_paren (this);
810 else if (TYPE_P (TREE_OPERAND (t
, 0)))
812 pp_cxx_left_paren (this);
813 type_id (TREE_OPERAND (t
, 0));
814 pp_cxx_right_paren (this);
817 unary_expression (TREE_OPERAND (t
, 0));
821 pp_cxx_ws_string (this, "@encode");
822 pp_cxx_whitespace (this);
823 pp_cxx_left_paren (this);
824 type_id (TREE_OPERAND (t
, 0));
825 pp_cxx_right_paren (this);
829 pp_cxx_ws_string (this, "noexcept");
830 pp_cxx_whitespace (this);
831 pp_cxx_left_paren (this);
832 expression (TREE_OPERAND (t
, 0));
833 pp_cxx_right_paren (this);
836 case UNARY_PLUS_EXPR
:
838 pp_cxx_cast_expression (this, TREE_OPERAND (t
, 0));
842 c_pretty_printer::unary_expression (t
);
849 ( type-id ) cast-expression */
852 pp_cxx_cast_expression (cxx_pretty_printer
*pp
, tree t
)
854 switch (TREE_CODE (t
))
857 case IMPLICIT_CONV_EXPR
:
858 pp
->type_id (TREE_TYPE (t
));
859 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
863 pp_c_cast_expression (pp
, t
);
870 pm-expression .* cast-expression
871 pm-expression ->* cast-expression */
874 pp_cxx_pm_expression (cxx_pretty_printer
*pp
, tree t
)
876 switch (TREE_CODE (t
))
878 /* Handle unfortunate OFFSET_REF overloading here. */
880 if (TYPE_P (TREE_OPERAND (t
, 0)))
882 pp_cxx_qualified_id (pp
, t
);
888 pp_cxx_pm_expression (pp
, TREE_OPERAND (t
, 0));
889 if (TREE_CODE (t
) == MEMBER_REF
)
894 pp_cxx_cast_expression (pp
, TREE_OPERAND (t
, 1));
899 pp_cxx_cast_expression (pp
, t
);
904 /* multiplicative-expression:
906 multiplicative-expression * pm-expression
907 multiplicative-expression / pm-expression
908 multiplicative-expression % pm-expression */
911 cxx_pretty_printer::multiplicative_expression (tree e
)
913 enum tree_code code
= TREE_CODE (e
);
919 multiplicative_expression (TREE_OPERAND (e
, 0));
921 if (code
== MULT_EXPR
)
923 else if (code
== TRUNC_DIV_EXPR
)
928 pp_cxx_pm_expression (this, TREE_OPERAND (e
, 1));
932 pp_cxx_pm_expression (this, e
);
937 /* conditional-expression:
938 logical-or-expression
939 logical-or-expression ? expression : assignment-expression */
942 cxx_pretty_printer::conditional_expression (tree e
)
944 if (TREE_CODE (e
) == COND_EXPR
)
946 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
950 expression (TREE_OPERAND (e
, 1));
952 assignment_expression (TREE_OPERAND (e
, 2));
955 pp_c_logical_or_expression (this, e
);
958 /* Pretty-print a compound assignment operator token as indicated by T. */
961 pp_cxx_assignment_operator (cxx_pretty_printer
*pp
, tree t
)
965 switch (TREE_CODE (t
))
988 op
= get_tree_code_name (TREE_CODE (t
));
992 pp_cxx_ws_string (pp
, op
);
996 /* assignment-expression:
997 conditional-expression
998 logical-or-expression assignment-operator assignment-expression
1002 throw assignment-expression(opt)
1004 assignment-operator: one of
1005 = *= /= %= += -= >>= <<= &= ^= |= */
1008 cxx_pretty_printer::assignment_expression (tree e
)
1010 switch (TREE_CODE (e
))
1014 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1018 assignment_expression (TREE_OPERAND (e
, 1));
1022 pp_cxx_ws_string (this, "throw");
1023 if (TREE_OPERAND (e
, 0))
1024 assignment_expression (TREE_OPERAND (e
, 0));
1028 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1029 pp_cxx_assignment_operator (this, TREE_OPERAND (e
, 1));
1030 assignment_expression (TREE_OPERAND (e
, 2));
1034 conditional_expression (e
);
1040 cxx_pretty_printer::expression (tree t
)
1042 switch (TREE_CODE (t
))
1052 case USERDEF_LITERAL
:
1053 pp_cxx_userdef_literal (this, t
);
1057 pp_cxx_unqualified_id (this, t
);
1065 pp_cxx_qualified_id (this, t
);
1078 case TEMPLATE_TYPE_PARM
:
1079 case TEMPLATE_PARM_INDEX
:
1080 case TEMPLATE_TEMPLATE_PARM
:
1083 primary_expression (t
);
1087 case DYNAMIC_CAST_EXPR
:
1088 case STATIC_CAST_EXPR
:
1089 case REINTERPRET_CAST_EXPR
:
1090 case CONST_CAST_EXPR
:
1094 case EMPTY_CLASS_EXPR
:
1096 case PSEUDO_DTOR_EXPR
:
1097 case AGGR_INIT_EXPR
:
1099 postfix_expression (t
);
1104 pp_cxx_new_expression (this, t
);
1108 case VEC_DELETE_EXPR
:
1109 pp_cxx_delete_expression (this, t
);
1115 case UNARY_PLUS_EXPR
:
1116 unary_expression (t
);
1120 case IMPLICIT_CONV_EXPR
:
1121 pp_cxx_cast_expression (this, t
);
1127 pp_cxx_pm_expression (this, t
);
1131 case TRUNC_DIV_EXPR
:
1132 case TRUNC_MOD_EXPR
:
1133 multiplicative_expression (t
);
1137 conditional_expression (t
);
1144 assignment_expression (t
);
1147 case NON_DEPENDENT_EXPR
:
1148 case MUST_NOT_THROW_EXPR
:
1149 expression (TREE_OPERAND (t
, 0));
1152 case EXPR_PACK_EXPANSION
:
1153 expression (PACK_EXPANSION_PATTERN (t
));
1154 pp_cxx_ws_string (this, "...");
1157 case UNARY_LEFT_FOLD_EXPR
:
1158 pp_cxx_unary_left_fold_expression (this, t
);
1161 case UNARY_RIGHT_FOLD_EXPR
:
1162 pp_cxx_unary_right_fold_expression (this, t
);
1165 case BINARY_LEFT_FOLD_EXPR
:
1166 case BINARY_RIGHT_FOLD_EXPR
:
1167 pp_cxx_binary_fold_expression (this, t
);
1170 case TEMPLATE_ID_EXPR
:
1171 pp_cxx_template_id (this, t
);
1174 case NONTYPE_ARGUMENT_PACK
:
1176 tree args
= ARGUMENT_PACK_ARGS (t
);
1177 int i
, len
= TREE_VEC_LENGTH (args
);
1178 for (i
= 0; i
< len
; ++i
)
1181 pp_cxx_separate_with (this, ',');
1182 expression (TREE_VEC_ELT (args
, i
));
1188 pp_cxx_ws_string (this, "<lambda>");
1192 pp_cxx_trait_expression (this, t
);
1205 pp_cxx_constraint (this, t
);
1209 pp_cxx_left_paren (this);
1210 expression (TREE_OPERAND (t
, 0));
1211 pp_cxx_right_paren (this);
1215 c_pretty_printer::expression (t
);
1223 /* function-specifier:
1229 cxx_pretty_printer::function_specifier (tree t
)
1231 switch (TREE_CODE (t
))
1234 if (DECL_VIRTUAL_P (t
))
1235 pp_cxx_ws_string (this, "virtual");
1236 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
1237 pp_cxx_ws_string (this, "explicit");
1239 c_pretty_printer::function_specifier (t
);
1246 /* decl-specifier-seq:
1247 decl-specifier-seq(opt) decl-specifier
1250 storage-class-specifier
1257 cxx_pretty_printer::declaration_specifiers (tree t
)
1259 switch (TREE_CODE (t
))
1265 storage_class_specifier (t
);
1266 declaration_specifiers (TREE_TYPE (t
));
1270 pp_cxx_ws_string (this, "typedef");
1271 declaration_specifiers (TREE_TYPE (t
));
1275 /* Constructors don't have return types. And conversion functions
1276 do not have a type-specifier in their return types. */
1277 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
1278 function_specifier (t
);
1279 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1280 declaration_specifiers (TREE_TYPE (TREE_TYPE (t
)));
1282 c_pretty_printer::declaration_specifiers (t
);
1285 c_pretty_printer::declaration_specifiers (t
);
1290 /* simple-type-specifier:
1291 ::(opt) nested-name-specifier(opt) type-name
1292 ::(opt) nested-name-specifier(opt) template(opt) template-id
1306 cxx_pretty_printer::simple_type_specifier (tree t
)
1308 switch (TREE_CODE (t
))
1313 pp_cxx_qualified_id (this, t
);
1316 case TEMPLATE_TYPE_PARM
:
1317 case TEMPLATE_TEMPLATE_PARM
:
1318 case TEMPLATE_PARM_INDEX
:
1319 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1320 pp_cxx_unqualified_id (this, t
);
1324 pp_cxx_ws_string (this, "typename");
1325 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t
));
1326 pp_cxx_unqualified_id (this, TYPE_NAME (t
));
1330 c_pretty_printer::simple_type_specifier (t
);
1335 /* type-specifier-seq:
1336 type-specifier type-specifier-seq(opt)
1339 simple-type-specifier
1342 elaborated-type-specifier
1346 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1348 switch (TREE_CODE (t
))
1351 case TEMPLATE_TYPE_PARM
:
1352 case TEMPLATE_TEMPLATE_PARM
:
1354 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1355 pp_cxx_cv_qualifier_seq (pp
, t
);
1356 pp
->simple_type_specifier (t
);
1360 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1361 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1362 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1366 pp_cxx_ws_string (pp
, "decltype");
1367 pp_cxx_left_paren (pp
);
1368 pp
->expression (DECLTYPE_TYPE_EXPR (t
));
1369 pp_cxx_right_paren (pp
);
1373 if (TYPE_PTRMEMFUNC_P (t
))
1375 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
1376 pp
->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm
)));
1377 pp_cxx_whitespace (pp
);
1378 pp_cxx_ptr_operator (pp
, t
);
1384 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1385 pp_c_specifier_qualifier_list (pp
, t
);
1390 * cv-qualifier-seq(opt)
1392 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1395 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1397 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1399 switch (TREE_CODE (t
))
1401 case REFERENCE_TYPE
:
1403 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1404 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1405 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1409 pp_cxx_cv_qualifier_seq (pp
, t
);
1416 if (TYPE_PTRMEMFUNC_P (t
))
1418 pp_cxx_left_paren (pp
);
1419 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1425 if (TYPE_PTRMEM_P (t
))
1427 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1428 pp_cxx_left_paren (pp
);
1429 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1431 pp_cxx_cv_qualifier_seq (pp
, t
);
1437 pp_unsupported_tree (pp
, t
);
1443 pp_cxx_implicit_parameter_type (tree mf
)
1445 return class_of_this_parm (TREE_TYPE (mf
));
1449 parameter-declaration:
1450 decl-specifier-seq declarator
1451 decl-specifier-seq declarator = assignment-expression
1452 decl-specifier-seq abstract-declarator(opt)
1453 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1456 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1458 pp
->declaration_specifiers (t
);
1460 pp
->abstract_declarator (t
);
1465 /* parameter-declaration-clause:
1466 parameter-declaration-list(opt) ...(opt)
1467 parameter-declaration-list , ...
1469 parameter-declaration-list:
1470 parameter-declaration
1471 parameter-declaration-list , parameter-declaration */
1474 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1480 // For a requires clause or the explicit printing of a parameter list
1481 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1482 // args and types are taken from the function decl T.
1483 if (TREE_CODE (t
) == PARM_DECL
)
1491 bool type_p
= TYPE_P (t
);
1492 args
= type_p
? NULL
: FUNCTION_FIRST_USER_PARM (t
);
1493 types
= type_p
? TYPE_ARG_TYPES (t
) : FUNCTION_FIRST_USER_PARMTYPE (t
);
1494 abstract
= args
== NULL
|| pp
->flags
& pp_c_flag_abstract
;
1498 /* Skip artificial parameter for nonstatic member functions. */
1499 if (TREE_CODE (t
) == METHOD_TYPE
)
1500 types
= TREE_CHAIN (types
);
1502 pp_cxx_left_paren (pp
);
1503 for (; args
; args
= TREE_CHAIN (args
), types
= TREE_CHAIN (types
))
1506 pp_cxx_separate_with (pp
, ',');
1508 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1509 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1511 pp_cxx_whitespace (pp
);
1513 pp_cxx_whitespace (pp
);
1514 pp
->assignment_expression (TREE_PURPOSE (types
));
1517 pp_cxx_right_paren (pp
);
1520 /* exception-specification:
1521 throw ( type-id-list(opt) )
1525 type-id-list , type-id */
1528 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1530 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1531 bool need_comma
= false;
1533 if (ex_spec
== NULL
)
1535 if (TREE_PURPOSE (ex_spec
))
1537 pp_cxx_ws_string (pp
, "noexcept");
1538 pp_cxx_whitespace (pp
);
1539 pp_cxx_left_paren (pp
);
1540 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1541 pp_cxx_ws_string (pp
, "<uninstantiated>");
1543 pp
->expression (TREE_PURPOSE (ex_spec
));
1544 pp_cxx_right_paren (pp
);
1547 pp_cxx_ws_string (pp
, "throw");
1548 pp_cxx_left_paren (pp
);
1549 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1551 tree type
= TREE_VALUE (ex_spec
);
1552 tree argpack
= NULL_TREE
;
1555 if (ARGUMENT_PACK_P (type
))
1557 argpack
= ARGUMENT_PACK_ARGS (type
);
1558 len
= TREE_VEC_LENGTH (argpack
);
1561 for (i
= 0; i
< len
; ++i
)
1564 type
= TREE_VEC_ELT (argpack
, i
);
1567 pp_cxx_separate_with (pp
, ',');
1574 pp_cxx_right_paren (pp
);
1577 /* direct-declarator:
1579 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1580 exception-specification(opt)
1581 direct-declaration [ constant-expression(opt) ]
1585 cxx_pretty_printer::direct_declarator (tree t
)
1587 switch (TREE_CODE (t
))
1595 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1597 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1598 || template_parameter_pack_p (t
))
1599 /* A function parameter pack or non-type template
1601 pp_cxx_ws_string (this, "...");
1603 id_expression (DECL_NAME (t
));
1605 abstract_declarator (TREE_TYPE (t
));
1609 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1611 pp_cxx_parameter_declaration_clause (this, t
);
1613 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1615 padding
= pp_before
;
1616 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1619 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1624 case TEMPLATE_TYPE_PARM
:
1625 case TEMPLATE_PARM_INDEX
:
1626 case TEMPLATE_TEMPLATE_PARM
:
1630 c_pretty_printer::direct_declarator (t
);
1637 ptr-operator declarator */
1640 cxx_pretty_printer::declarator (tree t
)
1642 direct_declarator (t
);
1644 // Print a requires clause.
1646 if (tree ci
= get_constraints (t
))
1647 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1648 pp_cxx_requires_clause (this, reqs
);
1651 /* ctor-initializer:
1652 : mem-initializer-list
1654 mem-initializer-list:
1656 mem-initializer , mem-initializer-list
1659 mem-initializer-id ( expression-list(opt) )
1662 ::(opt) nested-name-specifier(opt) class-name
1666 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1668 t
= TREE_OPERAND (t
, 0);
1669 pp_cxx_whitespace (pp
);
1671 pp_cxx_whitespace (pp
);
1672 for (; t
; t
= TREE_CHAIN (t
))
1674 tree purpose
= TREE_PURPOSE (t
);
1675 bool is_pack
= PACK_EXPANSION_P (purpose
);
1678 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1680 pp
->primary_expression (purpose
);
1681 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1683 pp_cxx_ws_string (pp
, "...");
1685 pp_cxx_separate_with (pp
, ',');
1689 /* function-definition:
1690 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1691 decl-specifier-seq(opt) declarator function-try-block */
1694 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1696 tree saved_scope
= pp
->enclosing_scope
;
1697 pp
->declaration_specifiers (t
);
1699 pp_needs_newline (pp
) = true;
1700 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1701 if (DECL_SAVED_TREE (t
))
1702 pp
->statement (DECL_SAVED_TREE (t
));
1704 pp_cxx_semicolon (pp
);
1705 pp_newline_and_flush (pp
);
1706 pp
->enclosing_scope
= saved_scope
;
1709 /* abstract-declarator:
1710 ptr-operator abstract-declarator(opt)
1711 direct-abstract-declarator */
1714 cxx_pretty_printer::abstract_declarator (tree t
)
1716 if (TYPE_PTRMEM_P (t
))
1717 pp_cxx_right_paren (this);
1718 else if (POINTER_TYPE_P (t
))
1720 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1721 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1722 pp_cxx_right_paren (this);
1725 direct_abstract_declarator (t
);
1728 /* direct-abstract-declarator:
1729 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1730 cv-qualifier-seq(opt) exception-specification(opt)
1731 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1732 ( abstract-declarator ) */
1735 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1737 switch (TREE_CODE (t
))
1739 case REFERENCE_TYPE
:
1740 abstract_declarator (t
);
1744 if (TYPE_PTRMEMFUNC_P (t
))
1745 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1750 pp_cxx_parameter_declaration_clause (this, t
);
1751 direct_abstract_declarator (TREE_TYPE (t
));
1752 if (TREE_CODE (t
) == METHOD_TYPE
)
1754 padding
= pp_before
;
1755 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1757 pp_cxx_exception_specification (this, t
);
1761 case TEMPLATE_TYPE_PARM
:
1762 case TEMPLATE_TEMPLATE_PARM
:
1763 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1764 case UNBOUND_CLASS_TEMPLATE
:
1768 c_pretty_printer::direct_abstract_declarator (t
);
1774 type-specifier-seq abstract-declarator(opt) */
1777 cxx_pretty_printer::type_id (tree t
)
1779 pp_flags saved_flags
= flags
;
1780 flags
|= pp_c_flag_abstract
;
1782 switch (TREE_CODE (t
))
1789 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1790 case UNBOUND_CLASS_TEMPLATE
:
1791 case TEMPLATE_TEMPLATE_PARM
:
1792 case TEMPLATE_TYPE_PARM
:
1793 case TEMPLATE_PARM_INDEX
:
1796 case UNDERLYING_TYPE
:
1798 case TEMPLATE_ID_EXPR
:
1799 pp_cxx_type_specifier_seq (this, t
);
1802 case TYPE_PACK_EXPANSION
:
1803 type_id (PACK_EXPANSION_PATTERN (t
));
1804 pp_cxx_ws_string (this, "...");
1808 c_pretty_printer::type_id (t
);
1812 flags
= saved_flags
;
1815 /* template-argument-list:
1816 template-argument ...(opt)
1817 template-argument-list, template-argument ...(opt)
1820 assignment-expression
1825 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1828 bool need_comma
= false;
1832 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1834 tree arg
= TREE_VEC_ELT (t
, i
);
1835 tree argpack
= NULL_TREE
;
1838 if (ARGUMENT_PACK_P (arg
))
1840 argpack
= ARGUMENT_PACK_ARGS (arg
);
1841 len
= TREE_VEC_LENGTH (argpack
);
1844 for (idx
= 0; idx
< len
; idx
++)
1847 arg
= TREE_VEC_ELT (argpack
, idx
);
1850 pp_cxx_separate_with (pp
, ',');
1854 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1855 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1858 pp
->expression (arg
);
1865 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1867 t
= DECL_EXPR_DECL (t
);
1868 pp_cxx_type_specifier_seq (pp
, t
);
1870 pp
->abstract_declarator (t
);
1878 cxx_pretty_printer::statement (tree t
)
1880 switch (TREE_CODE (t
))
1882 case CTOR_INITIALIZER
:
1883 pp_cxx_ctor_initializer (this, t
);
1887 pp_cxx_ws_string (this, "using");
1888 pp_cxx_ws_string (this, "namespace");
1889 if (DECL_CONTEXT (t
))
1890 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
1891 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
1895 pp_cxx_ws_string (this, "using");
1896 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
1897 pp_cxx_unqualified_id (this, DECL_NAME (t
));
1904 try compound-statement handler-seq */
1906 pp_maybe_newline_and_indent (this, 0);
1907 pp_cxx_ws_string (this, "try");
1908 pp_newline_and_indent (this, 3);
1909 statement (TRY_STMTS (t
));
1910 pp_newline_and_indent (this, -3);
1914 statement (TRY_HANDLERS (t
));
1919 handler handler-seq(opt)
1922 catch ( exception-declaration ) compound-statement
1924 exception-declaration:
1925 type-specifier-seq declarator
1926 type-specifier-seq abstract-declarator
1929 pp_cxx_ws_string (this, "catch");
1930 pp_cxx_left_paren (this);
1931 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
1932 pp_cxx_right_paren (this);
1933 pp_indentation (this) += 3;
1934 pp_needs_newline (this) = true;
1935 statement (HANDLER_BODY (t
));
1936 pp_indentation (this) -= 3;
1937 pp_needs_newline (this) = true;
1940 /* selection-statement:
1941 if ( expression ) statement
1942 if ( expression ) statement else statement */
1944 pp_cxx_ws_string (this, "if");
1945 pp_cxx_whitespace (this);
1946 pp_cxx_left_paren (this);
1947 expression (IF_COND (t
));
1948 pp_cxx_right_paren (this);
1949 pp_newline_and_indent (this, 2);
1950 statement (THEN_CLAUSE (t
));
1951 pp_newline_and_indent (this, -2);
1952 if (ELSE_CLAUSE (t
))
1954 tree else_clause
= ELSE_CLAUSE (t
);
1955 pp_cxx_ws_string (this, "else");
1956 if (TREE_CODE (else_clause
) == IF_STMT
)
1957 pp_cxx_whitespace (this);
1959 pp_newline_and_indent (this, 2);
1960 statement (else_clause
);
1961 if (TREE_CODE (else_clause
) != IF_STMT
)
1962 pp_newline_and_indent (this, -2);
1967 pp_cxx_ws_string (this, "switch");
1969 pp_cxx_left_paren (this);
1970 expression (SWITCH_STMT_COND (t
));
1971 pp_cxx_right_paren (this);
1972 pp_indentation (this) += 3;
1973 pp_needs_newline (this) = true;
1974 statement (SWITCH_STMT_BODY (t
));
1975 pp_newline_and_indent (this, -3);
1978 /* iteration-statement:
1979 while ( expression ) statement
1980 do statement while ( expression ) ;
1981 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1982 for ( declaration expression(opt) ; expression(opt) ) statement */
1984 pp_cxx_ws_string (this, "while");
1986 pp_cxx_left_paren (this);
1987 expression (WHILE_COND (t
));
1988 pp_cxx_right_paren (this);
1989 pp_newline_and_indent (this, 3);
1990 statement (WHILE_BODY (t
));
1991 pp_indentation (this) -= 3;
1992 pp_needs_newline (this) = true;
1996 pp_cxx_ws_string (this, "do");
1997 pp_newline_and_indent (this, 3);
1998 statement (DO_BODY (t
));
1999 pp_newline_and_indent (this, -3);
2000 pp_cxx_ws_string (this, "while");
2002 pp_cxx_left_paren (this);
2003 expression (DO_COND (t
));
2004 pp_cxx_right_paren (this);
2005 pp_cxx_semicolon (this);
2006 pp_needs_newline (this) = true;
2010 pp_cxx_ws_string (this, "for");
2012 pp_cxx_left_paren (this);
2013 if (FOR_INIT_STMT (t
))
2014 statement (FOR_INIT_STMT (t
));
2016 pp_cxx_semicolon (this);
2017 pp_needs_newline (this) = false;
2018 pp_cxx_whitespace (this);
2020 expression (FOR_COND (t
));
2021 pp_cxx_semicolon (this);
2022 pp_needs_newline (this) = false;
2023 pp_cxx_whitespace (this);
2025 expression (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;
2033 case RANGE_FOR_STMT
:
2034 pp_cxx_ws_string (this, "for");
2036 pp_cxx_left_paren (this);
2037 statement (RANGE_FOR_DECL (t
));
2039 pp_needs_newline (this) = false;
2042 statement (RANGE_FOR_EXPR (t
));
2043 pp_cxx_right_paren (this);
2044 pp_newline_and_indent (this, 3);
2045 statement (FOR_BODY (t
));
2046 pp_indentation (this) -= 3;
2047 pp_needs_newline (this) = true;
2053 return expression(opt) ; */
2056 pp_string (this, TREE_CODE (t
) == BREAK_STMT
? "break" : "continue");
2057 pp_cxx_semicolon (this);
2058 pp_needs_newline (this) = true;
2061 /* expression-statement:
2062 expression(opt) ; */
2064 expression (EXPR_STMT_EXPR (t
));
2065 pp_cxx_semicolon (this);
2066 pp_needs_newline (this) = true;
2070 pp_cxx_ws_string (this, "try");
2071 pp_newline_and_indent (this, 2);
2072 statement (CLEANUP_BODY (t
));
2073 pp_newline_and_indent (this, -2);
2074 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2075 pp_newline_and_indent (this, 2);
2076 statement (CLEANUP_EXPR (t
));
2077 pp_newline_and_indent (this, -2);
2085 c_pretty_printer::statement (t
);
2090 /* original-namespace-definition:
2091 namespace identifier { namespace-body }
2093 As an edge case, we also handle unnamed namespace definition here. */
2096 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2098 pp_cxx_ws_string (pp
, "namespace");
2099 if (DECL_CONTEXT (t
))
2100 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2102 pp_cxx_unqualified_id (pp
, t
);
2103 pp_cxx_whitespace (pp
);
2104 pp_cxx_left_brace (pp
);
2105 /* We do not print the namespace-body. */
2106 pp_cxx_whitespace (pp
);
2107 pp_cxx_right_brace (pp
);
2113 namespace-alias-definition:
2114 namespace identifier = qualified-namespace-specifier ;
2116 qualified-namespace-specifier:
2117 ::(opt) nested-name-specifier(opt) namespace-name */
2120 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2122 pp_cxx_ws_string (pp
, "namespace");
2123 if (DECL_CONTEXT (t
))
2124 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2125 pp_cxx_unqualified_id (pp
, t
);
2126 pp_cxx_whitespace (pp
);
2128 pp_cxx_whitespace (pp
);
2129 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2130 pp_cxx_nested_name_specifier (pp
,
2131 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2132 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2133 pp_cxx_semicolon (pp
);
2136 /* simple-declaration:
2137 decl-specifier-seq(opt) init-declarator-list(opt) */
2140 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2142 pp
->declaration_specifiers (t
);
2143 pp_cxx_init_declarator (pp
, t
);
2144 pp_cxx_semicolon (pp
);
2145 pp_needs_newline (pp
) = true;
2149 template-parameter-list:
2151 template-parameter-list , template-parameter */
2154 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2156 const int n
= TREE_VEC_LENGTH (t
);
2158 for (i
= 0; i
< n
; ++i
)
2161 pp_cxx_separate_with (pp
, ',');
2162 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2166 /* template-parameter:
2168 parameter-declaration
2171 class ...(opt) identifier(opt)
2172 class identifier(opt) = type-id
2173 typename identifier(opt)
2174 typename ...(opt) identifier(opt) = type-id
2175 template < template-parameter-list > class ...(opt) identifier(opt)
2176 template < template-parameter-list > class identifier(opt) = template-name */
2179 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2181 tree parameter
= TREE_VALUE (t
);
2182 switch (TREE_CODE (parameter
))
2185 pp_cxx_ws_string (pp
, "class");
2186 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2187 pp_cxx_ws_string (pp
, "...");
2188 if (DECL_NAME (parameter
))
2189 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2190 /* FIXME: Check if we should print also default argument. */
2194 pp_cxx_parameter_declaration (pp
, parameter
);
2201 pp_unsupported_tree (pp
, t
);
2206 /* Pretty-print a template parameter in the canonical form
2207 "template-parameter-<level>-<position in parameter list>". */
2210 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2212 const enum tree_code code
= TREE_CODE (parm
);
2214 /* Brings type template parameters to the canonical forms. */
2215 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2216 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2217 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2219 pp_cxx_begin_template_argument_list (pp
);
2220 pp
->translate_string ("template-parameter-");
2221 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2223 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2224 pp_cxx_end_template_argument_list (pp
);
2227 /* Print a constrained-type-specifier. */
2230 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2233 if (c
== error_mark_node
)
2235 pp_cxx_ws_string(pp
, "<unsatisfied-constrained-placeholder>");
2238 placeholder_extract_concept_and_args (c
, t
, a
);
2239 pp
->id_expression (t
);
2240 if (TREE_VEC_LENGTH (a
) > 1)
2242 pp_cxx_begin_template_argument_list (pp
);
2243 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2244 for (int i
= TREE_VEC_LENGTH (a
) - 1; i
> 0; --i
)
2245 TREE_VEC_ELT (args
, i
-1) = TREE_VEC_ELT (a
, i
);
2246 pp_cxx_template_argument_list (pp
, args
);
2248 pp_cxx_end_template_argument_list (pp
);
2253 template-declaration:
2254 export(opt) template < template-parameter-list > declaration
2258 template-declaration:
2259 export(opt) template < template-parameter-list >
2260 requires-clause(opt) declaration */
2263 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2265 tree tmpl
= most_general_template (t
);
2268 pp_maybe_newline_and_indent (pp
, 0);
2269 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2271 pp_cxx_ws_string (pp
, "template");
2272 pp_cxx_begin_template_argument_list (pp
);
2273 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2274 pp_cxx_end_template_argument_list (pp
);
2275 pp_newline_and_indent (pp
, 3);
2279 if (tree ci
= get_constraints (t
))
2280 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2282 pp_cxx_requires_clause (pp
, reqs
);
2283 pp_newline_and_indent (pp
, 6);
2286 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2287 pp_cxx_function_definition (pp
, t
);
2289 pp_cxx_simple_declaration (pp
, t
);
2293 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2295 pp_unsupported_tree (pp
, t
);
2299 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2301 pp_unsupported_tree (pp
, t
);
2308 template-declaration
2309 explicit-instantiation
2310 explicit-specialization
2311 linkage-specification
2312 namespace-definition
2317 namespace-alias-definition
2320 static_assert-declaration */
2322 cxx_pretty_printer::declaration (tree t
)
2324 if (TREE_CODE (t
) == STATIC_ASSERT
)
2326 pp_cxx_ws_string (this, "static_assert");
2327 pp_cxx_left_paren (this);
2328 expression (STATIC_ASSERT_CONDITION (t
));
2329 pp_cxx_separate_with (this, ',');
2330 expression (STATIC_ASSERT_MESSAGE (t
));
2331 pp_cxx_right_paren (this);
2333 else if (!DECL_LANG_SPECIFIC (t
))
2334 pp_cxx_simple_declaration (this, t
);
2335 else if (DECL_USE_TEMPLATE (t
))
2336 switch (DECL_USE_TEMPLATE (t
))
2339 pp_cxx_template_declaration (this, t
);
2343 pp_cxx_explicit_specialization (this, t
);
2347 pp_cxx_explicit_instantiation (this, t
);
2353 else switch (TREE_CODE (t
))
2357 pp_cxx_simple_declaration (this, t
);
2361 if (DECL_SAVED_TREE (t
))
2362 pp_cxx_function_definition (this, t
);
2364 pp_cxx_simple_declaration (this, t
);
2367 case NAMESPACE_DECL
:
2368 if (DECL_NAMESPACE_ALIAS (t
))
2369 pp_cxx_namespace_alias_definition (this, t
);
2371 pp_cxx_original_namespace_definition (this, t
);
2375 pp_unsupported_tree (this, t
);
2381 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2383 t
= TREE_OPERAND (t
, 0);
2384 pp_cxx_ws_string (pp
, "typeid");
2385 pp_cxx_left_paren (pp
);
2390 pp_cxx_right_paren (pp
);
2394 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2396 pp_cxx_ws_string (pp
, "va_arg");
2397 pp_cxx_left_paren (pp
);
2398 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2399 pp_cxx_separate_with (pp
, ',');
2400 pp
->type_id (TREE_TYPE (t
));
2401 pp_cxx_right_paren (pp
);
2405 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2407 switch (TREE_CODE (t
))
2410 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2411 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2413 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2414 pp_cxx_separate_with (pp
, ',');
2419 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2421 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2423 pp
->expression (TREE_OPERAND (t
, 1));
2426 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2428 pp_left_bracket (pp
);
2429 pp
->expression (TREE_OPERAND (t
, 1));
2430 pp_right_bracket (pp
);
2438 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2440 pp_cxx_ws_string (pp
, "offsetof");
2441 pp_cxx_left_paren (pp
);
2442 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2443 pp
->expression (TREE_OPERAND (t
, 0));
2444 pp_cxx_right_paren (pp
);
2448 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2450 pp_cxx_ws_string (pp
, "__builtin_addressof");
2451 pp_cxx_left_paren (pp
);
2452 pp
->expression (TREE_OPERAND (t
, 0));
2453 pp_cxx_right_paren (pp
);
2457 get_fold_operator (tree t
)
2459 int op
= int_cst_value (FOLD_EXPR_OP (t
));
2460 if (FOLD_EXPR_MODIFY_P (t
))
2464 case NOP_EXPR
: return "=";
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 default: gcc_unreachable ();
2482 case PLUS_EXPR
: return "+";
2483 case MINUS_EXPR
: return "-";
2484 case MULT_EXPR
: return "*";
2485 case TRUNC_DIV_EXPR
: return "/";
2486 case TRUNC_MOD_EXPR
: return "%";
2487 case BIT_XOR_EXPR
: return "^";
2488 case BIT_AND_EXPR
: return "&";
2489 case BIT_IOR_EXPR
: return "|";
2490 case LSHIFT_EXPR
: return "<<";
2491 case RSHIFT_EXPR
: return ">>";
2492 case EQ_EXPR
: return "==";
2493 case NE_EXPR
: return "!=";
2494 case LT_EXPR
: return "<";
2495 case GT_EXPR
: return ">";
2496 case LE_EXPR
: return "<=";
2497 case GE_EXPR
: return ">=";
2498 case TRUTH_ANDIF_EXPR
: return "&&";
2499 case TRUTH_ORIF_EXPR
: return "||";
2500 case MEMBER_REF
: return "->*";
2501 case DOTSTAR_EXPR
: return ".*";
2502 case OFFSET_REF
: return ".*";
2503 default: return ","; /* FIXME: Not the right default. */
2509 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2511 char const* op
= get_fold_operator (t
);
2512 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2513 pp_cxx_left_paren (pp
);
2514 pp_cxx_ws_string (pp
, "...");
2515 pp_cxx_ws_string (pp
, op
);
2516 pp
->expression (expr
);
2517 pp_cxx_right_paren (pp
);
2521 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2523 char const* op
= get_fold_operator (t
);
2524 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2525 pp_cxx_left_paren (pp
);
2526 pp
->expression (expr
);
2528 pp_cxx_ws_string (pp
, op
);
2529 pp_cxx_ws_string (pp
, "...");
2530 pp_cxx_right_paren (pp
);
2534 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2536 char const* op
= get_fold_operator (t
);
2537 tree t1
= TREE_OPERAND (t
, 1);
2538 tree t2
= TREE_OPERAND (t
, 2);
2539 if (t1
== FOLD_EXPR_PACK (t
))
2540 t1
= PACK_EXPANSION_PATTERN (t1
);
2542 t2
= PACK_EXPANSION_PATTERN (t2
);
2543 pp_cxx_left_paren (pp
);
2544 pp
->expression (t1
);
2545 pp_cxx_ws_string (pp
, op
);
2546 pp_cxx_ws_string (pp
, "...");
2547 pp_cxx_ws_string (pp
, op
);
2548 pp
->expression (t2
);
2549 pp_cxx_right_paren (pp
);
2553 pp_cxx_trait_expression (cxx_pretty_printer
*pp
, tree t
)
2555 cp_trait_kind kind
= TRAIT_EXPR_KIND (t
);
2559 case CPTK_HAS_NOTHROW_ASSIGN
:
2560 pp_cxx_ws_string (pp
, "__has_nothrow_assign");
2562 case CPTK_HAS_TRIVIAL_ASSIGN
:
2563 pp_cxx_ws_string (pp
, "__has_trivial_assign");
2565 case CPTK_HAS_NOTHROW_CONSTRUCTOR
:
2566 pp_cxx_ws_string (pp
, "__has_nothrow_constructor");
2568 case CPTK_HAS_TRIVIAL_CONSTRUCTOR
:
2569 pp_cxx_ws_string (pp
, "__has_trivial_constructor");
2571 case CPTK_HAS_NOTHROW_COPY
:
2572 pp_cxx_ws_string (pp
, "__has_nothrow_copy");
2574 case CPTK_HAS_TRIVIAL_COPY
:
2575 pp_cxx_ws_string (pp
, "__has_trivial_copy");
2577 case CPTK_HAS_TRIVIAL_DESTRUCTOR
:
2578 pp_cxx_ws_string (pp
, "__has_trivial_destructor");
2580 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS
:
2581 pp_cxx_ws_string (pp
, "__has_unique_object_representations");
2583 case CPTK_HAS_VIRTUAL_DESTRUCTOR
:
2584 pp_cxx_ws_string (pp
, "__has_virtual_destructor");
2586 case CPTK_IS_ABSTRACT
:
2587 pp_cxx_ws_string (pp
, "__is_abstract");
2589 case CPTK_IS_AGGREGATE
:
2590 pp_cxx_ws_string (pp
, "__is_aggregate");
2592 case CPTK_IS_BASE_OF
:
2593 pp_cxx_ws_string (pp
, "__is_base_of");
2596 pp_cxx_ws_string (pp
, "__is_class");
2599 pp_cxx_ws_string (pp
, "__is_empty");
2602 pp_cxx_ws_string (pp
, "__is_enum");
2605 pp_cxx_ws_string (pp
, "__is_final");
2608 pp_cxx_ws_string (pp
, "__is_pod");
2610 case CPTK_IS_POLYMORPHIC
:
2611 pp_cxx_ws_string (pp
, "__is_polymorphic");
2613 case CPTK_IS_SAME_AS
:
2614 pp_cxx_ws_string (pp
, "__is_same_as");
2616 case CPTK_IS_STD_LAYOUT
:
2617 pp_cxx_ws_string (pp
, "__is_std_layout");
2619 case CPTK_IS_TRIVIAL
:
2620 pp_cxx_ws_string (pp
, "__is_trivial");
2622 case CPTK_IS_TRIVIALLY_ASSIGNABLE
:
2623 pp_cxx_ws_string (pp
, "__is_trivially_assignable");
2625 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE
:
2626 pp_cxx_ws_string (pp
, "__is_trivially_constructible");
2628 case CPTK_IS_TRIVIALLY_COPYABLE
:
2629 pp_cxx_ws_string (pp
, "__is_trivially_copyable");
2632 pp_cxx_ws_string (pp
, "__is_union");
2634 case CPTK_IS_LITERAL_TYPE
:
2635 pp_cxx_ws_string (pp
, "__is_literal_type");
2637 case CPTK_IS_ASSIGNABLE
:
2638 pp_cxx_ws_string (pp
, "__is_assignable");
2640 case CPTK_IS_CONSTRUCTIBLE
:
2641 pp_cxx_ws_string (pp
, "__is_constructible");
2648 pp_cxx_left_paren (pp
);
2649 pp
->type_id (TRAIT_EXPR_TYPE1 (t
));
2651 if (kind
== CPTK_IS_BASE_OF
|| kind
== CPTK_IS_SAME_AS
)
2653 pp_cxx_separate_with (pp
, ',');
2654 pp
->type_id (TRAIT_EXPR_TYPE2 (t
));
2657 pp_cxx_right_paren (pp
);
2661 // 'requires' logical-or-expression
2663 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2667 pp
->padding
= pp_before
;
2668 pp_cxx_ws_string (pp
, "requires");
2675 compound-requirement
2677 nested-requirement */
2679 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2681 switch (TREE_CODE (t
))
2684 pp_cxx_simple_requirement (pp
, t
);
2688 pp_cxx_type_requirement (pp
, t
);
2692 pp_cxx_compound_requirement (pp
, t
);
2696 pp_cxx_nested_requirement (pp
, t
);
2704 // requirement-list:
2706 // requirement-list ';' requirement[opt]
2709 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2711 for (; t
; t
= TREE_CHAIN (t
))
2712 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2715 // requirement-body:
2716 // '{' requirement-list '}'
2718 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2720 pp_cxx_left_brace (pp
);
2721 pp_cxx_requirement_list (pp
, t
);
2722 pp_cxx_right_brace (pp
);
2725 // requires-expression:
2726 // 'requires' requirement-parameter-list requirement-body
2728 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2730 pp_string (pp
, "requires");
2731 if (tree parms
= TREE_OPERAND (t
, 0))
2733 pp_cxx_parameter_declaration_clause (pp
, parms
);
2734 pp_cxx_whitespace (pp
);
2736 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2739 /* simple-requirement:
2742 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2744 pp
->expression (TREE_OPERAND (t
, 0));
2745 pp_cxx_semicolon (pp
);
2748 /* type-requirement:
2749 typename type-name ';' */
2751 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2753 pp
->type_id (TREE_OPERAND (t
, 0));
2754 pp_cxx_semicolon (pp
);
2757 /* compound-requirement:
2758 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2760 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2762 pp_cxx_left_brace (pp
);
2763 pp
->expression (TREE_OPERAND (t
, 0));
2764 pp_cxx_right_brace (pp
);
2766 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2767 pp_cxx_ws_string (pp
, "noexcept");
2769 if (tree type
= TREE_OPERAND (t
, 1))
2771 pp_cxx_ws_string (pp
, "->");
2774 pp_cxx_semicolon (pp
);
2777 /* nested requirement:
2778 'requires' constraint-expression */
2780 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2782 pp_cxx_ws_string (pp
, "requires");
2783 pp
->expression (TREE_OPERAND (t
, 0));
2784 pp_cxx_semicolon (pp
);
2788 pp_cxx_predicate_constraint (cxx_pretty_printer
*pp
, tree t
)
2790 pp
->expression (TREE_OPERAND (t
, 0));
2794 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2796 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2797 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2798 tree args
= CHECK_CONSTR_ARGS (t
);
2799 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2802 pp
->expression (id
);
2803 else if (TREE_CODE (decl
) == FUNCTION_DECL
)
2805 tree call
= build_vl_exp (CALL_EXPR
, 2);
2806 TREE_OPERAND (call
, 0) = integer_two_node
;
2807 TREE_OPERAND (call
, 1) = id
;
2808 pp
->expression (call
);
2815 pp_cxx_expression_constraint (cxx_pretty_printer
*pp
, tree t
)
2817 pp_string (pp
, "<valid-expression ");
2818 pp_cxx_left_paren (pp
);
2819 pp
->expression (TREE_OPERAND (t
, 0));
2820 pp_cxx_right_paren (pp
);
2821 pp_string (pp
, ">");
2825 pp_cxx_type_constraint (cxx_pretty_printer
*pp
, tree t
)
2827 pp_string (pp
, "<valid-type ");
2828 pp
->type_id (TREE_OPERAND (t
, 0));
2829 pp_string (pp
, ">");
2833 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer
*pp
, tree t
)
2835 pp_string (pp
, "<implicitly-conversion ");
2836 pp_cxx_left_paren (pp
);
2837 pp
->expression (ICONV_CONSTR_EXPR (t
));
2838 pp_cxx_right_paren (pp
);
2839 pp_cxx_ws_string (pp
, "to");
2840 pp
->type_id (ICONV_CONSTR_TYPE (t
));
2841 pp_string (pp
, ">");
2845 pp_cxx_argument_deduction_constraint (cxx_pretty_printer
*pp
, tree t
)
2847 pp_string (pp
, "<argument-deduction ");
2848 pp_cxx_left_paren (pp
);
2849 pp
->expression (DEDUCT_CONSTR_EXPR (t
));
2850 pp_cxx_right_paren (pp
);
2851 pp_cxx_ws_string (pp
, "as");
2852 pp
->expression (DEDUCT_CONSTR_PATTERN (t
));
2853 pp_string (pp
, ">");
2857 pp_cxx_exception_constraint (cxx_pretty_printer
*pp
, tree t
)
2859 pp_cxx_ws_string (pp
, "noexcept");
2860 pp_cxx_whitespace (pp
);
2861 pp_cxx_left_paren (pp
);
2862 pp
->expression (TREE_OPERAND (t
, 0));
2863 pp_cxx_right_paren (pp
);
2867 pp_cxx_parameterized_constraint (cxx_pretty_printer
*pp
, tree t
)
2870 pp_string (pp
, "<requires ");
2871 if (tree parms
= PARM_CONSTR_PARMS (t
))
2873 pp_cxx_parameter_declaration_clause (pp
, parms
);
2874 pp_cxx_whitespace (pp
);
2876 pp_cxx_constraint (pp
, PARM_CONSTR_OPERAND (t
));
2877 pp_string (pp
, ">");
2881 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2883 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2884 pp_string (pp
, " and ");
2885 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2889 pp_cxx_disjunction (cxx_pretty_printer
*pp
, tree t
)
2891 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2892 pp_string (pp
, " or ");
2893 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2897 pp_cxx_constraint (cxx_pretty_printer
*pp
, tree t
)
2899 if (t
== error_mark_node
)
2900 return pp
->expression (t
);
2902 switch (TREE_CODE (t
))
2905 pp_cxx_predicate_constraint (pp
, t
);
2909 pp_cxx_check_constraint (pp
, t
);
2913 pp_cxx_expression_constraint (pp
, t
);
2917 pp_cxx_type_constraint (pp
, t
);
2921 pp_cxx_implicit_conversion_constraint (pp
, t
);
2925 pp_cxx_argument_deduction_constraint (pp
, t
);
2929 pp_cxx_exception_constraint (pp
, t
);
2933 pp_cxx_parameterized_constraint (pp
, t
);
2937 pp_cxx_conjunction (pp
, t
);
2941 pp_cxx_disjunction (pp
, t
);
2944 case EXPR_PACK_EXPANSION
:
2945 pp
->expression (TREE_OPERAND (t
, 0));
2955 typedef c_pretty_print_fn pp_fun
;
2957 /* Initialization of a C++ pretty-printer object. */
2959 cxx_pretty_printer::cxx_pretty_printer ()
2960 : c_pretty_printer (),
2961 enclosing_scope (global_namespace
)
2963 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2964 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;