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 (TYPE_PTRDATAMEM_P (t
))
1426 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1427 pp_cxx_whitespace (pp
);
1428 pp_cxx_ptr_operator (pp
, t
);
1434 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1435 pp_c_specifier_qualifier_list (pp
, t
);
1440 * cv-qualifier-seq(opt)
1442 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1445 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1447 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1449 switch (TREE_CODE (t
))
1451 case REFERENCE_TYPE
:
1453 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1454 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1455 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1459 pp_cxx_cv_qualifier_seq (pp
, t
);
1466 if (TYPE_PTRMEMFUNC_P (t
))
1468 pp_cxx_left_paren (pp
);
1469 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1475 if (TYPE_PTRMEM_P (t
))
1477 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1478 pp_cxx_left_paren (pp
);
1479 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1481 pp_cxx_cv_qualifier_seq (pp
, t
);
1487 pp_unsupported_tree (pp
, t
);
1493 pp_cxx_implicit_parameter_type (tree mf
)
1495 return class_of_this_parm (TREE_TYPE (mf
));
1499 parameter-declaration:
1500 decl-specifier-seq declarator
1501 decl-specifier-seq declarator = assignment-expression
1502 decl-specifier-seq abstract-declarator(opt)
1503 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1506 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1508 pp
->declaration_specifiers (t
);
1510 pp
->abstract_declarator (t
);
1515 /* parameter-declaration-clause:
1516 parameter-declaration-list(opt) ...(opt)
1517 parameter-declaration-list , ...
1519 parameter-declaration-list:
1520 parameter-declaration
1521 parameter-declaration-list , parameter-declaration */
1524 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1530 // For a requires clause or the explicit printing of a parameter list
1531 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1532 // args and types are taken from the function decl T.
1533 if (TREE_CODE (t
) == PARM_DECL
)
1541 bool type_p
= TYPE_P (t
);
1542 args
= type_p
? NULL
: FUNCTION_FIRST_USER_PARM (t
);
1543 types
= type_p
? TYPE_ARG_TYPES (t
) : FUNCTION_FIRST_USER_PARMTYPE (t
);
1544 abstract
= args
== NULL
|| pp
->flags
& pp_c_flag_abstract
;
1548 /* Skip artificial parameter for non-static member functions. */
1549 if (TREE_CODE (t
) == METHOD_TYPE
)
1550 types
= TREE_CHAIN (types
);
1552 pp_cxx_left_paren (pp
);
1553 for (; args
; args
= TREE_CHAIN (args
), types
= TREE_CHAIN (types
))
1556 pp_cxx_separate_with (pp
, ',');
1558 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1559 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1561 pp_cxx_whitespace (pp
);
1563 pp_cxx_whitespace (pp
);
1564 pp
->assignment_expression (TREE_PURPOSE (types
));
1567 pp_cxx_right_paren (pp
);
1570 /* exception-specification:
1571 throw ( type-id-list(opt) )
1575 type-id-list , type-id */
1578 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1580 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1581 bool need_comma
= false;
1583 if (ex_spec
== NULL
)
1585 if (TREE_PURPOSE (ex_spec
))
1587 pp_cxx_ws_string (pp
, "noexcept");
1588 pp_cxx_whitespace (pp
);
1589 pp_cxx_left_paren (pp
);
1590 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1591 pp_cxx_ws_string (pp
, "<uninstantiated>");
1593 pp
->expression (TREE_PURPOSE (ex_spec
));
1594 pp_cxx_right_paren (pp
);
1597 pp_cxx_ws_string (pp
, "throw");
1598 pp_cxx_left_paren (pp
);
1599 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1601 tree type
= TREE_VALUE (ex_spec
);
1602 tree argpack
= NULL_TREE
;
1605 if (ARGUMENT_PACK_P (type
))
1607 argpack
= ARGUMENT_PACK_ARGS (type
);
1608 len
= TREE_VEC_LENGTH (argpack
);
1611 for (i
= 0; i
< len
; ++i
)
1614 type
= TREE_VEC_ELT (argpack
, i
);
1617 pp_cxx_separate_with (pp
, ',');
1624 pp_cxx_right_paren (pp
);
1627 /* direct-declarator:
1629 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1630 exception-specification(opt)
1631 direct-declaration [ constant-expression(opt) ]
1635 cxx_pretty_printer::direct_declarator (tree t
)
1637 switch (TREE_CODE (t
))
1645 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1647 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1648 || template_parameter_pack_p (t
))
1649 /* A function parameter pack or non-type template
1651 pp_cxx_ws_string (this, "...");
1653 id_expression (DECL_NAME (t
));
1655 abstract_declarator (TREE_TYPE (t
));
1659 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1661 pp_cxx_parameter_declaration_clause (this, t
);
1663 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1665 padding
= pp_before
;
1666 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1669 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1674 case TEMPLATE_TYPE_PARM
:
1675 case TEMPLATE_PARM_INDEX
:
1676 case TEMPLATE_TEMPLATE_PARM
:
1680 c_pretty_printer::direct_declarator (t
);
1687 ptr-operator declarator */
1690 cxx_pretty_printer::declarator (tree t
)
1692 direct_declarator (t
);
1694 // Print a requires clause.
1696 if (tree ci
= get_constraints (t
))
1697 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1698 pp_cxx_requires_clause (this, reqs
);
1701 /* ctor-initializer:
1702 : mem-initializer-list
1704 mem-initializer-list:
1706 mem-initializer , mem-initializer-list
1709 mem-initializer-id ( expression-list(opt) )
1712 ::(opt) nested-name-specifier(opt) class-name
1716 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1718 t
= TREE_OPERAND (t
, 0);
1719 pp_cxx_whitespace (pp
);
1721 pp_cxx_whitespace (pp
);
1722 for (; t
; t
= TREE_CHAIN (t
))
1724 tree purpose
= TREE_PURPOSE (t
);
1725 bool is_pack
= PACK_EXPANSION_P (purpose
);
1728 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1730 pp
->primary_expression (purpose
);
1731 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1733 pp_cxx_ws_string (pp
, "...");
1735 pp_cxx_separate_with (pp
, ',');
1739 /* function-definition:
1740 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1741 decl-specifier-seq(opt) declarator function-try-block */
1744 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1746 tree saved_scope
= pp
->enclosing_scope
;
1747 pp
->declaration_specifiers (t
);
1749 pp_needs_newline (pp
) = true;
1750 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1751 if (DECL_SAVED_TREE (t
))
1752 pp
->statement (DECL_SAVED_TREE (t
));
1754 pp_cxx_semicolon (pp
);
1755 pp_newline_and_flush (pp
);
1756 pp
->enclosing_scope
= saved_scope
;
1759 /* abstract-declarator:
1760 ptr-operator abstract-declarator(opt)
1761 direct-abstract-declarator */
1764 cxx_pretty_printer::abstract_declarator (tree t
)
1766 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1767 or a pointer-to-data-member of array type:
1772 but not for a pointer-to-data-member of non-array type:
1776 so be mindful of that. */
1777 if (TYPE_PTRMEMFUNC_P (t
)
1778 || (TYPE_PTRDATAMEM_P (t
)
1779 && TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
))
1780 pp_cxx_right_paren (this);
1781 else if (INDIRECT_TYPE_P (t
))
1783 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1784 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1785 pp_cxx_right_paren (this);
1788 direct_abstract_declarator (t
);
1791 /* direct-abstract-declarator:
1792 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1793 cv-qualifier-seq(opt) exception-specification(opt)
1794 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1795 ( abstract-declarator ) */
1798 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1800 switch (TREE_CODE (t
))
1802 case REFERENCE_TYPE
:
1803 abstract_declarator (t
);
1807 if (TYPE_PTRMEMFUNC_P (t
))
1808 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1812 if (TYPE_PTRDATAMEM_P (t
))
1813 direct_abstract_declarator (TREE_TYPE (t
));
1818 pp_cxx_parameter_declaration_clause (this, t
);
1819 direct_abstract_declarator (TREE_TYPE (t
));
1820 if (TREE_CODE (t
) == METHOD_TYPE
)
1822 padding
= pp_before
;
1823 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1825 pp_cxx_exception_specification (this, t
);
1829 case TEMPLATE_TYPE_PARM
:
1830 case TEMPLATE_TEMPLATE_PARM
:
1831 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1832 case UNBOUND_CLASS_TEMPLATE
:
1837 c_pretty_printer::direct_abstract_declarator (t
);
1843 type-specifier-seq abstract-declarator(opt) */
1846 cxx_pretty_printer::type_id (tree t
)
1848 pp_flags saved_flags
= flags
;
1849 flags
|= pp_c_flag_abstract
;
1851 switch (TREE_CODE (t
))
1858 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1859 case UNBOUND_CLASS_TEMPLATE
:
1860 case TEMPLATE_TEMPLATE_PARM
:
1861 case TEMPLATE_TYPE_PARM
:
1862 case TEMPLATE_PARM_INDEX
:
1865 case UNDERLYING_TYPE
:
1867 case TEMPLATE_ID_EXPR
:
1869 pp_cxx_type_specifier_seq (this, t
);
1870 if (TYPE_PTRMEM_P (t
))
1871 abstract_declarator (t
);
1874 case TYPE_PACK_EXPANSION
:
1875 type_id (PACK_EXPANSION_PATTERN (t
));
1876 pp_cxx_ws_string (this, "...");
1879 case TYPE_ARGUMENT_PACK
:
1881 tree args
= ARGUMENT_PACK_ARGS (t
);
1882 int len
= TREE_VEC_LENGTH (args
);
1883 pp_cxx_left_brace (this);
1884 for (int i
= 0; i
< len
; ++i
)
1887 pp_cxx_separate_with (this, ',');
1888 type_id (TREE_VEC_ELT (args
, i
));
1890 pp_cxx_right_brace (this);
1895 c_pretty_printer::type_id (t
);
1899 flags
= saved_flags
;
1902 /* template-argument-list:
1903 template-argument ...(opt)
1904 template-argument-list, template-argument ...(opt)
1907 assignment-expression
1912 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1915 bool need_comma
= false;
1919 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1921 tree arg
= TREE_VEC_ELT (t
, i
);
1922 tree argpack
= NULL_TREE
;
1925 if (ARGUMENT_PACK_P (arg
))
1927 argpack
= ARGUMENT_PACK_ARGS (arg
);
1928 len
= TREE_VEC_LENGTH (argpack
);
1931 for (idx
= 0; idx
< len
; idx
++)
1934 arg
= TREE_VEC_ELT (argpack
, idx
);
1937 pp_cxx_separate_with (pp
, ',');
1941 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1942 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1944 else if (template_parm_object_p (arg
))
1945 pp
->expression (DECL_INITIAL (arg
));
1947 pp
->expression (arg
);
1954 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1956 t
= DECL_EXPR_DECL (t
);
1957 pp_cxx_type_specifier_seq (pp
, t
);
1959 pp
->abstract_declarator (t
);
1967 cxx_pretty_printer::statement (tree t
)
1969 switch (TREE_CODE (t
))
1971 case CTOR_INITIALIZER
:
1972 pp_cxx_ctor_initializer (this, t
);
1976 pp_cxx_ws_string (this, "using");
1977 pp_cxx_ws_string (this, "namespace");
1978 if (DECL_CONTEXT (t
))
1979 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
1980 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
1984 pp_cxx_ws_string (this, "using");
1985 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
1986 pp_cxx_unqualified_id (this, DECL_NAME (t
));
1993 try compound-statement handler-seq */
1995 pp_maybe_newline_and_indent (this, 0);
1996 pp_cxx_ws_string (this, "try");
1997 pp_newline_and_indent (this, 3);
1998 statement (TRY_STMTS (t
));
1999 pp_newline_and_indent (this, -3);
2003 statement (TRY_HANDLERS (t
));
2008 handler handler-seq(opt)
2011 catch ( exception-declaration ) compound-statement
2013 exception-declaration:
2014 type-specifier-seq declarator
2015 type-specifier-seq abstract-declarator
2018 pp_cxx_ws_string (this, "catch");
2019 pp_cxx_left_paren (this);
2020 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
2021 pp_cxx_right_paren (this);
2022 pp_indentation (this) += 3;
2023 pp_needs_newline (this) = true;
2024 statement (HANDLER_BODY (t
));
2025 pp_indentation (this) -= 3;
2026 pp_needs_newline (this) = true;
2029 /* selection-statement:
2030 if ( expression ) statement
2031 if ( expression ) statement else statement */
2033 pp_cxx_ws_string (this, "if");
2034 pp_cxx_whitespace (this);
2035 pp_cxx_left_paren (this);
2036 expression (IF_COND (t
));
2037 pp_cxx_right_paren (this);
2038 pp_newline_and_indent (this, 2);
2039 statement (THEN_CLAUSE (t
));
2040 pp_newline_and_indent (this, -2);
2041 if (ELSE_CLAUSE (t
))
2043 tree else_clause
= ELSE_CLAUSE (t
);
2044 pp_cxx_ws_string (this, "else");
2045 if (TREE_CODE (else_clause
) == IF_STMT
)
2046 pp_cxx_whitespace (this);
2048 pp_newline_and_indent (this, 2);
2049 statement (else_clause
);
2050 if (TREE_CODE (else_clause
) != IF_STMT
)
2051 pp_newline_and_indent (this, -2);
2055 case RANGE_FOR_STMT
:
2056 pp_cxx_ws_string (this, "for");
2058 pp_cxx_left_paren (this);
2059 if (RANGE_FOR_INIT_STMT (t
))
2061 statement (RANGE_FOR_INIT_STMT (t
));
2062 pp_needs_newline (this) = false;
2063 pp_cxx_whitespace (this);
2065 statement (RANGE_FOR_DECL (t
));
2067 pp_needs_newline (this) = false;
2070 statement (RANGE_FOR_EXPR (t
));
2071 pp_cxx_right_paren (this);
2072 pp_newline_and_indent (this, 3);
2073 statement (FOR_BODY (t
));
2074 pp_indentation (this) -= 3;
2075 pp_needs_newline (this) = true;
2078 /* expression-statement:
2079 expression(opt) ; */
2081 expression (EXPR_STMT_EXPR (t
));
2082 pp_cxx_semicolon (this);
2083 pp_needs_newline (this) = true;
2087 pp_cxx_ws_string (this, "try");
2088 pp_newline_and_indent (this, 2);
2089 statement (CLEANUP_BODY (t
));
2090 pp_newline_and_indent (this, -2);
2091 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2092 pp_newline_and_indent (this, 2);
2093 statement (CLEANUP_EXPR (t
));
2094 pp_newline_and_indent (this, -2);
2102 pp_cxx_ws_string (this, "#pragma omp depobj");
2104 pp_cxx_left_paren (this);
2105 expression (OMP_DEPOBJ_DEPOBJ (t
));
2106 pp_cxx_right_paren (this);
2107 if (OMP_DEPOBJ_CLAUSES (t
) && OMP_DEPOBJ_CLAUSES (t
) != error_mark_node
)
2109 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t
)) == OMP_CLAUSE
)
2110 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t
),
2111 pp_indentation (this), TDF_NONE
);
2113 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t
)))
2115 case OMP_CLAUSE_DEPEND_IN
:
2116 pp_cxx_ws_string (this, " update(in)");
2118 case OMP_CLAUSE_DEPEND_INOUT
:
2119 pp_cxx_ws_string (this, " update(inout)");
2121 case OMP_CLAUSE_DEPEND_OUT
:
2122 pp_cxx_ws_string (this, " update(out)");
2124 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
2125 pp_cxx_ws_string (this, " update(mutexinoutset)");
2127 case OMP_CLAUSE_DEPEND_LAST
:
2128 pp_cxx_ws_string (this, " destroy");
2134 pp_needs_newline (this) = true;
2138 c_pretty_printer::statement (t
);
2143 /* original-namespace-definition:
2144 namespace identifier { namespace-body }
2146 As an edge case, we also handle unnamed namespace definition here. */
2149 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2151 pp_cxx_ws_string (pp
, "namespace");
2152 if (DECL_CONTEXT (t
))
2153 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2155 pp_cxx_unqualified_id (pp
, t
);
2156 pp_cxx_whitespace (pp
);
2157 pp_cxx_left_brace (pp
);
2158 /* We do not print the namespace-body. */
2159 pp_cxx_whitespace (pp
);
2160 pp_cxx_right_brace (pp
);
2166 namespace-alias-definition:
2167 namespace identifier = qualified-namespace-specifier ;
2169 qualified-namespace-specifier:
2170 ::(opt) nested-name-specifier(opt) namespace-name */
2173 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2175 pp_cxx_ws_string (pp
, "namespace");
2176 if (DECL_CONTEXT (t
))
2177 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2178 pp_cxx_unqualified_id (pp
, t
);
2179 pp_cxx_whitespace (pp
);
2181 pp_cxx_whitespace (pp
);
2182 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2183 pp_cxx_nested_name_specifier (pp
,
2184 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2185 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2186 pp_cxx_semicolon (pp
);
2189 /* simple-declaration:
2190 decl-specifier-seq(opt) init-declarator-list(opt) */
2193 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2195 pp
->declaration_specifiers (t
);
2196 pp_cxx_init_declarator (pp
, t
);
2197 pp_cxx_semicolon (pp
);
2198 pp_needs_newline (pp
) = true;
2202 template-parameter-list:
2204 template-parameter-list , template-parameter */
2207 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2209 const int n
= TREE_VEC_LENGTH (t
);
2211 for (i
= 0; i
< n
; ++i
)
2214 pp_cxx_separate_with (pp
, ',');
2215 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2219 /* template-parameter:
2221 parameter-declaration
2224 class ...(opt) identifier(opt)
2225 class identifier(opt) = type-id
2226 typename identifier(opt)
2227 typename ...(opt) identifier(opt) = type-id
2228 template < template-parameter-list > class ...(opt) identifier(opt)
2229 template < template-parameter-list > class identifier(opt) = template-name */
2232 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2234 tree parameter
= TREE_VALUE (t
);
2235 switch (TREE_CODE (parameter
))
2238 pp_cxx_ws_string (pp
, "class");
2239 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2240 pp_cxx_ws_string (pp
, "...");
2241 if (DECL_NAME (parameter
))
2242 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2243 /* FIXME: Check if we should print also default argument. */
2247 pp_cxx_parameter_declaration (pp
, parameter
);
2254 pp_unsupported_tree (pp
, t
);
2259 /* Pretty-print a template parameter in the canonical form
2260 "template-parameter-<level>-<position in parameter list>". */
2263 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2265 const enum tree_code code
= TREE_CODE (parm
);
2267 /* Brings type template parameters to the canonical forms. */
2268 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2269 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2270 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2272 pp_cxx_begin_template_argument_list (pp
);
2273 pp
->translate_string ("template-parameter-");
2274 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2276 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2277 pp_cxx_end_template_argument_list (pp
);
2280 /* Print a constrained-type-specifier. */
2283 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2285 pp_cxx_whitespace (pp
);
2286 pp_cxx_left_bracket (pp
);
2287 pp
->translate_string ("requires");
2288 pp_cxx_whitespace (pp
);
2289 if (c
== error_mark_node
)
2291 pp_cxx_ws_string(pp
, "<unsatisfied-type-constraint>");
2295 placeholder_extract_concept_and_args (c
, t
, a
);
2296 pp
->id_expression (t
);
2297 pp_cxx_begin_template_argument_list (pp
);
2298 pp_cxx_ws_string (pp
, "<placeholder>");
2299 pp_cxx_separate_with (pp
, ',');
2300 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2301 for (int i
= 0; i
< TREE_VEC_LENGTH (a
) - 1; ++i
)
2302 TREE_VEC_ELT (args
, i
) = TREE_VEC_ELT (a
, i
+ 1);
2303 pp_cxx_template_argument_list (pp
, args
);
2305 pp_cxx_end_template_argument_list (pp
);
2306 pp_cxx_right_bracket (pp
);
2310 template-declaration:
2311 export(opt) template < template-parameter-list > declaration
2315 template-declaration:
2316 export(opt) template < template-parameter-list >
2317 requires-clause(opt) declaration */
2320 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2322 tree tmpl
= most_general_template (t
);
2325 pp_maybe_newline_and_indent (pp
, 0);
2326 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2328 pp_cxx_ws_string (pp
, "template");
2329 pp_cxx_begin_template_argument_list (pp
);
2330 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2331 pp_cxx_end_template_argument_list (pp
);
2332 pp_newline_and_indent (pp
, 3);
2336 if (tree ci
= get_constraints (t
))
2337 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2339 pp_cxx_requires_clause (pp
, reqs
);
2340 pp_newline_and_indent (pp
, 6);
2343 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2344 pp_cxx_function_definition (pp
, t
);
2345 else if (TREE_CODE (t
) == CONCEPT_DECL
)
2346 pp_cxx_concept_definition (pp
, t
);
2348 pp_cxx_simple_declaration (pp
, t
);
2352 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2354 pp_unsupported_tree (pp
, t
);
2358 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2360 pp_unsupported_tree (pp
, t
);
2364 pp_cxx_concept_definition (cxx_pretty_printer
*pp
, tree t
)
2366 pp_cxx_unqualified_id (pp
, DECL_NAME (t
));
2367 pp_cxx_whitespace (pp
);
2368 pp_cxx_ws_string (pp
, "=");
2369 pp_cxx_whitespace (pp
);
2370 pp
->expression (DECL_INITIAL (t
));
2371 pp_cxx_semicolon (pp
);
2378 template-declaration
2379 explicit-instantiation
2380 explicit-specialization
2381 linkage-specification
2382 namespace-definition
2387 namespace-alias-definition
2390 static_assert-declaration */
2392 cxx_pretty_printer::declaration (tree t
)
2394 if (TREE_CODE (t
) == STATIC_ASSERT
)
2396 pp_cxx_ws_string (this, "static_assert");
2397 pp_cxx_left_paren (this);
2398 expression (STATIC_ASSERT_CONDITION (t
));
2399 pp_cxx_separate_with (this, ',');
2400 expression (STATIC_ASSERT_MESSAGE (t
));
2401 pp_cxx_right_paren (this);
2403 else if (!DECL_LANG_SPECIFIC (t
))
2404 pp_cxx_simple_declaration (this, t
);
2405 else if (DECL_USE_TEMPLATE (t
))
2406 switch (DECL_USE_TEMPLATE (t
))
2409 pp_cxx_template_declaration (this, t
);
2413 pp_cxx_explicit_specialization (this, t
);
2417 pp_cxx_explicit_instantiation (this, t
);
2423 else switch (TREE_CODE (t
))
2427 pp_cxx_simple_declaration (this, t
);
2431 if (DECL_SAVED_TREE (t
))
2432 pp_cxx_function_definition (this, t
);
2434 pp_cxx_simple_declaration (this, t
);
2437 case NAMESPACE_DECL
:
2438 if (DECL_NAMESPACE_ALIAS (t
))
2439 pp_cxx_namespace_alias_definition (this, t
);
2441 pp_cxx_original_namespace_definition (this, t
);
2445 pp_unsupported_tree (this, t
);
2451 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2453 t
= TREE_OPERAND (t
, 0);
2454 pp_cxx_ws_string (pp
, "typeid");
2455 pp_cxx_left_paren (pp
);
2460 pp_cxx_right_paren (pp
);
2464 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2466 pp_cxx_ws_string (pp
, "va_arg");
2467 pp_cxx_left_paren (pp
);
2468 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2469 pp_cxx_separate_with (pp
, ',');
2470 pp
->type_id (TREE_TYPE (t
));
2471 pp_cxx_right_paren (pp
);
2475 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2477 switch (TREE_CODE (t
))
2480 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2481 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2483 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2484 pp_cxx_separate_with (pp
, ',');
2489 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2491 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2493 pp
->expression (TREE_OPERAND (t
, 1));
2496 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2498 pp_left_bracket (pp
);
2499 pp
->expression (TREE_OPERAND (t
, 1));
2500 pp_right_bracket (pp
);
2508 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2510 pp_cxx_ws_string (pp
, "offsetof");
2511 pp_cxx_left_paren (pp
);
2512 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2513 pp
->expression (TREE_OPERAND (t
, 0));
2514 pp_cxx_right_paren (pp
);
2518 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2520 pp_cxx_ws_string (pp
, "__builtin_addressof");
2521 pp_cxx_left_paren (pp
);
2522 pp
->expression (TREE_OPERAND (t
, 0));
2523 pp_cxx_right_paren (pp
);
2527 get_fold_operator (tree t
)
2529 int op
= int_cst_value (FOLD_EXPR_OP (t
));
2530 ovl_op_info_t
*info
= OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t
), op
);
2535 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2537 char const* op
= get_fold_operator (t
);
2538 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2539 pp_cxx_left_paren (pp
);
2540 pp_cxx_ws_string (pp
, "...");
2541 pp_cxx_ws_string (pp
, op
);
2542 pp
->expression (expr
);
2543 pp_cxx_right_paren (pp
);
2547 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2549 char const* op
= get_fold_operator (t
);
2550 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2551 pp_cxx_left_paren (pp
);
2552 pp
->expression (expr
);
2554 pp_cxx_ws_string (pp
, op
);
2555 pp_cxx_ws_string (pp
, "...");
2556 pp_cxx_right_paren (pp
);
2560 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2562 char const* op
= get_fold_operator (t
);
2563 tree t1
= TREE_OPERAND (t
, 1);
2564 tree t2
= TREE_OPERAND (t
, 2);
2565 if (t1
== FOLD_EXPR_PACK (t
))
2566 t1
= PACK_EXPANSION_PATTERN (t1
);
2568 t2
= PACK_EXPANSION_PATTERN (t2
);
2569 pp_cxx_left_paren (pp
);
2570 pp
->expression (t1
);
2571 pp_cxx_ws_string (pp
, op
);
2572 pp_cxx_ws_string (pp
, "...");
2573 pp_cxx_ws_string (pp
, op
);
2574 pp
->expression (t2
);
2575 pp_cxx_right_paren (pp
);
2579 pp_cxx_trait_expression (cxx_pretty_printer
*pp
, tree t
)
2581 cp_trait_kind kind
= TRAIT_EXPR_KIND (t
);
2585 case CPTK_HAS_NOTHROW_ASSIGN
:
2586 pp_cxx_ws_string (pp
, "__has_nothrow_assign");
2588 case CPTK_HAS_TRIVIAL_ASSIGN
:
2589 pp_cxx_ws_string (pp
, "__has_trivial_assign");
2591 case CPTK_HAS_NOTHROW_CONSTRUCTOR
:
2592 pp_cxx_ws_string (pp
, "__has_nothrow_constructor");
2594 case CPTK_HAS_TRIVIAL_CONSTRUCTOR
:
2595 pp_cxx_ws_string (pp
, "__has_trivial_constructor");
2597 case CPTK_HAS_NOTHROW_COPY
:
2598 pp_cxx_ws_string (pp
, "__has_nothrow_copy");
2600 case CPTK_HAS_TRIVIAL_COPY
:
2601 pp_cxx_ws_string (pp
, "__has_trivial_copy");
2603 case CPTK_HAS_TRIVIAL_DESTRUCTOR
:
2604 pp_cxx_ws_string (pp
, "__has_trivial_destructor");
2606 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS
:
2607 pp_cxx_ws_string (pp
, "__has_unique_object_representations");
2609 case CPTK_HAS_VIRTUAL_DESTRUCTOR
:
2610 pp_cxx_ws_string (pp
, "__has_virtual_destructor");
2612 case CPTK_IS_ABSTRACT
:
2613 pp_cxx_ws_string (pp
, "__is_abstract");
2615 case CPTK_IS_AGGREGATE
:
2616 pp_cxx_ws_string (pp
, "__is_aggregate");
2618 case CPTK_IS_BASE_OF
:
2619 pp_cxx_ws_string (pp
, "__is_base_of");
2622 pp_cxx_ws_string (pp
, "__is_class");
2625 pp_cxx_ws_string (pp
, "__is_empty");
2628 pp_cxx_ws_string (pp
, "__is_enum");
2631 pp_cxx_ws_string (pp
, "__is_final");
2634 pp_cxx_ws_string (pp
, "__is_pod");
2636 case CPTK_IS_POLYMORPHIC
:
2637 pp_cxx_ws_string (pp
, "__is_polymorphic");
2639 case CPTK_IS_SAME_AS
:
2640 pp_cxx_ws_string (pp
, "__is_same");
2642 case CPTK_IS_STD_LAYOUT
:
2643 pp_cxx_ws_string (pp
, "__is_std_layout");
2645 case CPTK_IS_TRIVIAL
:
2646 pp_cxx_ws_string (pp
, "__is_trivial");
2648 case CPTK_IS_TRIVIALLY_ASSIGNABLE
:
2649 pp_cxx_ws_string (pp
, "__is_trivially_assignable");
2651 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE
:
2652 pp_cxx_ws_string (pp
, "__is_trivially_constructible");
2654 case CPTK_IS_TRIVIALLY_COPYABLE
:
2655 pp_cxx_ws_string (pp
, "__is_trivially_copyable");
2658 pp_cxx_ws_string (pp
, "__is_union");
2660 case CPTK_IS_LITERAL_TYPE
:
2661 pp_cxx_ws_string (pp
, "__is_literal_type");
2663 case CPTK_IS_ASSIGNABLE
:
2664 pp_cxx_ws_string (pp
, "__is_assignable");
2666 case CPTK_IS_CONSTRUCTIBLE
:
2667 pp_cxx_ws_string (pp
, "__is_constructible");
2674 pp_cxx_left_paren (pp
);
2675 pp
->type_id (TRAIT_EXPR_TYPE1 (t
));
2677 if (kind
== CPTK_IS_BASE_OF
|| kind
== CPTK_IS_SAME_AS
)
2679 pp_cxx_separate_with (pp
, ',');
2680 pp
->type_id (TRAIT_EXPR_TYPE2 (t
));
2683 pp_cxx_right_paren (pp
);
2687 // 'requires' logical-or-expression
2689 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2693 pp
->padding
= pp_before
;
2694 pp_cxx_ws_string (pp
, "requires");
2701 compound-requirement
2703 nested-requirement */
2705 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2707 switch (TREE_CODE (t
))
2710 pp_cxx_simple_requirement (pp
, t
);
2714 pp_cxx_type_requirement (pp
, t
);
2718 pp_cxx_compound_requirement (pp
, t
);
2722 pp_cxx_nested_requirement (pp
, t
);
2730 // requirement-list:
2732 // requirement-list ';' requirement[opt]
2735 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2737 for (; t
; t
= TREE_CHAIN (t
))
2738 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2741 // requirement-body:
2742 // '{' requirement-list '}'
2744 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2746 pp_cxx_left_brace (pp
);
2747 pp_cxx_requirement_list (pp
, t
);
2748 pp_cxx_right_brace (pp
);
2751 // requires-expression:
2752 // 'requires' requirement-parameter-list requirement-body
2754 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2756 pp_string (pp
, "requires");
2757 if (tree parms
= TREE_OPERAND (t
, 0))
2759 pp_cxx_parameter_declaration_clause (pp
, parms
);
2760 pp_cxx_whitespace (pp
);
2762 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2765 /* simple-requirement:
2768 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2770 pp
->expression (TREE_OPERAND (t
, 0));
2771 pp_cxx_semicolon (pp
);
2774 /* type-requirement:
2775 typename type-name ';' */
2777 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2779 pp
->type_id (TREE_OPERAND (t
, 0));
2780 pp_cxx_semicolon (pp
);
2783 /* compound-requirement:
2784 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2786 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2788 pp_cxx_left_brace (pp
);
2789 pp
->expression (TREE_OPERAND (t
, 0));
2790 pp_cxx_right_brace (pp
);
2792 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2793 pp_cxx_ws_string (pp
, "noexcept");
2795 if (tree type
= TREE_OPERAND (t
, 1))
2797 pp_cxx_whitespace (pp
);
2798 pp_cxx_ws_string (pp
, "->");
2801 pp_cxx_semicolon (pp
);
2804 /* nested requirement:
2805 'requires' constraint-expression */
2807 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2809 pp_cxx_ws_string (pp
, "requires");
2810 pp
->expression (TREE_OPERAND (t
, 0));
2811 pp_cxx_semicolon (pp
);
2815 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2817 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2818 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2819 tree args
= CHECK_CONSTR_ARGS (t
);
2820 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2822 if (TREE_CODE (decl
) == CONCEPT_DECL
)
2823 pp
->expression (id
);
2824 else if (VAR_P (decl
))
2825 pp
->expression (id
);
2826 else if (TREE_CODE (decl
) == FUNCTION_DECL
)
2828 tree call
= build_vl_exp (CALL_EXPR
, 2);
2829 TREE_OPERAND (call
, 0) = integer_two_node
;
2830 TREE_OPERAND (call
, 1) = id
;
2831 pp
->expression (call
);
2837 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2841 pp_cxx_parameter_mapping (cxx_pretty_printer
*pp
, tree map
)
2843 pp_cxx_whitespace (pp
);
2844 pp_cxx_left_bracket (pp
);
2845 pp
->translate_string ("with");
2846 pp_cxx_whitespace (pp
);
2848 for (tree p
= map
; p
; p
= TREE_CHAIN (p
))
2850 tree parm
= TREE_VALUE (p
);
2851 tree arg
= TREE_PURPOSE (p
);
2856 pp_cxx_tree_identifier (pp
, DECL_NAME (TEMPLATE_PARM_DECL (parm
)));
2858 pp_cxx_whitespace (pp
);
2860 pp_cxx_whitespace (pp
);
2862 if (TYPE_P (arg
) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg
))
2865 pp
->expression (arg
);
2867 if (TREE_CHAIN (p
) != NULL_TREE
)
2868 pp_cxx_separate_with (pp
, ';');
2871 pp_cxx_right_bracket (pp
);
2875 pp_cxx_atomic_constraint (cxx_pretty_printer
*pp
, tree t
)
2877 /* Emit the expression. */
2878 pp
->expression (ATOMIC_CONSTR_EXPR (t
));
2880 /* Emit the parameter mapping. */
2881 tree map
= ATOMIC_CONSTR_MAP (t
);
2882 if (map
&& map
!= error_mark_node
)
2883 pp_cxx_parameter_mapping (pp
, map
);
2887 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2889 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2890 pp_string (pp
, " /\\ ");
2891 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2895 pp_cxx_disjunction (cxx_pretty_printer
*pp
, tree t
)
2897 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2898 pp_string (pp
, " \\/ ");
2899 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2903 pp_cxx_constraint (cxx_pretty_printer
*pp
, tree t
)
2905 if (t
== error_mark_node
)
2906 return pp
->expression (t
);
2908 switch (TREE_CODE (t
))
2911 pp_cxx_atomic_constraint (pp
, t
);
2915 pp_cxx_check_constraint (pp
, t
);
2919 pp_cxx_conjunction (pp
, t
);
2923 pp_cxx_disjunction (pp
, t
);
2926 case EXPR_PACK_EXPANSION
:
2927 pp
->expression (TREE_OPERAND (t
, 0));
2936 typedef c_pretty_print_fn pp_fun
;
2938 /* Initialization of a C++ pretty-printer object. */
2940 cxx_pretty_printer::cxx_pretty_printer ()
2941 : c_pretty_printer (),
2942 enclosing_scope (global_namespace
)
2944 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2945 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;
2948 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2951 cxx_pretty_printer::clone () const
2953 return new cxx_pretty_printer (*this);