Remove assert in get_def_bb_for_const
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob3b52a35a2e581818685e4c0c43cf8a5e62bed9fc
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);
40 static inline void
41 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
43 const char *p = pp_last_position_in_text (pp);
45 if (p != NULL && *p == c)
46 pp_cxx_whitespace (pp);
47 pp_character (pp, c);
48 pp->padding = pp_none;
51 #define pp_cxx_expression_list(PP, T) \
52 pp_c_expression_list (PP, T)
53 #define pp_cxx_space_for_pointer_operator(PP, T) \
54 pp_c_space_for_pointer_operator (PP, T)
55 #define pp_cxx_init_declarator(PP, T) \
56 pp_c_init_declarator (PP, T)
57 #define pp_cxx_call_argument_list(PP, T) \
58 pp_c_call_argument_list (PP, T)
60 void
61 pp_cxx_colon_colon (cxx_pretty_printer *pp)
63 pp_colon_colon (pp);
64 pp->padding = pp_none;
67 void
68 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
70 pp_cxx_nonconsecutive_character (pp, '<');
73 void
74 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
76 pp_cxx_nonconsecutive_character (pp, '>');
79 void
80 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
82 pp_separate_with (pp, c);
83 pp->padding = pp_none;
86 /* Expressions. */
88 static inline bool
89 is_destructor_name (tree name)
91 return name == complete_dtor_identifier
92 || name == base_dtor_identifier
93 || name == deleting_dtor_identifier;
96 /* conversion-function-id:
97 operator conversion-type-id
99 conversion-type-id:
100 type-specifier-seq conversion-declarator(opt)
102 conversion-declarator:
103 ptr-operator conversion-declarator(opt) */
105 static inline void
106 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
108 pp_cxx_ws_string (pp, "operator");
109 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
112 static inline void
113 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
115 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
116 pp_cxx_begin_template_argument_list (pp);
117 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
118 pp_cxx_end_template_argument_list (pp);
121 /* Prints the unqualified part of the id-expression T.
123 unqualified-id:
124 identifier
125 operator-function-id
126 conversion-function-id
127 ~ class-name
128 template-id */
130 static void
131 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
133 enum tree_code code = TREE_CODE (t);
134 switch (code)
136 case RESULT_DECL:
137 pp->translate_string ("<return-value>");
138 break;
140 case OVERLOAD:
141 t = OVL_CURRENT (t);
142 case VAR_DECL:
143 case PARM_DECL:
144 case CONST_DECL:
145 case TYPE_DECL:
146 case FUNCTION_DECL:
147 case NAMESPACE_DECL:
148 case FIELD_DECL:
149 case LABEL_DECL:
150 case USING_DECL:
151 case TEMPLATE_DECL:
152 t = DECL_NAME (t);
154 case IDENTIFIER_NODE:
155 if (t == NULL)
156 pp->translate_string ("<unnamed>");
157 else if (IDENTIFIER_TYPENAME_P (t))
158 pp_cxx_conversion_function_id (pp, t);
159 else
161 if (is_destructor_name (t))
163 pp_complement (pp);
164 /* FIXME: Why is this necessary? */
165 if (TREE_TYPE (t))
166 t = constructor_name (TREE_TYPE (t));
168 pp_cxx_tree_identifier (pp, t);
170 break;
172 case TEMPLATE_ID_EXPR:
173 pp_cxx_template_id (pp, t);
174 break;
176 case BASELINK:
177 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
178 break;
180 case RECORD_TYPE:
181 case UNION_TYPE:
182 case ENUMERAL_TYPE:
183 case TYPENAME_TYPE:
184 case UNBOUND_CLASS_TEMPLATE:
185 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
186 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
188 pp_cxx_begin_template_argument_list (pp);
189 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
190 (CLASSTYPE_TI_ARGS (t)));
191 pp_cxx_end_template_argument_list (pp);
193 break;
195 case BIT_NOT_EXPR:
196 pp_cxx_complement (pp);
197 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
198 break;
200 case TEMPLATE_TYPE_PARM:
201 case TEMPLATE_TEMPLATE_PARM:
202 if (TYPE_IDENTIFIER (t))
203 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
204 else
205 pp_cxx_canonical_template_parameter (pp, t);
206 break;
208 case TEMPLATE_PARM_INDEX:
209 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
210 break;
212 case BOUND_TEMPLATE_TEMPLATE_PARM:
213 pp_cxx_cv_qualifier_seq (pp, t);
214 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
215 pp_cxx_begin_template_argument_list (pp);
216 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
217 pp_cxx_end_template_argument_list (pp);
218 break;
220 default:
221 pp_unsupported_tree (pp, t);
222 break;
226 /* Pretty-print out the token sequence ":: template" in template codes
227 where it is needed to "inline declare" the (following) member as
228 a template. This situation arises when SCOPE of T is dependent
229 on template parameters. */
231 static inline void
232 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
234 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
235 && TYPE_P (scope) && dependent_type_p (scope))
236 pp_cxx_ws_string (pp, "template");
239 /* nested-name-specifier:
240 class-or-namespace-name :: nested-name-specifier(opt)
241 class-or-namespace-name :: template nested-name-specifier */
243 static void
244 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
246 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
248 tree scope = get_containing_scope (t);
249 pp_cxx_nested_name_specifier (pp, scope);
250 pp_cxx_template_keyword_if_needed (pp, scope, t);
251 pp_cxx_unqualified_id (pp, t);
252 pp_cxx_colon_colon (pp);
256 /* qualified-id:
257 nested-name-specifier template(opt) unqualified-id */
259 static void
260 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
262 switch (TREE_CODE (t))
264 /* A pointer-to-member is always qualified. */
265 case PTRMEM_CST:
266 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
267 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
268 break;
270 /* In Standard C++, functions cannot possibly be used as
271 nested-name-specifiers. However, there are situations where
272 is "makes sense" to output the surrounding function name for the
273 purpose of emphasizing on the scope kind. Just printing the
274 function name might not be sufficient as it may be overloaded; so,
275 we decorate the function with its signature too.
276 FIXME: This is probably the wrong pretty-printing for conversion
277 functions and some function templates. */
278 case OVERLOAD:
279 t = OVL_CURRENT (t);
280 case FUNCTION_DECL:
281 if (DECL_FUNCTION_MEMBER_P (t))
282 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
283 pp_cxx_unqualified_id
284 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
285 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
286 break;
288 case OFFSET_REF:
289 case SCOPE_REF:
290 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
291 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
292 break;
294 default:
296 tree scope = get_containing_scope (t);
297 if (scope != pp->enclosing_scope)
299 pp_cxx_nested_name_specifier (pp, scope);
300 pp_cxx_template_keyword_if_needed (pp, scope, t);
302 pp_cxx_unqualified_id (pp, t);
304 break;
309 void
310 cxx_pretty_printer::constant (tree t)
312 switch (TREE_CODE (t))
314 case STRING_CST:
316 const bool in_parens = PAREN_STRING_LITERAL_P (t);
317 if (in_parens)
318 pp_cxx_left_paren (this);
319 c_pretty_printer::constant (t);
320 if (in_parens)
321 pp_cxx_right_paren (this);
323 break;
325 case INTEGER_CST:
326 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
328 pp_string (this, "nullptr");
329 break;
331 /* else fall through. */
333 default:
334 c_pretty_printer::constant (t);
335 break;
339 /* id-expression:
340 unqualified-id
341 qualified-id */
343 void
344 cxx_pretty_printer::id_expression (tree t)
346 if (TREE_CODE (t) == OVERLOAD)
347 t = OVL_CURRENT (t);
348 if (DECL_P (t) && DECL_CONTEXT (t))
349 pp_cxx_qualified_id (this, t);
350 else
351 pp_cxx_unqualified_id (this, t);
354 /* user-defined literal:
355 literal ud-suffix */
357 void
358 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
360 pp->constant (USERDEF_LITERAL_VALUE (t));
361 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
365 /* primary-expression:
366 literal
367 this
368 :: identifier
369 :: operator-function-id
370 :: qualifier-id
371 ( expression )
372 id-expression
374 GNU Extensions:
375 __builtin_va_arg ( assignment-expression , type-id )
376 __builtin_offsetof ( type-id, offsetof-expression )
378 __has_nothrow_assign ( type-id )
379 __has_nothrow_constructor ( type-id )
380 __has_nothrow_copy ( type-id )
381 __has_trivial_assign ( type-id )
382 __has_trivial_constructor ( type-id )
383 __has_trivial_copy ( type-id )
384 __has_trivial_destructor ( type-id )
385 __has_virtual_destructor ( type-id )
386 __is_abstract ( type-id )
387 __is_base_of ( type-id , type-id )
388 __is_class ( type-id )
389 __is_empty ( type-id )
390 __is_enum ( type-id )
391 __is_literal_type ( type-id )
392 __is_pod ( type-id )
393 __is_polymorphic ( type-id )
394 __is_std_layout ( type-id )
395 __is_trivial ( type-id )
396 __is_union ( type-id ) */
398 void
399 cxx_pretty_printer::primary_expression (tree t)
401 switch (TREE_CODE (t))
403 case VOID_CST:
404 case INTEGER_CST:
405 case REAL_CST:
406 case COMPLEX_CST:
407 case STRING_CST:
408 constant (t);
409 break;
411 case USERDEF_LITERAL:
412 pp_cxx_userdef_literal (this, t);
413 break;
415 case BASELINK:
416 t = BASELINK_FUNCTIONS (t);
417 case VAR_DECL:
418 case PARM_DECL:
419 case FIELD_DECL:
420 case FUNCTION_DECL:
421 case OVERLOAD:
422 case CONST_DECL:
423 case TEMPLATE_DECL:
424 id_expression (t);
425 break;
427 case RESULT_DECL:
428 case TEMPLATE_TYPE_PARM:
429 case TEMPLATE_TEMPLATE_PARM:
430 case TEMPLATE_PARM_INDEX:
431 pp_cxx_unqualified_id (this, t);
432 break;
434 case STMT_EXPR:
435 pp_cxx_left_paren (this);
436 statement (STMT_EXPR_STMT (t));
437 pp_cxx_right_paren (this);
438 break;
440 case TRAIT_EXPR:
441 pp_cxx_trait_expression (this, t);
442 break;
444 case VA_ARG_EXPR:
445 pp_cxx_va_arg_expression (this, t);
446 break;
448 case OFFSETOF_EXPR:
449 pp_cxx_offsetof_expression (this, t);
450 break;
452 case REQUIRES_EXPR:
453 pp_cxx_requires_expr (this, t);
454 break;
456 default:
457 c_pretty_printer::primary_expression (t);
458 break;
462 /* postfix-expression:
463 primary-expression
464 postfix-expression [ expression ]
465 postfix-expression ( expression-list(opt) )
466 simple-type-specifier ( expression-list(opt) )
467 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
468 typename ::(opt) nested-name-specifier template(opt)
469 template-id ( expression-list(opt) )
470 postfix-expression . template(opt) ::(opt) id-expression
471 postfix-expression -> template(opt) ::(opt) id-expression
472 postfix-expression . pseudo-destructor-name
473 postfix-expression -> pseudo-destructor-name
474 postfix-expression ++
475 postfix-expression --
476 dynamic_cast < type-id > ( expression )
477 static_cast < type-id > ( expression )
478 reinterpret_cast < type-id > ( expression )
479 const_cast < type-id > ( expression )
480 typeid ( expression )
481 typeid ( type-id ) */
483 void
484 cxx_pretty_printer::postfix_expression (tree t)
486 enum tree_code code = TREE_CODE (t);
488 switch (code)
490 case AGGR_INIT_EXPR:
491 case CALL_EXPR:
493 tree fun = cp_get_callee (t);
494 tree saved_scope = enclosing_scope;
495 bool skipfirst = false;
496 tree arg;
498 if (TREE_CODE (fun) == ADDR_EXPR)
499 fun = TREE_OPERAND (fun, 0);
501 /* In templates, where there is no way to tell whether a given
502 call uses an actual member function. So the parser builds
503 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
504 instantiation time. */
505 if (TREE_CODE (fun) != FUNCTION_DECL)
507 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
509 tree object = (code == AGGR_INIT_EXPR
510 ? (AGGR_INIT_VIA_CTOR_P (t)
511 ? AGGR_INIT_EXPR_SLOT (t)
512 : AGGR_INIT_EXPR_ARG (t, 0))
513 : CALL_EXPR_ARG (t, 0));
515 while (TREE_CODE (object) == NOP_EXPR)
516 object = TREE_OPERAND (object, 0);
518 if (TREE_CODE (object) == ADDR_EXPR)
519 object = TREE_OPERAND (object, 0);
521 if (!TYPE_PTR_P (TREE_TYPE (object)))
523 postfix_expression (object);
524 pp_cxx_dot (this);
526 else
528 postfix_expression (object);
529 pp_cxx_arrow (this);
531 skipfirst = true;
532 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
535 postfix_expression (fun);
536 enclosing_scope = saved_scope;
537 pp_cxx_left_paren (this);
538 if (code == AGGR_INIT_EXPR)
540 aggr_init_expr_arg_iterator iter;
541 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
543 if (skipfirst)
544 skipfirst = false;
545 else
547 expression (arg);
548 if (more_aggr_init_expr_args_p (&iter))
549 pp_cxx_separate_with (this, ',');
553 else
555 call_expr_arg_iterator iter;
556 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
558 if (skipfirst)
559 skipfirst = false;
560 else
562 expression (arg);
563 if (more_call_expr_args_p (&iter))
564 pp_cxx_separate_with (this, ',');
568 pp_cxx_right_paren (this);
570 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
572 pp_cxx_separate_with (this, ',');
573 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
575 break;
577 case BASELINK:
578 case VAR_DECL:
579 case PARM_DECL:
580 case FIELD_DECL:
581 case FUNCTION_DECL:
582 case OVERLOAD:
583 case CONST_DECL:
584 case TEMPLATE_DECL:
585 case RESULT_DECL:
586 primary_expression (t);
587 break;
589 case DYNAMIC_CAST_EXPR:
590 case STATIC_CAST_EXPR:
591 case REINTERPRET_CAST_EXPR:
592 case CONST_CAST_EXPR:
593 if (code == DYNAMIC_CAST_EXPR)
594 pp_cxx_ws_string (this, "dynamic_cast");
595 else if (code == STATIC_CAST_EXPR)
596 pp_cxx_ws_string (this, "static_cast");
597 else if (code == REINTERPRET_CAST_EXPR)
598 pp_cxx_ws_string (this, "reinterpret_cast");
599 else
600 pp_cxx_ws_string (this, "const_cast");
601 pp_cxx_begin_template_argument_list (this);
602 type_id (TREE_TYPE (t));
603 pp_cxx_end_template_argument_list (this);
604 pp_left_paren (this);
605 expression (TREE_OPERAND (t, 0));
606 pp_right_paren (this);
607 break;
609 case EMPTY_CLASS_EXPR:
610 type_id (TREE_TYPE (t));
611 pp_left_paren (this);
612 pp_right_paren (this);
613 break;
615 case TYPEID_EXPR:
616 pp_cxx_typeid_expression (this, t);
617 break;
619 case PSEUDO_DTOR_EXPR:
620 postfix_expression (TREE_OPERAND (t, 0));
621 pp_cxx_dot (this);
622 if (TREE_OPERAND (t, 1))
624 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
625 pp_cxx_colon_colon (this);
627 pp_complement (this);
628 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
629 break;
631 case ARROW_EXPR:
632 postfix_expression (TREE_OPERAND (t, 0));
633 pp_cxx_arrow (this);
634 break;
636 default:
637 c_pretty_printer::postfix_expression (t);
638 break;
642 /* new-expression:
643 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
644 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
646 new-placement:
647 ( expression-list )
649 new-type-id:
650 type-specifier-seq new-declarator(opt)
652 new-declarator:
653 ptr-operator new-declarator(opt)
654 direct-new-declarator
656 direct-new-declarator
657 [ expression ]
658 direct-new-declarator [ constant-expression ]
660 new-initializer:
661 ( expression-list(opt) ) */
663 static void
664 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
666 enum tree_code code = TREE_CODE (t);
667 tree type = TREE_OPERAND (t, 1);
668 tree init = TREE_OPERAND (t, 2);
669 switch (code)
671 case NEW_EXPR:
672 case VEC_NEW_EXPR:
673 if (NEW_EXPR_USE_GLOBAL (t))
674 pp_cxx_colon_colon (pp);
675 pp_cxx_ws_string (pp, "new");
676 if (TREE_OPERAND (t, 0))
678 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
679 pp_space (pp);
681 if (TREE_CODE (type) == ARRAY_REF)
682 type = build_cplus_array_type
683 (TREE_OPERAND (type, 0),
684 build_index_type (fold_build2_loc (input_location,
685 MINUS_EXPR, integer_type_node,
686 TREE_OPERAND (type, 1),
687 integer_one_node)));
688 pp->type_id (type);
689 if (init)
691 pp_left_paren (pp);
692 if (TREE_CODE (init) == TREE_LIST)
693 pp_c_expression_list (pp, init);
694 else if (init == void_node)
695 ; /* OK, empty initializer list. */
696 else
697 pp->expression (init);
698 pp_right_paren (pp);
700 break;
702 default:
703 pp_unsupported_tree (pp, t);
707 /* delete-expression:
708 ::(opt) delete cast-expression
709 ::(opt) delete [ ] cast-expression */
711 static void
712 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
714 enum tree_code code = TREE_CODE (t);
715 switch (code)
717 case DELETE_EXPR:
718 case VEC_DELETE_EXPR:
719 if (DELETE_EXPR_USE_GLOBAL (t))
720 pp_cxx_colon_colon (pp);
721 pp_cxx_ws_string (pp, "delete");
722 pp_space (pp);
723 if (code == VEC_DELETE_EXPR
724 || DELETE_EXPR_USE_VEC (t))
726 pp_left_bracket (pp);
727 pp_right_bracket (pp);
728 pp_space (pp);
730 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
731 break;
733 default:
734 pp_unsupported_tree (pp, t);
738 /* unary-expression:
739 postfix-expression
740 ++ cast-expression
741 -- cast-expression
742 unary-operator cast-expression
743 sizeof unary-expression
744 sizeof ( type-id )
745 sizeof ... ( identifier )
746 new-expression
747 delete-expression
749 unary-operator: one of
750 * & + - !
752 GNU extensions:
753 __alignof__ unary-expression
754 __alignof__ ( type-id ) */
756 void
757 cxx_pretty_printer::unary_expression (tree t)
759 enum tree_code code = TREE_CODE (t);
760 switch (code)
762 case NEW_EXPR:
763 case VEC_NEW_EXPR:
764 pp_cxx_new_expression (this, t);
765 break;
767 case DELETE_EXPR:
768 case VEC_DELETE_EXPR:
769 pp_cxx_delete_expression (this, t);
770 break;
772 case SIZEOF_EXPR:
773 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
775 pp_cxx_ws_string (this, "sizeof");
776 pp_cxx_ws_string (this, "...");
777 pp_cxx_whitespace (this);
778 pp_cxx_left_paren (this);
779 if (TYPE_P (TREE_OPERAND (t, 0)))
780 type_id (TREE_OPERAND (t, 0));
781 else
782 unary_expression (TREE_OPERAND (t, 0));
783 pp_cxx_right_paren (this);
784 break;
786 /* Fall through */
788 case ALIGNOF_EXPR:
789 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
790 pp_cxx_whitespace (this);
791 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
793 pp_cxx_left_paren (this);
794 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
795 pp_cxx_right_paren (this);
797 else if (TYPE_P (TREE_OPERAND (t, 0)))
799 pp_cxx_left_paren (this);
800 type_id (TREE_OPERAND (t, 0));
801 pp_cxx_right_paren (this);
803 else
804 unary_expression (TREE_OPERAND (t, 0));
805 break;
807 case AT_ENCODE_EXPR:
808 pp_cxx_ws_string (this, "@encode");
809 pp_cxx_whitespace (this);
810 pp_cxx_left_paren (this);
811 type_id (TREE_OPERAND (t, 0));
812 pp_cxx_right_paren (this);
813 break;
815 case NOEXCEPT_EXPR:
816 pp_cxx_ws_string (this, "noexcept");
817 pp_cxx_whitespace (this);
818 pp_cxx_left_paren (this);
819 expression (TREE_OPERAND (t, 0));
820 pp_cxx_right_paren (this);
821 break;
823 case UNARY_PLUS_EXPR:
824 pp_plus (this);
825 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
826 break;
828 default:
829 c_pretty_printer::unary_expression (t);
830 break;
834 /* cast-expression:
835 unary-expression
836 ( type-id ) cast-expression */
838 static void
839 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
841 switch (TREE_CODE (t))
843 case CAST_EXPR:
844 case IMPLICIT_CONV_EXPR:
845 pp->type_id (TREE_TYPE (t));
846 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
847 break;
849 default:
850 pp_c_cast_expression (pp, t);
851 break;
855 /* pm-expression:
856 cast-expression
857 pm-expression .* cast-expression
858 pm-expression ->* cast-expression */
860 static void
861 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
863 switch (TREE_CODE (t))
865 /* Handle unfortunate OFFSET_REF overloading here. */
866 case OFFSET_REF:
867 if (TYPE_P (TREE_OPERAND (t, 0)))
869 pp_cxx_qualified_id (pp, t);
870 break;
872 /* Else fall through. */
873 case MEMBER_REF:
874 case DOTSTAR_EXPR:
875 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
876 if (TREE_CODE (t) == MEMBER_REF)
877 pp_cxx_arrow (pp);
878 else
879 pp_cxx_dot (pp);
880 pp_star(pp);
881 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
882 break;
885 default:
886 pp_cxx_cast_expression (pp, t);
887 break;
891 /* multiplicative-expression:
892 pm-expression
893 multiplicative-expression * pm-expression
894 multiplicative-expression / pm-expression
895 multiplicative-expression % pm-expression */
897 void
898 cxx_pretty_printer::multiplicative_expression (tree e)
900 enum tree_code code = TREE_CODE (e);
901 switch (code)
903 case MULT_EXPR:
904 case TRUNC_DIV_EXPR:
905 case TRUNC_MOD_EXPR:
906 multiplicative_expression (TREE_OPERAND (e, 0));
907 pp_space (this);
908 if (code == MULT_EXPR)
909 pp_star (this);
910 else if (code == TRUNC_DIV_EXPR)
911 pp_slash (this);
912 else
913 pp_modulo (this);
914 pp_space (this);
915 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
916 break;
918 default:
919 pp_cxx_pm_expression (this, e);
920 break;
924 /* conditional-expression:
925 logical-or-expression
926 logical-or-expression ? expression : assignment-expression */
928 void
929 cxx_pretty_printer::conditional_expression (tree e)
931 if (TREE_CODE (e) == COND_EXPR)
933 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
934 pp_space (this);
935 pp_question (this);
936 pp_space (this);
937 expression (TREE_OPERAND (e, 1));
938 pp_space (this);
939 assignment_expression (TREE_OPERAND (e, 2));
941 else
942 pp_c_logical_or_expression (this, e);
945 /* Pretty-print a compound assignment operator token as indicated by T. */
947 static void
948 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
950 const char *op;
952 switch (TREE_CODE (t))
954 case NOP_EXPR:
955 op = "=";
956 break;
958 case PLUS_EXPR:
959 op = "+=";
960 break;
962 case MINUS_EXPR:
963 op = "-=";
964 break;
966 case TRUNC_DIV_EXPR:
967 op = "/=";
968 break;
970 case TRUNC_MOD_EXPR:
971 op = "%=";
972 break;
974 default:
975 op = get_tree_code_name (TREE_CODE (t));
976 break;
979 pp_cxx_ws_string (pp, op);
983 /* assignment-expression:
984 conditional-expression
985 logical-or-expression assignment-operator assignment-expression
986 throw-expression
988 throw-expression:
989 throw assignment-expression(opt)
991 assignment-operator: one of
992 = *= /= %= += -= >>= <<= &= ^= |= */
994 void
995 cxx_pretty_printer::assignment_expression (tree e)
997 switch (TREE_CODE (e))
999 case MODIFY_EXPR:
1000 case INIT_EXPR:
1001 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1002 pp_space (this);
1003 pp_equal (this);
1004 pp_space (this);
1005 assignment_expression (TREE_OPERAND (e, 1));
1006 break;
1008 case THROW_EXPR:
1009 pp_cxx_ws_string (this, "throw");
1010 if (TREE_OPERAND (e, 0))
1011 assignment_expression (TREE_OPERAND (e, 0));
1012 break;
1014 case MODOP_EXPR:
1015 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1016 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1017 assignment_expression (TREE_OPERAND (e, 2));
1018 break;
1020 default:
1021 conditional_expression (e);
1022 break;
1026 void
1027 cxx_pretty_printer::expression (tree t)
1029 switch (TREE_CODE (t))
1031 case STRING_CST:
1032 case VOID_CST:
1033 case INTEGER_CST:
1034 case REAL_CST:
1035 case COMPLEX_CST:
1036 constant (t);
1037 break;
1039 case USERDEF_LITERAL:
1040 pp_cxx_userdef_literal (this, t);
1041 break;
1043 case RESULT_DECL:
1044 pp_cxx_unqualified_id (this, t);
1045 break;
1047 #if 0
1048 case OFFSET_REF:
1049 #endif
1050 case SCOPE_REF:
1051 case PTRMEM_CST:
1052 pp_cxx_qualified_id (this, t);
1053 break;
1055 case OVERLOAD:
1056 t = OVL_CURRENT (t);
1057 case VAR_DECL:
1058 case PARM_DECL:
1059 case FIELD_DECL:
1060 case CONST_DECL:
1061 case FUNCTION_DECL:
1062 case BASELINK:
1063 case TEMPLATE_DECL:
1064 case TEMPLATE_TYPE_PARM:
1065 case TEMPLATE_PARM_INDEX:
1066 case TEMPLATE_TEMPLATE_PARM:
1067 case STMT_EXPR:
1068 case REQUIRES_EXPR:
1069 primary_expression (t);
1070 break;
1072 case CALL_EXPR:
1073 case DYNAMIC_CAST_EXPR:
1074 case STATIC_CAST_EXPR:
1075 case REINTERPRET_CAST_EXPR:
1076 case CONST_CAST_EXPR:
1077 #if 0
1078 case MEMBER_REF:
1079 #endif
1080 case EMPTY_CLASS_EXPR:
1081 case TYPEID_EXPR:
1082 case PSEUDO_DTOR_EXPR:
1083 case AGGR_INIT_EXPR:
1084 case ARROW_EXPR:
1085 postfix_expression (t);
1086 break;
1088 case NEW_EXPR:
1089 case VEC_NEW_EXPR:
1090 pp_cxx_new_expression (this, t);
1091 break;
1093 case DELETE_EXPR:
1094 case VEC_DELETE_EXPR:
1095 pp_cxx_delete_expression (this, t);
1096 break;
1098 case SIZEOF_EXPR:
1099 case ALIGNOF_EXPR:
1100 case NOEXCEPT_EXPR:
1101 unary_expression (t);
1102 break;
1104 case CAST_EXPR:
1105 case IMPLICIT_CONV_EXPR:
1106 pp_cxx_cast_expression (this, t);
1107 break;
1109 case OFFSET_REF:
1110 case MEMBER_REF:
1111 case DOTSTAR_EXPR:
1112 pp_cxx_pm_expression (this, t);
1113 break;
1115 case MULT_EXPR:
1116 case TRUNC_DIV_EXPR:
1117 case TRUNC_MOD_EXPR:
1118 multiplicative_expression (t);
1119 break;
1121 case COND_EXPR:
1122 conditional_expression (t);
1123 break;
1125 case MODIFY_EXPR:
1126 case INIT_EXPR:
1127 case THROW_EXPR:
1128 case MODOP_EXPR:
1129 assignment_expression (t);
1130 break;
1132 case NON_DEPENDENT_EXPR:
1133 case MUST_NOT_THROW_EXPR:
1134 expression (TREE_OPERAND (t, 0));
1135 break;
1137 case EXPR_PACK_EXPANSION:
1138 expression (PACK_EXPANSION_PATTERN (t));
1139 pp_cxx_ws_string (this, "...");
1140 break;
1142 case TEMPLATE_ID_EXPR:
1143 pp_cxx_template_id (this, t);
1144 break;
1146 case NONTYPE_ARGUMENT_PACK:
1148 tree args = ARGUMENT_PACK_ARGS (t);
1149 int i, len = TREE_VEC_LENGTH (args);
1150 for (i = 0; i < len; ++i)
1152 if (i > 0)
1153 pp_cxx_separate_with (this, ',');
1154 expression (TREE_VEC_ELT (args, i));
1157 break;
1159 case LAMBDA_EXPR:
1160 pp_cxx_ws_string (this, "<lambda>");
1161 break;
1163 case TRAIT_EXPR:
1164 pp_cxx_trait_expression (this, t);
1165 break;
1167 case PRED_CONSTR:
1168 case EXPR_CONSTR:
1169 case TYPE_CONSTR:
1170 case ICONV_CONSTR:
1171 case DEDUCT_CONSTR:
1172 case EXCEPT_CONSTR:
1173 case PARM_CONSTR:
1174 case CONJ_CONSTR:
1175 case DISJ_CONSTR:
1176 pp_cxx_constraint (this, t);
1177 break;
1179 case PAREN_EXPR:
1180 pp_cxx_left_paren (this);
1181 expression (TREE_OPERAND (t, 0));
1182 pp_cxx_right_paren (this);
1183 break;
1185 default:
1186 c_pretty_printer::expression (t);
1187 break;
1192 /* Declarations. */
1194 /* function-specifier:
1195 inline
1196 virtual
1197 explicit */
1199 void
1200 cxx_pretty_printer::function_specifier (tree t)
1202 switch (TREE_CODE (t))
1204 case FUNCTION_DECL:
1205 if (DECL_VIRTUAL_P (t))
1206 pp_cxx_ws_string (this, "virtual");
1207 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1208 pp_cxx_ws_string (this, "explicit");
1209 else
1210 c_pretty_printer::function_specifier (t);
1212 default:
1213 break;
1217 /* decl-specifier-seq:
1218 decl-specifier-seq(opt) decl-specifier
1220 decl-specifier:
1221 storage-class-specifier
1222 type-specifier
1223 function-specifier
1224 friend
1225 typedef */
1227 void
1228 cxx_pretty_printer::declaration_specifiers (tree t)
1230 switch (TREE_CODE (t))
1232 case VAR_DECL:
1233 case PARM_DECL:
1234 case CONST_DECL:
1235 case FIELD_DECL:
1236 storage_class_specifier (t);
1237 declaration_specifiers (TREE_TYPE (t));
1238 break;
1240 case TYPE_DECL:
1241 pp_cxx_ws_string (this, "typedef");
1242 declaration_specifiers (TREE_TYPE (t));
1243 break;
1245 case FUNCTION_DECL:
1246 /* Constructors don't have return types. And conversion functions
1247 do not have a type-specifier in their return types. */
1248 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1249 function_specifier (t);
1250 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1251 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1252 else
1253 default:
1254 c_pretty_printer::declaration_specifiers (t);
1255 break;
1259 /* simple-type-specifier:
1260 ::(opt) nested-name-specifier(opt) type-name
1261 ::(opt) nested-name-specifier(opt) template(opt) template-id
1262 char
1263 wchar_t
1264 bool
1265 short
1267 long
1268 signed
1269 unsigned
1270 float
1271 double
1272 void */
1274 void
1275 cxx_pretty_printer::simple_type_specifier (tree t)
1277 switch (TREE_CODE (t))
1279 case RECORD_TYPE:
1280 case UNION_TYPE:
1281 case ENUMERAL_TYPE:
1282 pp_cxx_qualified_id (this, t);
1283 break;
1285 case TEMPLATE_TYPE_PARM:
1286 case TEMPLATE_TEMPLATE_PARM:
1287 case TEMPLATE_PARM_INDEX:
1288 case BOUND_TEMPLATE_TEMPLATE_PARM:
1289 pp_cxx_unqualified_id (this, t);
1290 break;
1292 case TYPENAME_TYPE:
1293 pp_cxx_ws_string (this, "typename");
1294 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1295 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1296 break;
1298 default:
1299 c_pretty_printer::simple_type_specifier (t);
1300 break;
1304 /* type-specifier-seq:
1305 type-specifier type-specifier-seq(opt)
1307 type-specifier:
1308 simple-type-specifier
1309 class-specifier
1310 enum-specifier
1311 elaborated-type-specifier
1312 cv-qualifier */
1314 static void
1315 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1317 switch (TREE_CODE (t))
1319 case TEMPLATE_DECL:
1320 case TEMPLATE_TYPE_PARM:
1321 case TEMPLATE_TEMPLATE_PARM:
1322 case TYPE_DECL:
1323 case BOUND_TEMPLATE_TEMPLATE_PARM:
1324 pp_cxx_cv_qualifier_seq (pp, t);
1325 pp->simple_type_specifier (t);
1326 break;
1328 case METHOD_TYPE:
1329 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1330 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1331 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1332 break;
1334 case DECLTYPE_TYPE:
1335 pp_cxx_ws_string (pp, "decltype");
1336 pp_cxx_left_paren (pp);
1337 pp->expression (DECLTYPE_TYPE_EXPR (t));
1338 pp_cxx_right_paren (pp);
1339 break;
1341 case RECORD_TYPE:
1342 if (TYPE_PTRMEMFUNC_P (t))
1344 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1345 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1346 pp_cxx_whitespace (pp);
1347 pp_cxx_ptr_operator (pp, t);
1348 break;
1350 /* else fall through */
1352 default:
1353 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1354 pp_c_specifier_qualifier_list (pp, t);
1358 /* ptr-operator:
1359 * cv-qualifier-seq(opt)
1361 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1363 static void
1364 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1366 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1367 t = TREE_TYPE (t);
1368 switch (TREE_CODE (t))
1370 case REFERENCE_TYPE:
1371 case POINTER_TYPE:
1372 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1373 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1374 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1375 if (TYPE_PTR_P (t))
1377 pp_star (pp);
1378 pp_cxx_cv_qualifier_seq (pp, t);
1380 else
1381 pp_ampersand (pp);
1382 break;
1384 case RECORD_TYPE:
1385 if (TYPE_PTRMEMFUNC_P (t))
1387 pp_cxx_left_paren (pp);
1388 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1389 pp_star (pp);
1390 break;
1392 case OFFSET_TYPE:
1393 if (TYPE_PTRMEM_P (t))
1395 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1396 pp_cxx_left_paren (pp);
1397 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1398 pp_star (pp);
1399 pp_cxx_cv_qualifier_seq (pp, t);
1400 break;
1402 /* else fall through. */
1404 default:
1405 pp_unsupported_tree (pp, t);
1406 break;
1410 static inline tree
1411 pp_cxx_implicit_parameter_type (tree mf)
1413 return class_of_this_parm (TREE_TYPE (mf));
1417 parameter-declaration:
1418 decl-specifier-seq declarator
1419 decl-specifier-seq declarator = assignment-expression
1420 decl-specifier-seq abstract-declarator(opt)
1421 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1423 static inline void
1424 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1426 pp->declaration_specifiers (t);
1427 if (TYPE_P (t))
1428 pp->abstract_declarator (t);
1429 else
1430 pp->declarator (t);
1433 /* parameter-declaration-clause:
1434 parameter-declaration-list(opt) ...(opt)
1435 parameter-declaration-list , ...
1437 parameter-declaration-list:
1438 parameter-declaration
1439 parameter-declaration-list , parameter-declaration */
1441 static void
1442 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1444 tree args;
1445 tree types;
1446 bool abstract;
1448 // For a requires clause or the explicit printing of a parameter list
1449 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1450 // args and types are taken from the function decl T.
1451 if (TREE_CODE (t) == PARM_DECL)
1453 args = t;
1454 types = t;
1455 abstract = false;
1457 else
1459 bool type_p = TYPE_P (t);
1460 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1461 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1462 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1464 bool first = true;
1466 /* Skip artificial parameter for nonstatic member functions. */
1467 if (TREE_CODE (t) == METHOD_TYPE)
1468 types = TREE_CHAIN (types);
1470 pp_cxx_left_paren (pp);
1471 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1473 if (!first)
1474 pp_cxx_separate_with (pp, ',');
1475 first = false;
1476 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1477 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1479 pp_cxx_whitespace (pp);
1480 pp_equal (pp);
1481 pp_cxx_whitespace (pp);
1482 pp->assignment_expression (TREE_PURPOSE (types));
1485 pp_cxx_right_paren (pp);
1488 /* exception-specification:
1489 throw ( type-id-list(opt) )
1491 type-id-list
1492 type-id
1493 type-id-list , type-id */
1495 static void
1496 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1498 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1499 bool need_comma = false;
1501 if (ex_spec == NULL)
1502 return;
1503 if (TREE_PURPOSE (ex_spec))
1505 pp_cxx_ws_string (pp, "noexcept");
1506 pp_cxx_whitespace (pp);
1507 pp_cxx_left_paren (pp);
1508 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1509 pp_cxx_ws_string (pp, "<uninstantiated>");
1510 else
1511 pp->expression (TREE_PURPOSE (ex_spec));
1512 pp_cxx_right_paren (pp);
1513 return;
1515 pp_cxx_ws_string (pp, "throw");
1516 pp_cxx_left_paren (pp);
1517 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1519 tree type = TREE_VALUE (ex_spec);
1520 tree argpack = NULL_TREE;
1521 int i, len = 1;
1523 if (ARGUMENT_PACK_P (type))
1525 argpack = ARGUMENT_PACK_ARGS (type);
1526 len = TREE_VEC_LENGTH (argpack);
1529 for (i = 0; i < len; ++i)
1531 if (argpack)
1532 type = TREE_VEC_ELT (argpack, i);
1534 if (need_comma)
1535 pp_cxx_separate_with (pp, ',');
1536 else
1537 need_comma = true;
1539 pp->type_id (type);
1542 pp_cxx_right_paren (pp);
1545 /* direct-declarator:
1546 declarator-id
1547 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1548 exception-specification(opt)
1549 direct-declaration [ constant-expression(opt) ]
1550 ( declarator ) */
1552 void
1553 cxx_pretty_printer::direct_declarator (tree t)
1555 switch (TREE_CODE (t))
1557 case VAR_DECL:
1558 case PARM_DECL:
1559 case CONST_DECL:
1560 case FIELD_DECL:
1561 if (DECL_NAME (t))
1563 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1565 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1566 || template_parameter_pack_p (t))
1567 /* A function parameter pack or non-type template
1568 parameter pack. */
1569 pp_cxx_ws_string (this, "...");
1571 id_expression (DECL_NAME (t));
1573 abstract_declarator (TREE_TYPE (t));
1574 break;
1576 case FUNCTION_DECL:
1577 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1578 expression (t);
1579 pp_cxx_parameter_declaration_clause (this, t);
1581 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1583 padding = pp_before;
1584 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1587 pp_cxx_exception_specification (this, TREE_TYPE (t));
1588 break;
1590 case TYPENAME_TYPE:
1591 case TEMPLATE_DECL:
1592 case TEMPLATE_TYPE_PARM:
1593 case TEMPLATE_PARM_INDEX:
1594 case TEMPLATE_TEMPLATE_PARM:
1595 break;
1597 default:
1598 c_pretty_printer::direct_declarator (t);
1599 break;
1603 /* declarator:
1604 direct-declarator
1605 ptr-operator declarator */
1607 void
1608 cxx_pretty_printer::declarator (tree t)
1610 direct_declarator (t);
1612 // Print a requires clause.
1613 if (flag_concepts)
1614 if (tree ci = get_constraints (t))
1615 if (tree reqs = CI_DECLARATOR_REQS (ci))
1616 pp_cxx_requires_clause (this, reqs);
1619 /* ctor-initializer:
1620 : mem-initializer-list
1622 mem-initializer-list:
1623 mem-initializer
1624 mem-initializer , mem-initializer-list
1626 mem-initializer:
1627 mem-initializer-id ( expression-list(opt) )
1629 mem-initializer-id:
1630 ::(opt) nested-name-specifier(opt) class-name
1631 identifier */
1633 static void
1634 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1636 t = TREE_OPERAND (t, 0);
1637 pp_cxx_whitespace (pp);
1638 pp_colon (pp);
1639 pp_cxx_whitespace (pp);
1640 for (; t; t = TREE_CHAIN (t))
1642 tree purpose = TREE_PURPOSE (t);
1643 bool is_pack = PACK_EXPANSION_P (purpose);
1645 if (is_pack)
1646 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1647 else
1648 pp->primary_expression (purpose);
1649 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1650 if (is_pack)
1651 pp_cxx_ws_string (pp, "...");
1652 if (TREE_CHAIN (t))
1653 pp_cxx_separate_with (pp, ',');
1657 /* function-definition:
1658 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1659 decl-specifier-seq(opt) declarator function-try-block */
1661 static void
1662 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1664 tree saved_scope = pp->enclosing_scope;
1665 pp->declaration_specifiers (t);
1666 pp->declarator (t);
1667 pp_needs_newline (pp) = true;
1668 pp->enclosing_scope = DECL_CONTEXT (t);
1669 if (DECL_SAVED_TREE (t))
1670 pp->statement (DECL_SAVED_TREE (t));
1671 else
1672 pp_cxx_semicolon (pp);
1673 pp_newline_and_flush (pp);
1674 pp->enclosing_scope = saved_scope;
1677 /* abstract-declarator:
1678 ptr-operator abstract-declarator(opt)
1679 direct-abstract-declarator */
1681 void
1682 cxx_pretty_printer::abstract_declarator (tree t)
1684 if (TYPE_PTRMEM_P (t))
1685 pp_cxx_right_paren (this);
1686 else if (POINTER_TYPE_P (t))
1688 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1689 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1690 pp_cxx_right_paren (this);
1691 t = TREE_TYPE (t);
1693 direct_abstract_declarator (t);
1696 /* direct-abstract-declarator:
1697 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1698 cv-qualifier-seq(opt) exception-specification(opt)
1699 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1700 ( abstract-declarator ) */
1702 void
1703 cxx_pretty_printer::direct_abstract_declarator (tree t)
1705 switch (TREE_CODE (t))
1707 case REFERENCE_TYPE:
1708 abstract_declarator (t);
1709 break;
1711 case RECORD_TYPE:
1712 if (TYPE_PTRMEMFUNC_P (t))
1713 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1714 break;
1716 case METHOD_TYPE:
1717 case FUNCTION_TYPE:
1718 pp_cxx_parameter_declaration_clause (this, t);
1719 direct_abstract_declarator (TREE_TYPE (t));
1720 if (TREE_CODE (t) == METHOD_TYPE)
1722 padding = pp_before;
1723 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1725 pp_cxx_exception_specification (this, t);
1726 break;
1728 case TYPENAME_TYPE:
1729 case TEMPLATE_TYPE_PARM:
1730 case TEMPLATE_TEMPLATE_PARM:
1731 case BOUND_TEMPLATE_TEMPLATE_PARM:
1732 case UNBOUND_CLASS_TEMPLATE:
1733 break;
1735 default:
1736 c_pretty_printer::direct_abstract_declarator (t);
1737 break;
1741 /* type-id:
1742 type-specifier-seq abstract-declarator(opt) */
1744 void
1745 cxx_pretty_printer::type_id (tree t)
1747 pp_flags saved_flags = flags;
1748 flags |= pp_c_flag_abstract;
1750 switch (TREE_CODE (t))
1752 case TYPE_DECL:
1753 case UNION_TYPE:
1754 case RECORD_TYPE:
1755 case ENUMERAL_TYPE:
1756 case TYPENAME_TYPE:
1757 case BOUND_TEMPLATE_TEMPLATE_PARM:
1758 case UNBOUND_CLASS_TEMPLATE:
1759 case TEMPLATE_TEMPLATE_PARM:
1760 case TEMPLATE_TYPE_PARM:
1761 case TEMPLATE_PARM_INDEX:
1762 case TEMPLATE_DECL:
1763 case TYPEOF_TYPE:
1764 case UNDERLYING_TYPE:
1765 case DECLTYPE_TYPE:
1766 case TEMPLATE_ID_EXPR:
1767 pp_cxx_type_specifier_seq (this, t);
1768 break;
1770 case TYPE_PACK_EXPANSION:
1771 type_id (PACK_EXPANSION_PATTERN (t));
1772 pp_cxx_ws_string (this, "...");
1773 break;
1775 default:
1776 c_pretty_printer::type_id (t);
1777 break;
1780 flags = saved_flags;
1783 /* template-argument-list:
1784 template-argument ...(opt)
1785 template-argument-list, template-argument ...(opt)
1787 template-argument:
1788 assignment-expression
1789 type-id
1790 template-name */
1792 static void
1793 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1795 int i;
1796 bool need_comma = false;
1798 if (t == NULL)
1799 return;
1800 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1802 tree arg = TREE_VEC_ELT (t, i);
1803 tree argpack = NULL_TREE;
1804 int idx, len = 1;
1806 if (ARGUMENT_PACK_P (arg))
1808 argpack = ARGUMENT_PACK_ARGS (arg);
1809 len = TREE_VEC_LENGTH (argpack);
1812 for (idx = 0; idx < len; idx++)
1814 if (argpack)
1815 arg = TREE_VEC_ELT (argpack, idx);
1817 if (need_comma)
1818 pp_cxx_separate_with (pp, ',');
1819 else
1820 need_comma = true;
1822 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1823 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1824 pp->type_id (arg);
1825 else
1826 pp->expression (arg);
1832 static void
1833 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1835 t = DECL_EXPR_DECL (t);
1836 pp_cxx_type_specifier_seq (pp, t);
1837 if (TYPE_P (t))
1838 pp->abstract_declarator (t);
1839 else
1840 pp->declarator (t);
1843 /* Statements. */
1845 void
1846 cxx_pretty_printer::statement (tree t)
1848 switch (TREE_CODE (t))
1850 case CTOR_INITIALIZER:
1851 pp_cxx_ctor_initializer (this, t);
1852 break;
1854 case USING_STMT:
1855 pp_cxx_ws_string (this, "using");
1856 pp_cxx_ws_string (this, "namespace");
1857 if (DECL_CONTEXT (t))
1858 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1859 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1860 break;
1862 case USING_DECL:
1863 pp_cxx_ws_string (this, "using");
1864 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1865 pp_cxx_unqualified_id (this, DECL_NAME (t));
1866 break;
1868 case EH_SPEC_BLOCK:
1869 break;
1871 /* try-block:
1872 try compound-statement handler-seq */
1873 case TRY_BLOCK:
1874 pp_maybe_newline_and_indent (this, 0);
1875 pp_cxx_ws_string (this, "try");
1876 pp_newline_and_indent (this, 3);
1877 statement (TRY_STMTS (t));
1878 pp_newline_and_indent (this, -3);
1879 if (CLEANUP_P (t))
1881 else
1882 statement (TRY_HANDLERS (t));
1883 break;
1886 handler-seq:
1887 handler handler-seq(opt)
1889 handler:
1890 catch ( exception-declaration ) compound-statement
1892 exception-declaration:
1893 type-specifier-seq declarator
1894 type-specifier-seq abstract-declarator
1895 ... */
1896 case HANDLER:
1897 pp_cxx_ws_string (this, "catch");
1898 pp_cxx_left_paren (this);
1899 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1900 pp_cxx_right_paren (this);
1901 pp_indentation (this) += 3;
1902 pp_needs_newline (this) = true;
1903 statement (HANDLER_BODY (t));
1904 pp_indentation (this) -= 3;
1905 pp_needs_newline (this) = true;
1906 break;
1908 /* selection-statement:
1909 if ( expression ) statement
1910 if ( expression ) statement else statement */
1911 case IF_STMT:
1912 pp_cxx_ws_string (this, "if");
1913 pp_cxx_whitespace (this);
1914 pp_cxx_left_paren (this);
1915 expression (IF_COND (t));
1916 pp_cxx_right_paren (this);
1917 pp_newline_and_indent (this, 2);
1918 statement (THEN_CLAUSE (t));
1919 pp_newline_and_indent (this, -2);
1920 if (ELSE_CLAUSE (t))
1922 tree else_clause = ELSE_CLAUSE (t);
1923 pp_cxx_ws_string (this, "else");
1924 if (TREE_CODE (else_clause) == IF_STMT)
1925 pp_cxx_whitespace (this);
1926 else
1927 pp_newline_and_indent (this, 2);
1928 statement (else_clause);
1929 if (TREE_CODE (else_clause) != IF_STMT)
1930 pp_newline_and_indent (this, -2);
1932 break;
1934 case SWITCH_STMT:
1935 pp_cxx_ws_string (this, "switch");
1936 pp_space (this);
1937 pp_cxx_left_paren (this);
1938 expression (SWITCH_STMT_COND (t));
1939 pp_cxx_right_paren (this);
1940 pp_indentation (this) += 3;
1941 pp_needs_newline (this) = true;
1942 statement (SWITCH_STMT_BODY (t));
1943 pp_newline_and_indent (this, -3);
1944 break;
1946 /* iteration-statement:
1947 while ( expression ) statement
1948 do statement while ( expression ) ;
1949 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1950 for ( declaration expression(opt) ; expression(opt) ) statement */
1951 case WHILE_STMT:
1952 pp_cxx_ws_string (this, "while");
1953 pp_space (this);
1954 pp_cxx_left_paren (this);
1955 expression (WHILE_COND (t));
1956 pp_cxx_right_paren (this);
1957 pp_newline_and_indent (this, 3);
1958 statement (WHILE_BODY (t));
1959 pp_indentation (this) -= 3;
1960 pp_needs_newline (this) = true;
1961 break;
1963 case DO_STMT:
1964 pp_cxx_ws_string (this, "do");
1965 pp_newline_and_indent (this, 3);
1966 statement (DO_BODY (t));
1967 pp_newline_and_indent (this, -3);
1968 pp_cxx_ws_string (this, "while");
1969 pp_space (this);
1970 pp_cxx_left_paren (this);
1971 expression (DO_COND (t));
1972 pp_cxx_right_paren (this);
1973 pp_cxx_semicolon (this);
1974 pp_needs_newline (this) = true;
1975 break;
1977 case FOR_STMT:
1978 pp_cxx_ws_string (this, "for");
1979 pp_space (this);
1980 pp_cxx_left_paren (this);
1981 if (FOR_INIT_STMT (t))
1982 statement (FOR_INIT_STMT (t));
1983 else
1984 pp_cxx_semicolon (this);
1985 pp_needs_newline (this) = false;
1986 pp_cxx_whitespace (this);
1987 if (FOR_COND (t))
1988 expression (FOR_COND (t));
1989 pp_cxx_semicolon (this);
1990 pp_needs_newline (this) = false;
1991 pp_cxx_whitespace (this);
1992 if (FOR_EXPR (t))
1993 expression (FOR_EXPR (t));
1994 pp_cxx_right_paren (this);
1995 pp_newline_and_indent (this, 3);
1996 statement (FOR_BODY (t));
1997 pp_indentation (this) -= 3;
1998 pp_needs_newline (this) = true;
1999 break;
2001 case RANGE_FOR_STMT:
2002 pp_cxx_ws_string (this, "for");
2003 pp_space (this);
2004 pp_cxx_left_paren (this);
2005 statement (RANGE_FOR_DECL (t));
2006 pp_space (this);
2007 pp_needs_newline (this) = false;
2008 pp_colon (this);
2009 pp_space (this);
2010 statement (RANGE_FOR_EXPR (t));
2011 pp_cxx_right_paren (this);
2012 pp_newline_and_indent (this, 3);
2013 statement (FOR_BODY (t));
2014 pp_indentation (this) -= 3;
2015 pp_needs_newline (this) = true;
2016 break;
2018 /* jump-statement:
2019 goto identifier;
2020 continue ;
2021 return expression(opt) ; */
2022 case BREAK_STMT:
2023 case CONTINUE_STMT:
2024 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2025 pp_cxx_semicolon (this);
2026 pp_needs_newline (this) = true;
2027 break;
2029 /* expression-statement:
2030 expression(opt) ; */
2031 case EXPR_STMT:
2032 expression (EXPR_STMT_EXPR (t));
2033 pp_cxx_semicolon (this);
2034 pp_needs_newline (this) = true;
2035 break;
2037 case CLEANUP_STMT:
2038 pp_cxx_ws_string (this, "try");
2039 pp_newline_and_indent (this, 2);
2040 statement (CLEANUP_BODY (t));
2041 pp_newline_and_indent (this, -2);
2042 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2043 pp_newline_and_indent (this, 2);
2044 statement (CLEANUP_EXPR (t));
2045 pp_newline_and_indent (this, -2);
2046 break;
2048 case STATIC_ASSERT:
2049 declaration (t);
2050 break;
2052 default:
2053 c_pretty_printer::statement (t);
2054 break;
2058 /* original-namespace-definition:
2059 namespace identifier { namespace-body }
2061 As an edge case, we also handle unnamed namespace definition here. */
2063 static void
2064 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2066 pp_cxx_ws_string (pp, "namespace");
2067 if (DECL_CONTEXT (t))
2068 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2069 if (DECL_NAME (t))
2070 pp_cxx_unqualified_id (pp, t);
2071 pp_cxx_whitespace (pp);
2072 pp_cxx_left_brace (pp);
2073 /* We do not print the namespace-body. */
2074 pp_cxx_whitespace (pp);
2075 pp_cxx_right_brace (pp);
2078 /* namespace-alias:
2079 identifier
2081 namespace-alias-definition:
2082 namespace identifier = qualified-namespace-specifier ;
2084 qualified-namespace-specifier:
2085 ::(opt) nested-name-specifier(opt) namespace-name */
2087 static void
2088 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2090 pp_cxx_ws_string (pp, "namespace");
2091 if (DECL_CONTEXT (t))
2092 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2093 pp_cxx_unqualified_id (pp, t);
2094 pp_cxx_whitespace (pp);
2095 pp_equal (pp);
2096 pp_cxx_whitespace (pp);
2097 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2098 pp_cxx_nested_name_specifier (pp,
2099 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2100 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2101 pp_cxx_semicolon (pp);
2104 /* simple-declaration:
2105 decl-specifier-seq(opt) init-declarator-list(opt) */
2107 static void
2108 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2110 pp->declaration_specifiers (t);
2111 pp_cxx_init_declarator (pp, t);
2112 pp_cxx_semicolon (pp);
2113 pp_needs_newline (pp) = true;
2117 template-parameter-list:
2118 template-parameter
2119 template-parameter-list , template-parameter */
2121 static inline void
2122 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2124 const int n = TREE_VEC_LENGTH (t);
2125 int i;
2126 for (i = 0; i < n; ++i)
2128 if (i)
2129 pp_cxx_separate_with (pp, ',');
2130 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2134 /* template-parameter:
2135 type-parameter
2136 parameter-declaration
2138 type-parameter:
2139 class ...(opt) identifier(opt)
2140 class identifier(opt) = type-id
2141 typename identifier(opt)
2142 typename ...(opt) identifier(opt) = type-id
2143 template < template-parameter-list > class ...(opt) identifier(opt)
2144 template < template-parameter-list > class identifier(opt) = template-name */
2146 static void
2147 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2149 tree parameter = TREE_VALUE (t);
2150 switch (TREE_CODE (parameter))
2152 case TYPE_DECL:
2153 pp_cxx_ws_string (pp, "class");
2154 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2155 pp_cxx_ws_string (pp, "...");
2156 if (DECL_NAME (parameter))
2157 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2158 /* FIXME: Check if we should print also default argument. */
2159 break;
2161 case PARM_DECL:
2162 pp_cxx_parameter_declaration (pp, parameter);
2163 break;
2165 case TEMPLATE_DECL:
2166 break;
2168 default:
2169 pp_unsupported_tree (pp, t);
2170 break;
2174 /* Pretty-print a template parameter in the canonical form
2175 "template-parameter-<level>-<position in parameter list>". */
2177 void
2178 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2180 const enum tree_code code = TREE_CODE (parm);
2182 /* Brings type template parameters to the canonical forms. */
2183 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2184 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2185 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2187 pp_cxx_begin_template_argument_list (pp);
2188 pp->translate_string ("template-parameter-");
2189 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2190 pp_minus (pp);
2191 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2192 pp_cxx_end_template_argument_list (pp);
2195 /* Print a constrained-type-specifier. */
2197 void
2198 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2200 tree t, a;
2201 placeholder_extract_concept_and_args (c, t, a);
2202 pp->id_expression (t);
2203 if (TREE_VEC_LENGTH (a) > 1)
2205 pp_cxx_begin_template_argument_list (pp);
2206 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2207 for (int i = TREE_VEC_LENGTH (a) - 1; i > 0; --i)
2208 TREE_VEC_ELT (args, i-1) = TREE_VEC_ELT (a, i);
2209 pp_cxx_template_argument_list (pp, args);
2210 ggc_free (args);
2211 pp_cxx_end_template_argument_list (pp);
2216 template-declaration:
2217 export(opt) template < template-parameter-list > declaration
2219 Concept extensions:
2221 template-declaration:
2222 export(opt) template < template-parameter-list >
2223 requires-clause(opt) declaration */
2225 static void
2226 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2228 tree tmpl = most_general_template (t);
2229 tree level;
2231 pp_maybe_newline_and_indent (pp, 0);
2232 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2234 pp_cxx_ws_string (pp, "template");
2235 pp_cxx_begin_template_argument_list (pp);
2236 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2237 pp_cxx_end_template_argument_list (pp);
2238 pp_newline_and_indent (pp, 3);
2241 if (flag_concepts)
2242 if (tree ci = get_constraints (t))
2243 if (tree reqs = CI_TEMPLATE_REQS (ci))
2245 pp_cxx_requires_clause (pp, reqs);
2246 pp_newline_and_indent (pp, 6);
2249 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2250 pp_cxx_function_definition (pp, t);
2251 else
2252 pp_cxx_simple_declaration (pp, t);
2255 static void
2256 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2258 pp_unsupported_tree (pp, t);
2261 static void
2262 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2264 pp_unsupported_tree (pp, t);
2268 declaration:
2269 block-declaration
2270 function-definition
2271 template-declaration
2272 explicit-instantiation
2273 explicit-specialization
2274 linkage-specification
2275 namespace-definition
2277 block-declaration:
2278 simple-declaration
2279 asm-definition
2280 namespace-alias-definition
2281 using-declaration
2282 using-directive
2283 static_assert-declaration */
2284 void
2285 cxx_pretty_printer::declaration (tree t)
2287 if (TREE_CODE (t) == STATIC_ASSERT)
2289 pp_cxx_ws_string (this, "static_assert");
2290 pp_cxx_left_paren (this);
2291 expression (STATIC_ASSERT_CONDITION (t));
2292 pp_cxx_separate_with (this, ',');
2293 expression (STATIC_ASSERT_MESSAGE (t));
2294 pp_cxx_right_paren (this);
2296 else if (!DECL_LANG_SPECIFIC (t))
2297 pp_cxx_simple_declaration (this, t);
2298 else if (DECL_USE_TEMPLATE (t))
2299 switch (DECL_USE_TEMPLATE (t))
2301 case 1:
2302 pp_cxx_template_declaration (this, t);
2303 break;
2305 case 2:
2306 pp_cxx_explicit_specialization (this, t);
2307 break;
2309 case 3:
2310 pp_cxx_explicit_instantiation (this, t);
2311 break;
2313 default:
2314 break;
2316 else switch (TREE_CODE (t))
2318 case VAR_DECL:
2319 case TYPE_DECL:
2320 pp_cxx_simple_declaration (this, t);
2321 break;
2323 case FUNCTION_DECL:
2324 if (DECL_SAVED_TREE (t))
2325 pp_cxx_function_definition (this, t);
2326 else
2327 pp_cxx_simple_declaration (this, t);
2328 break;
2330 case NAMESPACE_DECL:
2331 if (DECL_NAMESPACE_ALIAS (t))
2332 pp_cxx_namespace_alias_definition (this, t);
2333 else
2334 pp_cxx_original_namespace_definition (this, t);
2335 break;
2337 default:
2338 pp_unsupported_tree (this, t);
2339 break;
2343 static void
2344 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2346 t = TREE_OPERAND (t, 0);
2347 pp_cxx_ws_string (pp, "typeid");
2348 pp_cxx_left_paren (pp);
2349 if (TYPE_P (t))
2350 pp->type_id (t);
2351 else
2352 pp->expression (t);
2353 pp_cxx_right_paren (pp);
2356 void
2357 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2359 pp_cxx_ws_string (pp, "va_arg");
2360 pp_cxx_left_paren (pp);
2361 pp->assignment_expression (TREE_OPERAND (t, 0));
2362 pp_cxx_separate_with (pp, ',');
2363 pp->type_id (TREE_TYPE (t));
2364 pp_cxx_right_paren (pp);
2367 static bool
2368 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2370 switch (TREE_CODE (t))
2372 case ARROW_EXPR:
2373 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2374 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2376 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2377 pp_cxx_separate_with (pp, ',');
2378 return true;
2380 return false;
2381 case COMPONENT_REF:
2382 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2383 return false;
2384 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2385 pp_cxx_dot (pp);
2386 pp->expression (TREE_OPERAND (t, 1));
2387 return true;
2388 case ARRAY_REF:
2389 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2390 return false;
2391 pp_left_bracket (pp);
2392 pp->expression (TREE_OPERAND (t, 1));
2393 pp_right_bracket (pp);
2394 return true;
2395 default:
2396 return false;
2400 void
2401 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2403 pp_cxx_ws_string (pp, "offsetof");
2404 pp_cxx_left_paren (pp);
2405 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2406 pp->expression (TREE_OPERAND (t, 0));
2407 pp_cxx_right_paren (pp);
2410 void
2411 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2413 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2415 switch (kind)
2417 case CPTK_HAS_NOTHROW_ASSIGN:
2418 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2419 break;
2420 case CPTK_HAS_TRIVIAL_ASSIGN:
2421 pp_cxx_ws_string (pp, "__has_trivial_assign");
2422 break;
2423 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2424 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2425 break;
2426 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2427 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2428 break;
2429 case CPTK_HAS_NOTHROW_COPY:
2430 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2431 break;
2432 case CPTK_HAS_TRIVIAL_COPY:
2433 pp_cxx_ws_string (pp, "__has_trivial_copy");
2434 break;
2435 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2436 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2437 break;
2438 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2439 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2440 break;
2441 case CPTK_IS_ABSTRACT:
2442 pp_cxx_ws_string (pp, "__is_abstract");
2443 break;
2444 case CPTK_IS_BASE_OF:
2445 pp_cxx_ws_string (pp, "__is_base_of");
2446 break;
2447 case CPTK_IS_CLASS:
2448 pp_cxx_ws_string (pp, "__is_class");
2449 break;
2450 case CPTK_IS_EMPTY:
2451 pp_cxx_ws_string (pp, "__is_empty");
2452 break;
2453 case CPTK_IS_ENUM:
2454 pp_cxx_ws_string (pp, "__is_enum");
2455 break;
2456 case CPTK_IS_FINAL:
2457 pp_cxx_ws_string (pp, "__is_final");
2458 break;
2459 case CPTK_IS_POD:
2460 pp_cxx_ws_string (pp, "__is_pod");
2461 break;
2462 case CPTK_IS_POLYMORPHIC:
2463 pp_cxx_ws_string (pp, "__is_polymorphic");
2464 break;
2465 case CPTK_IS_SAME_AS:
2466 pp_cxx_ws_string (pp, "__is_same_as");
2467 break;
2468 case CPTK_IS_STD_LAYOUT:
2469 pp_cxx_ws_string (pp, "__is_std_layout");
2470 break;
2471 case CPTK_IS_TRIVIAL:
2472 pp_cxx_ws_string (pp, "__is_trivial");
2473 break;
2474 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2475 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2476 break;
2477 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2478 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2479 break;
2480 case CPTK_IS_TRIVIALLY_COPYABLE:
2481 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2482 break;
2483 case CPTK_IS_UNION:
2484 pp_cxx_ws_string (pp, "__is_union");
2485 break;
2486 case CPTK_IS_LITERAL_TYPE:
2487 pp_cxx_ws_string (pp, "__is_literal_type");
2488 break;
2490 default:
2491 gcc_unreachable ();
2494 pp_cxx_left_paren (pp);
2495 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2497 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2499 pp_cxx_separate_with (pp, ',');
2500 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2503 pp_cxx_right_paren (pp);
2506 // requires-clause:
2507 // 'requires' logical-or-expression
2508 void
2509 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2511 if (!t)
2512 return;
2513 pp->padding = pp_before;
2514 pp_cxx_ws_string (pp, "requires");
2515 pp_space (pp);
2516 pp->expression (t);
2519 /* requirement:
2520 simple-requirement
2521 compound-requirement
2522 type-requirement
2523 nested-requirement */
2524 static void
2525 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2527 switch (TREE_CODE (t))
2529 case SIMPLE_REQ:
2530 pp_cxx_simple_requirement (pp, t);
2531 break;
2533 case TYPE_REQ:
2534 pp_cxx_type_requirement (pp, t);
2535 break;
2537 case COMPOUND_REQ:
2538 pp_cxx_compound_requirement (pp, t);
2539 break;
2541 case NESTED_REQ:
2542 pp_cxx_nested_requirement (pp, t);
2543 break;
2545 default:
2546 gcc_unreachable ();
2550 // requirement-list:
2551 // requirement
2552 // requirement-list ';' requirement[opt]
2554 static void
2555 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2557 for (; t; t = TREE_CHAIN (t))
2558 pp_cxx_requirement (pp, TREE_VALUE (t));
2561 // requirement-body:
2562 // '{' requirement-list '}'
2563 static void
2564 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2566 pp_cxx_left_brace (pp);
2567 pp_cxx_requirement_list (pp, t);
2568 pp_cxx_right_brace (pp);
2571 // requires-expression:
2572 // 'requires' requirement-parameter-list requirement-body
2573 void
2574 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2576 pp_string (pp, "requires");
2577 if (tree parms = TREE_OPERAND (t, 0))
2579 pp_cxx_parameter_declaration_clause (pp, parms);
2580 pp_cxx_whitespace (pp);
2582 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2585 /* simple-requirement:
2586 expression ';' */
2587 void
2588 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2590 pp->expression (TREE_OPERAND (t, 0));
2591 pp_cxx_semicolon (pp);
2594 /* type-requirement:
2595 typename type-name ';' */
2596 void
2597 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2599 pp->type_id (TREE_OPERAND (t, 0));
2600 pp_cxx_semicolon (pp);
2603 /* compound-requirement:
2604 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2605 void
2606 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2608 pp_cxx_left_brace (pp);
2609 pp->expression (TREE_OPERAND (t, 0));
2610 pp_cxx_right_brace (pp);
2612 if (COMPOUND_REQ_NOEXCEPT_P (t))
2613 pp_cxx_ws_string (pp, "noexcept");
2615 if (tree type = TREE_OPERAND (t, 1))
2617 pp_cxx_ws_string (pp, "->");
2618 pp->type_id (type);
2622 /* nested requirement:
2623 'requires' constraint-expression */
2624 void
2625 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2627 pp_cxx_ws_string (pp, "requires");
2628 pp->expression (TREE_OPERAND (t, 0));
2629 pp_cxx_semicolon (pp);
2632 void
2633 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2635 pp_string (pp, "predicate");
2636 pp_left_paren (pp);
2637 pp->expression (TREE_OPERAND (t, 0));
2638 pp_right_paren (pp);
2641 void
2642 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2644 pp_string (pp, "valid_expr");
2645 pp_left_paren (pp);
2646 pp->expression (TREE_OPERAND (t, 0));
2647 pp_right_paren (pp);
2650 void
2651 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2653 pp_string (pp, "valid_type");
2654 pp_left_paren (pp);
2655 pp->type_id (TREE_OPERAND (t, 0));
2656 pp_right_paren (pp);
2659 void
2660 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2662 pp_string (pp, "convertible");
2663 pp_left_paren (pp);
2664 pp->expression (ICONV_CONSTR_EXPR (t));
2665 pp_cxx_separate_with (pp, ',');
2666 pp->expression (ICONV_CONSTR_TYPE (t));
2667 pp_right_paren (pp);
2670 void
2671 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2673 pp_string (pp, "deducible");
2674 pp_left_paren (pp);
2675 pp->expression (DEDUCT_CONSTR_EXPR (t));
2676 pp_cxx_separate_with (pp, ',');
2677 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2678 pp_right_paren (pp);
2681 void
2682 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2684 pp_cxx_ws_string (pp, "noexcept");
2685 pp_left_paren (pp);
2686 pp->expression (TREE_OPERAND (t, 0));
2687 pp_right_paren (pp);
2690 void
2691 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2693 pp_left_paren (pp);
2694 pp_string (pp, "forall");
2695 if (tree parms = PARM_CONSTR_PARMS (t))
2697 if (parms)
2698 pp_cxx_parameter_declaration_clause (pp, parms);
2699 pp_cxx_whitespace (pp);
2701 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2702 pp_right_paren (pp);
2705 void
2706 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2708 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2709 pp_string (pp, " and ");
2710 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2713 void
2714 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2716 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2717 pp_string (pp, " or ");
2718 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2721 void
2722 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2724 if (t == error_mark_node)
2725 return pp->expression (t);
2727 switch (TREE_CODE (t))
2729 case PRED_CONSTR:
2730 pp_cxx_predicate_constraint (pp, t);
2731 break;
2733 case EXPR_CONSTR:
2734 pp_cxx_expression_constraint (pp, t);
2735 break;
2737 case TYPE_CONSTR:
2738 pp_cxx_type_constraint (pp, t);
2739 break;
2741 case ICONV_CONSTR:
2742 pp_cxx_implicit_conversion_constraint (pp, t);
2743 break;
2745 case DEDUCT_CONSTR:
2746 pp_cxx_argument_deduction_constraint (pp, t);
2747 break;
2749 case EXCEPT_CONSTR:
2750 pp_cxx_exception_constraint (pp, t);
2751 break;
2753 case PARM_CONSTR:
2754 pp_cxx_parameterized_constraint (pp, t);
2755 break;
2757 case CONJ_CONSTR:
2758 pp_cxx_conjunction (pp, t);
2759 break;
2761 case DISJ_CONSTR:
2762 pp_cxx_disjunction (pp, t);
2763 break;
2765 default:
2766 gcc_unreachable ();
2772 typedef c_pretty_print_fn pp_fun;
2774 /* Initialization of a C++ pretty-printer object. */
2776 cxx_pretty_printer::cxx_pretty_printer ()
2777 : c_pretty_printer (),
2778 enclosing_scope (global_namespace)
2780 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2781 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;