Merge from trunk
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blobcf7e1c747ba7568d80703ee5f88fd542b478e363
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2014 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 "tm.h"
25 #include "intl.h"
26 #include "cp-tree.h"
27 #include "cxx-pretty-print.h"
28 #include "tree-pretty-print.h"
30 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
32 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
33 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
34 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
35 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
36 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
37 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
38 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
41 static inline void
42 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
44 const char *p = pp_last_position_in_text (pp);
46 if (p != NULL && *p == c)
47 pp_cxx_whitespace (pp);
48 pp_character (pp, c);
49 pp->padding = pp_none;
52 #define pp_cxx_expression_list(PP, T) \
53 pp_c_expression_list (PP, T)
54 #define pp_cxx_space_for_pointer_operator(PP, T) \
55 pp_c_space_for_pointer_operator (PP, T)
56 #define pp_cxx_init_declarator(PP, T) \
57 pp_c_init_declarator (PP, T)
58 #define pp_cxx_call_argument_list(PP, T) \
59 pp_c_call_argument_list (PP, T)
61 void
62 pp_cxx_colon_colon (cxx_pretty_printer *pp)
64 pp_colon_colon (pp);
65 pp->padding = pp_none;
68 void
69 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
71 pp_cxx_nonconsecutive_character (pp, '<');
74 void
75 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
77 pp_cxx_nonconsecutive_character (pp, '>');
80 void
81 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
83 pp_separate_with (pp, c);
84 pp->padding = pp_none;
87 /* Expressions. */
89 static inline bool
90 is_destructor_name (tree name)
92 return name == complete_dtor_identifier
93 || name == base_dtor_identifier
94 || name == deleting_dtor_identifier;
97 /* conversion-function-id:
98 operator conversion-type-id
100 conversion-type-id:
101 type-specifier-seq conversion-declarator(opt)
103 conversion-declarator:
104 ptr-operator conversion-declarator(opt) */
106 static inline void
107 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
109 pp_cxx_ws_string (pp, "operator");
110 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
113 static inline void
114 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
116 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
117 pp_cxx_begin_template_argument_list (pp);
118 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
119 pp_cxx_end_template_argument_list (pp);
122 /* Prints the unqualified part of the id-expression T.
124 unqualified-id:
125 identifier
126 operator-function-id
127 conversion-function-id
128 ~ class-name
129 template-id */
131 static void
132 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
134 enum tree_code code = TREE_CODE (t);
135 switch (code)
137 case RESULT_DECL:
138 pp->translate_string ("<return-value>");
139 break;
141 case OVERLOAD:
142 t = OVL_CURRENT (t);
143 case VAR_DECL:
144 case PARM_DECL:
145 case CONST_DECL:
146 case TYPE_DECL:
147 case FUNCTION_DECL:
148 case NAMESPACE_DECL:
149 case FIELD_DECL:
150 case LABEL_DECL:
151 case USING_DECL:
152 case TEMPLATE_DECL:
153 t = DECL_NAME (t);
155 case IDENTIFIER_NODE:
156 if (t == NULL)
157 pp->translate_string ("<unnamed>");
158 else if (IDENTIFIER_TYPENAME_P (t))
159 pp_cxx_conversion_function_id (pp, t);
160 else
162 if (is_destructor_name (t))
164 pp_complement (pp);
165 /* FIXME: Why is this necessary? */
166 if (TREE_TYPE (t))
167 t = constructor_name (TREE_TYPE (t));
169 pp_cxx_tree_identifier (pp, t);
171 break;
173 case TEMPLATE_ID_EXPR:
174 pp_cxx_template_id (pp, t);
175 break;
177 case BASELINK:
178 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
179 break;
181 case RECORD_TYPE:
182 case UNION_TYPE:
183 case ENUMERAL_TYPE:
184 case TYPENAME_TYPE:
185 case UNBOUND_CLASS_TEMPLATE:
186 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
187 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
189 pp_cxx_begin_template_argument_list (pp);
190 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
191 (CLASSTYPE_TI_ARGS (t)));
192 pp_cxx_end_template_argument_list (pp);
194 break;
196 case BIT_NOT_EXPR:
197 pp_cxx_complement (pp);
198 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
199 break;
201 case TEMPLATE_TYPE_PARM:
202 case TEMPLATE_TEMPLATE_PARM:
203 if (TYPE_IDENTIFIER (t))
204 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
205 else
206 pp_cxx_canonical_template_parameter (pp, t);
207 break;
209 case TEMPLATE_PARM_INDEX:
210 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
211 break;
213 case BOUND_TEMPLATE_TEMPLATE_PARM:
214 pp_cxx_cv_qualifier_seq (pp, t);
215 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
216 pp_cxx_begin_template_argument_list (pp);
217 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
218 pp_cxx_end_template_argument_list (pp);
219 break;
221 default:
222 pp_unsupported_tree (pp, t);
223 break;
227 /* Pretty-print out the token sequence ":: template" in template codes
228 where it is needed to "inline declare" the (following) member as
229 a template. This situation arises when SCOPE of T is dependent
230 on template parameters. */
232 static inline void
233 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
235 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
236 && TYPE_P (scope) && dependent_type_p (scope))
237 pp_cxx_ws_string (pp, "template");
240 /* nested-name-specifier:
241 class-or-namespace-name :: nested-name-specifier(opt)
242 class-or-namespace-name :: template nested-name-specifier */
244 static void
245 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
247 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
249 tree scope = get_containing_scope (t);
250 pp_cxx_nested_name_specifier (pp, scope);
251 pp_cxx_template_keyword_if_needed (pp, scope, t);
252 pp_cxx_unqualified_id (pp, t);
253 pp_cxx_colon_colon (pp);
257 /* qualified-id:
258 nested-name-specifier template(opt) unqualified-id */
260 static void
261 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
263 switch (TREE_CODE (t))
265 /* A pointer-to-member is always qualified. */
266 case PTRMEM_CST:
267 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
268 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
269 break;
271 /* In Standard C++, functions cannot possibly be used as
272 nested-name-specifiers. However, there are situations where
273 is "makes sense" to output the surrounding function name for the
274 purpose of emphasizing on the scope kind. Just printing the
275 function name might not be sufficient as it may be overloaded; so,
276 we decorate the function with its signature too.
277 FIXME: This is probably the wrong pretty-printing for conversion
278 functions and some function templates. */
279 case OVERLOAD:
280 t = OVL_CURRENT (t);
281 case FUNCTION_DECL:
282 if (DECL_FUNCTION_MEMBER_P (t))
283 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
284 pp_cxx_unqualified_id
285 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
286 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
287 break;
289 case OFFSET_REF:
290 case SCOPE_REF:
291 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
292 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
293 break;
295 default:
297 tree scope = get_containing_scope (t);
298 if (scope != pp->enclosing_scope)
300 pp_cxx_nested_name_specifier (pp, scope);
301 pp_cxx_template_keyword_if_needed (pp, scope, t);
303 pp_cxx_unqualified_id (pp, t);
305 break;
310 void
311 cxx_pretty_printer::constant (tree t)
313 switch (TREE_CODE (t))
315 case STRING_CST:
317 const bool in_parens = PAREN_STRING_LITERAL_P (t);
318 if (in_parens)
319 pp_cxx_left_paren (this);
320 c_pretty_printer::constant (t);
321 if (in_parens)
322 pp_cxx_right_paren (this);
324 break;
326 case INTEGER_CST:
327 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
329 pp_string (this, "nullptr");
330 break;
332 /* else fall through. */
334 default:
335 c_pretty_printer::constant (t);
336 break;
340 /* id-expression:
341 unqualified-id
342 qualified-id */
344 void
345 cxx_pretty_printer::id_expression (tree t)
347 if (TREE_CODE (t) == OVERLOAD)
348 t = OVL_CURRENT (t);
349 if (DECL_P (t) && DECL_CONTEXT (t))
350 pp_cxx_qualified_id (this, t);
351 else
352 pp_cxx_unqualified_id (this, t);
355 /* user-defined literal:
356 literal ud-suffix */
358 void
359 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
361 pp->constant (USERDEF_LITERAL_VALUE (t));
362 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
366 /* primary-expression:
367 literal
368 this
369 :: identifier
370 :: operator-function-id
371 :: qualifier-id
372 ( expression )
373 id-expression
375 GNU Extensions:
376 __builtin_va_arg ( assignment-expression , type-id )
377 __builtin_offsetof ( type-id, offsetof-expression )
379 __has_nothrow_assign ( type-id )
380 __has_nothrow_constructor ( type-id )
381 __has_nothrow_copy ( type-id )
382 __has_trivial_assign ( type-id )
383 __has_trivial_constructor ( type-id )
384 __has_trivial_copy ( type-id )
385 __has_trivial_destructor ( type-id )
386 __has_virtual_destructor ( type-id )
387 __is_abstract ( type-id )
388 __is_base_of ( type-id , type-id )
389 __is_class ( type-id )
390 __is_convertible_to ( type-id , type-id )
391 __is_empty ( type-id )
392 __is_enum ( type-id )
393 __is_literal_type ( type-id )
394 __is_pod ( type-id )
395 __is_polymorphic ( type-id )
396 __is_std_layout ( type-id )
397 __is_trivial ( type-id )
398 __is_union ( type-id ) */
400 void
401 cxx_pretty_printer::primary_expression (tree t)
403 switch (TREE_CODE (t))
405 case INTEGER_CST:
406 case REAL_CST:
407 case COMPLEX_CST:
408 case STRING_CST:
409 constant (t);
410 break;
412 case USERDEF_LITERAL:
413 pp_cxx_userdef_literal (this, t);
414 break;
416 case BASELINK:
417 t = BASELINK_FUNCTIONS (t);
418 case VAR_DECL:
419 case PARM_DECL:
420 case FIELD_DECL:
421 case FUNCTION_DECL:
422 case OVERLOAD:
423 case CONST_DECL:
424 case TEMPLATE_DECL:
425 id_expression (t);
426 break;
428 case RESULT_DECL:
429 case TEMPLATE_TYPE_PARM:
430 case TEMPLATE_TEMPLATE_PARM:
431 case TEMPLATE_PARM_INDEX:
432 pp_cxx_unqualified_id (this, t);
433 break;
435 case STMT_EXPR:
436 pp_cxx_left_paren (this);
437 statement (STMT_EXPR_STMT (t));
438 pp_cxx_right_paren (this);
439 break;
441 case TRAIT_EXPR:
442 pp_cxx_trait_expression (this, t);
443 break;
445 case VA_ARG_EXPR:
446 pp_cxx_va_arg_expression (this, t);
447 break;
449 case OFFSETOF_EXPR:
450 pp_cxx_offsetof_expression (this, t);
451 break;
453 case REQUIRES_EXPR:
454 pp_cxx_requires_expr (this, t);
455 break;
457 case EXPR_REQ:
458 pp_cxx_expr_requirement (this, t);
459 break;
461 case TYPE_REQ:
462 pp_cxx_type_requirement (this, t);
463 break;
465 case NESTED_REQ:
466 pp_cxx_nested_requirement (this, t);
467 break;
469 case VALIDEXPR_EXPR:
470 pp_cxx_validexpr_expr (this, t);
471 break;
473 case VALIDTYPE_EXPR:
474 pp_cxx_validtype_expr (this, t);
475 break;
477 case CONSTEXPR_EXPR:
478 pp_cxx_constexpr_expr (this, t);
479 break;
481 default:
482 c_pretty_printer::primary_expression (t);
483 break;
487 /* postfix-expression:
488 primary-expression
489 postfix-expression [ expression ]
490 postfix-expression ( expression-list(opt) )
491 simple-type-specifier ( expression-list(opt) )
492 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
493 typename ::(opt) nested-name-specifier template(opt)
494 template-id ( expression-list(opt) )
495 postfix-expression . template(opt) ::(opt) id-expression
496 postfix-expression -> template(opt) ::(opt) id-expression
497 postfix-expression . pseudo-destructor-name
498 postfix-expression -> pseudo-destructor-name
499 postfix-expression ++
500 postfix-expression --
501 dynamic_cast < type-id > ( expression )
502 static_cast < type-id > ( expression )
503 reinterpret_cast < type-id > ( expression )
504 const_cast < type-id > ( expression )
505 typeid ( expression )
506 typeid ( type-id ) */
508 void
509 cxx_pretty_printer::postfix_expression (tree t)
511 enum tree_code code = TREE_CODE (t);
513 switch (code)
515 case AGGR_INIT_EXPR:
516 case CALL_EXPR:
518 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
519 : CALL_EXPR_FN (t));
520 tree saved_scope = enclosing_scope;
521 bool skipfirst = false;
522 tree arg;
524 if (TREE_CODE (fun) == ADDR_EXPR)
525 fun = TREE_OPERAND (fun, 0);
527 /* In templates, where there is no way to tell whether a given
528 call uses an actual member function. So the parser builds
529 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
530 instantiation time. */
531 if (TREE_CODE (fun) != FUNCTION_DECL)
533 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
535 tree object = (code == AGGR_INIT_EXPR
536 ? (AGGR_INIT_VIA_CTOR_P (t)
537 ? AGGR_INIT_EXPR_SLOT (t)
538 : AGGR_INIT_EXPR_ARG (t, 0))
539 : CALL_EXPR_ARG (t, 0));
541 while (TREE_CODE (object) == NOP_EXPR)
542 object = TREE_OPERAND (object, 0);
544 if (TREE_CODE (object) == ADDR_EXPR)
545 object = TREE_OPERAND (object, 0);
547 if (!TYPE_PTR_P (TREE_TYPE (object)))
549 postfix_expression (object);
550 pp_cxx_dot (this);
552 else
554 postfix_expression (object);
555 pp_cxx_arrow (this);
557 skipfirst = true;
558 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
561 postfix_expression (fun);
562 enclosing_scope = saved_scope;
563 pp_cxx_left_paren (this);
564 if (code == AGGR_INIT_EXPR)
566 aggr_init_expr_arg_iterator iter;
567 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
569 if (skipfirst)
570 skipfirst = false;
571 else
573 expression (arg);
574 if (more_aggr_init_expr_args_p (&iter))
575 pp_cxx_separate_with (this, ',');
579 else
581 call_expr_arg_iterator iter;
582 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
584 if (skipfirst)
585 skipfirst = false;
586 else
588 expression (arg);
589 if (more_call_expr_args_p (&iter))
590 pp_cxx_separate_with (this, ',');
594 pp_cxx_right_paren (this);
596 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
598 pp_cxx_separate_with (this, ',');
599 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
601 break;
603 case BASELINK:
604 case VAR_DECL:
605 case PARM_DECL:
606 case FIELD_DECL:
607 case FUNCTION_DECL:
608 case OVERLOAD:
609 case CONST_DECL:
610 case TEMPLATE_DECL:
611 case RESULT_DECL:
612 primary_expression (t);
613 break;
615 case DYNAMIC_CAST_EXPR:
616 case STATIC_CAST_EXPR:
617 case REINTERPRET_CAST_EXPR:
618 case CONST_CAST_EXPR:
619 if (code == DYNAMIC_CAST_EXPR)
620 pp_cxx_ws_string (this, "dynamic_cast");
621 else if (code == STATIC_CAST_EXPR)
622 pp_cxx_ws_string (this, "static_cast");
623 else if (code == REINTERPRET_CAST_EXPR)
624 pp_cxx_ws_string (this, "reinterpret_cast");
625 else
626 pp_cxx_ws_string (this, "const_cast");
627 pp_cxx_begin_template_argument_list (this);
628 type_id (TREE_TYPE (t));
629 pp_cxx_end_template_argument_list (this);
630 pp_left_paren (this);
631 expression (TREE_OPERAND (t, 0));
632 pp_right_paren (this);
633 break;
635 case EMPTY_CLASS_EXPR:
636 type_id (TREE_TYPE (t));
637 pp_left_paren (this);
638 pp_right_paren (this);
639 break;
641 case TYPEID_EXPR:
642 pp_cxx_typeid_expression (this, t);
643 break;
645 case PSEUDO_DTOR_EXPR:
646 postfix_expression (TREE_OPERAND (t, 0));
647 pp_cxx_dot (this);
648 if (TREE_OPERAND (t, 1))
650 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
651 pp_cxx_colon_colon (this);
653 pp_complement (this);
654 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
655 break;
657 case ARROW_EXPR:
658 postfix_expression (TREE_OPERAND (t, 0));
659 pp_cxx_arrow (this);
660 break;
662 default:
663 c_pretty_printer::postfix_expression (t);
664 break;
668 /* new-expression:
669 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
670 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
672 new-placement:
673 ( expression-list )
675 new-type-id:
676 type-specifier-seq new-declarator(opt)
678 new-declarator:
679 ptr-operator new-declarator(opt)
680 direct-new-declarator
682 direct-new-declarator
683 [ expression ]
684 direct-new-declarator [ constant-expression ]
686 new-initializer:
687 ( expression-list(opt) ) */
689 static void
690 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
692 enum tree_code code = TREE_CODE (t);
693 tree type = TREE_OPERAND (t, 1);
694 tree init = TREE_OPERAND (t, 2);
695 switch (code)
697 case NEW_EXPR:
698 case VEC_NEW_EXPR:
699 if (NEW_EXPR_USE_GLOBAL (t))
700 pp_cxx_colon_colon (pp);
701 pp_cxx_ws_string (pp, "new");
702 if (TREE_OPERAND (t, 0))
704 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
705 pp_space (pp);
707 if (TREE_CODE (type) == ARRAY_REF)
708 type = build_cplus_array_type
709 (TREE_OPERAND (type, 0),
710 build_index_type (fold_build2_loc (input_location,
711 MINUS_EXPR, integer_type_node,
712 TREE_OPERAND (type, 1),
713 integer_one_node)));
714 pp->type_id (type);
715 if (init)
717 pp_left_paren (pp);
718 if (TREE_CODE (init) == TREE_LIST)
719 pp_c_expression_list (pp, init);
720 else if (init == void_zero_node)
721 ; /* OK, empty initializer list. */
722 else
723 pp->expression (init);
724 pp_right_paren (pp);
726 break;
728 default:
729 pp_unsupported_tree (pp, t);
733 /* delete-expression:
734 ::(opt) delete cast-expression
735 ::(opt) delete [ ] cast-expression */
737 static void
738 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
740 enum tree_code code = TREE_CODE (t);
741 switch (code)
743 case DELETE_EXPR:
744 case VEC_DELETE_EXPR:
745 if (DELETE_EXPR_USE_GLOBAL (t))
746 pp_cxx_colon_colon (pp);
747 pp_cxx_ws_string (pp, "delete");
748 pp_space (pp);
749 if (code == VEC_DELETE_EXPR
750 || DELETE_EXPR_USE_VEC (t))
752 pp_left_bracket (pp);
753 pp_right_bracket (pp);
754 pp_space (pp);
756 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
757 break;
759 default:
760 pp_unsupported_tree (pp, t);
764 /* unary-expression:
765 postfix-expression
766 ++ cast-expression
767 -- cast-expression
768 unary-operator cast-expression
769 sizeof unary-expression
770 sizeof ( type-id )
771 sizeof ... ( identifier )
772 new-expression
773 delete-expression
775 unary-operator: one of
776 * & + - !
778 GNU extensions:
779 __alignof__ unary-expression
780 __alignof__ ( type-id ) */
782 void
783 cxx_pretty_printer::unary_expression (tree t)
785 enum tree_code code = TREE_CODE (t);
786 switch (code)
788 case NEW_EXPR:
789 case VEC_NEW_EXPR:
790 pp_cxx_new_expression (this, t);
791 break;
793 case DELETE_EXPR:
794 case VEC_DELETE_EXPR:
795 pp_cxx_delete_expression (this, t);
796 break;
798 case SIZEOF_EXPR:
799 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
801 pp_cxx_ws_string (this, "sizeof");
802 pp_cxx_ws_string (this, "...");
803 pp_cxx_whitespace (this);
804 pp_cxx_left_paren (this);
805 if (TYPE_P (TREE_OPERAND (t, 0)))
806 type_id (TREE_OPERAND (t, 0));
807 else
808 unary_expression (TREE_OPERAND (t, 0));
809 pp_cxx_right_paren (this);
810 break;
812 /* Fall through */
814 case ALIGNOF_EXPR:
815 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
816 pp_cxx_whitespace (this);
817 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
819 pp_cxx_left_paren (this);
820 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
821 pp_cxx_right_paren (this);
823 else if (TYPE_P (TREE_OPERAND (t, 0)))
825 pp_cxx_left_paren (this);
826 type_id (TREE_OPERAND (t, 0));
827 pp_cxx_right_paren (this);
829 else
830 unary_expression (TREE_OPERAND (t, 0));
831 break;
833 case AT_ENCODE_EXPR:
834 pp_cxx_ws_string (this, "@encode");
835 pp_cxx_whitespace (this);
836 pp_cxx_left_paren (this);
837 type_id (TREE_OPERAND (t, 0));
838 pp_cxx_right_paren (this);
839 break;
841 case NOEXCEPT_EXPR:
842 pp_cxx_ws_string (this, "noexcept");
843 pp_cxx_whitespace (this);
844 pp_cxx_left_paren (this);
845 expression (TREE_OPERAND (t, 0));
846 pp_cxx_right_paren (this);
847 break;
849 case UNARY_PLUS_EXPR:
850 pp_plus (this);
851 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
852 break;
854 default:
855 c_pretty_printer::unary_expression (t);
856 break;
860 /* cast-expression:
861 unary-expression
862 ( type-id ) cast-expression */
864 static void
865 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
867 switch (TREE_CODE (t))
869 case CAST_EXPR:
870 case IMPLICIT_CONV_EXPR:
871 pp->type_id (TREE_TYPE (t));
872 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
873 break;
875 default:
876 pp_c_cast_expression (pp, t);
877 break;
881 /* pm-expression:
882 cast-expression
883 pm-expression .* cast-expression
884 pm-expression ->* cast-expression */
886 static void
887 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
889 switch (TREE_CODE (t))
891 /* Handle unfortunate OFFSET_REF overloading here. */
892 case OFFSET_REF:
893 if (TYPE_P (TREE_OPERAND (t, 0)))
895 pp_cxx_qualified_id (pp, t);
896 break;
898 /* Else fall through. */
899 case MEMBER_REF:
900 case DOTSTAR_EXPR:
901 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
902 if (TREE_CODE (t) == MEMBER_REF)
903 pp_cxx_arrow (pp);
904 else
905 pp_cxx_dot (pp);
906 pp_star(pp);
907 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
908 break;
911 default:
912 pp_cxx_cast_expression (pp, t);
913 break;
917 /* multiplicative-expression:
918 pm-expression
919 multiplicative-expression * pm-expression
920 multiplicative-expression / pm-expression
921 multiplicative-expression % pm-expression */
923 void
924 cxx_pretty_printer::multiplicative_expression (tree e)
926 enum tree_code code = TREE_CODE (e);
927 switch (code)
929 case MULT_EXPR:
930 case TRUNC_DIV_EXPR:
931 case TRUNC_MOD_EXPR:
932 multiplicative_expression (TREE_OPERAND (e, 0));
933 pp_space (this);
934 if (code == MULT_EXPR)
935 pp_star (this);
936 else if (code == TRUNC_DIV_EXPR)
937 pp_slash (this);
938 else
939 pp_modulo (this);
940 pp_space (this);
941 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
942 break;
944 default:
945 pp_cxx_pm_expression (this, e);
946 break;
950 /* conditional-expression:
951 logical-or-expression
952 logical-or-expression ? expression : assignment-expression */
954 void
955 cxx_pretty_printer::conditional_expression (tree e)
957 if (TREE_CODE (e) == COND_EXPR)
959 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
960 pp_space (this);
961 pp_question (this);
962 pp_space (this);
963 expression (TREE_OPERAND (e, 1));
964 pp_space (this);
965 assignment_expression (TREE_OPERAND (e, 2));
967 else
968 pp_c_logical_or_expression (this, e);
971 /* Pretty-print a compound assignment operator token as indicated by T. */
973 static void
974 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
976 const char *op;
978 switch (TREE_CODE (t))
980 case NOP_EXPR:
981 op = "=";
982 break;
984 case PLUS_EXPR:
985 op = "+=";
986 break;
988 case MINUS_EXPR:
989 op = "-=";
990 break;
992 case TRUNC_DIV_EXPR:
993 op = "/=";
994 break;
996 case TRUNC_MOD_EXPR:
997 op = "%=";
998 break;
1000 default:
1001 op = get_tree_code_name (TREE_CODE (t));
1002 break;
1005 pp_cxx_ws_string (pp, op);
1009 /* assignment-expression:
1010 conditional-expression
1011 logical-or-expression assignment-operator assignment-expression
1012 throw-expression
1014 throw-expression:
1015 throw assignment-expression(opt)
1017 assignment-operator: one of
1018 = *= /= %= += -= >>= <<= &= ^= |= */
1020 void
1021 cxx_pretty_printer::assignment_expression (tree e)
1023 switch (TREE_CODE (e))
1025 case MODIFY_EXPR:
1026 case INIT_EXPR:
1027 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1028 pp_space (this);
1029 pp_equal (this);
1030 pp_space (this);
1031 assignment_expression (TREE_OPERAND (e, 1));
1032 break;
1034 case THROW_EXPR:
1035 pp_cxx_ws_string (this, "throw");
1036 if (TREE_OPERAND (e, 0))
1037 assignment_expression (TREE_OPERAND (e, 0));
1038 break;
1040 case MODOP_EXPR:
1041 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1042 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1043 assignment_expression (TREE_OPERAND (e, 2));
1044 break;
1046 default:
1047 conditional_expression (e);
1048 break;
1052 void
1053 cxx_pretty_printer::expression (tree t)
1055 switch (TREE_CODE (t))
1057 case STRING_CST:
1058 case INTEGER_CST:
1059 case REAL_CST:
1060 case COMPLEX_CST:
1061 constant (t);
1062 break;
1064 case USERDEF_LITERAL:
1065 pp_cxx_userdef_literal (this, t);
1066 break;
1068 case RESULT_DECL:
1069 pp_cxx_unqualified_id (this, t);
1070 break;
1072 #if 0
1073 case OFFSET_REF:
1074 #endif
1075 case SCOPE_REF:
1076 case PTRMEM_CST:
1077 pp_cxx_qualified_id (this, t);
1078 break;
1080 case OVERLOAD:
1081 t = OVL_CURRENT (t);
1082 case VAR_DECL:
1083 case PARM_DECL:
1084 case FIELD_DECL:
1085 case CONST_DECL:
1086 case FUNCTION_DECL:
1087 case BASELINK:
1088 case TEMPLATE_DECL:
1089 case TEMPLATE_TYPE_PARM:
1090 case TEMPLATE_PARM_INDEX:
1091 case TEMPLATE_TEMPLATE_PARM:
1092 case STMT_EXPR:
1093 case REQUIRES_EXPR:
1094 case EXPR_REQ:
1095 case TYPE_REQ:
1096 case NESTED_REQ:
1097 primary_expression (t);
1098 break;
1100 case CALL_EXPR:
1101 case DYNAMIC_CAST_EXPR:
1102 case STATIC_CAST_EXPR:
1103 case REINTERPRET_CAST_EXPR:
1104 case CONST_CAST_EXPR:
1105 #if 0
1106 case MEMBER_REF:
1107 #endif
1108 case EMPTY_CLASS_EXPR:
1109 case TYPEID_EXPR:
1110 case PSEUDO_DTOR_EXPR:
1111 case AGGR_INIT_EXPR:
1112 case ARROW_EXPR:
1113 postfix_expression (t);
1114 break;
1116 case NEW_EXPR:
1117 case VEC_NEW_EXPR:
1118 pp_cxx_new_expression (this, t);
1119 break;
1121 case DELETE_EXPR:
1122 case VEC_DELETE_EXPR:
1123 pp_cxx_delete_expression (this, t);
1124 break;
1126 case SIZEOF_EXPR:
1127 case ALIGNOF_EXPR:
1128 case NOEXCEPT_EXPR:
1129 unary_expression (t);
1130 break;
1132 case CAST_EXPR:
1133 case IMPLICIT_CONV_EXPR:
1134 pp_cxx_cast_expression (this, t);
1135 break;
1137 case OFFSET_REF:
1138 case MEMBER_REF:
1139 case DOTSTAR_EXPR:
1140 pp_cxx_pm_expression (this, t);
1141 break;
1143 case MULT_EXPR:
1144 case TRUNC_DIV_EXPR:
1145 case TRUNC_MOD_EXPR:
1146 multiplicative_expression (t);
1147 break;
1149 case COND_EXPR:
1150 conditional_expression (t);
1151 break;
1153 case MODIFY_EXPR:
1154 case INIT_EXPR:
1155 case THROW_EXPR:
1156 case MODOP_EXPR:
1157 assignment_expression (t);
1158 break;
1160 case NON_DEPENDENT_EXPR:
1161 case MUST_NOT_THROW_EXPR:
1162 expression (TREE_OPERAND (t, 0));
1163 break;
1165 case EXPR_PACK_EXPANSION:
1166 expression (PACK_EXPANSION_PATTERN (t));
1167 pp_cxx_ws_string (this, "...");
1168 break;
1170 case TEMPLATE_ID_EXPR:
1171 pp_cxx_template_id (this, t);
1172 break;
1174 case NONTYPE_ARGUMENT_PACK:
1176 tree args = ARGUMENT_PACK_ARGS (t);
1177 int i, len = TREE_VEC_LENGTH (args);
1178 for (i = 0; i < len; ++i)
1180 if (i > 0)
1181 pp_cxx_separate_with (this, ',');
1182 expression (TREE_VEC_ELT (args, i));
1185 break;
1187 case LAMBDA_EXPR:
1188 pp_cxx_ws_string (this, "<lambda>");
1189 break;
1191 case PAREN_EXPR:
1192 pp_cxx_left_paren (this);
1193 expression (TREE_OPERAND (t, 0));
1194 pp_cxx_right_paren (this);
1195 break;
1197 default:
1198 c_pretty_printer::expression (t);
1199 break;
1204 /* Declarations. */
1206 /* function-specifier:
1207 inline
1208 virtual
1209 explicit */
1211 void
1212 cxx_pretty_printer::function_specifier (tree t)
1214 switch (TREE_CODE (t))
1216 case FUNCTION_DECL:
1217 if (DECL_VIRTUAL_P (t))
1218 pp_cxx_ws_string (this, "virtual");
1219 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1220 pp_cxx_ws_string (this, "explicit");
1221 else
1222 c_pretty_printer::function_specifier (t);
1224 default:
1225 break;
1229 /* decl-specifier-seq:
1230 decl-specifier-seq(opt) decl-specifier
1232 decl-specifier:
1233 storage-class-specifier
1234 type-specifier
1235 function-specifier
1236 friend
1237 typedef */
1239 void
1240 cxx_pretty_printer::declaration_specifiers (tree t)
1242 switch (TREE_CODE (t))
1244 case VAR_DECL:
1245 case PARM_DECL:
1246 case CONST_DECL:
1247 case FIELD_DECL:
1248 storage_class_specifier (t);
1249 declaration_specifiers (TREE_TYPE (t));
1250 break;
1252 case TYPE_DECL:
1253 pp_cxx_ws_string (this, "typedef");
1254 declaration_specifiers (TREE_TYPE (t));
1255 break;
1257 case FUNCTION_DECL:
1258 /* Constructors don't have return types. And conversion functions
1259 do not have a type-specifier in their return types. */
1260 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1261 function_specifier (t);
1262 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1263 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1264 else
1265 default:
1266 c_pretty_printer::declaration_specifiers (t);
1267 break;
1271 /* simple-type-specifier:
1272 ::(opt) nested-name-specifier(opt) type-name
1273 ::(opt) nested-name-specifier(opt) template(opt) template-id
1274 char
1275 wchar_t
1276 bool
1277 short
1279 long
1280 signed
1281 unsigned
1282 float
1283 double
1284 void */
1286 void
1287 cxx_pretty_printer::simple_type_specifier (tree t)
1289 switch (TREE_CODE (t))
1291 case RECORD_TYPE:
1292 case UNION_TYPE:
1293 case ENUMERAL_TYPE:
1294 pp_cxx_qualified_id (this, t);
1295 break;
1297 case TEMPLATE_TYPE_PARM:
1298 case TEMPLATE_TEMPLATE_PARM:
1299 case TEMPLATE_PARM_INDEX:
1300 case BOUND_TEMPLATE_TEMPLATE_PARM:
1301 pp_cxx_unqualified_id (this, t);
1302 break;
1304 case TYPENAME_TYPE:
1305 pp_cxx_ws_string (this, "typename");
1306 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1307 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1308 break;
1310 default:
1311 c_pretty_printer::simple_type_specifier (t);
1312 break;
1316 /* type-specifier-seq:
1317 type-specifier type-specifier-seq(opt)
1319 type-specifier:
1320 simple-type-specifier
1321 class-specifier
1322 enum-specifier
1323 elaborated-type-specifier
1324 cv-qualifier */
1326 static void
1327 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1329 switch (TREE_CODE (t))
1331 case TEMPLATE_DECL:
1332 case TEMPLATE_TYPE_PARM:
1333 case TEMPLATE_TEMPLATE_PARM:
1334 case TYPE_DECL:
1335 case BOUND_TEMPLATE_TEMPLATE_PARM:
1336 pp_cxx_cv_qualifier_seq (pp, t);
1337 pp->simple_type_specifier (t);
1338 break;
1340 case METHOD_TYPE:
1341 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1342 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1343 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1344 break;
1346 case DECLTYPE_TYPE:
1347 pp_cxx_ws_string (pp, "decltype");
1348 pp_cxx_left_paren (pp);
1349 pp->expression (DECLTYPE_TYPE_EXPR (t));
1350 pp_cxx_right_paren (pp);
1351 break;
1353 case RECORD_TYPE:
1354 if (TYPE_PTRMEMFUNC_P (t))
1356 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1357 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1358 pp_cxx_whitespace (pp);
1359 pp_cxx_ptr_operator (pp, t);
1360 break;
1362 /* else fall through */
1364 default:
1365 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1366 pp_c_specifier_qualifier_list (pp, t);
1370 /* ptr-operator:
1371 * cv-qualifier-seq(opt)
1373 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1375 static void
1376 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1378 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1379 t = TREE_TYPE (t);
1380 switch (TREE_CODE (t))
1382 case REFERENCE_TYPE:
1383 case POINTER_TYPE:
1384 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1385 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1386 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1387 if (TYPE_PTR_P (t))
1389 pp_star (pp);
1390 pp_cxx_cv_qualifier_seq (pp, t);
1392 else
1393 pp_ampersand (pp);
1394 break;
1396 case RECORD_TYPE:
1397 if (TYPE_PTRMEMFUNC_P (t))
1399 pp_cxx_left_paren (pp);
1400 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1401 pp_star (pp);
1402 break;
1404 case OFFSET_TYPE:
1405 if (TYPE_PTRMEM_P (t))
1407 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1408 pp_cxx_left_paren (pp);
1409 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1410 pp_star (pp);
1411 pp_cxx_cv_qualifier_seq (pp, t);
1412 break;
1414 /* else fall through. */
1416 default:
1417 pp_unsupported_tree (pp, t);
1418 break;
1422 static inline tree
1423 pp_cxx_implicit_parameter_type (tree mf)
1425 return class_of_this_parm (TREE_TYPE (mf));
1429 parameter-declaration:
1430 decl-specifier-seq declarator
1431 decl-specifier-seq declarator = assignment-expression
1432 decl-specifier-seq abstract-declarator(opt)
1433 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1435 static inline void
1436 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1438 pp->declaration_specifiers (t);
1439 if (TYPE_P (t))
1440 pp->abstract_declarator (t);
1441 else
1442 pp->declarator (t);
1445 /* parameter-declaration-clause:
1446 parameter-declaration-list(opt) ...(opt)
1447 parameter-declaration-list , ...
1449 parameter-declaration-list:
1450 parameter-declaration
1451 parameter-declaration-list , parameter-declaration */
1453 void
1454 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1456 tree args;
1457 tree types;
1458 bool abstract;
1460 // For a requires clause or the explicit printing of a parameter list
1461 // we expect T to be a TREE_LIST of PARM_DECLs. Otherwise, the list of
1462 // args and types are taken from the function decl T.
1463 if (TREE_CODE (t) == TREE_LIST)
1465 args = TREE_VALUE (t);
1466 types = TREE_VALUE (t);
1467 abstract = false;
1469 else
1471 bool type_p = TYPE_P (t);
1472 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1473 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1474 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1476 bool first = true;
1478 /* Skip artificial parameter for nonstatic member functions. */
1479 if (TREE_CODE (t) == METHOD_TYPE)
1480 types = TREE_CHAIN (types);
1482 pp_cxx_left_paren (pp);
1483 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1485 if (!first)
1486 pp_cxx_separate_with (pp, ',');
1487 first = false;
1488 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1489 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1491 pp_cxx_whitespace (pp);
1492 pp_equal (pp);
1493 pp_cxx_whitespace (pp);
1494 pp->assignment_expression (TREE_PURPOSE (types));
1497 pp_cxx_right_paren (pp);
1500 /* exception-specification:
1501 throw ( type-id-list(opt) )
1503 type-id-list
1504 type-id
1505 type-id-list , type-id */
1507 static void
1508 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1510 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1511 bool need_comma = false;
1513 if (ex_spec == NULL)
1514 return;
1515 if (TREE_PURPOSE (ex_spec))
1517 pp_cxx_ws_string (pp, "noexcept");
1518 pp_cxx_whitespace (pp);
1519 pp_cxx_left_paren (pp);
1520 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1521 pp_cxx_ws_string (pp, "<uninstantiated>");
1522 else
1523 pp->expression (TREE_PURPOSE (ex_spec));
1524 pp_cxx_right_paren (pp);
1525 return;
1527 pp_cxx_ws_string (pp, "throw");
1528 pp_cxx_left_paren (pp);
1529 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1531 tree type = TREE_VALUE (ex_spec);
1532 tree argpack = NULL_TREE;
1533 int i, len = 1;
1535 if (ARGUMENT_PACK_P (type))
1537 argpack = ARGUMENT_PACK_ARGS (type);
1538 len = TREE_VEC_LENGTH (argpack);
1541 for (i = 0; i < len; ++i)
1543 if (argpack)
1544 type = TREE_VEC_ELT (argpack, i);
1546 if (need_comma)
1547 pp_cxx_separate_with (pp, ',');
1548 else
1549 need_comma = true;
1551 pp->type_id (type);
1554 pp_cxx_right_paren (pp);
1557 /* direct-declarator:
1558 declarator-id
1559 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1560 exception-specification(opt)
1561 direct-declaration [ constant-expression(opt) ]
1562 ( declarator ) */
1564 void
1565 cxx_pretty_printer::direct_declarator (tree t)
1567 switch (TREE_CODE (t))
1569 case VAR_DECL:
1570 case PARM_DECL:
1571 case CONST_DECL:
1572 case FIELD_DECL:
1573 if (DECL_NAME (t))
1575 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1577 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1578 || template_parameter_pack_p (t))
1579 /* A function parameter pack or non-type template
1580 parameter pack. */
1581 pp_cxx_ws_string (this, "...");
1583 id_expression (DECL_NAME (t));
1585 abstract_declarator (TREE_TYPE (t));
1586 break;
1588 case FUNCTION_DECL:
1589 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1590 expression (t);
1591 pp_cxx_parameter_declaration_clause (this, t);
1593 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1595 padding = pp_before;
1596 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1599 pp_cxx_exception_specification (this, TREE_TYPE (t));
1600 break;
1602 case TYPENAME_TYPE:
1603 case TEMPLATE_DECL:
1604 case TEMPLATE_TYPE_PARM:
1605 case TEMPLATE_PARM_INDEX:
1606 case TEMPLATE_TEMPLATE_PARM:
1607 break;
1609 default:
1610 c_pretty_printer::direct_declarator (t);
1611 break;
1615 /* declarator:
1616 direct-declarator
1617 ptr-operator declarator */
1619 void
1620 cxx_pretty_printer::declarator (tree t)
1622 direct_declarator (t);
1625 /* ctor-initializer:
1626 : mem-initializer-list
1628 mem-initializer-list:
1629 mem-initializer
1630 mem-initializer , mem-initializer-list
1632 mem-initializer:
1633 mem-initializer-id ( expression-list(opt) )
1635 mem-initializer-id:
1636 ::(opt) nested-name-specifier(opt) class-name
1637 identifier */
1639 static void
1640 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1642 t = TREE_OPERAND (t, 0);
1643 pp_cxx_whitespace (pp);
1644 pp_colon (pp);
1645 pp_cxx_whitespace (pp);
1646 for (; t; t = TREE_CHAIN (t))
1648 tree purpose = TREE_PURPOSE (t);
1649 bool is_pack = PACK_EXPANSION_P (purpose);
1651 if (is_pack)
1652 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1653 else
1654 pp->primary_expression (purpose);
1655 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1656 if (is_pack)
1657 pp_cxx_ws_string (pp, "...");
1658 if (TREE_CHAIN (t))
1659 pp_cxx_separate_with (pp, ',');
1663 /* function-definition:
1664 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1665 decl-specifier-seq(opt) declarator function-try-block */
1667 static void
1668 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1670 tree saved_scope = pp->enclosing_scope;
1671 pp->declaration_specifiers (t);
1672 pp->declarator (t);
1673 pp_needs_newline (pp) = true;
1674 pp->enclosing_scope = DECL_CONTEXT (t);
1675 if (DECL_SAVED_TREE (t))
1676 pp->statement (DECL_SAVED_TREE (t));
1677 else
1678 pp_cxx_semicolon (pp);
1679 pp_newline_and_flush (pp);
1680 pp->enclosing_scope = saved_scope;
1683 /* abstract-declarator:
1684 ptr-operator abstract-declarator(opt)
1685 direct-abstract-declarator */
1687 void
1688 cxx_pretty_printer::abstract_declarator (tree t)
1690 if (TYPE_PTRMEM_P (t))
1691 pp_cxx_right_paren (this);
1692 else if (POINTER_TYPE_P (t))
1694 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1695 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1696 pp_cxx_right_paren (this);
1697 t = TREE_TYPE (t);
1699 direct_abstract_declarator (t);
1702 /* direct-abstract-declarator:
1703 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1704 cv-qualifier-seq(opt) exception-specification(opt)
1705 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1706 ( abstract-declarator ) */
1708 void
1709 cxx_pretty_printer::direct_abstract_declarator (tree t)
1711 switch (TREE_CODE (t))
1713 case REFERENCE_TYPE:
1714 abstract_declarator (t);
1715 break;
1717 case RECORD_TYPE:
1718 if (TYPE_PTRMEMFUNC_P (t))
1719 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1720 break;
1722 case METHOD_TYPE:
1723 case FUNCTION_TYPE:
1724 pp_cxx_parameter_declaration_clause (this, t);
1725 direct_abstract_declarator (TREE_TYPE (t));
1726 if (TREE_CODE (t) == METHOD_TYPE)
1728 padding = pp_before;
1729 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1731 pp_cxx_exception_specification (this, t);
1732 break;
1734 case TYPENAME_TYPE:
1735 case TEMPLATE_TYPE_PARM:
1736 case TEMPLATE_TEMPLATE_PARM:
1737 case BOUND_TEMPLATE_TEMPLATE_PARM:
1738 case UNBOUND_CLASS_TEMPLATE:
1739 break;
1741 default:
1742 c_pretty_printer::direct_abstract_declarator (t);
1743 break;
1747 /* type-id:
1748 type-specifier-seq abstract-declarator(opt) */
1750 void
1751 cxx_pretty_printer::type_id (tree t)
1753 pp_flags saved_flags = flags;
1754 flags |= pp_c_flag_abstract;
1756 switch (TREE_CODE (t))
1758 case TYPE_DECL:
1759 case UNION_TYPE:
1760 case RECORD_TYPE:
1761 case ENUMERAL_TYPE:
1762 case TYPENAME_TYPE:
1763 case BOUND_TEMPLATE_TEMPLATE_PARM:
1764 case UNBOUND_CLASS_TEMPLATE:
1765 case TEMPLATE_TEMPLATE_PARM:
1766 case TEMPLATE_TYPE_PARM:
1767 case TEMPLATE_PARM_INDEX:
1768 case TEMPLATE_DECL:
1769 case TYPEOF_TYPE:
1770 case UNDERLYING_TYPE:
1771 case DECLTYPE_TYPE:
1772 case TEMPLATE_ID_EXPR:
1773 pp_cxx_type_specifier_seq (this, t);
1774 break;
1776 case TYPE_PACK_EXPANSION:
1777 type_id (PACK_EXPANSION_PATTERN (t));
1778 pp_cxx_ws_string (this, "...");
1779 break;
1781 default:
1782 c_pretty_printer::type_id (t);
1783 break;
1786 flags = saved_flags;
1789 /* template-argument-list:
1790 template-argument ...(opt)
1791 template-argument-list, template-argument ...(opt)
1793 template-argument:
1794 assignment-expression
1795 type-id
1796 template-name */
1798 static void
1799 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1801 int i;
1802 bool need_comma = false;
1804 if (t == NULL)
1805 return;
1806 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1808 tree arg = TREE_VEC_ELT (t, i);
1809 tree argpack = NULL_TREE;
1810 int idx, len = 1;
1812 if (ARGUMENT_PACK_P (arg))
1814 argpack = ARGUMENT_PACK_ARGS (arg);
1815 len = TREE_VEC_LENGTH (argpack);
1818 for (idx = 0; idx < len; idx++)
1820 if (argpack)
1821 arg = TREE_VEC_ELT (argpack, idx);
1823 if (need_comma)
1824 pp_cxx_separate_with (pp, ',');
1825 else
1826 need_comma = true;
1828 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1829 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1830 pp->type_id (arg);
1831 else
1832 pp->expression (arg);
1838 static void
1839 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1841 t = DECL_EXPR_DECL (t);
1842 pp_cxx_type_specifier_seq (pp, t);
1843 if (TYPE_P (t))
1844 pp->abstract_declarator (t);
1845 else
1846 pp->declarator (t);
1849 /* Statements. */
1851 void
1852 cxx_pretty_printer::statement (tree t)
1854 switch (TREE_CODE (t))
1856 case CTOR_INITIALIZER:
1857 pp_cxx_ctor_initializer (this, t);
1858 break;
1860 case USING_STMT:
1861 pp_cxx_ws_string (this, "using");
1862 pp_cxx_ws_string (this, "namespace");
1863 if (DECL_CONTEXT (t))
1864 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1865 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1866 break;
1868 case USING_DECL:
1869 pp_cxx_ws_string (this, "using");
1870 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1871 pp_cxx_unqualified_id (this, DECL_NAME (t));
1872 break;
1874 case EH_SPEC_BLOCK:
1875 break;
1877 /* try-block:
1878 try compound-statement handler-seq */
1879 case TRY_BLOCK:
1880 pp_maybe_newline_and_indent (this, 0);
1881 pp_cxx_ws_string (this, "try");
1882 pp_newline_and_indent (this, 3);
1883 statement (TRY_STMTS (t));
1884 pp_newline_and_indent (this, -3);
1885 if (CLEANUP_P (t))
1887 else
1888 statement (TRY_HANDLERS (t));
1889 break;
1892 handler-seq:
1893 handler handler-seq(opt)
1895 handler:
1896 catch ( exception-declaration ) compound-statement
1898 exception-declaration:
1899 type-specifier-seq declarator
1900 type-specifier-seq abstract-declarator
1901 ... */
1902 case HANDLER:
1903 pp_cxx_ws_string (this, "catch");
1904 pp_cxx_left_paren (this);
1905 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1906 pp_cxx_right_paren (this);
1907 pp_indentation (this) += 3;
1908 pp_needs_newline (this) = true;
1909 statement (HANDLER_BODY (t));
1910 pp_indentation (this) -= 3;
1911 pp_needs_newline (this) = true;
1912 break;
1914 /* selection-statement:
1915 if ( expression ) statement
1916 if ( expression ) statement else statement */
1917 case IF_STMT:
1918 pp_cxx_ws_string (this, "if");
1919 pp_cxx_whitespace (this);
1920 pp_cxx_left_paren (this);
1921 expression (IF_COND (t));
1922 pp_cxx_right_paren (this);
1923 pp_newline_and_indent (this, 2);
1924 statement (THEN_CLAUSE (t));
1925 pp_newline_and_indent (this, -2);
1926 if (ELSE_CLAUSE (t))
1928 tree else_clause = ELSE_CLAUSE (t);
1929 pp_cxx_ws_string (this, "else");
1930 if (TREE_CODE (else_clause) == IF_STMT)
1931 pp_cxx_whitespace (this);
1932 else
1933 pp_newline_and_indent (this, 2);
1934 statement (else_clause);
1935 if (TREE_CODE (else_clause) != IF_STMT)
1936 pp_newline_and_indent (this, -2);
1938 break;
1940 case SWITCH_STMT:
1941 pp_cxx_ws_string (this, "switch");
1942 pp_space (this);
1943 pp_cxx_left_paren (this);
1944 expression (SWITCH_STMT_COND (t));
1945 pp_cxx_right_paren (this);
1946 pp_indentation (this) += 3;
1947 pp_needs_newline (this) = true;
1948 statement (SWITCH_STMT_BODY (t));
1949 pp_newline_and_indent (this, -3);
1950 break;
1952 /* iteration-statement:
1953 while ( expression ) statement
1954 do statement while ( expression ) ;
1955 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1956 for ( declaration expression(opt) ; expression(opt) ) statement */
1957 case WHILE_STMT:
1958 pp_cxx_ws_string (this, "while");
1959 pp_space (this);
1960 pp_cxx_left_paren (this);
1961 expression (WHILE_COND (t));
1962 pp_cxx_right_paren (this);
1963 pp_newline_and_indent (this, 3);
1964 statement (WHILE_BODY (t));
1965 pp_indentation (this) -= 3;
1966 pp_needs_newline (this) = true;
1967 break;
1969 case DO_STMT:
1970 pp_cxx_ws_string (this, "do");
1971 pp_newline_and_indent (this, 3);
1972 statement (DO_BODY (t));
1973 pp_newline_and_indent (this, -3);
1974 pp_cxx_ws_string (this, "while");
1975 pp_space (this);
1976 pp_cxx_left_paren (this);
1977 expression (DO_COND (t));
1978 pp_cxx_right_paren (this);
1979 pp_cxx_semicolon (this);
1980 pp_needs_newline (this) = true;
1981 break;
1983 case FOR_STMT:
1984 pp_cxx_ws_string (this, "for");
1985 pp_space (this);
1986 pp_cxx_left_paren (this);
1987 if (FOR_INIT_STMT (t))
1988 statement (FOR_INIT_STMT (t));
1989 else
1990 pp_cxx_semicolon (this);
1991 pp_needs_newline (this) = false;
1992 pp_cxx_whitespace (this);
1993 if (FOR_COND (t))
1994 expression (FOR_COND (t));
1995 pp_cxx_semicolon (this);
1996 pp_needs_newline (this) = false;
1997 pp_cxx_whitespace (this);
1998 if (FOR_EXPR (t))
1999 expression (FOR_EXPR (t));
2000 pp_cxx_right_paren (this);
2001 pp_newline_and_indent (this, 3);
2002 statement (FOR_BODY (t));
2003 pp_indentation (this) -= 3;
2004 pp_needs_newline (this) = true;
2005 break;
2007 case RANGE_FOR_STMT:
2008 pp_cxx_ws_string (this, "for");
2009 pp_space (this);
2010 pp_cxx_left_paren (this);
2011 statement (RANGE_FOR_DECL (t));
2012 pp_space (this);
2013 pp_needs_newline (this) = false;
2014 pp_colon (this);
2015 pp_space (this);
2016 statement (RANGE_FOR_EXPR (t));
2017 pp_cxx_right_paren (this);
2018 pp_newline_and_indent (this, 3);
2019 statement (FOR_BODY (t));
2020 pp_indentation (this) -= 3;
2021 pp_needs_newline (this) = true;
2022 break;
2024 /* jump-statement:
2025 goto identifier;
2026 continue ;
2027 return expression(opt) ; */
2028 case BREAK_STMT:
2029 case CONTINUE_STMT:
2030 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2031 pp_cxx_semicolon (this);
2032 pp_needs_newline (this) = true;
2033 break;
2035 /* expression-statement:
2036 expression(opt) ; */
2037 case EXPR_STMT:
2038 expression (EXPR_STMT_EXPR (t));
2039 pp_cxx_semicolon (this);
2040 pp_needs_newline (this) = true;
2041 break;
2043 case CLEANUP_STMT:
2044 pp_cxx_ws_string (this, "try");
2045 pp_newline_and_indent (this, 2);
2046 statement (CLEANUP_BODY (t));
2047 pp_newline_and_indent (this, -2);
2048 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2049 pp_newline_and_indent (this, 2);
2050 statement (CLEANUP_EXPR (t));
2051 pp_newline_and_indent (this, -2);
2052 break;
2054 case STATIC_ASSERT:
2055 declaration (t);
2056 break;
2058 default:
2059 c_pretty_printer::statement (t);
2060 break;
2064 /* original-namespace-definition:
2065 namespace identifier { namespace-body }
2067 As an edge case, we also handle unnamed namespace definition here. */
2069 static void
2070 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2072 pp_cxx_ws_string (pp, "namespace");
2073 if (DECL_CONTEXT (t))
2074 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2075 if (DECL_NAME (t))
2076 pp_cxx_unqualified_id (pp, t);
2077 pp_cxx_whitespace (pp);
2078 pp_cxx_left_brace (pp);
2079 /* We do not print the namespace-body. */
2080 pp_cxx_whitespace (pp);
2081 pp_cxx_right_brace (pp);
2084 /* namespace-alias:
2085 identifier
2087 namespace-alias-definition:
2088 namespace identifier = qualified-namespace-specifier ;
2090 qualified-namespace-specifier:
2091 ::(opt) nested-name-specifier(opt) namespace-name */
2093 static void
2094 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2096 pp_cxx_ws_string (pp, "namespace");
2097 if (DECL_CONTEXT (t))
2098 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2099 pp_cxx_unqualified_id (pp, t);
2100 pp_cxx_whitespace (pp);
2101 pp_equal (pp);
2102 pp_cxx_whitespace (pp);
2103 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2104 pp_cxx_nested_name_specifier (pp,
2105 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2106 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2107 pp_cxx_semicolon (pp);
2110 /* simple-declaration:
2111 decl-specifier-seq(opt) init-declarator-list(opt) */
2113 static void
2114 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2116 pp->declaration_specifiers (t);
2117 pp_cxx_init_declarator (pp, t);
2118 pp_cxx_semicolon (pp);
2119 pp_needs_newline (pp) = true;
2123 template-parameter-list:
2124 template-parameter
2125 template-parameter-list , template-parameter */
2127 static inline void
2128 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2130 const int n = TREE_VEC_LENGTH (t);
2131 int i;
2132 for (i = 0; i < n; ++i)
2134 if (i)
2135 pp_cxx_separate_with (pp, ',');
2136 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2140 /* template-parameter:
2141 type-parameter
2142 parameter-declaration
2144 type-parameter:
2145 class ...(opt) identifier(opt)
2146 class identifier(opt) = type-id
2147 typename identifier(opt)
2148 typename ...(opt) identifier(opt) = type-id
2149 template < template-parameter-list > class ...(opt) identifier(opt)
2150 template < template-parameter-list > class identifier(opt) = template-name */
2152 static void
2153 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2155 tree parameter = TREE_VALUE (t);
2156 switch (TREE_CODE (parameter))
2158 case TYPE_DECL:
2159 pp_cxx_ws_string (pp, "class");
2160 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2161 pp_cxx_ws_string (pp, "...");
2162 if (DECL_NAME (parameter))
2163 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2164 /* FIXME: Check if we should print also default argument. */
2165 break;
2167 case PARM_DECL:
2168 pp_cxx_parameter_declaration (pp, parameter);
2169 break;
2171 case TEMPLATE_DECL:
2172 break;
2174 default:
2175 pp_unsupported_tree (pp, t);
2176 break;
2180 /* Pretty-print a template parameter in the canonical form
2181 "template-parameter-<level>-<position in parameter list>". */
2183 void
2184 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2186 const enum tree_code code = TREE_CODE (parm);
2188 /* Brings type template parameters to the canonical forms. */
2189 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2190 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2191 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2193 pp_cxx_begin_template_argument_list (pp);
2194 pp->translate_string ("template-parameter-");
2195 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2196 pp_minus (pp);
2197 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2198 pp_cxx_end_template_argument_list (pp);
2202 template-declaration:
2203 export(opt) template < template-parameter-list > declaration */
2205 static void
2206 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2208 tree tmpl = most_general_template (t);
2209 tree level;
2211 pp_maybe_newline_and_indent (pp, 0);
2212 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2214 pp_cxx_ws_string (pp, "template");
2215 pp_cxx_begin_template_argument_list (pp);
2216 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2217 pp_cxx_end_template_argument_list (pp);
2218 pp_newline_and_indent (pp, 3);
2221 if (tree c = DECL_CONSTRAINTS (t))
2223 pp_cxx_ws_string (pp, "requires");
2224 pp->expression (CI_REQUIREMENTS (c));
2225 pp_newline_and_indent (pp, 6);
2228 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2229 pp_cxx_function_definition (pp, t);
2230 else
2231 pp_cxx_simple_declaration (pp, t);
2234 static void
2235 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2237 pp_unsupported_tree (pp, t);
2240 static void
2241 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2243 pp_unsupported_tree (pp, t);
2247 declaration:
2248 block-declaration
2249 function-definition
2250 template-declaration
2251 explicit-instantiation
2252 explicit-specialization
2253 linkage-specification
2254 namespace-definition
2256 block-declaration:
2257 simple-declaration
2258 asm-definition
2259 namespace-alias-definition
2260 using-declaration
2261 using-directive
2262 static_assert-declaration */
2263 void
2264 cxx_pretty_printer::declaration (tree t)
2266 if (TREE_CODE (t) == STATIC_ASSERT)
2268 pp_cxx_ws_string (this, "static_assert");
2269 pp_cxx_left_paren (this);
2270 expression (STATIC_ASSERT_CONDITION (t));
2271 pp_cxx_separate_with (this, ',');
2272 expression (STATIC_ASSERT_MESSAGE (t));
2273 pp_cxx_right_paren (this);
2275 else if (!DECL_LANG_SPECIFIC (t))
2276 pp_cxx_simple_declaration (this, t);
2277 else if (DECL_USE_TEMPLATE (t))
2278 switch (DECL_USE_TEMPLATE (t))
2280 case 1:
2281 pp_cxx_template_declaration (this, t);
2282 break;
2284 case 2:
2285 pp_cxx_explicit_specialization (this, t);
2286 break;
2288 case 3:
2289 pp_cxx_explicit_instantiation (this, t);
2290 break;
2292 default:
2293 break;
2295 else switch (TREE_CODE (t))
2297 case VAR_DECL:
2298 case TYPE_DECL:
2299 pp_cxx_simple_declaration (this, t);
2300 break;
2302 case FUNCTION_DECL:
2303 if (DECL_SAVED_TREE (t))
2304 pp_cxx_function_definition (this, t);
2305 else
2306 pp_cxx_simple_declaration (this, t);
2307 break;
2309 case NAMESPACE_DECL:
2310 if (DECL_NAMESPACE_ALIAS (t))
2311 pp_cxx_namespace_alias_definition (this, t);
2312 else
2313 pp_cxx_original_namespace_definition (this, t);
2314 break;
2316 default:
2317 pp_unsupported_tree (this, t);
2318 break;
2322 static void
2323 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2325 t = TREE_OPERAND (t, 0);
2326 pp_cxx_ws_string (pp, "typeid");
2327 pp_cxx_left_paren (pp);
2328 if (TYPE_P (t))
2329 pp->type_id (t);
2330 else
2331 pp->expression (t);
2332 pp_cxx_right_paren (pp);
2335 void
2336 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2338 pp_cxx_ws_string (pp, "va_arg");
2339 pp_cxx_left_paren (pp);
2340 pp->assignment_expression (TREE_OPERAND (t, 0));
2341 pp_cxx_separate_with (pp, ',');
2342 pp->type_id (TREE_TYPE (t));
2343 pp_cxx_right_paren (pp);
2346 static bool
2347 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2349 switch (TREE_CODE (t))
2351 case ARROW_EXPR:
2352 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2353 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2355 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2356 pp_cxx_separate_with (pp, ',');
2357 return true;
2359 return false;
2360 case COMPONENT_REF:
2361 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2362 return false;
2363 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2364 pp_cxx_dot (pp);
2365 pp->expression (TREE_OPERAND (t, 1));
2366 return true;
2367 case ARRAY_REF:
2368 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2369 return false;
2370 pp_left_bracket (pp);
2371 pp->expression (TREE_OPERAND (t, 1));
2372 pp_right_bracket (pp);
2373 return true;
2374 default:
2375 return false;
2379 void
2380 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2382 pp_cxx_ws_string (pp, "offsetof");
2383 pp_cxx_left_paren (pp);
2384 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2385 pp->expression (TREE_OPERAND (t, 0));
2386 pp_cxx_right_paren (pp);
2389 void
2390 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2392 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2394 switch (kind)
2396 case CPTK_HAS_NOTHROW_ASSIGN:
2397 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2398 break;
2399 case CPTK_HAS_TRIVIAL_ASSIGN:
2400 pp_cxx_ws_string (pp, "__has_trivial_assign");
2401 break;
2402 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2403 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2404 break;
2405 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2406 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2407 break;
2408 case CPTK_HAS_NOTHROW_COPY:
2409 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2410 break;
2411 case CPTK_HAS_TRIVIAL_COPY:
2412 pp_cxx_ws_string (pp, "__has_trivial_copy");
2413 break;
2414 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2415 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2416 break;
2417 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2418 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2419 break;
2420 case CPTK_IS_ABSTRACT:
2421 pp_cxx_ws_string (pp, "__is_abstract");
2422 break;
2423 case CPTK_IS_BASE_OF:
2424 pp_cxx_ws_string (pp, "__is_base_of");
2425 break;
2426 case CPTK_IS_CLASS:
2427 pp_cxx_ws_string (pp, "__is_class");
2428 break;
2429 case CPTK_IS_CONVERTIBLE_TO:
2430 pp_cxx_ws_string (pp, "__is_convertible_to");
2431 break;
2432 case CPTK_IS_EMPTY:
2433 pp_cxx_ws_string (pp, "__is_empty");
2434 break;
2435 case CPTK_IS_ENUM:
2436 pp_cxx_ws_string (pp, "__is_enum");
2437 break;
2438 case CPTK_IS_FINAL:
2439 pp_cxx_ws_string (pp, "__is_final");
2440 break;
2441 case CPTK_IS_POD:
2442 pp_cxx_ws_string (pp, "__is_pod");
2443 break;
2444 case CPTK_IS_POLYMORPHIC:
2445 pp_cxx_ws_string (pp, "__is_polymorphic");
2446 break;
2447 case CPTK_IS_SAME_AS:
2448 pp_cxx_ws_string (pp, "__is_same_as");
2449 break;
2450 case CPTK_IS_STD_LAYOUT:
2451 pp_cxx_ws_string (pp, "__is_std_layout");
2452 break;
2453 case CPTK_IS_TRIVIAL:
2454 pp_cxx_ws_string (pp, "__is_trivial");
2455 break;
2456 case CPTK_IS_UNION:
2457 pp_cxx_ws_string (pp, "__is_union");
2458 break;
2459 case CPTK_IS_LITERAL_TYPE:
2460 pp_cxx_ws_string (pp, "__is_literal_type");
2461 break;
2463 default:
2464 gcc_unreachable ();
2467 pp_cxx_left_paren (pp);
2468 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2470 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2472 pp_cxx_separate_with (pp, ',');
2473 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2476 pp_cxx_right_paren (pp);
2479 // requirement-list:
2480 // requirement
2481 // requirement-list ';' requirement[opt]
2483 // requirement:
2484 // simple-requirement
2485 // compound-requirement
2486 // type-requirement
2487 // nested-requirement
2488 static void
2489 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2491 int n = 3;
2492 while (t) {
2493 pp_newline_and_indent (pp, n);
2494 pp->expression (TREE_VALUE (t));
2495 n = 0;
2496 t = TREE_CHAIN (t);
2498 pp_newline_and_indent (pp, -3);
2501 // requirement-body:
2502 // '{' requirement-list '}'
2503 static void
2504 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2506 pp_cxx_left_brace (pp);
2507 pp_cxx_requirement_list (pp, t);
2508 pp_cxx_right_brace (pp);
2511 // requires-expression:
2512 // 'requires' requirement-parameter-list requirement-body
2513 void
2514 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2516 pp_cxx_ws_string (pp, "requires");
2517 pp_space (pp);
2518 pp_cxx_parameter_declaration_clause (pp, TREE_OPERAND (t, 0));
2519 pp_space (pp);
2520 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2523 // constraint-specifier:
2524 // noexcept
2525 // constexpr
2526 static void
2527 pp_cxx_constraint_specifier (cxx_pretty_printer *pp, tree t)
2529 if (TREE_CODE (t) == NOEXCEPT_EXPR)
2530 pp_cxx_ws_string (pp, "noexcept");
2531 else if (TREE_CODE (t) == CONSTEXPR_EXPR)
2532 pp_cxx_ws_string (pp, "constexpr");
2533 else
2534 gcc_unreachable ();
2537 // compound-requirement:
2538 // '{' expression '}' trailing-constraint-specifiers
2540 // trailing-constraint-specifiers:
2541 // constraint-specifiers-seq[opt] result-type-requirement[opt]
2543 // result-type-requirement:
2544 // '->' type-id
2545 static void
2546 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2548 // Get the expression requirement.
2549 tree ereq = TREE_OPERAND (t, 0);
2551 // Find the tree node containing the result type requirement.
2552 // Note that validtype requirements are implicit.
2553 tree treq = TREE_CHAIN (ereq);
2554 if (TREE_CODE (TREE_VALUE (treq)) == VALIDTYPE_EXPR)
2555 treq = TREE_CHAIN (treq);
2557 // Find tree nodes for any additional constraint specifiers.
2558 tree spec1 = TREE_CHAIN (treq);
2559 tree spec2 = spec1 ? TREE_CHAIN (spec1) : NULL_TREE;
2561 // Pretty print the {expr} requirement
2562 tree expr = TREE_OPERAND (TREE_VALUE (ereq), 0);
2563 pp_cxx_left_brace (pp);
2564 pp->expression (expr);
2565 pp_cxx_right_brace (pp);
2567 // Pretty constraint specifiers, if any.
2568 if (spec1)
2570 pp_space (pp);
2571 pp_cxx_constraint_specifier (pp, TREE_VALUE (spec1));
2572 if (spec2)
2573 pp_cxx_constraint_specifier (pp, TREE_VALUE (spec2));
2576 // Pretty print the '-> type-id' part of the expression.
2577 // Note that treq will contain a TRAIT_EXPR.
2578 if (treq)
2580 tree type = TRAIT_EXPR_TYPE2 (TREE_VALUE (treq));
2581 pp_space (pp);
2582 pp_cxx_arrow (pp);
2583 pp_space (pp);
2584 pp->type_id (type);
2588 // simple-requirement:
2589 // expression
2590 static void
2591 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2593 tree req = TREE_OPERAND (t, 0);
2594 pp->expression (TREE_OPERAND (req, 0));
2597 void
2598 pp_cxx_expr_requirement (cxx_pretty_printer *pp, tree t)
2600 tree reqs = TREE_OPERAND (t, 0);
2601 if (TREE_CODE (reqs) == TREE_LIST)
2602 pp_cxx_compound_requirement (pp, t);
2603 else
2604 pp_cxx_simple_requirement (pp, t);
2605 pp_cxx_semicolon (pp);
2608 // type-requirement:
2609 // type-id
2610 void
2611 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2613 tree req = TREE_OPERAND (t, 0);
2614 pp->type_id (TREE_OPERAND (req, 0));
2615 pp_cxx_semicolon (pp);
2618 // nested requirement:
2619 // 'requires' logical-or-expression
2620 void
2621 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2623 pp_cxx_ws_string (pp, "requires");
2624 pp->expression (TREE_OPERAND (t, 0));
2625 pp_cxx_semicolon (pp);
2628 void
2629 pp_cxx_validexpr_expr (cxx_pretty_printer *pp, tree t)
2631 pp_cxx_ws_string (pp, "__is_valid_expr");
2632 pp_cxx_left_paren (pp);
2633 pp->expression (TREE_OPERAND (t, 0));
2634 pp_cxx_right_paren (pp);
2637 void
2638 pp_cxx_validtype_expr (cxx_pretty_printer *pp, tree t)
2640 pp_cxx_ws_string (pp, "__is_valid_expr");
2641 pp_cxx_left_paren (pp);
2642 pp->type_id(TREE_OPERAND (t, 0));
2643 pp_cxx_right_paren (pp);
2646 void
2647 pp_cxx_constexpr_expr (cxx_pretty_printer *pp, tree t)
2649 pp_cxx_ws_string (pp, "__is_valid_expr");
2650 pp_cxx_left_paren (pp);
2651 pp->expression (TREE_OPERAND (t, 0));
2652 pp_cxx_right_paren (pp);
2656 typedef c_pretty_print_fn pp_fun;
2658 /* Initialization of a C++ pretty-printer object. */
2660 cxx_pretty_printer::cxx_pretty_printer ()
2661 : c_pretty_printer (),
2662 enclosing_scope (global_namespace)
2664 pp_set_line_maximum_length (this, 0);
2666 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2667 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;