1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2020 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
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
);
41 static void pp_cxx_concept_definition (cxx_pretty_printer
*, tree
);
45 pp_cxx_nonconsecutive_character (cxx_pretty_printer
*pp
, int c
)
47 const char *p
= pp_last_position_in_text (pp
);
49 if (p
!= NULL
&& *p
== c
)
50 pp_cxx_whitespace (pp
);
52 pp
->padding
= pp_none
;
55 #define pp_cxx_expression_list(PP, T) \
56 pp_c_expression_list (PP, T)
57 #define pp_cxx_space_for_pointer_operator(PP, T) \
58 pp_c_space_for_pointer_operator (PP, T)
59 #define pp_cxx_init_declarator(PP, T) \
60 pp_c_init_declarator (PP, T)
61 #define pp_cxx_call_argument_list(PP, T) \
62 pp_c_call_argument_list (PP, T)
65 pp_cxx_colon_colon (cxx_pretty_printer
*pp
)
68 pp
->padding
= pp_none
;
72 pp_cxx_begin_template_argument_list (cxx_pretty_printer
*pp
)
74 pp_cxx_nonconsecutive_character (pp
, '<');
78 pp_cxx_end_template_argument_list (cxx_pretty_printer
*pp
)
80 pp_cxx_nonconsecutive_character (pp
, '>');
84 pp_cxx_separate_with (cxx_pretty_printer
*pp
, int c
)
86 pp_separate_with (pp
, c
);
87 pp
->padding
= pp_none
;
92 /* conversion-function-id:
93 operator conversion-type-id
96 type-specifier-seq conversion-declarator(opt)
98 conversion-declarator:
99 ptr-operator conversion-declarator(opt) */
102 pp_cxx_conversion_function_id (cxx_pretty_printer
*pp
, tree t
)
104 pp_cxx_ws_string (pp
, "operator");
105 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
109 pp_cxx_template_id (cxx_pretty_printer
*pp
, tree t
)
111 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 0));
112 pp_cxx_begin_template_argument_list (pp
);
113 pp_cxx_template_argument_list (pp
, TREE_OPERAND (t
, 1));
114 pp_cxx_end_template_argument_list (pp
);
117 /* Prints the unqualified part of the id-expression T.
122 conversion-function-id
127 pp_cxx_unqualified_id (cxx_pretty_printer
*pp
, tree t
)
129 enum tree_code code
= TREE_CODE (t
);
133 pp
->translate_string ("<return-value>");
152 case IDENTIFIER_NODE
:
154 pp
->translate_string ("<unnamed>");
155 else if (IDENTIFIER_CONV_OP_P (t
))
156 pp_cxx_conversion_function_id (pp
, t
);
158 pp_cxx_tree_identifier (pp
, t
);
161 case TEMPLATE_ID_EXPR
:
162 pp_cxx_template_id (pp
, t
);
166 pp_cxx_unqualified_id (pp
, BASELINK_FUNCTIONS (t
));
173 case UNBOUND_CLASS_TEMPLATE
:
174 pp_cxx_unqualified_id (pp
, TYPE_NAME (t
));
175 if (tree ti
= TYPE_TEMPLATE_INFO_MAYBE_ALIAS (t
))
176 if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti
)))
178 pp_cxx_begin_template_argument_list (pp
);
179 tree args
= INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti
));
180 pp_cxx_template_argument_list (pp
, args
);
181 pp_cxx_end_template_argument_list (pp
);
186 pp_cxx_complement (pp
);
187 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 0));
190 case TEMPLATE_TYPE_PARM
:
191 case TEMPLATE_TEMPLATE_PARM
:
192 if (template_placeholder_p (t
))
194 t
= TREE_TYPE (CLASS_PLACEHOLDER_TEMPLATE (t
));
195 pp_cxx_unqualified_id (pp
, TYPE_IDENTIFIER (t
));
196 pp_string (pp
, "<...auto...>");
198 else if (TYPE_IDENTIFIER (t
))
199 pp_cxx_unqualified_id (pp
, TYPE_IDENTIFIER (t
));
201 pp_cxx_canonical_template_parameter (pp
, t
);
204 case TEMPLATE_PARM_INDEX
:
205 pp_cxx_unqualified_id (pp
, TEMPLATE_PARM_DECL (t
));
208 case BOUND_TEMPLATE_TEMPLATE_PARM
:
209 pp_cxx_cv_qualifier_seq (pp
, t
);
210 pp_cxx_unqualified_id (pp
, TYPE_IDENTIFIER (t
));
211 pp_cxx_begin_template_argument_list (pp
);
212 pp_cxx_template_argument_list (pp
, TYPE_TI_ARGS (t
));
213 pp_cxx_end_template_argument_list (pp
);
217 pp_unsupported_tree (pp
, t
);
222 /* Pretty-print out the token sequence ":: template" in template codes
223 where it is needed to "inline declare" the (following) member as
224 a template. This situation arises when SCOPE of T is dependent
225 on template parameters. */
228 pp_cxx_template_keyword_if_needed (cxx_pretty_printer
*pp
, tree scope
, tree t
)
230 if (TREE_CODE (t
) == TEMPLATE_ID_EXPR
231 && TYPE_P (scope
) && dependent_type_p (scope
))
232 pp_cxx_ws_string (pp
, "template");
235 /* nested-name-specifier:
236 class-or-namespace-name :: nested-name-specifier(opt)
237 class-or-namespace-name :: template nested-name-specifier */
240 pp_cxx_nested_name_specifier (cxx_pretty_printer
*pp
, tree t
)
242 /* FIXME: When diagnosing references to concepts (especially as types?)
243 we end up adding too many '::' to the name. This is partially due
244 to the fact that pp->enclosing_namespace is null. */
245 if (t
== global_namespace
)
247 pp_cxx_colon_colon (pp
);
249 else if (!SCOPE_FILE_SCOPE_P (t
) && t
!= pp
->enclosing_scope
)
251 tree scope
= get_containing_scope (t
);
252 pp_cxx_nested_name_specifier (pp
, scope
);
253 pp_cxx_template_keyword_if_needed (pp
, scope
, t
);
254 pp_cxx_unqualified_id (pp
, t
);
255 pp_cxx_colon_colon (pp
);
260 nested-name-specifier template(opt) unqualified-id */
263 pp_cxx_qualified_id (cxx_pretty_printer
*pp
, tree t
)
265 switch (TREE_CODE (t
))
267 /* A pointer-to-member is always qualified. */
269 pp_cxx_nested_name_specifier (pp
, PTRMEM_CST_CLASS (t
));
270 pp_cxx_unqualified_id (pp
, PTRMEM_CST_MEMBER (t
));
273 /* In Standard C++, functions cannot possibly be used as
274 nested-name-specifiers. However, there are situations where
275 is "makes sense" to output the surrounding function name for the
276 purpose of emphasizing on the scope kind. Just printing the
277 function name might not be sufficient as it may be overloaded; so,
278 we decorate the function with its signature too.
279 FIXME: This is probably the wrong pretty-printing for conversion
280 functions and some function templates. */
285 if (DECL_FUNCTION_MEMBER_P (t
))
286 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
287 pp_cxx_unqualified_id
288 (pp
, DECL_CONSTRUCTOR_P (t
) ? DECL_CONTEXT (t
) : t
);
289 pp_cxx_parameter_declaration_clause (pp
, TREE_TYPE (t
));
294 pp_cxx_nested_name_specifier (pp
, TREE_OPERAND (t
, 0));
295 pp_cxx_unqualified_id (pp
, TREE_OPERAND (t
, 1));
300 tree scope
= get_containing_scope (t
);
301 if (scope
!= pp
->enclosing_scope
)
303 pp_cxx_nested_name_specifier (pp
, scope
);
304 pp_cxx_template_keyword_if_needed (pp
, scope
, t
);
306 pp_cxx_unqualified_id (pp
, t
);
312 /* Given a value e of ENUMERAL_TYPE:
313 Print out the first ENUMERATOR id with value e, if one is found,
314 (including nested names but excluding the enum name if unscoped)
315 else print out the value as a C-style cast (type-id)value. */
318 pp_cxx_enumeration_constant (cxx_pretty_printer
*pp
, tree e
)
320 tree type
= TREE_TYPE (e
);
321 tree value
= NULL_TREE
;
323 /* Find the name of this constant. */
324 if ((pp
->flags
& pp_c_flag_gnu_v3
) == 0)
325 for (value
= TYPE_VALUES (type
); value
!= NULL_TREE
;
326 value
= TREE_CHAIN (value
))
327 if (tree_int_cst_equal (DECL_INITIAL (TREE_VALUE (value
)), e
))
330 if (value
!= NULL_TREE
)
332 if (!ENUM_IS_SCOPED (type
))
333 type
= get_containing_scope (type
);
334 pp_cxx_nested_name_specifier (pp
, type
);
335 pp
->id_expression (TREE_PURPOSE (value
));
339 /* Value must have been cast. */
340 pp_c_type_cast (pp
, type
);
341 pp_c_integer_constant (pp
, e
);
347 cxx_pretty_printer::constant (tree t
)
349 switch (TREE_CODE (t
))
353 const bool in_parens
= PAREN_STRING_LITERAL_P (t
);
355 pp_cxx_left_paren (this);
356 c_pretty_printer::constant (t
);
358 pp_cxx_right_paren (this);
363 if (NULLPTR_TYPE_P (TREE_TYPE (t
)))
365 pp_string (this, "nullptr");
368 else if (TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
370 pp_cxx_enumeration_constant (this, t
);
376 c_pretty_printer::constant (t
);
386 cxx_pretty_printer::id_expression (tree t
)
388 if (TREE_CODE (t
) == OVERLOAD
)
390 if (DECL_P (t
) && DECL_CONTEXT (t
))
391 pp_cxx_qualified_id (this, t
);
393 pp_cxx_unqualified_id (this, t
);
396 /* user-defined literal:
400 pp_cxx_userdef_literal (cxx_pretty_printer
*pp
, tree t
)
402 pp
->constant (USERDEF_LITERAL_VALUE (t
));
403 pp
->id_expression (USERDEF_LITERAL_SUFFIX_ID (t
));
407 /* primary-expression:
411 :: operator-function-id
417 __builtin_va_arg ( assignment-expression , type-id )
418 __builtin_offsetof ( type-id, offsetof-expression )
419 __builtin_addressof ( expression )
421 __has_nothrow_assign ( type-id )
422 __has_nothrow_constructor ( type-id )
423 __has_nothrow_copy ( type-id )
424 __has_trivial_assign ( type-id )
425 __has_trivial_constructor ( type-id )
426 __has_trivial_copy ( type-id )
427 __has_unique_object_representations ( type-id )
428 __has_trivial_destructor ( type-id )
429 __has_virtual_destructor ( type-id )
430 __is_abstract ( type-id )
431 __is_base_of ( type-id , type-id )
432 __is_class ( type-id )
433 __is_empty ( type-id )
434 __is_enum ( type-id )
435 __is_literal_type ( type-id )
437 __is_polymorphic ( type-id )
438 __is_std_layout ( type-id )
439 __is_trivial ( type-id )
440 __is_union ( type-id ) */
443 cxx_pretty_printer::primary_expression (tree t
)
445 switch (TREE_CODE (t
))
455 case USERDEF_LITERAL
:
456 pp_cxx_userdef_literal (this, t
);
460 t
= BASELINK_FUNCTIONS (t
);
473 case TEMPLATE_TYPE_PARM
:
474 case TEMPLATE_TEMPLATE_PARM
:
475 case TEMPLATE_PARM_INDEX
:
476 pp_cxx_unqualified_id (this, t
);
480 pp_cxx_left_paren (this);
481 statement (STMT_EXPR_STMT (t
));
482 pp_cxx_right_paren (this);
486 pp_cxx_trait_expression (this, t
);
490 pp_cxx_va_arg_expression (this, t
);
494 pp_cxx_offsetof_expression (this, t
);
498 pp_cxx_addressof_expression (this, t
);
502 pp_cxx_requires_expr (this, t
);
506 c_pretty_printer::primary_expression (t
);
511 /* postfix-expression:
513 postfix-expression [ expression ]
514 postfix-expression ( expression-list(opt) )
515 simple-type-specifier ( expression-list(opt) )
516 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
517 typename ::(opt) nested-name-specifier template(opt)
518 template-id ( expression-list(opt) )
519 postfix-expression . template(opt) ::(opt) id-expression
520 postfix-expression -> template(opt) ::(opt) id-expression
521 postfix-expression . pseudo-destructor-name
522 postfix-expression -> pseudo-destructor-name
523 postfix-expression ++
524 postfix-expression --
525 dynamic_cast < type-id > ( expression )
526 static_cast < type-id > ( expression )
527 reinterpret_cast < type-id > ( expression )
528 const_cast < type-id > ( expression )
529 typeid ( expression )
530 typeid ( type-id ) */
533 cxx_pretty_printer::postfix_expression (tree t
)
535 enum tree_code code
= TREE_CODE (t
);
542 tree fun
= cp_get_callee (t
);
543 tree saved_scope
= enclosing_scope
;
544 bool skipfirst
= false;
547 if (TREE_CODE (fun
) == ADDR_EXPR
)
548 fun
= TREE_OPERAND (fun
, 0);
550 /* In templates, where there is no way to tell whether a given
551 call uses an actual member function. So the parser builds
552 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
553 instantiation time. */
554 if (TREE_CODE (fun
) != FUNCTION_DECL
)
556 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun
))
558 tree object
= (code
== AGGR_INIT_EXPR
559 ? (AGGR_INIT_VIA_CTOR_P (t
)
560 ? AGGR_INIT_EXPR_SLOT (t
)
561 : AGGR_INIT_EXPR_ARG (t
, 0))
562 : CALL_EXPR_ARG (t
, 0));
564 while (TREE_CODE (object
) == NOP_EXPR
)
565 object
= TREE_OPERAND (object
, 0);
567 if (TREE_CODE (object
) == ADDR_EXPR
)
568 object
= TREE_OPERAND (object
, 0);
570 if (!TYPE_PTR_P (TREE_TYPE (object
)))
572 postfix_expression (object
);
577 postfix_expression (object
);
581 enclosing_scope
= strip_pointer_operator (TREE_TYPE (object
));
584 postfix_expression (fun
);
585 enclosing_scope
= saved_scope
;
586 pp_cxx_left_paren (this);
587 if (code
== AGGR_INIT_EXPR
)
589 aggr_init_expr_arg_iterator iter
;
590 FOR_EACH_AGGR_INIT_EXPR_ARG (arg
, iter
, t
)
597 if (more_aggr_init_expr_args_p (&iter
))
598 pp_cxx_separate_with (this, ',');
604 call_expr_arg_iterator iter
;
605 FOR_EACH_CALL_EXPR_ARG (arg
, iter
, t
)
612 if (more_call_expr_args_p (&iter
))
613 pp_cxx_separate_with (this, ',');
617 pp_cxx_right_paren (this);
619 if (code
== AGGR_INIT_EXPR
&& AGGR_INIT_VIA_CTOR_P (t
))
621 pp_cxx_separate_with (this, ',');
622 postfix_expression (AGGR_INIT_EXPR_SLOT (t
));
635 primary_expression (t
);
638 case DYNAMIC_CAST_EXPR
:
639 case STATIC_CAST_EXPR
:
640 case REINTERPRET_CAST_EXPR
:
641 case CONST_CAST_EXPR
:
642 if (code
== DYNAMIC_CAST_EXPR
)
643 pp_cxx_ws_string (this, "dynamic_cast");
644 else if (code
== STATIC_CAST_EXPR
)
645 pp_cxx_ws_string (this, "static_cast");
646 else if (code
== REINTERPRET_CAST_EXPR
)
647 pp_cxx_ws_string (this, "reinterpret_cast");
649 pp_cxx_ws_string (this, "const_cast");
650 pp_cxx_begin_template_argument_list (this);
651 type_id (TREE_TYPE (t
));
652 pp_cxx_end_template_argument_list (this);
653 pp_left_paren (this);
654 expression (TREE_OPERAND (t
, 0));
655 pp_right_paren (this);
658 case EMPTY_CLASS_EXPR
:
659 type_id (TREE_TYPE (t
));
660 pp_left_paren (this);
661 pp_right_paren (this);
665 pp_cxx_typeid_expression (this, t
);
668 case PSEUDO_DTOR_EXPR
:
669 postfix_expression (TREE_OPERAND (t
, 0));
671 if (TREE_OPERAND (t
, 1))
673 pp_cxx_qualified_id (this, TREE_OPERAND (t
, 1));
674 pp_cxx_colon_colon (this);
676 pp_complement (this);
677 pp_cxx_unqualified_id (this, TREE_OPERAND (t
, 2));
681 postfix_expression (TREE_OPERAND (t
, 0));
686 c_pretty_printer::postfix_expression (t
);
692 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
693 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
699 type-specifier-seq new-declarator(opt)
702 ptr-operator new-declarator(opt)
703 direct-new-declarator
705 direct-new-declarator
707 direct-new-declarator [ constant-expression ]
710 ( expression-list(opt) ) */
713 pp_cxx_new_expression (cxx_pretty_printer
*pp
, tree t
)
715 enum tree_code code
= TREE_CODE (t
);
716 tree type
= TREE_OPERAND (t
, 1);
717 tree init
= TREE_OPERAND (t
, 2);
722 if (NEW_EXPR_USE_GLOBAL (t
))
723 pp_cxx_colon_colon (pp
);
724 pp_cxx_ws_string (pp
, "new");
725 if (TREE_OPERAND (t
, 0))
727 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
730 if (TREE_CODE (type
) == ARRAY_REF
)
731 type
= build_cplus_array_type
732 (TREE_OPERAND (type
, 0),
733 build_index_type (fold_build2_loc (input_location
,
734 MINUS_EXPR
, integer_type_node
,
735 TREE_OPERAND (type
, 1),
741 if (TREE_CODE (init
) == TREE_LIST
)
742 pp_c_expression_list (pp
, init
);
743 else if (init
== void_node
)
744 ; /* OK, empty initializer list. */
746 pp
->expression (init
);
752 pp_unsupported_tree (pp
, t
);
756 /* delete-expression:
757 ::(opt) delete cast-expression
758 ::(opt) delete [ ] cast-expression */
761 pp_cxx_delete_expression (cxx_pretty_printer
*pp
, tree t
)
763 enum tree_code code
= TREE_CODE (t
);
767 case VEC_DELETE_EXPR
:
768 if (DELETE_EXPR_USE_GLOBAL (t
))
769 pp_cxx_colon_colon (pp
);
770 pp_cxx_ws_string (pp
, "delete");
772 if (code
== VEC_DELETE_EXPR
773 || DELETE_EXPR_USE_VEC (t
))
775 pp_left_bracket (pp
);
776 pp_right_bracket (pp
);
779 pp_c_cast_expression (pp
, TREE_OPERAND (t
, 0));
783 pp_unsupported_tree (pp
, t
);
791 unary-operator cast-expression
792 sizeof unary-expression
794 sizeof ... ( identifier )
798 unary-operator: one of
802 __alignof__ unary-expression
803 __alignof__ ( type-id ) */
806 cxx_pretty_printer::unary_expression (tree t
)
808 enum tree_code code
= TREE_CODE (t
);
813 pp_cxx_new_expression (this, t
);
817 case VEC_DELETE_EXPR
:
818 pp_cxx_delete_expression (this, t
);
822 if (PACK_EXPANSION_P (TREE_OPERAND (t
, 0)))
824 pp_cxx_ws_string (this, "sizeof");
825 pp_cxx_ws_string (this, "...");
826 pp_cxx_whitespace (this);
827 pp_cxx_left_paren (this);
828 if (TYPE_P (TREE_OPERAND (t
, 0)))
829 type_id (TREE_OPERAND (t
, 0));
831 unary_expression (TREE_OPERAND (t
, 0));
832 pp_cxx_right_paren (this);
838 pp_cxx_ws_string (this, code
== SIZEOF_EXPR
? "sizeof" : "__alignof__");
839 pp_cxx_whitespace (this);
840 if (TREE_CODE (t
) == SIZEOF_EXPR
&& SIZEOF_EXPR_TYPE_P (t
))
842 pp_cxx_left_paren (this);
843 type_id (TREE_TYPE (TREE_OPERAND (t
, 0)));
844 pp_cxx_right_paren (this);
846 else if (TYPE_P (TREE_OPERAND (t
, 0)))
848 pp_cxx_left_paren (this);
849 type_id (TREE_OPERAND (t
, 0));
850 pp_cxx_right_paren (this);
853 unary_expression (TREE_OPERAND (t
, 0));
857 pp_cxx_ws_string (this, "@encode");
858 pp_cxx_whitespace (this);
859 pp_cxx_left_paren (this);
860 type_id (TREE_OPERAND (t
, 0));
861 pp_cxx_right_paren (this);
865 pp_cxx_ws_string (this, "noexcept");
866 pp_cxx_whitespace (this);
867 pp_cxx_left_paren (this);
868 expression (TREE_OPERAND (t
, 0));
869 pp_cxx_right_paren (this);
872 case UNARY_PLUS_EXPR
:
874 pp_cxx_cast_expression (this, TREE_OPERAND (t
, 0));
878 c_pretty_printer::unary_expression (t
);
885 ( type-id ) cast-expression */
888 pp_cxx_cast_expression (cxx_pretty_printer
*pp
, tree t
)
890 switch (TREE_CODE (t
))
893 case IMPLICIT_CONV_EXPR
:
894 pp
->type_id (TREE_TYPE (t
));
895 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
899 pp_c_cast_expression (pp
, t
);
906 pm-expression .* cast-expression
907 pm-expression ->* cast-expression */
910 pp_cxx_pm_expression (cxx_pretty_printer
*pp
, tree t
)
912 switch (TREE_CODE (t
))
914 /* Handle unfortunate OFFSET_REF overloading here. */
916 if (TYPE_P (TREE_OPERAND (t
, 0)))
918 pp_cxx_qualified_id (pp
, t
);
924 pp_cxx_pm_expression (pp
, TREE_OPERAND (t
, 0));
925 if (TREE_CODE (t
) == MEMBER_REF
)
930 pp_cxx_cast_expression (pp
, TREE_OPERAND (t
, 1));
935 pp_cxx_cast_expression (pp
, t
);
940 /* multiplicative-expression:
942 multiplicative-expression * pm-expression
943 multiplicative-expression / pm-expression
944 multiplicative-expression % pm-expression */
947 cxx_pretty_printer::multiplicative_expression (tree e
)
949 enum tree_code code
= TREE_CODE (e
);
957 multiplicative_expression (TREE_OPERAND (e
, 0));
959 if (code
== MULT_EXPR
)
961 else if (code
!= TRUNC_MOD_EXPR
)
966 pp_cxx_pm_expression (this, TREE_OPERAND (e
, 1));
970 pp_cxx_pm_expression (this, e
);
975 /* conditional-expression:
976 logical-or-expression
977 logical-or-expression ? expression : assignment-expression */
980 cxx_pretty_printer::conditional_expression (tree e
)
982 if (TREE_CODE (e
) == COND_EXPR
)
984 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
988 expression (TREE_OPERAND (e
, 1));
990 assignment_expression (TREE_OPERAND (e
, 2));
993 pp_c_logical_or_expression (this, e
);
996 /* Pretty-print a compound assignment operator token as indicated by T. */
999 pp_cxx_assignment_operator (cxx_pretty_printer
*pp
, tree t
)
1003 switch (TREE_CODE (t
))
1017 case TRUNC_DIV_EXPR
:
1021 case TRUNC_MOD_EXPR
:
1026 op
= get_tree_code_name (TREE_CODE (t
));
1030 pp_cxx_ws_string (pp
, op
);
1034 /* assignment-expression:
1035 conditional-expression
1036 logical-or-expression assignment-operator assignment-expression
1040 throw assignment-expression(opt)
1042 assignment-operator: one of
1043 = *= /= %= += -= >>= <<= &= ^= |= */
1046 cxx_pretty_printer::assignment_expression (tree e
)
1048 switch (TREE_CODE (e
))
1052 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1056 assignment_expression (TREE_OPERAND (e
, 1));
1060 pp_cxx_ws_string (this, "throw");
1061 if (TREE_OPERAND (e
, 0))
1062 assignment_expression (TREE_OPERAND (e
, 0));
1066 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1067 pp_cxx_assignment_operator (this, TREE_OPERAND (e
, 1));
1068 assignment_expression (TREE_OPERAND (e
, 2));
1072 conditional_expression (e
);
1078 cxx_pretty_printer::expression (tree t
)
1080 switch (TREE_CODE (t
))
1090 case USERDEF_LITERAL
:
1091 pp_cxx_userdef_literal (this, t
);
1095 pp_cxx_unqualified_id (this, t
);
1103 pp_cxx_qualified_id (this, t
);
1116 case TEMPLATE_TYPE_PARM
:
1117 case TEMPLATE_PARM_INDEX
:
1118 case TEMPLATE_TEMPLATE_PARM
:
1121 primary_expression (t
);
1125 case DYNAMIC_CAST_EXPR
:
1126 case STATIC_CAST_EXPR
:
1127 case REINTERPRET_CAST_EXPR
:
1128 case CONST_CAST_EXPR
:
1132 case EMPTY_CLASS_EXPR
:
1134 case PSEUDO_DTOR_EXPR
:
1135 case AGGR_INIT_EXPR
:
1137 postfix_expression (t
);
1142 pp_cxx_new_expression (this, t
);
1146 case VEC_DELETE_EXPR
:
1147 pp_cxx_delete_expression (this, t
);
1153 case UNARY_PLUS_EXPR
:
1154 unary_expression (t
);
1158 case IMPLICIT_CONV_EXPR
:
1159 pp_cxx_cast_expression (this, t
);
1165 pp_cxx_pm_expression (this, t
);
1169 case TRUNC_DIV_EXPR
:
1170 case TRUNC_MOD_EXPR
:
1171 case EXACT_DIV_EXPR
:
1173 multiplicative_expression (t
);
1177 conditional_expression (t
);
1184 assignment_expression (t
);
1187 case NON_DEPENDENT_EXPR
:
1188 case MUST_NOT_THROW_EXPR
:
1189 expression (TREE_OPERAND (t
, 0));
1192 case EXPR_PACK_EXPANSION
:
1193 expression (PACK_EXPANSION_PATTERN (t
));
1194 pp_cxx_ws_string (this, "...");
1197 case UNARY_LEFT_FOLD_EXPR
:
1198 pp_cxx_unary_left_fold_expression (this, t
);
1201 case UNARY_RIGHT_FOLD_EXPR
:
1202 pp_cxx_unary_right_fold_expression (this, t
);
1205 case BINARY_LEFT_FOLD_EXPR
:
1206 case BINARY_RIGHT_FOLD_EXPR
:
1207 pp_cxx_binary_fold_expression (this, t
);
1210 case TEMPLATE_ID_EXPR
:
1211 pp_cxx_template_id (this, t
);
1214 case NONTYPE_ARGUMENT_PACK
:
1216 tree args
= ARGUMENT_PACK_ARGS (t
);
1217 int i
, len
= TREE_VEC_LENGTH (args
);
1218 pp_cxx_left_brace (this);
1219 for (i
= 0; i
< len
; ++i
)
1222 pp_cxx_separate_with (this, ',');
1223 expression (TREE_VEC_ELT (args
, i
));
1225 pp_cxx_right_brace (this);
1230 pp_cxx_ws_string (this, "<lambda>");
1234 pp_cxx_trait_expression (this, t
);
1241 pp_cxx_constraint (this, t
);
1245 pp_cxx_left_paren (this);
1246 expression (TREE_OPERAND (t
, 0));
1247 pp_cxx_right_paren (this);
1251 c_pretty_printer::expression (t
);
1259 /* function-specifier:
1265 cxx_pretty_printer::function_specifier (tree t
)
1267 switch (TREE_CODE (t
))
1270 if (DECL_VIRTUAL_P (t
))
1271 pp_cxx_ws_string (this, "virtual");
1272 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
1273 pp_cxx_ws_string (this, "explicit");
1275 c_pretty_printer::function_specifier (t
);
1282 /* decl-specifier-seq:
1283 decl-specifier-seq(opt) decl-specifier
1286 storage-class-specifier
1293 cxx_pretty_printer::declaration_specifiers (tree t
)
1295 switch (TREE_CODE (t
))
1301 storage_class_specifier (t
);
1302 declaration_specifiers (TREE_TYPE (t
));
1306 pp_cxx_ws_string (this, "typedef");
1307 declaration_specifiers (TREE_TYPE (t
));
1311 /* Constructors don't have return types. And conversion functions
1312 do not have a type-specifier in their return types. */
1313 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
1314 function_specifier (t
);
1315 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1316 declaration_specifiers (TREE_TYPE (TREE_TYPE (t
)));
1318 c_pretty_printer::declaration_specifiers (t
);
1321 c_pretty_printer::declaration_specifiers (t
);
1326 /* simple-type-specifier:
1327 ::(opt) nested-name-specifier(opt) type-name
1328 ::(opt) nested-name-specifier(opt) template(opt) template-id
1343 cxx_pretty_printer::simple_type_specifier (tree t
)
1345 switch (TREE_CODE (t
))
1350 pp_cxx_qualified_id (this, t
);
1353 case TEMPLATE_TYPE_PARM
:
1354 case TEMPLATE_TEMPLATE_PARM
:
1355 case TEMPLATE_PARM_INDEX
:
1356 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1357 pp_cxx_unqualified_id (this, t
);
1358 if (tree c
= PLACEHOLDER_TYPE_CONSTRAINTS (t
))
1359 pp_cxx_constrained_type_spec (this, c
);
1363 pp_cxx_ws_string (this, "typename");
1364 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t
));
1365 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t
));
1369 pp_cxx_ws_string (this, "decltype");
1370 pp_cxx_left_paren (this);
1371 this->expression (DECLTYPE_TYPE_EXPR (t
));
1372 pp_cxx_right_paren (this);
1376 c_pretty_printer::simple_type_specifier (t
);
1381 /* type-specifier-seq:
1382 type-specifier type-specifier-seq(opt)
1385 simple-type-specifier
1388 elaborated-type-specifier
1392 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1394 switch (TREE_CODE (t
))
1397 case TEMPLATE_TYPE_PARM
:
1398 case TEMPLATE_TEMPLATE_PARM
:
1400 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1402 pp_cxx_cv_qualifier_seq (pp
, t
);
1403 pp
->simple_type_specifier (t
);
1407 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1408 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1409 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1413 if (TYPE_PTRMEMFUNC_P (t
))
1415 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
1416 pp
->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm
)));
1417 pp_cxx_whitespace (pp
);
1418 pp_cxx_ptr_operator (pp
, t
);
1424 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1425 pp_c_specifier_qualifier_list (pp
, t
);
1430 * cv-qualifier-seq(opt)
1432 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1435 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1437 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1439 switch (TREE_CODE (t
))
1441 case REFERENCE_TYPE
:
1443 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1444 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1445 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1449 pp_cxx_cv_qualifier_seq (pp
, t
);
1456 if (TYPE_PTRMEMFUNC_P (t
))
1458 pp_cxx_left_paren (pp
);
1459 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1465 if (TYPE_PTRMEM_P (t
))
1467 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1468 pp_cxx_left_paren (pp
);
1469 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1471 pp_cxx_cv_qualifier_seq (pp
, t
);
1477 pp_unsupported_tree (pp
, t
);
1483 pp_cxx_implicit_parameter_type (tree mf
)
1485 return class_of_this_parm (TREE_TYPE (mf
));
1489 parameter-declaration:
1490 decl-specifier-seq declarator
1491 decl-specifier-seq declarator = assignment-expression
1492 decl-specifier-seq abstract-declarator(opt)
1493 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1496 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1498 pp
->declaration_specifiers (t
);
1500 pp
->abstract_declarator (t
);
1505 /* parameter-declaration-clause:
1506 parameter-declaration-list(opt) ...(opt)
1507 parameter-declaration-list , ...
1509 parameter-declaration-list:
1510 parameter-declaration
1511 parameter-declaration-list , parameter-declaration */
1514 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1520 // For a requires clause or the explicit printing of a parameter list
1521 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1522 // args and types are taken from the function decl T.
1523 if (TREE_CODE (t
) == PARM_DECL
)
1531 bool type_p
= TYPE_P (t
);
1532 args
= type_p
? NULL
: FUNCTION_FIRST_USER_PARM (t
);
1533 types
= type_p
? TYPE_ARG_TYPES (t
) : FUNCTION_FIRST_USER_PARMTYPE (t
);
1534 abstract
= args
== NULL
|| pp
->flags
& pp_c_flag_abstract
;
1538 /* Skip artificial parameter for non-static member functions. */
1539 if (TREE_CODE (t
) == METHOD_TYPE
)
1540 types
= TREE_CHAIN (types
);
1542 pp_cxx_left_paren (pp
);
1543 for (; args
; args
= TREE_CHAIN (args
), types
= TREE_CHAIN (types
))
1546 pp_cxx_separate_with (pp
, ',');
1548 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1549 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1551 pp_cxx_whitespace (pp
);
1553 pp_cxx_whitespace (pp
);
1554 pp
->assignment_expression (TREE_PURPOSE (types
));
1557 pp_cxx_right_paren (pp
);
1560 /* exception-specification:
1561 throw ( type-id-list(opt) )
1565 type-id-list , type-id */
1568 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1570 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1571 bool need_comma
= false;
1573 if (ex_spec
== NULL
)
1575 if (TREE_PURPOSE (ex_spec
))
1577 pp_cxx_ws_string (pp
, "noexcept");
1578 pp_cxx_whitespace (pp
);
1579 pp_cxx_left_paren (pp
);
1580 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1581 pp_cxx_ws_string (pp
, "<uninstantiated>");
1583 pp
->expression (TREE_PURPOSE (ex_spec
));
1584 pp_cxx_right_paren (pp
);
1587 pp_cxx_ws_string (pp
, "throw");
1588 pp_cxx_left_paren (pp
);
1589 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1591 tree type
= TREE_VALUE (ex_spec
);
1592 tree argpack
= NULL_TREE
;
1595 if (ARGUMENT_PACK_P (type
))
1597 argpack
= ARGUMENT_PACK_ARGS (type
);
1598 len
= TREE_VEC_LENGTH (argpack
);
1601 for (i
= 0; i
< len
; ++i
)
1604 type
= TREE_VEC_ELT (argpack
, i
);
1607 pp_cxx_separate_with (pp
, ',');
1614 pp_cxx_right_paren (pp
);
1617 /* direct-declarator:
1619 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1620 exception-specification(opt)
1621 direct-declaration [ constant-expression(opt) ]
1625 cxx_pretty_printer::direct_declarator (tree t
)
1627 switch (TREE_CODE (t
))
1635 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1637 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1638 || template_parameter_pack_p (t
))
1639 /* A function parameter pack or non-type template
1641 pp_cxx_ws_string (this, "...");
1643 id_expression (DECL_NAME (t
));
1645 abstract_declarator (TREE_TYPE (t
));
1649 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1651 pp_cxx_parameter_declaration_clause (this, t
);
1653 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1655 padding
= pp_before
;
1656 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1659 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1664 case TEMPLATE_TYPE_PARM
:
1665 case TEMPLATE_PARM_INDEX
:
1666 case TEMPLATE_TEMPLATE_PARM
:
1670 c_pretty_printer::direct_declarator (t
);
1677 ptr-operator declarator */
1680 cxx_pretty_printer::declarator (tree t
)
1682 direct_declarator (t
);
1684 // Print a requires clause.
1686 if (tree ci
= get_constraints (t
))
1687 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1688 pp_cxx_requires_clause (this, reqs
);
1691 /* ctor-initializer:
1692 : mem-initializer-list
1694 mem-initializer-list:
1696 mem-initializer , mem-initializer-list
1699 mem-initializer-id ( expression-list(opt) )
1702 ::(opt) nested-name-specifier(opt) class-name
1706 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1708 t
= TREE_OPERAND (t
, 0);
1709 pp_cxx_whitespace (pp
);
1711 pp_cxx_whitespace (pp
);
1712 for (; t
; t
= TREE_CHAIN (t
))
1714 tree purpose
= TREE_PURPOSE (t
);
1715 bool is_pack
= PACK_EXPANSION_P (purpose
);
1718 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1720 pp
->primary_expression (purpose
);
1721 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1723 pp_cxx_ws_string (pp
, "...");
1725 pp_cxx_separate_with (pp
, ',');
1729 /* function-definition:
1730 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1731 decl-specifier-seq(opt) declarator function-try-block */
1734 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1736 tree saved_scope
= pp
->enclosing_scope
;
1737 pp
->declaration_specifiers (t
);
1739 pp_needs_newline (pp
) = true;
1740 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1741 if (DECL_SAVED_TREE (t
))
1742 pp
->statement (DECL_SAVED_TREE (t
));
1744 pp_cxx_semicolon (pp
);
1745 pp_newline_and_flush (pp
);
1746 pp
->enclosing_scope
= saved_scope
;
1749 /* abstract-declarator:
1750 ptr-operator abstract-declarator(opt)
1751 direct-abstract-declarator */
1754 cxx_pretty_printer::abstract_declarator (tree t
)
1756 if (TYPE_PTRMEM_P (t
))
1757 pp_cxx_right_paren (this);
1758 else if (INDIRECT_TYPE_P (t
))
1760 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1761 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1762 pp_cxx_right_paren (this);
1765 direct_abstract_declarator (t
);
1768 /* direct-abstract-declarator:
1769 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1770 cv-qualifier-seq(opt) exception-specification(opt)
1771 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1772 ( abstract-declarator ) */
1775 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1777 switch (TREE_CODE (t
))
1779 case REFERENCE_TYPE
:
1780 abstract_declarator (t
);
1784 if (TYPE_PTRMEMFUNC_P (t
))
1785 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1790 pp_cxx_parameter_declaration_clause (this, t
);
1791 direct_abstract_declarator (TREE_TYPE (t
));
1792 if (TREE_CODE (t
) == METHOD_TYPE
)
1794 padding
= pp_before
;
1795 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1797 pp_cxx_exception_specification (this, t
);
1801 case TEMPLATE_TYPE_PARM
:
1802 case TEMPLATE_TEMPLATE_PARM
:
1803 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1804 case UNBOUND_CLASS_TEMPLATE
:
1809 c_pretty_printer::direct_abstract_declarator (t
);
1815 type-specifier-seq abstract-declarator(opt) */
1818 cxx_pretty_printer::type_id (tree t
)
1820 pp_flags saved_flags
= flags
;
1821 flags
|= pp_c_flag_abstract
;
1823 switch (TREE_CODE (t
))
1830 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1831 case UNBOUND_CLASS_TEMPLATE
:
1832 case TEMPLATE_TEMPLATE_PARM
:
1833 case TEMPLATE_TYPE_PARM
:
1834 case TEMPLATE_PARM_INDEX
:
1837 case UNDERLYING_TYPE
:
1839 case TEMPLATE_ID_EXPR
:
1840 pp_cxx_type_specifier_seq (this, t
);
1843 case TYPE_PACK_EXPANSION
:
1844 type_id (PACK_EXPANSION_PATTERN (t
));
1845 pp_cxx_ws_string (this, "...");
1848 case TYPE_ARGUMENT_PACK
:
1850 tree args
= ARGUMENT_PACK_ARGS (t
);
1851 int len
= TREE_VEC_LENGTH (args
);
1852 pp_cxx_left_brace (this);
1853 for (int i
= 0; i
< len
; ++i
)
1856 pp_cxx_separate_with (this, ',');
1857 type_id (TREE_VEC_ELT (args
, i
));
1859 pp_cxx_right_brace (this);
1864 c_pretty_printer::type_id (t
);
1868 flags
= saved_flags
;
1871 /* template-argument-list:
1872 template-argument ...(opt)
1873 template-argument-list, template-argument ...(opt)
1876 assignment-expression
1881 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1884 bool need_comma
= false;
1888 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1890 tree arg
= TREE_VEC_ELT (t
, i
);
1891 tree argpack
= NULL_TREE
;
1894 if (ARGUMENT_PACK_P (arg
))
1896 argpack
= ARGUMENT_PACK_ARGS (arg
);
1897 len
= TREE_VEC_LENGTH (argpack
);
1900 for (idx
= 0; idx
< len
; idx
++)
1903 arg
= TREE_VEC_ELT (argpack
, idx
);
1906 pp_cxx_separate_with (pp
, ',');
1910 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1911 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1914 pp
->expression (arg
);
1921 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1923 t
= DECL_EXPR_DECL (t
);
1924 pp_cxx_type_specifier_seq (pp
, t
);
1926 pp
->abstract_declarator (t
);
1934 cxx_pretty_printer::statement (tree t
)
1936 switch (TREE_CODE (t
))
1938 case CTOR_INITIALIZER
:
1939 pp_cxx_ctor_initializer (this, t
);
1943 pp_cxx_ws_string (this, "using");
1944 pp_cxx_ws_string (this, "namespace");
1945 if (DECL_CONTEXT (t
))
1946 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
1947 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
1951 pp_cxx_ws_string (this, "using");
1952 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
1953 pp_cxx_unqualified_id (this, DECL_NAME (t
));
1960 try compound-statement handler-seq */
1962 pp_maybe_newline_and_indent (this, 0);
1963 pp_cxx_ws_string (this, "try");
1964 pp_newline_and_indent (this, 3);
1965 statement (TRY_STMTS (t
));
1966 pp_newline_and_indent (this, -3);
1970 statement (TRY_HANDLERS (t
));
1975 handler handler-seq(opt)
1978 catch ( exception-declaration ) compound-statement
1980 exception-declaration:
1981 type-specifier-seq declarator
1982 type-specifier-seq abstract-declarator
1985 pp_cxx_ws_string (this, "catch");
1986 pp_cxx_left_paren (this);
1987 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
1988 pp_cxx_right_paren (this);
1989 pp_indentation (this) += 3;
1990 pp_needs_newline (this) = true;
1991 statement (HANDLER_BODY (t
));
1992 pp_indentation (this) -= 3;
1993 pp_needs_newline (this) = true;
1996 /* selection-statement:
1997 if ( expression ) statement
1998 if ( expression ) statement else statement */
2000 pp_cxx_ws_string (this, "if");
2001 pp_cxx_whitespace (this);
2002 pp_cxx_left_paren (this);
2003 expression (IF_COND (t
));
2004 pp_cxx_right_paren (this);
2005 pp_newline_and_indent (this, 2);
2006 statement (THEN_CLAUSE (t
));
2007 pp_newline_and_indent (this, -2);
2008 if (ELSE_CLAUSE (t
))
2010 tree else_clause
= ELSE_CLAUSE (t
);
2011 pp_cxx_ws_string (this, "else");
2012 if (TREE_CODE (else_clause
) == IF_STMT
)
2013 pp_cxx_whitespace (this);
2015 pp_newline_and_indent (this, 2);
2016 statement (else_clause
);
2017 if (TREE_CODE (else_clause
) != IF_STMT
)
2018 pp_newline_and_indent (this, -2);
2022 case RANGE_FOR_STMT
:
2023 pp_cxx_ws_string (this, "for");
2025 pp_cxx_left_paren (this);
2026 if (RANGE_FOR_INIT_STMT (t
))
2028 statement (RANGE_FOR_INIT_STMT (t
));
2029 pp_needs_newline (this) = false;
2030 pp_cxx_whitespace (this);
2032 statement (RANGE_FOR_DECL (t
));
2034 pp_needs_newline (this) = false;
2037 statement (RANGE_FOR_EXPR (t
));
2038 pp_cxx_right_paren (this);
2039 pp_newline_and_indent (this, 3);
2040 statement (FOR_BODY (t
));
2041 pp_indentation (this) -= 3;
2042 pp_needs_newline (this) = true;
2045 /* expression-statement:
2046 expression(opt) ; */
2048 expression (EXPR_STMT_EXPR (t
));
2049 pp_cxx_semicolon (this);
2050 pp_needs_newline (this) = true;
2054 pp_cxx_ws_string (this, "try");
2055 pp_newline_and_indent (this, 2);
2056 statement (CLEANUP_BODY (t
));
2057 pp_newline_and_indent (this, -2);
2058 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2059 pp_newline_and_indent (this, 2);
2060 statement (CLEANUP_EXPR (t
));
2061 pp_newline_and_indent (this, -2);
2069 pp_cxx_ws_string (this, "#pragma omp depobj");
2071 pp_cxx_left_paren (this);
2072 expression (OMP_DEPOBJ_DEPOBJ (t
));
2073 pp_cxx_right_paren (this);
2074 if (OMP_DEPOBJ_CLAUSES (t
) && OMP_DEPOBJ_CLAUSES (t
) != error_mark_node
)
2076 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t
)) == OMP_CLAUSE
)
2077 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t
),
2078 pp_indentation (this), TDF_NONE
);
2080 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t
)))
2082 case OMP_CLAUSE_DEPEND_IN
:
2083 pp_cxx_ws_string (this, " update(in)");
2085 case OMP_CLAUSE_DEPEND_INOUT
:
2086 pp_cxx_ws_string (this, " update(inout)");
2088 case OMP_CLAUSE_DEPEND_OUT
:
2089 pp_cxx_ws_string (this, " update(out)");
2091 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
2092 pp_cxx_ws_string (this, " update(mutexinoutset)");
2094 case OMP_CLAUSE_DEPEND_LAST
:
2095 pp_cxx_ws_string (this, " destroy");
2101 pp_needs_newline (this) = true;
2105 c_pretty_printer::statement (t
);
2110 /* original-namespace-definition:
2111 namespace identifier { namespace-body }
2113 As an edge case, we also handle unnamed namespace definition here. */
2116 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2118 pp_cxx_ws_string (pp
, "namespace");
2119 if (DECL_CONTEXT (t
))
2120 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2122 pp_cxx_unqualified_id (pp
, t
);
2123 pp_cxx_whitespace (pp
);
2124 pp_cxx_left_brace (pp
);
2125 /* We do not print the namespace-body. */
2126 pp_cxx_whitespace (pp
);
2127 pp_cxx_right_brace (pp
);
2133 namespace-alias-definition:
2134 namespace identifier = qualified-namespace-specifier ;
2136 qualified-namespace-specifier:
2137 ::(opt) nested-name-specifier(opt) namespace-name */
2140 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2142 pp_cxx_ws_string (pp
, "namespace");
2143 if (DECL_CONTEXT (t
))
2144 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2145 pp_cxx_unqualified_id (pp
, t
);
2146 pp_cxx_whitespace (pp
);
2148 pp_cxx_whitespace (pp
);
2149 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2150 pp_cxx_nested_name_specifier (pp
,
2151 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2152 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2153 pp_cxx_semicolon (pp
);
2156 /* simple-declaration:
2157 decl-specifier-seq(opt) init-declarator-list(opt) */
2160 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2162 pp
->declaration_specifiers (t
);
2163 pp_cxx_init_declarator (pp
, t
);
2164 pp_cxx_semicolon (pp
);
2165 pp_needs_newline (pp
) = true;
2169 template-parameter-list:
2171 template-parameter-list , template-parameter */
2174 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2176 const int n
= TREE_VEC_LENGTH (t
);
2178 for (i
= 0; i
< n
; ++i
)
2181 pp_cxx_separate_with (pp
, ',');
2182 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2186 /* template-parameter:
2188 parameter-declaration
2191 class ...(opt) identifier(opt)
2192 class identifier(opt) = type-id
2193 typename identifier(opt)
2194 typename ...(opt) identifier(opt) = type-id
2195 template < template-parameter-list > class ...(opt) identifier(opt)
2196 template < template-parameter-list > class identifier(opt) = template-name */
2199 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2201 tree parameter
= TREE_VALUE (t
);
2202 switch (TREE_CODE (parameter
))
2205 pp_cxx_ws_string (pp
, "class");
2206 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2207 pp_cxx_ws_string (pp
, "...");
2208 if (DECL_NAME (parameter
))
2209 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2210 /* FIXME: Check if we should print also default argument. */
2214 pp_cxx_parameter_declaration (pp
, parameter
);
2221 pp_unsupported_tree (pp
, t
);
2226 /* Pretty-print a template parameter in the canonical form
2227 "template-parameter-<level>-<position in parameter list>". */
2230 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2232 const enum tree_code code
= TREE_CODE (parm
);
2234 /* Brings type template parameters to the canonical forms. */
2235 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2236 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2237 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2239 pp_cxx_begin_template_argument_list (pp
);
2240 pp
->translate_string ("template-parameter-");
2241 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2243 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2244 pp_cxx_end_template_argument_list (pp
);
2247 /* Print a constrained-type-specifier. */
2250 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2252 pp_cxx_whitespace (pp
);
2253 pp_cxx_left_bracket (pp
);
2254 pp
->translate_string ("requires");
2255 pp_cxx_whitespace (pp
);
2256 if (c
== error_mark_node
)
2258 pp_cxx_ws_string(pp
, "<unsatisfied-type-constraint>");
2262 placeholder_extract_concept_and_args (c
, t
, a
);
2263 pp
->id_expression (t
);
2264 pp_cxx_begin_template_argument_list (pp
);
2265 pp_cxx_ws_string (pp
, "<placeholder>");
2266 pp_cxx_separate_with (pp
, ',');
2267 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2268 for (int i
= 0; i
< TREE_VEC_LENGTH (a
) - 1; ++i
)
2269 TREE_VEC_ELT (args
, i
) = TREE_VEC_ELT (a
, i
+ 1);
2270 pp_cxx_template_argument_list (pp
, args
);
2272 pp_cxx_end_template_argument_list (pp
);
2273 pp_cxx_right_bracket (pp
);
2277 template-declaration:
2278 export(opt) template < template-parameter-list > declaration
2282 template-declaration:
2283 export(opt) template < template-parameter-list >
2284 requires-clause(opt) declaration */
2287 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2289 tree tmpl
= most_general_template (t
);
2292 pp_maybe_newline_and_indent (pp
, 0);
2293 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2295 pp_cxx_ws_string (pp
, "template");
2296 pp_cxx_begin_template_argument_list (pp
);
2297 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2298 pp_cxx_end_template_argument_list (pp
);
2299 pp_newline_and_indent (pp
, 3);
2303 if (tree ci
= get_constraints (t
))
2304 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2306 pp_cxx_requires_clause (pp
, reqs
);
2307 pp_newline_and_indent (pp
, 6);
2310 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2311 pp_cxx_function_definition (pp
, t
);
2312 else if (TREE_CODE (t
) == CONCEPT_DECL
)
2313 pp_cxx_concept_definition (pp
, t
);
2315 pp_cxx_simple_declaration (pp
, t
);
2319 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2321 pp_unsupported_tree (pp
, t
);
2325 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2327 pp_unsupported_tree (pp
, t
);
2331 pp_cxx_concept_definition (cxx_pretty_printer
*pp
, tree t
)
2333 pp_cxx_unqualified_id (pp
, DECL_NAME (t
));
2334 pp_cxx_whitespace (pp
);
2335 pp_cxx_ws_string (pp
, "=");
2336 pp_cxx_whitespace (pp
);
2337 pp
->expression (DECL_INITIAL (t
));
2338 pp_cxx_semicolon (pp
);
2345 template-declaration
2346 explicit-instantiation
2347 explicit-specialization
2348 linkage-specification
2349 namespace-definition
2354 namespace-alias-definition
2357 static_assert-declaration */
2359 cxx_pretty_printer::declaration (tree t
)
2361 if (TREE_CODE (t
) == STATIC_ASSERT
)
2363 pp_cxx_ws_string (this, "static_assert");
2364 pp_cxx_left_paren (this);
2365 expression (STATIC_ASSERT_CONDITION (t
));
2366 pp_cxx_separate_with (this, ',');
2367 expression (STATIC_ASSERT_MESSAGE (t
));
2368 pp_cxx_right_paren (this);
2370 else if (!DECL_LANG_SPECIFIC (t
))
2371 pp_cxx_simple_declaration (this, t
);
2372 else if (DECL_USE_TEMPLATE (t
))
2373 switch (DECL_USE_TEMPLATE (t
))
2376 pp_cxx_template_declaration (this, t
);
2380 pp_cxx_explicit_specialization (this, t
);
2384 pp_cxx_explicit_instantiation (this, t
);
2390 else switch (TREE_CODE (t
))
2394 pp_cxx_simple_declaration (this, t
);
2398 if (DECL_SAVED_TREE (t
))
2399 pp_cxx_function_definition (this, t
);
2401 pp_cxx_simple_declaration (this, t
);
2404 case NAMESPACE_DECL
:
2405 if (DECL_NAMESPACE_ALIAS (t
))
2406 pp_cxx_namespace_alias_definition (this, t
);
2408 pp_cxx_original_namespace_definition (this, t
);
2412 pp_unsupported_tree (this, t
);
2418 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2420 t
= TREE_OPERAND (t
, 0);
2421 pp_cxx_ws_string (pp
, "typeid");
2422 pp_cxx_left_paren (pp
);
2427 pp_cxx_right_paren (pp
);
2431 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2433 pp_cxx_ws_string (pp
, "va_arg");
2434 pp_cxx_left_paren (pp
);
2435 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2436 pp_cxx_separate_with (pp
, ',');
2437 pp
->type_id (TREE_TYPE (t
));
2438 pp_cxx_right_paren (pp
);
2442 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2444 switch (TREE_CODE (t
))
2447 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2448 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2450 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2451 pp_cxx_separate_with (pp
, ',');
2456 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2458 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2460 pp
->expression (TREE_OPERAND (t
, 1));
2463 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2465 pp_left_bracket (pp
);
2466 pp
->expression (TREE_OPERAND (t
, 1));
2467 pp_right_bracket (pp
);
2475 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2477 pp_cxx_ws_string (pp
, "offsetof");
2478 pp_cxx_left_paren (pp
);
2479 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2480 pp
->expression (TREE_OPERAND (t
, 0));
2481 pp_cxx_right_paren (pp
);
2485 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2487 pp_cxx_ws_string (pp
, "__builtin_addressof");
2488 pp_cxx_left_paren (pp
);
2489 pp
->expression (TREE_OPERAND (t
, 0));
2490 pp_cxx_right_paren (pp
);
2494 get_fold_operator (tree t
)
2496 int op
= int_cst_value (FOLD_EXPR_OP (t
));
2497 ovl_op_info_t
*info
= OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t
), op
);
2502 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2504 char const* op
= get_fold_operator (t
);
2505 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2506 pp_cxx_left_paren (pp
);
2507 pp_cxx_ws_string (pp
, "...");
2508 pp_cxx_ws_string (pp
, op
);
2509 pp
->expression (expr
);
2510 pp_cxx_right_paren (pp
);
2514 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2516 char const* op
= get_fold_operator (t
);
2517 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2518 pp_cxx_left_paren (pp
);
2519 pp
->expression (expr
);
2521 pp_cxx_ws_string (pp
, op
);
2522 pp_cxx_ws_string (pp
, "...");
2523 pp_cxx_right_paren (pp
);
2527 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2529 char const* op
= get_fold_operator (t
);
2530 tree t1
= TREE_OPERAND (t
, 1);
2531 tree t2
= TREE_OPERAND (t
, 2);
2532 if (t1
== FOLD_EXPR_PACK (t
))
2533 t1
= PACK_EXPANSION_PATTERN (t1
);
2535 t2
= PACK_EXPANSION_PATTERN (t2
);
2536 pp_cxx_left_paren (pp
);
2537 pp
->expression (t1
);
2538 pp_cxx_ws_string (pp
, op
);
2539 pp_cxx_ws_string (pp
, "...");
2540 pp_cxx_ws_string (pp
, op
);
2541 pp
->expression (t2
);
2542 pp_cxx_right_paren (pp
);
2546 pp_cxx_trait_expression (cxx_pretty_printer
*pp
, tree t
)
2548 cp_trait_kind kind
= TRAIT_EXPR_KIND (t
);
2552 case CPTK_HAS_NOTHROW_ASSIGN
:
2553 pp_cxx_ws_string (pp
, "__has_nothrow_assign");
2555 case CPTK_HAS_TRIVIAL_ASSIGN
:
2556 pp_cxx_ws_string (pp
, "__has_trivial_assign");
2558 case CPTK_HAS_NOTHROW_CONSTRUCTOR
:
2559 pp_cxx_ws_string (pp
, "__has_nothrow_constructor");
2561 case CPTK_HAS_TRIVIAL_CONSTRUCTOR
:
2562 pp_cxx_ws_string (pp
, "__has_trivial_constructor");
2564 case CPTK_HAS_NOTHROW_COPY
:
2565 pp_cxx_ws_string (pp
, "__has_nothrow_copy");
2567 case CPTK_HAS_TRIVIAL_COPY
:
2568 pp_cxx_ws_string (pp
, "__has_trivial_copy");
2570 case CPTK_HAS_TRIVIAL_DESTRUCTOR
:
2571 pp_cxx_ws_string (pp
, "__has_trivial_destructor");
2573 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS
:
2574 pp_cxx_ws_string (pp
, "__has_unique_object_representations");
2576 case CPTK_HAS_VIRTUAL_DESTRUCTOR
:
2577 pp_cxx_ws_string (pp
, "__has_virtual_destructor");
2579 case CPTK_IS_ABSTRACT
:
2580 pp_cxx_ws_string (pp
, "__is_abstract");
2582 case CPTK_IS_AGGREGATE
:
2583 pp_cxx_ws_string (pp
, "__is_aggregate");
2585 case CPTK_IS_BASE_OF
:
2586 pp_cxx_ws_string (pp
, "__is_base_of");
2589 pp_cxx_ws_string (pp
, "__is_class");
2592 pp_cxx_ws_string (pp
, "__is_empty");
2595 pp_cxx_ws_string (pp
, "__is_enum");
2598 pp_cxx_ws_string (pp
, "__is_final");
2601 pp_cxx_ws_string (pp
, "__is_pod");
2603 case CPTK_IS_POLYMORPHIC
:
2604 pp_cxx_ws_string (pp
, "__is_polymorphic");
2606 case CPTK_IS_SAME_AS
:
2607 pp_cxx_ws_string (pp
, "__is_same");
2609 case CPTK_IS_STD_LAYOUT
:
2610 pp_cxx_ws_string (pp
, "__is_std_layout");
2612 case CPTK_IS_TRIVIAL
:
2613 pp_cxx_ws_string (pp
, "__is_trivial");
2615 case CPTK_IS_TRIVIALLY_ASSIGNABLE
:
2616 pp_cxx_ws_string (pp
, "__is_trivially_assignable");
2618 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE
:
2619 pp_cxx_ws_string (pp
, "__is_trivially_constructible");
2621 case CPTK_IS_TRIVIALLY_COPYABLE
:
2622 pp_cxx_ws_string (pp
, "__is_trivially_copyable");
2625 pp_cxx_ws_string (pp
, "__is_union");
2627 case CPTK_IS_LITERAL_TYPE
:
2628 pp_cxx_ws_string (pp
, "__is_literal_type");
2630 case CPTK_IS_ASSIGNABLE
:
2631 pp_cxx_ws_string (pp
, "__is_assignable");
2633 case CPTK_IS_CONSTRUCTIBLE
:
2634 pp_cxx_ws_string (pp
, "__is_constructible");
2641 pp_cxx_left_paren (pp
);
2642 pp
->type_id (TRAIT_EXPR_TYPE1 (t
));
2644 if (kind
== CPTK_IS_BASE_OF
|| kind
== CPTK_IS_SAME_AS
)
2646 pp_cxx_separate_with (pp
, ',');
2647 pp
->type_id (TRAIT_EXPR_TYPE2 (t
));
2650 pp_cxx_right_paren (pp
);
2654 // 'requires' logical-or-expression
2656 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2660 pp
->padding
= pp_before
;
2661 pp_cxx_ws_string (pp
, "requires");
2668 compound-requirement
2670 nested-requirement */
2672 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2674 switch (TREE_CODE (t
))
2677 pp_cxx_simple_requirement (pp
, t
);
2681 pp_cxx_type_requirement (pp
, t
);
2685 pp_cxx_compound_requirement (pp
, t
);
2689 pp_cxx_nested_requirement (pp
, t
);
2697 // requirement-list:
2699 // requirement-list ';' requirement[opt]
2702 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2704 for (; t
; t
= TREE_CHAIN (t
))
2705 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2708 // requirement-body:
2709 // '{' requirement-list '}'
2711 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2713 pp_cxx_left_brace (pp
);
2714 pp_cxx_requirement_list (pp
, t
);
2715 pp_cxx_right_brace (pp
);
2718 // requires-expression:
2719 // 'requires' requirement-parameter-list requirement-body
2721 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2723 pp_string (pp
, "requires");
2724 if (tree parms
= TREE_OPERAND (t
, 0))
2726 pp_cxx_parameter_declaration_clause (pp
, parms
);
2727 pp_cxx_whitespace (pp
);
2729 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2732 /* simple-requirement:
2735 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2737 pp
->expression (TREE_OPERAND (t
, 0));
2738 pp_cxx_semicolon (pp
);
2741 /* type-requirement:
2742 typename type-name ';' */
2744 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2746 pp
->type_id (TREE_OPERAND (t
, 0));
2747 pp_cxx_semicolon (pp
);
2750 /* compound-requirement:
2751 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2753 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2755 pp_cxx_left_brace (pp
);
2756 pp
->expression (TREE_OPERAND (t
, 0));
2757 pp_cxx_right_brace (pp
);
2759 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2760 pp_cxx_ws_string (pp
, "noexcept");
2762 if (tree type
= TREE_OPERAND (t
, 1))
2764 pp_cxx_whitespace (pp
);
2765 pp_cxx_ws_string (pp
, "->");
2768 pp_cxx_semicolon (pp
);
2771 /* nested requirement:
2772 'requires' constraint-expression */
2774 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2776 pp_cxx_ws_string (pp
, "requires");
2777 pp
->expression (TREE_OPERAND (t
, 0));
2778 pp_cxx_semicolon (pp
);
2782 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2784 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2785 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2786 tree args
= CHECK_CONSTR_ARGS (t
);
2787 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2789 if (TREE_CODE (decl
) == CONCEPT_DECL
)
2790 pp
->expression (id
);
2791 else if (VAR_P (decl
))
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
);
2804 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2808 pp_cxx_parameter_mapping (cxx_pretty_printer
*pp
, tree map
)
2810 pp_cxx_whitespace (pp
);
2811 pp_cxx_left_bracket (pp
);
2812 pp
->translate_string ("with");
2813 pp_cxx_whitespace (pp
);
2815 for (tree p
= map
; p
; p
= TREE_CHAIN (p
))
2817 tree parm
= TREE_VALUE (p
);
2818 tree arg
= TREE_PURPOSE (p
);
2823 pp_cxx_tree_identifier (pp
, DECL_NAME (TEMPLATE_PARM_DECL (parm
)));
2825 pp_cxx_whitespace (pp
);
2827 pp_cxx_whitespace (pp
);
2829 if (TYPE_P (arg
) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg
))
2832 pp
->expression (arg
);
2834 if (TREE_CHAIN (p
) != NULL_TREE
)
2835 pp_cxx_separate_with (pp
, ';');
2838 pp_cxx_right_bracket (pp
);
2842 pp_cxx_atomic_constraint (cxx_pretty_printer
*pp
, tree t
)
2844 /* Emit the expression. */
2845 pp
->expression (ATOMIC_CONSTR_EXPR (t
));
2847 /* Emit the parameter mapping. */
2848 tree map
= ATOMIC_CONSTR_MAP (t
);
2849 if (map
&& map
!= error_mark_node
)
2850 pp_cxx_parameter_mapping (pp
, map
);
2854 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2856 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2857 pp_string (pp
, " /\\ ");
2858 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2862 pp_cxx_disjunction (cxx_pretty_printer
*pp
, tree t
)
2864 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2865 pp_string (pp
, " \\/ ");
2866 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2870 pp_cxx_constraint (cxx_pretty_printer
*pp
, tree t
)
2872 if (t
== error_mark_node
)
2873 return pp
->expression (t
);
2875 switch (TREE_CODE (t
))
2878 pp_cxx_atomic_constraint (pp
, t
);
2882 pp_cxx_check_constraint (pp
, t
);
2886 pp_cxx_conjunction (pp
, t
);
2890 pp_cxx_disjunction (pp
, t
);
2893 case EXPR_PACK_EXPANSION
:
2894 pp
->expression (TREE_OPERAND (t
, 0));
2903 typedef c_pretty_print_fn pp_fun
;
2905 /* Initialization of a C++ pretty-printer object. */
2907 cxx_pretty_printer::cxx_pretty_printer ()
2908 : c_pretty_printer (),
2909 enclosing_scope (global_namespace
)
2911 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2912 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;
2915 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2918 cxx_pretty_printer::clone () const
2920 return new cxx_pretty_printer (*this);