1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2023 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 if (code
== SIZEOF_EXPR
)
848 pp_cxx_ws_string (this, "sizeof");
849 else if (ALIGNOF_EXPR_STD_P (t
))
850 pp_cxx_ws_string (this, "alignof");
852 pp_cxx_ws_string (this, "__alignof__");
853 pp_cxx_whitespace (this);
854 if (TREE_CODE (t
) == SIZEOF_EXPR
&& SIZEOF_EXPR_TYPE_P (t
))
856 pp_cxx_left_paren (this);
857 type_id (TREE_TYPE (TREE_OPERAND (t
, 0)));
858 pp_cxx_right_paren (this);
860 else if (TYPE_P (TREE_OPERAND (t
, 0)))
862 pp_cxx_left_paren (this);
863 type_id (TREE_OPERAND (t
, 0));
864 pp_cxx_right_paren (this);
867 unary_expression (TREE_OPERAND (t
, 0));
871 pp_cxx_ws_string (this, "@encode");
872 pp_cxx_whitespace (this);
873 pp_cxx_left_paren (this);
874 type_id (TREE_OPERAND (t
, 0));
875 pp_cxx_right_paren (this);
879 pp_cxx_ws_string (this, "noexcept");
880 pp_cxx_whitespace (this);
881 pp_cxx_left_paren (this);
882 expression (TREE_OPERAND (t
, 0));
883 pp_cxx_right_paren (this);
886 case UNARY_PLUS_EXPR
:
888 pp_cxx_cast_expression (this, TREE_OPERAND (t
, 0));
892 c_pretty_printer::unary_expression (t
);
899 ( type-id ) cast-expression */
902 pp_cxx_cast_expression (cxx_pretty_printer
*pp
, tree t
)
904 switch (TREE_CODE (t
))
907 case IMPLICIT_CONV_EXPR
:
908 pp
->type_id (TREE_TYPE (t
));
909 pp_cxx_call_argument_list (pp
, TREE_OPERAND (t
, 0));
913 pp_c_cast_expression (pp
, t
);
920 pm-expression .* cast-expression
921 pm-expression ->* cast-expression */
924 pp_cxx_pm_expression (cxx_pretty_printer
*pp
, tree t
)
926 switch (TREE_CODE (t
))
928 /* Handle unfortunate OFFSET_REF overloading here. */
930 if (TYPE_P (TREE_OPERAND (t
, 0)))
932 pp_cxx_qualified_id (pp
, t
);
938 pp_cxx_pm_expression (pp
, TREE_OPERAND (t
, 0));
939 if (TREE_CODE (t
) == MEMBER_REF
)
944 pp_cxx_cast_expression (pp
, TREE_OPERAND (t
, 1));
949 pp_cxx_cast_expression (pp
, t
);
954 /* multiplicative-expression:
956 multiplicative-expression * pm-expression
957 multiplicative-expression / pm-expression
958 multiplicative-expression % pm-expression */
961 cxx_pretty_printer::multiplicative_expression (tree e
)
963 enum tree_code code
= TREE_CODE (e
);
971 multiplicative_expression (TREE_OPERAND (e
, 0));
973 if (code
== MULT_EXPR
)
975 else if (code
!= TRUNC_MOD_EXPR
)
980 pp_cxx_pm_expression (this, TREE_OPERAND (e
, 1));
984 pp_cxx_pm_expression (this, e
);
989 /* conditional-expression:
990 logical-or-expression
991 logical-or-expression ? expression : assignment-expression */
994 cxx_pretty_printer::conditional_expression (tree e
)
996 if (TREE_CODE (e
) == COND_EXPR
)
998 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1002 expression (TREE_OPERAND (e
, 1));
1004 assignment_expression (TREE_OPERAND (e
, 2));
1007 pp_c_logical_or_expression (this, e
);
1010 /* Pretty-print a compound assignment operator token as indicated by T. */
1013 pp_cxx_assignment_operator (cxx_pretty_printer
*pp
, tree t
)
1017 switch (TREE_CODE (t
))
1031 case TRUNC_DIV_EXPR
:
1035 case TRUNC_MOD_EXPR
:
1040 op
= get_tree_code_name (TREE_CODE (t
));
1044 pp_cxx_ws_string (pp
, op
);
1048 /* assignment-expression:
1049 conditional-expression
1050 logical-or-expression assignment-operator assignment-expression
1054 throw assignment-expression(opt)
1056 assignment-operator: one of
1057 = *= /= %= += -= >>= <<= &= ^= |= */
1060 cxx_pretty_printer::assignment_expression (tree e
)
1062 switch (TREE_CODE (e
))
1066 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1070 assignment_expression (TREE_OPERAND (e
, 1));
1074 pp_cxx_ws_string (this, "throw");
1075 if (TREE_OPERAND (e
, 0))
1076 assignment_expression (TREE_OPERAND (e
, 0));
1080 pp_c_logical_or_expression (this, TREE_OPERAND (e
, 0));
1081 pp_cxx_assignment_operator (this, TREE_OPERAND (e
, 1));
1082 assignment_expression (TREE_OPERAND (e
, 2));
1086 conditional_expression (e
);
1092 cxx_pretty_printer::expression (tree t
)
1094 switch (TREE_CODE (t
))
1104 case USERDEF_LITERAL
:
1105 pp_cxx_userdef_literal (this, t
);
1109 pp_cxx_unqualified_id (this, t
);
1117 pp_cxx_qualified_id (this, t
);
1130 case TEMPLATE_TYPE_PARM
:
1131 case TEMPLATE_PARM_INDEX
:
1132 case TEMPLATE_TEMPLATE_PARM
:
1135 primary_expression (t
);
1139 case DYNAMIC_CAST_EXPR
:
1140 case STATIC_CAST_EXPR
:
1141 case REINTERPRET_CAST_EXPR
:
1142 case CONST_CAST_EXPR
:
1146 case EMPTY_CLASS_EXPR
:
1148 case PSEUDO_DTOR_EXPR
:
1149 case AGGR_INIT_EXPR
:
1151 postfix_expression (t
);
1156 pp_cxx_new_expression (this, t
);
1160 case VEC_DELETE_EXPR
:
1161 pp_cxx_delete_expression (this, t
);
1167 case UNARY_PLUS_EXPR
:
1168 unary_expression (t
);
1172 case IMPLICIT_CONV_EXPR
:
1173 pp_cxx_cast_expression (this, t
);
1179 pp_cxx_pm_expression (this, t
);
1183 case TRUNC_DIV_EXPR
:
1184 case TRUNC_MOD_EXPR
:
1185 case EXACT_DIV_EXPR
:
1187 multiplicative_expression (t
);
1191 conditional_expression (t
);
1198 assignment_expression (t
);
1201 case NON_DEPENDENT_EXPR
:
1202 case MUST_NOT_THROW_EXPR
:
1203 expression (TREE_OPERAND (t
, 0));
1206 case EXPR_PACK_EXPANSION
:
1207 expression (PACK_EXPANSION_PATTERN (t
));
1208 pp_cxx_ws_string (this, "...");
1211 case UNARY_LEFT_FOLD_EXPR
:
1212 pp_cxx_unary_left_fold_expression (this, t
);
1215 case UNARY_RIGHT_FOLD_EXPR
:
1216 pp_cxx_unary_right_fold_expression (this, t
);
1219 case BINARY_LEFT_FOLD_EXPR
:
1220 case BINARY_RIGHT_FOLD_EXPR
:
1221 pp_cxx_binary_fold_expression (this, t
);
1224 case TEMPLATE_ID_EXPR
:
1225 pp_cxx_template_id (this, t
);
1228 case NONTYPE_ARGUMENT_PACK
:
1230 tree args
= ARGUMENT_PACK_ARGS (t
);
1231 int i
, len
= TREE_VEC_LENGTH (args
);
1232 pp_cxx_left_brace (this);
1233 for (i
= 0; i
< len
; ++i
)
1236 pp_cxx_separate_with (this, ',');
1237 expression (TREE_VEC_ELT (args
, i
));
1239 pp_cxx_right_brace (this);
1244 pp_cxx_ws_string (this, "<lambda>");
1248 pp_cxx_trait (this, t
);
1255 pp_cxx_constraint (this, t
);
1259 pp_cxx_left_paren (this);
1260 expression (TREE_OPERAND (t
, 0));
1261 pp_cxx_right_paren (this);
1265 c_pretty_printer::expression (t
);
1273 /* function-specifier:
1279 cxx_pretty_printer::function_specifier (tree t
)
1281 switch (TREE_CODE (t
))
1284 if (DECL_VIRTUAL_P (t
))
1285 pp_cxx_ws_string (this, "virtual");
1286 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
1287 pp_cxx_ws_string (this, "explicit");
1289 c_pretty_printer::function_specifier (t
);
1296 /* decl-specifier-seq:
1297 decl-specifier-seq(opt) decl-specifier
1300 storage-class-specifier
1307 cxx_pretty_printer::declaration_specifiers (tree t
)
1309 switch (TREE_CODE (t
))
1315 storage_class_specifier (t
);
1316 declaration_specifiers (TREE_TYPE (t
));
1320 pp_cxx_ws_string (this, "typedef");
1321 declaration_specifiers (TREE_TYPE (t
));
1325 /* Constructors don't have return types. And conversion functions
1326 do not have a type-specifier in their return types. */
1327 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
1328 function_specifier (t
);
1329 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1330 declaration_specifiers (TREE_TYPE (TREE_TYPE (t
)));
1332 c_pretty_printer::declaration_specifiers (t
);
1335 c_pretty_printer::declaration_specifiers (t
);
1340 /* simple-type-specifier:
1341 ::(opt) nested-name-specifier(opt) type-name
1342 ::(opt) nested-name-specifier(opt) template(opt) template-id
1357 cxx_pretty_printer::simple_type_specifier (tree t
)
1359 switch (TREE_CODE (t
))
1364 pp_cxx_qualified_id (this, t
);
1367 case TEMPLATE_TYPE_PARM
:
1368 case TEMPLATE_TEMPLATE_PARM
:
1369 case TEMPLATE_PARM_INDEX
:
1370 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1371 pp_cxx_unqualified_id (this, t
);
1372 if (TREE_CODE (t
) == TEMPLATE_TYPE_PARM
)
1373 if (tree c
= PLACEHOLDER_TYPE_CONSTRAINTS (t
))
1374 pp_cxx_constrained_type_spec (this, c
);
1378 pp_cxx_ws_string (this, "typename");
1379 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t
));
1380 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t
));
1384 pp_cxx_ws_string (this, "decltype");
1385 pp_cxx_left_paren (this);
1386 this->expression (DECLTYPE_TYPE_EXPR (t
));
1387 pp_cxx_right_paren (this);
1391 pp_cxx_ws_string (this, "std::nullptr_t");
1395 pp_cxx_trait (this, t
);
1399 c_pretty_printer::simple_type_specifier (t
);
1404 /* type-specifier-seq:
1405 type-specifier type-specifier-seq(opt)
1408 simple-type-specifier
1411 elaborated-type-specifier
1415 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1417 switch (TREE_CODE (t
))
1420 case TEMPLATE_TYPE_PARM
:
1421 case TEMPLATE_TEMPLATE_PARM
:
1423 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1426 pp_cxx_cv_qualifier_seq (pp
, t
);
1427 pp
->simple_type_specifier (t
);
1431 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1432 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1433 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1437 if (TYPE_PTRMEMFUNC_P (t
))
1439 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
1440 pp
->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm
)));
1441 pp_cxx_whitespace (pp
);
1442 pp_cxx_ptr_operator (pp
, t
);
1448 if (TYPE_PTRDATAMEM_P (t
))
1450 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1451 pp_cxx_whitespace (pp
);
1452 pp_cxx_ptr_operator (pp
, t
);
1458 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1459 pp_c_specifier_qualifier_list (pp
, t
);
1464 * cv-qualifier-seq(opt)
1466 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1469 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1471 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1473 switch (TREE_CODE (t
))
1475 case REFERENCE_TYPE
:
1477 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1478 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1479 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1483 pp_cxx_cv_qualifier_seq (pp
, t
);
1490 if (TYPE_PTRMEMFUNC_P (t
))
1492 pp_cxx_left_paren (pp
);
1493 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1499 if (TYPE_PTRMEM_P (t
))
1501 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1502 pp_cxx_left_paren (pp
);
1503 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1505 pp_cxx_cv_qualifier_seq (pp
, t
);
1511 pp_unsupported_tree (pp
, t
);
1517 pp_cxx_implicit_parameter_type (tree mf
)
1519 return class_of_this_parm (TREE_TYPE (mf
));
1523 parameter-declaration:
1524 decl-specifier-seq declarator
1525 decl-specifier-seq declarator = assignment-expression
1526 decl-specifier-seq abstract-declarator(opt)
1527 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1530 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1532 pp
->declaration_specifiers (t
);
1534 pp
->abstract_declarator (t
);
1539 /* parameter-declaration-clause:
1540 parameter-declaration-list(opt) ...(opt)
1541 parameter-declaration-list , ...
1543 parameter-declaration-list:
1544 parameter-declaration
1545 parameter-declaration-list , parameter-declaration */
1548 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1550 gcc_assert (FUNC_OR_METHOD_TYPE_P (t
) || TREE_CODE (t
) == FUNCTION_DECL
);
1554 types
= TYPE_ARG_TYPES (t
);
1559 types
= FUNCTION_FIRST_USER_PARMTYPE (t
);
1560 args
= FUNCTION_FIRST_USER_PARM (t
);
1562 bool abstract
= !args
|| (pp
->flags
& pp_c_flag_abstract
);
1564 /* Skip artificial parameter for non-static member functions. */
1565 if (TREE_CODE (t
) == METHOD_TYPE
)
1566 types
= TREE_CHAIN (types
);
1569 pp_cxx_left_paren (pp
);
1570 for (; types
!= void_list_node
; types
= TREE_CHAIN (types
))
1573 pp_cxx_separate_with (pp
, ',');
1577 pp_cxx_ws_string (pp
, "...");
1580 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1581 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1583 pp_cxx_whitespace (pp
);
1585 pp_cxx_whitespace (pp
);
1586 pp
->assignment_expression (TREE_PURPOSE (types
));
1589 args
= TREE_CHAIN (args
);
1591 pp_cxx_right_paren (pp
);
1594 /* exception-specification:
1595 throw ( type-id-list(opt) )
1599 type-id-list , type-id */
1602 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1604 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1605 bool need_comma
= false;
1607 if (ex_spec
== NULL
)
1609 if (TREE_PURPOSE (ex_spec
))
1611 pp_cxx_ws_string (pp
, "noexcept");
1612 pp_cxx_whitespace (pp
);
1613 pp_cxx_left_paren (pp
);
1614 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1615 pp_cxx_ws_string (pp
, "<uninstantiated>");
1617 pp
->expression (TREE_PURPOSE (ex_spec
));
1618 pp_cxx_right_paren (pp
);
1621 pp_cxx_ws_string (pp
, "throw");
1622 pp_cxx_left_paren (pp
);
1623 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1625 tree type
= TREE_VALUE (ex_spec
);
1626 tree argpack
= NULL_TREE
;
1629 if (ARGUMENT_PACK_P (type
))
1631 argpack
= ARGUMENT_PACK_ARGS (type
);
1632 len
= TREE_VEC_LENGTH (argpack
);
1635 for (i
= 0; i
< len
; ++i
)
1638 type
= TREE_VEC_ELT (argpack
, i
);
1641 pp_cxx_separate_with (pp
, ',');
1648 pp_cxx_right_paren (pp
);
1651 /* direct-declarator:
1653 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1654 exception-specification(opt)
1655 direct-declaration [ constant-expression(opt) ]
1659 cxx_pretty_printer::direct_declarator (tree t
)
1661 switch (TREE_CODE (t
))
1669 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1671 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1672 || template_parameter_pack_p (t
))
1673 /* A function parameter pack or non-type template
1675 pp_cxx_ws_string (this, "...");
1677 id_expression (DECL_NAME (t
));
1679 abstract_declarator (TREE_TYPE (t
));
1683 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1685 pp_cxx_parameter_declaration_clause (this, t
);
1687 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1689 padding
= pp_before
;
1690 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1693 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1698 case TEMPLATE_TYPE_PARM
:
1699 case TEMPLATE_PARM_INDEX
:
1700 case TEMPLATE_TEMPLATE_PARM
:
1704 c_pretty_printer::direct_declarator (t
);
1711 ptr-operator declarator */
1714 cxx_pretty_printer::declarator (tree t
)
1716 direct_declarator (t
);
1718 // Print a requires clause.
1720 if (tree ci
= get_constraints (t
))
1721 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1722 pp_cxx_requires_clause (this, reqs
);
1725 /* ctor-initializer:
1726 : mem-initializer-list
1728 mem-initializer-list:
1730 mem-initializer , mem-initializer-list
1733 mem-initializer-id ( expression-list(opt) )
1736 ::(opt) nested-name-specifier(opt) class-name
1740 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1742 t
= TREE_OPERAND (t
, 0);
1743 pp_cxx_whitespace (pp
);
1745 pp_cxx_whitespace (pp
);
1746 for (; t
; t
= TREE_CHAIN (t
))
1748 tree purpose
= TREE_PURPOSE (t
);
1749 bool is_pack
= PACK_EXPANSION_P (purpose
);
1752 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1754 pp
->primary_expression (purpose
);
1755 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1757 pp_cxx_ws_string (pp
, "...");
1759 pp_cxx_separate_with (pp
, ',');
1763 /* function-definition:
1764 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1765 decl-specifier-seq(opt) declarator function-try-block */
1768 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1770 tree saved_scope
= pp
->enclosing_scope
;
1771 pp
->declaration_specifiers (t
);
1773 pp_needs_newline (pp
) = true;
1774 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1775 if (DECL_SAVED_TREE (t
))
1776 pp
->statement (DECL_SAVED_TREE (t
));
1778 pp_cxx_semicolon (pp
);
1779 pp_newline_and_flush (pp
);
1780 pp
->enclosing_scope
= saved_scope
;
1783 /* abstract-declarator:
1784 ptr-operator abstract-declarator(opt)
1785 direct-abstract-declarator */
1788 cxx_pretty_printer::abstract_declarator (tree t
)
1790 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1791 or a pointer-to-data-member of array type:
1796 but not for a pointer-to-data-member of non-array type:
1800 so be mindful of that. */
1801 if (TYPE_PTRMEMFUNC_P (t
)
1802 || (TYPE_PTRDATAMEM_P (t
)
1803 && TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
))
1804 pp_cxx_right_paren (this);
1805 else if (INDIRECT_TYPE_P (t
))
1807 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1808 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1809 pp_cxx_right_paren (this);
1812 direct_abstract_declarator (t
);
1815 /* direct-abstract-declarator:
1816 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1817 cv-qualifier-seq(opt) exception-specification(opt)
1818 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1819 ( abstract-declarator ) */
1822 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1824 switch (TREE_CODE (t
))
1826 case REFERENCE_TYPE
:
1827 abstract_declarator (t
);
1831 if (TYPE_PTRMEMFUNC_P (t
))
1832 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1836 if (TYPE_PTRDATAMEM_P (t
))
1837 direct_abstract_declarator (TREE_TYPE (t
));
1842 pp_cxx_parameter_declaration_clause (this, t
);
1843 direct_abstract_declarator (TREE_TYPE (t
));
1844 if (TREE_CODE (t
) == METHOD_TYPE
)
1846 padding
= pp_before
;
1847 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1849 pp_cxx_exception_specification (this, t
);
1853 case TEMPLATE_TYPE_PARM
:
1854 case TEMPLATE_TEMPLATE_PARM
:
1855 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1856 case UNBOUND_CLASS_TEMPLATE
:
1861 c_pretty_printer::direct_abstract_declarator (t
);
1867 type-specifier-seq abstract-declarator(opt) */
1870 cxx_pretty_printer::type_id (tree t
)
1872 pp_flags saved_flags
= flags
;
1873 flags
|= pp_c_flag_abstract
;
1875 switch (TREE_CODE (t
))
1882 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1883 case UNBOUND_CLASS_TEMPLATE
:
1884 case TEMPLATE_TEMPLATE_PARM
:
1885 case TEMPLATE_TYPE_PARM
:
1886 case TEMPLATE_PARM_INDEX
:
1892 case TEMPLATE_ID_EXPR
:
1894 pp_cxx_type_specifier_seq (this, t
);
1895 if (TYPE_PTRMEM_P (t
))
1896 abstract_declarator (t
);
1899 case TYPE_PACK_EXPANSION
:
1900 type_id (PACK_EXPANSION_PATTERN (t
));
1901 pp_cxx_ws_string (this, "...");
1904 case TYPE_ARGUMENT_PACK
:
1906 tree args
= ARGUMENT_PACK_ARGS (t
);
1907 int len
= TREE_VEC_LENGTH (args
);
1908 pp_cxx_left_brace (this);
1909 for (int i
= 0; i
< len
; ++i
)
1912 pp_cxx_separate_with (this, ',');
1913 type_id (TREE_VEC_ELT (args
, i
));
1915 pp_cxx_right_brace (this);
1920 c_pretty_printer::type_id (t
);
1924 flags
= saved_flags
;
1927 /* template-argument-list:
1928 template-argument ...(opt)
1929 template-argument-list, template-argument ...(opt)
1932 assignment-expression
1937 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1940 bool need_comma
= false;
1944 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1946 tree arg
= TREE_VEC_ELT (t
, i
);
1947 tree argpack
= NULL_TREE
;
1950 if (ARGUMENT_PACK_P (arg
))
1952 argpack
= ARGUMENT_PACK_ARGS (arg
);
1953 len
= TREE_VEC_LENGTH (argpack
);
1956 for (idx
= 0; idx
< len
; idx
++)
1959 arg
= TREE_VEC_ELT (argpack
, idx
);
1962 pp_cxx_separate_with (pp
, ',');
1966 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1967 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1969 else if (VAR_P (arg
) && DECL_NTTP_OBJECT_P (arg
))
1970 pp
->expression (DECL_INITIAL (arg
));
1972 pp
->expression (arg
);
1979 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1981 t
= DECL_EXPR_DECL (t
);
1982 pp_cxx_type_specifier_seq (pp
, t
);
1984 pp
->abstract_declarator (t
);
1992 cxx_pretty_printer::statement (tree t
)
1994 switch (TREE_CODE (t
))
1996 case CTOR_INITIALIZER
:
1997 pp_cxx_ctor_initializer (this, t
);
2001 pp_cxx_ws_string (this, "using");
2002 pp_cxx_ws_string (this, "namespace");
2003 if (DECL_CONTEXT (t
))
2004 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
2005 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
2009 pp_cxx_ws_string (this, "using");
2010 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
2011 pp_cxx_unqualified_id (this, DECL_NAME (t
));
2018 try compound-statement handler-seq */
2020 pp_maybe_newline_and_indent (this, 0);
2021 pp_cxx_ws_string (this, "try");
2022 pp_newline_and_indent (this, 3);
2023 statement (TRY_STMTS (t
));
2024 pp_newline_and_indent (this, -3);
2028 statement (TRY_HANDLERS (t
));
2033 handler handler-seq(opt)
2036 catch ( exception-declaration ) compound-statement
2038 exception-declaration:
2039 type-specifier-seq declarator
2040 type-specifier-seq abstract-declarator
2043 pp_cxx_ws_string (this, "catch");
2044 pp_cxx_left_paren (this);
2045 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
2046 pp_cxx_right_paren (this);
2047 pp_indentation (this) += 3;
2048 pp_needs_newline (this) = true;
2049 statement (HANDLER_BODY (t
));
2050 pp_indentation (this) -= 3;
2051 pp_needs_newline (this) = true;
2054 /* selection-statement:
2055 if ( expression ) statement
2056 if ( expression ) statement else statement */
2058 pp_cxx_ws_string (this, "if");
2059 pp_cxx_whitespace (this);
2060 pp_cxx_left_paren (this);
2061 expression (IF_COND (t
));
2062 pp_cxx_right_paren (this);
2063 pp_newline_and_indent (this, 2);
2064 statement (THEN_CLAUSE (t
));
2065 pp_newline_and_indent (this, -2);
2066 if (ELSE_CLAUSE (t
))
2068 tree else_clause
= ELSE_CLAUSE (t
);
2069 pp_cxx_ws_string (this, "else");
2070 if (TREE_CODE (else_clause
) == IF_STMT
)
2071 pp_cxx_whitespace (this);
2073 pp_newline_and_indent (this, 2);
2074 statement (else_clause
);
2075 if (TREE_CODE (else_clause
) != IF_STMT
)
2076 pp_newline_and_indent (this, -2);
2080 case RANGE_FOR_STMT
:
2081 pp_cxx_ws_string (this, "for");
2083 pp_cxx_left_paren (this);
2084 if (RANGE_FOR_INIT_STMT (t
))
2086 statement (RANGE_FOR_INIT_STMT (t
));
2087 pp_needs_newline (this) = false;
2088 pp_cxx_whitespace (this);
2090 statement (RANGE_FOR_DECL (t
));
2092 pp_needs_newline (this) = false;
2095 statement (RANGE_FOR_EXPR (t
));
2096 pp_cxx_right_paren (this);
2097 pp_newline_and_indent (this, 3);
2098 statement (FOR_BODY (t
));
2099 pp_indentation (this) -= 3;
2100 pp_needs_newline (this) = true;
2103 /* expression-statement:
2104 expression(opt) ; */
2106 expression (EXPR_STMT_EXPR (t
));
2107 pp_cxx_semicolon (this);
2108 pp_needs_newline (this) = true;
2112 pp_cxx_ws_string (this, "try");
2113 pp_newline_and_indent (this, 2);
2114 statement (CLEANUP_BODY (t
));
2115 pp_newline_and_indent (this, -2);
2116 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2117 pp_newline_and_indent (this, 2);
2118 statement (CLEANUP_EXPR (t
));
2119 pp_newline_and_indent (this, -2);
2127 pp_cxx_ws_string (this, "#pragma omp depobj");
2129 pp_cxx_left_paren (this);
2130 expression (OMP_DEPOBJ_DEPOBJ (t
));
2131 pp_cxx_right_paren (this);
2132 if (OMP_DEPOBJ_CLAUSES (t
) && OMP_DEPOBJ_CLAUSES (t
) != error_mark_node
)
2134 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t
)) == OMP_CLAUSE
)
2135 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t
),
2136 pp_indentation (this), TDF_NONE
);
2138 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t
)))
2140 case OMP_CLAUSE_DEPEND_IN
:
2141 pp_cxx_ws_string (this, " update(in)");
2143 case OMP_CLAUSE_DEPEND_INOUT
:
2144 pp_cxx_ws_string (this, " update(inout)");
2146 case OMP_CLAUSE_DEPEND_OUT
:
2147 pp_cxx_ws_string (this, " update(out)");
2149 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
2150 pp_cxx_ws_string (this, " update(mutexinoutset)");
2152 case OMP_CLAUSE_DEPEND_INOUTSET
:
2153 pp_cxx_ws_string (this, " update(inoutset)");
2155 case OMP_CLAUSE_DEPEND_LAST
:
2156 pp_cxx_ws_string (this, " destroy");
2162 pp_needs_newline (this) = true;
2166 c_pretty_printer::statement (t
);
2171 /* original-namespace-definition:
2172 namespace identifier { namespace-body }
2174 As an edge case, we also handle unnamed namespace definition here. */
2177 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2179 pp_cxx_ws_string (pp
, "namespace");
2180 if (DECL_CONTEXT (t
))
2181 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2183 pp_cxx_unqualified_id (pp
, t
);
2184 pp_cxx_whitespace (pp
);
2185 pp_cxx_left_brace (pp
);
2186 /* We do not print the namespace-body. */
2187 pp_cxx_whitespace (pp
);
2188 pp_cxx_right_brace (pp
);
2194 namespace-alias-definition:
2195 namespace identifier = qualified-namespace-specifier ;
2197 qualified-namespace-specifier:
2198 ::(opt) nested-name-specifier(opt) namespace-name */
2201 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2203 pp_cxx_ws_string (pp
, "namespace");
2204 if (DECL_CONTEXT (t
))
2205 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2206 pp_cxx_unqualified_id (pp
, t
);
2207 pp_cxx_whitespace (pp
);
2209 pp_cxx_whitespace (pp
);
2210 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2211 pp_cxx_nested_name_specifier (pp
,
2212 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2213 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2214 pp_cxx_semicolon (pp
);
2217 /* simple-declaration:
2218 decl-specifier-seq(opt) init-declarator-list(opt) */
2221 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2223 pp
->declaration_specifiers (t
);
2224 pp_cxx_init_declarator (pp
, t
);
2225 pp_cxx_semicolon (pp
);
2226 pp_needs_newline (pp
) = true;
2230 template-parameter-list:
2232 template-parameter-list , template-parameter */
2235 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2237 const int n
= TREE_VEC_LENGTH (t
);
2239 for (i
= 0; i
< n
; ++i
)
2242 pp_cxx_separate_with (pp
, ',');
2243 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2247 /* template-parameter:
2249 parameter-declaration
2252 class ...(opt) identifier(opt)
2253 class identifier(opt) = type-id
2254 typename identifier(opt)
2255 typename ...(opt) identifier(opt) = type-id
2256 template < template-parameter-list > class ...(opt) identifier(opt)
2257 template < template-parameter-list > class identifier(opt) = template-name */
2260 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2262 tree parameter
= TREE_VALUE (t
);
2263 switch (TREE_CODE (parameter
))
2266 pp_cxx_ws_string (pp
, "class");
2267 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2268 pp_cxx_ws_string (pp
, "...");
2269 if (DECL_NAME (parameter
))
2270 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2271 /* FIXME: Check if we should print also default argument. */
2275 pp_cxx_parameter_declaration (pp
, parameter
);
2282 pp_unsupported_tree (pp
, t
);
2287 /* Pretty-print a template parameter in the canonical form
2288 "template-parameter-<level>-<position in parameter list>". */
2291 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2293 const enum tree_code code
= TREE_CODE (parm
);
2295 /* Brings type template parameters to the canonical forms. */
2296 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2297 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2298 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2300 pp_cxx_begin_template_argument_list (pp
);
2301 pp
->translate_string ("template-parameter-");
2302 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2304 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2305 pp_cxx_end_template_argument_list (pp
);
2308 /* Print a constrained-type-specifier. */
2311 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2313 pp_cxx_whitespace (pp
);
2314 pp_cxx_left_bracket (pp
);
2315 pp
->translate_string ("requires");
2316 pp_cxx_whitespace (pp
);
2317 if (c
== error_mark_node
)
2319 pp_cxx_ws_string(pp
, "<unsatisfied-type-constraint>");
2323 placeholder_extract_concept_and_args (c
, t
, a
);
2324 pp
->id_expression (t
);
2325 pp_cxx_begin_template_argument_list (pp
);
2326 pp_cxx_ws_string (pp
, "<placeholder>");
2327 pp_cxx_separate_with (pp
, ',');
2328 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2329 for (int i
= 0; i
< TREE_VEC_LENGTH (a
) - 1; ++i
)
2330 TREE_VEC_ELT (args
, i
) = TREE_VEC_ELT (a
, i
+ 1);
2331 pp_cxx_template_argument_list (pp
, args
);
2333 pp_cxx_end_template_argument_list (pp
);
2334 pp_cxx_right_bracket (pp
);
2338 template-declaration:
2339 export(opt) template < template-parameter-list > declaration
2343 template-declaration:
2344 export(opt) template < template-parameter-list >
2345 requires-clause(opt) declaration */
2348 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2350 tree tmpl
= most_general_template (t
);
2353 pp_maybe_newline_and_indent (pp
, 0);
2354 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2356 pp_cxx_ws_string (pp
, "template");
2357 pp_cxx_begin_template_argument_list (pp
);
2358 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2359 pp_cxx_end_template_argument_list (pp
);
2360 pp_newline_and_indent (pp
, 3);
2364 if (tree ci
= get_constraints (t
))
2365 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2367 pp_cxx_requires_clause (pp
, reqs
);
2368 pp_newline_and_indent (pp
, 6);
2371 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2372 pp_cxx_function_definition (pp
, t
);
2373 else if (TREE_CODE (t
) == CONCEPT_DECL
)
2374 pp_cxx_concept_definition (pp
, t
);
2376 pp_cxx_simple_declaration (pp
, t
);
2380 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2382 pp_unsupported_tree (pp
, t
);
2386 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2388 pp_unsupported_tree (pp
, t
);
2392 pp_cxx_concept_definition (cxx_pretty_printer
*pp
, tree t
)
2394 pp_cxx_unqualified_id (pp
, DECL_NAME (t
));
2395 pp_cxx_whitespace (pp
);
2396 pp_cxx_ws_string (pp
, "=");
2397 pp_cxx_whitespace (pp
);
2398 pp
->expression (DECL_INITIAL (t
));
2399 pp_cxx_semicolon (pp
);
2406 template-declaration
2407 explicit-instantiation
2408 explicit-specialization
2409 linkage-specification
2410 namespace-definition
2415 namespace-alias-definition
2418 static_assert-declaration */
2420 cxx_pretty_printer::declaration (tree t
)
2422 if (TREE_CODE (t
) == STATIC_ASSERT
)
2424 pp_cxx_ws_string (this, "static_assert");
2425 pp_cxx_left_paren (this);
2426 expression (STATIC_ASSERT_CONDITION (t
));
2427 pp_cxx_separate_with (this, ',');
2428 expression (STATIC_ASSERT_MESSAGE (t
));
2429 pp_cxx_right_paren (this);
2431 else if (!DECL_LANG_SPECIFIC (t
))
2432 pp_cxx_simple_declaration (this, t
);
2433 else if (DECL_USE_TEMPLATE (t
))
2434 switch (DECL_USE_TEMPLATE (t
))
2437 pp_cxx_template_declaration (this, t
);
2441 pp_cxx_explicit_specialization (this, t
);
2445 pp_cxx_explicit_instantiation (this, t
);
2451 else switch (TREE_CODE (t
))
2455 pp_cxx_simple_declaration (this, t
);
2459 if (DECL_SAVED_TREE (t
))
2460 pp_cxx_function_definition (this, t
);
2462 pp_cxx_simple_declaration (this, t
);
2465 case NAMESPACE_DECL
:
2466 if (DECL_NAMESPACE_ALIAS (t
))
2467 pp_cxx_namespace_alias_definition (this, t
);
2469 pp_cxx_original_namespace_definition (this, t
);
2473 pp_unsupported_tree (this, t
);
2479 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2481 t
= TREE_OPERAND (t
, 0);
2482 pp_cxx_ws_string (pp
, "typeid");
2483 pp_cxx_left_paren (pp
);
2488 pp_cxx_right_paren (pp
);
2492 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2494 pp_cxx_ws_string (pp
, "va_arg");
2495 pp_cxx_left_paren (pp
);
2496 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2497 pp_cxx_separate_with (pp
, ',');
2498 pp
->type_id (TREE_TYPE (t
));
2499 pp_cxx_right_paren (pp
);
2503 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2505 switch (TREE_CODE (t
))
2508 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2509 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2511 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2512 pp_cxx_separate_with (pp
, ',');
2517 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2519 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2521 pp
->expression (TREE_OPERAND (t
, 1));
2524 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2526 pp_left_bracket (pp
);
2527 pp
->expression (TREE_OPERAND (t
, 1));
2528 pp_right_bracket (pp
);
2536 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2538 pp_cxx_ws_string (pp
, "offsetof");
2539 pp_cxx_left_paren (pp
);
2540 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2541 pp
->expression (TREE_OPERAND (t
, 0));
2542 pp_cxx_right_paren (pp
);
2546 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2548 pp_cxx_ws_string (pp
, "__builtin_addressof");
2549 pp_cxx_left_paren (pp
);
2550 pp
->expression (TREE_OPERAND (t
, 0));
2551 pp_cxx_right_paren (pp
);
2555 get_fold_operator (tree t
)
2557 ovl_op_info_t
*info
= OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t
),
2563 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2565 char const* op
= get_fold_operator (t
);
2566 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2567 pp_cxx_left_paren (pp
);
2568 pp_cxx_ws_string (pp
, "...");
2569 pp_cxx_ws_string (pp
, op
);
2570 pp
->expression (expr
);
2571 pp_cxx_right_paren (pp
);
2575 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2577 char const* op
= get_fold_operator (t
);
2578 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2579 pp_cxx_left_paren (pp
);
2580 pp
->expression (expr
);
2582 pp_cxx_ws_string (pp
, op
);
2583 pp_cxx_ws_string (pp
, "...");
2584 pp_cxx_right_paren (pp
);
2588 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2590 char const* op
= get_fold_operator (t
);
2591 tree t1
= TREE_OPERAND (t
, 1);
2592 tree t2
= TREE_OPERAND (t
, 2);
2593 if (t1
== FOLD_EXPR_PACK (t
))
2594 t1
= PACK_EXPANSION_PATTERN (t1
);
2596 t2
= PACK_EXPANSION_PATTERN (t2
);
2597 pp_cxx_left_paren (pp
);
2598 pp
->expression (t1
);
2599 pp_cxx_ws_string (pp
, op
);
2600 pp_cxx_ws_string (pp
, "...");
2601 pp_cxx_ws_string (pp
, op
);
2602 pp
->expression (t2
);
2603 pp_cxx_right_paren (pp
);
2607 pp_cxx_trait (cxx_pretty_printer
*pp
, tree t
)
2611 if (TREE_CODE (t
) == TRAIT_EXPR
)
2613 kind
= TRAIT_EXPR_KIND (t
);
2614 type1
= TRAIT_EXPR_TYPE1 (t
);
2615 type2
= TRAIT_EXPR_TYPE2 (t
);
2619 kind
= TRAIT_TYPE_KIND (t
);
2620 type1
= TRAIT_TYPE_TYPE1 (t
);
2621 type2
= TRAIT_TYPE_TYPE2 (t
);
2626 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2628 pp_cxx_ws_string (pp, NAME); \
2630 #include "cp-trait.def"
2634 if (kind
== CPTK_TYPE_PACK_ELEMENT
)
2636 pp_cxx_begin_template_argument_list (pp
);
2637 pp
->expression (type1
);
2641 pp_cxx_left_paren (pp
);
2643 pp
->type_id (type1
);
2645 pp
->expression (type1
);
2649 if (TREE_CODE (type2
) != TREE_VEC
)
2651 pp_cxx_separate_with (pp
, ',');
2652 pp
->type_id (type2
);
2655 for (tree arg
: tree_vec_range (type2
))
2657 pp_cxx_separate_with (pp
, ',');
2661 if (kind
== CPTK_TYPE_PACK_ELEMENT
)
2662 pp_cxx_end_template_argument_list (pp
);
2664 pp_cxx_right_paren (pp
);
2668 // 'requires' logical-or-expression
2670 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2674 pp
->padding
= pp_before
;
2675 pp_cxx_ws_string (pp
, "requires");
2682 compound-requirement
2684 nested-requirement */
2686 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2688 switch (TREE_CODE (t
))
2691 pp_cxx_simple_requirement (pp
, t
);
2695 pp_cxx_type_requirement (pp
, t
);
2699 pp_cxx_compound_requirement (pp
, t
);
2703 pp_cxx_nested_requirement (pp
, t
);
2711 // requirement-list:
2713 // requirement-list ';' requirement[opt]
2716 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2718 for (; t
; t
= TREE_CHAIN (t
))
2719 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2722 // requirement-body:
2723 // '{' requirement-list '}'
2725 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2727 pp_cxx_left_brace (pp
);
2728 pp_cxx_requirement_list (pp
, t
);
2729 pp_cxx_right_brace (pp
);
2732 // requires-expression:
2733 // 'requires' requirement-parameter-list requirement-body
2735 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2737 pp_string (pp
, "requires");
2738 if (tree parms
= REQUIRES_EXPR_PARMS (t
))
2741 pp_cxx_left_paren (pp
);
2742 for (; parms
; parms
= TREE_CHAIN (parms
))
2745 pp_cxx_separate_with (pp
, ',' );
2747 pp_cxx_parameter_declaration (pp
, parms
);
2749 pp_cxx_right_paren (pp
);
2750 pp_cxx_whitespace (pp
);
2752 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2755 /* simple-requirement:
2758 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2760 pp
->expression (TREE_OPERAND (t
, 0));
2761 pp_cxx_semicolon (pp
);
2764 /* type-requirement:
2765 typename type-name ';' */
2767 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2769 pp
->type_id (TREE_OPERAND (t
, 0));
2770 pp_cxx_semicolon (pp
);
2773 /* compound-requirement:
2774 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2776 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2778 pp_cxx_left_brace (pp
);
2779 pp
->expression (TREE_OPERAND (t
, 0));
2780 pp_cxx_right_brace (pp
);
2782 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2783 pp_cxx_ws_string (pp
, "noexcept");
2785 if (tree type
= TREE_OPERAND (t
, 1))
2787 pp_cxx_whitespace (pp
);
2788 pp_cxx_ws_string (pp
, "->");
2791 pp_cxx_semicolon (pp
);
2794 /* nested requirement:
2795 'requires' constraint-expression */
2797 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2799 pp_cxx_ws_string (pp
, "requires");
2800 pp
->expression (TREE_OPERAND (t
, 0));
2801 pp_cxx_semicolon (pp
);
2805 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2807 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2808 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2809 tree args
= CHECK_CONSTR_ARGS (t
);
2810 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2812 if (TREE_CODE (decl
) == CONCEPT_DECL
)
2813 pp
->expression (id
);
2814 else if (VAR_P (decl
))
2815 pp
->expression (id
);
2816 else if (TREE_CODE (decl
) == FUNCTION_DECL
)
2818 tree call
= build_vl_exp (CALL_EXPR
, 2);
2819 TREE_OPERAND (call
, 0) = integer_two_node
;
2820 TREE_OPERAND (call
, 1) = id
;
2821 pp
->expression (call
);
2827 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2831 pp_cxx_parameter_mapping (cxx_pretty_printer
*pp
, tree map
)
2833 pp_cxx_whitespace (pp
);
2834 pp_cxx_left_bracket (pp
);
2835 pp
->translate_string ("with");
2836 pp_cxx_whitespace (pp
);
2838 for (tree p
= map
; p
; p
= TREE_CHAIN (p
))
2840 tree parm
= TREE_VALUE (p
);
2841 tree arg
= TREE_PURPOSE (p
);
2845 else if (tree name
= DECL_NAME (TEMPLATE_PARM_DECL (parm
)))
2846 pp_cxx_tree_identifier (pp
, name
);
2848 pp
->translate_string ("<unnamed>");
2850 pp_cxx_whitespace (pp
);
2852 pp_cxx_whitespace (pp
);
2854 if (TYPE_P (arg
) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg
))
2857 pp
->expression (arg
);
2859 if (TREE_CHAIN (p
) != NULL_TREE
)
2860 pp_cxx_separate_with (pp
, ';');
2863 pp_cxx_right_bracket (pp
);
2867 pp_cxx_atomic_constraint (cxx_pretty_printer
*pp
, tree t
)
2869 /* Emit the expression. */
2870 pp
->expression (ATOMIC_CONSTR_EXPR (t
));
2872 /* Emit the parameter mapping. */
2873 tree map
= ATOMIC_CONSTR_MAP (t
);
2874 if (map
&& map
!= error_mark_node
)
2875 pp_cxx_parameter_mapping (pp
, map
);
2879 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2881 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2882 pp_string (pp
, " /\\ ");
2883 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2887 pp_cxx_disjunction (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_constraint (cxx_pretty_printer
*pp
, tree t
)
2897 if (t
== error_mark_node
)
2898 return pp
->expression (t
);
2900 switch (TREE_CODE (t
))
2903 pp_cxx_atomic_constraint (pp
, t
);
2907 pp_cxx_check_constraint (pp
, t
);
2911 pp_cxx_conjunction (pp
, t
);
2915 pp_cxx_disjunction (pp
, t
);
2918 case EXPR_PACK_EXPANSION
:
2919 pp
->expression (TREE_OPERAND (t
, 0));
2928 typedef c_pretty_print_fn pp_fun
;
2930 /* Initialization of a C++ pretty-printer object. */
2932 cxx_pretty_printer::cxx_pretty_printer ()
2933 : c_pretty_printer (),
2934 enclosing_scope (global_namespace
)
2936 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2937 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;
2940 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2943 cxx_pretty_printer::clone () const
2945 return new cxx_pretty_printer (*this);