Require target lra in gcc.dg/pr108095.c
[official-gcc.git] / gcc / cp / cxx-pretty-print.cc
blobeb16e63425f5c599847700a32f37a048d0735a36
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
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_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);
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 NON_DEPENDENT_EXPR:
1211 case MUST_NOT_THROW_EXPR:
1212 expression (TREE_OPERAND (t, 0));
1213 break;
1215 case EXPR_PACK_EXPANSION:
1216 expression (PACK_EXPANSION_PATTERN (t));
1217 pp_cxx_ws_string (this, "...");
1218 break;
1220 case UNARY_LEFT_FOLD_EXPR:
1221 pp_cxx_unary_left_fold_expression (this, t);
1222 break;
1224 case UNARY_RIGHT_FOLD_EXPR:
1225 pp_cxx_unary_right_fold_expression (this, t);
1226 break;
1228 case BINARY_LEFT_FOLD_EXPR:
1229 case BINARY_RIGHT_FOLD_EXPR:
1230 pp_cxx_binary_fold_expression (this, t);
1231 break;
1233 case TEMPLATE_ID_EXPR:
1234 pp_cxx_template_id (this, t);
1235 break;
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)
1244 if (i > 0)
1245 pp_cxx_separate_with (this, ',');
1246 expression (TREE_VEC_ELT (args, i));
1248 pp_cxx_right_brace (this);
1250 break;
1252 case LAMBDA_EXPR:
1253 pp_cxx_ws_string (this, "<lambda>");
1254 break;
1256 case TRAIT_EXPR:
1257 pp_cxx_trait (this, t);
1258 break;
1260 case ATOMIC_CONSTR:
1261 case CHECK_CONSTR:
1262 case CONJ_CONSTR:
1263 case DISJ_CONSTR:
1264 pp_cxx_constraint (this, t);
1265 break;
1267 case PAREN_EXPR:
1268 pp_cxx_left_paren (this);
1269 expression (TREE_OPERAND (t, 0));
1270 pp_cxx_right_paren (this);
1271 break;
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));
1278 break;
1280 /* FALLTHRU */
1281 default:
1282 c_pretty_printer::expression (t);
1283 break;
1288 /* Declarations. */
1290 /* function-specifier:
1291 inline
1292 virtual
1293 explicit */
1295 void
1296 cxx_pretty_printer::function_specifier (tree t)
1298 switch (TREE_CODE (t))
1300 case FUNCTION_DECL:
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");
1305 else
1306 c_pretty_printer::function_specifier (t);
1308 default:
1309 break;
1313 /* decl-specifier-seq:
1314 decl-specifier-seq(opt) decl-specifier
1316 decl-specifier:
1317 storage-class-specifier
1318 type-specifier
1319 function-specifier
1320 friend
1321 typedef */
1323 void
1324 cxx_pretty_printer::declaration_specifiers (tree t)
1326 switch (TREE_CODE (t))
1328 case VAR_DECL:
1329 case PARM_DECL:
1330 case CONST_DECL:
1331 case FIELD_DECL:
1332 storage_class_specifier (t);
1333 declaration_specifiers (TREE_TYPE (t));
1334 break;
1336 case TYPE_DECL:
1337 pp_cxx_ws_string (this, "typedef");
1338 declaration_specifiers (TREE_TYPE (t));
1339 break;
1341 case FUNCTION_DECL:
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)));
1348 else
1349 c_pretty_printer::declaration_specifiers (t);
1350 break;
1351 default:
1352 c_pretty_printer::declaration_specifiers (t);
1353 break;
1357 /* simple-type-specifier:
1358 ::(opt) nested-name-specifier(opt) type-name
1359 ::(opt) nested-name-specifier(opt) template(opt) template-id
1360 decltype-specifier
1361 char
1362 wchar_t
1363 bool
1364 short
1366 long
1367 signed
1368 unsigned
1369 float
1370 double
1371 void */
1373 void
1374 cxx_pretty_printer::simple_type_specifier (tree t)
1376 switch (TREE_CODE (t))
1378 case RECORD_TYPE:
1379 case UNION_TYPE:
1380 case ENUMERAL_TYPE:
1381 pp_cxx_qualified_id (this, t);
1382 break;
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);
1392 break;
1394 case TYPENAME_TYPE:
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));
1398 break;
1400 case DECLTYPE_TYPE:
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);
1405 break;
1407 case NULLPTR_TYPE:
1408 pp_cxx_ws_string (this, "std::nullptr_t");
1409 break;
1411 case TRAIT_TYPE:
1412 pp_cxx_trait (this, t);
1413 break;
1415 default:
1416 c_pretty_printer::simple_type_specifier (t);
1417 break;
1421 /* type-specifier-seq:
1422 type-specifier type-specifier-seq(opt)
1424 type-specifier:
1425 simple-type-specifier
1426 class-specifier
1427 enum-specifier
1428 elaborated-type-specifier
1429 cv-qualifier */
1431 static void
1432 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1434 switch (TREE_CODE (t))
1436 case TEMPLATE_DECL:
1437 case TEMPLATE_TYPE_PARM:
1438 case TEMPLATE_TEMPLATE_PARM:
1439 case TYPE_DECL:
1440 case BOUND_TEMPLATE_TEMPLATE_PARM:
1441 case DECLTYPE_TYPE:
1442 case NULLPTR_TYPE:
1443 pp_cxx_cv_qualifier_seq (pp, t);
1444 pp->simple_type_specifier (t);
1445 break;
1447 case METHOD_TYPE:
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));
1451 break;
1453 case RECORD_TYPE:
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);
1460 break;
1462 /* fall through */
1464 case OFFSET_TYPE:
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);
1470 break;
1472 /* fall through */
1474 default:
1475 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1476 pp_c_specifier_qualifier_list (pp, t);
1480 /* ptr-operator:
1481 * cv-qualifier-seq(opt)
1483 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1485 static void
1486 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1488 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1489 t = TREE_TYPE (t);
1490 switch (TREE_CODE (t))
1492 case REFERENCE_TYPE:
1493 case POINTER_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)));
1497 if (TYPE_PTR_P (t))
1499 pp_star (pp);
1500 pp_cxx_cv_qualifier_seq (pp, t);
1502 else
1503 pp_ampersand (pp);
1504 break;
1506 case RECORD_TYPE:
1507 if (TYPE_PTRMEMFUNC_P (t))
1509 pp_cxx_left_paren (pp);
1510 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1511 pp_star (pp);
1512 break;
1514 /* FALLTHRU */
1515 case OFFSET_TYPE:
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));
1521 pp_star (pp);
1522 pp_cxx_cv_qualifier_seq (pp, t);
1523 break;
1525 /* fall through. */
1527 default:
1528 pp_unsupported_tree (pp, t);
1529 break;
1533 static inline tree
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 */
1546 static inline void
1547 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1549 pp->declaration_specifiers (t);
1550 if (TYPE_P (t))
1551 pp->abstract_declarator (t);
1552 else
1553 pp->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 */
1564 static void
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);
1568 tree types, args;
1569 if (TYPE_P (t))
1571 types = TYPE_ARG_TYPES (t);
1572 args = NULL_TREE;
1574 else
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);
1585 bool first = true;
1586 pp_cxx_left_paren (pp);
1587 for (; types != void_list_node; types = TREE_CHAIN (types))
1589 if (!first)
1590 pp_cxx_separate_with (pp, ',');
1591 first = false;
1592 if (!types)
1594 pp_cxx_ws_string (pp, "...");
1595 break;
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);
1601 pp_equal (pp);
1602 pp_cxx_whitespace (pp);
1603 pp->assignment_expression (TREE_PURPOSE (types));
1605 if (!abstract)
1606 args = TREE_CHAIN (args);
1608 pp_cxx_right_paren (pp);
1611 /* exception-specification:
1612 throw ( type-id-list(opt) )
1614 type-id-list
1615 type-id
1616 type-id-list , type-id */
1618 static void
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)
1625 return;
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>");
1633 else
1634 pp->expression (TREE_PURPOSE (ex_spec));
1635 pp_cxx_right_paren (pp);
1636 return;
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;
1644 int i, len = 1;
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)
1654 if (argpack)
1655 type = TREE_VEC_ELT (argpack, i);
1657 if (need_comma)
1658 pp_cxx_separate_with (pp, ',');
1659 else
1660 need_comma = true;
1662 pp->type_id (type);
1665 pp_cxx_right_paren (pp);
1668 /* direct-declarator:
1669 declarator-id
1670 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1671 exception-specification(opt)
1672 direct-declaration [ constant-expression(opt) ]
1673 ( declarator ) */
1675 void
1676 cxx_pretty_printer::direct_declarator (tree t)
1678 switch (TREE_CODE (t))
1680 case VAR_DECL:
1681 case PARM_DECL:
1682 case CONST_DECL:
1683 case FIELD_DECL:
1684 if (DECL_NAME (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
1691 parameter pack. */
1692 pp_cxx_ws_string (this, "...");
1694 id_expression (DECL_NAME (t));
1696 abstract_declarator (TREE_TYPE (t));
1697 break;
1699 case FUNCTION_DECL:
1700 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1701 expression (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));
1711 break;
1713 case TYPENAME_TYPE:
1714 case TEMPLATE_DECL:
1715 case TEMPLATE_TYPE_PARM:
1716 case TEMPLATE_PARM_INDEX:
1717 case TEMPLATE_TEMPLATE_PARM:
1718 break;
1720 default:
1721 c_pretty_printer::direct_declarator (t);
1722 break;
1726 /* declarator:
1727 direct-declarator
1728 ptr-operator declarator */
1730 void
1731 cxx_pretty_printer::declarator (tree t)
1733 direct_declarator (t);
1735 // Print a requires clause.
1736 if (flag_concepts)
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:
1746 mem-initializer
1747 mem-initializer , mem-initializer-list
1749 mem-initializer:
1750 mem-initializer-id ( expression-list(opt) )
1752 mem-initializer-id:
1753 ::(opt) nested-name-specifier(opt) class-name
1754 identifier */
1756 static void
1757 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1759 t = TREE_OPERAND (t, 0);
1760 pp_cxx_whitespace (pp);
1761 pp_colon (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);
1768 if (is_pack)
1769 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1770 else
1771 pp->primary_expression (purpose);
1772 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1773 if (is_pack)
1774 pp_cxx_ws_string (pp, "...");
1775 if (TREE_CHAIN (t))
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 */
1784 static void
1785 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1787 tree saved_scope = pp->enclosing_scope;
1788 pp->declaration_specifiers (t);
1789 pp->declarator (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));
1794 else
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 */
1804 void
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:
1810 void (X::*)()
1811 int (X::*)[5]
1813 but not for a pointer-to-data-member of non-array type:
1815 int X::*
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);
1827 t = TREE_TYPE (t);
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 ) */
1838 void
1839 cxx_pretty_printer::direct_abstract_declarator (tree t)
1841 switch (TREE_CODE (t))
1843 case REFERENCE_TYPE:
1844 abstract_declarator (t);
1845 break;
1847 case RECORD_TYPE:
1848 if (TYPE_PTRMEMFUNC_P (t))
1849 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1850 break;
1852 case OFFSET_TYPE:
1853 if (TYPE_PTRDATAMEM_P (t))
1854 direct_abstract_declarator (TREE_TYPE (t));
1855 break;
1857 case METHOD_TYPE:
1858 case FUNCTION_TYPE:
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);
1867 break;
1869 case TYPENAME_TYPE:
1870 case TEMPLATE_TYPE_PARM:
1871 case TEMPLATE_TEMPLATE_PARM:
1872 case BOUND_TEMPLATE_TEMPLATE_PARM:
1873 case UNBOUND_CLASS_TEMPLATE:
1874 case DECLTYPE_TYPE:
1875 break;
1877 default:
1878 c_pretty_printer::direct_abstract_declarator (t);
1879 break;
1883 /* type-id:
1884 type-specifier-seq abstract-declarator(opt) */
1886 void
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))
1894 case TYPE_DECL:
1895 case UNION_TYPE:
1896 case RECORD_TYPE:
1897 case ENUMERAL_TYPE:
1898 case TYPENAME_TYPE:
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:
1904 case TEMPLATE_DECL:
1905 case TYPEOF_TYPE:
1906 case TRAIT_TYPE:
1907 case DECLTYPE_TYPE:
1908 case NULLPTR_TYPE:
1909 case TEMPLATE_ID_EXPR:
1910 case OFFSET_TYPE:
1911 pp_cxx_type_specifier_seq (this, t);
1912 if (TYPE_PTRMEM_P (t))
1913 abstract_declarator (t);
1914 break;
1916 case TYPE_PACK_EXPANSION:
1917 type_id (PACK_EXPANSION_PATTERN (t));
1918 pp_cxx_ws_string (this, "...");
1919 break;
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)
1928 if (i > 0)
1929 pp_cxx_separate_with (this, ',');
1930 type_id (TREE_VEC_ELT (args, i));
1932 pp_cxx_right_brace (this);
1934 break;
1936 default:
1937 c_pretty_printer::type_id (t);
1938 break;
1941 flags = saved_flags;
1944 /* template-argument-list:
1945 template-argument ...(opt)
1946 template-argument-list, template-argument ...(opt)
1948 template-argument:
1949 assignment-expression
1950 type-id
1951 template-name */
1953 static void
1954 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1956 int i;
1957 bool need_comma = false;
1959 if (t == NULL)
1960 return;
1961 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1963 tree arg = TREE_VEC_ELT (t, i);
1964 tree argpack = NULL_TREE;
1965 int idx, len = 1;
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++)
1975 if (argpack)
1976 arg = TREE_VEC_ELT (argpack, idx);
1978 if (need_comma)
1979 pp_cxx_separate_with (pp, ',');
1980 else
1981 need_comma = true;
1983 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1984 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1985 pp->type_id (arg);
1986 else
1987 pp->expression (arg);
1993 static void
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);
1998 if (TYPE_P (t))
1999 pp->abstract_declarator (t);
2000 else
2001 pp->declarator (t);
2004 /* Statements. */
2006 void
2007 cxx_pretty_printer::statement (tree t)
2009 switch (TREE_CODE (t))
2011 case CTOR_INITIALIZER:
2012 pp_cxx_ctor_initializer (this, t);
2013 break;
2015 case USING_STMT:
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));
2021 break;
2023 case USING_DECL:
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));
2027 break;
2029 case EH_SPEC_BLOCK:
2030 break;
2032 /* try-block:
2033 try compound-statement handler-seq */
2034 case TRY_BLOCK:
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);
2040 if (CLEANUP_P (t))
2042 else
2043 statement (TRY_HANDLERS (t));
2044 break;
2047 handler-seq:
2048 handler handler-seq(opt)
2050 handler:
2051 catch ( exception-declaration ) compound-statement
2053 exception-declaration:
2054 type-specifier-seq declarator
2055 type-specifier-seq abstract-declarator
2056 ... */
2057 case HANDLER:
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;
2067 break;
2069 /* selection-statement:
2070 if ( expression ) statement
2071 if ( expression ) statement else statement */
2072 case IF_STMT:
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);
2087 else
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);
2093 break;
2095 case RANGE_FOR_STMT:
2096 pp_cxx_ws_string (this, "for");
2097 pp_space (this);
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));
2106 pp_space (this);
2107 pp_needs_newline (this) = false;
2108 pp_colon (this);
2109 pp_space (this);
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;
2116 break;
2118 /* expression-statement:
2119 expression(opt) ; */
2120 case EXPR_STMT:
2121 expression (EXPR_STMT_EXPR (t));
2122 pp_cxx_semicolon (this);
2123 pp_needs_newline (this) = true;
2124 break;
2126 case CLEANUP_STMT:
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);
2135 break;
2137 case STATIC_ASSERT:
2138 declaration (t);
2139 break;
2141 case OMP_DEPOBJ:
2142 pp_cxx_ws_string (this, "#pragma omp depobj");
2143 pp_space (this);
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);
2152 else
2153 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2155 case OMP_CLAUSE_DEPEND_IN:
2156 pp_cxx_ws_string (this, " update(in)");
2157 break;
2158 case OMP_CLAUSE_DEPEND_INOUT:
2159 pp_cxx_ws_string (this, " update(inout)");
2160 break;
2161 case OMP_CLAUSE_DEPEND_OUT:
2162 pp_cxx_ws_string (this, " update(out)");
2163 break;
2164 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2165 pp_cxx_ws_string (this, " update(mutexinoutset)");
2166 break;
2167 case OMP_CLAUSE_DEPEND_INOUTSET:
2168 pp_cxx_ws_string (this, " update(inoutset)");
2169 break;
2170 case OMP_CLAUSE_DEPEND_LAST:
2171 pp_cxx_ws_string (this, " destroy");
2172 break;
2173 default:
2174 break;
2177 pp_needs_newline (this) = true;
2178 break;
2180 default:
2181 c_pretty_printer::statement (t);
2182 break;
2186 /* original-namespace-definition:
2187 namespace identifier { namespace-body }
2189 As an edge case, we also handle unnamed namespace definition here. */
2191 static void
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));
2197 if (DECL_NAME (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);
2206 /* namespace-alias:
2207 identifier
2209 namespace-alias-definition:
2210 namespace identifier = qualified-namespace-specifier ;
2212 qualified-namespace-specifier:
2213 ::(opt) nested-name-specifier(opt) namespace-name */
2215 static void
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);
2223 pp_equal (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) */
2235 static void
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:
2246 template-parameter
2247 template-parameter-list , template-parameter */
2249 static inline void
2250 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2252 const int n = TREE_VEC_LENGTH (t);
2253 int i;
2254 for (i = 0; i < n; ++i)
2256 if (i)
2257 pp_cxx_separate_with (pp, ',');
2258 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2262 /* template-parameter:
2263 type-parameter
2264 parameter-declaration
2266 type-parameter:
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 */
2274 static void
2275 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2277 tree parameter = TREE_VALUE (t);
2278 switch (TREE_CODE (parameter))
2280 case TYPE_DECL:
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. */
2287 break;
2289 case PARM_DECL:
2290 pp_cxx_parameter_declaration (pp, parameter);
2291 break;
2293 case TEMPLATE_DECL:
2294 break;
2296 default:
2297 pp_unsupported_tree (pp, t);
2298 break;
2302 /* Pretty-print a template parameter in the canonical form
2303 "template-parameter-<level>-<position in parameter list>". */
2305 void
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));
2318 pp_minus (pp);
2319 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2320 pp_cxx_end_template_argument_list (pp);
2323 /* Print a constrained-type-specifier. */
2325 void
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>");
2335 return;
2337 tree t, a;
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);
2347 ggc_free (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
2356 Concept extensions:
2358 template-declaration:
2359 export(opt) template < template-parameter-list >
2360 requires-clause(opt) declaration */
2362 static void
2363 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2365 tree tmpl = most_general_template (t);
2366 tree level;
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);
2378 if (flag_concepts)
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);
2390 else
2391 pp_cxx_simple_declaration (pp, t);
2394 static void
2395 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2397 pp_unsupported_tree (pp, t);
2400 static void
2401 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2403 pp_unsupported_tree (pp, t);
2406 static void
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);
2418 declaration:
2419 block-declaration
2420 function-definition
2421 template-declaration
2422 explicit-instantiation
2423 explicit-specialization
2424 linkage-specification
2425 namespace-definition
2427 block-declaration:
2428 simple-declaration
2429 asm-definition
2430 namespace-alias-definition
2431 using-declaration
2432 using-directive
2433 static_assert-declaration */
2434 void
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))
2451 case 1:
2452 pp_cxx_template_declaration (this, t);
2453 break;
2455 case 2:
2456 pp_cxx_explicit_specialization (this, t);
2457 break;
2459 case 3:
2460 pp_cxx_explicit_instantiation (this, t);
2461 break;
2463 default:
2464 break;
2466 else switch (TREE_CODE (t))
2468 case VAR_DECL:
2469 case TYPE_DECL:
2470 pp_cxx_simple_declaration (this, t);
2471 break;
2473 case FUNCTION_DECL:
2474 if (DECL_SAVED_TREE (t))
2475 pp_cxx_function_definition (this, t);
2476 else
2477 pp_cxx_simple_declaration (this, t);
2478 break;
2480 case NAMESPACE_DECL:
2481 if (DECL_NAMESPACE_ALIAS (t))
2482 pp_cxx_namespace_alias_definition (this, t);
2483 else
2484 pp_cxx_original_namespace_definition (this, t);
2485 break;
2487 default:
2488 pp_unsupported_tree (this, t);
2489 break;
2493 static void
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);
2499 if (TYPE_P (t))
2500 pp->type_id (t);
2501 else
2502 pp->expression (t);
2503 pp_cxx_right_paren (pp);
2506 void
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);
2517 static bool
2518 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2520 switch (TREE_CODE (t))
2522 case ARROW_EXPR:
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, ',');
2528 return true;
2530 return false;
2531 case COMPONENT_REF:
2532 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2533 return false;
2534 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2535 pp_cxx_dot (pp);
2536 pp->expression (TREE_OPERAND (t, 1));
2537 return true;
2538 case ARRAY_REF:
2539 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2540 return false;
2541 pp_left_bracket (pp);
2542 pp->expression (TREE_OPERAND (t, 1));
2543 pp_right_bracket (pp);
2544 return true;
2545 default:
2546 return false;
2550 void
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);
2560 void
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);
2569 static char const*
2570 get_fold_operator (tree t)
2572 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2573 FOLD_EXPR_OP (t));
2574 return info->name;
2577 void
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);
2589 void
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);
2596 pp_space (pp);
2597 pp_cxx_ws_string (pp, op);
2598 pp_cxx_ws_string (pp, "...");
2599 pp_cxx_right_paren (pp);
2602 void
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);
2610 else
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);
2621 void
2622 pp_cxx_trait (cxx_pretty_printer *pp, tree t)
2624 cp_trait_kind kind;
2625 tree type1, type2;
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);
2632 else
2634 kind = TRAIT_TYPE_KIND (t);
2635 type1 = TRAIT_TYPE_TYPE1 (t);
2636 type2 = TRAIT_TYPE_TYPE2 (t);
2639 switch (kind)
2641 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2642 case CPTK_##CODE: \
2643 pp_cxx_ws_string (pp, NAME); \
2644 break;
2645 #include "cp-trait.def"
2646 #undef DEFTRAIT
2649 if (kind == CPTK_TYPE_PACK_ELEMENT)
2651 pp_cxx_begin_template_argument_list (pp);
2652 pp->expression (type1);
2654 else
2656 pp_cxx_left_paren (pp);
2657 if (TYPE_P (type1))
2658 pp->type_id (type1);
2659 else
2660 pp->expression (type1);
2662 if (type2)
2664 if (TREE_CODE (type2) != TREE_VEC)
2666 pp_cxx_separate_with (pp, ',');
2667 pp->type_id (type2);
2669 else
2670 for (tree arg : tree_vec_range (type2))
2672 pp_cxx_separate_with (pp, ',');
2673 pp->type_id (arg);
2676 if (kind == CPTK_TYPE_PACK_ELEMENT)
2677 pp_cxx_end_template_argument_list (pp);
2678 else
2679 pp_cxx_right_paren (pp);
2682 // requires-clause:
2683 // 'requires' logical-or-expression
2684 void
2685 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2687 if (!t)
2688 return;
2689 pp->padding = pp_before;
2690 pp_cxx_ws_string (pp, "requires");
2691 pp_space (pp);
2692 pp->expression (t);
2695 /* requirement:
2696 simple-requirement
2697 compound-requirement
2698 type-requirement
2699 nested-requirement */
2700 static void
2701 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2703 switch (TREE_CODE (t))
2705 case SIMPLE_REQ:
2706 pp_cxx_simple_requirement (pp, t);
2707 break;
2709 case TYPE_REQ:
2710 pp_cxx_type_requirement (pp, t);
2711 break;
2713 case COMPOUND_REQ:
2714 pp_cxx_compound_requirement (pp, t);
2715 break;
2717 case NESTED_REQ:
2718 pp_cxx_nested_requirement (pp, t);
2719 break;
2721 default:
2722 gcc_unreachable ();
2726 // requirement-list:
2727 // requirement
2728 // requirement-list ';' requirement[opt]
2730 static void
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 '}'
2739 static void
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
2749 void
2750 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2752 pp_string (pp, "requires");
2753 if (tree parms = REQUIRES_EXPR_PARMS (t))
2755 bool first = true;
2756 pp_cxx_left_paren (pp);
2757 for (; parms; parms = TREE_CHAIN (parms))
2759 if (!first)
2760 pp_cxx_separate_with (pp, ',' );
2761 first = false;
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:
2771 expression ';' */
2772 void
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 ';' */
2781 void
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] */
2790 void
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, "->");
2804 pp->type_id (type);
2806 pp_cxx_semicolon (pp);
2809 /* nested requirement:
2810 'requires' constraint-expression */
2811 void
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);
2819 void
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);
2838 else
2839 gcc_unreachable ();
2842 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2843 constraint. */
2845 void
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);
2858 if (TYPE_P (parm))
2859 pp->type_id (parm);
2860 else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2861 pp_cxx_tree_identifier (pp, name);
2862 else
2863 pp->translate_string ("<unnamed>");
2865 pp_cxx_whitespace (pp);
2866 pp_equal (pp);
2867 pp_cxx_whitespace (pp);
2869 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2870 pp->type_id (arg);
2871 else
2872 pp->expression (arg);
2874 if (TREE_CHAIN (p) != NULL_TREE)
2875 pp_cxx_separate_with (pp, ';');
2878 pp_cxx_right_bracket (pp);
2881 void
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);
2893 void
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));
2901 void
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));
2909 void
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))
2917 case ATOMIC_CONSTR:
2918 pp_cxx_atomic_constraint (pp, t);
2919 break;
2921 case CHECK_CONSTR:
2922 pp_cxx_check_constraint (pp, t);
2923 break;
2925 case CONJ_CONSTR:
2926 pp_cxx_conjunction (pp, t);
2927 break;
2929 case DISJ_CONSTR:
2930 pp_cxx_disjunction (pp, t);
2931 break;
2933 case EXPR_PACK_EXPANSION:
2934 pp->expression (TREE_OPERAND (t, 0));
2935 break;
2937 default:
2938 gcc_unreachable ();
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. */
2957 pretty_printer *
2958 cxx_pretty_printer::clone () const
2960 return new cxx_pretty_printer (*this);