Daily bump.
[official-gcc.git] / gcc / cp / cxx-pretty-print.cc
blobc6d8cc84132b83f2fe662e8bb56b41c8898813ef
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
10 version.
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
15 for more details.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "cp-tree.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);
44 static inline void
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);
51 pp_character (pp, c);
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)
64 void
65 pp_cxx_colon_colon (cxx_pretty_printer *pp)
67 pp_colon_colon (pp);
68 pp->padding = pp_none;
71 void
72 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
74 pp_cxx_nonconsecutive_character (pp, '<');
77 void
78 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
80 pp_cxx_nonconsecutive_character (pp, '>');
83 void
84 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
86 pp_separate_with (pp, c);
87 pp->padding = pp_none;
90 /* Expressions. */
92 /* conversion-function-id:
93 operator conversion-type-id
95 conversion-type-id:
96 type-specifier-seq conversion-declarator(opt)
98 conversion-declarator:
99 ptr-operator conversion-declarator(opt) */
101 static inline void
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));
108 static inline void
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.
119 unqualified-id:
120 identifier
121 operator-function-id
122 conversion-function-id
123 ~ class-name
124 template-id */
126 static void
127 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
129 enum tree_code code = TREE_CODE (t);
130 switch (code)
132 case RESULT_DECL:
133 pp->translate_string ("<return-value>");
134 break;
136 case OVERLOAD:
137 t = OVL_FIRST (t);
138 /* FALLTHRU */
139 case VAR_DECL:
140 case PARM_DECL:
141 case CONST_DECL:
142 case TYPE_DECL:
143 case FUNCTION_DECL:
144 case NAMESPACE_DECL:
145 case FIELD_DECL:
146 case LABEL_DECL:
147 case USING_DECL:
148 case TEMPLATE_DECL:
149 t = DECL_NAME (t);
150 /* FALLTHRU */
152 case IDENTIFIER_NODE:
153 if (t == NULL)
154 pp->translate_string ("<unnamed>");
155 else if (IDENTIFIER_CONV_OP_P (t))
156 pp_cxx_conversion_function_id (pp, t);
157 else
158 pp_cxx_tree_identifier (pp, t);
159 break;
161 case TEMPLATE_ID_EXPR:
162 pp_cxx_template_id (pp, t);
163 break;
165 case BASELINK:
166 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
167 break;
169 case RECORD_TYPE:
170 case UNION_TYPE:
171 case ENUMERAL_TYPE:
172 case TYPENAME_TYPE:
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);
183 break;
185 case BIT_NOT_EXPR:
186 pp_cxx_complement (pp);
187 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
188 break;
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));
200 else
201 pp_cxx_canonical_template_parameter (pp, t);
202 break;
204 case TEMPLATE_PARM_INDEX:
205 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
206 break;
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);
214 break;
216 default:
217 pp_unsupported_tree (pp, t);
218 break;
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. */
227 static inline void
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 */
239 static void
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);
259 /* qualified-id:
260 nested-name-specifier template(opt) unqualified-id */
262 static void
263 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
265 switch (TREE_CODE (t))
267 /* A pointer-to-member is always qualified. */
268 case PTRMEM_CST:
269 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
270 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
271 break;
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. */
281 case OVERLOAD:
282 t = OVL_FIRST (t);
283 /* FALLTHRU */
284 case FUNCTION_DECL:
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));
290 break;
292 case OFFSET_REF:
293 case SCOPE_REF:
294 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
295 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
296 break;
298 default:
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);
308 break;
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. */
317 static void
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))
328 break;
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));
337 else
339 /* Value must have been cast. */
340 pp_c_type_cast (pp, type);
341 pp_c_integer_constant (pp, e);
346 void
347 cxx_pretty_printer::constant (tree t)
349 switch (TREE_CODE (t))
351 case STRING_CST:
353 const bool in_parens = PAREN_STRING_LITERAL_P (t);
354 if (in_parens)
355 pp_cxx_left_paren (this);
356 c_pretty_printer::constant (t);
357 if (in_parens)
358 pp_cxx_right_paren (this);
360 break;
362 case INTEGER_CST:
363 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
365 pp_string (this, "nullptr");
366 break;
368 else if (TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
370 pp_cxx_enumeration_constant (this, t);
371 break;
373 /* fall through. */
375 default:
376 c_pretty_printer::constant (t);
377 break;
381 /* id-expression:
382 unqualified-id
383 qualified-id */
385 void
386 cxx_pretty_printer::id_expression (tree t)
388 if (TREE_CODE (t) == OVERLOAD)
389 t = OVL_FIRST (t);
390 if (DECL_P (t) && DECL_CONTEXT (t))
391 pp_cxx_qualified_id (this, t);
392 else
393 pp_cxx_unqualified_id (this, t);
396 /* user-defined literal:
397 literal ud-suffix */
399 void
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:
408 literal
409 this
410 :: identifier
411 :: operator-function-id
412 :: qualifier-id
413 ( expression )
414 id-expression
416 GNU Extensions:
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 )
436 __is_pod ( type-id )
437 __is_polymorphic ( type-id )
438 __is_std_layout ( type-id )
439 __is_trivial ( type-id )
440 __is_union ( type-id ) */
442 void
443 cxx_pretty_printer::primary_expression (tree t)
445 switch (TREE_CODE (t))
447 case VOID_CST:
448 case INTEGER_CST:
449 case REAL_CST:
450 case COMPLEX_CST:
451 case STRING_CST:
452 constant (t);
453 break;
455 case USERDEF_LITERAL:
456 pp_cxx_userdef_literal (this, t);
457 break;
459 case BASELINK:
460 t = BASELINK_FUNCTIONS (t);
461 /* FALLTHRU */
462 case VAR_DECL:
463 case PARM_DECL:
464 case FIELD_DECL:
465 case FUNCTION_DECL:
466 case OVERLOAD:
467 case CONST_DECL:
468 case TEMPLATE_DECL:
469 id_expression (t);
470 break;
472 case RESULT_DECL:
473 case TEMPLATE_TYPE_PARM:
474 case TEMPLATE_TEMPLATE_PARM:
475 case TEMPLATE_PARM_INDEX:
476 pp_cxx_unqualified_id (this, t);
477 break;
479 case STMT_EXPR:
480 pp_cxx_left_paren (this);
481 statement (STMT_EXPR_STMT (t));
482 pp_cxx_right_paren (this);
483 break;
485 case TRAIT_EXPR:
486 pp_cxx_trait (this, t);
487 break;
489 case VA_ARG_EXPR:
490 pp_cxx_va_arg_expression (this, t);
491 break;
493 case OFFSETOF_EXPR:
494 pp_cxx_offsetof_expression (this, t);
495 break;
497 case ADDRESSOF_EXPR:
498 pp_cxx_addressof_expression (this, t);
499 break;
501 case REQUIRES_EXPR:
502 pp_cxx_requires_expr (this, t);
503 break;
505 default:
506 c_pretty_printer::primary_expression (t);
507 break;
511 /* postfix-expression:
512 primary-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 ) */
532 void
533 cxx_pretty_printer::postfix_expression (tree t)
535 enum tree_code code = TREE_CODE (t);
537 switch (code)
539 case AGGR_INIT_EXPR:
540 case CALL_EXPR:
542 tree fun = cp_get_callee (t);
543 tree saved_scope = enclosing_scope;
544 bool skipfirst = false;
545 tree arg;
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);
573 pp_cxx_dot (this);
575 else
577 postfix_expression (object);
578 pp_cxx_arrow (this);
580 skipfirst = true;
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)
592 if (skipfirst)
593 skipfirst = false;
594 else
596 expression (arg);
597 if (more_aggr_init_expr_args_p (&iter))
598 pp_cxx_separate_with (this, ',');
602 else
604 call_expr_arg_iterator iter;
605 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
607 if (skipfirst)
608 skipfirst = false;
609 else
611 expression (arg);
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));
624 break;
626 case BASELINK:
627 case VAR_DECL:
628 case PARM_DECL:
629 case FIELD_DECL:
630 case FUNCTION_DECL:
631 case OVERLOAD:
632 case CONST_DECL:
633 case TEMPLATE_DECL:
634 case RESULT_DECL:
635 primary_expression (t);
636 break;
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");
648 else
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);
656 break;
658 case BIT_CAST_EXPR:
659 pp_cxx_ws_string (this, "__builtin_bit_cast");
660 pp_left_paren (this);
661 type_id (TREE_TYPE (t));
662 pp_comma (this);
663 expression (TREE_OPERAND (t, 0));
664 pp_right_paren (this);
665 break;
667 case EMPTY_CLASS_EXPR:
668 type_id (TREE_TYPE (t));
669 pp_left_paren (this);
670 pp_right_paren (this);
671 break;
673 case TYPEID_EXPR:
674 pp_cxx_typeid_expression (this, t);
675 break;
677 case PSEUDO_DTOR_EXPR:
678 postfix_expression (TREE_OPERAND (t, 0));
679 pp_cxx_dot (this);
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));
687 break;
689 case ARROW_EXPR:
690 postfix_expression (TREE_OPERAND (t, 0));
691 pp_cxx_arrow (this);
692 break;
694 default:
695 c_pretty_printer::postfix_expression (t);
696 break;
700 /* new-expression:
701 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
702 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
704 new-placement:
705 ( expression-list )
707 new-type-id:
708 type-specifier-seq new-declarator(opt)
710 new-declarator:
711 ptr-operator new-declarator(opt)
712 direct-new-declarator
714 direct-new-declarator
715 [ expression ]
716 direct-new-declarator [ constant-expression ]
718 new-initializer:
719 ( expression-list(opt) ) */
721 static void
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);
727 switch (code)
729 case NEW_EXPR:
730 case VEC_NEW_EXPR:
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));
737 pp_space (pp);
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),
745 integer_one_node)));
746 pp->type_id (type);
747 if (init)
749 pp_left_paren (pp);
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. */
754 else
755 pp->expression (init);
756 pp_right_paren (pp);
758 break;
760 default:
761 pp_unsupported_tree (pp, t);
765 /* delete-expression:
766 ::(opt) delete cast-expression
767 ::(opt) delete [ ] cast-expression */
769 static void
770 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
772 enum tree_code code = TREE_CODE (t);
773 switch (code)
775 case DELETE_EXPR:
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");
780 pp_space (pp);
781 if (code == VEC_DELETE_EXPR
782 || DELETE_EXPR_USE_VEC (t))
784 pp_left_bracket (pp);
785 pp_right_bracket (pp);
786 pp_space (pp);
788 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
789 break;
791 default:
792 pp_unsupported_tree (pp, t);
796 /* unary-expression:
797 postfix-expression
798 ++ cast-expression
799 -- cast-expression
800 unary-operator cast-expression
801 sizeof unary-expression
802 sizeof ( type-id )
803 sizeof ... ( identifier )
804 new-expression
805 delete-expression
807 unary-operator: one of
808 * & + - !
810 GNU extensions:
811 __alignof__ unary-expression
812 __alignof__ ( type-id ) */
814 void
815 cxx_pretty_printer::unary_expression (tree t)
817 enum tree_code code = TREE_CODE (t);
818 switch (code)
820 case NEW_EXPR:
821 case VEC_NEW_EXPR:
822 pp_cxx_new_expression (this, t);
823 break;
825 case DELETE_EXPR:
826 case VEC_DELETE_EXPR:
827 pp_cxx_delete_expression (this, t);
828 break;
830 case SIZEOF_EXPR:
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));
839 else
840 unary_expression (TREE_OPERAND (t, 0));
841 pp_cxx_right_paren (this);
842 break;
844 /* Fall through */
846 case ALIGNOF_EXPR:
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");
851 else
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);
866 else
867 unary_expression (TREE_OPERAND (t, 0));
868 break;
870 case AT_ENCODE_EXPR:
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);
876 break;
878 case NOEXCEPT_EXPR:
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);
884 break;
886 case UNARY_PLUS_EXPR:
887 pp_plus (this);
888 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
889 break;
891 default:
892 c_pretty_printer::unary_expression (t);
893 break;
897 /* cast-expression:
898 unary-expression
899 ( type-id ) cast-expression */
901 static void
902 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
904 switch (TREE_CODE (t))
906 case CAST_EXPR:
907 case IMPLICIT_CONV_EXPR:
908 pp->type_id (TREE_TYPE (t));
909 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
910 break;
912 default:
913 pp_c_cast_expression (pp, t);
914 break;
918 /* pm-expression:
919 cast-expression
920 pm-expression .* cast-expression
921 pm-expression ->* cast-expression */
923 static void
924 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
926 switch (TREE_CODE (t))
928 /* Handle unfortunate OFFSET_REF overloading here. */
929 case OFFSET_REF:
930 if (TYPE_P (TREE_OPERAND (t, 0)))
932 pp_cxx_qualified_id (pp, t);
933 break;
935 /* Fall through. */
936 case MEMBER_REF:
937 case DOTSTAR_EXPR:
938 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
939 if (TREE_CODE (t) == MEMBER_REF)
940 pp_cxx_arrow (pp);
941 else
942 pp_cxx_dot (pp);
943 pp_star(pp);
944 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
945 break;
948 default:
949 pp_cxx_cast_expression (pp, t);
950 break;
954 /* multiplicative-expression:
955 pm-expression
956 multiplicative-expression * pm-expression
957 multiplicative-expression / pm-expression
958 multiplicative-expression % pm-expression */
960 void
961 cxx_pretty_printer::multiplicative_expression (tree e)
963 enum tree_code code = TREE_CODE (e);
964 switch (code)
966 case MULT_EXPR:
967 case TRUNC_DIV_EXPR:
968 case TRUNC_MOD_EXPR:
969 case EXACT_DIV_EXPR:
970 case RDIV_EXPR:
971 multiplicative_expression (TREE_OPERAND (e, 0));
972 pp_space (this);
973 if (code == MULT_EXPR)
974 pp_star (this);
975 else if (code != TRUNC_MOD_EXPR)
976 pp_slash (this);
977 else
978 pp_modulo (this);
979 pp_space (this);
980 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
981 break;
983 default:
984 pp_cxx_pm_expression (this, e);
985 break;
989 /* conditional-expression:
990 logical-or-expression
991 logical-or-expression ? expression : assignment-expression */
993 void
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));
999 pp_space (this);
1000 pp_question (this);
1001 pp_space (this);
1002 expression (TREE_OPERAND (e, 1));
1003 pp_space (this);
1004 assignment_expression (TREE_OPERAND (e, 2));
1006 else
1007 pp_c_logical_or_expression (this, e);
1010 /* Pretty-print a compound assignment operator token as indicated by T. */
1012 static void
1013 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
1015 const char *op;
1017 switch (TREE_CODE (t))
1019 case NOP_EXPR:
1020 op = "=";
1021 break;
1023 case PLUS_EXPR:
1024 op = "+=";
1025 break;
1027 case MINUS_EXPR:
1028 op = "-=";
1029 break;
1031 case TRUNC_DIV_EXPR:
1032 op = "/=";
1033 break;
1035 case TRUNC_MOD_EXPR:
1036 op = "%=";
1037 break;
1039 default:
1040 op = get_tree_code_name (TREE_CODE (t));
1041 break;
1044 pp_cxx_ws_string (pp, op);
1048 /* assignment-expression:
1049 conditional-expression
1050 logical-or-expression assignment-operator assignment-expression
1051 throw-expression
1053 throw-expression:
1054 throw assignment-expression(opt)
1056 assignment-operator: one of
1057 = *= /= %= += -= >>= <<= &= ^= |= */
1059 void
1060 cxx_pretty_printer::assignment_expression (tree e)
1062 switch (TREE_CODE (e))
1064 case MODIFY_EXPR:
1065 case INIT_EXPR:
1066 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1067 pp_space (this);
1068 pp_equal (this);
1069 pp_space (this);
1070 assignment_expression (TREE_OPERAND (e, 1));
1071 break;
1073 case THROW_EXPR:
1074 pp_cxx_ws_string (this, "throw");
1075 if (TREE_OPERAND (e, 0))
1076 assignment_expression (TREE_OPERAND (e, 0));
1077 break;
1079 case MODOP_EXPR:
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));
1083 break;
1085 default:
1086 conditional_expression (e);
1087 break;
1091 void
1092 cxx_pretty_printer::expression (tree t)
1094 switch (TREE_CODE (t))
1096 case STRING_CST:
1097 case VOID_CST:
1098 case INTEGER_CST:
1099 case REAL_CST:
1100 case COMPLEX_CST:
1101 constant (t);
1102 break;
1104 case USERDEF_LITERAL:
1105 pp_cxx_userdef_literal (this, t);
1106 break;
1108 case RESULT_DECL:
1109 pp_cxx_unqualified_id (this, t);
1110 break;
1112 #if 0
1113 case OFFSET_REF:
1114 #endif
1115 case SCOPE_REF:
1116 case PTRMEM_CST:
1117 pp_cxx_qualified_id (this, t);
1118 break;
1120 case OVERLOAD:
1121 t = OVL_FIRST (t);
1122 /* FALLTHRU */
1123 case VAR_DECL:
1124 if (DECL_NTTP_OBJECT_P (t))
1126 /* Print the type followed by the CONSTRUCTOR value of the
1127 NTTP object. */
1128 simple_type_specifier (cv_unqualified (TREE_TYPE (t)));
1129 expression (DECL_INITIAL (t));
1130 break;
1132 /* FALLTHRU */
1133 case PARM_DECL:
1134 case FIELD_DECL:
1135 case CONST_DECL:
1136 case FUNCTION_DECL:
1137 case BASELINK:
1138 case TEMPLATE_DECL:
1139 case TEMPLATE_TYPE_PARM:
1140 case TEMPLATE_PARM_INDEX:
1141 case TEMPLATE_TEMPLATE_PARM:
1142 case STMT_EXPR:
1143 case REQUIRES_EXPR:
1144 primary_expression (t);
1145 break;
1147 case CALL_EXPR:
1148 case DYNAMIC_CAST_EXPR:
1149 case STATIC_CAST_EXPR:
1150 case REINTERPRET_CAST_EXPR:
1151 case CONST_CAST_EXPR:
1152 #if 0
1153 case MEMBER_REF:
1154 #endif
1155 case EMPTY_CLASS_EXPR:
1156 case TYPEID_EXPR:
1157 case PSEUDO_DTOR_EXPR:
1158 case AGGR_INIT_EXPR:
1159 case ARROW_EXPR:
1160 postfix_expression (t);
1161 break;
1163 case NEW_EXPR:
1164 case VEC_NEW_EXPR:
1165 pp_cxx_new_expression (this, t);
1166 break;
1168 case DELETE_EXPR:
1169 case VEC_DELETE_EXPR:
1170 pp_cxx_delete_expression (this, t);
1171 break;
1173 case SIZEOF_EXPR:
1174 case ALIGNOF_EXPR:
1175 case NOEXCEPT_EXPR:
1176 case UNARY_PLUS_EXPR:
1177 unary_expression (t);
1178 break;
1180 case CAST_EXPR:
1181 case IMPLICIT_CONV_EXPR:
1182 pp_cxx_cast_expression (this, t);
1183 break;
1185 case OFFSET_REF:
1186 case MEMBER_REF:
1187 case DOTSTAR_EXPR:
1188 pp_cxx_pm_expression (this, t);
1189 break;
1191 case MULT_EXPR:
1192 case TRUNC_DIV_EXPR:
1193 case TRUNC_MOD_EXPR:
1194 case EXACT_DIV_EXPR:
1195 case RDIV_EXPR:
1196 multiplicative_expression (t);
1197 break;
1199 case COND_EXPR:
1200 conditional_expression (t);
1201 break;
1203 case MODIFY_EXPR:
1204 case INIT_EXPR:
1205 case THROW_EXPR:
1206 case MODOP_EXPR:
1207 assignment_expression (t);
1208 break;
1210 case MUST_NOT_THROW_EXPR:
1211 expression (TREE_OPERAND (t, 0));
1212 break;
1214 case EXPR_PACK_EXPANSION:
1215 expression (PACK_EXPANSION_PATTERN (t));
1216 pp_cxx_ws_string (this, "...");
1217 break;
1219 case UNARY_LEFT_FOLD_EXPR:
1220 pp_cxx_unary_left_fold_expression (this, t);
1221 break;
1223 case UNARY_RIGHT_FOLD_EXPR:
1224 pp_cxx_unary_right_fold_expression (this, t);
1225 break;
1227 case BINARY_LEFT_FOLD_EXPR:
1228 case BINARY_RIGHT_FOLD_EXPR:
1229 pp_cxx_binary_fold_expression (this, t);
1230 break;
1232 case TEMPLATE_ID_EXPR:
1233 pp_cxx_template_id (this, t);
1234 break;
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)
1243 if (i > 0)
1244 pp_cxx_separate_with (this, ',');
1245 expression (TREE_VEC_ELT (args, i));
1247 pp_cxx_right_brace (this);
1249 break;
1251 case LAMBDA_EXPR:
1252 pp_cxx_ws_string (this, "<lambda>");
1253 break;
1255 case TRAIT_EXPR:
1256 pp_cxx_trait (this, t);
1257 break;
1259 case ATOMIC_CONSTR:
1260 case CHECK_CONSTR:
1261 case CONJ_CONSTR:
1262 case DISJ_CONSTR:
1263 pp_cxx_constraint (this, t);
1264 break;
1266 case PAREN_EXPR:
1267 pp_cxx_left_paren (this);
1268 expression (TREE_OPERAND (t, 0));
1269 pp_cxx_right_paren (this);
1270 break;
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));
1277 break;
1279 /* FALLTHRU */
1280 default:
1281 c_pretty_printer::expression (t);
1282 break;
1287 /* Declarations. */
1289 /* function-specifier:
1290 inline
1291 virtual
1292 explicit */
1294 void
1295 cxx_pretty_printer::function_specifier (tree t)
1297 switch (TREE_CODE (t))
1299 case FUNCTION_DECL:
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");
1304 else
1305 c_pretty_printer::function_specifier (t);
1307 default:
1308 break;
1312 /* decl-specifier-seq:
1313 decl-specifier-seq(opt) decl-specifier
1315 decl-specifier:
1316 storage-class-specifier
1317 type-specifier
1318 function-specifier
1319 friend
1320 typedef */
1322 void
1323 cxx_pretty_printer::declaration_specifiers (tree t)
1325 switch (TREE_CODE (t))
1327 case VAR_DECL:
1328 case PARM_DECL:
1329 case CONST_DECL:
1330 case FIELD_DECL:
1331 storage_class_specifier (t);
1332 declaration_specifiers (TREE_TYPE (t));
1333 break;
1335 case TYPE_DECL:
1336 pp_cxx_ws_string (this, "typedef");
1337 declaration_specifiers (TREE_TYPE (t));
1338 break;
1340 case FUNCTION_DECL:
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)));
1347 else
1348 c_pretty_printer::declaration_specifiers (t);
1349 break;
1350 default:
1351 c_pretty_printer::declaration_specifiers (t);
1352 break;
1356 /* simple-type-specifier:
1357 ::(opt) nested-name-specifier(opt) type-name
1358 ::(opt) nested-name-specifier(opt) template(opt) template-id
1359 decltype-specifier
1360 char
1361 wchar_t
1362 bool
1363 short
1365 long
1366 signed
1367 unsigned
1368 float
1369 double
1370 void */
1372 void
1373 cxx_pretty_printer::simple_type_specifier (tree t)
1375 switch (TREE_CODE (t))
1377 case RECORD_TYPE:
1378 case UNION_TYPE:
1379 case ENUMERAL_TYPE:
1380 pp_cxx_qualified_id (this, t);
1381 break;
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);
1391 break;
1393 case TYPENAME_TYPE:
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));
1397 break;
1399 case DECLTYPE_TYPE:
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);
1404 break;
1406 case NULLPTR_TYPE:
1407 pp_cxx_ws_string (this, "std::nullptr_t");
1408 break;
1410 case TRAIT_TYPE:
1411 pp_cxx_trait (this, t);
1412 break;
1414 default:
1415 c_pretty_printer::simple_type_specifier (t);
1416 break;
1420 /* type-specifier-seq:
1421 type-specifier type-specifier-seq(opt)
1423 type-specifier:
1424 simple-type-specifier
1425 class-specifier
1426 enum-specifier
1427 elaborated-type-specifier
1428 cv-qualifier */
1430 static void
1431 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1433 switch (TREE_CODE (t))
1435 case TEMPLATE_DECL:
1436 case TEMPLATE_TYPE_PARM:
1437 case TEMPLATE_TEMPLATE_PARM:
1438 case TYPE_DECL:
1439 case BOUND_TEMPLATE_TEMPLATE_PARM:
1440 case DECLTYPE_TYPE:
1441 case NULLPTR_TYPE:
1442 pp_cxx_cv_qualifier_seq (pp, t);
1443 pp->simple_type_specifier (t);
1444 break;
1446 case METHOD_TYPE:
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));
1450 break;
1452 case RECORD_TYPE:
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);
1459 break;
1461 /* fall through */
1463 case OFFSET_TYPE:
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);
1469 break;
1471 /* fall through */
1473 default:
1474 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1475 pp_c_specifier_qualifier_list (pp, t);
1479 /* ptr-operator:
1480 * cv-qualifier-seq(opt)
1482 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1484 static void
1485 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1487 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1488 t = TREE_TYPE (t);
1489 switch (TREE_CODE (t))
1491 case REFERENCE_TYPE:
1492 case POINTER_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)));
1496 if (TYPE_PTR_P (t))
1498 pp_star (pp);
1499 pp_cxx_cv_qualifier_seq (pp, t);
1501 else
1502 pp_ampersand (pp);
1503 break;
1505 case RECORD_TYPE:
1506 if (TYPE_PTRMEMFUNC_P (t))
1508 pp_cxx_left_paren (pp);
1509 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1510 pp_star (pp);
1511 break;
1513 /* FALLTHRU */
1514 case OFFSET_TYPE:
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));
1520 pp_star (pp);
1521 pp_cxx_cv_qualifier_seq (pp, t);
1522 break;
1524 /* fall through. */
1526 default:
1527 pp_unsupported_tree (pp, t);
1528 break;
1532 static inline tree
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 */
1545 static inline void
1546 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1548 pp->declaration_specifiers (t);
1549 if (TYPE_P (t))
1550 pp->abstract_declarator (t);
1551 else
1552 pp->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 */
1563 static void
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);
1567 tree types, args;
1568 if (TYPE_P (t))
1570 types = TYPE_ARG_TYPES (t);
1571 args = NULL_TREE;
1573 else
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);
1584 bool first = true;
1585 pp_cxx_left_paren (pp);
1586 for (; types != void_list_node; types = TREE_CHAIN (types))
1588 if (!first)
1589 pp_cxx_separate_with (pp, ',');
1590 first = false;
1591 if (!types)
1593 pp_cxx_ws_string (pp, "...");
1594 break;
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);
1600 pp_equal (pp);
1601 pp_cxx_whitespace (pp);
1602 pp->assignment_expression (TREE_PURPOSE (types));
1604 if (!abstract)
1605 args = TREE_CHAIN (args);
1607 pp_cxx_right_paren (pp);
1610 /* exception-specification:
1611 throw ( type-id-list(opt) )
1613 type-id-list
1614 type-id
1615 type-id-list , type-id */
1617 static void
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)
1624 return;
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>");
1632 else
1633 pp->expression (TREE_PURPOSE (ex_spec));
1634 pp_cxx_right_paren (pp);
1635 return;
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;
1643 int i, len = 1;
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)
1653 if (argpack)
1654 type = TREE_VEC_ELT (argpack, i);
1656 if (need_comma)
1657 pp_cxx_separate_with (pp, ',');
1658 else
1659 need_comma = true;
1661 pp->type_id (type);
1664 pp_cxx_right_paren (pp);
1667 /* direct-declarator:
1668 declarator-id
1669 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1670 exception-specification(opt)
1671 direct-declaration [ constant-expression(opt) ]
1672 ( declarator ) */
1674 void
1675 cxx_pretty_printer::direct_declarator (tree t)
1677 switch (TREE_CODE (t))
1679 case VAR_DECL:
1680 case PARM_DECL:
1681 case CONST_DECL:
1682 case FIELD_DECL:
1683 if (DECL_NAME (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
1690 parameter pack. */
1691 pp_cxx_ws_string (this, "...");
1693 id_expression (DECL_NAME (t));
1695 abstract_declarator (TREE_TYPE (t));
1696 break;
1698 case FUNCTION_DECL:
1699 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1700 expression (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));
1710 break;
1712 case TYPENAME_TYPE:
1713 case TEMPLATE_DECL:
1714 case TEMPLATE_TYPE_PARM:
1715 case TEMPLATE_PARM_INDEX:
1716 case TEMPLATE_TEMPLATE_PARM:
1717 break;
1719 default:
1720 c_pretty_printer::direct_declarator (t);
1721 break;
1725 /* declarator:
1726 direct-declarator
1727 ptr-operator declarator */
1729 void
1730 cxx_pretty_printer::declarator (tree t)
1732 direct_declarator (t);
1734 // Print a requires clause.
1735 if (flag_concepts)
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:
1745 mem-initializer
1746 mem-initializer , mem-initializer-list
1748 mem-initializer:
1749 mem-initializer-id ( expression-list(opt) )
1751 mem-initializer-id:
1752 ::(opt) nested-name-specifier(opt) class-name
1753 identifier */
1755 static void
1756 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1758 t = TREE_OPERAND (t, 0);
1759 pp_cxx_whitespace (pp);
1760 pp_colon (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);
1767 if (is_pack)
1768 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1769 else
1770 pp->primary_expression (purpose);
1771 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1772 if (is_pack)
1773 pp_cxx_ws_string (pp, "...");
1774 if (TREE_CHAIN (t))
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 */
1783 static void
1784 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1786 tree saved_scope = pp->enclosing_scope;
1787 pp->declaration_specifiers (t);
1788 pp->declarator (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));
1793 else
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 */
1803 void
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:
1809 void (X::*)()
1810 int (X::*)[5]
1812 but not for a pointer-to-data-member of non-array type:
1814 int X::*
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);
1826 t = TREE_TYPE (t);
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 ) */
1837 void
1838 cxx_pretty_printer::direct_abstract_declarator (tree t)
1840 switch (TREE_CODE (t))
1842 case REFERENCE_TYPE:
1843 abstract_declarator (t);
1844 break;
1846 case RECORD_TYPE:
1847 if (TYPE_PTRMEMFUNC_P (t))
1848 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1849 break;
1851 case OFFSET_TYPE:
1852 if (TYPE_PTRDATAMEM_P (t))
1853 direct_abstract_declarator (TREE_TYPE (t));
1854 break;
1856 case METHOD_TYPE:
1857 case FUNCTION_TYPE:
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);
1866 break;
1868 case TYPENAME_TYPE:
1869 case TEMPLATE_TYPE_PARM:
1870 case TEMPLATE_TEMPLATE_PARM:
1871 case BOUND_TEMPLATE_TEMPLATE_PARM:
1872 case UNBOUND_CLASS_TEMPLATE:
1873 case DECLTYPE_TYPE:
1874 break;
1876 default:
1877 c_pretty_printer::direct_abstract_declarator (t);
1878 break;
1882 /* type-id:
1883 type-specifier-seq abstract-declarator(opt) */
1885 void
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))
1893 case TYPE_DECL:
1894 case UNION_TYPE:
1895 case RECORD_TYPE:
1896 case ENUMERAL_TYPE:
1897 case TYPENAME_TYPE:
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:
1903 case TEMPLATE_DECL:
1904 case TYPEOF_TYPE:
1905 case TRAIT_TYPE:
1906 case DECLTYPE_TYPE:
1907 case NULLPTR_TYPE:
1908 case TEMPLATE_ID_EXPR:
1909 case OFFSET_TYPE:
1910 pp_cxx_type_specifier_seq (this, t);
1911 if (TYPE_PTRMEM_P (t))
1912 abstract_declarator (t);
1913 break;
1915 case TYPE_PACK_EXPANSION:
1916 type_id (PACK_EXPANSION_PATTERN (t));
1917 pp_cxx_ws_string (this, "...");
1918 break;
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)
1927 if (i > 0)
1928 pp_cxx_separate_with (this, ',');
1929 type_id (TREE_VEC_ELT (args, i));
1931 pp_cxx_right_brace (this);
1933 break;
1935 default:
1936 c_pretty_printer::type_id (t);
1937 break;
1940 flags = saved_flags;
1943 /* template-argument-list:
1944 template-argument ...(opt)
1945 template-argument-list, template-argument ...(opt)
1947 template-argument:
1948 assignment-expression
1949 type-id
1950 template-name */
1952 static void
1953 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1955 int i;
1956 bool need_comma = false;
1958 if (t == NULL)
1959 return;
1960 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1962 tree arg = TREE_VEC_ELT (t, i);
1963 tree argpack = NULL_TREE;
1964 int idx, len = 1;
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++)
1974 if (argpack)
1975 arg = TREE_VEC_ELT (argpack, idx);
1977 if (need_comma)
1978 pp_cxx_separate_with (pp, ',');
1979 else
1980 need_comma = true;
1982 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1983 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1984 pp->type_id (arg);
1985 else
1986 pp->expression (arg);
1992 static void
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);
1997 if (TYPE_P (t))
1998 pp->abstract_declarator (t);
1999 else
2000 pp->declarator (t);
2003 /* Statements. */
2005 void
2006 cxx_pretty_printer::statement (tree t)
2008 switch (TREE_CODE (t))
2010 case CTOR_INITIALIZER:
2011 pp_cxx_ctor_initializer (this, t);
2012 break;
2014 case USING_STMT:
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));
2020 break;
2022 case USING_DECL:
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));
2026 break;
2028 case EH_SPEC_BLOCK:
2029 break;
2031 /* try-block:
2032 try compound-statement handler-seq */
2033 case TRY_BLOCK:
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);
2039 if (CLEANUP_P (t))
2041 else
2042 statement (TRY_HANDLERS (t));
2043 break;
2046 handler-seq:
2047 handler handler-seq(opt)
2049 handler:
2050 catch ( exception-declaration ) compound-statement
2052 exception-declaration:
2053 type-specifier-seq declarator
2054 type-specifier-seq abstract-declarator
2055 ... */
2056 case HANDLER:
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;
2066 break;
2068 /* selection-statement:
2069 if ( expression ) statement
2070 if ( expression ) statement else statement */
2071 case IF_STMT:
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);
2086 else
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);
2092 break;
2094 case RANGE_FOR_STMT:
2095 pp_cxx_ws_string (this, "for");
2096 pp_space (this);
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));
2105 pp_space (this);
2106 pp_needs_newline (this) = false;
2107 pp_colon (this);
2108 pp_space (this);
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;
2115 break;
2117 /* expression-statement:
2118 expression(opt) ; */
2119 case EXPR_STMT:
2120 expression (EXPR_STMT_EXPR (t));
2121 pp_cxx_semicolon (this);
2122 pp_needs_newline (this) = true;
2123 break;
2125 case CLEANUP_STMT:
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);
2134 break;
2136 case STATIC_ASSERT:
2137 declaration (t);
2138 break;
2140 case OMP_DEPOBJ:
2141 pp_cxx_ws_string (this, "#pragma omp depobj");
2142 pp_space (this);
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);
2151 else
2152 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2154 case OMP_CLAUSE_DEPEND_IN:
2155 pp_cxx_ws_string (this, " update(in)");
2156 break;
2157 case OMP_CLAUSE_DEPEND_INOUT:
2158 pp_cxx_ws_string (this, " update(inout)");
2159 break;
2160 case OMP_CLAUSE_DEPEND_OUT:
2161 pp_cxx_ws_string (this, " update(out)");
2162 break;
2163 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2164 pp_cxx_ws_string (this, " update(mutexinoutset)");
2165 break;
2166 case OMP_CLAUSE_DEPEND_INOUTSET:
2167 pp_cxx_ws_string (this, " update(inoutset)");
2168 break;
2169 case OMP_CLAUSE_DEPEND_LAST:
2170 pp_cxx_ws_string (this, " destroy");
2171 break;
2172 default:
2173 break;
2176 pp_needs_newline (this) = true;
2177 break;
2179 default:
2180 c_pretty_printer::statement (t);
2181 break;
2185 /* original-namespace-definition:
2186 namespace identifier { namespace-body }
2188 As an edge case, we also handle unnamed namespace definition here. */
2190 static void
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));
2196 if (DECL_NAME (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);
2205 /* namespace-alias:
2206 identifier
2208 namespace-alias-definition:
2209 namespace identifier = qualified-namespace-specifier ;
2211 qualified-namespace-specifier:
2212 ::(opt) nested-name-specifier(opt) namespace-name */
2214 static void
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);
2222 pp_equal (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) */
2234 static void
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:
2245 template-parameter
2246 template-parameter-list , template-parameter */
2248 static inline void
2249 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2251 const int n = TREE_VEC_LENGTH (t);
2252 int i;
2253 for (i = 0; i < n; ++i)
2255 if (i)
2256 pp_cxx_separate_with (pp, ',');
2257 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2261 /* template-parameter:
2262 type-parameter
2263 parameter-declaration
2265 type-parameter:
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 */
2273 static void
2274 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2276 tree parameter = TREE_VALUE (t);
2277 switch (TREE_CODE (parameter))
2279 case TYPE_DECL:
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. */
2286 break;
2288 case PARM_DECL:
2289 pp_cxx_parameter_declaration (pp, parameter);
2290 break;
2292 case TEMPLATE_DECL:
2293 break;
2295 default:
2296 pp_unsupported_tree (pp, t);
2297 break;
2301 /* Pretty-print a template parameter in the canonical form
2302 "template-parameter-<level>-<position in parameter list>". */
2304 void
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));
2317 pp_minus (pp);
2318 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2319 pp_cxx_end_template_argument_list (pp);
2322 /* Print a constrained-type-specifier. */
2324 void
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>");
2334 return;
2336 tree t, a;
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);
2346 ggc_free (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
2355 Concept extensions:
2357 template-declaration:
2358 export(opt) template < template-parameter-list >
2359 requires-clause(opt) declaration */
2361 static void
2362 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2364 tree tmpl = most_general_template (t);
2365 tree level;
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);
2377 if (flag_concepts)
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);
2389 else
2390 pp_cxx_simple_declaration (pp, t);
2393 static void
2394 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2396 pp_unsupported_tree (pp, t);
2399 static void
2400 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2402 pp_unsupported_tree (pp, t);
2405 static void
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);
2417 declaration:
2418 block-declaration
2419 function-definition
2420 template-declaration
2421 explicit-instantiation
2422 explicit-specialization
2423 linkage-specification
2424 namespace-definition
2426 block-declaration:
2427 simple-declaration
2428 asm-definition
2429 namespace-alias-definition
2430 using-declaration
2431 using-directive
2432 static_assert-declaration */
2433 void
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))
2450 case 1:
2451 pp_cxx_template_declaration (this, t);
2452 break;
2454 case 2:
2455 pp_cxx_explicit_specialization (this, t);
2456 break;
2458 case 3:
2459 pp_cxx_explicit_instantiation (this, t);
2460 break;
2462 default:
2463 break;
2465 else switch (TREE_CODE (t))
2467 case VAR_DECL:
2468 case TYPE_DECL:
2469 pp_cxx_simple_declaration (this, t);
2470 break;
2472 case FUNCTION_DECL:
2473 if (DECL_SAVED_TREE (t))
2474 pp_cxx_function_definition (this, t);
2475 else
2476 pp_cxx_simple_declaration (this, t);
2477 break;
2479 case NAMESPACE_DECL:
2480 if (DECL_NAMESPACE_ALIAS (t))
2481 pp_cxx_namespace_alias_definition (this, t);
2482 else
2483 pp_cxx_original_namespace_definition (this, t);
2484 break;
2486 default:
2487 pp_unsupported_tree (this, t);
2488 break;
2492 static void
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);
2498 if (TYPE_P (t))
2499 pp->type_id (t);
2500 else
2501 pp->expression (t);
2502 pp_cxx_right_paren (pp);
2505 void
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);
2516 static bool
2517 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2519 switch (TREE_CODE (t))
2521 case ARROW_EXPR:
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, ',');
2527 return true;
2529 return false;
2530 case COMPONENT_REF:
2531 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2532 return false;
2533 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2534 pp_cxx_dot (pp);
2535 pp->expression (TREE_OPERAND (t, 1));
2536 return true;
2537 case ARRAY_REF:
2538 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2539 return false;
2540 pp_left_bracket (pp);
2541 pp->expression (TREE_OPERAND (t, 1));
2542 pp_right_bracket (pp);
2543 return true;
2544 default:
2545 return false;
2549 void
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);
2559 void
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);
2568 static char const*
2569 get_fold_operator (tree t)
2571 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2572 FOLD_EXPR_OP (t));
2573 return info->name;
2576 void
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);
2588 void
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);
2595 pp_space (pp);
2596 pp_cxx_ws_string (pp, op);
2597 pp_cxx_ws_string (pp, "...");
2598 pp_cxx_right_paren (pp);
2601 void
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);
2609 else
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);
2620 void
2621 pp_cxx_trait (cxx_pretty_printer *pp, tree t)
2623 cp_trait_kind kind;
2624 tree type1, type2;
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);
2631 else
2633 kind = TRAIT_TYPE_KIND (t);
2634 type1 = TRAIT_TYPE_TYPE1 (t);
2635 type2 = TRAIT_TYPE_TYPE2 (t);
2638 switch (kind)
2640 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2641 case CPTK_##CODE: \
2642 pp_cxx_ws_string (pp, NAME); \
2643 break;
2644 #include "cp-trait.def"
2645 #undef DEFTRAIT
2648 if (kind == CPTK_TYPE_PACK_ELEMENT)
2650 pp_cxx_begin_template_argument_list (pp);
2651 pp->expression (type1);
2653 else
2655 pp_cxx_left_paren (pp);
2656 if (TYPE_P (type1))
2657 pp->type_id (type1);
2658 else
2659 pp->expression (type1);
2661 if (type2)
2663 if (TREE_CODE (type2) != TREE_VEC)
2665 pp_cxx_separate_with (pp, ',');
2666 pp->type_id (type2);
2668 else
2669 for (tree arg : tree_vec_range (type2))
2671 pp_cxx_separate_with (pp, ',');
2672 pp->type_id (arg);
2675 if (kind == CPTK_TYPE_PACK_ELEMENT)
2676 pp_cxx_end_template_argument_list (pp);
2677 else
2678 pp_cxx_right_paren (pp);
2681 // requires-clause:
2682 // 'requires' logical-or-expression
2683 void
2684 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2686 if (!t)
2687 return;
2688 pp->padding = pp_before;
2689 pp_cxx_ws_string (pp, "requires");
2690 pp_space (pp);
2691 pp->expression (t);
2694 /* requirement:
2695 simple-requirement
2696 compound-requirement
2697 type-requirement
2698 nested-requirement */
2699 static void
2700 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2702 switch (TREE_CODE (t))
2704 case SIMPLE_REQ:
2705 pp_cxx_simple_requirement (pp, t);
2706 break;
2708 case TYPE_REQ:
2709 pp_cxx_type_requirement (pp, t);
2710 break;
2712 case COMPOUND_REQ:
2713 pp_cxx_compound_requirement (pp, t);
2714 break;
2716 case NESTED_REQ:
2717 pp_cxx_nested_requirement (pp, t);
2718 break;
2720 default:
2721 gcc_unreachable ();
2725 // requirement-list:
2726 // requirement
2727 // requirement-list ';' requirement[opt]
2729 static void
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 '}'
2738 static void
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
2748 void
2749 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2751 pp_string (pp, "requires");
2752 if (tree parms = REQUIRES_EXPR_PARMS (t))
2754 bool first = true;
2755 pp_cxx_left_paren (pp);
2756 for (; parms; parms = TREE_CHAIN (parms))
2758 if (!first)
2759 pp_cxx_separate_with (pp, ',' );
2760 first = false;
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:
2770 expression ';' */
2771 void
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 ';' */
2780 void
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] */
2789 void
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, "->");
2803 pp->type_id (type);
2805 pp_cxx_semicolon (pp);
2808 /* nested requirement:
2809 'requires' constraint-expression */
2810 void
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);
2818 void
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);
2837 else
2838 gcc_unreachable ();
2841 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2842 constraint. */
2844 void
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);
2857 if (TYPE_P (parm))
2858 pp->type_id (parm);
2859 else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2860 pp_cxx_tree_identifier (pp, name);
2861 else
2862 pp->translate_string ("<unnamed>");
2864 pp_cxx_whitespace (pp);
2865 pp_equal (pp);
2866 pp_cxx_whitespace (pp);
2868 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2869 pp->type_id (arg);
2870 else
2871 pp->expression (arg);
2873 if (TREE_CHAIN (p) != NULL_TREE)
2874 pp_cxx_separate_with (pp, ';');
2877 pp_cxx_right_bracket (pp);
2880 void
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);
2892 void
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));
2900 void
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));
2908 void
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))
2916 case ATOMIC_CONSTR:
2917 pp_cxx_atomic_constraint (pp, t);
2918 break;
2920 case CHECK_CONSTR:
2921 pp_cxx_check_constraint (pp, t);
2922 break;
2924 case CONJ_CONSTR:
2925 pp_cxx_conjunction (pp, t);
2926 break;
2928 case DISJ_CONSTR:
2929 pp_cxx_disjunction (pp, t);
2930 break;
2932 case EXPR_PACK_EXPANSION:
2933 pp->expression (TREE_OPERAND (t, 0));
2934 break;
2936 default:
2937 gcc_unreachable ();
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. */
2956 pretty_printer *
2957 cxx_pretty_printer::clone () const
2959 return new cxx_pretty_printer (*this);