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_TYPENAME_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
);
1069 t
= OVL_CURRENT (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 unary_expression (t
);
1119 case IMPLICIT_CONV_EXPR
:
1120 pp_cxx_cast_expression (this, t
);
1126 pp_cxx_pm_expression (this, t
);
1130 case TRUNC_DIV_EXPR
:
1131 case TRUNC_MOD_EXPR
:
1132 multiplicative_expression (t
);
1136 conditional_expression (t
);
1143 assignment_expression (t
);
1146 case NON_DEPENDENT_EXPR
:
1147 case MUST_NOT_THROW_EXPR
:
1148 expression (TREE_OPERAND (t
, 0));
1151 case EXPR_PACK_EXPANSION
:
1152 expression (PACK_EXPANSION_PATTERN (t
));
1153 pp_cxx_ws_string (this, "...");
1156 case UNARY_LEFT_FOLD_EXPR
:
1157 pp_cxx_unary_left_fold_expression (this, t
);
1160 case UNARY_RIGHT_FOLD_EXPR
:
1161 pp_cxx_unary_right_fold_expression (this, t
);
1164 case BINARY_LEFT_FOLD_EXPR
:
1165 case BINARY_RIGHT_FOLD_EXPR
:
1166 pp_cxx_binary_fold_expression (this, t
);
1169 case TEMPLATE_ID_EXPR
:
1170 pp_cxx_template_id (this, t
);
1173 case NONTYPE_ARGUMENT_PACK
:
1175 tree args
= ARGUMENT_PACK_ARGS (t
);
1176 int i
, len
= TREE_VEC_LENGTH (args
);
1177 for (i
= 0; i
< len
; ++i
)
1180 pp_cxx_separate_with (this, ',');
1181 expression (TREE_VEC_ELT (args
, i
));
1187 pp_cxx_ws_string (this, "<lambda>");
1191 pp_cxx_trait_expression (this, t
);
1204 pp_cxx_constraint (this, t
);
1208 pp_cxx_left_paren (this);
1209 expression (TREE_OPERAND (t
, 0));
1210 pp_cxx_right_paren (this);
1214 c_pretty_printer::expression (t
);
1222 /* function-specifier:
1228 cxx_pretty_printer::function_specifier (tree t
)
1230 switch (TREE_CODE (t
))
1233 if (DECL_VIRTUAL_P (t
))
1234 pp_cxx_ws_string (this, "virtual");
1235 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
1236 pp_cxx_ws_string (this, "explicit");
1238 c_pretty_printer::function_specifier (t
);
1245 /* decl-specifier-seq:
1246 decl-specifier-seq(opt) decl-specifier
1249 storage-class-specifier
1256 cxx_pretty_printer::declaration_specifiers (tree t
)
1258 switch (TREE_CODE (t
))
1264 storage_class_specifier (t
);
1265 declaration_specifiers (TREE_TYPE (t
));
1269 pp_cxx_ws_string (this, "typedef");
1270 declaration_specifiers (TREE_TYPE (t
));
1274 /* Constructors don't have return types. And conversion functions
1275 do not have a type-specifier in their return types. */
1276 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
1277 function_specifier (t
);
1278 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1279 declaration_specifiers (TREE_TYPE (TREE_TYPE (t
)));
1281 c_pretty_printer::declaration_specifiers (t
);
1284 c_pretty_printer::declaration_specifiers (t
);
1289 /* simple-type-specifier:
1290 ::(opt) nested-name-specifier(opt) type-name
1291 ::(opt) nested-name-specifier(opt) template(opt) template-id
1305 cxx_pretty_printer::simple_type_specifier (tree t
)
1307 switch (TREE_CODE (t
))
1312 pp_cxx_qualified_id (this, t
);
1315 case TEMPLATE_TYPE_PARM
:
1316 case TEMPLATE_TEMPLATE_PARM
:
1317 case TEMPLATE_PARM_INDEX
:
1318 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1319 pp_cxx_unqualified_id (this, t
);
1323 pp_cxx_ws_string (this, "typename");
1324 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t
));
1325 pp_cxx_unqualified_id (this, TYPE_NAME (t
));
1329 c_pretty_printer::simple_type_specifier (t
);
1334 /* type-specifier-seq:
1335 type-specifier type-specifier-seq(opt)
1338 simple-type-specifier
1341 elaborated-type-specifier
1345 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1347 switch (TREE_CODE (t
))
1350 case TEMPLATE_TYPE_PARM
:
1351 case TEMPLATE_TEMPLATE_PARM
:
1353 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1354 pp_cxx_cv_qualifier_seq (pp
, t
);
1355 pp
->simple_type_specifier (t
);
1359 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1360 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1361 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1365 pp_cxx_ws_string (pp
, "decltype");
1366 pp_cxx_left_paren (pp
);
1367 pp
->expression (DECLTYPE_TYPE_EXPR (t
));
1368 pp_cxx_right_paren (pp
);
1372 if (TYPE_PTRMEMFUNC_P (t
))
1374 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
1375 pp
->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm
)));
1376 pp_cxx_whitespace (pp
);
1377 pp_cxx_ptr_operator (pp
, t
);
1383 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1384 pp_c_specifier_qualifier_list (pp
, t
);
1389 * cv-qualifier-seq(opt)
1391 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1394 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1396 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1398 switch (TREE_CODE (t
))
1400 case REFERENCE_TYPE
:
1402 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1403 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1404 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1408 pp_cxx_cv_qualifier_seq (pp
, t
);
1415 if (TYPE_PTRMEMFUNC_P (t
))
1417 pp_cxx_left_paren (pp
);
1418 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1424 if (TYPE_PTRMEM_P (t
))
1426 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1427 pp_cxx_left_paren (pp
);
1428 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1430 pp_cxx_cv_qualifier_seq (pp
, t
);
1436 pp_unsupported_tree (pp
, t
);
1442 pp_cxx_implicit_parameter_type (tree mf
)
1444 return class_of_this_parm (TREE_TYPE (mf
));
1448 parameter-declaration:
1449 decl-specifier-seq declarator
1450 decl-specifier-seq declarator = assignment-expression
1451 decl-specifier-seq abstract-declarator(opt)
1452 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1455 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1457 pp
->declaration_specifiers (t
);
1459 pp
->abstract_declarator (t
);
1464 /* parameter-declaration-clause:
1465 parameter-declaration-list(opt) ...(opt)
1466 parameter-declaration-list , ...
1468 parameter-declaration-list:
1469 parameter-declaration
1470 parameter-declaration-list , parameter-declaration */
1473 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1479 // For a requires clause or the explicit printing of a parameter list
1480 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1481 // args and types are taken from the function decl T.
1482 if (TREE_CODE (t
) == PARM_DECL
)
1490 bool type_p
= TYPE_P (t
);
1491 args
= type_p
? NULL
: FUNCTION_FIRST_USER_PARM (t
);
1492 types
= type_p
? TYPE_ARG_TYPES (t
) : FUNCTION_FIRST_USER_PARMTYPE (t
);
1493 abstract
= args
== NULL
|| pp
->flags
& pp_c_flag_abstract
;
1497 /* Skip artificial parameter for nonstatic member functions. */
1498 if (TREE_CODE (t
) == METHOD_TYPE
)
1499 types
= TREE_CHAIN (types
);
1501 pp_cxx_left_paren (pp
);
1502 for (; args
; args
= TREE_CHAIN (args
), types
= TREE_CHAIN (types
))
1505 pp_cxx_separate_with (pp
, ',');
1507 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1508 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1510 pp_cxx_whitespace (pp
);
1512 pp_cxx_whitespace (pp
);
1513 pp
->assignment_expression (TREE_PURPOSE (types
));
1516 pp_cxx_right_paren (pp
);
1519 /* exception-specification:
1520 throw ( type-id-list(opt) )
1524 type-id-list , type-id */
1527 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1529 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1530 bool need_comma
= false;
1532 if (ex_spec
== NULL
)
1534 if (TREE_PURPOSE (ex_spec
))
1536 pp_cxx_ws_string (pp
, "noexcept");
1537 pp_cxx_whitespace (pp
);
1538 pp_cxx_left_paren (pp
);
1539 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1540 pp_cxx_ws_string (pp
, "<uninstantiated>");
1542 pp
->expression (TREE_PURPOSE (ex_spec
));
1543 pp_cxx_right_paren (pp
);
1546 pp_cxx_ws_string (pp
, "throw");
1547 pp_cxx_left_paren (pp
);
1548 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1550 tree type
= TREE_VALUE (ex_spec
);
1551 tree argpack
= NULL_TREE
;
1554 if (ARGUMENT_PACK_P (type
))
1556 argpack
= ARGUMENT_PACK_ARGS (type
);
1557 len
= TREE_VEC_LENGTH (argpack
);
1560 for (i
= 0; i
< len
; ++i
)
1563 type
= TREE_VEC_ELT (argpack
, i
);
1566 pp_cxx_separate_with (pp
, ',');
1573 pp_cxx_right_paren (pp
);
1576 /* direct-declarator:
1578 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1579 exception-specification(opt)
1580 direct-declaration [ constant-expression(opt) ]
1584 cxx_pretty_printer::direct_declarator (tree t
)
1586 switch (TREE_CODE (t
))
1594 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1596 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1597 || template_parameter_pack_p (t
))
1598 /* A function parameter pack or non-type template
1600 pp_cxx_ws_string (this, "...");
1602 id_expression (DECL_NAME (t
));
1604 abstract_declarator (TREE_TYPE (t
));
1608 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1610 pp_cxx_parameter_declaration_clause (this, t
);
1612 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1614 padding
= pp_before
;
1615 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1618 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1623 case TEMPLATE_TYPE_PARM
:
1624 case TEMPLATE_PARM_INDEX
:
1625 case TEMPLATE_TEMPLATE_PARM
:
1629 c_pretty_printer::direct_declarator (t
);
1636 ptr-operator declarator */
1639 cxx_pretty_printer::declarator (tree t
)
1641 direct_declarator (t
);
1643 // Print a requires clause.
1645 if (tree ci
= get_constraints (t
))
1646 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1647 pp_cxx_requires_clause (this, reqs
);
1650 /* ctor-initializer:
1651 : mem-initializer-list
1653 mem-initializer-list:
1655 mem-initializer , mem-initializer-list
1658 mem-initializer-id ( expression-list(opt) )
1661 ::(opt) nested-name-specifier(opt) class-name
1665 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1667 t
= TREE_OPERAND (t
, 0);
1668 pp_cxx_whitespace (pp
);
1670 pp_cxx_whitespace (pp
);
1671 for (; t
; t
= TREE_CHAIN (t
))
1673 tree purpose
= TREE_PURPOSE (t
);
1674 bool is_pack
= PACK_EXPANSION_P (purpose
);
1677 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1679 pp
->primary_expression (purpose
);
1680 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1682 pp_cxx_ws_string (pp
, "...");
1684 pp_cxx_separate_with (pp
, ',');
1688 /* function-definition:
1689 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1690 decl-specifier-seq(opt) declarator function-try-block */
1693 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1695 tree saved_scope
= pp
->enclosing_scope
;
1696 pp
->declaration_specifiers (t
);
1698 pp_needs_newline (pp
) = true;
1699 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1700 if (DECL_SAVED_TREE (t
))
1701 pp
->statement (DECL_SAVED_TREE (t
));
1703 pp_cxx_semicolon (pp
);
1704 pp_newline_and_flush (pp
);
1705 pp
->enclosing_scope
= saved_scope
;
1708 /* abstract-declarator:
1709 ptr-operator abstract-declarator(opt)
1710 direct-abstract-declarator */
1713 cxx_pretty_printer::abstract_declarator (tree t
)
1715 if (TYPE_PTRMEM_P (t
))
1716 pp_cxx_right_paren (this);
1717 else if (POINTER_TYPE_P (t
))
1719 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1720 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1721 pp_cxx_right_paren (this);
1724 direct_abstract_declarator (t
);
1727 /* direct-abstract-declarator:
1728 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1729 cv-qualifier-seq(opt) exception-specification(opt)
1730 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1731 ( abstract-declarator ) */
1734 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1736 switch (TREE_CODE (t
))
1738 case REFERENCE_TYPE
:
1739 abstract_declarator (t
);
1743 if (TYPE_PTRMEMFUNC_P (t
))
1744 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1749 pp_cxx_parameter_declaration_clause (this, t
);
1750 direct_abstract_declarator (TREE_TYPE (t
));
1751 if (TREE_CODE (t
) == METHOD_TYPE
)
1753 padding
= pp_before
;
1754 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1756 pp_cxx_exception_specification (this, t
);
1760 case TEMPLATE_TYPE_PARM
:
1761 case TEMPLATE_TEMPLATE_PARM
:
1762 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1763 case UNBOUND_CLASS_TEMPLATE
:
1767 c_pretty_printer::direct_abstract_declarator (t
);
1773 type-specifier-seq abstract-declarator(opt) */
1776 cxx_pretty_printer::type_id (tree t
)
1778 pp_flags saved_flags
= flags
;
1779 flags
|= pp_c_flag_abstract
;
1781 switch (TREE_CODE (t
))
1788 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1789 case UNBOUND_CLASS_TEMPLATE
:
1790 case TEMPLATE_TEMPLATE_PARM
:
1791 case TEMPLATE_TYPE_PARM
:
1792 case TEMPLATE_PARM_INDEX
:
1795 case UNDERLYING_TYPE
:
1797 case TEMPLATE_ID_EXPR
:
1798 pp_cxx_type_specifier_seq (this, t
);
1801 case TYPE_PACK_EXPANSION
:
1802 type_id (PACK_EXPANSION_PATTERN (t
));
1803 pp_cxx_ws_string (this, "...");
1807 c_pretty_printer::type_id (t
);
1811 flags
= saved_flags
;
1814 /* template-argument-list:
1815 template-argument ...(opt)
1816 template-argument-list, template-argument ...(opt)
1819 assignment-expression
1824 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1827 bool need_comma
= false;
1831 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1833 tree arg
= TREE_VEC_ELT (t
, i
);
1834 tree argpack
= NULL_TREE
;
1837 if (ARGUMENT_PACK_P (arg
))
1839 argpack
= ARGUMENT_PACK_ARGS (arg
);
1840 len
= TREE_VEC_LENGTH (argpack
);
1843 for (idx
= 0; idx
< len
; idx
++)
1846 arg
= TREE_VEC_ELT (argpack
, idx
);
1849 pp_cxx_separate_with (pp
, ',');
1853 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1854 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1857 pp
->expression (arg
);
1864 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1866 t
= DECL_EXPR_DECL (t
);
1867 pp_cxx_type_specifier_seq (pp
, t
);
1869 pp
->abstract_declarator (t
);
1877 cxx_pretty_printer::statement (tree t
)
1879 switch (TREE_CODE (t
))
1881 case CTOR_INITIALIZER
:
1882 pp_cxx_ctor_initializer (this, t
);
1886 pp_cxx_ws_string (this, "using");
1887 pp_cxx_ws_string (this, "namespace");
1888 if (DECL_CONTEXT (t
))
1889 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
1890 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
1894 pp_cxx_ws_string (this, "using");
1895 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
1896 pp_cxx_unqualified_id (this, DECL_NAME (t
));
1903 try compound-statement handler-seq */
1905 pp_maybe_newline_and_indent (this, 0);
1906 pp_cxx_ws_string (this, "try");
1907 pp_newline_and_indent (this, 3);
1908 statement (TRY_STMTS (t
));
1909 pp_newline_and_indent (this, -3);
1913 statement (TRY_HANDLERS (t
));
1918 handler handler-seq(opt)
1921 catch ( exception-declaration ) compound-statement
1923 exception-declaration:
1924 type-specifier-seq declarator
1925 type-specifier-seq abstract-declarator
1928 pp_cxx_ws_string (this, "catch");
1929 pp_cxx_left_paren (this);
1930 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
1931 pp_cxx_right_paren (this);
1932 pp_indentation (this) += 3;
1933 pp_needs_newline (this) = true;
1934 statement (HANDLER_BODY (t
));
1935 pp_indentation (this) -= 3;
1936 pp_needs_newline (this) = true;
1939 /* selection-statement:
1940 if ( expression ) statement
1941 if ( expression ) statement else statement */
1943 pp_cxx_ws_string (this, "if");
1944 pp_cxx_whitespace (this);
1945 pp_cxx_left_paren (this);
1946 expression (IF_COND (t
));
1947 pp_cxx_right_paren (this);
1948 pp_newline_and_indent (this, 2);
1949 statement (THEN_CLAUSE (t
));
1950 pp_newline_and_indent (this, -2);
1951 if (ELSE_CLAUSE (t
))
1953 tree else_clause
= ELSE_CLAUSE (t
);
1954 pp_cxx_ws_string (this, "else");
1955 if (TREE_CODE (else_clause
) == IF_STMT
)
1956 pp_cxx_whitespace (this);
1958 pp_newline_and_indent (this, 2);
1959 statement (else_clause
);
1960 if (TREE_CODE (else_clause
) != IF_STMT
)
1961 pp_newline_and_indent (this, -2);
1966 pp_cxx_ws_string (this, "switch");
1968 pp_cxx_left_paren (this);
1969 expression (SWITCH_STMT_COND (t
));
1970 pp_cxx_right_paren (this);
1971 pp_indentation (this) += 3;
1972 pp_needs_newline (this) = true;
1973 statement (SWITCH_STMT_BODY (t
));
1974 pp_newline_and_indent (this, -3);
1977 /* iteration-statement:
1978 while ( expression ) statement
1979 do statement while ( expression ) ;
1980 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1981 for ( declaration expression(opt) ; expression(opt) ) statement */
1983 pp_cxx_ws_string (this, "while");
1985 pp_cxx_left_paren (this);
1986 expression (WHILE_COND (t
));
1987 pp_cxx_right_paren (this);
1988 pp_newline_and_indent (this, 3);
1989 statement (WHILE_BODY (t
));
1990 pp_indentation (this) -= 3;
1991 pp_needs_newline (this) = true;
1995 pp_cxx_ws_string (this, "do");
1996 pp_newline_and_indent (this, 3);
1997 statement (DO_BODY (t
));
1998 pp_newline_and_indent (this, -3);
1999 pp_cxx_ws_string (this, "while");
2001 pp_cxx_left_paren (this);
2002 expression (DO_COND (t
));
2003 pp_cxx_right_paren (this);
2004 pp_cxx_semicolon (this);
2005 pp_needs_newline (this) = true;
2009 pp_cxx_ws_string (this, "for");
2011 pp_cxx_left_paren (this);
2012 if (FOR_INIT_STMT (t
))
2013 statement (FOR_INIT_STMT (t
));
2015 pp_cxx_semicolon (this);
2016 pp_needs_newline (this) = false;
2017 pp_cxx_whitespace (this);
2019 expression (FOR_COND (t
));
2020 pp_cxx_semicolon (this);
2021 pp_needs_newline (this) = false;
2022 pp_cxx_whitespace (this);
2024 expression (FOR_EXPR (t
));
2025 pp_cxx_right_paren (this);
2026 pp_newline_and_indent (this, 3);
2027 statement (FOR_BODY (t
));
2028 pp_indentation (this) -= 3;
2029 pp_needs_newline (this) = true;
2032 case RANGE_FOR_STMT
:
2033 pp_cxx_ws_string (this, "for");
2035 pp_cxx_left_paren (this);
2036 statement (RANGE_FOR_DECL (t
));
2038 pp_needs_newline (this) = false;
2041 statement (RANGE_FOR_EXPR (t
));
2042 pp_cxx_right_paren (this);
2043 pp_newline_and_indent (this, 3);
2044 statement (FOR_BODY (t
));
2045 pp_indentation (this) -= 3;
2046 pp_needs_newline (this) = true;
2052 return expression(opt) ; */
2055 pp_string (this, TREE_CODE (t
) == BREAK_STMT
? "break" : "continue");
2056 pp_cxx_semicolon (this);
2057 pp_needs_newline (this) = true;
2060 /* expression-statement:
2061 expression(opt) ; */
2063 expression (EXPR_STMT_EXPR (t
));
2064 pp_cxx_semicolon (this);
2065 pp_needs_newline (this) = true;
2069 pp_cxx_ws_string (this, "try");
2070 pp_newline_and_indent (this, 2);
2071 statement (CLEANUP_BODY (t
));
2072 pp_newline_and_indent (this, -2);
2073 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2074 pp_newline_and_indent (this, 2);
2075 statement (CLEANUP_EXPR (t
));
2076 pp_newline_and_indent (this, -2);
2084 c_pretty_printer::statement (t
);
2089 /* original-namespace-definition:
2090 namespace identifier { namespace-body }
2092 As an edge case, we also handle unnamed namespace definition here. */
2095 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2097 pp_cxx_ws_string (pp
, "namespace");
2098 if (DECL_CONTEXT (t
))
2099 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2101 pp_cxx_unqualified_id (pp
, t
);
2102 pp_cxx_whitespace (pp
);
2103 pp_cxx_left_brace (pp
);
2104 /* We do not print the namespace-body. */
2105 pp_cxx_whitespace (pp
);
2106 pp_cxx_right_brace (pp
);
2112 namespace-alias-definition:
2113 namespace identifier = qualified-namespace-specifier ;
2115 qualified-namespace-specifier:
2116 ::(opt) nested-name-specifier(opt) namespace-name */
2119 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2121 pp_cxx_ws_string (pp
, "namespace");
2122 if (DECL_CONTEXT (t
))
2123 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2124 pp_cxx_unqualified_id (pp
, t
);
2125 pp_cxx_whitespace (pp
);
2127 pp_cxx_whitespace (pp
);
2128 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2129 pp_cxx_nested_name_specifier (pp
,
2130 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2131 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2132 pp_cxx_semicolon (pp
);
2135 /* simple-declaration:
2136 decl-specifier-seq(opt) init-declarator-list(opt) */
2139 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2141 pp
->declaration_specifiers (t
);
2142 pp_cxx_init_declarator (pp
, t
);
2143 pp_cxx_semicolon (pp
);
2144 pp_needs_newline (pp
) = true;
2148 template-parameter-list:
2150 template-parameter-list , template-parameter */
2153 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2155 const int n
= TREE_VEC_LENGTH (t
);
2157 for (i
= 0; i
< n
; ++i
)
2160 pp_cxx_separate_with (pp
, ',');
2161 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2165 /* template-parameter:
2167 parameter-declaration
2170 class ...(opt) identifier(opt)
2171 class identifier(opt) = type-id
2172 typename identifier(opt)
2173 typename ...(opt) identifier(opt) = type-id
2174 template < template-parameter-list > class ...(opt) identifier(opt)
2175 template < template-parameter-list > class identifier(opt) = template-name */
2178 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2180 tree parameter
= TREE_VALUE (t
);
2181 switch (TREE_CODE (parameter
))
2184 pp_cxx_ws_string (pp
, "class");
2185 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2186 pp_cxx_ws_string (pp
, "...");
2187 if (DECL_NAME (parameter
))
2188 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2189 /* FIXME: Check if we should print also default argument. */
2193 pp_cxx_parameter_declaration (pp
, parameter
);
2200 pp_unsupported_tree (pp
, t
);
2205 /* Pretty-print a template parameter in the canonical form
2206 "template-parameter-<level>-<position in parameter list>". */
2209 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2211 const enum tree_code code
= TREE_CODE (parm
);
2213 /* Brings type template parameters to the canonical forms. */
2214 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2215 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2216 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2218 pp_cxx_begin_template_argument_list (pp
);
2219 pp
->translate_string ("template-parameter-");
2220 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2222 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2223 pp_cxx_end_template_argument_list (pp
);
2226 /* Print a constrained-type-specifier. */
2229 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2232 if (c
== error_mark_node
)
2234 pp_cxx_ws_string(pp
, "<unsatisfied-constrained-placeholder>");
2237 placeholder_extract_concept_and_args (c
, t
, a
);
2238 pp
->id_expression (t
);
2239 if (TREE_VEC_LENGTH (a
) > 1)
2241 pp_cxx_begin_template_argument_list (pp
);
2242 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2243 for (int i
= TREE_VEC_LENGTH (a
) - 1; i
> 0; --i
)
2244 TREE_VEC_ELT (args
, i
-1) = TREE_VEC_ELT (a
, i
);
2245 pp_cxx_template_argument_list (pp
, args
);
2247 pp_cxx_end_template_argument_list (pp
);
2252 template-declaration:
2253 export(opt) template < template-parameter-list > declaration
2257 template-declaration:
2258 export(opt) template < template-parameter-list >
2259 requires-clause(opt) declaration */
2262 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2264 tree tmpl
= most_general_template (t
);
2267 pp_maybe_newline_and_indent (pp
, 0);
2268 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2270 pp_cxx_ws_string (pp
, "template");
2271 pp_cxx_begin_template_argument_list (pp
);
2272 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2273 pp_cxx_end_template_argument_list (pp
);
2274 pp_newline_and_indent (pp
, 3);
2278 if (tree ci
= get_constraints (t
))
2279 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2281 pp_cxx_requires_clause (pp
, reqs
);
2282 pp_newline_and_indent (pp
, 6);
2285 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2286 pp_cxx_function_definition (pp
, t
);
2288 pp_cxx_simple_declaration (pp
, t
);
2292 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2294 pp_unsupported_tree (pp
, t
);
2298 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2300 pp_unsupported_tree (pp
, t
);
2307 template-declaration
2308 explicit-instantiation
2309 explicit-specialization
2310 linkage-specification
2311 namespace-definition
2316 namespace-alias-definition
2319 static_assert-declaration */
2321 cxx_pretty_printer::declaration (tree t
)
2323 if (TREE_CODE (t
) == STATIC_ASSERT
)
2325 pp_cxx_ws_string (this, "static_assert");
2326 pp_cxx_left_paren (this);
2327 expression (STATIC_ASSERT_CONDITION (t
));
2328 pp_cxx_separate_with (this, ',');
2329 expression (STATIC_ASSERT_MESSAGE (t
));
2330 pp_cxx_right_paren (this);
2332 else if (!DECL_LANG_SPECIFIC (t
))
2333 pp_cxx_simple_declaration (this, t
);
2334 else if (DECL_USE_TEMPLATE (t
))
2335 switch (DECL_USE_TEMPLATE (t
))
2338 pp_cxx_template_declaration (this, t
);
2342 pp_cxx_explicit_specialization (this, t
);
2346 pp_cxx_explicit_instantiation (this, t
);
2352 else switch (TREE_CODE (t
))
2356 pp_cxx_simple_declaration (this, t
);
2360 if (DECL_SAVED_TREE (t
))
2361 pp_cxx_function_definition (this, t
);
2363 pp_cxx_simple_declaration (this, t
);
2366 case NAMESPACE_DECL
:
2367 if (DECL_NAMESPACE_ALIAS (t
))
2368 pp_cxx_namespace_alias_definition (this, t
);
2370 pp_cxx_original_namespace_definition (this, t
);
2374 pp_unsupported_tree (this, t
);
2380 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2382 t
= TREE_OPERAND (t
, 0);
2383 pp_cxx_ws_string (pp
, "typeid");
2384 pp_cxx_left_paren (pp
);
2389 pp_cxx_right_paren (pp
);
2393 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2395 pp_cxx_ws_string (pp
, "va_arg");
2396 pp_cxx_left_paren (pp
);
2397 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2398 pp_cxx_separate_with (pp
, ',');
2399 pp
->type_id (TREE_TYPE (t
));
2400 pp_cxx_right_paren (pp
);
2404 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2406 switch (TREE_CODE (t
))
2409 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2410 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2412 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2413 pp_cxx_separate_with (pp
, ',');
2418 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2420 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2422 pp
->expression (TREE_OPERAND (t
, 1));
2425 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2427 pp_left_bracket (pp
);
2428 pp
->expression (TREE_OPERAND (t
, 1));
2429 pp_right_bracket (pp
);
2437 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2439 pp_cxx_ws_string (pp
, "offsetof");
2440 pp_cxx_left_paren (pp
);
2441 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2442 pp
->expression (TREE_OPERAND (t
, 0));
2443 pp_cxx_right_paren (pp
);
2447 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2449 pp_cxx_ws_string (pp
, "__builtin_addressof");
2450 pp_cxx_left_paren (pp
);
2451 pp
->expression (TREE_OPERAND (t
, 0));
2452 pp_cxx_right_paren (pp
);
2456 get_fold_operator (tree t
)
2458 int op
= int_cst_value (FOLD_EXPR_OP (t
));
2459 if (FOLD_EXPR_MODIFY_P (t
))
2463 case NOP_EXPR
: return "=";
2464 case PLUS_EXPR
: return "+=";
2465 case MINUS_EXPR
: return "-=";
2466 case MULT_EXPR
: return "*=";
2467 case TRUNC_DIV_EXPR
: return "/=";
2468 case TRUNC_MOD_EXPR
: return "%=";
2469 case BIT_XOR_EXPR
: return "^=";
2470 case BIT_AND_EXPR
: return "&=";
2471 case BIT_IOR_EXPR
: return "|=";
2472 case LSHIFT_EXPR
: return "<<=";
2473 case RSHIFT_EXPR
: return ">>=";
2474 default: gcc_unreachable ();
2481 case PLUS_EXPR
: return "+";
2482 case MINUS_EXPR
: return "-";
2483 case MULT_EXPR
: return "*";
2484 case TRUNC_DIV_EXPR
: return "/";
2485 case TRUNC_MOD_EXPR
: return "%";
2486 case BIT_XOR_EXPR
: return "^";
2487 case BIT_AND_EXPR
: return "&";
2488 case BIT_IOR_EXPR
: return "|";
2489 case LSHIFT_EXPR
: return "<<";
2490 case RSHIFT_EXPR
: return ">>";
2491 case EQ_EXPR
: return "==";
2492 case NE_EXPR
: return "!=";
2493 case LT_EXPR
: return "<";
2494 case GT_EXPR
: return ">";
2495 case LE_EXPR
: return "<=";
2496 case GE_EXPR
: return ">=";
2497 case TRUTH_ANDIF_EXPR
: return "&&";
2498 case TRUTH_ORIF_EXPR
: return "||";
2499 case MEMBER_REF
: return "->*";
2500 case DOTSTAR_EXPR
: return ".*";
2501 case OFFSET_REF
: return ".*";
2502 default: return ","; /* FIXME: Not the right default. */
2508 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2510 char const* op
= get_fold_operator (t
);
2511 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2512 pp_cxx_left_paren (pp
);
2513 pp_cxx_ws_string (pp
, "...");
2514 pp_cxx_ws_string (pp
, op
);
2515 pp
->expression (expr
);
2516 pp_cxx_right_paren (pp
);
2520 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2522 char const* op
= get_fold_operator (t
);
2523 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2524 pp_cxx_left_paren (pp
);
2525 pp
->expression (expr
);
2527 pp_cxx_ws_string (pp
, op
);
2528 pp_cxx_ws_string (pp
, "...");
2529 pp_cxx_right_paren (pp
);
2533 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2535 char const* op
= get_fold_operator (t
);
2536 tree t1
= TREE_OPERAND (t
, 1);
2537 tree t2
= TREE_OPERAND (t
, 2);
2538 if (t1
== FOLD_EXPR_PACK (t
))
2539 t1
= PACK_EXPANSION_PATTERN (t1
);
2541 t2
= PACK_EXPANSION_PATTERN (t2
);
2542 pp_cxx_left_paren (pp
);
2543 pp
->expression (t1
);
2544 pp_cxx_ws_string (pp
, op
);
2545 pp_cxx_ws_string (pp
, "...");
2546 pp_cxx_ws_string (pp
, op
);
2547 pp
->expression (t2
);
2548 pp_cxx_right_paren (pp
);
2552 pp_cxx_trait_expression (cxx_pretty_printer
*pp
, tree t
)
2554 cp_trait_kind kind
= TRAIT_EXPR_KIND (t
);
2558 case CPTK_HAS_NOTHROW_ASSIGN
:
2559 pp_cxx_ws_string (pp
, "__has_nothrow_assign");
2561 case CPTK_HAS_TRIVIAL_ASSIGN
:
2562 pp_cxx_ws_string (pp
, "__has_trivial_assign");
2564 case CPTK_HAS_NOTHROW_CONSTRUCTOR
:
2565 pp_cxx_ws_string (pp
, "__has_nothrow_constructor");
2567 case CPTK_HAS_TRIVIAL_CONSTRUCTOR
:
2568 pp_cxx_ws_string (pp
, "__has_trivial_constructor");
2570 case CPTK_HAS_NOTHROW_COPY
:
2571 pp_cxx_ws_string (pp
, "__has_nothrow_copy");
2573 case CPTK_HAS_TRIVIAL_COPY
:
2574 pp_cxx_ws_string (pp
, "__has_trivial_copy");
2576 case CPTK_HAS_TRIVIAL_DESTRUCTOR
:
2577 pp_cxx_ws_string (pp
, "__has_trivial_destructor");
2579 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS
:
2580 pp_cxx_ws_string (pp
, "__has_unique_object_representations");
2582 case CPTK_HAS_VIRTUAL_DESTRUCTOR
:
2583 pp_cxx_ws_string (pp
, "__has_virtual_destructor");
2585 case CPTK_IS_ABSTRACT
:
2586 pp_cxx_ws_string (pp
, "__is_abstract");
2588 case CPTK_IS_BASE_OF
:
2589 pp_cxx_ws_string (pp
, "__is_base_of");
2592 pp_cxx_ws_string (pp
, "__is_class");
2595 pp_cxx_ws_string (pp
, "__is_empty");
2598 pp_cxx_ws_string (pp
, "__is_enum");
2601 pp_cxx_ws_string (pp
, "__is_final");
2604 pp_cxx_ws_string (pp
, "__is_pod");
2606 case CPTK_IS_POLYMORPHIC
:
2607 pp_cxx_ws_string (pp
, "__is_polymorphic");
2609 case CPTK_IS_SAME_AS
:
2610 pp_cxx_ws_string (pp
, "__is_same_as");
2612 case CPTK_IS_STD_LAYOUT
:
2613 pp_cxx_ws_string (pp
, "__is_std_layout");
2615 case CPTK_IS_TRIVIAL
:
2616 pp_cxx_ws_string (pp
, "__is_trivial");
2618 case CPTK_IS_TRIVIALLY_ASSIGNABLE
:
2619 pp_cxx_ws_string (pp
, "__is_trivially_assignable");
2621 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE
:
2622 pp_cxx_ws_string (pp
, "__is_trivially_constructible");
2624 case CPTK_IS_TRIVIALLY_COPYABLE
:
2625 pp_cxx_ws_string (pp
, "__is_trivially_copyable");
2628 pp_cxx_ws_string (pp
, "__is_union");
2630 case CPTK_IS_LITERAL_TYPE
:
2631 pp_cxx_ws_string (pp
, "__is_literal_type");
2638 pp_cxx_left_paren (pp
);
2639 pp
->type_id (TRAIT_EXPR_TYPE1 (t
));
2641 if (kind
== CPTK_IS_BASE_OF
|| kind
== CPTK_IS_SAME_AS
)
2643 pp_cxx_separate_with (pp
, ',');
2644 pp
->type_id (TRAIT_EXPR_TYPE2 (t
));
2647 pp_cxx_right_paren (pp
);
2651 // 'requires' logical-or-expression
2653 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2657 pp
->padding
= pp_before
;
2658 pp_cxx_ws_string (pp
, "requires");
2665 compound-requirement
2667 nested-requirement */
2669 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2671 switch (TREE_CODE (t
))
2674 pp_cxx_simple_requirement (pp
, t
);
2678 pp_cxx_type_requirement (pp
, t
);
2682 pp_cxx_compound_requirement (pp
, t
);
2686 pp_cxx_nested_requirement (pp
, t
);
2694 // requirement-list:
2696 // requirement-list ';' requirement[opt]
2699 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2701 for (; t
; t
= TREE_CHAIN (t
))
2702 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2705 // requirement-body:
2706 // '{' requirement-list '}'
2708 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2710 pp_cxx_left_brace (pp
);
2711 pp_cxx_requirement_list (pp
, t
);
2712 pp_cxx_right_brace (pp
);
2715 // requires-expression:
2716 // 'requires' requirement-parameter-list requirement-body
2718 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2720 pp_string (pp
, "requires");
2721 if (tree parms
= TREE_OPERAND (t
, 0))
2723 pp_cxx_parameter_declaration_clause (pp
, parms
);
2724 pp_cxx_whitespace (pp
);
2726 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2729 /* simple-requirement:
2732 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2734 pp
->expression (TREE_OPERAND (t
, 0));
2735 pp_cxx_semicolon (pp
);
2738 /* type-requirement:
2739 typename type-name ';' */
2741 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2743 pp
->type_id (TREE_OPERAND (t
, 0));
2744 pp_cxx_semicolon (pp
);
2747 /* compound-requirement:
2748 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2750 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2752 pp_cxx_left_brace (pp
);
2753 pp
->expression (TREE_OPERAND (t
, 0));
2754 pp_cxx_right_brace (pp
);
2756 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2757 pp_cxx_ws_string (pp
, "noexcept");
2759 if (tree type
= TREE_OPERAND (t
, 1))
2761 pp_cxx_ws_string (pp
, "->");
2764 pp_cxx_semicolon (pp
);
2767 /* nested requirement:
2768 'requires' constraint-expression */
2770 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2772 pp_cxx_ws_string (pp
, "requires");
2773 pp
->expression (TREE_OPERAND (t
, 0));
2774 pp_cxx_semicolon (pp
);
2778 pp_cxx_predicate_constraint (cxx_pretty_printer
*pp
, tree t
)
2780 pp
->expression (TREE_OPERAND (t
, 0));
2784 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2786 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2787 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2788 tree args
= CHECK_CONSTR_ARGS (t
);
2789 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2792 pp
->expression (id
);
2793 else if (TREE_CODE (decl
) == FUNCTION_DECL
)
2795 tree call
= build_vl_exp (CALL_EXPR
, 2);
2796 TREE_OPERAND (call
, 0) = integer_two_node
;
2797 TREE_OPERAND (call
, 1) = id
;
2798 pp
->expression (call
);
2805 pp_cxx_expression_constraint (cxx_pretty_printer
*pp
, tree t
)
2807 pp_string (pp
, "<valid-expression ");
2808 pp_cxx_left_paren (pp
);
2809 pp
->expression (TREE_OPERAND (t
, 0));
2810 pp_cxx_right_paren (pp
);
2811 pp_string (pp
, ">");
2815 pp_cxx_type_constraint (cxx_pretty_printer
*pp
, tree t
)
2817 pp_string (pp
, "<valid-type ");
2818 pp
->type_id (TREE_OPERAND (t
, 0));
2819 pp_string (pp
, ">");
2823 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer
*pp
, tree t
)
2825 pp_string (pp
, "<implicitly-conversion ");
2826 pp_cxx_left_paren (pp
);
2827 pp
->expression (ICONV_CONSTR_EXPR (t
));
2828 pp_cxx_right_paren (pp
);
2829 pp_cxx_ws_string (pp
, "to");
2830 pp
->type_id (ICONV_CONSTR_TYPE (t
));
2831 pp_string (pp
, ">");
2835 pp_cxx_argument_deduction_constraint (cxx_pretty_printer
*pp
, tree t
)
2837 pp_string (pp
, "<argument-deduction ");
2838 pp_cxx_left_paren (pp
);
2839 pp
->expression (DEDUCT_CONSTR_EXPR (t
));
2840 pp_cxx_right_paren (pp
);
2841 pp_cxx_ws_string (pp
, "as");
2842 pp
->expression (DEDUCT_CONSTR_PATTERN (t
));
2843 pp_string (pp
, ">");
2847 pp_cxx_exception_constraint (cxx_pretty_printer
*pp
, tree t
)
2849 pp_cxx_ws_string (pp
, "noexcept");
2850 pp_cxx_whitespace (pp
);
2851 pp_cxx_left_paren (pp
);
2852 pp
->expression (TREE_OPERAND (t
, 0));
2853 pp_cxx_right_paren (pp
);
2857 pp_cxx_parameterized_constraint (cxx_pretty_printer
*pp
, tree t
)
2860 pp_string (pp
, "<requires ");
2861 if (tree parms
= PARM_CONSTR_PARMS (t
))
2863 pp_cxx_parameter_declaration_clause (pp
, parms
);
2864 pp_cxx_whitespace (pp
);
2866 pp_cxx_constraint (pp
, PARM_CONSTR_OPERAND (t
));
2867 pp_string (pp
, ">");
2871 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2873 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2874 pp_string (pp
, " and ");
2875 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2879 pp_cxx_disjunction (cxx_pretty_printer
*pp
, tree t
)
2881 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2882 pp_string (pp
, " or ");
2883 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2887 pp_cxx_constraint (cxx_pretty_printer
*pp
, tree t
)
2889 if (t
== error_mark_node
)
2890 return pp
->expression (t
);
2892 switch (TREE_CODE (t
))
2895 pp_cxx_predicate_constraint (pp
, t
);
2899 pp_cxx_check_constraint (pp
, t
);
2903 pp_cxx_expression_constraint (pp
, t
);
2907 pp_cxx_type_constraint (pp
, t
);
2911 pp_cxx_implicit_conversion_constraint (pp
, t
);
2915 pp_cxx_argument_deduction_constraint (pp
, t
);
2919 pp_cxx_exception_constraint (pp
, t
);
2923 pp_cxx_parameterized_constraint (pp
, t
);
2927 pp_cxx_conjunction (pp
, t
);
2931 pp_cxx_disjunction (pp
, t
);
2934 case EXPR_PACK_EXPANSION
:
2935 pp
->expression (TREE_OPERAND (t
, 0));
2945 typedef c_pretty_print_fn pp_fun
;
2947 /* Initialization of a C++ pretty-printer object. */
2949 cxx_pretty_printer::cxx_pretty_printer ()
2950 : c_pretty_printer (),
2951 enclosing_scope (global_namespace
)
2953 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2954 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;