1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2022 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 (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);
659 pp_cxx_ws_string (this, "__builtin_bit_cast");
660 pp_left_paren (this);
661 type_id (TREE_TYPE (t
));
663 expression (TREE_OPERAND (t
, 0));
664 pp_right_paren (this);
667 case EMPTY_CLASS_EXPR
:
668 type_id (TREE_TYPE (t
));
669 pp_left_paren (this);
670 pp_right_paren (this);
674 pp_cxx_typeid_expression (this, t
);
677 case PSEUDO_DTOR_EXPR
:
678 postfix_expression (TREE_OPERAND (t
, 0));
680 if (TREE_OPERAND (t
, 1))
682 pp_cxx_qualified_id (this, TREE_OPERAND (t
, 1));
683 pp_cxx_colon_colon (this);
685 pp_complement (this);
686 pp_cxx_unqualified_id (this, TREE_OPERAND (t
, 2));
690 postfix_expression (TREE_OPERAND (t
, 0));
695 c_pretty_printer::postfix_expression (t
);
701 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
702 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
708 type-specifier-seq new-declarator(opt)
711 ptr-operator new-declarator(opt)
712 direct-new-declarator
714 direct-new-declarator
716 direct-new-declarator [ constant-expression ]
719 ( expression-list(opt) ) */
722 pp_cxx_new_expression (cxx_pretty_printer
*pp
, tree t
)
724 enum tree_code code
= TREE_CODE (t
);
725 tree type
= TREE_OPERAND (t
, 1);
726 tree init
= TREE_OPERAND (t
, 2);
731 if (NEW_EXPR_USE_GLOBAL (t
))
732 pp_cxx_colon_colon (pp
);
733 pp_cxx_ws_string (pp
, "new");
734 if (TREE_OPERAND (t
, 0))
736 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
739 if (TREE_CODE (type
) == ARRAY_REF
)
740 type
= build_cplus_array_type
741 (TREE_OPERAND (type
, 0),
742 build_index_type (fold_build2_loc (input_location
,
743 MINUS_EXPR
, integer_type_node
,
744 TREE_OPERAND (type
, 1),
750 if (TREE_CODE (init
) == TREE_LIST
)
751 pp_c_expression_list (pp
, init
);
752 else if (init
== void_node
)
753 ; /* OK, empty initializer list. */
755 pp
->expression (init
);
761 pp_unsupported_tree (pp
, t
);
765 /* delete-expression:
766 ::(opt) delete cast-expression
767 ::(opt) delete [ ] cast-expression */
770 pp_cxx_delete_expression (cxx_pretty_printer
*pp
, tree t
)
772 enum tree_code code
= TREE_CODE (t
);
776 case VEC_DELETE_EXPR
:
777 if (DELETE_EXPR_USE_GLOBAL (t
))
778 pp_cxx_colon_colon (pp
);
779 pp_cxx_ws_string (pp
, "delete");
781 if (code
== VEC_DELETE_EXPR
782 || DELETE_EXPR_USE_VEC (t
))
784 pp_left_bracket (pp
);
785 pp_right_bracket (pp
);
788 pp_c_cast_expression (pp
, TREE_OPERAND (t
, 0));
792 pp_unsupported_tree (pp
, t
);
800 unary-operator cast-expression
801 sizeof unary-expression
803 sizeof ... ( identifier )
807 unary-operator: one of
811 __alignof__ unary-expression
812 __alignof__ ( type-id ) */
815 cxx_pretty_printer::unary_expression (tree t
)
817 enum tree_code code
= TREE_CODE (t
);
822 pp_cxx_new_expression (this, t
);
826 case VEC_DELETE_EXPR
:
827 pp_cxx_delete_expression (this, t
);
831 if (PACK_EXPANSION_P (TREE_OPERAND (t
, 0)))
833 pp_cxx_ws_string (this, "sizeof");
834 pp_cxx_ws_string (this, "...");
835 pp_cxx_whitespace (this);
836 pp_cxx_left_paren (this);
837 if (TYPE_P (TREE_OPERAND (t
, 0)))
838 type_id (TREE_OPERAND (t
, 0));
840 unary_expression (TREE_OPERAND (t
, 0));
841 pp_cxx_right_paren (this);
847 pp_cxx_ws_string (this, code
== SIZEOF_EXPR
? "sizeof" : "__alignof__");
848 pp_cxx_whitespace (this);
849 if (TREE_CODE (t
) == SIZEOF_EXPR
&& SIZEOF_EXPR_TYPE_P (t
))
851 pp_cxx_left_paren (this);
852 type_id (TREE_TYPE (TREE_OPERAND (t
, 0)));
853 pp_cxx_right_paren (this);
855 else if (TYPE_P (TREE_OPERAND (t
, 0)))
857 pp_cxx_left_paren (this);
858 type_id (TREE_OPERAND (t
, 0));
859 pp_cxx_right_paren (this);
862 unary_expression (TREE_OPERAND (t
, 0));
866 pp_cxx_ws_string (this, "@encode");
867 pp_cxx_whitespace (this);
868 pp_cxx_left_paren (this);
869 type_id (TREE_OPERAND (t
, 0));
870 pp_cxx_right_paren (this);
874 pp_cxx_ws_string (this, "noexcept");
875 pp_cxx_whitespace (this);
876 pp_cxx_left_paren (this);
877 expression (TREE_OPERAND (t
, 0));
878 pp_cxx_right_paren (this);
881 case UNARY_PLUS_EXPR
:
883 pp_cxx_cast_expression (this, TREE_OPERAND (t
, 0));
887 c_pretty_printer::unary_expression (t
);
894 ( type-id ) cast-expression */
897 pp_cxx_cast_expression (cxx_pretty_printer
*pp
, tree t
)
899 switch (TREE_CODE (t
))
902 case IMPLICIT_CONV_EXPR
:
903 pp
->type_id (TREE_TYPE (t
));
904 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
908 pp_c_cast_expression (pp
, t
);
915 pm-expression .* cast-expression
916 pm-expression ->* cast-expression */
919 pp_cxx_pm_expression (cxx_pretty_printer
*pp
, tree t
)
921 switch (TREE_CODE (t
))
923 /* Handle unfortunate OFFSET_REF overloading here. */
925 if (TYPE_P (TREE_OPERAND (t
, 0)))
927 pp_cxx_qualified_id (pp
, t
);
933 pp_cxx_pm_expression (pp
, TREE_OPERAND (t
, 0));
934 if (TREE_CODE (t
) == MEMBER_REF
)
939 pp_cxx_cast_expression (pp
, TREE_OPERAND (t
, 1));
944 pp_cxx_cast_expression (pp
, t
);
949 /* multiplicative-expression:
951 multiplicative-expression * pm-expression
952 multiplicative-expression / pm-expression
953 multiplicative-expression % pm-expression */
956 cxx_pretty_printer::multiplicative_expression (tree e
)
958 enum tree_code code
= TREE_CODE (e
);
966 multiplicative_expression (TREE_OPERAND (e
, 0));
968 if (code
== MULT_EXPR
)
970 else if (code
!= TRUNC_MOD_EXPR
)
975 pp_cxx_pm_expression (this, TREE_OPERAND (e
, 1));
979 pp_cxx_pm_expression (this, e
);
984 /* conditional-expression:
985 logical-or-expression
986 logical-or-expression ? expression : assignment-expression */
989 cxx_pretty_printer::conditional_expression (tree e
)
991 if (TREE_CODE (e
) == COND_EXPR
)
993 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
997 expression (TREE_OPERAND (e
, 1));
999 assignment_expression (TREE_OPERAND (e
, 2));
1002 pp_c_logical_or_expression (this, e
);
1005 /* Pretty-print a compound assignment operator token as indicated by T. */
1008 pp_cxx_assignment_operator (cxx_pretty_printer
*pp
, tree t
)
1012 switch (TREE_CODE (t
))
1026 case TRUNC_DIV_EXPR
:
1030 case TRUNC_MOD_EXPR
:
1035 op
= get_tree_code_name (TREE_CODE (t
));
1039 pp_cxx_ws_string (pp
, op
);
1043 /* assignment-expression:
1044 conditional-expression
1045 logical-or-expression assignment-operator assignment-expression
1049 throw assignment-expression(opt)
1051 assignment-operator: one of
1052 = *= /= %= += -= >>= <<= &= ^= |= */
1055 cxx_pretty_printer::assignment_expression (tree e
)
1057 switch (TREE_CODE (e
))
1061 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1065 assignment_expression (TREE_OPERAND (e
, 1));
1069 pp_cxx_ws_string (this, "throw");
1070 if (TREE_OPERAND (e
, 0))
1071 assignment_expression (TREE_OPERAND (e
, 0));
1075 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1076 pp_cxx_assignment_operator (this, TREE_OPERAND (e
, 1));
1077 assignment_expression (TREE_OPERAND (e
, 2));
1081 conditional_expression (e
);
1087 cxx_pretty_printer::expression (tree t
)
1089 switch (TREE_CODE (t
))
1099 case USERDEF_LITERAL
:
1100 pp_cxx_userdef_literal (this, t
);
1104 pp_cxx_unqualified_id (this, t
);
1112 pp_cxx_qualified_id (this, t
);
1125 case TEMPLATE_TYPE_PARM
:
1126 case TEMPLATE_PARM_INDEX
:
1127 case TEMPLATE_TEMPLATE_PARM
:
1130 primary_expression (t
);
1134 case DYNAMIC_CAST_EXPR
:
1135 case STATIC_CAST_EXPR
:
1136 case REINTERPRET_CAST_EXPR
:
1137 case CONST_CAST_EXPR
:
1141 case EMPTY_CLASS_EXPR
:
1143 case PSEUDO_DTOR_EXPR
:
1144 case AGGR_INIT_EXPR
:
1146 postfix_expression (t
);
1151 pp_cxx_new_expression (this, t
);
1155 case VEC_DELETE_EXPR
:
1156 pp_cxx_delete_expression (this, t
);
1162 case UNARY_PLUS_EXPR
:
1163 unary_expression (t
);
1167 case IMPLICIT_CONV_EXPR
:
1168 pp_cxx_cast_expression (this, t
);
1174 pp_cxx_pm_expression (this, t
);
1178 case TRUNC_DIV_EXPR
:
1179 case TRUNC_MOD_EXPR
:
1180 case EXACT_DIV_EXPR
:
1182 multiplicative_expression (t
);
1186 conditional_expression (t
);
1193 assignment_expression (t
);
1196 case NON_DEPENDENT_EXPR
:
1197 case MUST_NOT_THROW_EXPR
:
1198 expression (TREE_OPERAND (t
, 0));
1201 case EXPR_PACK_EXPANSION
:
1202 expression (PACK_EXPANSION_PATTERN (t
));
1203 pp_cxx_ws_string (this, "...");
1206 case UNARY_LEFT_FOLD_EXPR
:
1207 pp_cxx_unary_left_fold_expression (this, t
);
1210 case UNARY_RIGHT_FOLD_EXPR
:
1211 pp_cxx_unary_right_fold_expression (this, t
);
1214 case BINARY_LEFT_FOLD_EXPR
:
1215 case BINARY_RIGHT_FOLD_EXPR
:
1216 pp_cxx_binary_fold_expression (this, t
);
1219 case TEMPLATE_ID_EXPR
:
1220 pp_cxx_template_id (this, t
);
1223 case NONTYPE_ARGUMENT_PACK
:
1225 tree args
= ARGUMENT_PACK_ARGS (t
);
1226 int i
, len
= TREE_VEC_LENGTH (args
);
1227 pp_cxx_left_brace (this);
1228 for (i
= 0; i
< len
; ++i
)
1231 pp_cxx_separate_with (this, ',');
1232 expression (TREE_VEC_ELT (args
, i
));
1234 pp_cxx_right_brace (this);
1239 pp_cxx_ws_string (this, "<lambda>");
1243 pp_cxx_trait (this, t
);
1250 pp_cxx_constraint (this, t
);
1254 pp_cxx_left_paren (this);
1255 expression (TREE_OPERAND (t
, 0));
1256 pp_cxx_right_paren (this);
1260 c_pretty_printer::expression (t
);
1268 /* function-specifier:
1274 cxx_pretty_printer::function_specifier (tree t
)
1276 switch (TREE_CODE (t
))
1279 if (DECL_VIRTUAL_P (t
))
1280 pp_cxx_ws_string (this, "virtual");
1281 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
1282 pp_cxx_ws_string (this, "explicit");
1284 c_pretty_printer::function_specifier (t
);
1291 /* decl-specifier-seq:
1292 decl-specifier-seq(opt) decl-specifier
1295 storage-class-specifier
1302 cxx_pretty_printer::declaration_specifiers (tree t
)
1304 switch (TREE_CODE (t
))
1310 storage_class_specifier (t
);
1311 declaration_specifiers (TREE_TYPE (t
));
1315 pp_cxx_ws_string (this, "typedef");
1316 declaration_specifiers (TREE_TYPE (t
));
1320 /* Constructors don't have return types. And conversion functions
1321 do not have a type-specifier in their return types. */
1322 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
1323 function_specifier (t
);
1324 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1325 declaration_specifiers (TREE_TYPE (TREE_TYPE (t
)));
1327 c_pretty_printer::declaration_specifiers (t
);
1330 c_pretty_printer::declaration_specifiers (t
);
1335 /* simple-type-specifier:
1336 ::(opt) nested-name-specifier(opt) type-name
1337 ::(opt) nested-name-specifier(opt) template(opt) template-id
1352 cxx_pretty_printer::simple_type_specifier (tree t
)
1354 switch (TREE_CODE (t
))
1359 pp_cxx_qualified_id (this, t
);
1362 case TEMPLATE_TYPE_PARM
:
1363 case TEMPLATE_TEMPLATE_PARM
:
1364 case TEMPLATE_PARM_INDEX
:
1365 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1366 pp_cxx_unqualified_id (this, t
);
1367 if (tree c
= PLACEHOLDER_TYPE_CONSTRAINTS (t
))
1368 pp_cxx_constrained_type_spec (this, c
);
1372 pp_cxx_ws_string (this, "typename");
1373 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t
));
1374 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t
));
1378 pp_cxx_ws_string (this, "decltype");
1379 pp_cxx_left_paren (this);
1380 this->expression (DECLTYPE_TYPE_EXPR (t
));
1381 pp_cxx_right_paren (this);
1385 pp_cxx_ws_string (this, "std::nullptr_t");
1389 pp_cxx_trait (this, t
);
1393 c_pretty_printer::simple_type_specifier (t
);
1398 /* type-specifier-seq:
1399 type-specifier type-specifier-seq(opt)
1402 simple-type-specifier
1405 elaborated-type-specifier
1409 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1411 switch (TREE_CODE (t
))
1414 case TEMPLATE_TYPE_PARM
:
1415 case TEMPLATE_TEMPLATE_PARM
:
1417 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1420 pp_cxx_cv_qualifier_seq (pp
, t
);
1421 pp
->simple_type_specifier (t
);
1425 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1426 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1427 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1431 if (TYPE_PTRMEMFUNC_P (t
))
1433 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
1434 pp
->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm
)));
1435 pp_cxx_whitespace (pp
);
1436 pp_cxx_ptr_operator (pp
, t
);
1442 if (TYPE_PTRDATAMEM_P (t
))
1444 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1445 pp_cxx_whitespace (pp
);
1446 pp_cxx_ptr_operator (pp
, t
);
1452 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1453 pp_c_specifier_qualifier_list (pp
, t
);
1458 * cv-qualifier-seq(opt)
1460 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1463 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1465 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1467 switch (TREE_CODE (t
))
1469 case REFERENCE_TYPE
:
1471 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1472 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1473 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1477 pp_cxx_cv_qualifier_seq (pp
, t
);
1484 if (TYPE_PTRMEMFUNC_P (t
))
1486 pp_cxx_left_paren (pp
);
1487 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1493 if (TYPE_PTRMEM_P (t
))
1495 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1496 pp_cxx_left_paren (pp
);
1497 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1499 pp_cxx_cv_qualifier_seq (pp
, t
);
1505 pp_unsupported_tree (pp
, t
);
1511 pp_cxx_implicit_parameter_type (tree mf
)
1513 return class_of_this_parm (TREE_TYPE (mf
));
1517 parameter-declaration:
1518 decl-specifier-seq declarator
1519 decl-specifier-seq declarator = assignment-expression
1520 decl-specifier-seq abstract-declarator(opt)
1521 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1524 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1526 pp
->declaration_specifiers (t
);
1528 pp
->abstract_declarator (t
);
1533 /* parameter-declaration-clause:
1534 parameter-declaration-list(opt) ...(opt)
1535 parameter-declaration-list , ...
1537 parameter-declaration-list:
1538 parameter-declaration
1539 parameter-declaration-list , parameter-declaration */
1542 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1544 gcc_assert (FUNC_OR_METHOD_TYPE_P (t
) || TREE_CODE (t
) == FUNCTION_DECL
);
1548 types
= TYPE_ARG_TYPES (t
);
1553 types
= FUNCTION_FIRST_USER_PARMTYPE (t
);
1554 args
= FUNCTION_FIRST_USER_PARM (t
);
1556 bool abstract
= !args
|| (pp
->flags
& pp_c_flag_abstract
);
1558 /* Skip artificial parameter for non-static member functions. */
1559 if (TREE_CODE (t
) == METHOD_TYPE
)
1560 types
= TREE_CHAIN (types
);
1563 pp_cxx_left_paren (pp
);
1564 for (; types
!= void_list_node
; types
= TREE_CHAIN (types
))
1567 pp_cxx_separate_with (pp
, ',');
1571 pp_cxx_ws_string (pp
, "...");
1574 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1575 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1577 pp_cxx_whitespace (pp
);
1579 pp_cxx_whitespace (pp
);
1580 pp
->assignment_expression (TREE_PURPOSE (types
));
1583 args
= TREE_CHAIN (args
);
1585 pp_cxx_right_paren (pp
);
1588 /* exception-specification:
1589 throw ( type-id-list(opt) )
1593 type-id-list , type-id */
1596 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1598 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1599 bool need_comma
= false;
1601 if (ex_spec
== NULL
)
1603 if (TREE_PURPOSE (ex_spec
))
1605 pp_cxx_ws_string (pp
, "noexcept");
1606 pp_cxx_whitespace (pp
);
1607 pp_cxx_left_paren (pp
);
1608 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1609 pp_cxx_ws_string (pp
, "<uninstantiated>");
1611 pp
->expression (TREE_PURPOSE (ex_spec
));
1612 pp_cxx_right_paren (pp
);
1615 pp_cxx_ws_string (pp
, "throw");
1616 pp_cxx_left_paren (pp
);
1617 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1619 tree type
= TREE_VALUE (ex_spec
);
1620 tree argpack
= NULL_TREE
;
1623 if (ARGUMENT_PACK_P (type
))
1625 argpack
= ARGUMENT_PACK_ARGS (type
);
1626 len
= TREE_VEC_LENGTH (argpack
);
1629 for (i
= 0; i
< len
; ++i
)
1632 type
= TREE_VEC_ELT (argpack
, i
);
1635 pp_cxx_separate_with (pp
, ',');
1642 pp_cxx_right_paren (pp
);
1645 /* direct-declarator:
1647 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1648 exception-specification(opt)
1649 direct-declaration [ constant-expression(opt) ]
1653 cxx_pretty_printer::direct_declarator (tree t
)
1655 switch (TREE_CODE (t
))
1663 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1665 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1666 || template_parameter_pack_p (t
))
1667 /* A function parameter pack or non-type template
1669 pp_cxx_ws_string (this, "...");
1671 id_expression (DECL_NAME (t
));
1673 abstract_declarator (TREE_TYPE (t
));
1677 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1679 pp_cxx_parameter_declaration_clause (this, t
);
1681 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1683 padding
= pp_before
;
1684 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1687 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1692 case TEMPLATE_TYPE_PARM
:
1693 case TEMPLATE_PARM_INDEX
:
1694 case TEMPLATE_TEMPLATE_PARM
:
1698 c_pretty_printer::direct_declarator (t
);
1705 ptr-operator declarator */
1708 cxx_pretty_printer::declarator (tree t
)
1710 direct_declarator (t
);
1712 // Print a requires clause.
1714 if (tree ci
= get_constraints (t
))
1715 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1716 pp_cxx_requires_clause (this, reqs
);
1719 /* ctor-initializer:
1720 : mem-initializer-list
1722 mem-initializer-list:
1724 mem-initializer , mem-initializer-list
1727 mem-initializer-id ( expression-list(opt) )
1730 ::(opt) nested-name-specifier(opt) class-name
1734 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1736 t
= TREE_OPERAND (t
, 0);
1737 pp_cxx_whitespace (pp
);
1739 pp_cxx_whitespace (pp
);
1740 for (; t
; t
= TREE_CHAIN (t
))
1742 tree purpose
= TREE_PURPOSE (t
);
1743 bool is_pack
= PACK_EXPANSION_P (purpose
);
1746 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1748 pp
->primary_expression (purpose
);
1749 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1751 pp_cxx_ws_string (pp
, "...");
1753 pp_cxx_separate_with (pp
, ',');
1757 /* function-definition:
1758 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1759 decl-specifier-seq(opt) declarator function-try-block */
1762 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1764 tree saved_scope
= pp
->enclosing_scope
;
1765 pp
->declaration_specifiers (t
);
1767 pp_needs_newline (pp
) = true;
1768 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1769 if (DECL_SAVED_TREE (t
))
1770 pp
->statement (DECL_SAVED_TREE (t
));
1772 pp_cxx_semicolon (pp
);
1773 pp_newline_and_flush (pp
);
1774 pp
->enclosing_scope
= saved_scope
;
1777 /* abstract-declarator:
1778 ptr-operator abstract-declarator(opt)
1779 direct-abstract-declarator */
1782 cxx_pretty_printer::abstract_declarator (tree t
)
1784 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1785 or a pointer-to-data-member of array type:
1790 but not for a pointer-to-data-member of non-array type:
1794 so be mindful of that. */
1795 if (TYPE_PTRMEMFUNC_P (t
)
1796 || (TYPE_PTRDATAMEM_P (t
)
1797 && TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
))
1798 pp_cxx_right_paren (this);
1799 else if (INDIRECT_TYPE_P (t
))
1801 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1802 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1803 pp_cxx_right_paren (this);
1806 direct_abstract_declarator (t
);
1809 /* direct-abstract-declarator:
1810 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1811 cv-qualifier-seq(opt) exception-specification(opt)
1812 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1813 ( abstract-declarator ) */
1816 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1818 switch (TREE_CODE (t
))
1820 case REFERENCE_TYPE
:
1821 abstract_declarator (t
);
1825 if (TYPE_PTRMEMFUNC_P (t
))
1826 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1830 if (TYPE_PTRDATAMEM_P (t
))
1831 direct_abstract_declarator (TREE_TYPE (t
));
1836 pp_cxx_parameter_declaration_clause (this, t
);
1837 direct_abstract_declarator (TREE_TYPE (t
));
1838 if (TREE_CODE (t
) == METHOD_TYPE
)
1840 padding
= pp_before
;
1841 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1843 pp_cxx_exception_specification (this, t
);
1847 case TEMPLATE_TYPE_PARM
:
1848 case TEMPLATE_TEMPLATE_PARM
:
1849 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1850 case UNBOUND_CLASS_TEMPLATE
:
1855 c_pretty_printer::direct_abstract_declarator (t
);
1861 type-specifier-seq abstract-declarator(opt) */
1864 cxx_pretty_printer::type_id (tree t
)
1866 pp_flags saved_flags
= flags
;
1867 flags
|= pp_c_flag_abstract
;
1869 switch (TREE_CODE (t
))
1876 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1877 case UNBOUND_CLASS_TEMPLATE
:
1878 case TEMPLATE_TEMPLATE_PARM
:
1879 case TEMPLATE_TYPE_PARM
:
1880 case TEMPLATE_PARM_INDEX
:
1886 case TEMPLATE_ID_EXPR
:
1888 pp_cxx_type_specifier_seq (this, t
);
1889 if (TYPE_PTRMEM_P (t
))
1890 abstract_declarator (t
);
1893 case TYPE_PACK_EXPANSION
:
1894 type_id (PACK_EXPANSION_PATTERN (t
));
1895 pp_cxx_ws_string (this, "...");
1898 case TYPE_ARGUMENT_PACK
:
1900 tree args
= ARGUMENT_PACK_ARGS (t
);
1901 int len
= TREE_VEC_LENGTH (args
);
1902 pp_cxx_left_brace (this);
1903 for (int i
= 0; i
< len
; ++i
)
1906 pp_cxx_separate_with (this, ',');
1907 type_id (TREE_VEC_ELT (args
, i
));
1909 pp_cxx_right_brace (this);
1914 c_pretty_printer::type_id (t
);
1918 flags
= saved_flags
;
1921 /* template-argument-list:
1922 template-argument ...(opt)
1923 template-argument-list, template-argument ...(opt)
1926 assignment-expression
1931 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1934 bool need_comma
= false;
1938 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1940 tree arg
= TREE_VEC_ELT (t
, i
);
1941 tree argpack
= NULL_TREE
;
1944 if (ARGUMENT_PACK_P (arg
))
1946 argpack
= ARGUMENT_PACK_ARGS (arg
);
1947 len
= TREE_VEC_LENGTH (argpack
);
1950 for (idx
= 0; idx
< len
; idx
++)
1953 arg
= TREE_VEC_ELT (argpack
, idx
);
1956 pp_cxx_separate_with (pp
, ',');
1960 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1961 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1963 else if (TREE_CODE (arg
) == VAR_DECL
&& DECL_NTTP_OBJECT_P (arg
))
1964 pp
->expression (DECL_INITIAL (arg
));
1966 pp
->expression (arg
);
1973 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1975 t
= DECL_EXPR_DECL (t
);
1976 pp_cxx_type_specifier_seq (pp
, t
);
1978 pp
->abstract_declarator (t
);
1986 cxx_pretty_printer::statement (tree t
)
1988 switch (TREE_CODE (t
))
1990 case CTOR_INITIALIZER
:
1991 pp_cxx_ctor_initializer (this, t
);
1995 pp_cxx_ws_string (this, "using");
1996 pp_cxx_ws_string (this, "namespace");
1997 if (DECL_CONTEXT (t
))
1998 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
1999 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
2003 pp_cxx_ws_string (this, "using");
2004 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
2005 pp_cxx_unqualified_id (this, DECL_NAME (t
));
2012 try compound-statement handler-seq */
2014 pp_maybe_newline_and_indent (this, 0);
2015 pp_cxx_ws_string (this, "try");
2016 pp_newline_and_indent (this, 3);
2017 statement (TRY_STMTS (t
));
2018 pp_newline_and_indent (this, -3);
2022 statement (TRY_HANDLERS (t
));
2027 handler handler-seq(opt)
2030 catch ( exception-declaration ) compound-statement
2032 exception-declaration:
2033 type-specifier-seq declarator
2034 type-specifier-seq abstract-declarator
2037 pp_cxx_ws_string (this, "catch");
2038 pp_cxx_left_paren (this);
2039 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
2040 pp_cxx_right_paren (this);
2041 pp_indentation (this) += 3;
2042 pp_needs_newline (this) = true;
2043 statement (HANDLER_BODY (t
));
2044 pp_indentation (this) -= 3;
2045 pp_needs_newline (this) = true;
2048 /* selection-statement:
2049 if ( expression ) statement
2050 if ( expression ) statement else statement */
2052 pp_cxx_ws_string (this, "if");
2053 pp_cxx_whitespace (this);
2054 pp_cxx_left_paren (this);
2055 expression (IF_COND (t
));
2056 pp_cxx_right_paren (this);
2057 pp_newline_and_indent (this, 2);
2058 statement (THEN_CLAUSE (t
));
2059 pp_newline_and_indent (this, -2);
2060 if (ELSE_CLAUSE (t
))
2062 tree else_clause
= ELSE_CLAUSE (t
);
2063 pp_cxx_ws_string (this, "else");
2064 if (TREE_CODE (else_clause
) == IF_STMT
)
2065 pp_cxx_whitespace (this);
2067 pp_newline_and_indent (this, 2);
2068 statement (else_clause
);
2069 if (TREE_CODE (else_clause
) != IF_STMT
)
2070 pp_newline_and_indent (this, -2);
2074 case RANGE_FOR_STMT
:
2075 pp_cxx_ws_string (this, "for");
2077 pp_cxx_left_paren (this);
2078 if (RANGE_FOR_INIT_STMT (t
))
2080 statement (RANGE_FOR_INIT_STMT (t
));
2081 pp_needs_newline (this) = false;
2082 pp_cxx_whitespace (this);
2084 statement (RANGE_FOR_DECL (t
));
2086 pp_needs_newline (this) = false;
2089 statement (RANGE_FOR_EXPR (t
));
2090 pp_cxx_right_paren (this);
2091 pp_newline_and_indent (this, 3);
2092 statement (FOR_BODY (t
));
2093 pp_indentation (this) -= 3;
2094 pp_needs_newline (this) = true;
2097 /* expression-statement:
2098 expression(opt) ; */
2100 expression (EXPR_STMT_EXPR (t
));
2101 pp_cxx_semicolon (this);
2102 pp_needs_newline (this) = true;
2106 pp_cxx_ws_string (this, "try");
2107 pp_newline_and_indent (this, 2);
2108 statement (CLEANUP_BODY (t
));
2109 pp_newline_and_indent (this, -2);
2110 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2111 pp_newline_and_indent (this, 2);
2112 statement (CLEANUP_EXPR (t
));
2113 pp_newline_and_indent (this, -2);
2121 pp_cxx_ws_string (this, "#pragma omp depobj");
2123 pp_cxx_left_paren (this);
2124 expression (OMP_DEPOBJ_DEPOBJ (t
));
2125 pp_cxx_right_paren (this);
2126 if (OMP_DEPOBJ_CLAUSES (t
) && OMP_DEPOBJ_CLAUSES (t
) != error_mark_node
)
2128 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t
)) == OMP_CLAUSE
)
2129 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t
),
2130 pp_indentation (this), TDF_NONE
);
2132 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t
)))
2134 case OMP_CLAUSE_DEPEND_IN
:
2135 pp_cxx_ws_string (this, " update(in)");
2137 case OMP_CLAUSE_DEPEND_INOUT
:
2138 pp_cxx_ws_string (this, " update(inout)");
2140 case OMP_CLAUSE_DEPEND_OUT
:
2141 pp_cxx_ws_string (this, " update(out)");
2143 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
2144 pp_cxx_ws_string (this, " update(mutexinoutset)");
2146 case OMP_CLAUSE_DEPEND_INOUTSET
:
2147 pp_cxx_ws_string (this, " update(inoutset)");
2149 case OMP_CLAUSE_DEPEND_LAST
:
2150 pp_cxx_ws_string (this, " destroy");
2156 pp_needs_newline (this) = true;
2160 c_pretty_printer::statement (t
);
2165 /* original-namespace-definition:
2166 namespace identifier { namespace-body }
2168 As an edge case, we also handle unnamed namespace definition here. */
2171 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2173 pp_cxx_ws_string (pp
, "namespace");
2174 if (DECL_CONTEXT (t
))
2175 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2177 pp_cxx_unqualified_id (pp
, t
);
2178 pp_cxx_whitespace (pp
);
2179 pp_cxx_left_brace (pp
);
2180 /* We do not print the namespace-body. */
2181 pp_cxx_whitespace (pp
);
2182 pp_cxx_right_brace (pp
);
2188 namespace-alias-definition:
2189 namespace identifier = qualified-namespace-specifier ;
2191 qualified-namespace-specifier:
2192 ::(opt) nested-name-specifier(opt) namespace-name */
2195 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2197 pp_cxx_ws_string (pp
, "namespace");
2198 if (DECL_CONTEXT (t
))
2199 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2200 pp_cxx_unqualified_id (pp
, t
);
2201 pp_cxx_whitespace (pp
);
2203 pp_cxx_whitespace (pp
);
2204 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2205 pp_cxx_nested_name_specifier (pp
,
2206 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2207 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2208 pp_cxx_semicolon (pp
);
2211 /* simple-declaration:
2212 decl-specifier-seq(opt) init-declarator-list(opt) */
2215 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2217 pp
->declaration_specifiers (t
);
2218 pp_cxx_init_declarator (pp
, t
);
2219 pp_cxx_semicolon (pp
);
2220 pp_needs_newline (pp
) = true;
2224 template-parameter-list:
2226 template-parameter-list , template-parameter */
2229 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2231 const int n
= TREE_VEC_LENGTH (t
);
2233 for (i
= 0; i
< n
; ++i
)
2236 pp_cxx_separate_with (pp
, ',');
2237 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2241 /* template-parameter:
2243 parameter-declaration
2246 class ...(opt) identifier(opt)
2247 class identifier(opt) = type-id
2248 typename identifier(opt)
2249 typename ...(opt) identifier(opt) = type-id
2250 template < template-parameter-list > class ...(opt) identifier(opt)
2251 template < template-parameter-list > class identifier(opt) = template-name */
2254 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2256 tree parameter
= TREE_VALUE (t
);
2257 switch (TREE_CODE (parameter
))
2260 pp_cxx_ws_string (pp
, "class");
2261 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2262 pp_cxx_ws_string (pp
, "...");
2263 if (DECL_NAME (parameter
))
2264 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2265 /* FIXME: Check if we should print also default argument. */
2269 pp_cxx_parameter_declaration (pp
, parameter
);
2276 pp_unsupported_tree (pp
, t
);
2281 /* Pretty-print a template parameter in the canonical form
2282 "template-parameter-<level>-<position in parameter list>". */
2285 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2287 const enum tree_code code
= TREE_CODE (parm
);
2289 /* Brings type template parameters to the canonical forms. */
2290 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2291 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2292 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2294 pp_cxx_begin_template_argument_list (pp
);
2295 pp
->translate_string ("template-parameter-");
2296 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2298 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2299 pp_cxx_end_template_argument_list (pp
);
2302 /* Print a constrained-type-specifier. */
2305 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2307 pp_cxx_whitespace (pp
);
2308 pp_cxx_left_bracket (pp
);
2309 pp
->translate_string ("requires");
2310 pp_cxx_whitespace (pp
);
2311 if (c
== error_mark_node
)
2313 pp_cxx_ws_string(pp
, "<unsatisfied-type-constraint>");
2317 placeholder_extract_concept_and_args (c
, t
, a
);
2318 pp
->id_expression (t
);
2319 pp_cxx_begin_template_argument_list (pp
);
2320 pp_cxx_ws_string (pp
, "<placeholder>");
2321 pp_cxx_separate_with (pp
, ',');
2322 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2323 for (int i
= 0; i
< TREE_VEC_LENGTH (a
) - 1; ++i
)
2324 TREE_VEC_ELT (args
, i
) = TREE_VEC_ELT (a
, i
+ 1);
2325 pp_cxx_template_argument_list (pp
, args
);
2327 pp_cxx_end_template_argument_list (pp
);
2328 pp_cxx_right_bracket (pp
);
2332 template-declaration:
2333 export(opt) template < template-parameter-list > declaration
2337 template-declaration:
2338 export(opt) template < template-parameter-list >
2339 requires-clause(opt) declaration */
2342 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2344 tree tmpl
= most_general_template (t
);
2347 pp_maybe_newline_and_indent (pp
, 0);
2348 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2350 pp_cxx_ws_string (pp
, "template");
2351 pp_cxx_begin_template_argument_list (pp
);
2352 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2353 pp_cxx_end_template_argument_list (pp
);
2354 pp_newline_and_indent (pp
, 3);
2358 if (tree ci
= get_constraints (t
))
2359 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2361 pp_cxx_requires_clause (pp
, reqs
);
2362 pp_newline_and_indent (pp
, 6);
2365 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2366 pp_cxx_function_definition (pp
, t
);
2367 else if (TREE_CODE (t
) == CONCEPT_DECL
)
2368 pp_cxx_concept_definition (pp
, t
);
2370 pp_cxx_simple_declaration (pp
, t
);
2374 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2376 pp_unsupported_tree (pp
, t
);
2380 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2382 pp_unsupported_tree (pp
, t
);
2386 pp_cxx_concept_definition (cxx_pretty_printer
*pp
, tree t
)
2388 pp_cxx_unqualified_id (pp
, DECL_NAME (t
));
2389 pp_cxx_whitespace (pp
);
2390 pp_cxx_ws_string (pp
, "=");
2391 pp_cxx_whitespace (pp
);
2392 pp
->expression (DECL_INITIAL (t
));
2393 pp_cxx_semicolon (pp
);
2400 template-declaration
2401 explicit-instantiation
2402 explicit-specialization
2403 linkage-specification
2404 namespace-definition
2409 namespace-alias-definition
2412 static_assert-declaration */
2414 cxx_pretty_printer::declaration (tree t
)
2416 if (TREE_CODE (t
) == STATIC_ASSERT
)
2418 pp_cxx_ws_string (this, "static_assert");
2419 pp_cxx_left_paren (this);
2420 expression (STATIC_ASSERT_CONDITION (t
));
2421 pp_cxx_separate_with (this, ',');
2422 expression (STATIC_ASSERT_MESSAGE (t
));
2423 pp_cxx_right_paren (this);
2425 else if (!DECL_LANG_SPECIFIC (t
))
2426 pp_cxx_simple_declaration (this, t
);
2427 else if (DECL_USE_TEMPLATE (t
))
2428 switch (DECL_USE_TEMPLATE (t
))
2431 pp_cxx_template_declaration (this, t
);
2435 pp_cxx_explicit_specialization (this, t
);
2439 pp_cxx_explicit_instantiation (this, t
);
2445 else switch (TREE_CODE (t
))
2449 pp_cxx_simple_declaration (this, t
);
2453 if (DECL_SAVED_TREE (t
))
2454 pp_cxx_function_definition (this, t
);
2456 pp_cxx_simple_declaration (this, t
);
2459 case NAMESPACE_DECL
:
2460 if (DECL_NAMESPACE_ALIAS (t
))
2461 pp_cxx_namespace_alias_definition (this, t
);
2463 pp_cxx_original_namespace_definition (this, t
);
2467 pp_unsupported_tree (this, t
);
2473 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2475 t
= TREE_OPERAND (t
, 0);
2476 pp_cxx_ws_string (pp
, "typeid");
2477 pp_cxx_left_paren (pp
);
2482 pp_cxx_right_paren (pp
);
2486 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2488 pp_cxx_ws_string (pp
, "va_arg");
2489 pp_cxx_left_paren (pp
);
2490 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2491 pp_cxx_separate_with (pp
, ',');
2492 pp
->type_id (TREE_TYPE (t
));
2493 pp_cxx_right_paren (pp
);
2497 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2499 switch (TREE_CODE (t
))
2502 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2503 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2505 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2506 pp_cxx_separate_with (pp
, ',');
2511 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2513 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2515 pp
->expression (TREE_OPERAND (t
, 1));
2518 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2520 pp_left_bracket (pp
);
2521 pp
->expression (TREE_OPERAND (t
, 1));
2522 pp_right_bracket (pp
);
2530 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2532 pp_cxx_ws_string (pp
, "offsetof");
2533 pp_cxx_left_paren (pp
);
2534 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2535 pp
->expression (TREE_OPERAND (t
, 0));
2536 pp_cxx_right_paren (pp
);
2540 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2542 pp_cxx_ws_string (pp
, "__builtin_addressof");
2543 pp_cxx_left_paren (pp
);
2544 pp
->expression (TREE_OPERAND (t
, 0));
2545 pp_cxx_right_paren (pp
);
2549 get_fold_operator (tree t
)
2551 ovl_op_info_t
*info
= OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t
),
2557 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2559 char const* op
= get_fold_operator (t
);
2560 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2561 pp_cxx_left_paren (pp
);
2562 pp_cxx_ws_string (pp
, "...");
2563 pp_cxx_ws_string (pp
, op
);
2564 pp
->expression (expr
);
2565 pp_cxx_right_paren (pp
);
2569 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2571 char const* op
= get_fold_operator (t
);
2572 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2573 pp_cxx_left_paren (pp
);
2574 pp
->expression (expr
);
2576 pp_cxx_ws_string (pp
, op
);
2577 pp_cxx_ws_string (pp
, "...");
2578 pp_cxx_right_paren (pp
);
2582 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2584 char const* op
= get_fold_operator (t
);
2585 tree t1
= TREE_OPERAND (t
, 1);
2586 tree t2
= TREE_OPERAND (t
, 2);
2587 if (t1
== FOLD_EXPR_PACK (t
))
2588 t1
= PACK_EXPANSION_PATTERN (t1
);
2590 t2
= PACK_EXPANSION_PATTERN (t2
);
2591 pp_cxx_left_paren (pp
);
2592 pp
->expression (t1
);
2593 pp_cxx_ws_string (pp
, op
);
2594 pp_cxx_ws_string (pp
, "...");
2595 pp_cxx_ws_string (pp
, op
);
2596 pp
->expression (t2
);
2597 pp_cxx_right_paren (pp
);
2601 pp_cxx_trait (cxx_pretty_printer
*pp
, tree t
)
2605 if (TREE_CODE (t
) == TRAIT_EXPR
)
2607 kind
= TRAIT_EXPR_KIND (t
);
2608 type1
= TRAIT_EXPR_TYPE1 (t
);
2609 type2
= TRAIT_EXPR_TYPE2 (t
);
2613 kind
= TRAIT_TYPE_KIND (t
);
2614 type1
= TRAIT_TYPE_TYPE1 (t
);
2615 type2
= TRAIT_TYPE_TYPE2 (t
);
2620 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2622 pp_cxx_ws_string (pp, NAME); \
2624 #include "cp-trait.def"
2628 pp_cxx_left_paren (pp
);
2629 pp
->type_id (type1
);
2632 if (TREE_CODE (type2
) != TREE_LIST
)
2634 pp_cxx_separate_with (pp
, ',');
2635 pp
->type_id (type2
);
2638 for (tree arg
= type2
; arg
; arg
= TREE_CHAIN (arg
))
2640 pp_cxx_separate_with (pp
, ',');
2641 pp
->type_id (TREE_VALUE (arg
));
2644 pp_cxx_right_paren (pp
);
2648 // 'requires' logical-or-expression
2650 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2654 pp
->padding
= pp_before
;
2655 pp_cxx_ws_string (pp
, "requires");
2662 compound-requirement
2664 nested-requirement */
2666 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2668 switch (TREE_CODE (t
))
2671 pp_cxx_simple_requirement (pp
, t
);
2675 pp_cxx_type_requirement (pp
, t
);
2679 pp_cxx_compound_requirement (pp
, t
);
2683 pp_cxx_nested_requirement (pp
, t
);
2691 // requirement-list:
2693 // requirement-list ';' requirement[opt]
2696 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2698 for (; t
; t
= TREE_CHAIN (t
))
2699 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2702 // requirement-body:
2703 // '{' requirement-list '}'
2705 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2707 pp_cxx_left_brace (pp
);
2708 pp_cxx_requirement_list (pp
, t
);
2709 pp_cxx_right_brace (pp
);
2712 // requires-expression:
2713 // 'requires' requirement-parameter-list requirement-body
2715 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2717 pp_string (pp
, "requires");
2718 if (tree parms
= REQUIRES_EXPR_PARMS (t
))
2721 pp_cxx_left_paren (pp
);
2722 for (; parms
; parms
= TREE_CHAIN (parms
))
2725 pp_cxx_separate_with (pp
, ',' );
2727 pp_cxx_parameter_declaration (pp
, parms
);
2729 pp_cxx_right_paren (pp
);
2730 pp_cxx_whitespace (pp
);
2732 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2735 /* simple-requirement:
2738 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2740 pp
->expression (TREE_OPERAND (t
, 0));
2741 pp_cxx_semicolon (pp
);
2744 /* type-requirement:
2745 typename type-name ';' */
2747 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2749 pp
->type_id (TREE_OPERAND (t
, 0));
2750 pp_cxx_semicolon (pp
);
2753 /* compound-requirement:
2754 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2756 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2758 pp_cxx_left_brace (pp
);
2759 pp
->expression (TREE_OPERAND (t
, 0));
2760 pp_cxx_right_brace (pp
);
2762 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2763 pp_cxx_ws_string (pp
, "noexcept");
2765 if (tree type
= TREE_OPERAND (t
, 1))
2767 pp_cxx_whitespace (pp
);
2768 pp_cxx_ws_string (pp
, "->");
2771 pp_cxx_semicolon (pp
);
2774 /* nested requirement:
2775 'requires' constraint-expression */
2777 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2779 pp_cxx_ws_string (pp
, "requires");
2780 pp
->expression (TREE_OPERAND (t
, 0));
2781 pp_cxx_semicolon (pp
);
2785 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2787 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2788 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2789 tree args
= CHECK_CONSTR_ARGS (t
);
2790 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2792 if (TREE_CODE (decl
) == CONCEPT_DECL
)
2793 pp
->expression (id
);
2794 else if (VAR_P (decl
))
2795 pp
->expression (id
);
2796 else if (TREE_CODE (decl
) == FUNCTION_DECL
)
2798 tree call
= build_vl_exp (CALL_EXPR
, 2);
2799 TREE_OPERAND (call
, 0) = integer_two_node
;
2800 TREE_OPERAND (call
, 1) = id
;
2801 pp
->expression (call
);
2807 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2811 pp_cxx_parameter_mapping (cxx_pretty_printer
*pp
, tree map
)
2813 pp_cxx_whitespace (pp
);
2814 pp_cxx_left_bracket (pp
);
2815 pp
->translate_string ("with");
2816 pp_cxx_whitespace (pp
);
2818 for (tree p
= map
; p
; p
= TREE_CHAIN (p
))
2820 tree parm
= TREE_VALUE (p
);
2821 tree arg
= TREE_PURPOSE (p
);
2825 else if (tree name
= DECL_NAME (TEMPLATE_PARM_DECL (parm
)))
2826 pp_cxx_tree_identifier (pp
, name
);
2828 pp
->translate_string ("<unnamed>");
2830 pp_cxx_whitespace (pp
);
2832 pp_cxx_whitespace (pp
);
2834 if (TYPE_P (arg
) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg
))
2837 pp
->expression (arg
);
2839 if (TREE_CHAIN (p
) != NULL_TREE
)
2840 pp_cxx_separate_with (pp
, ';');
2843 pp_cxx_right_bracket (pp
);
2847 pp_cxx_atomic_constraint (cxx_pretty_printer
*pp
, tree t
)
2849 /* Emit the expression. */
2850 pp
->expression (ATOMIC_CONSTR_EXPR (t
));
2852 /* Emit the parameter mapping. */
2853 tree map
= ATOMIC_CONSTR_MAP (t
);
2854 if (map
&& map
!= error_mark_node
)
2855 pp_cxx_parameter_mapping (pp
, map
);
2859 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2861 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2862 pp_string (pp
, " /\\ ");
2863 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2867 pp_cxx_disjunction (cxx_pretty_printer
*pp
, tree t
)
2869 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2870 pp_string (pp
, " \\/ ");
2871 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2875 pp_cxx_constraint (cxx_pretty_printer
*pp
, tree t
)
2877 if (t
== error_mark_node
)
2878 return pp
->expression (t
);
2880 switch (TREE_CODE (t
))
2883 pp_cxx_atomic_constraint (pp
, t
);
2887 pp_cxx_check_constraint (pp
, t
);
2891 pp_cxx_conjunction (pp
, t
);
2895 pp_cxx_disjunction (pp
, t
);
2898 case EXPR_PACK_EXPANSION
:
2899 pp
->expression (TREE_OPERAND (t
, 0));
2908 typedef c_pretty_print_fn pp_fun
;
2910 /* Initialization of a C++ pretty-printer object. */
2912 cxx_pretty_printer::cxx_pretty_printer ()
2913 : c_pretty_printer (),
2914 enclosing_scope (global_namespace
)
2916 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2917 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;
2920 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2923 cxx_pretty_printer::clone () const
2925 return new cxx_pretty_printer (*this);