Implement P0258R2 - helper for C++17
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob68dcf58ea1ceaf264bcf61013ae61f39e382599f
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2016 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);
43 static inline void
44 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
46 const char *p = pp_last_position_in_text (pp);
48 if (p != NULL && *p == c)
49 pp_cxx_whitespace (pp);
50 pp_character (pp, c);
51 pp->padding = pp_none;
54 #define pp_cxx_expression_list(PP, T) \
55 pp_c_expression_list (PP, T)
56 #define pp_cxx_space_for_pointer_operator(PP, T) \
57 pp_c_space_for_pointer_operator (PP, T)
58 #define pp_cxx_init_declarator(PP, T) \
59 pp_c_init_declarator (PP, T)
60 #define pp_cxx_call_argument_list(PP, T) \
61 pp_c_call_argument_list (PP, T)
63 void
64 pp_cxx_colon_colon (cxx_pretty_printer *pp)
66 pp_colon_colon (pp);
67 pp->padding = pp_none;
70 void
71 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
73 pp_cxx_nonconsecutive_character (pp, '<');
76 void
77 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
79 pp_cxx_nonconsecutive_character (pp, '>');
82 void
83 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
85 pp_separate_with (pp, c);
86 pp->padding = pp_none;
89 /* Expressions. */
91 static inline bool
92 is_destructor_name (tree name)
94 return name == complete_dtor_identifier
95 || name == base_dtor_identifier
96 || name == deleting_dtor_identifier;
99 /* conversion-function-id:
100 operator conversion-type-id
102 conversion-type-id:
103 type-specifier-seq conversion-declarator(opt)
105 conversion-declarator:
106 ptr-operator conversion-declarator(opt) */
108 static inline void
109 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
111 pp_cxx_ws_string (pp, "operator");
112 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
115 static inline void
116 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
118 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
119 pp_cxx_begin_template_argument_list (pp);
120 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
121 pp_cxx_end_template_argument_list (pp);
124 /* Prints the unqualified part of the id-expression T.
126 unqualified-id:
127 identifier
128 operator-function-id
129 conversion-function-id
130 ~ class-name
131 template-id */
133 static void
134 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
136 enum tree_code code = TREE_CODE (t);
137 switch (code)
139 case RESULT_DECL:
140 pp->translate_string ("<return-value>");
141 break;
143 case OVERLOAD:
144 t = OVL_CURRENT (t);
145 /* FALLTHRU */
146 case VAR_DECL:
147 case PARM_DECL:
148 case CONST_DECL:
149 case TYPE_DECL:
150 case FUNCTION_DECL:
151 case NAMESPACE_DECL:
152 case FIELD_DECL:
153 case LABEL_DECL:
154 case USING_DECL:
155 case TEMPLATE_DECL:
156 t = DECL_NAME (t);
157 /* FALLTHRU */
159 case IDENTIFIER_NODE:
160 if (t == NULL)
161 pp->translate_string ("<unnamed>");
162 else if (IDENTIFIER_TYPENAME_P (t))
163 pp_cxx_conversion_function_id (pp, t);
164 else
166 if (is_destructor_name (t))
168 pp_complement (pp);
169 /* FIXME: Why is this necessary? */
170 if (TREE_TYPE (t))
171 t = constructor_name (TREE_TYPE (t));
173 pp_cxx_tree_identifier (pp, t);
175 break;
177 case TEMPLATE_ID_EXPR:
178 pp_cxx_template_id (pp, t);
179 break;
181 case BASELINK:
182 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
183 break;
185 case RECORD_TYPE:
186 case UNION_TYPE:
187 case ENUMERAL_TYPE:
188 case TYPENAME_TYPE:
189 case UNBOUND_CLASS_TEMPLATE:
190 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
191 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
193 pp_cxx_begin_template_argument_list (pp);
194 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
195 (CLASSTYPE_TI_ARGS (t)));
196 pp_cxx_end_template_argument_list (pp);
198 break;
200 case BIT_NOT_EXPR:
201 pp_cxx_complement (pp);
202 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
203 break;
205 case TEMPLATE_TYPE_PARM:
206 case TEMPLATE_TEMPLATE_PARM:
207 if (TYPE_IDENTIFIER (t))
208 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
209 else
210 pp_cxx_canonical_template_parameter (pp, t);
211 break;
213 case TEMPLATE_PARM_INDEX:
214 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
215 break;
217 case BOUND_TEMPLATE_TEMPLATE_PARM:
218 pp_cxx_cv_qualifier_seq (pp, t);
219 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
220 pp_cxx_begin_template_argument_list (pp);
221 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
222 pp_cxx_end_template_argument_list (pp);
223 break;
225 default:
226 pp_unsupported_tree (pp, t);
227 break;
231 /* Pretty-print out the token sequence ":: template" in template codes
232 where it is needed to "inline declare" the (following) member as
233 a template. This situation arises when SCOPE of T is dependent
234 on template parameters. */
236 static inline void
237 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
239 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
240 && TYPE_P (scope) && dependent_type_p (scope))
241 pp_cxx_ws_string (pp, "template");
244 /* nested-name-specifier:
245 class-or-namespace-name :: nested-name-specifier(opt)
246 class-or-namespace-name :: template nested-name-specifier */
248 static void
249 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
251 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
253 tree scope = get_containing_scope (t);
254 pp_cxx_nested_name_specifier (pp, scope);
255 pp_cxx_template_keyword_if_needed (pp, scope, t);
256 pp_cxx_unqualified_id (pp, t);
257 pp_cxx_colon_colon (pp);
261 /* qualified-id:
262 nested-name-specifier template(opt) unqualified-id */
264 static void
265 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
267 switch (TREE_CODE (t))
269 /* A pointer-to-member is always qualified. */
270 case PTRMEM_CST:
271 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
272 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
273 break;
275 /* In Standard C++, functions cannot possibly be used as
276 nested-name-specifiers. However, there are situations where
277 is "makes sense" to output the surrounding function name for the
278 purpose of emphasizing on the scope kind. Just printing the
279 function name might not be sufficient as it may be overloaded; so,
280 we decorate the function with its signature too.
281 FIXME: This is probably the wrong pretty-printing for conversion
282 functions and some function templates. */
283 case OVERLOAD:
284 t = OVL_CURRENT (t);
285 /* FALLTHRU */
286 case FUNCTION_DECL:
287 if (DECL_FUNCTION_MEMBER_P (t))
288 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
289 pp_cxx_unqualified_id
290 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
291 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
292 break;
294 case OFFSET_REF:
295 case SCOPE_REF:
296 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
297 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
298 break;
300 default:
302 tree scope = get_containing_scope (t);
303 if (scope != pp->enclosing_scope)
305 pp_cxx_nested_name_specifier (pp, scope);
306 pp_cxx_template_keyword_if_needed (pp, scope, t);
308 pp_cxx_unqualified_id (pp, t);
310 break;
315 void
316 cxx_pretty_printer::constant (tree t)
318 switch (TREE_CODE (t))
320 case STRING_CST:
322 const bool in_parens = PAREN_STRING_LITERAL_P (t);
323 if (in_parens)
324 pp_cxx_left_paren (this);
325 c_pretty_printer::constant (t);
326 if (in_parens)
327 pp_cxx_right_paren (this);
329 break;
331 case INTEGER_CST:
332 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
334 pp_string (this, "nullptr");
335 break;
337 /* fall through. */
339 default:
340 c_pretty_printer::constant (t);
341 break;
345 /* id-expression:
346 unqualified-id
347 qualified-id */
349 void
350 cxx_pretty_printer::id_expression (tree t)
352 if (TREE_CODE (t) == OVERLOAD)
353 t = OVL_CURRENT (t);
354 if (DECL_P (t) && DECL_CONTEXT (t))
355 pp_cxx_qualified_id (this, t);
356 else
357 pp_cxx_unqualified_id (this, t);
360 /* user-defined literal:
361 literal ud-suffix */
363 void
364 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
366 pp->constant (USERDEF_LITERAL_VALUE (t));
367 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
371 /* primary-expression:
372 literal
373 this
374 :: identifier
375 :: operator-function-id
376 :: qualifier-id
377 ( expression )
378 id-expression
380 GNU Extensions:
381 __builtin_va_arg ( assignment-expression , type-id )
382 __builtin_offsetof ( type-id, offsetof-expression )
384 __has_nothrow_assign ( type-id )
385 __has_nothrow_constructor ( type-id )
386 __has_nothrow_copy ( type-id )
387 __has_trivial_assign ( type-id )
388 __has_trivial_constructor ( type-id )
389 __has_trivial_copy ( type-id )
390 __has_trivial_destructor ( type-id )
391 __has_virtual_destructor ( type-id )
392 __is_abstract ( type-id )
393 __is_base_of ( type-id , type-id )
394 __is_class ( type-id )
395 __is_empty ( type-id )
396 __is_enum ( type-id )
397 __is_literal_type ( type-id )
398 __is_pod ( type-id )
399 __is_polymorphic ( type-id )
400 __is_std_layout ( type-id )
401 __is_trivial ( type-id )
402 __is_union ( type-id ) */
404 void
405 cxx_pretty_printer::primary_expression (tree t)
407 switch (TREE_CODE (t))
409 case VOID_CST:
410 case INTEGER_CST:
411 case REAL_CST:
412 case COMPLEX_CST:
413 case STRING_CST:
414 constant (t);
415 break;
417 case USERDEF_LITERAL:
418 pp_cxx_userdef_literal (this, t);
419 break;
421 case BASELINK:
422 t = BASELINK_FUNCTIONS (t);
423 /* FALLTHRU */
424 case VAR_DECL:
425 case PARM_DECL:
426 case FIELD_DECL:
427 case FUNCTION_DECL:
428 case OVERLOAD:
429 case CONST_DECL:
430 case TEMPLATE_DECL:
431 id_expression (t);
432 break;
434 case RESULT_DECL:
435 case TEMPLATE_TYPE_PARM:
436 case TEMPLATE_TEMPLATE_PARM:
437 case TEMPLATE_PARM_INDEX:
438 pp_cxx_unqualified_id (this, t);
439 break;
441 case STMT_EXPR:
442 pp_cxx_left_paren (this);
443 statement (STMT_EXPR_STMT (t));
444 pp_cxx_right_paren (this);
445 break;
447 case TRAIT_EXPR:
448 pp_cxx_trait_expression (this, t);
449 break;
451 case VA_ARG_EXPR:
452 pp_cxx_va_arg_expression (this, t);
453 break;
455 case OFFSETOF_EXPR:
456 pp_cxx_offsetof_expression (this, t);
457 break;
459 case REQUIRES_EXPR:
460 pp_cxx_requires_expr (this, t);
461 break;
463 default:
464 c_pretty_printer::primary_expression (t);
465 break;
469 /* postfix-expression:
470 primary-expression
471 postfix-expression [ expression ]
472 postfix-expression ( expression-list(opt) )
473 simple-type-specifier ( expression-list(opt) )
474 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
475 typename ::(opt) nested-name-specifier template(opt)
476 template-id ( expression-list(opt) )
477 postfix-expression . template(opt) ::(opt) id-expression
478 postfix-expression -> template(opt) ::(opt) id-expression
479 postfix-expression . pseudo-destructor-name
480 postfix-expression -> pseudo-destructor-name
481 postfix-expression ++
482 postfix-expression --
483 dynamic_cast < type-id > ( expression )
484 static_cast < type-id > ( expression )
485 reinterpret_cast < type-id > ( expression )
486 const_cast < type-id > ( expression )
487 typeid ( expression )
488 typeid ( type-id ) */
490 void
491 cxx_pretty_printer::postfix_expression (tree t)
493 enum tree_code code = TREE_CODE (t);
495 switch (code)
497 case AGGR_INIT_EXPR:
498 case CALL_EXPR:
500 tree fun = cp_get_callee (t);
501 tree saved_scope = enclosing_scope;
502 bool skipfirst = false;
503 tree arg;
505 if (TREE_CODE (fun) == ADDR_EXPR)
506 fun = TREE_OPERAND (fun, 0);
508 /* In templates, where there is no way to tell whether a given
509 call uses an actual member function. So the parser builds
510 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
511 instantiation time. */
512 if (TREE_CODE (fun) != FUNCTION_DECL)
514 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
516 tree object = (code == AGGR_INIT_EXPR
517 ? (AGGR_INIT_VIA_CTOR_P (t)
518 ? AGGR_INIT_EXPR_SLOT (t)
519 : AGGR_INIT_EXPR_ARG (t, 0))
520 : CALL_EXPR_ARG (t, 0));
522 while (TREE_CODE (object) == NOP_EXPR)
523 object = TREE_OPERAND (object, 0);
525 if (TREE_CODE (object) == ADDR_EXPR)
526 object = TREE_OPERAND (object, 0);
528 if (!TYPE_PTR_P (TREE_TYPE (object)))
530 postfix_expression (object);
531 pp_cxx_dot (this);
533 else
535 postfix_expression (object);
536 pp_cxx_arrow (this);
538 skipfirst = true;
539 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
542 postfix_expression (fun);
543 enclosing_scope = saved_scope;
544 pp_cxx_left_paren (this);
545 if (code == AGGR_INIT_EXPR)
547 aggr_init_expr_arg_iterator iter;
548 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
550 if (skipfirst)
551 skipfirst = false;
552 else
554 expression (arg);
555 if (more_aggr_init_expr_args_p (&iter))
556 pp_cxx_separate_with (this, ',');
560 else
562 call_expr_arg_iterator iter;
563 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
565 if (skipfirst)
566 skipfirst = false;
567 else
569 expression (arg);
570 if (more_call_expr_args_p (&iter))
571 pp_cxx_separate_with (this, ',');
575 pp_cxx_right_paren (this);
577 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
579 pp_cxx_separate_with (this, ',');
580 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
582 break;
584 case BASELINK:
585 case VAR_DECL:
586 case PARM_DECL:
587 case FIELD_DECL:
588 case FUNCTION_DECL:
589 case OVERLOAD:
590 case CONST_DECL:
591 case TEMPLATE_DECL:
592 case RESULT_DECL:
593 primary_expression (t);
594 break;
596 case DYNAMIC_CAST_EXPR:
597 case STATIC_CAST_EXPR:
598 case REINTERPRET_CAST_EXPR:
599 case CONST_CAST_EXPR:
600 if (code == DYNAMIC_CAST_EXPR)
601 pp_cxx_ws_string (this, "dynamic_cast");
602 else if (code == STATIC_CAST_EXPR)
603 pp_cxx_ws_string (this, "static_cast");
604 else if (code == REINTERPRET_CAST_EXPR)
605 pp_cxx_ws_string (this, "reinterpret_cast");
606 else
607 pp_cxx_ws_string (this, "const_cast");
608 pp_cxx_begin_template_argument_list (this);
609 type_id (TREE_TYPE (t));
610 pp_cxx_end_template_argument_list (this);
611 pp_left_paren (this);
612 expression (TREE_OPERAND (t, 0));
613 pp_right_paren (this);
614 break;
616 case EMPTY_CLASS_EXPR:
617 type_id (TREE_TYPE (t));
618 pp_left_paren (this);
619 pp_right_paren (this);
620 break;
622 case TYPEID_EXPR:
623 pp_cxx_typeid_expression (this, t);
624 break;
626 case PSEUDO_DTOR_EXPR:
627 postfix_expression (TREE_OPERAND (t, 0));
628 pp_cxx_dot (this);
629 if (TREE_OPERAND (t, 1))
631 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
632 pp_cxx_colon_colon (this);
634 pp_complement (this);
635 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
636 break;
638 case ARROW_EXPR:
639 postfix_expression (TREE_OPERAND (t, 0));
640 pp_cxx_arrow (this);
641 break;
643 default:
644 c_pretty_printer::postfix_expression (t);
645 break;
649 /* new-expression:
650 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
651 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
653 new-placement:
654 ( expression-list )
656 new-type-id:
657 type-specifier-seq new-declarator(opt)
659 new-declarator:
660 ptr-operator new-declarator(opt)
661 direct-new-declarator
663 direct-new-declarator
664 [ expression ]
665 direct-new-declarator [ constant-expression ]
667 new-initializer:
668 ( expression-list(opt) ) */
670 static void
671 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
673 enum tree_code code = TREE_CODE (t);
674 tree type = TREE_OPERAND (t, 1);
675 tree init = TREE_OPERAND (t, 2);
676 switch (code)
678 case NEW_EXPR:
679 case VEC_NEW_EXPR:
680 if (NEW_EXPR_USE_GLOBAL (t))
681 pp_cxx_colon_colon (pp);
682 pp_cxx_ws_string (pp, "new");
683 if (TREE_OPERAND (t, 0))
685 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
686 pp_space (pp);
688 if (TREE_CODE (type) == ARRAY_REF)
689 type = build_cplus_array_type
690 (TREE_OPERAND (type, 0),
691 build_index_type (fold_build2_loc (input_location,
692 MINUS_EXPR, integer_type_node,
693 TREE_OPERAND (type, 1),
694 integer_one_node)));
695 pp->type_id (type);
696 if (init)
698 pp_left_paren (pp);
699 if (TREE_CODE (init) == TREE_LIST)
700 pp_c_expression_list (pp, init);
701 else if (init == void_node)
702 ; /* OK, empty initializer list. */
703 else
704 pp->expression (init);
705 pp_right_paren (pp);
707 break;
709 default:
710 pp_unsupported_tree (pp, t);
714 /* delete-expression:
715 ::(opt) delete cast-expression
716 ::(opt) delete [ ] cast-expression */
718 static void
719 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
721 enum tree_code code = TREE_CODE (t);
722 switch (code)
724 case DELETE_EXPR:
725 case VEC_DELETE_EXPR:
726 if (DELETE_EXPR_USE_GLOBAL (t))
727 pp_cxx_colon_colon (pp);
728 pp_cxx_ws_string (pp, "delete");
729 pp_space (pp);
730 if (code == VEC_DELETE_EXPR
731 || DELETE_EXPR_USE_VEC (t))
733 pp_left_bracket (pp);
734 pp_right_bracket (pp);
735 pp_space (pp);
737 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
738 break;
740 default:
741 pp_unsupported_tree (pp, t);
745 /* unary-expression:
746 postfix-expression
747 ++ cast-expression
748 -- cast-expression
749 unary-operator cast-expression
750 sizeof unary-expression
751 sizeof ( type-id )
752 sizeof ... ( identifier )
753 new-expression
754 delete-expression
756 unary-operator: one of
757 * & + - !
759 GNU extensions:
760 __alignof__ unary-expression
761 __alignof__ ( type-id ) */
763 void
764 cxx_pretty_printer::unary_expression (tree t)
766 enum tree_code code = TREE_CODE (t);
767 switch (code)
769 case NEW_EXPR:
770 case VEC_NEW_EXPR:
771 pp_cxx_new_expression (this, t);
772 break;
774 case DELETE_EXPR:
775 case VEC_DELETE_EXPR:
776 pp_cxx_delete_expression (this, t);
777 break;
779 case SIZEOF_EXPR:
780 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
782 pp_cxx_ws_string (this, "sizeof");
783 pp_cxx_ws_string (this, "...");
784 pp_cxx_whitespace (this);
785 pp_cxx_left_paren (this);
786 if (TYPE_P (TREE_OPERAND (t, 0)))
787 type_id (TREE_OPERAND (t, 0));
788 else
789 unary_expression (TREE_OPERAND (t, 0));
790 pp_cxx_right_paren (this);
791 break;
793 /* Fall through */
795 case ALIGNOF_EXPR:
796 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
797 pp_cxx_whitespace (this);
798 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
800 pp_cxx_left_paren (this);
801 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
802 pp_cxx_right_paren (this);
804 else if (TYPE_P (TREE_OPERAND (t, 0)))
806 pp_cxx_left_paren (this);
807 type_id (TREE_OPERAND (t, 0));
808 pp_cxx_right_paren (this);
810 else
811 unary_expression (TREE_OPERAND (t, 0));
812 break;
814 case AT_ENCODE_EXPR:
815 pp_cxx_ws_string (this, "@encode");
816 pp_cxx_whitespace (this);
817 pp_cxx_left_paren (this);
818 type_id (TREE_OPERAND (t, 0));
819 pp_cxx_right_paren (this);
820 break;
822 case NOEXCEPT_EXPR:
823 pp_cxx_ws_string (this, "noexcept");
824 pp_cxx_whitespace (this);
825 pp_cxx_left_paren (this);
826 expression (TREE_OPERAND (t, 0));
827 pp_cxx_right_paren (this);
828 break;
830 case UNARY_PLUS_EXPR:
831 pp_plus (this);
832 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
833 break;
835 default:
836 c_pretty_printer::unary_expression (t);
837 break;
841 /* cast-expression:
842 unary-expression
843 ( type-id ) cast-expression */
845 static void
846 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
848 switch (TREE_CODE (t))
850 case CAST_EXPR:
851 case IMPLICIT_CONV_EXPR:
852 pp->type_id (TREE_TYPE (t));
853 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
854 break;
856 default:
857 pp_c_cast_expression (pp, t);
858 break;
862 /* pm-expression:
863 cast-expression
864 pm-expression .* cast-expression
865 pm-expression ->* cast-expression */
867 static void
868 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
870 switch (TREE_CODE (t))
872 /* Handle unfortunate OFFSET_REF overloading here. */
873 case OFFSET_REF:
874 if (TYPE_P (TREE_OPERAND (t, 0)))
876 pp_cxx_qualified_id (pp, t);
877 break;
879 /* Fall through. */
880 case MEMBER_REF:
881 case DOTSTAR_EXPR:
882 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
883 if (TREE_CODE (t) == MEMBER_REF)
884 pp_cxx_arrow (pp);
885 else
886 pp_cxx_dot (pp);
887 pp_star(pp);
888 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
889 break;
892 default:
893 pp_cxx_cast_expression (pp, t);
894 break;
898 /* multiplicative-expression:
899 pm-expression
900 multiplicative-expression * pm-expression
901 multiplicative-expression / pm-expression
902 multiplicative-expression % pm-expression */
904 void
905 cxx_pretty_printer::multiplicative_expression (tree e)
907 enum tree_code code = TREE_CODE (e);
908 switch (code)
910 case MULT_EXPR:
911 case TRUNC_DIV_EXPR:
912 case TRUNC_MOD_EXPR:
913 multiplicative_expression (TREE_OPERAND (e, 0));
914 pp_space (this);
915 if (code == MULT_EXPR)
916 pp_star (this);
917 else if (code == TRUNC_DIV_EXPR)
918 pp_slash (this);
919 else
920 pp_modulo (this);
921 pp_space (this);
922 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
923 break;
925 default:
926 pp_cxx_pm_expression (this, e);
927 break;
931 /* conditional-expression:
932 logical-or-expression
933 logical-or-expression ? expression : assignment-expression */
935 void
936 cxx_pretty_printer::conditional_expression (tree e)
938 if (TREE_CODE (e) == COND_EXPR)
940 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
941 pp_space (this);
942 pp_question (this);
943 pp_space (this);
944 expression (TREE_OPERAND (e, 1));
945 pp_space (this);
946 assignment_expression (TREE_OPERAND (e, 2));
948 else
949 pp_c_logical_or_expression (this, e);
952 /* Pretty-print a compound assignment operator token as indicated by T. */
954 static void
955 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
957 const char *op;
959 switch (TREE_CODE (t))
961 case NOP_EXPR:
962 op = "=";
963 break;
965 case PLUS_EXPR:
966 op = "+=";
967 break;
969 case MINUS_EXPR:
970 op = "-=";
971 break;
973 case TRUNC_DIV_EXPR:
974 op = "/=";
975 break;
977 case TRUNC_MOD_EXPR:
978 op = "%=";
979 break;
981 default:
982 op = get_tree_code_name (TREE_CODE (t));
983 break;
986 pp_cxx_ws_string (pp, op);
990 /* assignment-expression:
991 conditional-expression
992 logical-or-expression assignment-operator assignment-expression
993 throw-expression
995 throw-expression:
996 throw assignment-expression(opt)
998 assignment-operator: one of
999 = *= /= %= += -= >>= <<= &= ^= |= */
1001 void
1002 cxx_pretty_printer::assignment_expression (tree e)
1004 switch (TREE_CODE (e))
1006 case MODIFY_EXPR:
1007 case INIT_EXPR:
1008 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1009 pp_space (this);
1010 pp_equal (this);
1011 pp_space (this);
1012 assignment_expression (TREE_OPERAND (e, 1));
1013 break;
1015 case THROW_EXPR:
1016 pp_cxx_ws_string (this, "throw");
1017 if (TREE_OPERAND (e, 0))
1018 assignment_expression (TREE_OPERAND (e, 0));
1019 break;
1021 case MODOP_EXPR:
1022 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1023 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1024 assignment_expression (TREE_OPERAND (e, 2));
1025 break;
1027 default:
1028 conditional_expression (e);
1029 break;
1033 void
1034 cxx_pretty_printer::expression (tree t)
1036 switch (TREE_CODE (t))
1038 case STRING_CST:
1039 case VOID_CST:
1040 case INTEGER_CST:
1041 case REAL_CST:
1042 case COMPLEX_CST:
1043 constant (t);
1044 break;
1046 case USERDEF_LITERAL:
1047 pp_cxx_userdef_literal (this, t);
1048 break;
1050 case RESULT_DECL:
1051 pp_cxx_unqualified_id (this, t);
1052 break;
1054 #if 0
1055 case OFFSET_REF:
1056 #endif
1057 case SCOPE_REF:
1058 case PTRMEM_CST:
1059 pp_cxx_qualified_id (this, t);
1060 break;
1062 case OVERLOAD:
1063 t = OVL_CURRENT (t);
1064 /* FALLTHRU */
1065 case VAR_DECL:
1066 case PARM_DECL:
1067 case FIELD_DECL:
1068 case CONST_DECL:
1069 case FUNCTION_DECL:
1070 case BASELINK:
1071 case TEMPLATE_DECL:
1072 case TEMPLATE_TYPE_PARM:
1073 case TEMPLATE_PARM_INDEX:
1074 case TEMPLATE_TEMPLATE_PARM:
1075 case STMT_EXPR:
1076 case REQUIRES_EXPR:
1077 primary_expression (t);
1078 break;
1080 case CALL_EXPR:
1081 case DYNAMIC_CAST_EXPR:
1082 case STATIC_CAST_EXPR:
1083 case REINTERPRET_CAST_EXPR:
1084 case CONST_CAST_EXPR:
1085 #if 0
1086 case MEMBER_REF:
1087 #endif
1088 case EMPTY_CLASS_EXPR:
1089 case TYPEID_EXPR:
1090 case PSEUDO_DTOR_EXPR:
1091 case AGGR_INIT_EXPR:
1092 case ARROW_EXPR:
1093 postfix_expression (t);
1094 break;
1096 case NEW_EXPR:
1097 case VEC_NEW_EXPR:
1098 pp_cxx_new_expression (this, t);
1099 break;
1101 case DELETE_EXPR:
1102 case VEC_DELETE_EXPR:
1103 pp_cxx_delete_expression (this, t);
1104 break;
1106 case SIZEOF_EXPR:
1107 case ALIGNOF_EXPR:
1108 case NOEXCEPT_EXPR:
1109 unary_expression (t);
1110 break;
1112 case CAST_EXPR:
1113 case IMPLICIT_CONV_EXPR:
1114 pp_cxx_cast_expression (this, t);
1115 break;
1117 case OFFSET_REF:
1118 case MEMBER_REF:
1119 case DOTSTAR_EXPR:
1120 pp_cxx_pm_expression (this, t);
1121 break;
1123 case MULT_EXPR:
1124 case TRUNC_DIV_EXPR:
1125 case TRUNC_MOD_EXPR:
1126 multiplicative_expression (t);
1127 break;
1129 case COND_EXPR:
1130 conditional_expression (t);
1131 break;
1133 case MODIFY_EXPR:
1134 case INIT_EXPR:
1135 case THROW_EXPR:
1136 case MODOP_EXPR:
1137 assignment_expression (t);
1138 break;
1140 case NON_DEPENDENT_EXPR:
1141 case MUST_NOT_THROW_EXPR:
1142 expression (TREE_OPERAND (t, 0));
1143 break;
1145 case EXPR_PACK_EXPANSION:
1146 expression (PACK_EXPANSION_PATTERN (t));
1147 pp_cxx_ws_string (this, "...");
1148 break;
1150 case UNARY_LEFT_FOLD_EXPR:
1151 pp_cxx_unary_left_fold_expression (this, t);
1152 break;
1154 case UNARY_RIGHT_FOLD_EXPR:
1155 pp_cxx_unary_right_fold_expression (this, t);
1156 break;
1158 case BINARY_LEFT_FOLD_EXPR:
1159 case BINARY_RIGHT_FOLD_EXPR:
1160 pp_cxx_binary_fold_expression (this, t);
1161 break;
1163 case TEMPLATE_ID_EXPR:
1164 pp_cxx_template_id (this, t);
1165 break;
1167 case NONTYPE_ARGUMENT_PACK:
1169 tree args = ARGUMENT_PACK_ARGS (t);
1170 int i, len = TREE_VEC_LENGTH (args);
1171 for (i = 0; i < len; ++i)
1173 if (i > 0)
1174 pp_cxx_separate_with (this, ',');
1175 expression (TREE_VEC_ELT (args, i));
1178 break;
1180 case LAMBDA_EXPR:
1181 pp_cxx_ws_string (this, "<lambda>");
1182 break;
1184 case TRAIT_EXPR:
1185 pp_cxx_trait_expression (this, t);
1186 break;
1188 case PRED_CONSTR:
1189 case CHECK_CONSTR:
1190 case EXPR_CONSTR:
1191 case TYPE_CONSTR:
1192 case ICONV_CONSTR:
1193 case DEDUCT_CONSTR:
1194 case EXCEPT_CONSTR:
1195 case PARM_CONSTR:
1196 case CONJ_CONSTR:
1197 case DISJ_CONSTR:
1198 pp_cxx_constraint (this, t);
1199 break;
1201 case PAREN_EXPR:
1202 pp_cxx_left_paren (this);
1203 expression (TREE_OPERAND (t, 0));
1204 pp_cxx_right_paren (this);
1205 break;
1207 default:
1208 c_pretty_printer::expression (t);
1209 break;
1214 /* Declarations. */
1216 /* function-specifier:
1217 inline
1218 virtual
1219 explicit */
1221 void
1222 cxx_pretty_printer::function_specifier (tree t)
1224 switch (TREE_CODE (t))
1226 case FUNCTION_DECL:
1227 if (DECL_VIRTUAL_P (t))
1228 pp_cxx_ws_string (this, "virtual");
1229 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1230 pp_cxx_ws_string (this, "explicit");
1231 else
1232 c_pretty_printer::function_specifier (t);
1234 default:
1235 break;
1239 /* decl-specifier-seq:
1240 decl-specifier-seq(opt) decl-specifier
1242 decl-specifier:
1243 storage-class-specifier
1244 type-specifier
1245 function-specifier
1246 friend
1247 typedef */
1249 void
1250 cxx_pretty_printer::declaration_specifiers (tree t)
1252 switch (TREE_CODE (t))
1254 case VAR_DECL:
1255 case PARM_DECL:
1256 case CONST_DECL:
1257 case FIELD_DECL:
1258 storage_class_specifier (t);
1259 declaration_specifiers (TREE_TYPE (t));
1260 break;
1262 case TYPE_DECL:
1263 pp_cxx_ws_string (this, "typedef");
1264 declaration_specifiers (TREE_TYPE (t));
1265 break;
1267 case FUNCTION_DECL:
1268 /* Constructors don't have return types. And conversion functions
1269 do not have a type-specifier in their return types. */
1270 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1271 function_specifier (t);
1272 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1273 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1274 else
1275 c_pretty_printer::declaration_specifiers (t);
1276 break;
1277 default:
1278 c_pretty_printer::declaration_specifiers (t);
1279 break;
1283 /* simple-type-specifier:
1284 ::(opt) nested-name-specifier(opt) type-name
1285 ::(opt) nested-name-specifier(opt) template(opt) template-id
1286 char
1287 wchar_t
1288 bool
1289 short
1291 long
1292 signed
1293 unsigned
1294 float
1295 double
1296 void */
1298 void
1299 cxx_pretty_printer::simple_type_specifier (tree t)
1301 switch (TREE_CODE (t))
1303 case RECORD_TYPE:
1304 case UNION_TYPE:
1305 case ENUMERAL_TYPE:
1306 pp_cxx_qualified_id (this, t);
1307 break;
1309 case TEMPLATE_TYPE_PARM:
1310 case TEMPLATE_TEMPLATE_PARM:
1311 case TEMPLATE_PARM_INDEX:
1312 case BOUND_TEMPLATE_TEMPLATE_PARM:
1313 pp_cxx_unqualified_id (this, t);
1314 break;
1316 case TYPENAME_TYPE:
1317 pp_cxx_ws_string (this, "typename");
1318 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1319 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1320 break;
1322 default:
1323 c_pretty_printer::simple_type_specifier (t);
1324 break;
1328 /* type-specifier-seq:
1329 type-specifier type-specifier-seq(opt)
1331 type-specifier:
1332 simple-type-specifier
1333 class-specifier
1334 enum-specifier
1335 elaborated-type-specifier
1336 cv-qualifier */
1338 static void
1339 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1341 switch (TREE_CODE (t))
1343 case TEMPLATE_DECL:
1344 case TEMPLATE_TYPE_PARM:
1345 case TEMPLATE_TEMPLATE_PARM:
1346 case TYPE_DECL:
1347 case BOUND_TEMPLATE_TEMPLATE_PARM:
1348 pp_cxx_cv_qualifier_seq (pp, t);
1349 pp->simple_type_specifier (t);
1350 break;
1352 case METHOD_TYPE:
1353 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1354 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1355 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1356 break;
1358 case DECLTYPE_TYPE:
1359 pp_cxx_ws_string (pp, "decltype");
1360 pp_cxx_left_paren (pp);
1361 pp->expression (DECLTYPE_TYPE_EXPR (t));
1362 pp_cxx_right_paren (pp);
1363 break;
1365 case RECORD_TYPE:
1366 if (TYPE_PTRMEMFUNC_P (t))
1368 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1369 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1370 pp_cxx_whitespace (pp);
1371 pp_cxx_ptr_operator (pp, t);
1372 break;
1374 /* fall through */
1376 default:
1377 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1378 pp_c_specifier_qualifier_list (pp, t);
1382 /* ptr-operator:
1383 * cv-qualifier-seq(opt)
1385 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1387 static void
1388 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1390 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1391 t = TREE_TYPE (t);
1392 switch (TREE_CODE (t))
1394 case REFERENCE_TYPE:
1395 case POINTER_TYPE:
1396 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1397 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1398 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1399 if (TYPE_PTR_P (t))
1401 pp_star (pp);
1402 pp_cxx_cv_qualifier_seq (pp, t);
1404 else
1405 pp_ampersand (pp);
1406 break;
1408 case RECORD_TYPE:
1409 if (TYPE_PTRMEMFUNC_P (t))
1411 pp_cxx_left_paren (pp);
1412 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1413 pp_star (pp);
1414 break;
1416 /* FALLTHRU */
1417 case OFFSET_TYPE:
1418 if (TYPE_PTRMEM_P (t))
1420 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1421 pp_cxx_left_paren (pp);
1422 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1423 pp_star (pp);
1424 pp_cxx_cv_qualifier_seq (pp, t);
1425 break;
1427 /* fall through. */
1429 default:
1430 pp_unsupported_tree (pp, t);
1431 break;
1435 static inline tree
1436 pp_cxx_implicit_parameter_type (tree mf)
1438 return class_of_this_parm (TREE_TYPE (mf));
1442 parameter-declaration:
1443 decl-specifier-seq declarator
1444 decl-specifier-seq declarator = assignment-expression
1445 decl-specifier-seq abstract-declarator(opt)
1446 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1448 static inline void
1449 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1451 pp->declaration_specifiers (t);
1452 if (TYPE_P (t))
1453 pp->abstract_declarator (t);
1454 else
1455 pp->declarator (t);
1458 /* parameter-declaration-clause:
1459 parameter-declaration-list(opt) ...(opt)
1460 parameter-declaration-list , ...
1462 parameter-declaration-list:
1463 parameter-declaration
1464 parameter-declaration-list , parameter-declaration */
1466 static void
1467 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1469 tree args;
1470 tree types;
1471 bool abstract;
1473 // For a requires clause or the explicit printing of a parameter list
1474 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1475 // args and types are taken from the function decl T.
1476 if (TREE_CODE (t) == PARM_DECL)
1478 args = t;
1479 types = t;
1480 abstract = false;
1482 else
1484 bool type_p = TYPE_P (t);
1485 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1486 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1487 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1489 bool first = true;
1491 /* Skip artificial parameter for nonstatic member functions. */
1492 if (TREE_CODE (t) == METHOD_TYPE)
1493 types = TREE_CHAIN (types);
1495 pp_cxx_left_paren (pp);
1496 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1498 if (!first)
1499 pp_cxx_separate_with (pp, ',');
1500 first = false;
1501 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1502 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1504 pp_cxx_whitespace (pp);
1505 pp_equal (pp);
1506 pp_cxx_whitespace (pp);
1507 pp->assignment_expression (TREE_PURPOSE (types));
1510 pp_cxx_right_paren (pp);
1513 /* exception-specification:
1514 throw ( type-id-list(opt) )
1516 type-id-list
1517 type-id
1518 type-id-list , type-id */
1520 static void
1521 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1523 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1524 bool need_comma = false;
1526 if (ex_spec == NULL)
1527 return;
1528 if (TREE_PURPOSE (ex_spec))
1530 pp_cxx_ws_string (pp, "noexcept");
1531 pp_cxx_whitespace (pp);
1532 pp_cxx_left_paren (pp);
1533 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1534 pp_cxx_ws_string (pp, "<uninstantiated>");
1535 else
1536 pp->expression (TREE_PURPOSE (ex_spec));
1537 pp_cxx_right_paren (pp);
1538 return;
1540 pp_cxx_ws_string (pp, "throw");
1541 pp_cxx_left_paren (pp);
1542 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1544 tree type = TREE_VALUE (ex_spec);
1545 tree argpack = NULL_TREE;
1546 int i, len = 1;
1548 if (ARGUMENT_PACK_P (type))
1550 argpack = ARGUMENT_PACK_ARGS (type);
1551 len = TREE_VEC_LENGTH (argpack);
1554 for (i = 0; i < len; ++i)
1556 if (argpack)
1557 type = TREE_VEC_ELT (argpack, i);
1559 if (need_comma)
1560 pp_cxx_separate_with (pp, ',');
1561 else
1562 need_comma = true;
1564 pp->type_id (type);
1567 pp_cxx_right_paren (pp);
1570 /* direct-declarator:
1571 declarator-id
1572 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1573 exception-specification(opt)
1574 direct-declaration [ constant-expression(opt) ]
1575 ( declarator ) */
1577 void
1578 cxx_pretty_printer::direct_declarator (tree t)
1580 switch (TREE_CODE (t))
1582 case VAR_DECL:
1583 case PARM_DECL:
1584 case CONST_DECL:
1585 case FIELD_DECL:
1586 if (DECL_NAME (t))
1588 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1590 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1591 || template_parameter_pack_p (t))
1592 /* A function parameter pack or non-type template
1593 parameter pack. */
1594 pp_cxx_ws_string (this, "...");
1596 id_expression (DECL_NAME (t));
1598 abstract_declarator (TREE_TYPE (t));
1599 break;
1601 case FUNCTION_DECL:
1602 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1603 expression (t);
1604 pp_cxx_parameter_declaration_clause (this, t);
1606 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1608 padding = pp_before;
1609 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1612 pp_cxx_exception_specification (this, TREE_TYPE (t));
1613 break;
1615 case TYPENAME_TYPE:
1616 case TEMPLATE_DECL:
1617 case TEMPLATE_TYPE_PARM:
1618 case TEMPLATE_PARM_INDEX:
1619 case TEMPLATE_TEMPLATE_PARM:
1620 break;
1622 default:
1623 c_pretty_printer::direct_declarator (t);
1624 break;
1628 /* declarator:
1629 direct-declarator
1630 ptr-operator declarator */
1632 void
1633 cxx_pretty_printer::declarator (tree t)
1635 direct_declarator (t);
1637 // Print a requires clause.
1638 if (flag_concepts)
1639 if (tree ci = get_constraints (t))
1640 if (tree reqs = CI_DECLARATOR_REQS (ci))
1641 pp_cxx_requires_clause (this, reqs);
1644 /* ctor-initializer:
1645 : mem-initializer-list
1647 mem-initializer-list:
1648 mem-initializer
1649 mem-initializer , mem-initializer-list
1651 mem-initializer:
1652 mem-initializer-id ( expression-list(opt) )
1654 mem-initializer-id:
1655 ::(opt) nested-name-specifier(opt) class-name
1656 identifier */
1658 static void
1659 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1661 t = TREE_OPERAND (t, 0);
1662 pp_cxx_whitespace (pp);
1663 pp_colon (pp);
1664 pp_cxx_whitespace (pp);
1665 for (; t; t = TREE_CHAIN (t))
1667 tree purpose = TREE_PURPOSE (t);
1668 bool is_pack = PACK_EXPANSION_P (purpose);
1670 if (is_pack)
1671 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1672 else
1673 pp->primary_expression (purpose);
1674 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1675 if (is_pack)
1676 pp_cxx_ws_string (pp, "...");
1677 if (TREE_CHAIN (t))
1678 pp_cxx_separate_with (pp, ',');
1682 /* function-definition:
1683 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1684 decl-specifier-seq(opt) declarator function-try-block */
1686 static void
1687 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1689 tree saved_scope = pp->enclosing_scope;
1690 pp->declaration_specifiers (t);
1691 pp->declarator (t);
1692 pp_needs_newline (pp) = true;
1693 pp->enclosing_scope = DECL_CONTEXT (t);
1694 if (DECL_SAVED_TREE (t))
1695 pp->statement (DECL_SAVED_TREE (t));
1696 else
1697 pp_cxx_semicolon (pp);
1698 pp_newline_and_flush (pp);
1699 pp->enclosing_scope = saved_scope;
1702 /* abstract-declarator:
1703 ptr-operator abstract-declarator(opt)
1704 direct-abstract-declarator */
1706 void
1707 cxx_pretty_printer::abstract_declarator (tree t)
1709 if (TYPE_PTRMEM_P (t))
1710 pp_cxx_right_paren (this);
1711 else if (POINTER_TYPE_P (t))
1713 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1714 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1715 pp_cxx_right_paren (this);
1716 t = TREE_TYPE (t);
1718 direct_abstract_declarator (t);
1721 /* direct-abstract-declarator:
1722 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1723 cv-qualifier-seq(opt) exception-specification(opt)
1724 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1725 ( abstract-declarator ) */
1727 void
1728 cxx_pretty_printer::direct_abstract_declarator (tree t)
1730 switch (TREE_CODE (t))
1732 case REFERENCE_TYPE:
1733 abstract_declarator (t);
1734 break;
1736 case RECORD_TYPE:
1737 if (TYPE_PTRMEMFUNC_P (t))
1738 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1739 break;
1741 case METHOD_TYPE:
1742 case FUNCTION_TYPE:
1743 pp_cxx_parameter_declaration_clause (this, t);
1744 direct_abstract_declarator (TREE_TYPE (t));
1745 if (TREE_CODE (t) == METHOD_TYPE)
1747 padding = pp_before;
1748 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1750 pp_cxx_exception_specification (this, t);
1751 break;
1753 case TYPENAME_TYPE:
1754 case TEMPLATE_TYPE_PARM:
1755 case TEMPLATE_TEMPLATE_PARM:
1756 case BOUND_TEMPLATE_TEMPLATE_PARM:
1757 case UNBOUND_CLASS_TEMPLATE:
1758 break;
1760 default:
1761 c_pretty_printer::direct_abstract_declarator (t);
1762 break;
1766 /* type-id:
1767 type-specifier-seq abstract-declarator(opt) */
1769 void
1770 cxx_pretty_printer::type_id (tree t)
1772 pp_flags saved_flags = flags;
1773 flags |= pp_c_flag_abstract;
1775 switch (TREE_CODE (t))
1777 case TYPE_DECL:
1778 case UNION_TYPE:
1779 case RECORD_TYPE:
1780 case ENUMERAL_TYPE:
1781 case TYPENAME_TYPE:
1782 case BOUND_TEMPLATE_TEMPLATE_PARM:
1783 case UNBOUND_CLASS_TEMPLATE:
1784 case TEMPLATE_TEMPLATE_PARM:
1785 case TEMPLATE_TYPE_PARM:
1786 case TEMPLATE_PARM_INDEX:
1787 case TEMPLATE_DECL:
1788 case TYPEOF_TYPE:
1789 case UNDERLYING_TYPE:
1790 case DECLTYPE_TYPE:
1791 case TEMPLATE_ID_EXPR:
1792 pp_cxx_type_specifier_seq (this, t);
1793 break;
1795 case TYPE_PACK_EXPANSION:
1796 type_id (PACK_EXPANSION_PATTERN (t));
1797 pp_cxx_ws_string (this, "...");
1798 break;
1800 default:
1801 c_pretty_printer::type_id (t);
1802 break;
1805 flags = saved_flags;
1808 /* template-argument-list:
1809 template-argument ...(opt)
1810 template-argument-list, template-argument ...(opt)
1812 template-argument:
1813 assignment-expression
1814 type-id
1815 template-name */
1817 static void
1818 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1820 int i;
1821 bool need_comma = false;
1823 if (t == NULL)
1824 return;
1825 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1827 tree arg = TREE_VEC_ELT (t, i);
1828 tree argpack = NULL_TREE;
1829 int idx, len = 1;
1831 if (ARGUMENT_PACK_P (arg))
1833 argpack = ARGUMENT_PACK_ARGS (arg);
1834 len = TREE_VEC_LENGTH (argpack);
1837 for (idx = 0; idx < len; idx++)
1839 if (argpack)
1840 arg = TREE_VEC_ELT (argpack, idx);
1842 if (need_comma)
1843 pp_cxx_separate_with (pp, ',');
1844 else
1845 need_comma = true;
1847 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1848 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1849 pp->type_id (arg);
1850 else
1851 pp->expression (arg);
1857 static void
1858 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1860 t = DECL_EXPR_DECL (t);
1861 pp_cxx_type_specifier_seq (pp, t);
1862 if (TYPE_P (t))
1863 pp->abstract_declarator (t);
1864 else
1865 pp->declarator (t);
1868 /* Statements. */
1870 void
1871 cxx_pretty_printer::statement (tree t)
1873 switch (TREE_CODE (t))
1875 case CTOR_INITIALIZER:
1876 pp_cxx_ctor_initializer (this, t);
1877 break;
1879 case USING_STMT:
1880 pp_cxx_ws_string (this, "using");
1881 pp_cxx_ws_string (this, "namespace");
1882 if (DECL_CONTEXT (t))
1883 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1884 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1885 break;
1887 case USING_DECL:
1888 pp_cxx_ws_string (this, "using");
1889 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1890 pp_cxx_unqualified_id (this, DECL_NAME (t));
1891 break;
1893 case EH_SPEC_BLOCK:
1894 break;
1896 /* try-block:
1897 try compound-statement handler-seq */
1898 case TRY_BLOCK:
1899 pp_maybe_newline_and_indent (this, 0);
1900 pp_cxx_ws_string (this, "try");
1901 pp_newline_and_indent (this, 3);
1902 statement (TRY_STMTS (t));
1903 pp_newline_and_indent (this, -3);
1904 if (CLEANUP_P (t))
1906 else
1907 statement (TRY_HANDLERS (t));
1908 break;
1911 handler-seq:
1912 handler handler-seq(opt)
1914 handler:
1915 catch ( exception-declaration ) compound-statement
1917 exception-declaration:
1918 type-specifier-seq declarator
1919 type-specifier-seq abstract-declarator
1920 ... */
1921 case HANDLER:
1922 pp_cxx_ws_string (this, "catch");
1923 pp_cxx_left_paren (this);
1924 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1925 pp_cxx_right_paren (this);
1926 pp_indentation (this) += 3;
1927 pp_needs_newline (this) = true;
1928 statement (HANDLER_BODY (t));
1929 pp_indentation (this) -= 3;
1930 pp_needs_newline (this) = true;
1931 break;
1933 /* selection-statement:
1934 if ( expression ) statement
1935 if ( expression ) statement else statement */
1936 case IF_STMT:
1937 pp_cxx_ws_string (this, "if");
1938 pp_cxx_whitespace (this);
1939 pp_cxx_left_paren (this);
1940 expression (IF_COND (t));
1941 pp_cxx_right_paren (this);
1942 pp_newline_and_indent (this, 2);
1943 statement (THEN_CLAUSE (t));
1944 pp_newline_and_indent (this, -2);
1945 if (ELSE_CLAUSE (t))
1947 tree else_clause = ELSE_CLAUSE (t);
1948 pp_cxx_ws_string (this, "else");
1949 if (TREE_CODE (else_clause) == IF_STMT)
1950 pp_cxx_whitespace (this);
1951 else
1952 pp_newline_and_indent (this, 2);
1953 statement (else_clause);
1954 if (TREE_CODE (else_clause) != IF_STMT)
1955 pp_newline_and_indent (this, -2);
1957 break;
1959 case SWITCH_STMT:
1960 pp_cxx_ws_string (this, "switch");
1961 pp_space (this);
1962 pp_cxx_left_paren (this);
1963 expression (SWITCH_STMT_COND (t));
1964 pp_cxx_right_paren (this);
1965 pp_indentation (this) += 3;
1966 pp_needs_newline (this) = true;
1967 statement (SWITCH_STMT_BODY (t));
1968 pp_newline_and_indent (this, -3);
1969 break;
1971 /* iteration-statement:
1972 while ( expression ) statement
1973 do statement while ( expression ) ;
1974 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1975 for ( declaration expression(opt) ; expression(opt) ) statement */
1976 case WHILE_STMT:
1977 pp_cxx_ws_string (this, "while");
1978 pp_space (this);
1979 pp_cxx_left_paren (this);
1980 expression (WHILE_COND (t));
1981 pp_cxx_right_paren (this);
1982 pp_newline_and_indent (this, 3);
1983 statement (WHILE_BODY (t));
1984 pp_indentation (this) -= 3;
1985 pp_needs_newline (this) = true;
1986 break;
1988 case DO_STMT:
1989 pp_cxx_ws_string (this, "do");
1990 pp_newline_and_indent (this, 3);
1991 statement (DO_BODY (t));
1992 pp_newline_and_indent (this, -3);
1993 pp_cxx_ws_string (this, "while");
1994 pp_space (this);
1995 pp_cxx_left_paren (this);
1996 expression (DO_COND (t));
1997 pp_cxx_right_paren (this);
1998 pp_cxx_semicolon (this);
1999 pp_needs_newline (this) = true;
2000 break;
2002 case FOR_STMT:
2003 pp_cxx_ws_string (this, "for");
2004 pp_space (this);
2005 pp_cxx_left_paren (this);
2006 if (FOR_INIT_STMT (t))
2007 statement (FOR_INIT_STMT (t));
2008 else
2009 pp_cxx_semicolon (this);
2010 pp_needs_newline (this) = false;
2011 pp_cxx_whitespace (this);
2012 if (FOR_COND (t))
2013 expression (FOR_COND (t));
2014 pp_cxx_semicolon (this);
2015 pp_needs_newline (this) = false;
2016 pp_cxx_whitespace (this);
2017 if (FOR_EXPR (t))
2018 expression (FOR_EXPR (t));
2019 pp_cxx_right_paren (this);
2020 pp_newline_and_indent (this, 3);
2021 statement (FOR_BODY (t));
2022 pp_indentation (this) -= 3;
2023 pp_needs_newline (this) = true;
2024 break;
2026 case RANGE_FOR_STMT:
2027 pp_cxx_ws_string (this, "for");
2028 pp_space (this);
2029 pp_cxx_left_paren (this);
2030 statement (RANGE_FOR_DECL (t));
2031 pp_space (this);
2032 pp_needs_newline (this) = false;
2033 pp_colon (this);
2034 pp_space (this);
2035 statement (RANGE_FOR_EXPR (t));
2036 pp_cxx_right_paren (this);
2037 pp_newline_and_indent (this, 3);
2038 statement (FOR_BODY (t));
2039 pp_indentation (this) -= 3;
2040 pp_needs_newline (this) = true;
2041 break;
2043 /* jump-statement:
2044 goto identifier;
2045 continue ;
2046 return expression(opt) ; */
2047 case BREAK_STMT:
2048 case CONTINUE_STMT:
2049 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2050 pp_cxx_semicolon (this);
2051 pp_needs_newline (this) = true;
2052 break;
2054 /* expression-statement:
2055 expression(opt) ; */
2056 case EXPR_STMT:
2057 expression (EXPR_STMT_EXPR (t));
2058 pp_cxx_semicolon (this);
2059 pp_needs_newline (this) = true;
2060 break;
2062 case CLEANUP_STMT:
2063 pp_cxx_ws_string (this, "try");
2064 pp_newline_and_indent (this, 2);
2065 statement (CLEANUP_BODY (t));
2066 pp_newline_and_indent (this, -2);
2067 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2068 pp_newline_and_indent (this, 2);
2069 statement (CLEANUP_EXPR (t));
2070 pp_newline_and_indent (this, -2);
2071 break;
2073 case STATIC_ASSERT:
2074 declaration (t);
2075 break;
2077 default:
2078 c_pretty_printer::statement (t);
2079 break;
2083 /* original-namespace-definition:
2084 namespace identifier { namespace-body }
2086 As an edge case, we also handle unnamed namespace definition here. */
2088 static void
2089 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2091 pp_cxx_ws_string (pp, "namespace");
2092 if (DECL_CONTEXT (t))
2093 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2094 if (DECL_NAME (t))
2095 pp_cxx_unqualified_id (pp, t);
2096 pp_cxx_whitespace (pp);
2097 pp_cxx_left_brace (pp);
2098 /* We do not print the namespace-body. */
2099 pp_cxx_whitespace (pp);
2100 pp_cxx_right_brace (pp);
2103 /* namespace-alias:
2104 identifier
2106 namespace-alias-definition:
2107 namespace identifier = qualified-namespace-specifier ;
2109 qualified-namespace-specifier:
2110 ::(opt) nested-name-specifier(opt) namespace-name */
2112 static void
2113 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2115 pp_cxx_ws_string (pp, "namespace");
2116 if (DECL_CONTEXT (t))
2117 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2118 pp_cxx_unqualified_id (pp, t);
2119 pp_cxx_whitespace (pp);
2120 pp_equal (pp);
2121 pp_cxx_whitespace (pp);
2122 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2123 pp_cxx_nested_name_specifier (pp,
2124 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2125 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2126 pp_cxx_semicolon (pp);
2129 /* simple-declaration:
2130 decl-specifier-seq(opt) init-declarator-list(opt) */
2132 static void
2133 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2135 pp->declaration_specifiers (t);
2136 pp_cxx_init_declarator (pp, t);
2137 pp_cxx_semicolon (pp);
2138 pp_needs_newline (pp) = true;
2142 template-parameter-list:
2143 template-parameter
2144 template-parameter-list , template-parameter */
2146 static inline void
2147 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2149 const int n = TREE_VEC_LENGTH (t);
2150 int i;
2151 for (i = 0; i < n; ++i)
2153 if (i)
2154 pp_cxx_separate_with (pp, ',');
2155 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2159 /* template-parameter:
2160 type-parameter
2161 parameter-declaration
2163 type-parameter:
2164 class ...(opt) identifier(opt)
2165 class identifier(opt) = type-id
2166 typename identifier(opt)
2167 typename ...(opt) identifier(opt) = type-id
2168 template < template-parameter-list > class ...(opt) identifier(opt)
2169 template < template-parameter-list > class identifier(opt) = template-name */
2171 static void
2172 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2174 tree parameter = TREE_VALUE (t);
2175 switch (TREE_CODE (parameter))
2177 case TYPE_DECL:
2178 pp_cxx_ws_string (pp, "class");
2179 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2180 pp_cxx_ws_string (pp, "...");
2181 if (DECL_NAME (parameter))
2182 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2183 /* FIXME: Check if we should print also default argument. */
2184 break;
2186 case PARM_DECL:
2187 pp_cxx_parameter_declaration (pp, parameter);
2188 break;
2190 case TEMPLATE_DECL:
2191 break;
2193 default:
2194 pp_unsupported_tree (pp, t);
2195 break;
2199 /* Pretty-print a template parameter in the canonical form
2200 "template-parameter-<level>-<position in parameter list>". */
2202 void
2203 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2205 const enum tree_code code = TREE_CODE (parm);
2207 /* Brings type template parameters to the canonical forms. */
2208 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2209 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2210 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2212 pp_cxx_begin_template_argument_list (pp);
2213 pp->translate_string ("template-parameter-");
2214 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2215 pp_minus (pp);
2216 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2217 pp_cxx_end_template_argument_list (pp);
2220 /* Print a constrained-type-specifier. */
2222 void
2223 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2225 tree t, a;
2226 if (c == error_mark_node)
2228 pp_cxx_ws_string(pp, "<unsatisfied-constrained-placeholder>");
2229 return;
2231 placeholder_extract_concept_and_args (c, t, a);
2232 pp->id_expression (t);
2233 if (TREE_VEC_LENGTH (a) > 1)
2235 pp_cxx_begin_template_argument_list (pp);
2236 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2237 for (int i = TREE_VEC_LENGTH (a) - 1; i > 0; --i)
2238 TREE_VEC_ELT (args, i-1) = TREE_VEC_ELT (a, i);
2239 pp_cxx_template_argument_list (pp, args);
2240 ggc_free (args);
2241 pp_cxx_end_template_argument_list (pp);
2246 template-declaration:
2247 export(opt) template < template-parameter-list > declaration
2249 Concept extensions:
2251 template-declaration:
2252 export(opt) template < template-parameter-list >
2253 requires-clause(opt) declaration */
2255 static void
2256 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2258 tree tmpl = most_general_template (t);
2259 tree level;
2261 pp_maybe_newline_and_indent (pp, 0);
2262 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2264 pp_cxx_ws_string (pp, "template");
2265 pp_cxx_begin_template_argument_list (pp);
2266 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2267 pp_cxx_end_template_argument_list (pp);
2268 pp_newline_and_indent (pp, 3);
2271 if (flag_concepts)
2272 if (tree ci = get_constraints (t))
2273 if (tree reqs = CI_TEMPLATE_REQS (ci))
2275 pp_cxx_requires_clause (pp, reqs);
2276 pp_newline_and_indent (pp, 6);
2279 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2280 pp_cxx_function_definition (pp, t);
2281 else
2282 pp_cxx_simple_declaration (pp, t);
2285 static void
2286 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2288 pp_unsupported_tree (pp, t);
2291 static void
2292 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2294 pp_unsupported_tree (pp, t);
2298 declaration:
2299 block-declaration
2300 function-definition
2301 template-declaration
2302 explicit-instantiation
2303 explicit-specialization
2304 linkage-specification
2305 namespace-definition
2307 block-declaration:
2308 simple-declaration
2309 asm-definition
2310 namespace-alias-definition
2311 using-declaration
2312 using-directive
2313 static_assert-declaration */
2314 void
2315 cxx_pretty_printer::declaration (tree t)
2317 if (TREE_CODE (t) == STATIC_ASSERT)
2319 pp_cxx_ws_string (this, "static_assert");
2320 pp_cxx_left_paren (this);
2321 expression (STATIC_ASSERT_CONDITION (t));
2322 pp_cxx_separate_with (this, ',');
2323 expression (STATIC_ASSERT_MESSAGE (t));
2324 pp_cxx_right_paren (this);
2326 else if (!DECL_LANG_SPECIFIC (t))
2327 pp_cxx_simple_declaration (this, t);
2328 else if (DECL_USE_TEMPLATE (t))
2329 switch (DECL_USE_TEMPLATE (t))
2331 case 1:
2332 pp_cxx_template_declaration (this, t);
2333 break;
2335 case 2:
2336 pp_cxx_explicit_specialization (this, t);
2337 break;
2339 case 3:
2340 pp_cxx_explicit_instantiation (this, t);
2341 break;
2343 default:
2344 break;
2346 else switch (TREE_CODE (t))
2348 case VAR_DECL:
2349 case TYPE_DECL:
2350 pp_cxx_simple_declaration (this, t);
2351 break;
2353 case FUNCTION_DECL:
2354 if (DECL_SAVED_TREE (t))
2355 pp_cxx_function_definition (this, t);
2356 else
2357 pp_cxx_simple_declaration (this, t);
2358 break;
2360 case NAMESPACE_DECL:
2361 if (DECL_NAMESPACE_ALIAS (t))
2362 pp_cxx_namespace_alias_definition (this, t);
2363 else
2364 pp_cxx_original_namespace_definition (this, t);
2365 break;
2367 default:
2368 pp_unsupported_tree (this, t);
2369 break;
2373 static void
2374 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2376 t = TREE_OPERAND (t, 0);
2377 pp_cxx_ws_string (pp, "typeid");
2378 pp_cxx_left_paren (pp);
2379 if (TYPE_P (t))
2380 pp->type_id (t);
2381 else
2382 pp->expression (t);
2383 pp_cxx_right_paren (pp);
2386 void
2387 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2389 pp_cxx_ws_string (pp, "va_arg");
2390 pp_cxx_left_paren (pp);
2391 pp->assignment_expression (TREE_OPERAND (t, 0));
2392 pp_cxx_separate_with (pp, ',');
2393 pp->type_id (TREE_TYPE (t));
2394 pp_cxx_right_paren (pp);
2397 static bool
2398 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2400 switch (TREE_CODE (t))
2402 case ARROW_EXPR:
2403 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2404 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2406 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2407 pp_cxx_separate_with (pp, ',');
2408 return true;
2410 return false;
2411 case COMPONENT_REF:
2412 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2413 return false;
2414 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2415 pp_cxx_dot (pp);
2416 pp->expression (TREE_OPERAND (t, 1));
2417 return true;
2418 case ARRAY_REF:
2419 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2420 return false;
2421 pp_left_bracket (pp);
2422 pp->expression (TREE_OPERAND (t, 1));
2423 pp_right_bracket (pp);
2424 return true;
2425 default:
2426 return false;
2430 void
2431 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2433 pp_cxx_ws_string (pp, "offsetof");
2434 pp_cxx_left_paren (pp);
2435 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2436 pp->expression (TREE_OPERAND (t, 0));
2437 pp_cxx_right_paren (pp);
2440 static char const*
2441 get_fold_operator (tree t)
2443 int op = int_cst_value (FOLD_EXPR_OP (t));
2444 if (FOLD_EXPR_MODIFY_P (t))
2446 switch (op)
2448 case NOP_EXPR: return "=";
2449 case PLUS_EXPR: return "+=";
2450 case MINUS_EXPR: return "-=";
2451 case MULT_EXPR: return "*=";
2452 case TRUNC_DIV_EXPR: return "/=";
2453 case TRUNC_MOD_EXPR: return "%=";
2454 case BIT_XOR_EXPR: return "^=";
2455 case BIT_AND_EXPR: return "&=";
2456 case BIT_IOR_EXPR: return "|=";
2457 case LSHIFT_EXPR: return "<<=";
2458 case RSHIFT_EXPR: return ">>=";
2459 default: gcc_unreachable ();
2462 else
2464 switch (op)
2466 case PLUS_EXPR: return "+";
2467 case MINUS_EXPR: return "-";
2468 case MULT_EXPR: return "*";
2469 case TRUNC_DIV_EXPR: return "/";
2470 case TRUNC_MOD_EXPR: return "%";
2471 case BIT_XOR_EXPR: return "^";
2472 case BIT_AND_EXPR: return "&";
2473 case BIT_IOR_EXPR: return "|";
2474 case LSHIFT_EXPR: return "<<";
2475 case RSHIFT_EXPR: return ">>";
2476 case EQ_EXPR: return "==";
2477 case NE_EXPR: return "!=";
2478 case LT_EXPR: return "<";
2479 case GT_EXPR: return ">";
2480 case LE_EXPR: return "<=";
2481 case GE_EXPR: return ">=";
2482 case TRUTH_ANDIF_EXPR: return "&&";
2483 case TRUTH_ORIF_EXPR: return "||";
2484 case MEMBER_REF: return "->*";
2485 case DOTSTAR_EXPR: return ".*";
2486 case OFFSET_REF: return ".*";
2487 default: return ","; /* FIXME: Not the right default. */
2492 void
2493 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2495 char const* op = get_fold_operator (t);
2496 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2497 pp_cxx_left_paren (pp);
2498 pp_cxx_ws_string (pp, "...");
2499 pp_cxx_ws_string (pp, op);
2500 pp->expression (expr);
2501 pp_cxx_right_paren (pp);
2504 void
2505 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2507 char const* op = get_fold_operator (t);
2508 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2509 pp_cxx_left_paren (pp);
2510 pp->expression (expr);
2511 pp_space (pp);
2512 pp_cxx_ws_string (pp, op);
2513 pp_cxx_ws_string (pp, "...");
2514 pp_cxx_right_paren (pp);
2517 void
2518 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2520 char const* op = get_fold_operator (t);
2521 tree t1 = TREE_OPERAND (t, 1);
2522 tree t2 = TREE_OPERAND (t, 2);
2523 if (t1 == FOLD_EXPR_PACK (t))
2524 t1 = PACK_EXPANSION_PATTERN (t1);
2525 else
2526 t2 = PACK_EXPANSION_PATTERN (t2);
2527 pp_cxx_left_paren (pp);
2528 pp->expression (t1);
2529 pp_cxx_ws_string (pp, op);
2530 pp_cxx_ws_string (pp, "...");
2531 pp_cxx_ws_string (pp, op);
2532 pp->expression (t2);
2533 pp_cxx_right_paren (pp);
2536 void
2537 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2539 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2541 switch (kind)
2543 case CPTK_HAS_NOTHROW_ASSIGN:
2544 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2545 break;
2546 case CPTK_HAS_TRIVIAL_ASSIGN:
2547 pp_cxx_ws_string (pp, "__has_trivial_assign");
2548 break;
2549 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2550 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2551 break;
2552 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2553 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2554 break;
2555 case CPTK_HAS_NOTHROW_COPY:
2556 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2557 break;
2558 case CPTK_HAS_TRIVIAL_COPY:
2559 pp_cxx_ws_string (pp, "__has_trivial_copy");
2560 break;
2561 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2562 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2563 break;
2564 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
2565 pp_cxx_ws_string (pp, "__has_unique_object_representations");
2566 break;
2567 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2568 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2569 break;
2570 case CPTK_IS_ABSTRACT:
2571 pp_cxx_ws_string (pp, "__is_abstract");
2572 break;
2573 case CPTK_IS_BASE_OF:
2574 pp_cxx_ws_string (pp, "__is_base_of");
2575 break;
2576 case CPTK_IS_CLASS:
2577 pp_cxx_ws_string (pp, "__is_class");
2578 break;
2579 case CPTK_IS_EMPTY:
2580 pp_cxx_ws_string (pp, "__is_empty");
2581 break;
2582 case CPTK_IS_ENUM:
2583 pp_cxx_ws_string (pp, "__is_enum");
2584 break;
2585 case CPTK_IS_FINAL:
2586 pp_cxx_ws_string (pp, "__is_final");
2587 break;
2588 case CPTK_IS_POD:
2589 pp_cxx_ws_string (pp, "__is_pod");
2590 break;
2591 case CPTK_IS_POLYMORPHIC:
2592 pp_cxx_ws_string (pp, "__is_polymorphic");
2593 break;
2594 case CPTK_IS_SAME_AS:
2595 pp_cxx_ws_string (pp, "__is_same_as");
2596 break;
2597 case CPTK_IS_STD_LAYOUT:
2598 pp_cxx_ws_string (pp, "__is_std_layout");
2599 break;
2600 case CPTK_IS_TRIVIAL:
2601 pp_cxx_ws_string (pp, "__is_trivial");
2602 break;
2603 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2604 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2605 break;
2606 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2607 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2608 break;
2609 case CPTK_IS_TRIVIALLY_COPYABLE:
2610 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2611 break;
2612 case CPTK_IS_UNION:
2613 pp_cxx_ws_string (pp, "__is_union");
2614 break;
2615 case CPTK_IS_LITERAL_TYPE:
2616 pp_cxx_ws_string (pp, "__is_literal_type");
2617 break;
2619 default:
2620 gcc_unreachable ();
2623 pp_cxx_left_paren (pp);
2624 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2626 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2628 pp_cxx_separate_with (pp, ',');
2629 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2632 pp_cxx_right_paren (pp);
2635 // requires-clause:
2636 // 'requires' logical-or-expression
2637 void
2638 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2640 if (!t)
2641 return;
2642 pp->padding = pp_before;
2643 pp_cxx_ws_string (pp, "requires");
2644 pp_space (pp);
2645 pp->expression (t);
2648 /* requirement:
2649 simple-requirement
2650 compound-requirement
2651 type-requirement
2652 nested-requirement */
2653 static void
2654 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2656 switch (TREE_CODE (t))
2658 case SIMPLE_REQ:
2659 pp_cxx_simple_requirement (pp, t);
2660 break;
2662 case TYPE_REQ:
2663 pp_cxx_type_requirement (pp, t);
2664 break;
2666 case COMPOUND_REQ:
2667 pp_cxx_compound_requirement (pp, t);
2668 break;
2670 case NESTED_REQ:
2671 pp_cxx_nested_requirement (pp, t);
2672 break;
2674 default:
2675 gcc_unreachable ();
2679 // requirement-list:
2680 // requirement
2681 // requirement-list ';' requirement[opt]
2683 static void
2684 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2686 for (; t; t = TREE_CHAIN (t))
2687 pp_cxx_requirement (pp, TREE_VALUE (t));
2690 // requirement-body:
2691 // '{' requirement-list '}'
2692 static void
2693 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2695 pp_cxx_left_brace (pp);
2696 pp_cxx_requirement_list (pp, t);
2697 pp_cxx_right_brace (pp);
2700 // requires-expression:
2701 // 'requires' requirement-parameter-list requirement-body
2702 void
2703 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2705 pp_string (pp, "requires");
2706 if (tree parms = TREE_OPERAND (t, 0))
2708 pp_cxx_parameter_declaration_clause (pp, parms);
2709 pp_cxx_whitespace (pp);
2711 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2714 /* simple-requirement:
2715 expression ';' */
2716 void
2717 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2719 pp->expression (TREE_OPERAND (t, 0));
2720 pp_cxx_semicolon (pp);
2723 /* type-requirement:
2724 typename type-name ';' */
2725 void
2726 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2728 pp->type_id (TREE_OPERAND (t, 0));
2729 pp_cxx_semicolon (pp);
2732 /* compound-requirement:
2733 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2734 void
2735 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2737 pp_cxx_left_brace (pp);
2738 pp->expression (TREE_OPERAND (t, 0));
2739 pp_cxx_right_brace (pp);
2741 if (COMPOUND_REQ_NOEXCEPT_P (t))
2742 pp_cxx_ws_string (pp, "noexcept");
2744 if (tree type = TREE_OPERAND (t, 1))
2746 pp_cxx_ws_string (pp, "->");
2747 pp->type_id (type);
2749 pp_cxx_semicolon (pp);
2752 /* nested requirement:
2753 'requires' constraint-expression */
2754 void
2755 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2757 pp_cxx_ws_string (pp, "requires");
2758 pp->expression (TREE_OPERAND (t, 0));
2759 pp_cxx_semicolon (pp);
2762 void
2763 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2765 pp->expression (TREE_OPERAND (t, 0));
2768 void
2769 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2771 tree decl = CHECK_CONSTR_CONCEPT (t);
2772 tree tmpl = DECL_TI_TEMPLATE (decl);
2773 tree args = CHECK_CONSTR_ARGS (t);
2774 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2776 if (TREE_CODE (decl) == VAR_DECL)
2777 pp->expression (id);
2778 else if (TREE_CODE (decl) == FUNCTION_DECL)
2780 tree call = build_vl_exp (CALL_EXPR, 2);
2781 TREE_OPERAND (call, 0) = integer_two_node;
2782 TREE_OPERAND (call, 1) = id;
2783 pp->expression (call);
2785 else
2786 gcc_unreachable ();
2789 void
2790 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2792 pp_string (pp, "<valid-expression ");
2793 pp_cxx_left_paren (pp);
2794 pp->expression (TREE_OPERAND (t, 0));
2795 pp_cxx_right_paren (pp);
2796 pp_string (pp, ">");
2799 void
2800 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2802 pp_string (pp, "<valid-type ");
2803 pp->type_id (TREE_OPERAND (t, 0));
2804 pp_string (pp, ">");
2807 void
2808 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2810 pp_string (pp, "<implicitly-conversion ");
2811 pp_cxx_left_paren (pp);
2812 pp->expression (ICONV_CONSTR_EXPR (t));
2813 pp_cxx_right_paren (pp);
2814 pp_cxx_ws_string (pp, "to");
2815 pp->type_id (ICONV_CONSTR_TYPE (t));
2816 pp_string (pp, ">");
2819 void
2820 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2822 pp_string (pp, "<argument-deduction ");
2823 pp_cxx_left_paren (pp);
2824 pp->expression (DEDUCT_CONSTR_EXPR (t));
2825 pp_cxx_right_paren (pp);
2826 pp_cxx_ws_string (pp, "as");
2827 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2828 pp_string (pp, ">");
2831 void
2832 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2834 pp_cxx_ws_string (pp, "noexcept");
2835 pp_cxx_whitespace (pp);
2836 pp_cxx_left_paren (pp);
2837 pp->expression (TREE_OPERAND (t, 0));
2838 pp_cxx_right_paren (pp);
2841 void
2842 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2844 pp_left_paren (pp);
2845 pp_string (pp, "<requires ");
2846 if (tree parms = PARM_CONSTR_PARMS (t))
2848 pp_cxx_parameter_declaration_clause (pp, parms);
2849 pp_cxx_whitespace (pp);
2851 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2852 pp_string (pp, ">");
2855 void
2856 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2858 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2859 pp_string (pp, " and ");
2860 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2863 void
2864 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2866 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2867 pp_string (pp, " or ");
2868 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2871 void
2872 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2874 if (t == error_mark_node)
2875 return pp->expression (t);
2877 switch (TREE_CODE (t))
2879 case PRED_CONSTR:
2880 pp_cxx_predicate_constraint (pp, t);
2881 break;
2883 case CHECK_CONSTR:
2884 pp_cxx_check_constraint (pp, t);
2885 break;
2887 case EXPR_CONSTR:
2888 pp_cxx_expression_constraint (pp, t);
2889 break;
2891 case TYPE_CONSTR:
2892 pp_cxx_type_constraint (pp, t);
2893 break;
2895 case ICONV_CONSTR:
2896 pp_cxx_implicit_conversion_constraint (pp, t);
2897 break;
2899 case DEDUCT_CONSTR:
2900 pp_cxx_argument_deduction_constraint (pp, t);
2901 break;
2903 case EXCEPT_CONSTR:
2904 pp_cxx_exception_constraint (pp, t);
2905 break;
2907 case PARM_CONSTR:
2908 pp_cxx_parameterized_constraint (pp, t);
2909 break;
2911 case CONJ_CONSTR:
2912 pp_cxx_conjunction (pp, t);
2913 break;
2915 case DISJ_CONSTR:
2916 pp_cxx_disjunction (pp, t);
2917 break;
2919 case EXPR_PACK_EXPANSION:
2920 pp->expression (TREE_OPERAND (t, 0));
2921 break;
2923 default:
2924 gcc_unreachable ();
2930 typedef c_pretty_print_fn pp_fun;
2932 /* Initialization of a C++ pretty-printer object. */
2934 cxx_pretty_printer::cxx_pretty_printer ()
2935 : c_pretty_printer (),
2936 enclosing_scope (global_namespace)
2938 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2939 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;