1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2024 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_OBJECT_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
);
1124 if (DECL_NTTP_OBJECT_P (t
))
1126 /* Print the type followed by the CONSTRUCTOR value of the
1128 simple_type_specifier (cv_unqualified (TREE_TYPE (t
)));
1129 expression (DECL_INITIAL (t
));
1139 case TEMPLATE_TYPE_PARM
:
1140 case TEMPLATE_PARM_INDEX
:
1141 case TEMPLATE_TEMPLATE_PARM
:
1144 primary_expression (t
);
1148 case DYNAMIC_CAST_EXPR
:
1149 case STATIC_CAST_EXPR
:
1150 case REINTERPRET_CAST_EXPR
:
1151 case CONST_CAST_EXPR
:
1155 case EMPTY_CLASS_EXPR
:
1157 case PSEUDO_DTOR_EXPR
:
1158 case AGGR_INIT_EXPR
:
1160 postfix_expression (t
);
1165 pp_cxx_new_expression (this, t
);
1169 case VEC_DELETE_EXPR
:
1170 pp_cxx_delete_expression (this, t
);
1176 case UNARY_PLUS_EXPR
:
1177 unary_expression (t
);
1181 case IMPLICIT_CONV_EXPR
:
1182 pp_cxx_cast_expression (this, t
);
1188 pp_cxx_pm_expression (this, t
);
1192 case TRUNC_DIV_EXPR
:
1193 case TRUNC_MOD_EXPR
:
1194 case EXACT_DIV_EXPR
:
1196 multiplicative_expression (t
);
1200 conditional_expression (t
);
1207 assignment_expression (t
);
1210 case MUST_NOT_THROW_EXPR
:
1211 expression (TREE_OPERAND (t
, 0));
1214 case EXPR_PACK_EXPANSION
:
1215 expression (PACK_EXPANSION_PATTERN (t
));
1216 pp_cxx_ws_string (this, "...");
1219 case UNARY_LEFT_FOLD_EXPR
:
1220 pp_cxx_unary_left_fold_expression (this, t
);
1223 case UNARY_RIGHT_FOLD_EXPR
:
1224 pp_cxx_unary_right_fold_expression (this, t
);
1227 case BINARY_LEFT_FOLD_EXPR
:
1228 case BINARY_RIGHT_FOLD_EXPR
:
1229 pp_cxx_binary_fold_expression (this, t
);
1232 case TEMPLATE_ID_EXPR
:
1233 pp_cxx_template_id (this, t
);
1236 case NONTYPE_ARGUMENT_PACK
:
1238 tree args
= ARGUMENT_PACK_ARGS (t
);
1239 int i
, len
= TREE_VEC_LENGTH (args
);
1240 pp_cxx_left_brace (this);
1241 for (i
= 0; i
< len
; ++i
)
1244 pp_cxx_separate_with (this, ',');
1245 expression (TREE_VEC_ELT (args
, i
));
1247 pp_cxx_right_brace (this);
1252 pp_cxx_ws_string (this, "<lambda>");
1256 pp_cxx_trait (this, t
);
1263 pp_cxx_constraint (this, t
);
1267 pp_cxx_left_paren (this);
1268 expression (TREE_OPERAND (t
, 0));
1269 pp_cxx_right_paren (this);
1272 case VIEW_CONVERT_EXPR
:
1273 if (TREE_CODE (TREE_OPERAND (t
, 0)) == TEMPLATE_PARM_INDEX
)
1275 /* Strip const VIEW_CONVERT_EXPR wrappers for class NTTPs. */
1276 expression (TREE_OPERAND (t
, 0));
1281 c_pretty_printer::expression (t
);
1289 /* function-specifier:
1295 cxx_pretty_printer::function_specifier (tree t
)
1297 switch (TREE_CODE (t
))
1300 if (DECL_VIRTUAL_P (t
))
1301 pp_cxx_ws_string (this, "virtual");
1302 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
1303 pp_cxx_ws_string (this, "explicit");
1305 c_pretty_printer::function_specifier (t
);
1312 /* decl-specifier-seq:
1313 decl-specifier-seq(opt) decl-specifier
1316 storage-class-specifier
1323 cxx_pretty_printer::declaration_specifiers (tree t
)
1325 switch (TREE_CODE (t
))
1331 storage_class_specifier (t
);
1332 declaration_specifiers (TREE_TYPE (t
));
1336 pp_cxx_ws_string (this, "typedef");
1337 declaration_specifiers (TREE_TYPE (t
));
1341 /* Constructors don't have return types. And conversion functions
1342 do not have a type-specifier in their return types. */
1343 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
1344 function_specifier (t
);
1345 else if (DECL_IOBJ_MEMBER_FUNCTION_P (t
))
1346 declaration_specifiers (TREE_TYPE (TREE_TYPE (t
)));
1348 c_pretty_printer::declaration_specifiers (t
);
1351 c_pretty_printer::declaration_specifiers (t
);
1356 /* simple-type-specifier:
1357 ::(opt) nested-name-specifier(opt) type-name
1358 ::(opt) nested-name-specifier(opt) template(opt) template-id
1373 cxx_pretty_printer::simple_type_specifier (tree t
)
1375 switch (TREE_CODE (t
))
1380 pp_cxx_qualified_id (this, t
);
1383 case TEMPLATE_TYPE_PARM
:
1384 case TEMPLATE_TEMPLATE_PARM
:
1385 case TEMPLATE_PARM_INDEX
:
1386 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1387 pp_cxx_unqualified_id (this, t
);
1388 if (TREE_CODE (t
) == TEMPLATE_TYPE_PARM
)
1389 if (tree c
= PLACEHOLDER_TYPE_CONSTRAINTS (t
))
1390 pp_cxx_constrained_type_spec (this, c
);
1394 pp_cxx_ws_string (this, "typename");
1395 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t
));
1396 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t
));
1400 pp_cxx_ws_string (this, "decltype");
1401 pp_cxx_left_paren (this);
1402 this->expression (DECLTYPE_TYPE_EXPR (t
));
1403 pp_cxx_right_paren (this);
1407 pp_cxx_ws_string (this, "std::nullptr_t");
1411 pp_cxx_trait (this, t
);
1415 c_pretty_printer::simple_type_specifier (t
);
1420 /* type-specifier-seq:
1421 type-specifier type-specifier-seq(opt)
1424 simple-type-specifier
1427 elaborated-type-specifier
1431 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1433 switch (TREE_CODE (t
))
1436 case TEMPLATE_TYPE_PARM
:
1437 case TEMPLATE_TEMPLATE_PARM
:
1439 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1442 pp_cxx_cv_qualifier_seq (pp
, t
);
1443 pp
->simple_type_specifier (t
);
1447 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1448 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1449 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1453 if (TYPE_PTRMEMFUNC_P (t
))
1455 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
1456 pp
->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm
)));
1457 pp_cxx_whitespace (pp
);
1458 pp_cxx_ptr_operator (pp
, t
);
1464 if (TYPE_PTRDATAMEM_P (t
))
1466 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1467 pp_cxx_whitespace (pp
);
1468 pp_cxx_ptr_operator (pp
, t
);
1474 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1475 pp_c_specifier_qualifier_list (pp
, t
);
1480 * cv-qualifier-seq(opt)
1482 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1485 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1487 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1489 switch (TREE_CODE (t
))
1491 case REFERENCE_TYPE
:
1493 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1494 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1495 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1499 pp_cxx_cv_qualifier_seq (pp
, t
);
1506 if (TYPE_PTRMEMFUNC_P (t
))
1508 pp_cxx_left_paren (pp
);
1509 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1515 if (TYPE_PTRMEM_P (t
))
1517 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1518 pp_cxx_left_paren (pp
);
1519 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1521 pp_cxx_cv_qualifier_seq (pp
, t
);
1527 pp_unsupported_tree (pp
, t
);
1533 pp_cxx_implicit_parameter_type (tree mf
)
1535 return class_of_this_parm (TREE_TYPE (mf
));
1539 parameter-declaration:
1540 decl-specifier-seq declarator
1541 decl-specifier-seq declarator = assignment-expression
1542 decl-specifier-seq abstract-declarator(opt)
1543 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1546 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1548 pp
->declaration_specifiers (t
);
1550 pp
->abstract_declarator (t
);
1555 /* parameter-declaration-clause:
1556 parameter-declaration-list(opt) ...(opt)
1557 parameter-declaration-list , ...
1559 parameter-declaration-list:
1560 parameter-declaration
1561 parameter-declaration-list , parameter-declaration */
1564 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1566 gcc_assert (FUNC_OR_METHOD_TYPE_P (t
) || TREE_CODE (t
) == FUNCTION_DECL
);
1570 types
= TYPE_ARG_TYPES (t
);
1575 types
= FUNCTION_FIRST_USER_PARMTYPE (t
);
1576 args
= FUNCTION_FIRST_USER_PARM (t
);
1578 bool abstract
= !args
|| (pp
->flags
& pp_c_flag_abstract
);
1580 /* Skip artificial parameter for non-static member functions. */
1581 if (TREE_CODE (t
) == METHOD_TYPE
)
1582 types
= TREE_CHAIN (types
);
1585 pp_cxx_left_paren (pp
);
1586 for (; types
!= void_list_node
; types
= TREE_CHAIN (types
))
1589 pp_cxx_separate_with (pp
, ',');
1593 pp_cxx_ws_string (pp
, "...");
1596 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1597 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1599 pp_cxx_whitespace (pp
);
1601 pp_cxx_whitespace (pp
);
1602 pp
->assignment_expression (TREE_PURPOSE (types
));
1605 args
= TREE_CHAIN (args
);
1607 pp_cxx_right_paren (pp
);
1610 /* exception-specification:
1611 throw ( type-id-list(opt) )
1615 type-id-list , type-id */
1618 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1620 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1621 bool need_comma
= false;
1623 if (ex_spec
== NULL
)
1625 if (TREE_PURPOSE (ex_spec
))
1627 pp_cxx_ws_string (pp
, "noexcept");
1628 pp_cxx_whitespace (pp
);
1629 pp_cxx_left_paren (pp
);
1630 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1631 pp_cxx_ws_string (pp
, "<uninstantiated>");
1633 pp
->expression (TREE_PURPOSE (ex_spec
));
1634 pp_cxx_right_paren (pp
);
1637 pp_cxx_ws_string (pp
, "throw");
1638 pp_cxx_left_paren (pp
);
1639 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1641 tree type
= TREE_VALUE (ex_spec
);
1642 tree argpack
= NULL_TREE
;
1645 if (ARGUMENT_PACK_P (type
))
1647 argpack
= ARGUMENT_PACK_ARGS (type
);
1648 len
= TREE_VEC_LENGTH (argpack
);
1651 for (i
= 0; i
< len
; ++i
)
1654 type
= TREE_VEC_ELT (argpack
, i
);
1657 pp_cxx_separate_with (pp
, ',');
1664 pp_cxx_right_paren (pp
);
1667 /* direct-declarator:
1669 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1670 exception-specification(opt)
1671 direct-declaration [ constant-expression(opt) ]
1675 cxx_pretty_printer::direct_declarator (tree t
)
1677 switch (TREE_CODE (t
))
1685 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1687 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1688 || template_parameter_pack_p (t
))
1689 /* A function parameter pack or non-type template
1691 pp_cxx_ws_string (this, "...");
1693 id_expression (DECL_NAME (t
));
1695 abstract_declarator (TREE_TYPE (t
));
1699 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1701 pp_cxx_parameter_declaration_clause (this, t
);
1703 if (DECL_IOBJ_MEMBER_FUNCTION_P (t
))
1705 padding
= pp_before
;
1706 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1709 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1714 case TEMPLATE_TYPE_PARM
:
1715 case TEMPLATE_PARM_INDEX
:
1716 case TEMPLATE_TEMPLATE_PARM
:
1720 c_pretty_printer::direct_declarator (t
);
1727 ptr-operator declarator */
1730 cxx_pretty_printer::declarator (tree t
)
1732 direct_declarator (t
);
1734 // Print a requires clause.
1736 if (tree ci
= get_constraints (t
))
1737 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1738 pp_cxx_requires_clause (this, reqs
);
1741 /* ctor-initializer:
1742 : mem-initializer-list
1744 mem-initializer-list:
1746 mem-initializer , mem-initializer-list
1749 mem-initializer-id ( expression-list(opt) )
1752 ::(opt) nested-name-specifier(opt) class-name
1756 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1758 t
= TREE_OPERAND (t
, 0);
1759 pp_cxx_whitespace (pp
);
1761 pp_cxx_whitespace (pp
);
1762 for (; t
; t
= TREE_CHAIN (t
))
1764 tree purpose
= TREE_PURPOSE (t
);
1765 bool is_pack
= PACK_EXPANSION_P (purpose
);
1768 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1770 pp
->primary_expression (purpose
);
1771 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1773 pp_cxx_ws_string (pp
, "...");
1775 pp_cxx_separate_with (pp
, ',');
1779 /* function-definition:
1780 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1781 decl-specifier-seq(opt) declarator function-try-block */
1784 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1786 tree saved_scope
= pp
->enclosing_scope
;
1787 pp
->declaration_specifiers (t
);
1789 pp_needs_newline (pp
) = true;
1790 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1791 if (DECL_SAVED_TREE (t
))
1792 pp
->statement (DECL_SAVED_TREE (t
));
1794 pp_cxx_semicolon (pp
);
1795 pp_newline_and_flush (pp
);
1796 pp
->enclosing_scope
= saved_scope
;
1799 /* abstract-declarator:
1800 ptr-operator abstract-declarator(opt)
1801 direct-abstract-declarator */
1804 cxx_pretty_printer::abstract_declarator (tree t
)
1806 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1807 or a pointer-to-data-member of array type:
1812 but not for a pointer-to-data-member of non-array type:
1816 so be mindful of that. */
1817 if (TYPE_PTRMEMFUNC_P (t
)
1818 || (TYPE_PTRDATAMEM_P (t
)
1819 && TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
))
1820 pp_cxx_right_paren (this);
1821 else if (INDIRECT_TYPE_P (t
))
1823 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1824 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1825 pp_cxx_right_paren (this);
1828 direct_abstract_declarator (t
);
1831 /* direct-abstract-declarator:
1832 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1833 cv-qualifier-seq(opt) exception-specification(opt)
1834 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1835 ( abstract-declarator ) */
1838 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1840 switch (TREE_CODE (t
))
1842 case REFERENCE_TYPE
:
1843 abstract_declarator (t
);
1847 if (TYPE_PTRMEMFUNC_P (t
))
1848 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1852 if (TYPE_PTRDATAMEM_P (t
))
1853 direct_abstract_declarator (TREE_TYPE (t
));
1858 pp_cxx_parameter_declaration_clause (this, t
);
1859 direct_abstract_declarator (TREE_TYPE (t
));
1860 if (TREE_CODE (t
) == METHOD_TYPE
)
1862 padding
= pp_before
;
1863 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1865 pp_cxx_exception_specification (this, t
);
1869 case TEMPLATE_TYPE_PARM
:
1870 case TEMPLATE_TEMPLATE_PARM
:
1871 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1872 case UNBOUND_CLASS_TEMPLATE
:
1877 c_pretty_printer::direct_abstract_declarator (t
);
1883 type-specifier-seq abstract-declarator(opt) */
1886 cxx_pretty_printer::type_id (tree t
)
1888 pp_flags saved_flags
= flags
;
1889 flags
|= pp_c_flag_abstract
;
1891 switch (TREE_CODE (t
))
1898 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1899 case UNBOUND_CLASS_TEMPLATE
:
1900 case TEMPLATE_TEMPLATE_PARM
:
1901 case TEMPLATE_TYPE_PARM
:
1902 case TEMPLATE_PARM_INDEX
:
1908 case TEMPLATE_ID_EXPR
:
1910 pp_cxx_type_specifier_seq (this, t
);
1911 if (TYPE_PTRMEM_P (t
))
1912 abstract_declarator (t
);
1915 case TYPE_PACK_EXPANSION
:
1916 type_id (PACK_EXPANSION_PATTERN (t
));
1917 pp_cxx_ws_string (this, "...");
1920 case TYPE_ARGUMENT_PACK
:
1922 tree args
= ARGUMENT_PACK_ARGS (t
);
1923 int len
= TREE_VEC_LENGTH (args
);
1924 pp_cxx_left_brace (this);
1925 for (int i
= 0; i
< len
; ++i
)
1928 pp_cxx_separate_with (this, ',');
1929 type_id (TREE_VEC_ELT (args
, i
));
1931 pp_cxx_right_brace (this);
1936 c_pretty_printer::type_id (t
);
1940 flags
= saved_flags
;
1943 /* template-argument-list:
1944 template-argument ...(opt)
1945 template-argument-list, template-argument ...(opt)
1948 assignment-expression
1953 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1956 bool need_comma
= false;
1960 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1962 tree arg
= TREE_VEC_ELT (t
, i
);
1963 tree argpack
= NULL_TREE
;
1966 if (ARGUMENT_PACK_P (arg
))
1968 argpack
= ARGUMENT_PACK_ARGS (arg
);
1969 len
= TREE_VEC_LENGTH (argpack
);
1972 for (idx
= 0; idx
< len
; idx
++)
1975 arg
= TREE_VEC_ELT (argpack
, idx
);
1978 pp_cxx_separate_with (pp
, ',');
1982 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1983 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1986 pp
->expression (arg
);
1993 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1995 t
= DECL_EXPR_DECL (t
);
1996 pp_cxx_type_specifier_seq (pp
, t
);
1998 pp
->abstract_declarator (t
);
2006 cxx_pretty_printer::statement (tree t
)
2008 switch (TREE_CODE (t
))
2010 case CTOR_INITIALIZER
:
2011 pp_cxx_ctor_initializer (this, t
);
2015 pp_cxx_ws_string (this, "using");
2016 pp_cxx_ws_string (this, "namespace");
2017 if (DECL_CONTEXT (t
))
2018 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
2019 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
2023 pp_cxx_ws_string (this, "using");
2024 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
2025 pp_cxx_unqualified_id (this, DECL_NAME (t
));
2032 try compound-statement handler-seq */
2034 pp_maybe_newline_and_indent (this, 0);
2035 pp_cxx_ws_string (this, "try");
2036 pp_newline_and_indent (this, 3);
2037 statement (TRY_STMTS (t
));
2038 pp_newline_and_indent (this, -3);
2042 statement (TRY_HANDLERS (t
));
2047 handler handler-seq(opt)
2050 catch ( exception-declaration ) compound-statement
2052 exception-declaration:
2053 type-specifier-seq declarator
2054 type-specifier-seq abstract-declarator
2057 pp_cxx_ws_string (this, "catch");
2058 pp_cxx_left_paren (this);
2059 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
2060 pp_cxx_right_paren (this);
2061 pp_indentation (this) += 3;
2062 pp_needs_newline (this) = true;
2063 statement (HANDLER_BODY (t
));
2064 pp_indentation (this) -= 3;
2065 pp_needs_newline (this) = true;
2068 /* selection-statement:
2069 if ( expression ) statement
2070 if ( expression ) statement else statement */
2072 pp_cxx_ws_string (this, "if");
2073 pp_cxx_whitespace (this);
2074 pp_cxx_left_paren (this);
2075 expression (IF_COND (t
));
2076 pp_cxx_right_paren (this);
2077 pp_newline_and_indent (this, 2);
2078 statement (THEN_CLAUSE (t
));
2079 pp_newline_and_indent (this, -2);
2080 if (ELSE_CLAUSE (t
))
2082 tree else_clause
= ELSE_CLAUSE (t
);
2083 pp_cxx_ws_string (this, "else");
2084 if (TREE_CODE (else_clause
) == IF_STMT
)
2085 pp_cxx_whitespace (this);
2087 pp_newline_and_indent (this, 2);
2088 statement (else_clause
);
2089 if (TREE_CODE (else_clause
) != IF_STMT
)
2090 pp_newline_and_indent (this, -2);
2094 case RANGE_FOR_STMT
:
2095 pp_cxx_ws_string (this, "for");
2097 pp_cxx_left_paren (this);
2098 if (RANGE_FOR_INIT_STMT (t
))
2100 statement (RANGE_FOR_INIT_STMT (t
));
2101 pp_needs_newline (this) = false;
2102 pp_cxx_whitespace (this);
2104 statement (RANGE_FOR_DECL (t
));
2106 pp_needs_newline (this) = false;
2109 statement (RANGE_FOR_EXPR (t
));
2110 pp_cxx_right_paren (this);
2111 pp_newline_and_indent (this, 3);
2112 statement (FOR_BODY (t
));
2113 pp_indentation (this) -= 3;
2114 pp_needs_newline (this) = true;
2117 /* expression-statement:
2118 expression(opt) ; */
2120 expression (EXPR_STMT_EXPR (t
));
2121 pp_cxx_semicolon (this);
2122 pp_needs_newline (this) = true;
2126 pp_cxx_ws_string (this, "try");
2127 pp_newline_and_indent (this, 2);
2128 statement (CLEANUP_BODY (t
));
2129 pp_newline_and_indent (this, -2);
2130 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2131 pp_newline_and_indent (this, 2);
2132 statement (CLEANUP_EXPR (t
));
2133 pp_newline_and_indent (this, -2);
2141 pp_cxx_ws_string (this, "#pragma omp depobj");
2143 pp_cxx_left_paren (this);
2144 expression (OMP_DEPOBJ_DEPOBJ (t
));
2145 pp_cxx_right_paren (this);
2146 if (OMP_DEPOBJ_CLAUSES (t
) && OMP_DEPOBJ_CLAUSES (t
) != error_mark_node
)
2148 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t
)) == OMP_CLAUSE
)
2149 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t
),
2150 pp_indentation (this), TDF_NONE
);
2152 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t
)))
2154 case OMP_CLAUSE_DEPEND_IN
:
2155 pp_cxx_ws_string (this, " update(in)");
2157 case OMP_CLAUSE_DEPEND_INOUT
:
2158 pp_cxx_ws_string (this, " update(inout)");
2160 case OMP_CLAUSE_DEPEND_OUT
:
2161 pp_cxx_ws_string (this, " update(out)");
2163 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
2164 pp_cxx_ws_string (this, " update(mutexinoutset)");
2166 case OMP_CLAUSE_DEPEND_INOUTSET
:
2167 pp_cxx_ws_string (this, " update(inoutset)");
2169 case OMP_CLAUSE_DEPEND_LAST
:
2170 pp_cxx_ws_string (this, " destroy");
2176 pp_needs_newline (this) = true;
2180 c_pretty_printer::statement (t
);
2185 /* original-namespace-definition:
2186 namespace identifier { namespace-body }
2188 As an edge case, we also handle unnamed namespace definition here. */
2191 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2193 pp_cxx_ws_string (pp
, "namespace");
2194 if (DECL_CONTEXT (t
))
2195 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2197 pp_cxx_unqualified_id (pp
, t
);
2198 pp_cxx_whitespace (pp
);
2199 pp_cxx_left_brace (pp
);
2200 /* We do not print the namespace-body. */
2201 pp_cxx_whitespace (pp
);
2202 pp_cxx_right_brace (pp
);
2208 namespace-alias-definition:
2209 namespace identifier = qualified-namespace-specifier ;
2211 qualified-namespace-specifier:
2212 ::(opt) nested-name-specifier(opt) namespace-name */
2215 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2217 pp_cxx_ws_string (pp
, "namespace");
2218 if (DECL_CONTEXT (t
))
2219 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2220 pp_cxx_unqualified_id (pp
, t
);
2221 pp_cxx_whitespace (pp
);
2223 pp_cxx_whitespace (pp
);
2224 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2225 pp_cxx_nested_name_specifier (pp
,
2226 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2227 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2228 pp_cxx_semicolon (pp
);
2231 /* simple-declaration:
2232 decl-specifier-seq(opt) init-declarator-list(opt) */
2235 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2237 pp
->declaration_specifiers (t
);
2238 pp_cxx_init_declarator (pp
, t
);
2239 pp_cxx_semicolon (pp
);
2240 pp_needs_newline (pp
) = true;
2244 template-parameter-list:
2246 template-parameter-list , template-parameter */
2249 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2251 const int n
= TREE_VEC_LENGTH (t
);
2253 for (i
= 0; i
< n
; ++i
)
2256 pp_cxx_separate_with (pp
, ',');
2257 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2261 /* template-parameter:
2263 parameter-declaration
2266 class ...(opt) identifier(opt)
2267 class identifier(opt) = type-id
2268 typename identifier(opt)
2269 typename ...(opt) identifier(opt) = type-id
2270 template < template-parameter-list > class ...(opt) identifier(opt)
2271 template < template-parameter-list > class identifier(opt) = template-name */
2274 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2276 tree parameter
= TREE_VALUE (t
);
2277 switch (TREE_CODE (parameter
))
2280 pp_cxx_ws_string (pp
, "class");
2281 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2282 pp_cxx_ws_string (pp
, "...");
2283 if (DECL_NAME (parameter
))
2284 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2285 /* FIXME: Check if we should print also default argument. */
2289 pp_cxx_parameter_declaration (pp
, parameter
);
2296 pp_unsupported_tree (pp
, t
);
2301 /* Pretty-print a template parameter in the canonical form
2302 "template-parameter-<level>-<position in parameter list>". */
2305 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2307 const enum tree_code code
= TREE_CODE (parm
);
2309 /* Brings type template parameters to the canonical forms. */
2310 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2311 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2312 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2314 pp_cxx_begin_template_argument_list (pp
);
2315 pp
->translate_string ("template-parameter-");
2316 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2318 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2319 pp_cxx_end_template_argument_list (pp
);
2322 /* Print a constrained-type-specifier. */
2325 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2327 pp_cxx_whitespace (pp
);
2328 pp_cxx_left_bracket (pp
);
2329 pp
->translate_string ("requires");
2330 pp_cxx_whitespace (pp
);
2331 if (c
== error_mark_node
)
2333 pp_cxx_ws_string(pp
, "<unsatisfied-type-constraint>");
2337 placeholder_extract_concept_and_args (c
, t
, a
);
2338 pp
->id_expression (t
);
2339 pp_cxx_begin_template_argument_list (pp
);
2340 pp_cxx_ws_string (pp
, "<placeholder>");
2341 pp_cxx_separate_with (pp
, ',');
2342 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2343 for (int i
= 0; i
< TREE_VEC_LENGTH (a
) - 1; ++i
)
2344 TREE_VEC_ELT (args
, i
) = TREE_VEC_ELT (a
, i
+ 1);
2345 pp_cxx_template_argument_list (pp
, args
);
2347 pp_cxx_end_template_argument_list (pp
);
2348 pp_cxx_right_bracket (pp
);
2352 template-declaration:
2353 export(opt) template < template-parameter-list > declaration
2357 template-declaration:
2358 export(opt) template < template-parameter-list >
2359 requires-clause(opt) declaration */
2362 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2364 tree tmpl
= most_general_template (t
);
2367 pp_maybe_newline_and_indent (pp
, 0);
2368 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2370 pp_cxx_ws_string (pp
, "template");
2371 pp_cxx_begin_template_argument_list (pp
);
2372 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2373 pp_cxx_end_template_argument_list (pp
);
2374 pp_newline_and_indent (pp
, 3);
2378 if (tree ci
= get_constraints (t
))
2379 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2381 pp_cxx_requires_clause (pp
, reqs
);
2382 pp_newline_and_indent (pp
, 6);
2385 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2386 pp_cxx_function_definition (pp
, t
);
2387 else if (TREE_CODE (t
) == CONCEPT_DECL
)
2388 pp_cxx_concept_definition (pp
, t
);
2390 pp_cxx_simple_declaration (pp
, t
);
2394 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2396 pp_unsupported_tree (pp
, t
);
2400 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2402 pp_unsupported_tree (pp
, t
);
2406 pp_cxx_concept_definition (cxx_pretty_printer
*pp
, tree t
)
2408 pp_cxx_unqualified_id (pp
, DECL_NAME (t
));
2409 pp_cxx_whitespace (pp
);
2410 pp_cxx_ws_string (pp
, "=");
2411 pp_cxx_whitespace (pp
);
2412 pp
->expression (DECL_INITIAL (t
));
2413 pp_cxx_semicolon (pp
);
2420 template-declaration
2421 explicit-instantiation
2422 explicit-specialization
2423 linkage-specification
2424 namespace-definition
2429 namespace-alias-definition
2432 static_assert-declaration */
2434 cxx_pretty_printer::declaration (tree t
)
2436 if (TREE_CODE (t
) == STATIC_ASSERT
)
2438 pp_cxx_ws_string (this, "static_assert");
2439 pp_cxx_left_paren (this);
2440 expression (STATIC_ASSERT_CONDITION (t
));
2441 pp_cxx_separate_with (this, ',');
2442 expression (STATIC_ASSERT_MESSAGE (t
));
2443 pp_cxx_right_paren (this);
2445 else if (!DECL_LANG_SPECIFIC (t
))
2446 pp_cxx_simple_declaration (this, t
);
2447 else if (DECL_USE_TEMPLATE (t
))
2448 switch (DECL_USE_TEMPLATE (t
))
2451 pp_cxx_template_declaration (this, t
);
2455 pp_cxx_explicit_specialization (this, t
);
2459 pp_cxx_explicit_instantiation (this, t
);
2465 else switch (TREE_CODE (t
))
2469 pp_cxx_simple_declaration (this, t
);
2473 if (DECL_SAVED_TREE (t
))
2474 pp_cxx_function_definition (this, t
);
2476 pp_cxx_simple_declaration (this, t
);
2479 case NAMESPACE_DECL
:
2480 if (DECL_NAMESPACE_ALIAS (t
))
2481 pp_cxx_namespace_alias_definition (this, t
);
2483 pp_cxx_original_namespace_definition (this, t
);
2487 pp_unsupported_tree (this, t
);
2493 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2495 t
= TREE_OPERAND (t
, 0);
2496 pp_cxx_ws_string (pp
, "typeid");
2497 pp_cxx_left_paren (pp
);
2502 pp_cxx_right_paren (pp
);
2506 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2508 pp_cxx_ws_string (pp
, "va_arg");
2509 pp_cxx_left_paren (pp
);
2510 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2511 pp_cxx_separate_with (pp
, ',');
2512 pp
->type_id (TREE_TYPE (t
));
2513 pp_cxx_right_paren (pp
);
2517 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2519 switch (TREE_CODE (t
))
2522 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2523 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2525 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2526 pp_cxx_separate_with (pp
, ',');
2531 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2533 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2535 pp
->expression (TREE_OPERAND (t
, 1));
2538 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2540 pp_left_bracket (pp
);
2541 pp
->expression (TREE_OPERAND (t
, 1));
2542 pp_right_bracket (pp
);
2550 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2552 pp_cxx_ws_string (pp
, "offsetof");
2553 pp_cxx_left_paren (pp
);
2554 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2555 pp
->expression (TREE_OPERAND (t
, 0));
2556 pp_cxx_right_paren (pp
);
2560 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2562 pp_cxx_ws_string (pp
, "__builtin_addressof");
2563 pp_cxx_left_paren (pp
);
2564 pp
->expression (TREE_OPERAND (t
, 0));
2565 pp_cxx_right_paren (pp
);
2569 get_fold_operator (tree t
)
2571 ovl_op_info_t
*info
= OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t
),
2577 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2579 char const* op
= get_fold_operator (t
);
2580 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2581 pp_cxx_left_paren (pp
);
2582 pp_cxx_ws_string (pp
, "...");
2583 pp_cxx_ws_string (pp
, op
);
2584 pp
->expression (expr
);
2585 pp_cxx_right_paren (pp
);
2589 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2591 char const* op
= get_fold_operator (t
);
2592 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2593 pp_cxx_left_paren (pp
);
2594 pp
->expression (expr
);
2596 pp_cxx_ws_string (pp
, op
);
2597 pp_cxx_ws_string (pp
, "...");
2598 pp_cxx_right_paren (pp
);
2602 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2604 char const* op
= get_fold_operator (t
);
2605 tree t1
= TREE_OPERAND (t
, 1);
2606 tree t2
= TREE_OPERAND (t
, 2);
2607 if (t1
== FOLD_EXPR_PACK (t
))
2608 t1
= PACK_EXPANSION_PATTERN (t1
);
2610 t2
= PACK_EXPANSION_PATTERN (t2
);
2611 pp_cxx_left_paren (pp
);
2612 pp
->expression (t1
);
2613 pp_cxx_ws_string (pp
, op
);
2614 pp_cxx_ws_string (pp
, "...");
2615 pp_cxx_ws_string (pp
, op
);
2616 pp
->expression (t2
);
2617 pp_cxx_right_paren (pp
);
2621 pp_cxx_trait (cxx_pretty_printer
*pp
, tree t
)
2625 if (TREE_CODE (t
) == TRAIT_EXPR
)
2627 kind
= TRAIT_EXPR_KIND (t
);
2628 type1
= TRAIT_EXPR_TYPE1 (t
);
2629 type2
= TRAIT_EXPR_TYPE2 (t
);
2633 kind
= TRAIT_TYPE_KIND (t
);
2634 type1
= TRAIT_TYPE_TYPE1 (t
);
2635 type2
= TRAIT_TYPE_TYPE2 (t
);
2640 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2642 pp_cxx_ws_string (pp, NAME); \
2644 #include "cp-trait.def"
2648 if (kind
== CPTK_TYPE_PACK_ELEMENT
)
2650 pp_cxx_begin_template_argument_list (pp
);
2651 pp
->expression (type1
);
2655 pp_cxx_left_paren (pp
);
2657 pp
->type_id (type1
);
2659 pp
->expression (type1
);
2663 if (TREE_CODE (type2
) != TREE_VEC
)
2665 pp_cxx_separate_with (pp
, ',');
2666 pp
->type_id (type2
);
2669 for (tree arg
: tree_vec_range (type2
))
2671 pp_cxx_separate_with (pp
, ',');
2675 if (kind
== CPTK_TYPE_PACK_ELEMENT
)
2676 pp_cxx_end_template_argument_list (pp
);
2678 pp_cxx_right_paren (pp
);
2682 // 'requires' logical-or-expression
2684 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2688 pp
->padding
= pp_before
;
2689 pp_cxx_ws_string (pp
, "requires");
2696 compound-requirement
2698 nested-requirement */
2700 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2702 switch (TREE_CODE (t
))
2705 pp_cxx_simple_requirement (pp
, t
);
2709 pp_cxx_type_requirement (pp
, t
);
2713 pp_cxx_compound_requirement (pp
, t
);
2717 pp_cxx_nested_requirement (pp
, t
);
2725 // requirement-list:
2727 // requirement-list ';' requirement[opt]
2730 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2732 for (; t
; t
= TREE_CHAIN (t
))
2733 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2736 // requirement-body:
2737 // '{' requirement-list '}'
2739 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2741 pp_cxx_left_brace (pp
);
2742 pp_cxx_requirement_list (pp
, t
);
2743 pp_cxx_right_brace (pp
);
2746 // requires-expression:
2747 // 'requires' requirement-parameter-list requirement-body
2749 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2751 pp_string (pp
, "requires");
2752 if (tree parms
= REQUIRES_EXPR_PARMS (t
))
2755 pp_cxx_left_paren (pp
);
2756 for (; parms
; parms
= TREE_CHAIN (parms
))
2759 pp_cxx_separate_with (pp
, ',' );
2761 pp_cxx_parameter_declaration (pp
, parms
);
2763 pp_cxx_right_paren (pp
);
2764 pp_cxx_whitespace (pp
);
2766 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2769 /* simple-requirement:
2772 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2774 pp
->expression (TREE_OPERAND (t
, 0));
2775 pp_cxx_semicolon (pp
);
2778 /* type-requirement:
2779 typename type-name ';' */
2781 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2783 pp
->type_id (TREE_OPERAND (t
, 0));
2784 pp_cxx_semicolon (pp
);
2787 /* compound-requirement:
2788 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2790 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2792 pp_cxx_left_brace (pp
);
2793 pp
->expression (TREE_OPERAND (t
, 0));
2794 pp_cxx_right_brace (pp
);
2796 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2797 pp_cxx_ws_string (pp
, "noexcept");
2799 if (tree type
= TREE_OPERAND (t
, 1))
2801 pp_cxx_whitespace (pp
);
2802 pp_cxx_ws_string (pp
, "->");
2805 pp_cxx_semicolon (pp
);
2808 /* nested requirement:
2809 'requires' constraint-expression */
2811 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2813 pp_cxx_ws_string (pp
, "requires");
2814 pp
->expression (TREE_OPERAND (t
, 0));
2815 pp_cxx_semicolon (pp
);
2819 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2821 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2822 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2823 tree args
= CHECK_CONSTR_ARGS (t
);
2824 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2826 if (TREE_CODE (decl
) == CONCEPT_DECL
)
2827 pp
->expression (id
);
2828 else if (VAR_P (decl
))
2829 pp
->expression (id
);
2830 else if (TREE_CODE (decl
) == FUNCTION_DECL
)
2832 tree call
= build_vl_exp (CALL_EXPR
, 2);
2833 TREE_OPERAND (call
, 0) = integer_two_node
;
2834 TREE_OPERAND (call
, 1) = id
;
2835 pp
->expression (call
);
2841 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2845 pp_cxx_parameter_mapping (cxx_pretty_printer
*pp
, tree map
)
2847 pp_cxx_whitespace (pp
);
2848 pp_cxx_left_bracket (pp
);
2849 pp
->translate_string ("with");
2850 pp_cxx_whitespace (pp
);
2852 for (tree p
= map
; p
; p
= TREE_CHAIN (p
))
2854 tree parm
= TREE_VALUE (p
);
2855 tree arg
= TREE_PURPOSE (p
);
2859 else if (tree name
= DECL_NAME (TEMPLATE_PARM_DECL (parm
)))
2860 pp_cxx_tree_identifier (pp
, name
);
2862 pp
->translate_string ("<unnamed>");
2864 pp_cxx_whitespace (pp
);
2866 pp_cxx_whitespace (pp
);
2868 if (TYPE_P (arg
) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg
))
2871 pp
->expression (arg
);
2873 if (TREE_CHAIN (p
) != NULL_TREE
)
2874 pp_cxx_separate_with (pp
, ';');
2877 pp_cxx_right_bracket (pp
);
2881 pp_cxx_atomic_constraint (cxx_pretty_printer
*pp
, tree t
)
2883 /* Emit the expression. */
2884 pp
->expression (ATOMIC_CONSTR_EXPR (t
));
2886 /* Emit the parameter mapping. */
2887 tree map
= ATOMIC_CONSTR_MAP (t
);
2888 if (map
&& map
!= error_mark_node
)
2889 pp_cxx_parameter_mapping (pp
, map
);
2893 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2895 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2896 pp_string (pp
, " /\\ ");
2897 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2901 pp_cxx_disjunction (cxx_pretty_printer
*pp
, tree t
)
2903 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2904 pp_string (pp
, " \\/ ");
2905 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2909 pp_cxx_constraint (cxx_pretty_printer
*pp
, tree t
)
2911 if (t
== error_mark_node
)
2912 return pp
->expression (t
);
2914 switch (TREE_CODE (t
))
2917 pp_cxx_atomic_constraint (pp
, t
);
2921 pp_cxx_check_constraint (pp
, t
);
2925 pp_cxx_conjunction (pp
, t
);
2929 pp_cxx_disjunction (pp
, t
);
2932 case EXPR_PACK_EXPANSION
:
2933 pp
->expression (TREE_OPERAND (t
, 0));
2942 typedef c_pretty_print_fn pp_fun
;
2944 /* Initialization of a C++ pretty-printer object. */
2946 cxx_pretty_printer::cxx_pretty_printer ()
2947 : c_pretty_printer (),
2948 enclosing_scope (global_namespace
)
2950 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2951 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;
2954 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2957 cxx_pretty_printer::clone () const
2959 return new cxx_pretty_printer (*this);