Require target lra in gcc.c-torture/compile/asmgoto-6.c
[official-gcc.git] / gcc / cp / cxx-pretty-print.cc
blob909a9dc917f20b70b2c4bdb55e68b880320592b5
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 case PARM_DECL:
1125 case FIELD_DECL:
1126 case CONST_DECL:
1127 case FUNCTION_DECL:
1128 case BASELINK:
1129 case TEMPLATE_DECL:
1130 case TEMPLATE_TYPE_PARM:
1131 case TEMPLATE_PARM_INDEX:
1132 case TEMPLATE_TEMPLATE_PARM:
1133 case STMT_EXPR:
1134 case REQUIRES_EXPR:
1135 primary_expression (t);
1136 break;
1138 case CALL_EXPR:
1139 case DYNAMIC_CAST_EXPR:
1140 case STATIC_CAST_EXPR:
1141 case REINTERPRET_CAST_EXPR:
1142 case CONST_CAST_EXPR:
1143 #if 0
1144 case MEMBER_REF:
1145 #endif
1146 case EMPTY_CLASS_EXPR:
1147 case TYPEID_EXPR:
1148 case PSEUDO_DTOR_EXPR:
1149 case AGGR_INIT_EXPR:
1150 case ARROW_EXPR:
1151 postfix_expression (t);
1152 break;
1154 case NEW_EXPR:
1155 case VEC_NEW_EXPR:
1156 pp_cxx_new_expression (this, t);
1157 break;
1159 case DELETE_EXPR:
1160 case VEC_DELETE_EXPR:
1161 pp_cxx_delete_expression (this, t);
1162 break;
1164 case SIZEOF_EXPR:
1165 case ALIGNOF_EXPR:
1166 case NOEXCEPT_EXPR:
1167 case UNARY_PLUS_EXPR:
1168 unary_expression (t);
1169 break;
1171 case CAST_EXPR:
1172 case IMPLICIT_CONV_EXPR:
1173 pp_cxx_cast_expression (this, t);
1174 break;
1176 case OFFSET_REF:
1177 case MEMBER_REF:
1178 case DOTSTAR_EXPR:
1179 pp_cxx_pm_expression (this, t);
1180 break;
1182 case MULT_EXPR:
1183 case TRUNC_DIV_EXPR:
1184 case TRUNC_MOD_EXPR:
1185 case EXACT_DIV_EXPR:
1186 case RDIV_EXPR:
1187 multiplicative_expression (t);
1188 break;
1190 case COND_EXPR:
1191 conditional_expression (t);
1192 break;
1194 case MODIFY_EXPR:
1195 case INIT_EXPR:
1196 case THROW_EXPR:
1197 case MODOP_EXPR:
1198 assignment_expression (t);
1199 break;
1201 case NON_DEPENDENT_EXPR:
1202 case MUST_NOT_THROW_EXPR:
1203 expression (TREE_OPERAND (t, 0));
1204 break;
1206 case EXPR_PACK_EXPANSION:
1207 expression (PACK_EXPANSION_PATTERN (t));
1208 pp_cxx_ws_string (this, "...");
1209 break;
1211 case UNARY_LEFT_FOLD_EXPR:
1212 pp_cxx_unary_left_fold_expression (this, t);
1213 break;
1215 case UNARY_RIGHT_FOLD_EXPR:
1216 pp_cxx_unary_right_fold_expression (this, t);
1217 break;
1219 case BINARY_LEFT_FOLD_EXPR:
1220 case BINARY_RIGHT_FOLD_EXPR:
1221 pp_cxx_binary_fold_expression (this, t);
1222 break;
1224 case TEMPLATE_ID_EXPR:
1225 pp_cxx_template_id (this, t);
1226 break;
1228 case NONTYPE_ARGUMENT_PACK:
1230 tree args = ARGUMENT_PACK_ARGS (t);
1231 int i, len = TREE_VEC_LENGTH (args);
1232 pp_cxx_left_brace (this);
1233 for (i = 0; i < len; ++i)
1235 if (i > 0)
1236 pp_cxx_separate_with (this, ',');
1237 expression (TREE_VEC_ELT (args, i));
1239 pp_cxx_right_brace (this);
1241 break;
1243 case LAMBDA_EXPR:
1244 pp_cxx_ws_string (this, "<lambda>");
1245 break;
1247 case TRAIT_EXPR:
1248 pp_cxx_trait (this, t);
1249 break;
1251 case ATOMIC_CONSTR:
1252 case CHECK_CONSTR:
1253 case CONJ_CONSTR:
1254 case DISJ_CONSTR:
1255 pp_cxx_constraint (this, t);
1256 break;
1258 case PAREN_EXPR:
1259 pp_cxx_left_paren (this);
1260 expression (TREE_OPERAND (t, 0));
1261 pp_cxx_right_paren (this);
1262 break;
1264 default:
1265 c_pretty_printer::expression (t);
1266 break;
1271 /* Declarations. */
1273 /* function-specifier:
1274 inline
1275 virtual
1276 explicit */
1278 void
1279 cxx_pretty_printer::function_specifier (tree t)
1281 switch (TREE_CODE (t))
1283 case FUNCTION_DECL:
1284 if (DECL_VIRTUAL_P (t))
1285 pp_cxx_ws_string (this, "virtual");
1286 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1287 pp_cxx_ws_string (this, "explicit");
1288 else
1289 c_pretty_printer::function_specifier (t);
1291 default:
1292 break;
1296 /* decl-specifier-seq:
1297 decl-specifier-seq(opt) decl-specifier
1299 decl-specifier:
1300 storage-class-specifier
1301 type-specifier
1302 function-specifier
1303 friend
1304 typedef */
1306 void
1307 cxx_pretty_printer::declaration_specifiers (tree t)
1309 switch (TREE_CODE (t))
1311 case VAR_DECL:
1312 case PARM_DECL:
1313 case CONST_DECL:
1314 case FIELD_DECL:
1315 storage_class_specifier (t);
1316 declaration_specifiers (TREE_TYPE (t));
1317 break;
1319 case TYPE_DECL:
1320 pp_cxx_ws_string (this, "typedef");
1321 declaration_specifiers (TREE_TYPE (t));
1322 break;
1324 case FUNCTION_DECL:
1325 /* Constructors don't have return types. And conversion functions
1326 do not have a type-specifier in their return types. */
1327 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1328 function_specifier (t);
1329 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1330 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1331 else
1332 c_pretty_printer::declaration_specifiers (t);
1333 break;
1334 default:
1335 c_pretty_printer::declaration_specifiers (t);
1336 break;
1340 /* simple-type-specifier:
1341 ::(opt) nested-name-specifier(opt) type-name
1342 ::(opt) nested-name-specifier(opt) template(opt) template-id
1343 decltype-specifier
1344 char
1345 wchar_t
1346 bool
1347 short
1349 long
1350 signed
1351 unsigned
1352 float
1353 double
1354 void */
1356 void
1357 cxx_pretty_printer::simple_type_specifier (tree t)
1359 switch (TREE_CODE (t))
1361 case RECORD_TYPE:
1362 case UNION_TYPE:
1363 case ENUMERAL_TYPE:
1364 pp_cxx_qualified_id (this, t);
1365 break;
1367 case TEMPLATE_TYPE_PARM:
1368 case TEMPLATE_TEMPLATE_PARM:
1369 case TEMPLATE_PARM_INDEX:
1370 case BOUND_TEMPLATE_TEMPLATE_PARM:
1371 pp_cxx_unqualified_id (this, t);
1372 if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
1373 if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
1374 pp_cxx_constrained_type_spec (this, c);
1375 break;
1377 case TYPENAME_TYPE:
1378 pp_cxx_ws_string (this, "typename");
1379 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1380 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
1381 break;
1383 case DECLTYPE_TYPE:
1384 pp_cxx_ws_string (this, "decltype");
1385 pp_cxx_left_paren (this);
1386 this->expression (DECLTYPE_TYPE_EXPR (t));
1387 pp_cxx_right_paren (this);
1388 break;
1390 case NULLPTR_TYPE:
1391 pp_cxx_ws_string (this, "std::nullptr_t");
1392 break;
1394 case TRAIT_TYPE:
1395 pp_cxx_trait (this, t);
1396 break;
1398 default:
1399 c_pretty_printer::simple_type_specifier (t);
1400 break;
1404 /* type-specifier-seq:
1405 type-specifier type-specifier-seq(opt)
1407 type-specifier:
1408 simple-type-specifier
1409 class-specifier
1410 enum-specifier
1411 elaborated-type-specifier
1412 cv-qualifier */
1414 static void
1415 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1417 switch (TREE_CODE (t))
1419 case TEMPLATE_DECL:
1420 case TEMPLATE_TYPE_PARM:
1421 case TEMPLATE_TEMPLATE_PARM:
1422 case TYPE_DECL:
1423 case BOUND_TEMPLATE_TEMPLATE_PARM:
1424 case DECLTYPE_TYPE:
1425 case NULLPTR_TYPE:
1426 pp_cxx_cv_qualifier_seq (pp, t);
1427 pp->simple_type_specifier (t);
1428 break;
1430 case METHOD_TYPE:
1431 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1432 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1433 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1434 break;
1436 case RECORD_TYPE:
1437 if (TYPE_PTRMEMFUNC_P (t))
1439 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1440 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1441 pp_cxx_whitespace (pp);
1442 pp_cxx_ptr_operator (pp, t);
1443 break;
1445 /* fall through */
1447 case OFFSET_TYPE:
1448 if (TYPE_PTRDATAMEM_P (t))
1450 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1451 pp_cxx_whitespace (pp);
1452 pp_cxx_ptr_operator (pp, t);
1453 break;
1455 /* fall through */
1457 default:
1458 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1459 pp_c_specifier_qualifier_list (pp, t);
1463 /* ptr-operator:
1464 * cv-qualifier-seq(opt)
1466 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1468 static void
1469 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1471 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1472 t = TREE_TYPE (t);
1473 switch (TREE_CODE (t))
1475 case REFERENCE_TYPE:
1476 case POINTER_TYPE:
1477 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1478 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1479 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1480 if (TYPE_PTR_P (t))
1482 pp_star (pp);
1483 pp_cxx_cv_qualifier_seq (pp, t);
1485 else
1486 pp_ampersand (pp);
1487 break;
1489 case RECORD_TYPE:
1490 if (TYPE_PTRMEMFUNC_P (t))
1492 pp_cxx_left_paren (pp);
1493 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1494 pp_star (pp);
1495 break;
1497 /* FALLTHRU */
1498 case OFFSET_TYPE:
1499 if (TYPE_PTRMEM_P (t))
1501 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1502 pp_cxx_left_paren (pp);
1503 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1504 pp_star (pp);
1505 pp_cxx_cv_qualifier_seq (pp, t);
1506 break;
1508 /* fall through. */
1510 default:
1511 pp_unsupported_tree (pp, t);
1512 break;
1516 static inline tree
1517 pp_cxx_implicit_parameter_type (tree mf)
1519 return class_of_this_parm (TREE_TYPE (mf));
1523 parameter-declaration:
1524 decl-specifier-seq declarator
1525 decl-specifier-seq declarator = assignment-expression
1526 decl-specifier-seq abstract-declarator(opt)
1527 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1529 static inline void
1530 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1532 pp->declaration_specifiers (t);
1533 if (TYPE_P (t))
1534 pp->abstract_declarator (t);
1535 else
1536 pp->declarator (t);
1539 /* parameter-declaration-clause:
1540 parameter-declaration-list(opt) ...(opt)
1541 parameter-declaration-list , ...
1543 parameter-declaration-list:
1544 parameter-declaration
1545 parameter-declaration-list , parameter-declaration */
1547 static void
1548 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1550 gcc_assert (FUNC_OR_METHOD_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL);
1551 tree types, args;
1552 if (TYPE_P (t))
1554 types = TYPE_ARG_TYPES (t);
1555 args = NULL_TREE;
1557 else
1559 types = FUNCTION_FIRST_USER_PARMTYPE (t);
1560 args = FUNCTION_FIRST_USER_PARM (t);
1562 bool abstract = !args || (pp->flags & pp_c_flag_abstract);
1564 /* Skip artificial parameter for non-static member functions. */
1565 if (TREE_CODE (t) == METHOD_TYPE)
1566 types = TREE_CHAIN (types);
1568 bool first = true;
1569 pp_cxx_left_paren (pp);
1570 for (; types != void_list_node; types = TREE_CHAIN (types))
1572 if (!first)
1573 pp_cxx_separate_with (pp, ',');
1574 first = false;
1575 if (!types)
1577 pp_cxx_ws_string (pp, "...");
1578 break;
1580 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1581 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1583 pp_cxx_whitespace (pp);
1584 pp_equal (pp);
1585 pp_cxx_whitespace (pp);
1586 pp->assignment_expression (TREE_PURPOSE (types));
1588 if (!abstract)
1589 args = TREE_CHAIN (args);
1591 pp_cxx_right_paren (pp);
1594 /* exception-specification:
1595 throw ( type-id-list(opt) )
1597 type-id-list
1598 type-id
1599 type-id-list , type-id */
1601 static void
1602 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1604 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1605 bool need_comma = false;
1607 if (ex_spec == NULL)
1608 return;
1609 if (TREE_PURPOSE (ex_spec))
1611 pp_cxx_ws_string (pp, "noexcept");
1612 pp_cxx_whitespace (pp);
1613 pp_cxx_left_paren (pp);
1614 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1615 pp_cxx_ws_string (pp, "<uninstantiated>");
1616 else
1617 pp->expression (TREE_PURPOSE (ex_spec));
1618 pp_cxx_right_paren (pp);
1619 return;
1621 pp_cxx_ws_string (pp, "throw");
1622 pp_cxx_left_paren (pp);
1623 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1625 tree type = TREE_VALUE (ex_spec);
1626 tree argpack = NULL_TREE;
1627 int i, len = 1;
1629 if (ARGUMENT_PACK_P (type))
1631 argpack = ARGUMENT_PACK_ARGS (type);
1632 len = TREE_VEC_LENGTH (argpack);
1635 for (i = 0; i < len; ++i)
1637 if (argpack)
1638 type = TREE_VEC_ELT (argpack, i);
1640 if (need_comma)
1641 pp_cxx_separate_with (pp, ',');
1642 else
1643 need_comma = true;
1645 pp->type_id (type);
1648 pp_cxx_right_paren (pp);
1651 /* direct-declarator:
1652 declarator-id
1653 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1654 exception-specification(opt)
1655 direct-declaration [ constant-expression(opt) ]
1656 ( declarator ) */
1658 void
1659 cxx_pretty_printer::direct_declarator (tree t)
1661 switch (TREE_CODE (t))
1663 case VAR_DECL:
1664 case PARM_DECL:
1665 case CONST_DECL:
1666 case FIELD_DECL:
1667 if (DECL_NAME (t))
1669 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1671 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1672 || template_parameter_pack_p (t))
1673 /* A function parameter pack or non-type template
1674 parameter pack. */
1675 pp_cxx_ws_string (this, "...");
1677 id_expression (DECL_NAME (t));
1679 abstract_declarator (TREE_TYPE (t));
1680 break;
1682 case FUNCTION_DECL:
1683 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1684 expression (t);
1685 pp_cxx_parameter_declaration_clause (this, t);
1687 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1689 padding = pp_before;
1690 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1693 pp_cxx_exception_specification (this, TREE_TYPE (t));
1694 break;
1696 case TYPENAME_TYPE:
1697 case TEMPLATE_DECL:
1698 case TEMPLATE_TYPE_PARM:
1699 case TEMPLATE_PARM_INDEX:
1700 case TEMPLATE_TEMPLATE_PARM:
1701 break;
1703 default:
1704 c_pretty_printer::direct_declarator (t);
1705 break;
1709 /* declarator:
1710 direct-declarator
1711 ptr-operator declarator */
1713 void
1714 cxx_pretty_printer::declarator (tree t)
1716 direct_declarator (t);
1718 // Print a requires clause.
1719 if (flag_concepts)
1720 if (tree ci = get_constraints (t))
1721 if (tree reqs = CI_DECLARATOR_REQS (ci))
1722 pp_cxx_requires_clause (this, reqs);
1725 /* ctor-initializer:
1726 : mem-initializer-list
1728 mem-initializer-list:
1729 mem-initializer
1730 mem-initializer , mem-initializer-list
1732 mem-initializer:
1733 mem-initializer-id ( expression-list(opt) )
1735 mem-initializer-id:
1736 ::(opt) nested-name-specifier(opt) class-name
1737 identifier */
1739 static void
1740 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1742 t = TREE_OPERAND (t, 0);
1743 pp_cxx_whitespace (pp);
1744 pp_colon (pp);
1745 pp_cxx_whitespace (pp);
1746 for (; t; t = TREE_CHAIN (t))
1748 tree purpose = TREE_PURPOSE (t);
1749 bool is_pack = PACK_EXPANSION_P (purpose);
1751 if (is_pack)
1752 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1753 else
1754 pp->primary_expression (purpose);
1755 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1756 if (is_pack)
1757 pp_cxx_ws_string (pp, "...");
1758 if (TREE_CHAIN (t))
1759 pp_cxx_separate_with (pp, ',');
1763 /* function-definition:
1764 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1765 decl-specifier-seq(opt) declarator function-try-block */
1767 static void
1768 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1770 tree saved_scope = pp->enclosing_scope;
1771 pp->declaration_specifiers (t);
1772 pp->declarator (t);
1773 pp_needs_newline (pp) = true;
1774 pp->enclosing_scope = DECL_CONTEXT (t);
1775 if (DECL_SAVED_TREE (t))
1776 pp->statement (DECL_SAVED_TREE (t));
1777 else
1778 pp_cxx_semicolon (pp);
1779 pp_newline_and_flush (pp);
1780 pp->enclosing_scope = saved_scope;
1783 /* abstract-declarator:
1784 ptr-operator abstract-declarator(opt)
1785 direct-abstract-declarator */
1787 void
1788 cxx_pretty_printer::abstract_declarator (tree t)
1790 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1791 or a pointer-to-data-member of array type:
1793 void (X::*)()
1794 int (X::*)[5]
1796 but not for a pointer-to-data-member of non-array type:
1798 int X::*
1800 so be mindful of that. */
1801 if (TYPE_PTRMEMFUNC_P (t)
1802 || (TYPE_PTRDATAMEM_P (t)
1803 && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
1804 pp_cxx_right_paren (this);
1805 else if (INDIRECT_TYPE_P (t))
1807 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1808 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1809 pp_cxx_right_paren (this);
1810 t = TREE_TYPE (t);
1812 direct_abstract_declarator (t);
1815 /* direct-abstract-declarator:
1816 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1817 cv-qualifier-seq(opt) exception-specification(opt)
1818 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1819 ( abstract-declarator ) */
1821 void
1822 cxx_pretty_printer::direct_abstract_declarator (tree t)
1824 switch (TREE_CODE (t))
1826 case REFERENCE_TYPE:
1827 abstract_declarator (t);
1828 break;
1830 case RECORD_TYPE:
1831 if (TYPE_PTRMEMFUNC_P (t))
1832 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1833 break;
1835 case OFFSET_TYPE:
1836 if (TYPE_PTRDATAMEM_P (t))
1837 direct_abstract_declarator (TREE_TYPE (t));
1838 break;
1840 case METHOD_TYPE:
1841 case FUNCTION_TYPE:
1842 pp_cxx_parameter_declaration_clause (this, t);
1843 direct_abstract_declarator (TREE_TYPE (t));
1844 if (TREE_CODE (t) == METHOD_TYPE)
1846 padding = pp_before;
1847 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1849 pp_cxx_exception_specification (this, t);
1850 break;
1852 case TYPENAME_TYPE:
1853 case TEMPLATE_TYPE_PARM:
1854 case TEMPLATE_TEMPLATE_PARM:
1855 case BOUND_TEMPLATE_TEMPLATE_PARM:
1856 case UNBOUND_CLASS_TEMPLATE:
1857 case DECLTYPE_TYPE:
1858 break;
1860 default:
1861 c_pretty_printer::direct_abstract_declarator (t);
1862 break;
1866 /* type-id:
1867 type-specifier-seq abstract-declarator(opt) */
1869 void
1870 cxx_pretty_printer::type_id (tree t)
1872 pp_flags saved_flags = flags;
1873 flags |= pp_c_flag_abstract;
1875 switch (TREE_CODE (t))
1877 case TYPE_DECL:
1878 case UNION_TYPE:
1879 case RECORD_TYPE:
1880 case ENUMERAL_TYPE:
1881 case TYPENAME_TYPE:
1882 case BOUND_TEMPLATE_TEMPLATE_PARM:
1883 case UNBOUND_CLASS_TEMPLATE:
1884 case TEMPLATE_TEMPLATE_PARM:
1885 case TEMPLATE_TYPE_PARM:
1886 case TEMPLATE_PARM_INDEX:
1887 case TEMPLATE_DECL:
1888 case TYPEOF_TYPE:
1889 case TRAIT_TYPE:
1890 case DECLTYPE_TYPE:
1891 case NULLPTR_TYPE:
1892 case TEMPLATE_ID_EXPR:
1893 case OFFSET_TYPE:
1894 pp_cxx_type_specifier_seq (this, t);
1895 if (TYPE_PTRMEM_P (t))
1896 abstract_declarator (t);
1897 break;
1899 case TYPE_PACK_EXPANSION:
1900 type_id (PACK_EXPANSION_PATTERN (t));
1901 pp_cxx_ws_string (this, "...");
1902 break;
1904 case TYPE_ARGUMENT_PACK:
1906 tree args = ARGUMENT_PACK_ARGS (t);
1907 int len = TREE_VEC_LENGTH (args);
1908 pp_cxx_left_brace (this);
1909 for (int i = 0; i < len; ++i)
1911 if (i > 0)
1912 pp_cxx_separate_with (this, ',');
1913 type_id (TREE_VEC_ELT (args, i));
1915 pp_cxx_right_brace (this);
1917 break;
1919 default:
1920 c_pretty_printer::type_id (t);
1921 break;
1924 flags = saved_flags;
1927 /* template-argument-list:
1928 template-argument ...(opt)
1929 template-argument-list, template-argument ...(opt)
1931 template-argument:
1932 assignment-expression
1933 type-id
1934 template-name */
1936 static void
1937 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1939 int i;
1940 bool need_comma = false;
1942 if (t == NULL)
1943 return;
1944 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1946 tree arg = TREE_VEC_ELT (t, i);
1947 tree argpack = NULL_TREE;
1948 int idx, len = 1;
1950 if (ARGUMENT_PACK_P (arg))
1952 argpack = ARGUMENT_PACK_ARGS (arg);
1953 len = TREE_VEC_LENGTH (argpack);
1956 for (idx = 0; idx < len; idx++)
1958 if (argpack)
1959 arg = TREE_VEC_ELT (argpack, idx);
1961 if (need_comma)
1962 pp_cxx_separate_with (pp, ',');
1963 else
1964 need_comma = true;
1966 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1967 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1968 pp->type_id (arg);
1969 else if (VAR_P (arg) && DECL_NTTP_OBJECT_P (arg))
1970 pp->expression (DECL_INITIAL (arg));
1971 else
1972 pp->expression (arg);
1978 static void
1979 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1981 t = DECL_EXPR_DECL (t);
1982 pp_cxx_type_specifier_seq (pp, t);
1983 if (TYPE_P (t))
1984 pp->abstract_declarator (t);
1985 else
1986 pp->declarator (t);
1989 /* Statements. */
1991 void
1992 cxx_pretty_printer::statement (tree t)
1994 switch (TREE_CODE (t))
1996 case CTOR_INITIALIZER:
1997 pp_cxx_ctor_initializer (this, t);
1998 break;
2000 case USING_STMT:
2001 pp_cxx_ws_string (this, "using");
2002 pp_cxx_ws_string (this, "namespace");
2003 if (DECL_CONTEXT (t))
2004 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
2005 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
2006 break;
2008 case USING_DECL:
2009 pp_cxx_ws_string (this, "using");
2010 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
2011 pp_cxx_unqualified_id (this, DECL_NAME (t));
2012 break;
2014 case EH_SPEC_BLOCK:
2015 break;
2017 /* try-block:
2018 try compound-statement handler-seq */
2019 case TRY_BLOCK:
2020 pp_maybe_newline_and_indent (this, 0);
2021 pp_cxx_ws_string (this, "try");
2022 pp_newline_and_indent (this, 3);
2023 statement (TRY_STMTS (t));
2024 pp_newline_and_indent (this, -3);
2025 if (CLEANUP_P (t))
2027 else
2028 statement (TRY_HANDLERS (t));
2029 break;
2032 handler-seq:
2033 handler handler-seq(opt)
2035 handler:
2036 catch ( exception-declaration ) compound-statement
2038 exception-declaration:
2039 type-specifier-seq declarator
2040 type-specifier-seq abstract-declarator
2041 ... */
2042 case HANDLER:
2043 pp_cxx_ws_string (this, "catch");
2044 pp_cxx_left_paren (this);
2045 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
2046 pp_cxx_right_paren (this);
2047 pp_indentation (this) += 3;
2048 pp_needs_newline (this) = true;
2049 statement (HANDLER_BODY (t));
2050 pp_indentation (this) -= 3;
2051 pp_needs_newline (this) = true;
2052 break;
2054 /* selection-statement:
2055 if ( expression ) statement
2056 if ( expression ) statement else statement */
2057 case IF_STMT:
2058 pp_cxx_ws_string (this, "if");
2059 pp_cxx_whitespace (this);
2060 pp_cxx_left_paren (this);
2061 expression (IF_COND (t));
2062 pp_cxx_right_paren (this);
2063 pp_newline_and_indent (this, 2);
2064 statement (THEN_CLAUSE (t));
2065 pp_newline_and_indent (this, -2);
2066 if (ELSE_CLAUSE (t))
2068 tree else_clause = ELSE_CLAUSE (t);
2069 pp_cxx_ws_string (this, "else");
2070 if (TREE_CODE (else_clause) == IF_STMT)
2071 pp_cxx_whitespace (this);
2072 else
2073 pp_newline_and_indent (this, 2);
2074 statement (else_clause);
2075 if (TREE_CODE (else_clause) != IF_STMT)
2076 pp_newline_and_indent (this, -2);
2078 break;
2080 case RANGE_FOR_STMT:
2081 pp_cxx_ws_string (this, "for");
2082 pp_space (this);
2083 pp_cxx_left_paren (this);
2084 if (RANGE_FOR_INIT_STMT (t))
2086 statement (RANGE_FOR_INIT_STMT (t));
2087 pp_needs_newline (this) = false;
2088 pp_cxx_whitespace (this);
2090 statement (RANGE_FOR_DECL (t));
2091 pp_space (this);
2092 pp_needs_newline (this) = false;
2093 pp_colon (this);
2094 pp_space (this);
2095 statement (RANGE_FOR_EXPR (t));
2096 pp_cxx_right_paren (this);
2097 pp_newline_and_indent (this, 3);
2098 statement (FOR_BODY (t));
2099 pp_indentation (this) -= 3;
2100 pp_needs_newline (this) = true;
2101 break;
2103 /* expression-statement:
2104 expression(opt) ; */
2105 case EXPR_STMT:
2106 expression (EXPR_STMT_EXPR (t));
2107 pp_cxx_semicolon (this);
2108 pp_needs_newline (this) = true;
2109 break;
2111 case CLEANUP_STMT:
2112 pp_cxx_ws_string (this, "try");
2113 pp_newline_and_indent (this, 2);
2114 statement (CLEANUP_BODY (t));
2115 pp_newline_and_indent (this, -2);
2116 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2117 pp_newline_and_indent (this, 2);
2118 statement (CLEANUP_EXPR (t));
2119 pp_newline_and_indent (this, -2);
2120 break;
2122 case STATIC_ASSERT:
2123 declaration (t);
2124 break;
2126 case OMP_DEPOBJ:
2127 pp_cxx_ws_string (this, "#pragma omp depobj");
2128 pp_space (this);
2129 pp_cxx_left_paren (this);
2130 expression (OMP_DEPOBJ_DEPOBJ (t));
2131 pp_cxx_right_paren (this);
2132 if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
2134 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
2135 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t),
2136 pp_indentation (this), TDF_NONE);
2137 else
2138 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2140 case OMP_CLAUSE_DEPEND_IN:
2141 pp_cxx_ws_string (this, " update(in)");
2142 break;
2143 case OMP_CLAUSE_DEPEND_INOUT:
2144 pp_cxx_ws_string (this, " update(inout)");
2145 break;
2146 case OMP_CLAUSE_DEPEND_OUT:
2147 pp_cxx_ws_string (this, " update(out)");
2148 break;
2149 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2150 pp_cxx_ws_string (this, " update(mutexinoutset)");
2151 break;
2152 case OMP_CLAUSE_DEPEND_INOUTSET:
2153 pp_cxx_ws_string (this, " update(inoutset)");
2154 break;
2155 case OMP_CLAUSE_DEPEND_LAST:
2156 pp_cxx_ws_string (this, " destroy");
2157 break;
2158 default:
2159 break;
2162 pp_needs_newline (this) = true;
2163 break;
2165 default:
2166 c_pretty_printer::statement (t);
2167 break;
2171 /* original-namespace-definition:
2172 namespace identifier { namespace-body }
2174 As an edge case, we also handle unnamed namespace definition here. */
2176 static void
2177 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2179 pp_cxx_ws_string (pp, "namespace");
2180 if (DECL_CONTEXT (t))
2181 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2182 if (DECL_NAME (t))
2183 pp_cxx_unqualified_id (pp, t);
2184 pp_cxx_whitespace (pp);
2185 pp_cxx_left_brace (pp);
2186 /* We do not print the namespace-body. */
2187 pp_cxx_whitespace (pp);
2188 pp_cxx_right_brace (pp);
2191 /* namespace-alias:
2192 identifier
2194 namespace-alias-definition:
2195 namespace identifier = qualified-namespace-specifier ;
2197 qualified-namespace-specifier:
2198 ::(opt) nested-name-specifier(opt) namespace-name */
2200 static void
2201 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2203 pp_cxx_ws_string (pp, "namespace");
2204 if (DECL_CONTEXT (t))
2205 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2206 pp_cxx_unqualified_id (pp, t);
2207 pp_cxx_whitespace (pp);
2208 pp_equal (pp);
2209 pp_cxx_whitespace (pp);
2210 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2211 pp_cxx_nested_name_specifier (pp,
2212 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2213 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2214 pp_cxx_semicolon (pp);
2217 /* simple-declaration:
2218 decl-specifier-seq(opt) init-declarator-list(opt) */
2220 static void
2221 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2223 pp->declaration_specifiers (t);
2224 pp_cxx_init_declarator (pp, t);
2225 pp_cxx_semicolon (pp);
2226 pp_needs_newline (pp) = true;
2230 template-parameter-list:
2231 template-parameter
2232 template-parameter-list , template-parameter */
2234 static inline void
2235 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2237 const int n = TREE_VEC_LENGTH (t);
2238 int i;
2239 for (i = 0; i < n; ++i)
2241 if (i)
2242 pp_cxx_separate_with (pp, ',');
2243 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2247 /* template-parameter:
2248 type-parameter
2249 parameter-declaration
2251 type-parameter:
2252 class ...(opt) identifier(opt)
2253 class identifier(opt) = type-id
2254 typename identifier(opt)
2255 typename ...(opt) identifier(opt) = type-id
2256 template < template-parameter-list > class ...(opt) identifier(opt)
2257 template < template-parameter-list > class identifier(opt) = template-name */
2259 static void
2260 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2262 tree parameter = TREE_VALUE (t);
2263 switch (TREE_CODE (parameter))
2265 case TYPE_DECL:
2266 pp_cxx_ws_string (pp, "class");
2267 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2268 pp_cxx_ws_string (pp, "...");
2269 if (DECL_NAME (parameter))
2270 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2271 /* FIXME: Check if we should print also default argument. */
2272 break;
2274 case PARM_DECL:
2275 pp_cxx_parameter_declaration (pp, parameter);
2276 break;
2278 case TEMPLATE_DECL:
2279 break;
2281 default:
2282 pp_unsupported_tree (pp, t);
2283 break;
2287 /* Pretty-print a template parameter in the canonical form
2288 "template-parameter-<level>-<position in parameter list>". */
2290 void
2291 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2293 const enum tree_code code = TREE_CODE (parm);
2295 /* Brings type template parameters to the canonical forms. */
2296 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2297 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2298 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2300 pp_cxx_begin_template_argument_list (pp);
2301 pp->translate_string ("template-parameter-");
2302 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2303 pp_minus (pp);
2304 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2305 pp_cxx_end_template_argument_list (pp);
2308 /* Print a constrained-type-specifier. */
2310 void
2311 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2313 pp_cxx_whitespace (pp);
2314 pp_cxx_left_bracket (pp);
2315 pp->translate_string ("requires");
2316 pp_cxx_whitespace (pp);
2317 if (c == error_mark_node)
2319 pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
2320 return;
2322 tree t, a;
2323 placeholder_extract_concept_and_args (c, t, a);
2324 pp->id_expression (t);
2325 pp_cxx_begin_template_argument_list (pp);
2326 pp_cxx_ws_string (pp, "<placeholder>");
2327 pp_cxx_separate_with (pp, ',');
2328 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2329 for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i)
2330 TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1);
2331 pp_cxx_template_argument_list (pp, args);
2332 ggc_free (args);
2333 pp_cxx_end_template_argument_list (pp);
2334 pp_cxx_right_bracket (pp);
2338 template-declaration:
2339 export(opt) template < template-parameter-list > declaration
2341 Concept extensions:
2343 template-declaration:
2344 export(opt) template < template-parameter-list >
2345 requires-clause(opt) declaration */
2347 static void
2348 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2350 tree tmpl = most_general_template (t);
2351 tree level;
2353 pp_maybe_newline_and_indent (pp, 0);
2354 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2356 pp_cxx_ws_string (pp, "template");
2357 pp_cxx_begin_template_argument_list (pp);
2358 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2359 pp_cxx_end_template_argument_list (pp);
2360 pp_newline_and_indent (pp, 3);
2363 if (flag_concepts)
2364 if (tree ci = get_constraints (t))
2365 if (tree reqs = CI_TEMPLATE_REQS (ci))
2367 pp_cxx_requires_clause (pp, reqs);
2368 pp_newline_and_indent (pp, 6);
2371 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2372 pp_cxx_function_definition (pp, t);
2373 else if (TREE_CODE (t) == CONCEPT_DECL)
2374 pp_cxx_concept_definition (pp, t);
2375 else
2376 pp_cxx_simple_declaration (pp, t);
2379 static void
2380 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2382 pp_unsupported_tree (pp, t);
2385 static void
2386 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2388 pp_unsupported_tree (pp, t);
2391 static void
2392 pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t)
2394 pp_cxx_unqualified_id (pp, DECL_NAME (t));
2395 pp_cxx_whitespace (pp);
2396 pp_cxx_ws_string (pp, "=");
2397 pp_cxx_whitespace (pp);
2398 pp->expression (DECL_INITIAL (t));
2399 pp_cxx_semicolon (pp);
2403 declaration:
2404 block-declaration
2405 function-definition
2406 template-declaration
2407 explicit-instantiation
2408 explicit-specialization
2409 linkage-specification
2410 namespace-definition
2412 block-declaration:
2413 simple-declaration
2414 asm-definition
2415 namespace-alias-definition
2416 using-declaration
2417 using-directive
2418 static_assert-declaration */
2419 void
2420 cxx_pretty_printer::declaration (tree t)
2422 if (TREE_CODE (t) == STATIC_ASSERT)
2424 pp_cxx_ws_string (this, "static_assert");
2425 pp_cxx_left_paren (this);
2426 expression (STATIC_ASSERT_CONDITION (t));
2427 pp_cxx_separate_with (this, ',');
2428 expression (STATIC_ASSERT_MESSAGE (t));
2429 pp_cxx_right_paren (this);
2431 else if (!DECL_LANG_SPECIFIC (t))
2432 pp_cxx_simple_declaration (this, t);
2433 else if (DECL_USE_TEMPLATE (t))
2434 switch (DECL_USE_TEMPLATE (t))
2436 case 1:
2437 pp_cxx_template_declaration (this, t);
2438 break;
2440 case 2:
2441 pp_cxx_explicit_specialization (this, t);
2442 break;
2444 case 3:
2445 pp_cxx_explicit_instantiation (this, t);
2446 break;
2448 default:
2449 break;
2451 else switch (TREE_CODE (t))
2453 case VAR_DECL:
2454 case TYPE_DECL:
2455 pp_cxx_simple_declaration (this, t);
2456 break;
2458 case FUNCTION_DECL:
2459 if (DECL_SAVED_TREE (t))
2460 pp_cxx_function_definition (this, t);
2461 else
2462 pp_cxx_simple_declaration (this, t);
2463 break;
2465 case NAMESPACE_DECL:
2466 if (DECL_NAMESPACE_ALIAS (t))
2467 pp_cxx_namespace_alias_definition (this, t);
2468 else
2469 pp_cxx_original_namespace_definition (this, t);
2470 break;
2472 default:
2473 pp_unsupported_tree (this, t);
2474 break;
2478 static void
2479 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2481 t = TREE_OPERAND (t, 0);
2482 pp_cxx_ws_string (pp, "typeid");
2483 pp_cxx_left_paren (pp);
2484 if (TYPE_P (t))
2485 pp->type_id (t);
2486 else
2487 pp->expression (t);
2488 pp_cxx_right_paren (pp);
2491 void
2492 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2494 pp_cxx_ws_string (pp, "va_arg");
2495 pp_cxx_left_paren (pp);
2496 pp->assignment_expression (TREE_OPERAND (t, 0));
2497 pp_cxx_separate_with (pp, ',');
2498 pp->type_id (TREE_TYPE (t));
2499 pp_cxx_right_paren (pp);
2502 static bool
2503 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2505 switch (TREE_CODE (t))
2507 case ARROW_EXPR:
2508 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2509 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2511 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2512 pp_cxx_separate_with (pp, ',');
2513 return true;
2515 return false;
2516 case COMPONENT_REF:
2517 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2518 return false;
2519 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2520 pp_cxx_dot (pp);
2521 pp->expression (TREE_OPERAND (t, 1));
2522 return true;
2523 case ARRAY_REF:
2524 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2525 return false;
2526 pp_left_bracket (pp);
2527 pp->expression (TREE_OPERAND (t, 1));
2528 pp_right_bracket (pp);
2529 return true;
2530 default:
2531 return false;
2535 void
2536 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2538 pp_cxx_ws_string (pp, "offsetof");
2539 pp_cxx_left_paren (pp);
2540 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2541 pp->expression (TREE_OPERAND (t, 0));
2542 pp_cxx_right_paren (pp);
2545 void
2546 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2548 pp_cxx_ws_string (pp, "__builtin_addressof");
2549 pp_cxx_left_paren (pp);
2550 pp->expression (TREE_OPERAND (t, 0));
2551 pp_cxx_right_paren (pp);
2554 static char const*
2555 get_fold_operator (tree t)
2557 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2558 FOLD_EXPR_OP (t));
2559 return info->name;
2562 void
2563 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2565 char const* op = get_fold_operator (t);
2566 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2567 pp_cxx_left_paren (pp);
2568 pp_cxx_ws_string (pp, "...");
2569 pp_cxx_ws_string (pp, op);
2570 pp->expression (expr);
2571 pp_cxx_right_paren (pp);
2574 void
2575 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2577 char const* op = get_fold_operator (t);
2578 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2579 pp_cxx_left_paren (pp);
2580 pp->expression (expr);
2581 pp_space (pp);
2582 pp_cxx_ws_string (pp, op);
2583 pp_cxx_ws_string (pp, "...");
2584 pp_cxx_right_paren (pp);
2587 void
2588 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2590 char const* op = get_fold_operator (t);
2591 tree t1 = TREE_OPERAND (t, 1);
2592 tree t2 = TREE_OPERAND (t, 2);
2593 if (t1 == FOLD_EXPR_PACK (t))
2594 t1 = PACK_EXPANSION_PATTERN (t1);
2595 else
2596 t2 = PACK_EXPANSION_PATTERN (t2);
2597 pp_cxx_left_paren (pp);
2598 pp->expression (t1);
2599 pp_cxx_ws_string (pp, op);
2600 pp_cxx_ws_string (pp, "...");
2601 pp_cxx_ws_string (pp, op);
2602 pp->expression (t2);
2603 pp_cxx_right_paren (pp);
2606 void
2607 pp_cxx_trait (cxx_pretty_printer *pp, tree t)
2609 cp_trait_kind kind;
2610 tree type1, type2;
2611 if (TREE_CODE (t) == TRAIT_EXPR)
2613 kind = TRAIT_EXPR_KIND (t);
2614 type1 = TRAIT_EXPR_TYPE1 (t);
2615 type2 = TRAIT_EXPR_TYPE2 (t);
2617 else
2619 kind = TRAIT_TYPE_KIND (t);
2620 type1 = TRAIT_TYPE_TYPE1 (t);
2621 type2 = TRAIT_TYPE_TYPE2 (t);
2624 switch (kind)
2626 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2627 case CPTK_##CODE: \
2628 pp_cxx_ws_string (pp, NAME); \
2629 break;
2630 #include "cp-trait.def"
2631 #undef DEFTRAIT
2634 if (kind == CPTK_TYPE_PACK_ELEMENT)
2636 pp_cxx_begin_template_argument_list (pp);
2637 pp->expression (type1);
2639 else
2641 pp_cxx_left_paren (pp);
2642 if (TYPE_P (type1))
2643 pp->type_id (type1);
2644 else
2645 pp->expression (type1);
2647 if (type2)
2649 if (TREE_CODE (type2) != TREE_VEC)
2651 pp_cxx_separate_with (pp, ',');
2652 pp->type_id (type2);
2654 else
2655 for (tree arg : tree_vec_range (type2))
2657 pp_cxx_separate_with (pp, ',');
2658 pp->type_id (arg);
2661 if (kind == CPTK_TYPE_PACK_ELEMENT)
2662 pp_cxx_end_template_argument_list (pp);
2663 else
2664 pp_cxx_right_paren (pp);
2667 // requires-clause:
2668 // 'requires' logical-or-expression
2669 void
2670 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2672 if (!t)
2673 return;
2674 pp->padding = pp_before;
2675 pp_cxx_ws_string (pp, "requires");
2676 pp_space (pp);
2677 pp->expression (t);
2680 /* requirement:
2681 simple-requirement
2682 compound-requirement
2683 type-requirement
2684 nested-requirement */
2685 static void
2686 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2688 switch (TREE_CODE (t))
2690 case SIMPLE_REQ:
2691 pp_cxx_simple_requirement (pp, t);
2692 break;
2694 case TYPE_REQ:
2695 pp_cxx_type_requirement (pp, t);
2696 break;
2698 case COMPOUND_REQ:
2699 pp_cxx_compound_requirement (pp, t);
2700 break;
2702 case NESTED_REQ:
2703 pp_cxx_nested_requirement (pp, t);
2704 break;
2706 default:
2707 gcc_unreachable ();
2711 // requirement-list:
2712 // requirement
2713 // requirement-list ';' requirement[opt]
2715 static void
2716 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2718 for (; t; t = TREE_CHAIN (t))
2719 pp_cxx_requirement (pp, TREE_VALUE (t));
2722 // requirement-body:
2723 // '{' requirement-list '}'
2724 static void
2725 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2727 pp_cxx_left_brace (pp);
2728 pp_cxx_requirement_list (pp, t);
2729 pp_cxx_right_brace (pp);
2732 // requires-expression:
2733 // 'requires' requirement-parameter-list requirement-body
2734 void
2735 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2737 pp_string (pp, "requires");
2738 if (tree parms = REQUIRES_EXPR_PARMS (t))
2740 bool first = true;
2741 pp_cxx_left_paren (pp);
2742 for (; parms; parms = TREE_CHAIN (parms))
2744 if (!first)
2745 pp_cxx_separate_with (pp, ',' );
2746 first = false;
2747 pp_cxx_parameter_declaration (pp, parms);
2749 pp_cxx_right_paren (pp);
2750 pp_cxx_whitespace (pp);
2752 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2755 /* simple-requirement:
2756 expression ';' */
2757 void
2758 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2760 pp->expression (TREE_OPERAND (t, 0));
2761 pp_cxx_semicolon (pp);
2764 /* type-requirement:
2765 typename type-name ';' */
2766 void
2767 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2769 pp->type_id (TREE_OPERAND (t, 0));
2770 pp_cxx_semicolon (pp);
2773 /* compound-requirement:
2774 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2775 void
2776 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2778 pp_cxx_left_brace (pp);
2779 pp->expression (TREE_OPERAND (t, 0));
2780 pp_cxx_right_brace (pp);
2782 if (COMPOUND_REQ_NOEXCEPT_P (t))
2783 pp_cxx_ws_string (pp, "noexcept");
2785 if (tree type = TREE_OPERAND (t, 1))
2787 pp_cxx_whitespace (pp);
2788 pp_cxx_ws_string (pp, "->");
2789 pp->type_id (type);
2791 pp_cxx_semicolon (pp);
2794 /* nested requirement:
2795 'requires' constraint-expression */
2796 void
2797 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2799 pp_cxx_ws_string (pp, "requires");
2800 pp->expression (TREE_OPERAND (t, 0));
2801 pp_cxx_semicolon (pp);
2804 void
2805 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2807 tree decl = CHECK_CONSTR_CONCEPT (t);
2808 tree tmpl = DECL_TI_TEMPLATE (decl);
2809 tree args = CHECK_CONSTR_ARGS (t);
2810 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2812 if (TREE_CODE (decl) == CONCEPT_DECL)
2813 pp->expression (id);
2814 else if (VAR_P (decl))
2815 pp->expression (id);
2816 else if (TREE_CODE (decl) == FUNCTION_DECL)
2818 tree call = build_vl_exp (CALL_EXPR, 2);
2819 TREE_OPERAND (call, 0) = integer_two_node;
2820 TREE_OPERAND (call, 1) = id;
2821 pp->expression (call);
2823 else
2824 gcc_unreachable ();
2827 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2828 constraint. */
2830 void
2831 pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map)
2833 pp_cxx_whitespace (pp);
2834 pp_cxx_left_bracket (pp);
2835 pp->translate_string ("with");
2836 pp_cxx_whitespace (pp);
2838 for (tree p = map; p; p = TREE_CHAIN (p))
2840 tree parm = TREE_VALUE (p);
2841 tree arg = TREE_PURPOSE (p);
2843 if (TYPE_P (parm))
2844 pp->type_id (parm);
2845 else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2846 pp_cxx_tree_identifier (pp, name);
2847 else
2848 pp->translate_string ("<unnamed>");
2850 pp_cxx_whitespace (pp);
2851 pp_equal (pp);
2852 pp_cxx_whitespace (pp);
2854 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2855 pp->type_id (arg);
2856 else
2857 pp->expression (arg);
2859 if (TREE_CHAIN (p) != NULL_TREE)
2860 pp_cxx_separate_with (pp, ';');
2863 pp_cxx_right_bracket (pp);
2866 void
2867 pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t)
2869 /* Emit the expression. */
2870 pp->expression (ATOMIC_CONSTR_EXPR (t));
2872 /* Emit the parameter mapping. */
2873 tree map = ATOMIC_CONSTR_MAP (t);
2874 if (map && map != error_mark_node)
2875 pp_cxx_parameter_mapping (pp, map);
2878 void
2879 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2881 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2882 pp_string (pp, " /\\ ");
2883 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2886 void
2887 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2889 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2890 pp_string (pp, " \\/ ");
2891 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2894 void
2895 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2897 if (t == error_mark_node)
2898 return pp->expression (t);
2900 switch (TREE_CODE (t))
2902 case ATOMIC_CONSTR:
2903 pp_cxx_atomic_constraint (pp, t);
2904 break;
2906 case CHECK_CONSTR:
2907 pp_cxx_check_constraint (pp, t);
2908 break;
2910 case CONJ_CONSTR:
2911 pp_cxx_conjunction (pp, t);
2912 break;
2914 case DISJ_CONSTR:
2915 pp_cxx_disjunction (pp, t);
2916 break;
2918 case EXPR_PACK_EXPANSION:
2919 pp->expression (TREE_OPERAND (t, 0));
2920 break;
2922 default:
2923 gcc_unreachable ();
2928 typedef c_pretty_print_fn pp_fun;
2930 /* Initialization of a C++ pretty-printer object. */
2932 cxx_pretty_printer::cxx_pretty_printer ()
2933 : c_pretty_printer (),
2934 enclosing_scope (global_namespace)
2936 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2937 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2940 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2942 pretty_printer *
2943 cxx_pretty_printer::clone () const
2945 return new cxx_pretty_printer (*this);