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
);
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 NON_DEPENDENT_EXPR
:
1211 case MUST_NOT_THROW_EXPR
:
1212 expression (TREE_OPERAND (t
, 0));
1215 case EXPR_PACK_EXPANSION
:
1216 expression (PACK_EXPANSION_PATTERN (t
));
1217 pp_cxx_ws_string (this, "...");
1220 case UNARY_LEFT_FOLD_EXPR
:
1221 pp_cxx_unary_left_fold_expression (this, t
);
1224 case UNARY_RIGHT_FOLD_EXPR
:
1225 pp_cxx_unary_right_fold_expression (this, t
);
1228 case BINARY_LEFT_FOLD_EXPR
:
1229 case BINARY_RIGHT_FOLD_EXPR
:
1230 pp_cxx_binary_fold_expression (this, t
);
1233 case TEMPLATE_ID_EXPR
:
1234 pp_cxx_template_id (this, t
);
1237 case NONTYPE_ARGUMENT_PACK
:
1239 tree args
= ARGUMENT_PACK_ARGS (t
);
1240 int i
, len
= TREE_VEC_LENGTH (args
);
1241 pp_cxx_left_brace (this);
1242 for (i
= 0; i
< len
; ++i
)
1245 pp_cxx_separate_with (this, ',');
1246 expression (TREE_VEC_ELT (args
, i
));
1248 pp_cxx_right_brace (this);
1253 pp_cxx_ws_string (this, "<lambda>");
1257 pp_cxx_trait (this, t
);
1264 pp_cxx_constraint (this, t
);
1268 pp_cxx_left_paren (this);
1269 expression (TREE_OPERAND (t
, 0));
1270 pp_cxx_right_paren (this);
1273 case VIEW_CONVERT_EXPR
:
1274 if (TREE_CODE (TREE_OPERAND (t
, 0)) == TEMPLATE_PARM_INDEX
)
1276 /* Strip const VIEW_CONVERT_EXPR wrappers for class NTTPs. */
1277 expression (TREE_OPERAND (t
, 0));
1282 c_pretty_printer::expression (t
);
1290 /* function-specifier:
1296 cxx_pretty_printer::function_specifier (tree t
)
1298 switch (TREE_CODE (t
))
1301 if (DECL_VIRTUAL_P (t
))
1302 pp_cxx_ws_string (this, "virtual");
1303 else if (DECL_CONSTRUCTOR_P (t
) && DECL_NONCONVERTING_P (t
))
1304 pp_cxx_ws_string (this, "explicit");
1306 c_pretty_printer::function_specifier (t
);
1313 /* decl-specifier-seq:
1314 decl-specifier-seq(opt) decl-specifier
1317 storage-class-specifier
1324 cxx_pretty_printer::declaration_specifiers (tree t
)
1326 switch (TREE_CODE (t
))
1332 storage_class_specifier (t
);
1333 declaration_specifiers (TREE_TYPE (t
));
1337 pp_cxx_ws_string (this, "typedef");
1338 declaration_specifiers (TREE_TYPE (t
));
1342 /* Constructors don't have return types. And conversion functions
1343 do not have a type-specifier in their return types. */
1344 if (DECL_CONSTRUCTOR_P (t
) || DECL_CONV_FN_P (t
))
1345 function_specifier (t
);
1346 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1347 declaration_specifiers (TREE_TYPE (TREE_TYPE (t
)));
1349 c_pretty_printer::declaration_specifiers (t
);
1352 c_pretty_printer::declaration_specifiers (t
);
1357 /* simple-type-specifier:
1358 ::(opt) nested-name-specifier(opt) type-name
1359 ::(opt) nested-name-specifier(opt) template(opt) template-id
1374 cxx_pretty_printer::simple_type_specifier (tree t
)
1376 switch (TREE_CODE (t
))
1381 pp_cxx_qualified_id (this, t
);
1384 case TEMPLATE_TYPE_PARM
:
1385 case TEMPLATE_TEMPLATE_PARM
:
1386 case TEMPLATE_PARM_INDEX
:
1387 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1388 pp_cxx_unqualified_id (this, t
);
1389 if (TREE_CODE (t
) == TEMPLATE_TYPE_PARM
)
1390 if (tree c
= PLACEHOLDER_TYPE_CONSTRAINTS (t
))
1391 pp_cxx_constrained_type_spec (this, c
);
1395 pp_cxx_ws_string (this, "typename");
1396 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t
));
1397 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t
));
1401 pp_cxx_ws_string (this, "decltype");
1402 pp_cxx_left_paren (this);
1403 this->expression (DECLTYPE_TYPE_EXPR (t
));
1404 pp_cxx_right_paren (this);
1408 pp_cxx_ws_string (this, "std::nullptr_t");
1412 pp_cxx_trait (this, t
);
1416 c_pretty_printer::simple_type_specifier (t
);
1421 /* type-specifier-seq:
1422 type-specifier type-specifier-seq(opt)
1425 simple-type-specifier
1428 elaborated-type-specifier
1432 pp_cxx_type_specifier_seq (cxx_pretty_printer
*pp
, tree t
)
1434 switch (TREE_CODE (t
))
1437 case TEMPLATE_TYPE_PARM
:
1438 case TEMPLATE_TEMPLATE_PARM
:
1440 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1443 pp_cxx_cv_qualifier_seq (pp
, t
);
1444 pp
->simple_type_specifier (t
);
1448 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1449 pp_cxx_space_for_pointer_operator (pp
, TREE_TYPE (t
));
1450 pp_cxx_nested_name_specifier (pp
, TYPE_METHOD_BASETYPE (t
));
1454 if (TYPE_PTRMEMFUNC_P (t
))
1456 tree pfm
= TYPE_PTRMEMFUNC_FN_TYPE (t
);
1457 pp
->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm
)));
1458 pp_cxx_whitespace (pp
);
1459 pp_cxx_ptr_operator (pp
, t
);
1465 if (TYPE_PTRDATAMEM_P (t
))
1467 pp_cxx_type_specifier_seq (pp
, TREE_TYPE (t
));
1468 pp_cxx_whitespace (pp
);
1469 pp_cxx_ptr_operator (pp
, t
);
1475 if (!(TREE_CODE (t
) == FUNCTION_DECL
&& DECL_CONSTRUCTOR_P (t
)))
1476 pp_c_specifier_qualifier_list (pp
, t
);
1481 * cv-qualifier-seq(opt)
1483 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1486 pp_cxx_ptr_operator (cxx_pretty_printer
*pp
, tree t
)
1488 if (!TYPE_P (t
) && TREE_CODE (t
) != TYPE_DECL
)
1490 switch (TREE_CODE (t
))
1492 case REFERENCE_TYPE
:
1494 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t
)))
1495 pp_cxx_ptr_operator (pp
, TREE_TYPE (t
));
1496 pp_c_attributes_display (pp
, TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1500 pp_cxx_cv_qualifier_seq (pp
, t
);
1507 if (TYPE_PTRMEMFUNC_P (t
))
1509 pp_cxx_left_paren (pp
);
1510 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEMFUNC_OBJECT_TYPE (t
));
1516 if (TYPE_PTRMEM_P (t
))
1518 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
1519 pp_cxx_left_paren (pp
);
1520 pp_cxx_nested_name_specifier (pp
, TYPE_PTRMEM_CLASS_TYPE (t
));
1522 pp_cxx_cv_qualifier_seq (pp
, t
);
1528 pp_unsupported_tree (pp
, t
);
1534 pp_cxx_implicit_parameter_type (tree mf
)
1536 return class_of_this_parm (TREE_TYPE (mf
));
1540 parameter-declaration:
1541 decl-specifier-seq declarator
1542 decl-specifier-seq declarator = assignment-expression
1543 decl-specifier-seq abstract-declarator(opt)
1544 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1547 pp_cxx_parameter_declaration (cxx_pretty_printer
*pp
, tree t
)
1549 pp
->declaration_specifiers (t
);
1551 pp
->abstract_declarator (t
);
1556 /* parameter-declaration-clause:
1557 parameter-declaration-list(opt) ...(opt)
1558 parameter-declaration-list , ...
1560 parameter-declaration-list:
1561 parameter-declaration
1562 parameter-declaration-list , parameter-declaration */
1565 pp_cxx_parameter_declaration_clause (cxx_pretty_printer
*pp
, tree t
)
1567 gcc_assert (FUNC_OR_METHOD_TYPE_P (t
) || TREE_CODE (t
) == FUNCTION_DECL
);
1571 types
= TYPE_ARG_TYPES (t
);
1576 types
= FUNCTION_FIRST_USER_PARMTYPE (t
);
1577 args
= FUNCTION_FIRST_USER_PARM (t
);
1579 bool abstract
= !args
|| (pp
->flags
& pp_c_flag_abstract
);
1581 /* Skip artificial parameter for non-static member functions. */
1582 if (TREE_CODE (t
) == METHOD_TYPE
)
1583 types
= TREE_CHAIN (types
);
1586 pp_cxx_left_paren (pp
);
1587 for (; types
!= void_list_node
; types
= TREE_CHAIN (types
))
1590 pp_cxx_separate_with (pp
, ',');
1594 pp_cxx_ws_string (pp
, "...");
1597 pp_cxx_parameter_declaration (pp
, abstract
? TREE_VALUE (types
) : args
);
1598 if (!abstract
&& pp
->flags
& pp_cxx_flag_default_argument
)
1600 pp_cxx_whitespace (pp
);
1602 pp_cxx_whitespace (pp
);
1603 pp
->assignment_expression (TREE_PURPOSE (types
));
1606 args
= TREE_CHAIN (args
);
1608 pp_cxx_right_paren (pp
);
1611 /* exception-specification:
1612 throw ( type-id-list(opt) )
1616 type-id-list , type-id */
1619 pp_cxx_exception_specification (cxx_pretty_printer
*pp
, tree t
)
1621 tree ex_spec
= TYPE_RAISES_EXCEPTIONS (t
);
1622 bool need_comma
= false;
1624 if (ex_spec
== NULL
)
1626 if (TREE_PURPOSE (ex_spec
))
1628 pp_cxx_ws_string (pp
, "noexcept");
1629 pp_cxx_whitespace (pp
);
1630 pp_cxx_left_paren (pp
);
1631 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec
))
1632 pp_cxx_ws_string (pp
, "<uninstantiated>");
1634 pp
->expression (TREE_PURPOSE (ex_spec
));
1635 pp_cxx_right_paren (pp
);
1638 pp_cxx_ws_string (pp
, "throw");
1639 pp_cxx_left_paren (pp
);
1640 for (; ex_spec
&& TREE_VALUE (ex_spec
); ex_spec
= TREE_CHAIN (ex_spec
))
1642 tree type
= TREE_VALUE (ex_spec
);
1643 tree argpack
= NULL_TREE
;
1646 if (ARGUMENT_PACK_P (type
))
1648 argpack
= ARGUMENT_PACK_ARGS (type
);
1649 len
= TREE_VEC_LENGTH (argpack
);
1652 for (i
= 0; i
< len
; ++i
)
1655 type
= TREE_VEC_ELT (argpack
, i
);
1658 pp_cxx_separate_with (pp
, ',');
1665 pp_cxx_right_paren (pp
);
1668 /* direct-declarator:
1670 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1671 exception-specification(opt)
1672 direct-declaration [ constant-expression(opt) ]
1676 cxx_pretty_printer::direct_declarator (tree t
)
1678 switch (TREE_CODE (t
))
1686 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t
));
1688 if ((TREE_CODE (t
) == PARM_DECL
&& DECL_PACK_P (t
))
1689 || template_parameter_pack_p (t
))
1690 /* A function parameter pack or non-type template
1692 pp_cxx_ws_string (this, "...");
1694 id_expression (DECL_NAME (t
));
1696 abstract_declarator (TREE_TYPE (t
));
1700 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t
)));
1702 pp_cxx_parameter_declaration_clause (this, t
);
1704 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t
))
1706 padding
= pp_before
;
1707 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t
));
1710 pp_cxx_exception_specification (this, TREE_TYPE (t
));
1715 case TEMPLATE_TYPE_PARM
:
1716 case TEMPLATE_PARM_INDEX
:
1717 case TEMPLATE_TEMPLATE_PARM
:
1721 c_pretty_printer::direct_declarator (t
);
1728 ptr-operator declarator */
1731 cxx_pretty_printer::declarator (tree t
)
1733 direct_declarator (t
);
1735 // Print a requires clause.
1737 if (tree ci
= get_constraints (t
))
1738 if (tree reqs
= CI_DECLARATOR_REQS (ci
))
1739 pp_cxx_requires_clause (this, reqs
);
1742 /* ctor-initializer:
1743 : mem-initializer-list
1745 mem-initializer-list:
1747 mem-initializer , mem-initializer-list
1750 mem-initializer-id ( expression-list(opt) )
1753 ::(opt) nested-name-specifier(opt) class-name
1757 pp_cxx_ctor_initializer (cxx_pretty_printer
*pp
, tree t
)
1759 t
= TREE_OPERAND (t
, 0);
1760 pp_cxx_whitespace (pp
);
1762 pp_cxx_whitespace (pp
);
1763 for (; t
; t
= TREE_CHAIN (t
))
1765 tree purpose
= TREE_PURPOSE (t
);
1766 bool is_pack
= PACK_EXPANSION_P (purpose
);
1769 pp
->primary_expression (PACK_EXPANSION_PATTERN (purpose
));
1771 pp
->primary_expression (purpose
);
1772 pp_cxx_call_argument_list (pp
, TREE_VALUE (t
));
1774 pp_cxx_ws_string (pp
, "...");
1776 pp_cxx_separate_with (pp
, ',');
1780 /* function-definition:
1781 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1782 decl-specifier-seq(opt) declarator function-try-block */
1785 pp_cxx_function_definition (cxx_pretty_printer
*pp
, tree t
)
1787 tree saved_scope
= pp
->enclosing_scope
;
1788 pp
->declaration_specifiers (t
);
1790 pp_needs_newline (pp
) = true;
1791 pp
->enclosing_scope
= DECL_CONTEXT (t
);
1792 if (DECL_SAVED_TREE (t
))
1793 pp
->statement (DECL_SAVED_TREE (t
));
1795 pp_cxx_semicolon (pp
);
1796 pp_newline_and_flush (pp
);
1797 pp
->enclosing_scope
= saved_scope
;
1800 /* abstract-declarator:
1801 ptr-operator abstract-declarator(opt)
1802 direct-abstract-declarator */
1805 cxx_pretty_printer::abstract_declarator (tree t
)
1807 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1808 or a pointer-to-data-member of array type:
1813 but not for a pointer-to-data-member of non-array type:
1817 so be mindful of that. */
1818 if (TYPE_PTRMEMFUNC_P (t
)
1819 || (TYPE_PTRDATAMEM_P (t
)
1820 && TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
))
1821 pp_cxx_right_paren (this);
1822 else if (INDIRECT_TYPE_P (t
))
1824 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
1825 || TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
)
1826 pp_cxx_right_paren (this);
1829 direct_abstract_declarator (t
);
1832 /* direct-abstract-declarator:
1833 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1834 cv-qualifier-seq(opt) exception-specification(opt)
1835 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1836 ( abstract-declarator ) */
1839 cxx_pretty_printer::direct_abstract_declarator (tree t
)
1841 switch (TREE_CODE (t
))
1843 case REFERENCE_TYPE
:
1844 abstract_declarator (t
);
1848 if (TYPE_PTRMEMFUNC_P (t
))
1849 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t
));
1853 if (TYPE_PTRDATAMEM_P (t
))
1854 direct_abstract_declarator (TREE_TYPE (t
));
1859 pp_cxx_parameter_declaration_clause (this, t
);
1860 direct_abstract_declarator (TREE_TYPE (t
));
1861 if (TREE_CODE (t
) == METHOD_TYPE
)
1863 padding
= pp_before
;
1864 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t
));
1866 pp_cxx_exception_specification (this, t
);
1870 case TEMPLATE_TYPE_PARM
:
1871 case TEMPLATE_TEMPLATE_PARM
:
1872 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1873 case UNBOUND_CLASS_TEMPLATE
:
1878 c_pretty_printer::direct_abstract_declarator (t
);
1884 type-specifier-seq abstract-declarator(opt) */
1887 cxx_pretty_printer::type_id (tree t
)
1889 pp_flags saved_flags
= flags
;
1890 flags
|= pp_c_flag_abstract
;
1892 switch (TREE_CODE (t
))
1899 case BOUND_TEMPLATE_TEMPLATE_PARM
:
1900 case UNBOUND_CLASS_TEMPLATE
:
1901 case TEMPLATE_TEMPLATE_PARM
:
1902 case TEMPLATE_TYPE_PARM
:
1903 case TEMPLATE_PARM_INDEX
:
1909 case TEMPLATE_ID_EXPR
:
1911 pp_cxx_type_specifier_seq (this, t
);
1912 if (TYPE_PTRMEM_P (t
))
1913 abstract_declarator (t
);
1916 case TYPE_PACK_EXPANSION
:
1917 type_id (PACK_EXPANSION_PATTERN (t
));
1918 pp_cxx_ws_string (this, "...");
1921 case TYPE_ARGUMENT_PACK
:
1923 tree args
= ARGUMENT_PACK_ARGS (t
);
1924 int len
= TREE_VEC_LENGTH (args
);
1925 pp_cxx_left_brace (this);
1926 for (int i
= 0; i
< len
; ++i
)
1929 pp_cxx_separate_with (this, ',');
1930 type_id (TREE_VEC_ELT (args
, i
));
1932 pp_cxx_right_brace (this);
1937 c_pretty_printer::type_id (t
);
1941 flags
= saved_flags
;
1944 /* template-argument-list:
1945 template-argument ...(opt)
1946 template-argument-list, template-argument ...(opt)
1949 assignment-expression
1954 pp_cxx_template_argument_list (cxx_pretty_printer
*pp
, tree t
)
1957 bool need_comma
= false;
1961 for (i
= 0; i
< TREE_VEC_LENGTH (t
); ++i
)
1963 tree arg
= TREE_VEC_ELT (t
, i
);
1964 tree argpack
= NULL_TREE
;
1967 if (ARGUMENT_PACK_P (arg
))
1969 argpack
= ARGUMENT_PACK_ARGS (arg
);
1970 len
= TREE_VEC_LENGTH (argpack
);
1973 for (idx
= 0; idx
< len
; idx
++)
1976 arg
= TREE_VEC_ELT (argpack
, idx
);
1979 pp_cxx_separate_with (pp
, ',');
1983 if (TYPE_P (arg
) || (TREE_CODE (arg
) == TEMPLATE_DECL
1984 && TYPE_P (DECL_TEMPLATE_RESULT (arg
))))
1987 pp
->expression (arg
);
1994 pp_cxx_exception_declaration (cxx_pretty_printer
*pp
, tree t
)
1996 t
= DECL_EXPR_DECL (t
);
1997 pp_cxx_type_specifier_seq (pp
, t
);
1999 pp
->abstract_declarator (t
);
2007 cxx_pretty_printer::statement (tree t
)
2009 switch (TREE_CODE (t
))
2011 case CTOR_INITIALIZER
:
2012 pp_cxx_ctor_initializer (this, t
);
2016 pp_cxx_ws_string (this, "using");
2017 pp_cxx_ws_string (this, "namespace");
2018 if (DECL_CONTEXT (t
))
2019 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t
));
2020 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t
));
2024 pp_cxx_ws_string (this, "using");
2025 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t
));
2026 pp_cxx_unqualified_id (this, DECL_NAME (t
));
2033 try compound-statement handler-seq */
2035 pp_maybe_newline_and_indent (this, 0);
2036 pp_cxx_ws_string (this, "try");
2037 pp_newline_and_indent (this, 3);
2038 statement (TRY_STMTS (t
));
2039 pp_newline_and_indent (this, -3);
2043 statement (TRY_HANDLERS (t
));
2048 handler handler-seq(opt)
2051 catch ( exception-declaration ) compound-statement
2053 exception-declaration:
2054 type-specifier-seq declarator
2055 type-specifier-seq abstract-declarator
2058 pp_cxx_ws_string (this, "catch");
2059 pp_cxx_left_paren (this);
2060 pp_cxx_exception_declaration (this, HANDLER_PARMS (t
));
2061 pp_cxx_right_paren (this);
2062 pp_indentation (this) += 3;
2063 pp_needs_newline (this) = true;
2064 statement (HANDLER_BODY (t
));
2065 pp_indentation (this) -= 3;
2066 pp_needs_newline (this) = true;
2069 /* selection-statement:
2070 if ( expression ) statement
2071 if ( expression ) statement else statement */
2073 pp_cxx_ws_string (this, "if");
2074 pp_cxx_whitespace (this);
2075 pp_cxx_left_paren (this);
2076 expression (IF_COND (t
));
2077 pp_cxx_right_paren (this);
2078 pp_newline_and_indent (this, 2);
2079 statement (THEN_CLAUSE (t
));
2080 pp_newline_and_indent (this, -2);
2081 if (ELSE_CLAUSE (t
))
2083 tree else_clause
= ELSE_CLAUSE (t
);
2084 pp_cxx_ws_string (this, "else");
2085 if (TREE_CODE (else_clause
) == IF_STMT
)
2086 pp_cxx_whitespace (this);
2088 pp_newline_and_indent (this, 2);
2089 statement (else_clause
);
2090 if (TREE_CODE (else_clause
) != IF_STMT
)
2091 pp_newline_and_indent (this, -2);
2095 case RANGE_FOR_STMT
:
2096 pp_cxx_ws_string (this, "for");
2098 pp_cxx_left_paren (this);
2099 if (RANGE_FOR_INIT_STMT (t
))
2101 statement (RANGE_FOR_INIT_STMT (t
));
2102 pp_needs_newline (this) = false;
2103 pp_cxx_whitespace (this);
2105 statement (RANGE_FOR_DECL (t
));
2107 pp_needs_newline (this) = false;
2110 statement (RANGE_FOR_EXPR (t
));
2111 pp_cxx_right_paren (this);
2112 pp_newline_and_indent (this, 3);
2113 statement (FOR_BODY (t
));
2114 pp_indentation (this) -= 3;
2115 pp_needs_newline (this) = true;
2118 /* expression-statement:
2119 expression(opt) ; */
2121 expression (EXPR_STMT_EXPR (t
));
2122 pp_cxx_semicolon (this);
2123 pp_needs_newline (this) = true;
2127 pp_cxx_ws_string (this, "try");
2128 pp_newline_and_indent (this, 2);
2129 statement (CLEANUP_BODY (t
));
2130 pp_newline_and_indent (this, -2);
2131 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t
) ? "catch" : "finally");
2132 pp_newline_and_indent (this, 2);
2133 statement (CLEANUP_EXPR (t
));
2134 pp_newline_and_indent (this, -2);
2142 pp_cxx_ws_string (this, "#pragma omp depobj");
2144 pp_cxx_left_paren (this);
2145 expression (OMP_DEPOBJ_DEPOBJ (t
));
2146 pp_cxx_right_paren (this);
2147 if (OMP_DEPOBJ_CLAUSES (t
) && OMP_DEPOBJ_CLAUSES (t
) != error_mark_node
)
2149 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t
)) == OMP_CLAUSE
)
2150 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t
),
2151 pp_indentation (this), TDF_NONE
);
2153 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t
)))
2155 case OMP_CLAUSE_DEPEND_IN
:
2156 pp_cxx_ws_string (this, " update(in)");
2158 case OMP_CLAUSE_DEPEND_INOUT
:
2159 pp_cxx_ws_string (this, " update(inout)");
2161 case OMP_CLAUSE_DEPEND_OUT
:
2162 pp_cxx_ws_string (this, " update(out)");
2164 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET
:
2165 pp_cxx_ws_string (this, " update(mutexinoutset)");
2167 case OMP_CLAUSE_DEPEND_INOUTSET
:
2168 pp_cxx_ws_string (this, " update(inoutset)");
2170 case OMP_CLAUSE_DEPEND_LAST
:
2171 pp_cxx_ws_string (this, " destroy");
2177 pp_needs_newline (this) = true;
2181 c_pretty_printer::statement (t
);
2186 /* original-namespace-definition:
2187 namespace identifier { namespace-body }
2189 As an edge case, we also handle unnamed namespace definition here. */
2192 pp_cxx_original_namespace_definition (cxx_pretty_printer
*pp
, tree t
)
2194 pp_cxx_ws_string (pp
, "namespace");
2195 if (DECL_CONTEXT (t
))
2196 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2198 pp_cxx_unqualified_id (pp
, t
);
2199 pp_cxx_whitespace (pp
);
2200 pp_cxx_left_brace (pp
);
2201 /* We do not print the namespace-body. */
2202 pp_cxx_whitespace (pp
);
2203 pp_cxx_right_brace (pp
);
2209 namespace-alias-definition:
2210 namespace identifier = qualified-namespace-specifier ;
2212 qualified-namespace-specifier:
2213 ::(opt) nested-name-specifier(opt) namespace-name */
2216 pp_cxx_namespace_alias_definition (cxx_pretty_printer
*pp
, tree t
)
2218 pp_cxx_ws_string (pp
, "namespace");
2219 if (DECL_CONTEXT (t
))
2220 pp_cxx_nested_name_specifier (pp
, DECL_CONTEXT (t
));
2221 pp_cxx_unqualified_id (pp
, t
);
2222 pp_cxx_whitespace (pp
);
2224 pp_cxx_whitespace (pp
);
2225 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)))
2226 pp_cxx_nested_name_specifier (pp
,
2227 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t
)));
2228 pp_cxx_qualified_id (pp
, DECL_NAMESPACE_ALIAS (t
));
2229 pp_cxx_semicolon (pp
);
2232 /* simple-declaration:
2233 decl-specifier-seq(opt) init-declarator-list(opt) */
2236 pp_cxx_simple_declaration (cxx_pretty_printer
*pp
, tree t
)
2238 pp
->declaration_specifiers (t
);
2239 pp_cxx_init_declarator (pp
, t
);
2240 pp_cxx_semicolon (pp
);
2241 pp_needs_newline (pp
) = true;
2245 template-parameter-list:
2247 template-parameter-list , template-parameter */
2250 pp_cxx_template_parameter_list (cxx_pretty_printer
*pp
, tree t
)
2252 const int n
= TREE_VEC_LENGTH (t
);
2254 for (i
= 0; i
< n
; ++i
)
2257 pp_cxx_separate_with (pp
, ',');
2258 pp_cxx_template_parameter (pp
, TREE_VEC_ELT (t
, i
));
2262 /* template-parameter:
2264 parameter-declaration
2267 class ...(opt) identifier(opt)
2268 class identifier(opt) = type-id
2269 typename identifier(opt)
2270 typename ...(opt) identifier(opt) = type-id
2271 template < template-parameter-list > class ...(opt) identifier(opt)
2272 template < template-parameter-list > class identifier(opt) = template-name */
2275 pp_cxx_template_parameter (cxx_pretty_printer
*pp
, tree t
)
2277 tree parameter
= TREE_VALUE (t
);
2278 switch (TREE_CODE (parameter
))
2281 pp_cxx_ws_string (pp
, "class");
2282 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t
)))
2283 pp_cxx_ws_string (pp
, "...");
2284 if (DECL_NAME (parameter
))
2285 pp_cxx_tree_identifier (pp
, DECL_NAME (parameter
));
2286 /* FIXME: Check if we should print also default argument. */
2290 pp_cxx_parameter_declaration (pp
, parameter
);
2297 pp_unsupported_tree (pp
, t
);
2302 /* Pretty-print a template parameter in the canonical form
2303 "template-parameter-<level>-<position in parameter list>". */
2306 pp_cxx_canonical_template_parameter (cxx_pretty_printer
*pp
, tree parm
)
2308 const enum tree_code code
= TREE_CODE (parm
);
2310 /* Brings type template parameters to the canonical forms. */
2311 if (code
== TEMPLATE_TYPE_PARM
|| code
== TEMPLATE_TEMPLATE_PARM
2312 || code
== BOUND_TEMPLATE_TEMPLATE_PARM
)
2313 parm
= TEMPLATE_TYPE_PARM_INDEX (parm
);
2315 pp_cxx_begin_template_argument_list (pp
);
2316 pp
->translate_string ("template-parameter-");
2317 pp_wide_integer (pp
, TEMPLATE_PARM_LEVEL (parm
));
2319 pp_wide_integer (pp
, TEMPLATE_PARM_IDX (parm
) + 1);
2320 pp_cxx_end_template_argument_list (pp
);
2323 /* Print a constrained-type-specifier. */
2326 pp_cxx_constrained_type_spec (cxx_pretty_printer
*pp
, tree c
)
2328 pp_cxx_whitespace (pp
);
2329 pp_cxx_left_bracket (pp
);
2330 pp
->translate_string ("requires");
2331 pp_cxx_whitespace (pp
);
2332 if (c
== error_mark_node
)
2334 pp_cxx_ws_string(pp
, "<unsatisfied-type-constraint>");
2338 placeholder_extract_concept_and_args (c
, t
, a
);
2339 pp
->id_expression (t
);
2340 pp_cxx_begin_template_argument_list (pp
);
2341 pp_cxx_ws_string (pp
, "<placeholder>");
2342 pp_cxx_separate_with (pp
, ',');
2343 tree args
= make_tree_vec (TREE_VEC_LENGTH (a
) - 1);
2344 for (int i
= 0; i
< TREE_VEC_LENGTH (a
) - 1; ++i
)
2345 TREE_VEC_ELT (args
, i
) = TREE_VEC_ELT (a
, i
+ 1);
2346 pp_cxx_template_argument_list (pp
, args
);
2348 pp_cxx_end_template_argument_list (pp
);
2349 pp_cxx_right_bracket (pp
);
2353 template-declaration:
2354 export(opt) template < template-parameter-list > declaration
2358 template-declaration:
2359 export(opt) template < template-parameter-list >
2360 requires-clause(opt) declaration */
2363 pp_cxx_template_declaration (cxx_pretty_printer
*pp
, tree t
)
2365 tree tmpl
= most_general_template (t
);
2368 pp_maybe_newline_and_indent (pp
, 0);
2369 for (level
= DECL_TEMPLATE_PARMS (tmpl
); level
; level
= TREE_CHAIN (level
))
2371 pp_cxx_ws_string (pp
, "template");
2372 pp_cxx_begin_template_argument_list (pp
);
2373 pp_cxx_template_parameter_list (pp
, TREE_VALUE (level
));
2374 pp_cxx_end_template_argument_list (pp
);
2375 pp_newline_and_indent (pp
, 3);
2379 if (tree ci
= get_constraints (t
))
2380 if (tree reqs
= CI_TEMPLATE_REQS (ci
))
2382 pp_cxx_requires_clause (pp
, reqs
);
2383 pp_newline_and_indent (pp
, 6);
2386 if (TREE_CODE (t
) == FUNCTION_DECL
&& DECL_SAVED_TREE (t
))
2387 pp_cxx_function_definition (pp
, t
);
2388 else if (TREE_CODE (t
) == CONCEPT_DECL
)
2389 pp_cxx_concept_definition (pp
, t
);
2391 pp_cxx_simple_declaration (pp
, t
);
2395 pp_cxx_explicit_specialization (cxx_pretty_printer
*pp
, tree t
)
2397 pp_unsupported_tree (pp
, t
);
2401 pp_cxx_explicit_instantiation (cxx_pretty_printer
*pp
, tree t
)
2403 pp_unsupported_tree (pp
, t
);
2407 pp_cxx_concept_definition (cxx_pretty_printer
*pp
, tree t
)
2409 pp_cxx_unqualified_id (pp
, DECL_NAME (t
));
2410 pp_cxx_whitespace (pp
);
2411 pp_cxx_ws_string (pp
, "=");
2412 pp_cxx_whitespace (pp
);
2413 pp
->expression (DECL_INITIAL (t
));
2414 pp_cxx_semicolon (pp
);
2421 template-declaration
2422 explicit-instantiation
2423 explicit-specialization
2424 linkage-specification
2425 namespace-definition
2430 namespace-alias-definition
2433 static_assert-declaration */
2435 cxx_pretty_printer::declaration (tree t
)
2437 if (TREE_CODE (t
) == STATIC_ASSERT
)
2439 pp_cxx_ws_string (this, "static_assert");
2440 pp_cxx_left_paren (this);
2441 expression (STATIC_ASSERT_CONDITION (t
));
2442 pp_cxx_separate_with (this, ',');
2443 expression (STATIC_ASSERT_MESSAGE (t
));
2444 pp_cxx_right_paren (this);
2446 else if (!DECL_LANG_SPECIFIC (t
))
2447 pp_cxx_simple_declaration (this, t
);
2448 else if (DECL_USE_TEMPLATE (t
))
2449 switch (DECL_USE_TEMPLATE (t
))
2452 pp_cxx_template_declaration (this, t
);
2456 pp_cxx_explicit_specialization (this, t
);
2460 pp_cxx_explicit_instantiation (this, t
);
2466 else switch (TREE_CODE (t
))
2470 pp_cxx_simple_declaration (this, t
);
2474 if (DECL_SAVED_TREE (t
))
2475 pp_cxx_function_definition (this, t
);
2477 pp_cxx_simple_declaration (this, t
);
2480 case NAMESPACE_DECL
:
2481 if (DECL_NAMESPACE_ALIAS (t
))
2482 pp_cxx_namespace_alias_definition (this, t
);
2484 pp_cxx_original_namespace_definition (this, t
);
2488 pp_unsupported_tree (this, t
);
2494 pp_cxx_typeid_expression (cxx_pretty_printer
*pp
, tree t
)
2496 t
= TREE_OPERAND (t
, 0);
2497 pp_cxx_ws_string (pp
, "typeid");
2498 pp_cxx_left_paren (pp
);
2503 pp_cxx_right_paren (pp
);
2507 pp_cxx_va_arg_expression (cxx_pretty_printer
*pp
, tree t
)
2509 pp_cxx_ws_string (pp
, "va_arg");
2510 pp_cxx_left_paren (pp
);
2511 pp
->assignment_expression (TREE_OPERAND (t
, 0));
2512 pp_cxx_separate_with (pp
, ',');
2513 pp
->type_id (TREE_TYPE (t
));
2514 pp_cxx_right_paren (pp
);
2518 pp_cxx_offsetof_expression_1 (cxx_pretty_printer
*pp
, tree t
)
2520 switch (TREE_CODE (t
))
2523 if (TREE_CODE (TREE_OPERAND (t
, 0)) == STATIC_CAST_EXPR
2524 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t
, 0))))
2526 pp
->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t
, 0))));
2527 pp_cxx_separate_with (pp
, ',');
2532 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2534 if (TREE_CODE (TREE_OPERAND (t
, 0)) != ARROW_EXPR
)
2536 pp
->expression (TREE_OPERAND (t
, 1));
2539 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2541 pp_left_bracket (pp
);
2542 pp
->expression (TREE_OPERAND (t
, 1));
2543 pp_right_bracket (pp
);
2551 pp_cxx_offsetof_expression (cxx_pretty_printer
*pp
, tree t
)
2553 pp_cxx_ws_string (pp
, "offsetof");
2554 pp_cxx_left_paren (pp
);
2555 if (!pp_cxx_offsetof_expression_1 (pp
, TREE_OPERAND (t
, 0)))
2556 pp
->expression (TREE_OPERAND (t
, 0));
2557 pp_cxx_right_paren (pp
);
2561 pp_cxx_addressof_expression (cxx_pretty_printer
*pp
, tree t
)
2563 pp_cxx_ws_string (pp
, "__builtin_addressof");
2564 pp_cxx_left_paren (pp
);
2565 pp
->expression (TREE_OPERAND (t
, 0));
2566 pp_cxx_right_paren (pp
);
2570 get_fold_operator (tree t
)
2572 ovl_op_info_t
*info
= OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t
),
2578 pp_cxx_unary_left_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2580 char const* op
= get_fold_operator (t
);
2581 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2582 pp_cxx_left_paren (pp
);
2583 pp_cxx_ws_string (pp
, "...");
2584 pp_cxx_ws_string (pp
, op
);
2585 pp
->expression (expr
);
2586 pp_cxx_right_paren (pp
);
2590 pp_cxx_unary_right_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2592 char const* op
= get_fold_operator (t
);
2593 tree expr
= PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t
));
2594 pp_cxx_left_paren (pp
);
2595 pp
->expression (expr
);
2597 pp_cxx_ws_string (pp
, op
);
2598 pp_cxx_ws_string (pp
, "...");
2599 pp_cxx_right_paren (pp
);
2603 pp_cxx_binary_fold_expression (cxx_pretty_printer
*pp
, tree t
)
2605 char const* op
= get_fold_operator (t
);
2606 tree t1
= TREE_OPERAND (t
, 1);
2607 tree t2
= TREE_OPERAND (t
, 2);
2608 if (t1
== FOLD_EXPR_PACK (t
))
2609 t1
= PACK_EXPANSION_PATTERN (t1
);
2611 t2
= PACK_EXPANSION_PATTERN (t2
);
2612 pp_cxx_left_paren (pp
);
2613 pp
->expression (t1
);
2614 pp_cxx_ws_string (pp
, op
);
2615 pp_cxx_ws_string (pp
, "...");
2616 pp_cxx_ws_string (pp
, op
);
2617 pp
->expression (t2
);
2618 pp_cxx_right_paren (pp
);
2622 pp_cxx_trait (cxx_pretty_printer
*pp
, tree t
)
2626 if (TREE_CODE (t
) == TRAIT_EXPR
)
2628 kind
= TRAIT_EXPR_KIND (t
);
2629 type1
= TRAIT_EXPR_TYPE1 (t
);
2630 type2
= TRAIT_EXPR_TYPE2 (t
);
2634 kind
= TRAIT_TYPE_KIND (t
);
2635 type1
= TRAIT_TYPE_TYPE1 (t
);
2636 type2
= TRAIT_TYPE_TYPE2 (t
);
2641 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2643 pp_cxx_ws_string (pp, NAME); \
2645 #include "cp-trait.def"
2649 if (kind
== CPTK_TYPE_PACK_ELEMENT
)
2651 pp_cxx_begin_template_argument_list (pp
);
2652 pp
->expression (type1
);
2656 pp_cxx_left_paren (pp
);
2658 pp
->type_id (type1
);
2660 pp
->expression (type1
);
2664 if (TREE_CODE (type2
) != TREE_VEC
)
2666 pp_cxx_separate_with (pp
, ',');
2667 pp
->type_id (type2
);
2670 for (tree arg
: tree_vec_range (type2
))
2672 pp_cxx_separate_with (pp
, ',');
2676 if (kind
== CPTK_TYPE_PACK_ELEMENT
)
2677 pp_cxx_end_template_argument_list (pp
);
2679 pp_cxx_right_paren (pp
);
2683 // 'requires' logical-or-expression
2685 pp_cxx_requires_clause (cxx_pretty_printer
*pp
, tree t
)
2689 pp
->padding
= pp_before
;
2690 pp_cxx_ws_string (pp
, "requires");
2697 compound-requirement
2699 nested-requirement */
2701 pp_cxx_requirement (cxx_pretty_printer
*pp
, tree t
)
2703 switch (TREE_CODE (t
))
2706 pp_cxx_simple_requirement (pp
, t
);
2710 pp_cxx_type_requirement (pp
, t
);
2714 pp_cxx_compound_requirement (pp
, t
);
2718 pp_cxx_nested_requirement (pp
, t
);
2726 // requirement-list:
2728 // requirement-list ';' requirement[opt]
2731 pp_cxx_requirement_list (cxx_pretty_printer
*pp
, tree t
)
2733 for (; t
; t
= TREE_CHAIN (t
))
2734 pp_cxx_requirement (pp
, TREE_VALUE (t
));
2737 // requirement-body:
2738 // '{' requirement-list '}'
2740 pp_cxx_requirement_body (cxx_pretty_printer
*pp
, tree t
)
2742 pp_cxx_left_brace (pp
);
2743 pp_cxx_requirement_list (pp
, t
);
2744 pp_cxx_right_brace (pp
);
2747 // requires-expression:
2748 // 'requires' requirement-parameter-list requirement-body
2750 pp_cxx_requires_expr (cxx_pretty_printer
*pp
, tree t
)
2752 pp_string (pp
, "requires");
2753 if (tree parms
= REQUIRES_EXPR_PARMS (t
))
2756 pp_cxx_left_paren (pp
);
2757 for (; parms
; parms
= TREE_CHAIN (parms
))
2760 pp_cxx_separate_with (pp
, ',' );
2762 pp_cxx_parameter_declaration (pp
, parms
);
2764 pp_cxx_right_paren (pp
);
2765 pp_cxx_whitespace (pp
);
2767 pp_cxx_requirement_body (pp
, TREE_OPERAND (t
, 1));
2770 /* simple-requirement:
2773 pp_cxx_simple_requirement (cxx_pretty_printer
*pp
, tree t
)
2775 pp
->expression (TREE_OPERAND (t
, 0));
2776 pp_cxx_semicolon (pp
);
2779 /* type-requirement:
2780 typename type-name ';' */
2782 pp_cxx_type_requirement (cxx_pretty_printer
*pp
, tree t
)
2784 pp
->type_id (TREE_OPERAND (t
, 0));
2785 pp_cxx_semicolon (pp
);
2788 /* compound-requirement:
2789 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2791 pp_cxx_compound_requirement (cxx_pretty_printer
*pp
, tree t
)
2793 pp_cxx_left_brace (pp
);
2794 pp
->expression (TREE_OPERAND (t
, 0));
2795 pp_cxx_right_brace (pp
);
2797 if (COMPOUND_REQ_NOEXCEPT_P (t
))
2798 pp_cxx_ws_string (pp
, "noexcept");
2800 if (tree type
= TREE_OPERAND (t
, 1))
2802 pp_cxx_whitespace (pp
);
2803 pp_cxx_ws_string (pp
, "->");
2806 pp_cxx_semicolon (pp
);
2809 /* nested requirement:
2810 'requires' constraint-expression */
2812 pp_cxx_nested_requirement (cxx_pretty_printer
*pp
, tree t
)
2814 pp_cxx_ws_string (pp
, "requires");
2815 pp
->expression (TREE_OPERAND (t
, 0));
2816 pp_cxx_semicolon (pp
);
2820 pp_cxx_check_constraint (cxx_pretty_printer
*pp
, tree t
)
2822 tree decl
= CHECK_CONSTR_CONCEPT (t
);
2823 tree tmpl
= DECL_TI_TEMPLATE (decl
);
2824 tree args
= CHECK_CONSTR_ARGS (t
);
2825 tree id
= build_nt (TEMPLATE_ID_EXPR
, tmpl
, args
);
2827 if (TREE_CODE (decl
) == CONCEPT_DECL
)
2828 pp
->expression (id
);
2829 else if (VAR_P (decl
))
2830 pp
->expression (id
);
2831 else if (TREE_CODE (decl
) == FUNCTION_DECL
)
2833 tree call
= build_vl_exp (CALL_EXPR
, 2);
2834 TREE_OPERAND (call
, 0) = integer_two_node
;
2835 TREE_OPERAND (call
, 1) = id
;
2836 pp
->expression (call
);
2842 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2846 pp_cxx_parameter_mapping (cxx_pretty_printer
*pp
, tree map
)
2848 pp_cxx_whitespace (pp
);
2849 pp_cxx_left_bracket (pp
);
2850 pp
->translate_string ("with");
2851 pp_cxx_whitespace (pp
);
2853 for (tree p
= map
; p
; p
= TREE_CHAIN (p
))
2855 tree parm
= TREE_VALUE (p
);
2856 tree arg
= TREE_PURPOSE (p
);
2860 else if (tree name
= DECL_NAME (TEMPLATE_PARM_DECL (parm
)))
2861 pp_cxx_tree_identifier (pp
, name
);
2863 pp
->translate_string ("<unnamed>");
2865 pp_cxx_whitespace (pp
);
2867 pp_cxx_whitespace (pp
);
2869 if (TYPE_P (arg
) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg
))
2872 pp
->expression (arg
);
2874 if (TREE_CHAIN (p
) != NULL_TREE
)
2875 pp_cxx_separate_with (pp
, ';');
2878 pp_cxx_right_bracket (pp
);
2882 pp_cxx_atomic_constraint (cxx_pretty_printer
*pp
, tree t
)
2884 /* Emit the expression. */
2885 pp
->expression (ATOMIC_CONSTR_EXPR (t
));
2887 /* Emit the parameter mapping. */
2888 tree map
= ATOMIC_CONSTR_MAP (t
);
2889 if (map
&& map
!= error_mark_node
)
2890 pp_cxx_parameter_mapping (pp
, map
);
2894 pp_cxx_conjunction (cxx_pretty_printer
*pp
, tree t
)
2896 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2897 pp_string (pp
, " /\\ ");
2898 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2902 pp_cxx_disjunction (cxx_pretty_printer
*pp
, tree t
)
2904 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 0));
2905 pp_string (pp
, " \\/ ");
2906 pp_cxx_constraint (pp
, TREE_OPERAND (t
, 1));
2910 pp_cxx_constraint (cxx_pretty_printer
*pp
, tree t
)
2912 if (t
== error_mark_node
)
2913 return pp
->expression (t
);
2915 switch (TREE_CODE (t
))
2918 pp_cxx_atomic_constraint (pp
, t
);
2922 pp_cxx_check_constraint (pp
, t
);
2926 pp_cxx_conjunction (pp
, t
);
2930 pp_cxx_disjunction (pp
, t
);
2933 case EXPR_PACK_EXPANSION
:
2934 pp
->expression (TREE_OPERAND (t
, 0));
2943 typedef c_pretty_print_fn pp_fun
;
2945 /* Initialization of a C++ pretty-printer object. */
2947 cxx_pretty_printer::cxx_pretty_printer ()
2948 : c_pretty_printer (),
2949 enclosing_scope (global_namespace
)
2951 type_specifier_seq
= (pp_fun
) pp_cxx_type_specifier_seq
;
2952 parameter_list
= (pp_fun
) pp_cxx_parameter_declaration_clause
;
2955 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2958 cxx_pretty_printer::clone () const
2960 return new cxx_pretty_printer (*this);