aarch64: Use dup and zip1 for interleaving elements in vector initializer.
[official-gcc.git] / gcc / cp / cxx-pretty-print.cc
blob8ca1b8f234a5ea26161c808afa936f5d54393aba
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2022 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 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
848 pp_cxx_whitespace (this);
849 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
851 pp_cxx_left_paren (this);
852 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
853 pp_cxx_right_paren (this);
855 else if (TYPE_P (TREE_OPERAND (t, 0)))
857 pp_cxx_left_paren (this);
858 type_id (TREE_OPERAND (t, 0));
859 pp_cxx_right_paren (this);
861 else
862 unary_expression (TREE_OPERAND (t, 0));
863 break;
865 case AT_ENCODE_EXPR:
866 pp_cxx_ws_string (this, "@encode");
867 pp_cxx_whitespace (this);
868 pp_cxx_left_paren (this);
869 type_id (TREE_OPERAND (t, 0));
870 pp_cxx_right_paren (this);
871 break;
873 case NOEXCEPT_EXPR:
874 pp_cxx_ws_string (this, "noexcept");
875 pp_cxx_whitespace (this);
876 pp_cxx_left_paren (this);
877 expression (TREE_OPERAND (t, 0));
878 pp_cxx_right_paren (this);
879 break;
881 case UNARY_PLUS_EXPR:
882 pp_plus (this);
883 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
884 break;
886 default:
887 c_pretty_printer::unary_expression (t);
888 break;
892 /* cast-expression:
893 unary-expression
894 ( type-id ) cast-expression */
896 static void
897 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
899 switch (TREE_CODE (t))
901 case CAST_EXPR:
902 case IMPLICIT_CONV_EXPR:
903 pp->type_id (TREE_TYPE (t));
904 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
905 break;
907 default:
908 pp_c_cast_expression (pp, t);
909 break;
913 /* pm-expression:
914 cast-expression
915 pm-expression .* cast-expression
916 pm-expression ->* cast-expression */
918 static void
919 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
921 switch (TREE_CODE (t))
923 /* Handle unfortunate OFFSET_REF overloading here. */
924 case OFFSET_REF:
925 if (TYPE_P (TREE_OPERAND (t, 0)))
927 pp_cxx_qualified_id (pp, t);
928 break;
930 /* Fall through. */
931 case MEMBER_REF:
932 case DOTSTAR_EXPR:
933 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
934 if (TREE_CODE (t) == MEMBER_REF)
935 pp_cxx_arrow (pp);
936 else
937 pp_cxx_dot (pp);
938 pp_star(pp);
939 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
940 break;
943 default:
944 pp_cxx_cast_expression (pp, t);
945 break;
949 /* multiplicative-expression:
950 pm-expression
951 multiplicative-expression * pm-expression
952 multiplicative-expression / pm-expression
953 multiplicative-expression % pm-expression */
955 void
956 cxx_pretty_printer::multiplicative_expression (tree e)
958 enum tree_code code = TREE_CODE (e);
959 switch (code)
961 case MULT_EXPR:
962 case TRUNC_DIV_EXPR:
963 case TRUNC_MOD_EXPR:
964 case EXACT_DIV_EXPR:
965 case RDIV_EXPR:
966 multiplicative_expression (TREE_OPERAND (e, 0));
967 pp_space (this);
968 if (code == MULT_EXPR)
969 pp_star (this);
970 else if (code != TRUNC_MOD_EXPR)
971 pp_slash (this);
972 else
973 pp_modulo (this);
974 pp_space (this);
975 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
976 break;
978 default:
979 pp_cxx_pm_expression (this, e);
980 break;
984 /* conditional-expression:
985 logical-or-expression
986 logical-or-expression ? expression : assignment-expression */
988 void
989 cxx_pretty_printer::conditional_expression (tree e)
991 if (TREE_CODE (e) == COND_EXPR)
993 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
994 pp_space (this);
995 pp_question (this);
996 pp_space (this);
997 expression (TREE_OPERAND (e, 1));
998 pp_space (this);
999 assignment_expression (TREE_OPERAND (e, 2));
1001 else
1002 pp_c_logical_or_expression (this, e);
1005 /* Pretty-print a compound assignment operator token as indicated by T. */
1007 static void
1008 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
1010 const char *op;
1012 switch (TREE_CODE (t))
1014 case NOP_EXPR:
1015 op = "=";
1016 break;
1018 case PLUS_EXPR:
1019 op = "+=";
1020 break;
1022 case MINUS_EXPR:
1023 op = "-=";
1024 break;
1026 case TRUNC_DIV_EXPR:
1027 op = "/=";
1028 break;
1030 case TRUNC_MOD_EXPR:
1031 op = "%=";
1032 break;
1034 default:
1035 op = get_tree_code_name (TREE_CODE (t));
1036 break;
1039 pp_cxx_ws_string (pp, op);
1043 /* assignment-expression:
1044 conditional-expression
1045 logical-or-expression assignment-operator assignment-expression
1046 throw-expression
1048 throw-expression:
1049 throw assignment-expression(opt)
1051 assignment-operator: one of
1052 = *= /= %= += -= >>= <<= &= ^= |= */
1054 void
1055 cxx_pretty_printer::assignment_expression (tree e)
1057 switch (TREE_CODE (e))
1059 case MODIFY_EXPR:
1060 case INIT_EXPR:
1061 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1062 pp_space (this);
1063 pp_equal (this);
1064 pp_space (this);
1065 assignment_expression (TREE_OPERAND (e, 1));
1066 break;
1068 case THROW_EXPR:
1069 pp_cxx_ws_string (this, "throw");
1070 if (TREE_OPERAND (e, 0))
1071 assignment_expression (TREE_OPERAND (e, 0));
1072 break;
1074 case MODOP_EXPR:
1075 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1076 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1077 assignment_expression (TREE_OPERAND (e, 2));
1078 break;
1080 default:
1081 conditional_expression (e);
1082 break;
1086 void
1087 cxx_pretty_printer::expression (tree t)
1089 switch (TREE_CODE (t))
1091 case STRING_CST:
1092 case VOID_CST:
1093 case INTEGER_CST:
1094 case REAL_CST:
1095 case COMPLEX_CST:
1096 constant (t);
1097 break;
1099 case USERDEF_LITERAL:
1100 pp_cxx_userdef_literal (this, t);
1101 break;
1103 case RESULT_DECL:
1104 pp_cxx_unqualified_id (this, t);
1105 break;
1107 #if 0
1108 case OFFSET_REF:
1109 #endif
1110 case SCOPE_REF:
1111 case PTRMEM_CST:
1112 pp_cxx_qualified_id (this, t);
1113 break;
1115 case OVERLOAD:
1116 t = OVL_FIRST (t);
1117 /* FALLTHRU */
1118 case VAR_DECL:
1119 case PARM_DECL:
1120 case FIELD_DECL:
1121 case CONST_DECL:
1122 case FUNCTION_DECL:
1123 case BASELINK:
1124 case TEMPLATE_DECL:
1125 case TEMPLATE_TYPE_PARM:
1126 case TEMPLATE_PARM_INDEX:
1127 case TEMPLATE_TEMPLATE_PARM:
1128 case STMT_EXPR:
1129 case REQUIRES_EXPR:
1130 primary_expression (t);
1131 break;
1133 case CALL_EXPR:
1134 case DYNAMIC_CAST_EXPR:
1135 case STATIC_CAST_EXPR:
1136 case REINTERPRET_CAST_EXPR:
1137 case CONST_CAST_EXPR:
1138 #if 0
1139 case MEMBER_REF:
1140 #endif
1141 case EMPTY_CLASS_EXPR:
1142 case TYPEID_EXPR:
1143 case PSEUDO_DTOR_EXPR:
1144 case AGGR_INIT_EXPR:
1145 case ARROW_EXPR:
1146 postfix_expression (t);
1147 break;
1149 case NEW_EXPR:
1150 case VEC_NEW_EXPR:
1151 pp_cxx_new_expression (this, t);
1152 break;
1154 case DELETE_EXPR:
1155 case VEC_DELETE_EXPR:
1156 pp_cxx_delete_expression (this, t);
1157 break;
1159 case SIZEOF_EXPR:
1160 case ALIGNOF_EXPR:
1161 case NOEXCEPT_EXPR:
1162 case UNARY_PLUS_EXPR:
1163 unary_expression (t);
1164 break;
1166 case CAST_EXPR:
1167 case IMPLICIT_CONV_EXPR:
1168 pp_cxx_cast_expression (this, t);
1169 break;
1171 case OFFSET_REF:
1172 case MEMBER_REF:
1173 case DOTSTAR_EXPR:
1174 pp_cxx_pm_expression (this, t);
1175 break;
1177 case MULT_EXPR:
1178 case TRUNC_DIV_EXPR:
1179 case TRUNC_MOD_EXPR:
1180 case EXACT_DIV_EXPR:
1181 case RDIV_EXPR:
1182 multiplicative_expression (t);
1183 break;
1185 case COND_EXPR:
1186 conditional_expression (t);
1187 break;
1189 case MODIFY_EXPR:
1190 case INIT_EXPR:
1191 case THROW_EXPR:
1192 case MODOP_EXPR:
1193 assignment_expression (t);
1194 break;
1196 case NON_DEPENDENT_EXPR:
1197 case MUST_NOT_THROW_EXPR:
1198 expression (TREE_OPERAND (t, 0));
1199 break;
1201 case EXPR_PACK_EXPANSION:
1202 expression (PACK_EXPANSION_PATTERN (t));
1203 pp_cxx_ws_string (this, "...");
1204 break;
1206 case UNARY_LEFT_FOLD_EXPR:
1207 pp_cxx_unary_left_fold_expression (this, t);
1208 break;
1210 case UNARY_RIGHT_FOLD_EXPR:
1211 pp_cxx_unary_right_fold_expression (this, t);
1212 break;
1214 case BINARY_LEFT_FOLD_EXPR:
1215 case BINARY_RIGHT_FOLD_EXPR:
1216 pp_cxx_binary_fold_expression (this, t);
1217 break;
1219 case TEMPLATE_ID_EXPR:
1220 pp_cxx_template_id (this, t);
1221 break;
1223 case NONTYPE_ARGUMENT_PACK:
1225 tree args = ARGUMENT_PACK_ARGS (t);
1226 int i, len = TREE_VEC_LENGTH (args);
1227 pp_cxx_left_brace (this);
1228 for (i = 0; i < len; ++i)
1230 if (i > 0)
1231 pp_cxx_separate_with (this, ',');
1232 expression (TREE_VEC_ELT (args, i));
1234 pp_cxx_right_brace (this);
1236 break;
1238 case LAMBDA_EXPR:
1239 pp_cxx_ws_string (this, "<lambda>");
1240 break;
1242 case TRAIT_EXPR:
1243 pp_cxx_trait (this, t);
1244 break;
1246 case ATOMIC_CONSTR:
1247 case CHECK_CONSTR:
1248 case CONJ_CONSTR:
1249 case DISJ_CONSTR:
1250 pp_cxx_constraint (this, t);
1251 break;
1253 case PAREN_EXPR:
1254 pp_cxx_left_paren (this);
1255 expression (TREE_OPERAND (t, 0));
1256 pp_cxx_right_paren (this);
1257 break;
1259 default:
1260 c_pretty_printer::expression (t);
1261 break;
1266 /* Declarations. */
1268 /* function-specifier:
1269 inline
1270 virtual
1271 explicit */
1273 void
1274 cxx_pretty_printer::function_specifier (tree t)
1276 switch (TREE_CODE (t))
1278 case FUNCTION_DECL:
1279 if (DECL_VIRTUAL_P (t))
1280 pp_cxx_ws_string (this, "virtual");
1281 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1282 pp_cxx_ws_string (this, "explicit");
1283 else
1284 c_pretty_printer::function_specifier (t);
1286 default:
1287 break;
1291 /* decl-specifier-seq:
1292 decl-specifier-seq(opt) decl-specifier
1294 decl-specifier:
1295 storage-class-specifier
1296 type-specifier
1297 function-specifier
1298 friend
1299 typedef */
1301 void
1302 cxx_pretty_printer::declaration_specifiers (tree t)
1304 switch (TREE_CODE (t))
1306 case VAR_DECL:
1307 case PARM_DECL:
1308 case CONST_DECL:
1309 case FIELD_DECL:
1310 storage_class_specifier (t);
1311 declaration_specifiers (TREE_TYPE (t));
1312 break;
1314 case TYPE_DECL:
1315 pp_cxx_ws_string (this, "typedef");
1316 declaration_specifiers (TREE_TYPE (t));
1317 break;
1319 case FUNCTION_DECL:
1320 /* Constructors don't have return types. And conversion functions
1321 do not have a type-specifier in their return types. */
1322 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1323 function_specifier (t);
1324 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1325 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1326 else
1327 c_pretty_printer::declaration_specifiers (t);
1328 break;
1329 default:
1330 c_pretty_printer::declaration_specifiers (t);
1331 break;
1335 /* simple-type-specifier:
1336 ::(opt) nested-name-specifier(opt) type-name
1337 ::(opt) nested-name-specifier(opt) template(opt) template-id
1338 decltype-specifier
1339 char
1340 wchar_t
1341 bool
1342 short
1344 long
1345 signed
1346 unsigned
1347 float
1348 double
1349 void */
1351 void
1352 cxx_pretty_printer::simple_type_specifier (tree t)
1354 switch (TREE_CODE (t))
1356 case RECORD_TYPE:
1357 case UNION_TYPE:
1358 case ENUMERAL_TYPE:
1359 pp_cxx_qualified_id (this, t);
1360 break;
1362 case TEMPLATE_TYPE_PARM:
1363 case TEMPLATE_TEMPLATE_PARM:
1364 case TEMPLATE_PARM_INDEX:
1365 case BOUND_TEMPLATE_TEMPLATE_PARM:
1366 pp_cxx_unqualified_id (this, t);
1367 if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
1368 pp_cxx_constrained_type_spec (this, c);
1369 break;
1371 case TYPENAME_TYPE:
1372 pp_cxx_ws_string (this, "typename");
1373 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1374 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
1375 break;
1377 case DECLTYPE_TYPE:
1378 pp_cxx_ws_string (this, "decltype");
1379 pp_cxx_left_paren (this);
1380 this->expression (DECLTYPE_TYPE_EXPR (t));
1381 pp_cxx_right_paren (this);
1382 break;
1384 case NULLPTR_TYPE:
1385 pp_cxx_ws_string (this, "std::nullptr_t");
1386 break;
1388 case TRAIT_TYPE:
1389 pp_cxx_trait (this, t);
1390 break;
1392 default:
1393 c_pretty_printer::simple_type_specifier (t);
1394 break;
1398 /* type-specifier-seq:
1399 type-specifier type-specifier-seq(opt)
1401 type-specifier:
1402 simple-type-specifier
1403 class-specifier
1404 enum-specifier
1405 elaborated-type-specifier
1406 cv-qualifier */
1408 static void
1409 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1411 switch (TREE_CODE (t))
1413 case TEMPLATE_DECL:
1414 case TEMPLATE_TYPE_PARM:
1415 case TEMPLATE_TEMPLATE_PARM:
1416 case TYPE_DECL:
1417 case BOUND_TEMPLATE_TEMPLATE_PARM:
1418 case DECLTYPE_TYPE:
1419 case NULLPTR_TYPE:
1420 pp_cxx_cv_qualifier_seq (pp, t);
1421 pp->simple_type_specifier (t);
1422 break;
1424 case METHOD_TYPE:
1425 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1426 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1427 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1428 break;
1430 case RECORD_TYPE:
1431 if (TYPE_PTRMEMFUNC_P (t))
1433 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1434 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1435 pp_cxx_whitespace (pp);
1436 pp_cxx_ptr_operator (pp, t);
1437 break;
1439 /* fall through */
1441 case OFFSET_TYPE:
1442 if (TYPE_PTRDATAMEM_P (t))
1444 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1445 pp_cxx_whitespace (pp);
1446 pp_cxx_ptr_operator (pp, t);
1447 break;
1449 /* fall through */
1451 default:
1452 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1453 pp_c_specifier_qualifier_list (pp, t);
1457 /* ptr-operator:
1458 * cv-qualifier-seq(opt)
1460 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1462 static void
1463 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1465 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1466 t = TREE_TYPE (t);
1467 switch (TREE_CODE (t))
1469 case REFERENCE_TYPE:
1470 case POINTER_TYPE:
1471 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1472 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1473 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1474 if (TYPE_PTR_P (t))
1476 pp_star (pp);
1477 pp_cxx_cv_qualifier_seq (pp, t);
1479 else
1480 pp_ampersand (pp);
1481 break;
1483 case RECORD_TYPE:
1484 if (TYPE_PTRMEMFUNC_P (t))
1486 pp_cxx_left_paren (pp);
1487 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1488 pp_star (pp);
1489 break;
1491 /* FALLTHRU */
1492 case OFFSET_TYPE:
1493 if (TYPE_PTRMEM_P (t))
1495 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1496 pp_cxx_left_paren (pp);
1497 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1498 pp_star (pp);
1499 pp_cxx_cv_qualifier_seq (pp, t);
1500 break;
1502 /* fall through. */
1504 default:
1505 pp_unsupported_tree (pp, t);
1506 break;
1510 static inline tree
1511 pp_cxx_implicit_parameter_type (tree mf)
1513 return class_of_this_parm (TREE_TYPE (mf));
1517 parameter-declaration:
1518 decl-specifier-seq declarator
1519 decl-specifier-seq declarator = assignment-expression
1520 decl-specifier-seq abstract-declarator(opt)
1521 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1523 static inline void
1524 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1526 pp->declaration_specifiers (t);
1527 if (TYPE_P (t))
1528 pp->abstract_declarator (t);
1529 else
1530 pp->declarator (t);
1533 /* parameter-declaration-clause:
1534 parameter-declaration-list(opt) ...(opt)
1535 parameter-declaration-list , ...
1537 parameter-declaration-list:
1538 parameter-declaration
1539 parameter-declaration-list , parameter-declaration */
1541 static void
1542 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1544 gcc_assert (FUNC_OR_METHOD_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL);
1545 tree types, args;
1546 if (TYPE_P (t))
1548 types = TYPE_ARG_TYPES (t);
1549 args = NULL_TREE;
1551 else
1553 types = FUNCTION_FIRST_USER_PARMTYPE (t);
1554 args = FUNCTION_FIRST_USER_PARM (t);
1556 bool abstract = !args || (pp->flags & pp_c_flag_abstract);
1558 /* Skip artificial parameter for non-static member functions. */
1559 if (TREE_CODE (t) == METHOD_TYPE)
1560 types = TREE_CHAIN (types);
1562 bool first = true;
1563 pp_cxx_left_paren (pp);
1564 for (; types != void_list_node; types = TREE_CHAIN (types))
1566 if (!first)
1567 pp_cxx_separate_with (pp, ',');
1568 first = false;
1569 if (!types)
1571 pp_cxx_ws_string (pp, "...");
1572 break;
1574 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1575 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1577 pp_cxx_whitespace (pp);
1578 pp_equal (pp);
1579 pp_cxx_whitespace (pp);
1580 pp->assignment_expression (TREE_PURPOSE (types));
1582 if (!abstract)
1583 args = TREE_CHAIN (args);
1585 pp_cxx_right_paren (pp);
1588 /* exception-specification:
1589 throw ( type-id-list(opt) )
1591 type-id-list
1592 type-id
1593 type-id-list , type-id */
1595 static void
1596 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1598 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1599 bool need_comma = false;
1601 if (ex_spec == NULL)
1602 return;
1603 if (TREE_PURPOSE (ex_spec))
1605 pp_cxx_ws_string (pp, "noexcept");
1606 pp_cxx_whitespace (pp);
1607 pp_cxx_left_paren (pp);
1608 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1609 pp_cxx_ws_string (pp, "<uninstantiated>");
1610 else
1611 pp->expression (TREE_PURPOSE (ex_spec));
1612 pp_cxx_right_paren (pp);
1613 return;
1615 pp_cxx_ws_string (pp, "throw");
1616 pp_cxx_left_paren (pp);
1617 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1619 tree type = TREE_VALUE (ex_spec);
1620 tree argpack = NULL_TREE;
1621 int i, len = 1;
1623 if (ARGUMENT_PACK_P (type))
1625 argpack = ARGUMENT_PACK_ARGS (type);
1626 len = TREE_VEC_LENGTH (argpack);
1629 for (i = 0; i < len; ++i)
1631 if (argpack)
1632 type = TREE_VEC_ELT (argpack, i);
1634 if (need_comma)
1635 pp_cxx_separate_with (pp, ',');
1636 else
1637 need_comma = true;
1639 pp->type_id (type);
1642 pp_cxx_right_paren (pp);
1645 /* direct-declarator:
1646 declarator-id
1647 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1648 exception-specification(opt)
1649 direct-declaration [ constant-expression(opt) ]
1650 ( declarator ) */
1652 void
1653 cxx_pretty_printer::direct_declarator (tree t)
1655 switch (TREE_CODE (t))
1657 case VAR_DECL:
1658 case PARM_DECL:
1659 case CONST_DECL:
1660 case FIELD_DECL:
1661 if (DECL_NAME (t))
1663 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1665 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1666 || template_parameter_pack_p (t))
1667 /* A function parameter pack or non-type template
1668 parameter pack. */
1669 pp_cxx_ws_string (this, "...");
1671 id_expression (DECL_NAME (t));
1673 abstract_declarator (TREE_TYPE (t));
1674 break;
1676 case FUNCTION_DECL:
1677 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1678 expression (t);
1679 pp_cxx_parameter_declaration_clause (this, t);
1681 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1683 padding = pp_before;
1684 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1687 pp_cxx_exception_specification (this, TREE_TYPE (t));
1688 break;
1690 case TYPENAME_TYPE:
1691 case TEMPLATE_DECL:
1692 case TEMPLATE_TYPE_PARM:
1693 case TEMPLATE_PARM_INDEX:
1694 case TEMPLATE_TEMPLATE_PARM:
1695 break;
1697 default:
1698 c_pretty_printer::direct_declarator (t);
1699 break;
1703 /* declarator:
1704 direct-declarator
1705 ptr-operator declarator */
1707 void
1708 cxx_pretty_printer::declarator (tree t)
1710 direct_declarator (t);
1712 // Print a requires clause.
1713 if (flag_concepts)
1714 if (tree ci = get_constraints (t))
1715 if (tree reqs = CI_DECLARATOR_REQS (ci))
1716 pp_cxx_requires_clause (this, reqs);
1719 /* ctor-initializer:
1720 : mem-initializer-list
1722 mem-initializer-list:
1723 mem-initializer
1724 mem-initializer , mem-initializer-list
1726 mem-initializer:
1727 mem-initializer-id ( expression-list(opt) )
1729 mem-initializer-id:
1730 ::(opt) nested-name-specifier(opt) class-name
1731 identifier */
1733 static void
1734 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1736 t = TREE_OPERAND (t, 0);
1737 pp_cxx_whitespace (pp);
1738 pp_colon (pp);
1739 pp_cxx_whitespace (pp);
1740 for (; t; t = TREE_CHAIN (t))
1742 tree purpose = TREE_PURPOSE (t);
1743 bool is_pack = PACK_EXPANSION_P (purpose);
1745 if (is_pack)
1746 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1747 else
1748 pp->primary_expression (purpose);
1749 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1750 if (is_pack)
1751 pp_cxx_ws_string (pp, "...");
1752 if (TREE_CHAIN (t))
1753 pp_cxx_separate_with (pp, ',');
1757 /* function-definition:
1758 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1759 decl-specifier-seq(opt) declarator function-try-block */
1761 static void
1762 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1764 tree saved_scope = pp->enclosing_scope;
1765 pp->declaration_specifiers (t);
1766 pp->declarator (t);
1767 pp_needs_newline (pp) = true;
1768 pp->enclosing_scope = DECL_CONTEXT (t);
1769 if (DECL_SAVED_TREE (t))
1770 pp->statement (DECL_SAVED_TREE (t));
1771 else
1772 pp_cxx_semicolon (pp);
1773 pp_newline_and_flush (pp);
1774 pp->enclosing_scope = saved_scope;
1777 /* abstract-declarator:
1778 ptr-operator abstract-declarator(opt)
1779 direct-abstract-declarator */
1781 void
1782 cxx_pretty_printer::abstract_declarator (tree t)
1784 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1785 or a pointer-to-data-member of array type:
1787 void (X::*)()
1788 int (X::*)[5]
1790 but not for a pointer-to-data-member of non-array type:
1792 int X::*
1794 so be mindful of that. */
1795 if (TYPE_PTRMEMFUNC_P (t)
1796 || (TYPE_PTRDATAMEM_P (t)
1797 && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
1798 pp_cxx_right_paren (this);
1799 else if (INDIRECT_TYPE_P (t))
1801 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1802 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1803 pp_cxx_right_paren (this);
1804 t = TREE_TYPE (t);
1806 direct_abstract_declarator (t);
1809 /* direct-abstract-declarator:
1810 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1811 cv-qualifier-seq(opt) exception-specification(opt)
1812 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1813 ( abstract-declarator ) */
1815 void
1816 cxx_pretty_printer::direct_abstract_declarator (tree t)
1818 switch (TREE_CODE (t))
1820 case REFERENCE_TYPE:
1821 abstract_declarator (t);
1822 break;
1824 case RECORD_TYPE:
1825 if (TYPE_PTRMEMFUNC_P (t))
1826 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1827 break;
1829 case OFFSET_TYPE:
1830 if (TYPE_PTRDATAMEM_P (t))
1831 direct_abstract_declarator (TREE_TYPE (t));
1832 break;
1834 case METHOD_TYPE:
1835 case FUNCTION_TYPE:
1836 pp_cxx_parameter_declaration_clause (this, t);
1837 direct_abstract_declarator (TREE_TYPE (t));
1838 if (TREE_CODE (t) == METHOD_TYPE)
1840 padding = pp_before;
1841 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1843 pp_cxx_exception_specification (this, t);
1844 break;
1846 case TYPENAME_TYPE:
1847 case TEMPLATE_TYPE_PARM:
1848 case TEMPLATE_TEMPLATE_PARM:
1849 case BOUND_TEMPLATE_TEMPLATE_PARM:
1850 case UNBOUND_CLASS_TEMPLATE:
1851 case DECLTYPE_TYPE:
1852 break;
1854 default:
1855 c_pretty_printer::direct_abstract_declarator (t);
1856 break;
1860 /* type-id:
1861 type-specifier-seq abstract-declarator(opt) */
1863 void
1864 cxx_pretty_printer::type_id (tree t)
1866 pp_flags saved_flags = flags;
1867 flags |= pp_c_flag_abstract;
1869 switch (TREE_CODE (t))
1871 case TYPE_DECL:
1872 case UNION_TYPE:
1873 case RECORD_TYPE:
1874 case ENUMERAL_TYPE:
1875 case TYPENAME_TYPE:
1876 case BOUND_TEMPLATE_TEMPLATE_PARM:
1877 case UNBOUND_CLASS_TEMPLATE:
1878 case TEMPLATE_TEMPLATE_PARM:
1879 case TEMPLATE_TYPE_PARM:
1880 case TEMPLATE_PARM_INDEX:
1881 case TEMPLATE_DECL:
1882 case TYPEOF_TYPE:
1883 case TRAIT_TYPE:
1884 case DECLTYPE_TYPE:
1885 case NULLPTR_TYPE:
1886 case TEMPLATE_ID_EXPR:
1887 case OFFSET_TYPE:
1888 pp_cxx_type_specifier_seq (this, t);
1889 if (TYPE_PTRMEM_P (t))
1890 abstract_declarator (t);
1891 break;
1893 case TYPE_PACK_EXPANSION:
1894 type_id (PACK_EXPANSION_PATTERN (t));
1895 pp_cxx_ws_string (this, "...");
1896 break;
1898 case TYPE_ARGUMENT_PACK:
1900 tree args = ARGUMENT_PACK_ARGS (t);
1901 int len = TREE_VEC_LENGTH (args);
1902 pp_cxx_left_brace (this);
1903 for (int i = 0; i < len; ++i)
1905 if (i > 0)
1906 pp_cxx_separate_with (this, ',');
1907 type_id (TREE_VEC_ELT (args, i));
1909 pp_cxx_right_brace (this);
1911 break;
1913 default:
1914 c_pretty_printer::type_id (t);
1915 break;
1918 flags = saved_flags;
1921 /* template-argument-list:
1922 template-argument ...(opt)
1923 template-argument-list, template-argument ...(opt)
1925 template-argument:
1926 assignment-expression
1927 type-id
1928 template-name */
1930 static void
1931 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1933 int i;
1934 bool need_comma = false;
1936 if (t == NULL)
1937 return;
1938 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1940 tree arg = TREE_VEC_ELT (t, i);
1941 tree argpack = NULL_TREE;
1942 int idx, len = 1;
1944 if (ARGUMENT_PACK_P (arg))
1946 argpack = ARGUMENT_PACK_ARGS (arg);
1947 len = TREE_VEC_LENGTH (argpack);
1950 for (idx = 0; idx < len; idx++)
1952 if (argpack)
1953 arg = TREE_VEC_ELT (argpack, idx);
1955 if (need_comma)
1956 pp_cxx_separate_with (pp, ',');
1957 else
1958 need_comma = true;
1960 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1961 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1962 pp->type_id (arg);
1963 else if (TREE_CODE (arg) == VAR_DECL && DECL_NTTP_OBJECT_P (arg))
1964 pp->expression (DECL_INITIAL (arg));
1965 else
1966 pp->expression (arg);
1972 static void
1973 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1975 t = DECL_EXPR_DECL (t);
1976 pp_cxx_type_specifier_seq (pp, t);
1977 if (TYPE_P (t))
1978 pp->abstract_declarator (t);
1979 else
1980 pp->declarator (t);
1983 /* Statements. */
1985 void
1986 cxx_pretty_printer::statement (tree t)
1988 switch (TREE_CODE (t))
1990 case CTOR_INITIALIZER:
1991 pp_cxx_ctor_initializer (this, t);
1992 break;
1994 case USING_STMT:
1995 pp_cxx_ws_string (this, "using");
1996 pp_cxx_ws_string (this, "namespace");
1997 if (DECL_CONTEXT (t))
1998 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1999 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
2000 break;
2002 case USING_DECL:
2003 pp_cxx_ws_string (this, "using");
2004 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
2005 pp_cxx_unqualified_id (this, DECL_NAME (t));
2006 break;
2008 case EH_SPEC_BLOCK:
2009 break;
2011 /* try-block:
2012 try compound-statement handler-seq */
2013 case TRY_BLOCK:
2014 pp_maybe_newline_and_indent (this, 0);
2015 pp_cxx_ws_string (this, "try");
2016 pp_newline_and_indent (this, 3);
2017 statement (TRY_STMTS (t));
2018 pp_newline_and_indent (this, -3);
2019 if (CLEANUP_P (t))
2021 else
2022 statement (TRY_HANDLERS (t));
2023 break;
2026 handler-seq:
2027 handler handler-seq(opt)
2029 handler:
2030 catch ( exception-declaration ) compound-statement
2032 exception-declaration:
2033 type-specifier-seq declarator
2034 type-specifier-seq abstract-declarator
2035 ... */
2036 case HANDLER:
2037 pp_cxx_ws_string (this, "catch");
2038 pp_cxx_left_paren (this);
2039 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
2040 pp_cxx_right_paren (this);
2041 pp_indentation (this) += 3;
2042 pp_needs_newline (this) = true;
2043 statement (HANDLER_BODY (t));
2044 pp_indentation (this) -= 3;
2045 pp_needs_newline (this) = true;
2046 break;
2048 /* selection-statement:
2049 if ( expression ) statement
2050 if ( expression ) statement else statement */
2051 case IF_STMT:
2052 pp_cxx_ws_string (this, "if");
2053 pp_cxx_whitespace (this);
2054 pp_cxx_left_paren (this);
2055 expression (IF_COND (t));
2056 pp_cxx_right_paren (this);
2057 pp_newline_and_indent (this, 2);
2058 statement (THEN_CLAUSE (t));
2059 pp_newline_and_indent (this, -2);
2060 if (ELSE_CLAUSE (t))
2062 tree else_clause = ELSE_CLAUSE (t);
2063 pp_cxx_ws_string (this, "else");
2064 if (TREE_CODE (else_clause) == IF_STMT)
2065 pp_cxx_whitespace (this);
2066 else
2067 pp_newline_and_indent (this, 2);
2068 statement (else_clause);
2069 if (TREE_CODE (else_clause) != IF_STMT)
2070 pp_newline_and_indent (this, -2);
2072 break;
2074 case RANGE_FOR_STMT:
2075 pp_cxx_ws_string (this, "for");
2076 pp_space (this);
2077 pp_cxx_left_paren (this);
2078 if (RANGE_FOR_INIT_STMT (t))
2080 statement (RANGE_FOR_INIT_STMT (t));
2081 pp_needs_newline (this) = false;
2082 pp_cxx_whitespace (this);
2084 statement (RANGE_FOR_DECL (t));
2085 pp_space (this);
2086 pp_needs_newline (this) = false;
2087 pp_colon (this);
2088 pp_space (this);
2089 statement (RANGE_FOR_EXPR (t));
2090 pp_cxx_right_paren (this);
2091 pp_newline_and_indent (this, 3);
2092 statement (FOR_BODY (t));
2093 pp_indentation (this) -= 3;
2094 pp_needs_newline (this) = true;
2095 break;
2097 /* expression-statement:
2098 expression(opt) ; */
2099 case EXPR_STMT:
2100 expression (EXPR_STMT_EXPR (t));
2101 pp_cxx_semicolon (this);
2102 pp_needs_newline (this) = true;
2103 break;
2105 case CLEANUP_STMT:
2106 pp_cxx_ws_string (this, "try");
2107 pp_newline_and_indent (this, 2);
2108 statement (CLEANUP_BODY (t));
2109 pp_newline_and_indent (this, -2);
2110 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2111 pp_newline_and_indent (this, 2);
2112 statement (CLEANUP_EXPR (t));
2113 pp_newline_and_indent (this, -2);
2114 break;
2116 case STATIC_ASSERT:
2117 declaration (t);
2118 break;
2120 case OMP_DEPOBJ:
2121 pp_cxx_ws_string (this, "#pragma omp depobj");
2122 pp_space (this);
2123 pp_cxx_left_paren (this);
2124 expression (OMP_DEPOBJ_DEPOBJ (t));
2125 pp_cxx_right_paren (this);
2126 if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
2128 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
2129 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t),
2130 pp_indentation (this), TDF_NONE);
2131 else
2132 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2134 case OMP_CLAUSE_DEPEND_IN:
2135 pp_cxx_ws_string (this, " update(in)");
2136 break;
2137 case OMP_CLAUSE_DEPEND_INOUT:
2138 pp_cxx_ws_string (this, " update(inout)");
2139 break;
2140 case OMP_CLAUSE_DEPEND_OUT:
2141 pp_cxx_ws_string (this, " update(out)");
2142 break;
2143 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2144 pp_cxx_ws_string (this, " update(mutexinoutset)");
2145 break;
2146 case OMP_CLAUSE_DEPEND_INOUTSET:
2147 pp_cxx_ws_string (this, " update(inoutset)");
2148 break;
2149 case OMP_CLAUSE_DEPEND_LAST:
2150 pp_cxx_ws_string (this, " destroy");
2151 break;
2152 default:
2153 break;
2156 pp_needs_newline (this) = true;
2157 break;
2159 default:
2160 c_pretty_printer::statement (t);
2161 break;
2165 /* original-namespace-definition:
2166 namespace identifier { namespace-body }
2168 As an edge case, we also handle unnamed namespace definition here. */
2170 static void
2171 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2173 pp_cxx_ws_string (pp, "namespace");
2174 if (DECL_CONTEXT (t))
2175 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2176 if (DECL_NAME (t))
2177 pp_cxx_unqualified_id (pp, t);
2178 pp_cxx_whitespace (pp);
2179 pp_cxx_left_brace (pp);
2180 /* We do not print the namespace-body. */
2181 pp_cxx_whitespace (pp);
2182 pp_cxx_right_brace (pp);
2185 /* namespace-alias:
2186 identifier
2188 namespace-alias-definition:
2189 namespace identifier = qualified-namespace-specifier ;
2191 qualified-namespace-specifier:
2192 ::(opt) nested-name-specifier(opt) namespace-name */
2194 static void
2195 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2197 pp_cxx_ws_string (pp, "namespace");
2198 if (DECL_CONTEXT (t))
2199 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2200 pp_cxx_unqualified_id (pp, t);
2201 pp_cxx_whitespace (pp);
2202 pp_equal (pp);
2203 pp_cxx_whitespace (pp);
2204 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2205 pp_cxx_nested_name_specifier (pp,
2206 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2207 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2208 pp_cxx_semicolon (pp);
2211 /* simple-declaration:
2212 decl-specifier-seq(opt) init-declarator-list(opt) */
2214 static void
2215 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2217 pp->declaration_specifiers (t);
2218 pp_cxx_init_declarator (pp, t);
2219 pp_cxx_semicolon (pp);
2220 pp_needs_newline (pp) = true;
2224 template-parameter-list:
2225 template-parameter
2226 template-parameter-list , template-parameter */
2228 static inline void
2229 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2231 const int n = TREE_VEC_LENGTH (t);
2232 int i;
2233 for (i = 0; i < n; ++i)
2235 if (i)
2236 pp_cxx_separate_with (pp, ',');
2237 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2241 /* template-parameter:
2242 type-parameter
2243 parameter-declaration
2245 type-parameter:
2246 class ...(opt) identifier(opt)
2247 class identifier(opt) = type-id
2248 typename identifier(opt)
2249 typename ...(opt) identifier(opt) = type-id
2250 template < template-parameter-list > class ...(opt) identifier(opt)
2251 template < template-parameter-list > class identifier(opt) = template-name */
2253 static void
2254 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2256 tree parameter = TREE_VALUE (t);
2257 switch (TREE_CODE (parameter))
2259 case TYPE_DECL:
2260 pp_cxx_ws_string (pp, "class");
2261 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2262 pp_cxx_ws_string (pp, "...");
2263 if (DECL_NAME (parameter))
2264 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2265 /* FIXME: Check if we should print also default argument. */
2266 break;
2268 case PARM_DECL:
2269 pp_cxx_parameter_declaration (pp, parameter);
2270 break;
2272 case TEMPLATE_DECL:
2273 break;
2275 default:
2276 pp_unsupported_tree (pp, t);
2277 break;
2281 /* Pretty-print a template parameter in the canonical form
2282 "template-parameter-<level>-<position in parameter list>". */
2284 void
2285 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2287 const enum tree_code code = TREE_CODE (parm);
2289 /* Brings type template parameters to the canonical forms. */
2290 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2291 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2292 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2294 pp_cxx_begin_template_argument_list (pp);
2295 pp->translate_string ("template-parameter-");
2296 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2297 pp_minus (pp);
2298 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2299 pp_cxx_end_template_argument_list (pp);
2302 /* Print a constrained-type-specifier. */
2304 void
2305 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2307 pp_cxx_whitespace (pp);
2308 pp_cxx_left_bracket (pp);
2309 pp->translate_string ("requires");
2310 pp_cxx_whitespace (pp);
2311 if (c == error_mark_node)
2313 pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
2314 return;
2316 tree t, a;
2317 placeholder_extract_concept_and_args (c, t, a);
2318 pp->id_expression (t);
2319 pp_cxx_begin_template_argument_list (pp);
2320 pp_cxx_ws_string (pp, "<placeholder>");
2321 pp_cxx_separate_with (pp, ',');
2322 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2323 for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i)
2324 TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1);
2325 pp_cxx_template_argument_list (pp, args);
2326 ggc_free (args);
2327 pp_cxx_end_template_argument_list (pp);
2328 pp_cxx_right_bracket (pp);
2332 template-declaration:
2333 export(opt) template < template-parameter-list > declaration
2335 Concept extensions:
2337 template-declaration:
2338 export(opt) template < template-parameter-list >
2339 requires-clause(opt) declaration */
2341 static void
2342 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2344 tree tmpl = most_general_template (t);
2345 tree level;
2347 pp_maybe_newline_and_indent (pp, 0);
2348 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2350 pp_cxx_ws_string (pp, "template");
2351 pp_cxx_begin_template_argument_list (pp);
2352 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2353 pp_cxx_end_template_argument_list (pp);
2354 pp_newline_and_indent (pp, 3);
2357 if (flag_concepts)
2358 if (tree ci = get_constraints (t))
2359 if (tree reqs = CI_TEMPLATE_REQS (ci))
2361 pp_cxx_requires_clause (pp, reqs);
2362 pp_newline_and_indent (pp, 6);
2365 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2366 pp_cxx_function_definition (pp, t);
2367 else if (TREE_CODE (t) == CONCEPT_DECL)
2368 pp_cxx_concept_definition (pp, t);
2369 else
2370 pp_cxx_simple_declaration (pp, t);
2373 static void
2374 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2376 pp_unsupported_tree (pp, t);
2379 static void
2380 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2382 pp_unsupported_tree (pp, t);
2385 static void
2386 pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t)
2388 pp_cxx_unqualified_id (pp, DECL_NAME (t));
2389 pp_cxx_whitespace (pp);
2390 pp_cxx_ws_string (pp, "=");
2391 pp_cxx_whitespace (pp);
2392 pp->expression (DECL_INITIAL (t));
2393 pp_cxx_semicolon (pp);
2397 declaration:
2398 block-declaration
2399 function-definition
2400 template-declaration
2401 explicit-instantiation
2402 explicit-specialization
2403 linkage-specification
2404 namespace-definition
2406 block-declaration:
2407 simple-declaration
2408 asm-definition
2409 namespace-alias-definition
2410 using-declaration
2411 using-directive
2412 static_assert-declaration */
2413 void
2414 cxx_pretty_printer::declaration (tree t)
2416 if (TREE_CODE (t) == STATIC_ASSERT)
2418 pp_cxx_ws_string (this, "static_assert");
2419 pp_cxx_left_paren (this);
2420 expression (STATIC_ASSERT_CONDITION (t));
2421 pp_cxx_separate_with (this, ',');
2422 expression (STATIC_ASSERT_MESSAGE (t));
2423 pp_cxx_right_paren (this);
2425 else if (!DECL_LANG_SPECIFIC (t))
2426 pp_cxx_simple_declaration (this, t);
2427 else if (DECL_USE_TEMPLATE (t))
2428 switch (DECL_USE_TEMPLATE (t))
2430 case 1:
2431 pp_cxx_template_declaration (this, t);
2432 break;
2434 case 2:
2435 pp_cxx_explicit_specialization (this, t);
2436 break;
2438 case 3:
2439 pp_cxx_explicit_instantiation (this, t);
2440 break;
2442 default:
2443 break;
2445 else switch (TREE_CODE (t))
2447 case VAR_DECL:
2448 case TYPE_DECL:
2449 pp_cxx_simple_declaration (this, t);
2450 break;
2452 case FUNCTION_DECL:
2453 if (DECL_SAVED_TREE (t))
2454 pp_cxx_function_definition (this, t);
2455 else
2456 pp_cxx_simple_declaration (this, t);
2457 break;
2459 case NAMESPACE_DECL:
2460 if (DECL_NAMESPACE_ALIAS (t))
2461 pp_cxx_namespace_alias_definition (this, t);
2462 else
2463 pp_cxx_original_namespace_definition (this, t);
2464 break;
2466 default:
2467 pp_unsupported_tree (this, t);
2468 break;
2472 static void
2473 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2475 t = TREE_OPERAND (t, 0);
2476 pp_cxx_ws_string (pp, "typeid");
2477 pp_cxx_left_paren (pp);
2478 if (TYPE_P (t))
2479 pp->type_id (t);
2480 else
2481 pp->expression (t);
2482 pp_cxx_right_paren (pp);
2485 void
2486 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2488 pp_cxx_ws_string (pp, "va_arg");
2489 pp_cxx_left_paren (pp);
2490 pp->assignment_expression (TREE_OPERAND (t, 0));
2491 pp_cxx_separate_with (pp, ',');
2492 pp->type_id (TREE_TYPE (t));
2493 pp_cxx_right_paren (pp);
2496 static bool
2497 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2499 switch (TREE_CODE (t))
2501 case ARROW_EXPR:
2502 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2503 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2505 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2506 pp_cxx_separate_with (pp, ',');
2507 return true;
2509 return false;
2510 case COMPONENT_REF:
2511 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2512 return false;
2513 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2514 pp_cxx_dot (pp);
2515 pp->expression (TREE_OPERAND (t, 1));
2516 return true;
2517 case ARRAY_REF:
2518 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2519 return false;
2520 pp_left_bracket (pp);
2521 pp->expression (TREE_OPERAND (t, 1));
2522 pp_right_bracket (pp);
2523 return true;
2524 default:
2525 return false;
2529 void
2530 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2532 pp_cxx_ws_string (pp, "offsetof");
2533 pp_cxx_left_paren (pp);
2534 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2535 pp->expression (TREE_OPERAND (t, 0));
2536 pp_cxx_right_paren (pp);
2539 void
2540 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2542 pp_cxx_ws_string (pp, "__builtin_addressof");
2543 pp_cxx_left_paren (pp);
2544 pp->expression (TREE_OPERAND (t, 0));
2545 pp_cxx_right_paren (pp);
2548 static char const*
2549 get_fold_operator (tree t)
2551 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2552 FOLD_EXPR_OP (t));
2553 return info->name;
2556 void
2557 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2559 char const* op = get_fold_operator (t);
2560 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2561 pp_cxx_left_paren (pp);
2562 pp_cxx_ws_string (pp, "...");
2563 pp_cxx_ws_string (pp, op);
2564 pp->expression (expr);
2565 pp_cxx_right_paren (pp);
2568 void
2569 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2571 char const* op = get_fold_operator (t);
2572 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2573 pp_cxx_left_paren (pp);
2574 pp->expression (expr);
2575 pp_space (pp);
2576 pp_cxx_ws_string (pp, op);
2577 pp_cxx_ws_string (pp, "...");
2578 pp_cxx_right_paren (pp);
2581 void
2582 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2584 char const* op = get_fold_operator (t);
2585 tree t1 = TREE_OPERAND (t, 1);
2586 tree t2 = TREE_OPERAND (t, 2);
2587 if (t1 == FOLD_EXPR_PACK (t))
2588 t1 = PACK_EXPANSION_PATTERN (t1);
2589 else
2590 t2 = PACK_EXPANSION_PATTERN (t2);
2591 pp_cxx_left_paren (pp);
2592 pp->expression (t1);
2593 pp_cxx_ws_string (pp, op);
2594 pp_cxx_ws_string (pp, "...");
2595 pp_cxx_ws_string (pp, op);
2596 pp->expression (t2);
2597 pp_cxx_right_paren (pp);
2600 void
2601 pp_cxx_trait (cxx_pretty_printer *pp, tree t)
2603 cp_trait_kind kind;
2604 tree type1, type2;
2605 if (TREE_CODE (t) == TRAIT_EXPR)
2607 kind = TRAIT_EXPR_KIND (t);
2608 type1 = TRAIT_EXPR_TYPE1 (t);
2609 type2 = TRAIT_EXPR_TYPE2 (t);
2611 else
2613 kind = TRAIT_TYPE_KIND (t);
2614 type1 = TRAIT_TYPE_TYPE1 (t);
2615 type2 = TRAIT_TYPE_TYPE2 (t);
2618 switch (kind)
2620 #define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2621 case CPTK_##CODE: \
2622 pp_cxx_ws_string (pp, NAME); \
2623 break;
2624 #include "cp-trait.def"
2625 #undef DEFTRAIT
2628 pp_cxx_left_paren (pp);
2629 pp->type_id (type1);
2630 if (type2)
2632 if (TREE_CODE (type2) != TREE_LIST)
2634 pp_cxx_separate_with (pp, ',');
2635 pp->type_id (type2);
2637 else
2638 for (tree arg = type2; arg; arg = TREE_CHAIN (arg))
2640 pp_cxx_separate_with (pp, ',');
2641 pp->type_id (TREE_VALUE (arg));
2644 pp_cxx_right_paren (pp);
2647 // requires-clause:
2648 // 'requires' logical-or-expression
2649 void
2650 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2652 if (!t)
2653 return;
2654 pp->padding = pp_before;
2655 pp_cxx_ws_string (pp, "requires");
2656 pp_space (pp);
2657 pp->expression (t);
2660 /* requirement:
2661 simple-requirement
2662 compound-requirement
2663 type-requirement
2664 nested-requirement */
2665 static void
2666 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2668 switch (TREE_CODE (t))
2670 case SIMPLE_REQ:
2671 pp_cxx_simple_requirement (pp, t);
2672 break;
2674 case TYPE_REQ:
2675 pp_cxx_type_requirement (pp, t);
2676 break;
2678 case COMPOUND_REQ:
2679 pp_cxx_compound_requirement (pp, t);
2680 break;
2682 case NESTED_REQ:
2683 pp_cxx_nested_requirement (pp, t);
2684 break;
2686 default:
2687 gcc_unreachable ();
2691 // requirement-list:
2692 // requirement
2693 // requirement-list ';' requirement[opt]
2695 static void
2696 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2698 for (; t; t = TREE_CHAIN (t))
2699 pp_cxx_requirement (pp, TREE_VALUE (t));
2702 // requirement-body:
2703 // '{' requirement-list '}'
2704 static void
2705 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2707 pp_cxx_left_brace (pp);
2708 pp_cxx_requirement_list (pp, t);
2709 pp_cxx_right_brace (pp);
2712 // requires-expression:
2713 // 'requires' requirement-parameter-list requirement-body
2714 void
2715 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2717 pp_string (pp, "requires");
2718 if (tree parms = REQUIRES_EXPR_PARMS (t))
2720 bool first = true;
2721 pp_cxx_left_paren (pp);
2722 for (; parms; parms = TREE_CHAIN (parms))
2724 if (!first)
2725 pp_cxx_separate_with (pp, ',' );
2726 first = false;
2727 pp_cxx_parameter_declaration (pp, parms);
2729 pp_cxx_right_paren (pp);
2730 pp_cxx_whitespace (pp);
2732 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2735 /* simple-requirement:
2736 expression ';' */
2737 void
2738 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2740 pp->expression (TREE_OPERAND (t, 0));
2741 pp_cxx_semicolon (pp);
2744 /* type-requirement:
2745 typename type-name ';' */
2746 void
2747 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2749 pp->type_id (TREE_OPERAND (t, 0));
2750 pp_cxx_semicolon (pp);
2753 /* compound-requirement:
2754 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2755 void
2756 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2758 pp_cxx_left_brace (pp);
2759 pp->expression (TREE_OPERAND (t, 0));
2760 pp_cxx_right_brace (pp);
2762 if (COMPOUND_REQ_NOEXCEPT_P (t))
2763 pp_cxx_ws_string (pp, "noexcept");
2765 if (tree type = TREE_OPERAND (t, 1))
2767 pp_cxx_whitespace (pp);
2768 pp_cxx_ws_string (pp, "->");
2769 pp->type_id (type);
2771 pp_cxx_semicolon (pp);
2774 /* nested requirement:
2775 'requires' constraint-expression */
2776 void
2777 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2779 pp_cxx_ws_string (pp, "requires");
2780 pp->expression (TREE_OPERAND (t, 0));
2781 pp_cxx_semicolon (pp);
2784 void
2785 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2787 tree decl = CHECK_CONSTR_CONCEPT (t);
2788 tree tmpl = DECL_TI_TEMPLATE (decl);
2789 tree args = CHECK_CONSTR_ARGS (t);
2790 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2792 if (TREE_CODE (decl) == CONCEPT_DECL)
2793 pp->expression (id);
2794 else if (VAR_P (decl))
2795 pp->expression (id);
2796 else if (TREE_CODE (decl) == FUNCTION_DECL)
2798 tree call = build_vl_exp (CALL_EXPR, 2);
2799 TREE_OPERAND (call, 0) = integer_two_node;
2800 TREE_OPERAND (call, 1) = id;
2801 pp->expression (call);
2803 else
2804 gcc_unreachable ();
2807 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2808 constraint. */
2810 void
2811 pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map)
2813 pp_cxx_whitespace (pp);
2814 pp_cxx_left_bracket (pp);
2815 pp->translate_string ("with");
2816 pp_cxx_whitespace (pp);
2818 for (tree p = map; p; p = TREE_CHAIN (p))
2820 tree parm = TREE_VALUE (p);
2821 tree arg = TREE_PURPOSE (p);
2823 if (TYPE_P (parm))
2824 pp->type_id (parm);
2825 else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2826 pp_cxx_tree_identifier (pp, name);
2827 else
2828 pp->translate_string ("<unnamed>");
2830 pp_cxx_whitespace (pp);
2831 pp_equal (pp);
2832 pp_cxx_whitespace (pp);
2834 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2835 pp->type_id (arg);
2836 else
2837 pp->expression (arg);
2839 if (TREE_CHAIN (p) != NULL_TREE)
2840 pp_cxx_separate_with (pp, ';');
2843 pp_cxx_right_bracket (pp);
2846 void
2847 pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t)
2849 /* Emit the expression. */
2850 pp->expression (ATOMIC_CONSTR_EXPR (t));
2852 /* Emit the parameter mapping. */
2853 tree map = ATOMIC_CONSTR_MAP (t);
2854 if (map && map != error_mark_node)
2855 pp_cxx_parameter_mapping (pp, map);
2858 void
2859 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2861 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2862 pp_string (pp, " /\\ ");
2863 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2866 void
2867 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2869 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2870 pp_string (pp, " \\/ ");
2871 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2874 void
2875 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2877 if (t == error_mark_node)
2878 return pp->expression (t);
2880 switch (TREE_CODE (t))
2882 case ATOMIC_CONSTR:
2883 pp_cxx_atomic_constraint (pp, t);
2884 break;
2886 case CHECK_CONSTR:
2887 pp_cxx_check_constraint (pp, t);
2888 break;
2890 case CONJ_CONSTR:
2891 pp_cxx_conjunction (pp, t);
2892 break;
2894 case DISJ_CONSTR:
2895 pp_cxx_disjunction (pp, t);
2896 break;
2898 case EXPR_PACK_EXPANSION:
2899 pp->expression (TREE_OPERAND (t, 0));
2900 break;
2902 default:
2903 gcc_unreachable ();
2908 typedef c_pretty_print_fn pp_fun;
2910 /* Initialization of a C++ pretty-printer object. */
2912 cxx_pretty_printer::cxx_pretty_printer ()
2913 : c_pretty_printer (),
2914 enclosing_scope (global_namespace)
2916 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2917 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2920 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2922 pretty_printer *
2923 cxx_pretty_printer::clone () const
2925 return new cxx_pretty_printer (*this);