Merge from trunk.
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob36bc8d20f58c8b9a782ef75a1ea6ed66b464a848
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 VOID_CST:
406 case INTEGER_CST:
407 case REAL_CST:
408 case COMPLEX_CST:
409 case STRING_CST:
410 constant (t);
411 break;
413 case USERDEF_LITERAL:
414 pp_cxx_userdef_literal (this, t);
415 break;
417 case BASELINK:
418 t = BASELINK_FUNCTIONS (t);
419 case VAR_DECL:
420 case PARM_DECL:
421 case FIELD_DECL:
422 case FUNCTION_DECL:
423 case OVERLOAD:
424 case CONST_DECL:
425 case TEMPLATE_DECL:
426 id_expression (t);
427 break;
429 case RESULT_DECL:
430 case TEMPLATE_TYPE_PARM:
431 case TEMPLATE_TEMPLATE_PARM:
432 case TEMPLATE_PARM_INDEX:
433 pp_cxx_unqualified_id (this, t);
434 break;
436 case STMT_EXPR:
437 pp_cxx_left_paren (this);
438 statement (STMT_EXPR_STMT (t));
439 pp_cxx_right_paren (this);
440 break;
442 case TRAIT_EXPR:
443 pp_cxx_trait_expression (this, t);
444 break;
446 case VA_ARG_EXPR:
447 pp_cxx_va_arg_expression (this, t);
448 break;
450 case OFFSETOF_EXPR:
451 pp_cxx_offsetof_expression (this, t);
452 break;
454 case REQUIRES_EXPR:
455 pp_cxx_requires_expr (this, t);
456 break;
458 case EXPR_REQ:
459 pp_cxx_expr_requirement (this, t);
460 break;
462 case TYPE_REQ:
463 pp_cxx_type_requirement (this, t);
464 break;
466 case NESTED_REQ:
467 pp_cxx_nested_requirement (this, t);
468 break;
470 case VALIDEXPR_EXPR:
471 pp_cxx_validexpr_expr (this, t);
472 break;
474 case VALIDTYPE_EXPR:
475 pp_cxx_validtype_expr (this, t);
476 break;
478 case CONSTEXPR_EXPR:
479 pp_cxx_constexpr_expr (this, t);
480 break;
482 default:
483 c_pretty_printer::primary_expression (t);
484 break;
488 /* postfix-expression:
489 primary-expression
490 postfix-expression [ expression ]
491 postfix-expression ( expression-list(opt) )
492 simple-type-specifier ( expression-list(opt) )
493 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
494 typename ::(opt) nested-name-specifier template(opt)
495 template-id ( expression-list(opt) )
496 postfix-expression . template(opt) ::(opt) id-expression
497 postfix-expression -> template(opt) ::(opt) id-expression
498 postfix-expression . pseudo-destructor-name
499 postfix-expression -> pseudo-destructor-name
500 postfix-expression ++
501 postfix-expression --
502 dynamic_cast < type-id > ( expression )
503 static_cast < type-id > ( expression )
504 reinterpret_cast < type-id > ( expression )
505 const_cast < type-id > ( expression )
506 typeid ( expression )
507 typeid ( type-id ) */
509 void
510 cxx_pretty_printer::postfix_expression (tree t)
512 enum tree_code code = TREE_CODE (t);
514 switch (code)
516 case AGGR_INIT_EXPR:
517 case CALL_EXPR:
519 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
520 : CALL_EXPR_FN (t));
521 tree saved_scope = enclosing_scope;
522 bool skipfirst = false;
523 tree arg;
525 if (TREE_CODE (fun) == ADDR_EXPR)
526 fun = TREE_OPERAND (fun, 0);
528 /* In templates, where there is no way to tell whether a given
529 call uses an actual member function. So the parser builds
530 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
531 instantiation time. */
532 if (TREE_CODE (fun) != FUNCTION_DECL)
534 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
536 tree object = (code == AGGR_INIT_EXPR
537 ? (AGGR_INIT_VIA_CTOR_P (t)
538 ? AGGR_INIT_EXPR_SLOT (t)
539 : AGGR_INIT_EXPR_ARG (t, 0))
540 : CALL_EXPR_ARG (t, 0));
542 while (TREE_CODE (object) == NOP_EXPR)
543 object = TREE_OPERAND (object, 0);
545 if (TREE_CODE (object) == ADDR_EXPR)
546 object = TREE_OPERAND (object, 0);
548 if (!TYPE_PTR_P (TREE_TYPE (object)))
550 postfix_expression (object);
551 pp_cxx_dot (this);
553 else
555 postfix_expression (object);
556 pp_cxx_arrow (this);
558 skipfirst = true;
559 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
562 postfix_expression (fun);
563 enclosing_scope = saved_scope;
564 pp_cxx_left_paren (this);
565 if (code == AGGR_INIT_EXPR)
567 aggr_init_expr_arg_iterator iter;
568 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
570 if (skipfirst)
571 skipfirst = false;
572 else
574 expression (arg);
575 if (more_aggr_init_expr_args_p (&iter))
576 pp_cxx_separate_with (this, ',');
580 else
582 call_expr_arg_iterator iter;
583 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
585 if (skipfirst)
586 skipfirst = false;
587 else
589 expression (arg);
590 if (more_call_expr_args_p (&iter))
591 pp_cxx_separate_with (this, ',');
595 pp_cxx_right_paren (this);
597 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
599 pp_cxx_separate_with (this, ',');
600 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
602 break;
604 case BASELINK:
605 case VAR_DECL:
606 case PARM_DECL:
607 case FIELD_DECL:
608 case FUNCTION_DECL:
609 case OVERLOAD:
610 case CONST_DECL:
611 case TEMPLATE_DECL:
612 case RESULT_DECL:
613 primary_expression (t);
614 break;
616 case DYNAMIC_CAST_EXPR:
617 case STATIC_CAST_EXPR:
618 case REINTERPRET_CAST_EXPR:
619 case CONST_CAST_EXPR:
620 if (code == DYNAMIC_CAST_EXPR)
621 pp_cxx_ws_string (this, "dynamic_cast");
622 else if (code == STATIC_CAST_EXPR)
623 pp_cxx_ws_string (this, "static_cast");
624 else if (code == REINTERPRET_CAST_EXPR)
625 pp_cxx_ws_string (this, "reinterpret_cast");
626 else
627 pp_cxx_ws_string (this, "const_cast");
628 pp_cxx_begin_template_argument_list (this);
629 type_id (TREE_TYPE (t));
630 pp_cxx_end_template_argument_list (this);
631 pp_left_paren (this);
632 expression (TREE_OPERAND (t, 0));
633 pp_right_paren (this);
634 break;
636 case EMPTY_CLASS_EXPR:
637 type_id (TREE_TYPE (t));
638 pp_left_paren (this);
639 pp_right_paren (this);
640 break;
642 case TYPEID_EXPR:
643 pp_cxx_typeid_expression (this, t);
644 break;
646 case PSEUDO_DTOR_EXPR:
647 postfix_expression (TREE_OPERAND (t, 0));
648 pp_cxx_dot (this);
649 if (TREE_OPERAND (t, 1))
651 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
652 pp_cxx_colon_colon (this);
654 pp_complement (this);
655 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
656 break;
658 case ARROW_EXPR:
659 postfix_expression (TREE_OPERAND (t, 0));
660 pp_cxx_arrow (this);
661 break;
663 default:
664 c_pretty_printer::postfix_expression (t);
665 break;
669 /* new-expression:
670 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
671 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
673 new-placement:
674 ( expression-list )
676 new-type-id:
677 type-specifier-seq new-declarator(opt)
679 new-declarator:
680 ptr-operator new-declarator(opt)
681 direct-new-declarator
683 direct-new-declarator
684 [ expression ]
685 direct-new-declarator [ constant-expression ]
687 new-initializer:
688 ( expression-list(opt) ) */
690 static void
691 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
693 enum tree_code code = TREE_CODE (t);
694 tree type = TREE_OPERAND (t, 1);
695 tree init = TREE_OPERAND (t, 2);
696 switch (code)
698 case NEW_EXPR:
699 case VEC_NEW_EXPR:
700 if (NEW_EXPR_USE_GLOBAL (t))
701 pp_cxx_colon_colon (pp);
702 pp_cxx_ws_string (pp, "new");
703 if (TREE_OPERAND (t, 0))
705 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
706 pp_space (pp);
708 if (TREE_CODE (type) == ARRAY_REF)
709 type = build_cplus_array_type
710 (TREE_OPERAND (type, 0),
711 build_index_type (fold_build2_loc (input_location,
712 MINUS_EXPR, integer_type_node,
713 TREE_OPERAND (type, 1),
714 integer_one_node)));
715 pp->type_id (type);
716 if (init)
718 pp_left_paren (pp);
719 if (TREE_CODE (init) == TREE_LIST)
720 pp_c_expression_list (pp, init);
721 else if (init == void_node)
722 ; /* OK, empty initializer list. */
723 else
724 pp->expression (init);
725 pp_right_paren (pp);
727 break;
729 default:
730 pp_unsupported_tree (pp, t);
734 /* delete-expression:
735 ::(opt) delete cast-expression
736 ::(opt) delete [ ] cast-expression */
738 static void
739 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
741 enum tree_code code = TREE_CODE (t);
742 switch (code)
744 case DELETE_EXPR:
745 case VEC_DELETE_EXPR:
746 if (DELETE_EXPR_USE_GLOBAL (t))
747 pp_cxx_colon_colon (pp);
748 pp_cxx_ws_string (pp, "delete");
749 pp_space (pp);
750 if (code == VEC_DELETE_EXPR
751 || DELETE_EXPR_USE_VEC (t))
753 pp_left_bracket (pp);
754 pp_right_bracket (pp);
755 pp_space (pp);
757 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
758 break;
760 default:
761 pp_unsupported_tree (pp, t);
765 /* unary-expression:
766 postfix-expression
767 ++ cast-expression
768 -- cast-expression
769 unary-operator cast-expression
770 sizeof unary-expression
771 sizeof ( type-id )
772 sizeof ... ( identifier )
773 new-expression
774 delete-expression
776 unary-operator: one of
777 * & + - !
779 GNU extensions:
780 __alignof__ unary-expression
781 __alignof__ ( type-id ) */
783 void
784 cxx_pretty_printer::unary_expression (tree t)
786 enum tree_code code = TREE_CODE (t);
787 switch (code)
789 case NEW_EXPR:
790 case VEC_NEW_EXPR:
791 pp_cxx_new_expression (this, t);
792 break;
794 case DELETE_EXPR:
795 case VEC_DELETE_EXPR:
796 pp_cxx_delete_expression (this, t);
797 break;
799 case SIZEOF_EXPR:
800 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
802 pp_cxx_ws_string (this, "sizeof");
803 pp_cxx_ws_string (this, "...");
804 pp_cxx_whitespace (this);
805 pp_cxx_left_paren (this);
806 if (TYPE_P (TREE_OPERAND (t, 0)))
807 type_id (TREE_OPERAND (t, 0));
808 else
809 unary_expression (TREE_OPERAND (t, 0));
810 pp_cxx_right_paren (this);
811 break;
813 /* Fall through */
815 case ALIGNOF_EXPR:
816 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
817 pp_cxx_whitespace (this);
818 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
820 pp_cxx_left_paren (this);
821 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
822 pp_cxx_right_paren (this);
824 else if (TYPE_P (TREE_OPERAND (t, 0)))
826 pp_cxx_left_paren (this);
827 type_id (TREE_OPERAND (t, 0));
828 pp_cxx_right_paren (this);
830 else
831 unary_expression (TREE_OPERAND (t, 0));
832 break;
834 case AT_ENCODE_EXPR:
835 pp_cxx_ws_string (this, "@encode");
836 pp_cxx_whitespace (this);
837 pp_cxx_left_paren (this);
838 type_id (TREE_OPERAND (t, 0));
839 pp_cxx_right_paren (this);
840 break;
842 case NOEXCEPT_EXPR:
843 pp_cxx_ws_string (this, "noexcept");
844 pp_cxx_whitespace (this);
845 pp_cxx_left_paren (this);
846 expression (TREE_OPERAND (t, 0));
847 pp_cxx_right_paren (this);
848 break;
850 case UNARY_PLUS_EXPR:
851 pp_plus (this);
852 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
853 break;
855 default:
856 c_pretty_printer::unary_expression (t);
857 break;
861 /* cast-expression:
862 unary-expression
863 ( type-id ) cast-expression */
865 static void
866 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
868 switch (TREE_CODE (t))
870 case CAST_EXPR:
871 case IMPLICIT_CONV_EXPR:
872 pp->type_id (TREE_TYPE (t));
873 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
874 break;
876 default:
877 pp_c_cast_expression (pp, t);
878 break;
882 /* pm-expression:
883 cast-expression
884 pm-expression .* cast-expression
885 pm-expression ->* cast-expression */
887 static void
888 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
890 switch (TREE_CODE (t))
892 /* Handle unfortunate OFFSET_REF overloading here. */
893 case OFFSET_REF:
894 if (TYPE_P (TREE_OPERAND (t, 0)))
896 pp_cxx_qualified_id (pp, t);
897 break;
899 /* Else fall through. */
900 case MEMBER_REF:
901 case DOTSTAR_EXPR:
902 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
903 if (TREE_CODE (t) == MEMBER_REF)
904 pp_cxx_arrow (pp);
905 else
906 pp_cxx_dot (pp);
907 pp_star(pp);
908 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
909 break;
912 default:
913 pp_cxx_cast_expression (pp, t);
914 break;
918 /* multiplicative-expression:
919 pm-expression
920 multiplicative-expression * pm-expression
921 multiplicative-expression / pm-expression
922 multiplicative-expression % pm-expression */
924 void
925 cxx_pretty_printer::multiplicative_expression (tree e)
927 enum tree_code code = TREE_CODE (e);
928 switch (code)
930 case MULT_EXPR:
931 case TRUNC_DIV_EXPR:
932 case TRUNC_MOD_EXPR:
933 multiplicative_expression (TREE_OPERAND (e, 0));
934 pp_space (this);
935 if (code == MULT_EXPR)
936 pp_star (this);
937 else if (code == TRUNC_DIV_EXPR)
938 pp_slash (this);
939 else
940 pp_modulo (this);
941 pp_space (this);
942 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
943 break;
945 default:
946 pp_cxx_pm_expression (this, e);
947 break;
951 /* conditional-expression:
952 logical-or-expression
953 logical-or-expression ? expression : assignment-expression */
955 void
956 cxx_pretty_printer::conditional_expression (tree e)
958 if (TREE_CODE (e) == COND_EXPR)
960 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
961 pp_space (this);
962 pp_question (this);
963 pp_space (this);
964 expression (TREE_OPERAND (e, 1));
965 pp_space (this);
966 assignment_expression (TREE_OPERAND (e, 2));
968 else
969 pp_c_logical_or_expression (this, e);
972 /* Pretty-print a compound assignment operator token as indicated by T. */
974 static void
975 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
977 const char *op;
979 switch (TREE_CODE (t))
981 case NOP_EXPR:
982 op = "=";
983 break;
985 case PLUS_EXPR:
986 op = "+=";
987 break;
989 case MINUS_EXPR:
990 op = "-=";
991 break;
993 case TRUNC_DIV_EXPR:
994 op = "/=";
995 break;
997 case TRUNC_MOD_EXPR:
998 op = "%=";
999 break;
1001 default:
1002 op = get_tree_code_name (TREE_CODE (t));
1003 break;
1006 pp_cxx_ws_string (pp, op);
1010 /* assignment-expression:
1011 conditional-expression
1012 logical-or-expression assignment-operator assignment-expression
1013 throw-expression
1015 throw-expression:
1016 throw assignment-expression(opt)
1018 assignment-operator: one of
1019 = *= /= %= += -= >>= <<= &= ^= |= */
1021 void
1022 cxx_pretty_printer::assignment_expression (tree e)
1024 switch (TREE_CODE (e))
1026 case MODIFY_EXPR:
1027 case INIT_EXPR:
1028 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1029 pp_space (this);
1030 pp_equal (this);
1031 pp_space (this);
1032 assignment_expression (TREE_OPERAND (e, 1));
1033 break;
1035 case THROW_EXPR:
1036 pp_cxx_ws_string (this, "throw");
1037 if (TREE_OPERAND (e, 0))
1038 assignment_expression (TREE_OPERAND (e, 0));
1039 break;
1041 case MODOP_EXPR:
1042 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1043 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1044 assignment_expression (TREE_OPERAND (e, 2));
1045 break;
1047 default:
1048 conditional_expression (e);
1049 break;
1053 void
1054 cxx_pretty_printer::expression (tree t)
1056 switch (TREE_CODE (t))
1058 case STRING_CST:
1059 case VOID_CST:
1060 case INTEGER_CST:
1061 case REAL_CST:
1062 case COMPLEX_CST:
1063 constant (t);
1064 break;
1066 case USERDEF_LITERAL:
1067 pp_cxx_userdef_literal (this, t);
1068 break;
1070 case RESULT_DECL:
1071 pp_cxx_unqualified_id (this, t);
1072 break;
1074 #if 0
1075 case OFFSET_REF:
1076 #endif
1077 case SCOPE_REF:
1078 case PTRMEM_CST:
1079 pp_cxx_qualified_id (this, t);
1080 break;
1082 case OVERLOAD:
1083 t = OVL_CURRENT (t);
1084 case VAR_DECL:
1085 case PARM_DECL:
1086 case FIELD_DECL:
1087 case CONST_DECL:
1088 case FUNCTION_DECL:
1089 case BASELINK:
1090 case TEMPLATE_DECL:
1091 case TEMPLATE_TYPE_PARM:
1092 case TEMPLATE_PARM_INDEX:
1093 case TEMPLATE_TEMPLATE_PARM:
1094 case STMT_EXPR:
1095 case REQUIRES_EXPR:
1096 case EXPR_REQ:
1097 case TYPE_REQ:
1098 case NESTED_REQ:
1099 primary_expression (t);
1100 break;
1102 case CALL_EXPR:
1103 case DYNAMIC_CAST_EXPR:
1104 case STATIC_CAST_EXPR:
1105 case REINTERPRET_CAST_EXPR:
1106 case CONST_CAST_EXPR:
1107 #if 0
1108 case MEMBER_REF:
1109 #endif
1110 case EMPTY_CLASS_EXPR:
1111 case TYPEID_EXPR:
1112 case PSEUDO_DTOR_EXPR:
1113 case AGGR_INIT_EXPR:
1114 case ARROW_EXPR:
1115 postfix_expression (t);
1116 break;
1118 case NEW_EXPR:
1119 case VEC_NEW_EXPR:
1120 pp_cxx_new_expression (this, t);
1121 break;
1123 case DELETE_EXPR:
1124 case VEC_DELETE_EXPR:
1125 pp_cxx_delete_expression (this, t);
1126 break;
1128 case SIZEOF_EXPR:
1129 case ALIGNOF_EXPR:
1130 case NOEXCEPT_EXPR:
1131 unary_expression (t);
1132 break;
1134 case CAST_EXPR:
1135 case IMPLICIT_CONV_EXPR:
1136 pp_cxx_cast_expression (this, t);
1137 break;
1139 case OFFSET_REF:
1140 case MEMBER_REF:
1141 case DOTSTAR_EXPR:
1142 pp_cxx_pm_expression (this, t);
1143 break;
1145 case MULT_EXPR:
1146 case TRUNC_DIV_EXPR:
1147 case TRUNC_MOD_EXPR:
1148 multiplicative_expression (t);
1149 break;
1151 case COND_EXPR:
1152 conditional_expression (t);
1153 break;
1155 case MODIFY_EXPR:
1156 case INIT_EXPR:
1157 case THROW_EXPR:
1158 case MODOP_EXPR:
1159 assignment_expression (t);
1160 break;
1162 case NON_DEPENDENT_EXPR:
1163 case MUST_NOT_THROW_EXPR:
1164 expression (TREE_OPERAND (t, 0));
1165 break;
1167 case EXPR_PACK_EXPANSION:
1168 expression (PACK_EXPANSION_PATTERN (t));
1169 pp_cxx_ws_string (this, "...");
1170 break;
1172 case TEMPLATE_ID_EXPR:
1173 pp_cxx_template_id (this, t);
1174 break;
1176 case NONTYPE_ARGUMENT_PACK:
1178 tree args = ARGUMENT_PACK_ARGS (t);
1179 int i, len = TREE_VEC_LENGTH (args);
1180 for (i = 0; i < len; ++i)
1182 if (i > 0)
1183 pp_cxx_separate_with (this, ',');
1184 expression (TREE_VEC_ELT (args, i));
1187 break;
1189 case LAMBDA_EXPR:
1190 pp_cxx_ws_string (this, "<lambda>");
1191 break;
1193 case PAREN_EXPR:
1194 pp_cxx_left_paren (this);
1195 expression (TREE_OPERAND (t, 0));
1196 pp_cxx_right_paren (this);
1197 break;
1199 default:
1200 c_pretty_printer::expression (t);
1201 break;
1206 /* Declarations. */
1208 /* function-specifier:
1209 inline
1210 virtual
1211 explicit */
1213 void
1214 cxx_pretty_printer::function_specifier (tree t)
1216 switch (TREE_CODE (t))
1218 case FUNCTION_DECL:
1219 if (DECL_VIRTUAL_P (t))
1220 pp_cxx_ws_string (this, "virtual");
1221 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1222 pp_cxx_ws_string (this, "explicit");
1223 else
1224 c_pretty_printer::function_specifier (t);
1226 default:
1227 break;
1231 /* decl-specifier-seq:
1232 decl-specifier-seq(opt) decl-specifier
1234 decl-specifier:
1235 storage-class-specifier
1236 type-specifier
1237 function-specifier
1238 friend
1239 typedef */
1241 void
1242 cxx_pretty_printer::declaration_specifiers (tree t)
1244 switch (TREE_CODE (t))
1246 case VAR_DECL:
1247 case PARM_DECL:
1248 case CONST_DECL:
1249 case FIELD_DECL:
1250 storage_class_specifier (t);
1251 declaration_specifiers (TREE_TYPE (t));
1252 break;
1254 case TYPE_DECL:
1255 pp_cxx_ws_string (this, "typedef");
1256 declaration_specifiers (TREE_TYPE (t));
1257 break;
1259 case FUNCTION_DECL:
1260 /* Constructors don't have return types. And conversion functions
1261 do not have a type-specifier in their return types. */
1262 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1263 function_specifier (t);
1264 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1265 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1266 else
1267 default:
1268 c_pretty_printer::declaration_specifiers (t);
1269 break;
1273 /* simple-type-specifier:
1274 ::(opt) nested-name-specifier(opt) type-name
1275 ::(opt) nested-name-specifier(opt) template(opt) template-id
1276 char
1277 wchar_t
1278 bool
1279 short
1281 long
1282 signed
1283 unsigned
1284 float
1285 double
1286 void */
1288 void
1289 cxx_pretty_printer::simple_type_specifier (tree t)
1291 switch (TREE_CODE (t))
1293 case RECORD_TYPE:
1294 case UNION_TYPE:
1295 case ENUMERAL_TYPE:
1296 pp_cxx_qualified_id (this, t);
1297 break;
1299 case TEMPLATE_TYPE_PARM:
1300 case TEMPLATE_TEMPLATE_PARM:
1301 case TEMPLATE_PARM_INDEX:
1302 case BOUND_TEMPLATE_TEMPLATE_PARM:
1303 pp_cxx_unqualified_id (this, t);
1304 break;
1306 case TYPENAME_TYPE:
1307 pp_cxx_ws_string (this, "typename");
1308 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1309 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1310 break;
1312 default:
1313 c_pretty_printer::simple_type_specifier (t);
1314 break;
1318 /* type-specifier-seq:
1319 type-specifier type-specifier-seq(opt)
1321 type-specifier:
1322 simple-type-specifier
1323 class-specifier
1324 enum-specifier
1325 elaborated-type-specifier
1326 cv-qualifier */
1328 static void
1329 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1331 switch (TREE_CODE (t))
1333 case TEMPLATE_DECL:
1334 case TEMPLATE_TYPE_PARM:
1335 case TEMPLATE_TEMPLATE_PARM:
1336 case TYPE_DECL:
1337 case BOUND_TEMPLATE_TEMPLATE_PARM:
1338 pp_cxx_cv_qualifier_seq (pp, t);
1339 pp->simple_type_specifier (t);
1340 break;
1342 case METHOD_TYPE:
1343 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1344 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1345 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1346 break;
1348 case DECLTYPE_TYPE:
1349 pp_cxx_ws_string (pp, "decltype");
1350 pp_cxx_left_paren (pp);
1351 pp->expression (DECLTYPE_TYPE_EXPR (t));
1352 pp_cxx_right_paren (pp);
1353 break;
1355 case RECORD_TYPE:
1356 if (TYPE_PTRMEMFUNC_P (t))
1358 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1359 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1360 pp_cxx_whitespace (pp);
1361 pp_cxx_ptr_operator (pp, t);
1362 break;
1364 /* else fall through */
1366 default:
1367 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1368 pp_c_specifier_qualifier_list (pp, t);
1372 /* ptr-operator:
1373 * cv-qualifier-seq(opt)
1375 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1377 static void
1378 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1380 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1381 t = TREE_TYPE (t);
1382 switch (TREE_CODE (t))
1384 case REFERENCE_TYPE:
1385 case POINTER_TYPE:
1386 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1387 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1388 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1389 if (TYPE_PTR_P (t))
1391 pp_star (pp);
1392 pp_cxx_cv_qualifier_seq (pp, t);
1394 else
1395 pp_ampersand (pp);
1396 break;
1398 case RECORD_TYPE:
1399 if (TYPE_PTRMEMFUNC_P (t))
1401 pp_cxx_left_paren (pp);
1402 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1403 pp_star (pp);
1404 break;
1406 case OFFSET_TYPE:
1407 if (TYPE_PTRMEM_P (t))
1409 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1410 pp_cxx_left_paren (pp);
1411 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1412 pp_star (pp);
1413 pp_cxx_cv_qualifier_seq (pp, t);
1414 break;
1416 /* else fall through. */
1418 default:
1419 pp_unsupported_tree (pp, t);
1420 break;
1424 static inline tree
1425 pp_cxx_implicit_parameter_type (tree mf)
1427 return class_of_this_parm (TREE_TYPE (mf));
1431 parameter-declaration:
1432 decl-specifier-seq declarator
1433 decl-specifier-seq declarator = assignment-expression
1434 decl-specifier-seq abstract-declarator(opt)
1435 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1437 static inline void
1438 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1440 pp->declaration_specifiers (t);
1441 if (TYPE_P (t))
1442 pp->abstract_declarator (t);
1443 else
1444 pp->declarator (t);
1447 /* parameter-declaration-clause:
1448 parameter-declaration-list(opt) ...(opt)
1449 parameter-declaration-list , ...
1451 parameter-declaration-list:
1452 parameter-declaration
1453 parameter-declaration-list , parameter-declaration */
1455 void
1456 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1458 tree args;
1459 tree types;
1460 bool abstract;
1462 // For a requires clause or the explicit printing of a parameter list
1463 // we expect T to be a TREE_LIST of PARM_DECLs. Otherwise, the list of
1464 // args and types are taken from the function decl T.
1465 if (TREE_CODE (t) == TREE_LIST)
1467 args = TREE_VALUE (t);
1468 types = TREE_VALUE (t);
1469 abstract = false;
1471 else
1473 bool type_p = TYPE_P (t);
1474 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1475 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1476 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1478 bool first = true;
1480 /* Skip artificial parameter for nonstatic member functions. */
1481 if (TREE_CODE (t) == METHOD_TYPE)
1482 types = TREE_CHAIN (types);
1484 pp_cxx_left_paren (pp);
1485 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1487 if (!first)
1488 pp_cxx_separate_with (pp, ',');
1489 first = false;
1490 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1491 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1493 pp_cxx_whitespace (pp);
1494 pp_equal (pp);
1495 pp_cxx_whitespace (pp);
1496 pp->assignment_expression (TREE_PURPOSE (types));
1499 pp_cxx_right_paren (pp);
1502 /* exception-specification:
1503 throw ( type-id-list(opt) )
1505 type-id-list
1506 type-id
1507 type-id-list , type-id */
1509 static void
1510 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1512 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1513 bool need_comma = false;
1515 if (ex_spec == NULL)
1516 return;
1517 if (TREE_PURPOSE (ex_spec))
1519 pp_cxx_ws_string (pp, "noexcept");
1520 pp_cxx_whitespace (pp);
1521 pp_cxx_left_paren (pp);
1522 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1523 pp_cxx_ws_string (pp, "<uninstantiated>");
1524 else
1525 pp->expression (TREE_PURPOSE (ex_spec));
1526 pp_cxx_right_paren (pp);
1527 return;
1529 pp_cxx_ws_string (pp, "throw");
1530 pp_cxx_left_paren (pp);
1531 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1533 tree type = TREE_VALUE (ex_spec);
1534 tree argpack = NULL_TREE;
1535 int i, len = 1;
1537 if (ARGUMENT_PACK_P (type))
1539 argpack = ARGUMENT_PACK_ARGS (type);
1540 len = TREE_VEC_LENGTH (argpack);
1543 for (i = 0; i < len; ++i)
1545 if (argpack)
1546 type = TREE_VEC_ELT (argpack, i);
1548 if (need_comma)
1549 pp_cxx_separate_with (pp, ',');
1550 else
1551 need_comma = true;
1553 pp->type_id (type);
1556 pp_cxx_right_paren (pp);
1559 /* direct-declarator:
1560 declarator-id
1561 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1562 exception-specification(opt)
1563 direct-declaration [ constant-expression(opt) ]
1564 ( declarator ) */
1566 void
1567 cxx_pretty_printer::direct_declarator (tree t)
1569 switch (TREE_CODE (t))
1571 case VAR_DECL:
1572 case PARM_DECL:
1573 case CONST_DECL:
1574 case FIELD_DECL:
1575 if (DECL_NAME (t))
1577 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1579 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1580 || template_parameter_pack_p (t))
1581 /* A function parameter pack or non-type template
1582 parameter pack. */
1583 pp_cxx_ws_string (this, "...");
1585 id_expression (DECL_NAME (t));
1587 abstract_declarator (TREE_TYPE (t));
1588 break;
1590 case FUNCTION_DECL:
1591 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1592 expression (t);
1593 pp_cxx_parameter_declaration_clause (this, t);
1595 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1597 padding = pp_before;
1598 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1601 pp_cxx_exception_specification (this, TREE_TYPE (t));
1602 break;
1604 case TYPENAME_TYPE:
1605 case TEMPLATE_DECL:
1606 case TEMPLATE_TYPE_PARM:
1607 case TEMPLATE_PARM_INDEX:
1608 case TEMPLATE_TEMPLATE_PARM:
1609 break;
1611 default:
1612 c_pretty_printer::direct_declarator (t);
1613 break;
1617 /* declarator:
1618 direct-declarator
1619 ptr-operator declarator */
1621 void
1622 cxx_pretty_printer::declarator (tree t)
1624 direct_declarator (t);
1627 /* ctor-initializer:
1628 : mem-initializer-list
1630 mem-initializer-list:
1631 mem-initializer
1632 mem-initializer , mem-initializer-list
1634 mem-initializer:
1635 mem-initializer-id ( expression-list(opt) )
1637 mem-initializer-id:
1638 ::(opt) nested-name-specifier(opt) class-name
1639 identifier */
1641 static void
1642 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1644 t = TREE_OPERAND (t, 0);
1645 pp_cxx_whitespace (pp);
1646 pp_colon (pp);
1647 pp_cxx_whitespace (pp);
1648 for (; t; t = TREE_CHAIN (t))
1650 tree purpose = TREE_PURPOSE (t);
1651 bool is_pack = PACK_EXPANSION_P (purpose);
1653 if (is_pack)
1654 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1655 else
1656 pp->primary_expression (purpose);
1657 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1658 if (is_pack)
1659 pp_cxx_ws_string (pp, "...");
1660 if (TREE_CHAIN (t))
1661 pp_cxx_separate_with (pp, ',');
1665 /* function-definition:
1666 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1667 decl-specifier-seq(opt) declarator function-try-block */
1669 static void
1670 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1672 tree saved_scope = pp->enclosing_scope;
1673 pp->declaration_specifiers (t);
1674 pp->declarator (t);
1675 pp_needs_newline (pp) = true;
1676 pp->enclosing_scope = DECL_CONTEXT (t);
1677 if (DECL_SAVED_TREE (t))
1678 pp->statement (DECL_SAVED_TREE (t));
1679 else
1680 pp_cxx_semicolon (pp);
1681 pp_newline_and_flush (pp);
1682 pp->enclosing_scope = saved_scope;
1685 /* abstract-declarator:
1686 ptr-operator abstract-declarator(opt)
1687 direct-abstract-declarator */
1689 void
1690 cxx_pretty_printer::abstract_declarator (tree t)
1692 if (TYPE_PTRMEM_P (t))
1693 pp_cxx_right_paren (this);
1694 else if (POINTER_TYPE_P (t))
1696 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1697 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1698 pp_cxx_right_paren (this);
1699 t = TREE_TYPE (t);
1701 direct_abstract_declarator (t);
1704 /* direct-abstract-declarator:
1705 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1706 cv-qualifier-seq(opt) exception-specification(opt)
1707 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1708 ( abstract-declarator ) */
1710 void
1711 cxx_pretty_printer::direct_abstract_declarator (tree t)
1713 switch (TREE_CODE (t))
1715 case REFERENCE_TYPE:
1716 abstract_declarator (t);
1717 break;
1719 case RECORD_TYPE:
1720 if (TYPE_PTRMEMFUNC_P (t))
1721 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1722 break;
1724 case METHOD_TYPE:
1725 case FUNCTION_TYPE:
1726 pp_cxx_parameter_declaration_clause (this, t);
1727 direct_abstract_declarator (TREE_TYPE (t));
1728 if (TREE_CODE (t) == METHOD_TYPE)
1730 padding = pp_before;
1731 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1733 pp_cxx_exception_specification (this, t);
1734 break;
1736 case TYPENAME_TYPE:
1737 case TEMPLATE_TYPE_PARM:
1738 case TEMPLATE_TEMPLATE_PARM:
1739 case BOUND_TEMPLATE_TEMPLATE_PARM:
1740 case UNBOUND_CLASS_TEMPLATE:
1741 break;
1743 default:
1744 c_pretty_printer::direct_abstract_declarator (t);
1745 break;
1749 /* type-id:
1750 type-specifier-seq abstract-declarator(opt) */
1752 void
1753 cxx_pretty_printer::type_id (tree t)
1755 pp_flags saved_flags = flags;
1756 flags |= pp_c_flag_abstract;
1758 switch (TREE_CODE (t))
1760 case TYPE_DECL:
1761 case UNION_TYPE:
1762 case RECORD_TYPE:
1763 case ENUMERAL_TYPE:
1764 case TYPENAME_TYPE:
1765 case BOUND_TEMPLATE_TEMPLATE_PARM:
1766 case UNBOUND_CLASS_TEMPLATE:
1767 case TEMPLATE_TEMPLATE_PARM:
1768 case TEMPLATE_TYPE_PARM:
1769 case TEMPLATE_PARM_INDEX:
1770 case TEMPLATE_DECL:
1771 case TYPEOF_TYPE:
1772 case UNDERLYING_TYPE:
1773 case DECLTYPE_TYPE:
1774 case TEMPLATE_ID_EXPR:
1775 pp_cxx_type_specifier_seq (this, t);
1776 break;
1778 case TYPE_PACK_EXPANSION:
1779 type_id (PACK_EXPANSION_PATTERN (t));
1780 pp_cxx_ws_string (this, "...");
1781 break;
1783 default:
1784 c_pretty_printer::type_id (t);
1785 break;
1788 flags = saved_flags;
1791 /* template-argument-list:
1792 template-argument ...(opt)
1793 template-argument-list, template-argument ...(opt)
1795 template-argument:
1796 assignment-expression
1797 type-id
1798 template-name */
1800 static void
1801 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1803 int i;
1804 bool need_comma = false;
1806 if (t == NULL)
1807 return;
1808 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1810 tree arg = TREE_VEC_ELT (t, i);
1811 tree argpack = NULL_TREE;
1812 int idx, len = 1;
1814 if (ARGUMENT_PACK_P (arg))
1816 argpack = ARGUMENT_PACK_ARGS (arg);
1817 len = TREE_VEC_LENGTH (argpack);
1820 for (idx = 0; idx < len; idx++)
1822 if (argpack)
1823 arg = TREE_VEC_ELT (argpack, idx);
1825 if (need_comma)
1826 pp_cxx_separate_with (pp, ',');
1827 else
1828 need_comma = true;
1830 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1831 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1832 pp->type_id (arg);
1833 else
1834 pp->expression (arg);
1840 static void
1841 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1843 t = DECL_EXPR_DECL (t);
1844 pp_cxx_type_specifier_seq (pp, t);
1845 if (TYPE_P (t))
1846 pp->abstract_declarator (t);
1847 else
1848 pp->declarator (t);
1851 /* Statements. */
1853 void
1854 cxx_pretty_printer::statement (tree t)
1856 switch (TREE_CODE (t))
1858 case CTOR_INITIALIZER:
1859 pp_cxx_ctor_initializer (this, t);
1860 break;
1862 case USING_STMT:
1863 pp_cxx_ws_string (this, "using");
1864 pp_cxx_ws_string (this, "namespace");
1865 if (DECL_CONTEXT (t))
1866 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1867 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1868 break;
1870 case USING_DECL:
1871 pp_cxx_ws_string (this, "using");
1872 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1873 pp_cxx_unqualified_id (this, DECL_NAME (t));
1874 break;
1876 case EH_SPEC_BLOCK:
1877 break;
1879 /* try-block:
1880 try compound-statement handler-seq */
1881 case TRY_BLOCK:
1882 pp_maybe_newline_and_indent (this, 0);
1883 pp_cxx_ws_string (this, "try");
1884 pp_newline_and_indent (this, 3);
1885 statement (TRY_STMTS (t));
1886 pp_newline_and_indent (this, -3);
1887 if (CLEANUP_P (t))
1889 else
1890 statement (TRY_HANDLERS (t));
1891 break;
1894 handler-seq:
1895 handler handler-seq(opt)
1897 handler:
1898 catch ( exception-declaration ) compound-statement
1900 exception-declaration:
1901 type-specifier-seq declarator
1902 type-specifier-seq abstract-declarator
1903 ... */
1904 case HANDLER:
1905 pp_cxx_ws_string (this, "catch");
1906 pp_cxx_left_paren (this);
1907 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1908 pp_cxx_right_paren (this);
1909 pp_indentation (this) += 3;
1910 pp_needs_newline (this) = true;
1911 statement (HANDLER_BODY (t));
1912 pp_indentation (this) -= 3;
1913 pp_needs_newline (this) = true;
1914 break;
1916 /* selection-statement:
1917 if ( expression ) statement
1918 if ( expression ) statement else statement */
1919 case IF_STMT:
1920 pp_cxx_ws_string (this, "if");
1921 pp_cxx_whitespace (this);
1922 pp_cxx_left_paren (this);
1923 expression (IF_COND (t));
1924 pp_cxx_right_paren (this);
1925 pp_newline_and_indent (this, 2);
1926 statement (THEN_CLAUSE (t));
1927 pp_newline_and_indent (this, -2);
1928 if (ELSE_CLAUSE (t))
1930 tree else_clause = ELSE_CLAUSE (t);
1931 pp_cxx_ws_string (this, "else");
1932 if (TREE_CODE (else_clause) == IF_STMT)
1933 pp_cxx_whitespace (this);
1934 else
1935 pp_newline_and_indent (this, 2);
1936 statement (else_clause);
1937 if (TREE_CODE (else_clause) != IF_STMT)
1938 pp_newline_and_indent (this, -2);
1940 break;
1942 case SWITCH_STMT:
1943 pp_cxx_ws_string (this, "switch");
1944 pp_space (this);
1945 pp_cxx_left_paren (this);
1946 expression (SWITCH_STMT_COND (t));
1947 pp_cxx_right_paren (this);
1948 pp_indentation (this) += 3;
1949 pp_needs_newline (this) = true;
1950 statement (SWITCH_STMT_BODY (t));
1951 pp_newline_and_indent (this, -3);
1952 break;
1954 /* iteration-statement:
1955 while ( expression ) statement
1956 do statement while ( expression ) ;
1957 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1958 for ( declaration expression(opt) ; expression(opt) ) statement */
1959 case WHILE_STMT:
1960 pp_cxx_ws_string (this, "while");
1961 pp_space (this);
1962 pp_cxx_left_paren (this);
1963 expression (WHILE_COND (t));
1964 pp_cxx_right_paren (this);
1965 pp_newline_and_indent (this, 3);
1966 statement (WHILE_BODY (t));
1967 pp_indentation (this) -= 3;
1968 pp_needs_newline (this) = true;
1969 break;
1971 case DO_STMT:
1972 pp_cxx_ws_string (this, "do");
1973 pp_newline_and_indent (this, 3);
1974 statement (DO_BODY (t));
1975 pp_newline_and_indent (this, -3);
1976 pp_cxx_ws_string (this, "while");
1977 pp_space (this);
1978 pp_cxx_left_paren (this);
1979 expression (DO_COND (t));
1980 pp_cxx_right_paren (this);
1981 pp_cxx_semicolon (this);
1982 pp_needs_newline (this) = true;
1983 break;
1985 case FOR_STMT:
1986 pp_cxx_ws_string (this, "for");
1987 pp_space (this);
1988 pp_cxx_left_paren (this);
1989 if (FOR_INIT_STMT (t))
1990 statement (FOR_INIT_STMT (t));
1991 else
1992 pp_cxx_semicolon (this);
1993 pp_needs_newline (this) = false;
1994 pp_cxx_whitespace (this);
1995 if (FOR_COND (t))
1996 expression (FOR_COND (t));
1997 pp_cxx_semicolon (this);
1998 pp_needs_newline (this) = false;
1999 pp_cxx_whitespace (this);
2000 if (FOR_EXPR (t))
2001 expression (FOR_EXPR (t));
2002 pp_cxx_right_paren (this);
2003 pp_newline_and_indent (this, 3);
2004 statement (FOR_BODY (t));
2005 pp_indentation (this) -= 3;
2006 pp_needs_newline (this) = true;
2007 break;
2009 case RANGE_FOR_STMT:
2010 pp_cxx_ws_string (this, "for");
2011 pp_space (this);
2012 pp_cxx_left_paren (this);
2013 statement (RANGE_FOR_DECL (t));
2014 pp_space (this);
2015 pp_needs_newline (this) = false;
2016 pp_colon (this);
2017 pp_space (this);
2018 statement (RANGE_FOR_EXPR (t));
2019 pp_cxx_right_paren (this);
2020 pp_newline_and_indent (this, 3);
2021 statement (FOR_BODY (t));
2022 pp_indentation (this) -= 3;
2023 pp_needs_newline (this) = true;
2024 break;
2026 /* jump-statement:
2027 goto identifier;
2028 continue ;
2029 return expression(opt) ; */
2030 case BREAK_STMT:
2031 case CONTINUE_STMT:
2032 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2033 pp_cxx_semicolon (this);
2034 pp_needs_newline (this) = true;
2035 break;
2037 /* expression-statement:
2038 expression(opt) ; */
2039 case EXPR_STMT:
2040 expression (EXPR_STMT_EXPR (t));
2041 pp_cxx_semicolon (this);
2042 pp_needs_newline (this) = true;
2043 break;
2045 case CLEANUP_STMT:
2046 pp_cxx_ws_string (this, "try");
2047 pp_newline_and_indent (this, 2);
2048 statement (CLEANUP_BODY (t));
2049 pp_newline_and_indent (this, -2);
2050 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2051 pp_newline_and_indent (this, 2);
2052 statement (CLEANUP_EXPR (t));
2053 pp_newline_and_indent (this, -2);
2054 break;
2056 case STATIC_ASSERT:
2057 declaration (t);
2058 break;
2060 default:
2061 c_pretty_printer::statement (t);
2062 break;
2066 /* original-namespace-definition:
2067 namespace identifier { namespace-body }
2069 As an edge case, we also handle unnamed namespace definition here. */
2071 static void
2072 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2074 pp_cxx_ws_string (pp, "namespace");
2075 if (DECL_CONTEXT (t))
2076 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2077 if (DECL_NAME (t))
2078 pp_cxx_unqualified_id (pp, t);
2079 pp_cxx_whitespace (pp);
2080 pp_cxx_left_brace (pp);
2081 /* We do not print the namespace-body. */
2082 pp_cxx_whitespace (pp);
2083 pp_cxx_right_brace (pp);
2086 /* namespace-alias:
2087 identifier
2089 namespace-alias-definition:
2090 namespace identifier = qualified-namespace-specifier ;
2092 qualified-namespace-specifier:
2093 ::(opt) nested-name-specifier(opt) namespace-name */
2095 static void
2096 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2098 pp_cxx_ws_string (pp, "namespace");
2099 if (DECL_CONTEXT (t))
2100 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2101 pp_cxx_unqualified_id (pp, t);
2102 pp_cxx_whitespace (pp);
2103 pp_equal (pp);
2104 pp_cxx_whitespace (pp);
2105 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2106 pp_cxx_nested_name_specifier (pp,
2107 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2108 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2109 pp_cxx_semicolon (pp);
2112 /* simple-declaration:
2113 decl-specifier-seq(opt) init-declarator-list(opt) */
2115 static void
2116 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2118 pp->declaration_specifiers (t);
2119 pp_cxx_init_declarator (pp, t);
2120 pp_cxx_semicolon (pp);
2121 pp_needs_newline (pp) = true;
2125 template-parameter-list:
2126 template-parameter
2127 template-parameter-list , template-parameter */
2129 static inline void
2130 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2132 const int n = TREE_VEC_LENGTH (t);
2133 int i;
2134 for (i = 0; i < n; ++i)
2136 if (i)
2137 pp_cxx_separate_with (pp, ',');
2138 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2142 /* template-parameter:
2143 type-parameter
2144 parameter-declaration
2146 type-parameter:
2147 class ...(opt) identifier(opt)
2148 class identifier(opt) = type-id
2149 typename identifier(opt)
2150 typename ...(opt) identifier(opt) = type-id
2151 template < template-parameter-list > class ...(opt) identifier(opt)
2152 template < template-parameter-list > class identifier(opt) = template-name */
2154 static void
2155 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2157 tree parameter = TREE_VALUE (t);
2158 switch (TREE_CODE (parameter))
2160 case TYPE_DECL:
2161 pp_cxx_ws_string (pp, "class");
2162 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2163 pp_cxx_ws_string (pp, "...");
2164 if (DECL_NAME (parameter))
2165 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2166 /* FIXME: Check if we should print also default argument. */
2167 break;
2169 case PARM_DECL:
2170 pp_cxx_parameter_declaration (pp, parameter);
2171 break;
2173 case TEMPLATE_DECL:
2174 break;
2176 default:
2177 pp_unsupported_tree (pp, t);
2178 break;
2182 /* Pretty-print a template parameter in the canonical form
2183 "template-parameter-<level>-<position in parameter list>". */
2185 void
2186 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2188 const enum tree_code code = TREE_CODE (parm);
2190 /* Brings type template parameters to the canonical forms. */
2191 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2192 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2193 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2195 pp_cxx_begin_template_argument_list (pp);
2196 pp->translate_string ("template-parameter-");
2197 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2198 pp_minus (pp);
2199 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2200 pp_cxx_end_template_argument_list (pp);
2204 template-declaration:
2205 export(opt) template < template-parameter-list > declaration */
2207 static void
2208 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2210 tree tmpl = most_general_template (t);
2211 tree level;
2213 pp_maybe_newline_and_indent (pp, 0);
2214 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2216 pp_cxx_ws_string (pp, "template");
2217 pp_cxx_begin_template_argument_list (pp);
2218 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2219 pp_cxx_end_template_argument_list (pp);
2220 pp_newline_and_indent (pp, 3);
2223 if (tree c = DECL_CONSTRAINTS (t))
2225 pp_cxx_ws_string (pp, "requires");
2226 pp->expression (CI_REQUIREMENTS (c));
2227 pp_newline_and_indent (pp, 6);
2230 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2231 pp_cxx_function_definition (pp, t);
2232 else
2233 pp_cxx_simple_declaration (pp, t);
2236 static void
2237 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2239 pp_unsupported_tree (pp, t);
2242 static void
2243 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2245 pp_unsupported_tree (pp, t);
2249 declaration:
2250 block-declaration
2251 function-definition
2252 template-declaration
2253 explicit-instantiation
2254 explicit-specialization
2255 linkage-specification
2256 namespace-definition
2258 block-declaration:
2259 simple-declaration
2260 asm-definition
2261 namespace-alias-definition
2262 using-declaration
2263 using-directive
2264 static_assert-declaration */
2265 void
2266 cxx_pretty_printer::declaration (tree t)
2268 if (TREE_CODE (t) == STATIC_ASSERT)
2270 pp_cxx_ws_string (this, "static_assert");
2271 pp_cxx_left_paren (this);
2272 expression (STATIC_ASSERT_CONDITION (t));
2273 pp_cxx_separate_with (this, ',');
2274 expression (STATIC_ASSERT_MESSAGE (t));
2275 pp_cxx_right_paren (this);
2277 else if (!DECL_LANG_SPECIFIC (t))
2278 pp_cxx_simple_declaration (this, t);
2279 else if (DECL_USE_TEMPLATE (t))
2280 switch (DECL_USE_TEMPLATE (t))
2282 case 1:
2283 pp_cxx_template_declaration (this, t);
2284 break;
2286 case 2:
2287 pp_cxx_explicit_specialization (this, t);
2288 break;
2290 case 3:
2291 pp_cxx_explicit_instantiation (this, t);
2292 break;
2294 default:
2295 break;
2297 else switch (TREE_CODE (t))
2299 case VAR_DECL:
2300 case TYPE_DECL:
2301 pp_cxx_simple_declaration (this, t);
2302 break;
2304 case FUNCTION_DECL:
2305 if (DECL_SAVED_TREE (t))
2306 pp_cxx_function_definition (this, t);
2307 else
2308 pp_cxx_simple_declaration (this, t);
2309 break;
2311 case NAMESPACE_DECL:
2312 if (DECL_NAMESPACE_ALIAS (t))
2313 pp_cxx_namespace_alias_definition (this, t);
2314 else
2315 pp_cxx_original_namespace_definition (this, t);
2316 break;
2318 default:
2319 pp_unsupported_tree (this, t);
2320 break;
2324 static void
2325 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2327 t = TREE_OPERAND (t, 0);
2328 pp_cxx_ws_string (pp, "typeid");
2329 pp_cxx_left_paren (pp);
2330 if (TYPE_P (t))
2331 pp->type_id (t);
2332 else
2333 pp->expression (t);
2334 pp_cxx_right_paren (pp);
2337 void
2338 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2340 pp_cxx_ws_string (pp, "va_arg");
2341 pp_cxx_left_paren (pp);
2342 pp->assignment_expression (TREE_OPERAND (t, 0));
2343 pp_cxx_separate_with (pp, ',');
2344 pp->type_id (TREE_TYPE (t));
2345 pp_cxx_right_paren (pp);
2348 static bool
2349 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2351 switch (TREE_CODE (t))
2353 case ARROW_EXPR:
2354 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2355 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2357 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2358 pp_cxx_separate_with (pp, ',');
2359 return true;
2361 return false;
2362 case COMPONENT_REF:
2363 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2364 return false;
2365 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2366 pp_cxx_dot (pp);
2367 pp->expression (TREE_OPERAND (t, 1));
2368 return true;
2369 case ARRAY_REF:
2370 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2371 return false;
2372 pp_left_bracket (pp);
2373 pp->expression (TREE_OPERAND (t, 1));
2374 pp_right_bracket (pp);
2375 return true;
2376 default:
2377 return false;
2381 void
2382 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2384 pp_cxx_ws_string (pp, "offsetof");
2385 pp_cxx_left_paren (pp);
2386 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2387 pp->expression (TREE_OPERAND (t, 0));
2388 pp_cxx_right_paren (pp);
2391 void
2392 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2394 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2396 switch (kind)
2398 case CPTK_HAS_NOTHROW_ASSIGN:
2399 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2400 break;
2401 case CPTK_HAS_TRIVIAL_ASSIGN:
2402 pp_cxx_ws_string (pp, "__has_trivial_assign");
2403 break;
2404 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2405 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2406 break;
2407 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2408 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2409 break;
2410 case CPTK_HAS_NOTHROW_COPY:
2411 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2412 break;
2413 case CPTK_HAS_TRIVIAL_COPY:
2414 pp_cxx_ws_string (pp, "__has_trivial_copy");
2415 break;
2416 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2417 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2418 break;
2419 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2420 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2421 break;
2422 case CPTK_IS_ABSTRACT:
2423 pp_cxx_ws_string (pp, "__is_abstract");
2424 break;
2425 case CPTK_IS_BASE_OF:
2426 pp_cxx_ws_string (pp, "__is_base_of");
2427 break;
2428 case CPTK_IS_CLASS:
2429 pp_cxx_ws_string (pp, "__is_class");
2430 break;
2431 case CPTK_IS_CONVERTIBLE_TO:
2432 pp_cxx_ws_string (pp, "__is_convertible_to");
2433 break;
2434 case CPTK_IS_EMPTY:
2435 pp_cxx_ws_string (pp, "__is_empty");
2436 break;
2437 case CPTK_IS_ENUM:
2438 pp_cxx_ws_string (pp, "__is_enum");
2439 break;
2440 case CPTK_IS_FINAL:
2441 pp_cxx_ws_string (pp, "__is_final");
2442 break;
2443 case CPTK_IS_POD:
2444 pp_cxx_ws_string (pp, "__is_pod");
2445 break;
2446 case CPTK_IS_POLYMORPHIC:
2447 pp_cxx_ws_string (pp, "__is_polymorphic");
2448 break;
2449 case CPTK_IS_SAME_AS:
2450 pp_cxx_ws_string (pp, "__is_same_as");
2451 break;
2452 case CPTK_IS_STD_LAYOUT:
2453 pp_cxx_ws_string (pp, "__is_std_layout");
2454 break;
2455 case CPTK_IS_TRIVIAL:
2456 pp_cxx_ws_string (pp, "__is_trivial");
2457 break;
2458 case CPTK_IS_UNION:
2459 pp_cxx_ws_string (pp, "__is_union");
2460 break;
2461 case CPTK_IS_LITERAL_TYPE:
2462 pp_cxx_ws_string (pp, "__is_literal_type");
2463 break;
2465 default:
2466 gcc_unreachable ();
2469 pp_cxx_left_paren (pp);
2470 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2472 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2474 pp_cxx_separate_with (pp, ',');
2475 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2478 pp_cxx_right_paren (pp);
2481 // requirement-list:
2482 // requirement
2483 // requirement-list ';' requirement[opt]
2485 // requirement:
2486 // simple-requirement
2487 // compound-requirement
2488 // type-requirement
2489 // nested-requirement
2490 static void
2491 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2493 int n = 3;
2494 while (t) {
2495 pp_newline_and_indent (pp, n);
2496 pp->expression (TREE_VALUE (t));
2497 n = 0;
2498 t = TREE_CHAIN (t);
2500 pp_newline_and_indent (pp, -3);
2503 // requirement-body:
2504 // '{' requirement-list '}'
2505 static void
2506 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2508 pp_cxx_left_brace (pp);
2509 pp_cxx_requirement_list (pp, t);
2510 pp_cxx_right_brace (pp);
2513 // requires-expression:
2514 // 'requires' requirement-parameter-list requirement-body
2515 void
2516 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2518 pp_cxx_ws_string (pp, "requires");
2519 pp_space (pp);
2520 pp_cxx_parameter_declaration_clause (pp, TREE_OPERAND (t, 0));
2521 pp_space (pp);
2522 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2525 // constraint-specifier:
2526 // noexcept
2527 // constexpr
2528 static void
2529 pp_cxx_constraint_specifier (cxx_pretty_printer *pp, tree t)
2531 if (TREE_CODE (t) == NOEXCEPT_EXPR)
2532 pp_cxx_ws_string (pp, "noexcept");
2533 else if (TREE_CODE (t) == CONSTEXPR_EXPR)
2534 pp_cxx_ws_string (pp, "constexpr");
2535 else
2536 gcc_unreachable ();
2539 // compound-requirement:
2540 // '{' expression '}' trailing-constraint-specifiers
2542 // trailing-constraint-specifiers:
2543 // constraint-specifiers-seq[opt] result-type-requirement[opt]
2545 // result-type-requirement:
2546 // '->' type-id
2547 static void
2548 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2550 // Get the expression requirement.
2551 tree ereq = TREE_OPERAND (t, 0);
2553 // Find the tree node containing the result type requirement.
2554 // Note that validtype requirements are implicit.
2555 tree treq = TREE_CHAIN (ereq);
2556 if (TREE_CODE (TREE_VALUE (treq)) == VALIDTYPE_EXPR)
2557 treq = TREE_CHAIN (treq);
2559 // Find tree nodes for any additional constraint specifiers.
2560 tree spec1 = TREE_CHAIN (treq);
2561 tree spec2 = spec1 ? TREE_CHAIN (spec1) : NULL_TREE;
2563 // Pretty print the {expr} requirement
2564 tree expr = TREE_OPERAND (TREE_VALUE (ereq), 0);
2565 pp_cxx_left_brace (pp);
2566 pp->expression (expr);
2567 pp_cxx_right_brace (pp);
2569 // Pretty constraint specifiers, if any.
2570 if (spec1)
2572 pp_space (pp);
2573 pp_cxx_constraint_specifier (pp, TREE_VALUE (spec1));
2574 if (spec2)
2575 pp_cxx_constraint_specifier (pp, TREE_VALUE (spec2));
2578 // Pretty print the '-> type-id' part of the expression.
2579 // Note that treq will contain a TRAIT_EXPR.
2580 if (treq)
2582 tree type = TRAIT_EXPR_TYPE2 (TREE_VALUE (treq));
2583 pp_space (pp);
2584 pp_cxx_arrow (pp);
2585 pp_space (pp);
2586 pp->type_id (type);
2590 // simple-requirement:
2591 // expression
2592 static void
2593 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2595 tree req = TREE_OPERAND (t, 0);
2596 pp->expression (TREE_OPERAND (req, 0));
2599 void
2600 pp_cxx_expr_requirement (cxx_pretty_printer *pp, tree t)
2602 tree reqs = TREE_OPERAND (t, 0);
2603 if (TREE_CODE (reqs) == TREE_LIST)
2604 pp_cxx_compound_requirement (pp, t);
2605 else
2606 pp_cxx_simple_requirement (pp, t);
2607 pp_cxx_semicolon (pp);
2610 // type-requirement:
2611 // type-id
2612 void
2613 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2615 tree req = TREE_OPERAND (t, 0);
2616 pp->type_id (TREE_OPERAND (req, 0));
2617 pp_cxx_semicolon (pp);
2620 // nested requirement:
2621 // 'requires' logical-or-expression
2622 void
2623 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2625 pp_cxx_ws_string (pp, "requires");
2626 pp->expression (TREE_OPERAND (t, 0));
2627 pp_cxx_semicolon (pp);
2630 void
2631 pp_cxx_validexpr_expr (cxx_pretty_printer *pp, tree t)
2633 pp_cxx_ws_string (pp, "__is_valid_expr");
2634 pp_cxx_left_paren (pp);
2635 pp->expression (TREE_OPERAND (t, 0));
2636 pp_cxx_right_paren (pp);
2639 void
2640 pp_cxx_validtype_expr (cxx_pretty_printer *pp, tree t)
2642 pp_cxx_ws_string (pp, "__is_valid_expr");
2643 pp_cxx_left_paren (pp);
2644 pp->type_id(TREE_OPERAND (t, 0));
2645 pp_cxx_right_paren (pp);
2648 void
2649 pp_cxx_constexpr_expr (cxx_pretty_printer *pp, tree t)
2651 pp_cxx_ws_string (pp, "__is_valid_expr");
2652 pp_cxx_left_paren (pp);
2653 pp->expression (TREE_OPERAND (t, 0));
2654 pp_cxx_right_paren (pp);
2658 typedef c_pretty_print_fn pp_fun;
2660 /* Initialization of a C++ pretty-printer object. */
2662 cxx_pretty_printer::cxx_pretty_printer ()
2663 : c_pretty_printer (),
2664 enclosing_scope (global_namespace)
2666 pp_set_line_maximum_length (this, 0);
2668 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2669 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;