PR c/7652
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blobf4d2a2eef2307293e54a9843d3f965b267bd3eb6
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "cp-tree.h"
25 #include "cxx-pretty-print.h"
26 #include "tree-pretty-print.h"
28 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
29 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
30 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
32 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
33 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
34 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
35 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
36 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
37 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
38 static void pp_cxx_unary_left_fold_expression (cxx_pretty_printer *, tree);
39 static void pp_cxx_unary_right_fold_expression (cxx_pretty_printer *, tree);
40 static void pp_cxx_binary_fold_expression (cxx_pretty_printer *, tree);
43 static inline void
44 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
46 const char *p = pp_last_position_in_text (pp);
48 if (p != NULL && *p == c)
49 pp_cxx_whitespace (pp);
50 pp_character (pp, c);
51 pp->padding = pp_none;
54 #define pp_cxx_expression_list(PP, T) \
55 pp_c_expression_list (PP, T)
56 #define pp_cxx_space_for_pointer_operator(PP, T) \
57 pp_c_space_for_pointer_operator (PP, T)
58 #define pp_cxx_init_declarator(PP, T) \
59 pp_c_init_declarator (PP, T)
60 #define pp_cxx_call_argument_list(PP, T) \
61 pp_c_call_argument_list (PP, T)
63 void
64 pp_cxx_colon_colon (cxx_pretty_printer *pp)
66 pp_colon_colon (pp);
67 pp->padding = pp_none;
70 void
71 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
73 pp_cxx_nonconsecutive_character (pp, '<');
76 void
77 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
79 pp_cxx_nonconsecutive_character (pp, '>');
82 void
83 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
85 pp_separate_with (pp, c);
86 pp->padding = pp_none;
89 /* Expressions. */
91 static inline bool
92 is_destructor_name (tree name)
94 return name == complete_dtor_identifier
95 || name == base_dtor_identifier
96 || name == deleting_dtor_identifier;
99 /* conversion-function-id:
100 operator conversion-type-id
102 conversion-type-id:
103 type-specifier-seq conversion-declarator(opt)
105 conversion-declarator:
106 ptr-operator conversion-declarator(opt) */
108 static inline void
109 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
111 pp_cxx_ws_string (pp, "operator");
112 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
115 static inline void
116 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
118 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
119 pp_cxx_begin_template_argument_list (pp);
120 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
121 pp_cxx_end_template_argument_list (pp);
124 /* Prints the unqualified part of the id-expression T.
126 unqualified-id:
127 identifier
128 operator-function-id
129 conversion-function-id
130 ~ class-name
131 template-id */
133 static void
134 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
136 enum tree_code code = TREE_CODE (t);
137 switch (code)
139 case RESULT_DECL:
140 pp->translate_string ("<return-value>");
141 break;
143 case OVERLOAD:
144 t = OVL_CURRENT (t);
145 /* XXX Really fallthru? */
146 /* FALLTHRU */
147 case VAR_DECL:
148 case PARM_DECL:
149 case CONST_DECL:
150 case TYPE_DECL:
151 case FUNCTION_DECL:
152 case NAMESPACE_DECL:
153 case FIELD_DECL:
154 case LABEL_DECL:
155 case USING_DECL:
156 case TEMPLATE_DECL:
157 t = DECL_NAME (t);
158 /* FALLTHRU */
160 case IDENTIFIER_NODE:
161 if (t == NULL)
162 pp->translate_string ("<unnamed>");
163 else if (IDENTIFIER_TYPENAME_P (t))
164 pp_cxx_conversion_function_id (pp, t);
165 else
167 if (is_destructor_name (t))
169 pp_complement (pp);
170 /* FIXME: Why is this necessary? */
171 if (TREE_TYPE (t))
172 t = constructor_name (TREE_TYPE (t));
174 pp_cxx_tree_identifier (pp, t);
176 break;
178 case TEMPLATE_ID_EXPR:
179 pp_cxx_template_id (pp, t);
180 break;
182 case BASELINK:
183 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
184 break;
186 case RECORD_TYPE:
187 case UNION_TYPE:
188 case ENUMERAL_TYPE:
189 case TYPENAME_TYPE:
190 case UNBOUND_CLASS_TEMPLATE:
191 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
192 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
194 pp_cxx_begin_template_argument_list (pp);
195 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
196 (CLASSTYPE_TI_ARGS (t)));
197 pp_cxx_end_template_argument_list (pp);
199 break;
201 case BIT_NOT_EXPR:
202 pp_cxx_complement (pp);
203 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
204 break;
206 case TEMPLATE_TYPE_PARM:
207 case TEMPLATE_TEMPLATE_PARM:
208 if (TYPE_IDENTIFIER (t))
209 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
210 else
211 pp_cxx_canonical_template_parameter (pp, t);
212 break;
214 case TEMPLATE_PARM_INDEX:
215 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
216 break;
218 case BOUND_TEMPLATE_TEMPLATE_PARM:
219 pp_cxx_cv_qualifier_seq (pp, t);
220 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
221 pp_cxx_begin_template_argument_list (pp);
222 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
223 pp_cxx_end_template_argument_list (pp);
224 break;
226 default:
227 pp_unsupported_tree (pp, t);
228 break;
232 /* Pretty-print out the token sequence ":: template" in template codes
233 where it is needed to "inline declare" the (following) member as
234 a template. This situation arises when SCOPE of T is dependent
235 on template parameters. */
237 static inline void
238 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
240 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
241 && TYPE_P (scope) && dependent_type_p (scope))
242 pp_cxx_ws_string (pp, "template");
245 /* nested-name-specifier:
246 class-or-namespace-name :: nested-name-specifier(opt)
247 class-or-namespace-name :: template nested-name-specifier */
249 static void
250 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
252 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
254 tree scope = get_containing_scope (t);
255 pp_cxx_nested_name_specifier (pp, scope);
256 pp_cxx_template_keyword_if_needed (pp, scope, t);
257 pp_cxx_unqualified_id (pp, t);
258 pp_cxx_colon_colon (pp);
262 /* qualified-id:
263 nested-name-specifier template(opt) unqualified-id */
265 static void
266 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
268 switch (TREE_CODE (t))
270 /* A pointer-to-member is always qualified. */
271 case PTRMEM_CST:
272 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
273 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
274 break;
276 /* In Standard C++, functions cannot possibly be used as
277 nested-name-specifiers. However, there are situations where
278 is "makes sense" to output the surrounding function name for the
279 purpose of emphasizing on the scope kind. Just printing the
280 function name might not be sufficient as it may be overloaded; so,
281 we decorate the function with its signature too.
282 FIXME: This is probably the wrong pretty-printing for conversion
283 functions and some function templates. */
284 case OVERLOAD:
285 t = OVL_CURRENT (t);
286 /* FALLTHRU */
287 case FUNCTION_DECL:
288 if (DECL_FUNCTION_MEMBER_P (t))
289 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
290 pp_cxx_unqualified_id
291 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
292 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
293 break;
295 case OFFSET_REF:
296 case SCOPE_REF:
297 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
298 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
299 break;
301 default:
303 tree scope = get_containing_scope (t);
304 if (scope != pp->enclosing_scope)
306 pp_cxx_nested_name_specifier (pp, scope);
307 pp_cxx_template_keyword_if_needed (pp, scope, t);
309 pp_cxx_unqualified_id (pp, t);
311 break;
316 void
317 cxx_pretty_printer::constant (tree t)
319 switch (TREE_CODE (t))
321 case STRING_CST:
323 const bool in_parens = PAREN_STRING_LITERAL_P (t);
324 if (in_parens)
325 pp_cxx_left_paren (this);
326 c_pretty_printer::constant (t);
327 if (in_parens)
328 pp_cxx_right_paren (this);
330 break;
332 case INTEGER_CST:
333 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
335 pp_string (this, "nullptr");
336 break;
338 /* fall through. */
340 default:
341 c_pretty_printer::constant (t);
342 break;
346 /* id-expression:
347 unqualified-id
348 qualified-id */
350 void
351 cxx_pretty_printer::id_expression (tree t)
353 if (TREE_CODE (t) == OVERLOAD)
354 t = OVL_CURRENT (t);
355 if (DECL_P (t) && DECL_CONTEXT (t))
356 pp_cxx_qualified_id (this, t);
357 else
358 pp_cxx_unqualified_id (this, t);
361 /* user-defined literal:
362 literal ud-suffix */
364 void
365 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
367 pp->constant (USERDEF_LITERAL_VALUE (t));
368 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
372 /* primary-expression:
373 literal
374 this
375 :: identifier
376 :: operator-function-id
377 :: qualifier-id
378 ( expression )
379 id-expression
381 GNU Extensions:
382 __builtin_va_arg ( assignment-expression , type-id )
383 __builtin_offsetof ( type-id, offsetof-expression )
385 __has_nothrow_assign ( type-id )
386 __has_nothrow_constructor ( type-id )
387 __has_nothrow_copy ( type-id )
388 __has_trivial_assign ( type-id )
389 __has_trivial_constructor ( type-id )
390 __has_trivial_copy ( type-id )
391 __has_trivial_destructor ( type-id )
392 __has_virtual_destructor ( type-id )
393 __is_abstract ( type-id )
394 __is_base_of ( type-id , type-id )
395 __is_class ( type-id )
396 __is_empty ( type-id )
397 __is_enum ( type-id )
398 __is_literal_type ( type-id )
399 __is_pod ( type-id )
400 __is_polymorphic ( type-id )
401 __is_std_layout ( type-id )
402 __is_trivial ( type-id )
403 __is_union ( type-id ) */
405 void
406 cxx_pretty_printer::primary_expression (tree t)
408 switch (TREE_CODE (t))
410 case VOID_CST:
411 case INTEGER_CST:
412 case REAL_CST:
413 case COMPLEX_CST:
414 case STRING_CST:
415 constant (t);
416 break;
418 case USERDEF_LITERAL:
419 pp_cxx_userdef_literal (this, t);
420 break;
422 case BASELINK:
423 t = BASELINK_FUNCTIONS (t);
424 /* FALLTHRU */
425 case VAR_DECL:
426 case PARM_DECL:
427 case FIELD_DECL:
428 case FUNCTION_DECL:
429 case OVERLOAD:
430 case CONST_DECL:
431 case TEMPLATE_DECL:
432 id_expression (t);
433 break;
435 case RESULT_DECL:
436 case TEMPLATE_TYPE_PARM:
437 case TEMPLATE_TEMPLATE_PARM:
438 case TEMPLATE_PARM_INDEX:
439 pp_cxx_unqualified_id (this, t);
440 break;
442 case STMT_EXPR:
443 pp_cxx_left_paren (this);
444 statement (STMT_EXPR_STMT (t));
445 pp_cxx_right_paren (this);
446 break;
448 case TRAIT_EXPR:
449 pp_cxx_trait_expression (this, t);
450 break;
452 case VA_ARG_EXPR:
453 pp_cxx_va_arg_expression (this, t);
454 break;
456 case OFFSETOF_EXPR:
457 pp_cxx_offsetof_expression (this, t);
458 break;
460 case REQUIRES_EXPR:
461 pp_cxx_requires_expr (this, t);
462 break;
464 default:
465 c_pretty_printer::primary_expression (t);
466 break;
470 /* postfix-expression:
471 primary-expression
472 postfix-expression [ expression ]
473 postfix-expression ( expression-list(opt) )
474 simple-type-specifier ( expression-list(opt) )
475 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
476 typename ::(opt) nested-name-specifier template(opt)
477 template-id ( expression-list(opt) )
478 postfix-expression . template(opt) ::(opt) id-expression
479 postfix-expression -> template(opt) ::(opt) id-expression
480 postfix-expression . pseudo-destructor-name
481 postfix-expression -> pseudo-destructor-name
482 postfix-expression ++
483 postfix-expression --
484 dynamic_cast < type-id > ( expression )
485 static_cast < type-id > ( expression )
486 reinterpret_cast < type-id > ( expression )
487 const_cast < type-id > ( expression )
488 typeid ( expression )
489 typeid ( type-id ) */
491 void
492 cxx_pretty_printer::postfix_expression (tree t)
494 enum tree_code code = TREE_CODE (t);
496 switch (code)
498 case AGGR_INIT_EXPR:
499 case CALL_EXPR:
501 tree fun = cp_get_callee (t);
502 tree saved_scope = enclosing_scope;
503 bool skipfirst = false;
504 tree arg;
506 if (TREE_CODE (fun) == ADDR_EXPR)
507 fun = TREE_OPERAND (fun, 0);
509 /* In templates, where there is no way to tell whether a given
510 call uses an actual member function. So the parser builds
511 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
512 instantiation time. */
513 if (TREE_CODE (fun) != FUNCTION_DECL)
515 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
517 tree object = (code == AGGR_INIT_EXPR
518 ? (AGGR_INIT_VIA_CTOR_P (t)
519 ? AGGR_INIT_EXPR_SLOT (t)
520 : AGGR_INIT_EXPR_ARG (t, 0))
521 : CALL_EXPR_ARG (t, 0));
523 while (TREE_CODE (object) == NOP_EXPR)
524 object = TREE_OPERAND (object, 0);
526 if (TREE_CODE (object) == ADDR_EXPR)
527 object = TREE_OPERAND (object, 0);
529 if (!TYPE_PTR_P (TREE_TYPE (object)))
531 postfix_expression (object);
532 pp_cxx_dot (this);
534 else
536 postfix_expression (object);
537 pp_cxx_arrow (this);
539 skipfirst = true;
540 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
543 postfix_expression (fun);
544 enclosing_scope = saved_scope;
545 pp_cxx_left_paren (this);
546 if (code == AGGR_INIT_EXPR)
548 aggr_init_expr_arg_iterator iter;
549 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
551 if (skipfirst)
552 skipfirst = false;
553 else
555 expression (arg);
556 if (more_aggr_init_expr_args_p (&iter))
557 pp_cxx_separate_with (this, ',');
561 else
563 call_expr_arg_iterator iter;
564 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
566 if (skipfirst)
567 skipfirst = false;
568 else
570 expression (arg);
571 if (more_call_expr_args_p (&iter))
572 pp_cxx_separate_with (this, ',');
576 pp_cxx_right_paren (this);
578 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
580 pp_cxx_separate_with (this, ',');
581 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
583 break;
585 case BASELINK:
586 case VAR_DECL:
587 case PARM_DECL:
588 case FIELD_DECL:
589 case FUNCTION_DECL:
590 case OVERLOAD:
591 case CONST_DECL:
592 case TEMPLATE_DECL:
593 case RESULT_DECL:
594 primary_expression (t);
595 break;
597 case DYNAMIC_CAST_EXPR:
598 case STATIC_CAST_EXPR:
599 case REINTERPRET_CAST_EXPR:
600 case CONST_CAST_EXPR:
601 if (code == DYNAMIC_CAST_EXPR)
602 pp_cxx_ws_string (this, "dynamic_cast");
603 else if (code == STATIC_CAST_EXPR)
604 pp_cxx_ws_string (this, "static_cast");
605 else if (code == REINTERPRET_CAST_EXPR)
606 pp_cxx_ws_string (this, "reinterpret_cast");
607 else
608 pp_cxx_ws_string (this, "const_cast");
609 pp_cxx_begin_template_argument_list (this);
610 type_id (TREE_TYPE (t));
611 pp_cxx_end_template_argument_list (this);
612 pp_left_paren (this);
613 expression (TREE_OPERAND (t, 0));
614 pp_right_paren (this);
615 break;
617 case EMPTY_CLASS_EXPR:
618 type_id (TREE_TYPE (t));
619 pp_left_paren (this);
620 pp_right_paren (this);
621 break;
623 case TYPEID_EXPR:
624 pp_cxx_typeid_expression (this, t);
625 break;
627 case PSEUDO_DTOR_EXPR:
628 postfix_expression (TREE_OPERAND (t, 0));
629 pp_cxx_dot (this);
630 if (TREE_OPERAND (t, 1))
632 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
633 pp_cxx_colon_colon (this);
635 pp_complement (this);
636 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
637 break;
639 case ARROW_EXPR:
640 postfix_expression (TREE_OPERAND (t, 0));
641 pp_cxx_arrow (this);
642 break;
644 default:
645 c_pretty_printer::postfix_expression (t);
646 break;
650 /* new-expression:
651 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
652 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
654 new-placement:
655 ( expression-list )
657 new-type-id:
658 type-specifier-seq new-declarator(opt)
660 new-declarator:
661 ptr-operator new-declarator(opt)
662 direct-new-declarator
664 direct-new-declarator
665 [ expression ]
666 direct-new-declarator [ constant-expression ]
668 new-initializer:
669 ( expression-list(opt) ) */
671 static void
672 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
674 enum tree_code code = TREE_CODE (t);
675 tree type = TREE_OPERAND (t, 1);
676 tree init = TREE_OPERAND (t, 2);
677 switch (code)
679 case NEW_EXPR:
680 case VEC_NEW_EXPR:
681 if (NEW_EXPR_USE_GLOBAL (t))
682 pp_cxx_colon_colon (pp);
683 pp_cxx_ws_string (pp, "new");
684 if (TREE_OPERAND (t, 0))
686 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
687 pp_space (pp);
689 if (TREE_CODE (type) == ARRAY_REF)
690 type = build_cplus_array_type
691 (TREE_OPERAND (type, 0),
692 build_index_type (fold_build2_loc (input_location,
693 MINUS_EXPR, integer_type_node,
694 TREE_OPERAND (type, 1),
695 integer_one_node)));
696 pp->type_id (type);
697 if (init)
699 pp_left_paren (pp);
700 if (TREE_CODE (init) == TREE_LIST)
701 pp_c_expression_list (pp, init);
702 else if (init == void_node)
703 ; /* OK, empty initializer list. */
704 else
705 pp->expression (init);
706 pp_right_paren (pp);
708 break;
710 default:
711 pp_unsupported_tree (pp, t);
715 /* delete-expression:
716 ::(opt) delete cast-expression
717 ::(opt) delete [ ] cast-expression */
719 static void
720 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
722 enum tree_code code = TREE_CODE (t);
723 switch (code)
725 case DELETE_EXPR:
726 case VEC_DELETE_EXPR:
727 if (DELETE_EXPR_USE_GLOBAL (t))
728 pp_cxx_colon_colon (pp);
729 pp_cxx_ws_string (pp, "delete");
730 pp_space (pp);
731 if (code == VEC_DELETE_EXPR
732 || DELETE_EXPR_USE_VEC (t))
734 pp_left_bracket (pp);
735 pp_right_bracket (pp);
736 pp_space (pp);
738 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
739 break;
741 default:
742 pp_unsupported_tree (pp, t);
746 /* unary-expression:
747 postfix-expression
748 ++ cast-expression
749 -- cast-expression
750 unary-operator cast-expression
751 sizeof unary-expression
752 sizeof ( type-id )
753 sizeof ... ( identifier )
754 new-expression
755 delete-expression
757 unary-operator: one of
758 * & + - !
760 GNU extensions:
761 __alignof__ unary-expression
762 __alignof__ ( type-id ) */
764 void
765 cxx_pretty_printer::unary_expression (tree t)
767 enum tree_code code = TREE_CODE (t);
768 switch (code)
770 case NEW_EXPR:
771 case VEC_NEW_EXPR:
772 pp_cxx_new_expression (this, t);
773 break;
775 case DELETE_EXPR:
776 case VEC_DELETE_EXPR:
777 pp_cxx_delete_expression (this, t);
778 break;
780 case SIZEOF_EXPR:
781 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
783 pp_cxx_ws_string (this, "sizeof");
784 pp_cxx_ws_string (this, "...");
785 pp_cxx_whitespace (this);
786 pp_cxx_left_paren (this);
787 if (TYPE_P (TREE_OPERAND (t, 0)))
788 type_id (TREE_OPERAND (t, 0));
789 else
790 unary_expression (TREE_OPERAND (t, 0));
791 pp_cxx_right_paren (this);
792 break;
794 /* Fall through */
796 case ALIGNOF_EXPR:
797 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
798 pp_cxx_whitespace (this);
799 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
801 pp_cxx_left_paren (this);
802 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
803 pp_cxx_right_paren (this);
805 else if (TYPE_P (TREE_OPERAND (t, 0)))
807 pp_cxx_left_paren (this);
808 type_id (TREE_OPERAND (t, 0));
809 pp_cxx_right_paren (this);
811 else
812 unary_expression (TREE_OPERAND (t, 0));
813 break;
815 case AT_ENCODE_EXPR:
816 pp_cxx_ws_string (this, "@encode");
817 pp_cxx_whitespace (this);
818 pp_cxx_left_paren (this);
819 type_id (TREE_OPERAND (t, 0));
820 pp_cxx_right_paren (this);
821 break;
823 case NOEXCEPT_EXPR:
824 pp_cxx_ws_string (this, "noexcept");
825 pp_cxx_whitespace (this);
826 pp_cxx_left_paren (this);
827 expression (TREE_OPERAND (t, 0));
828 pp_cxx_right_paren (this);
829 break;
831 case UNARY_PLUS_EXPR:
832 pp_plus (this);
833 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
834 break;
836 default:
837 c_pretty_printer::unary_expression (t);
838 break;
842 /* cast-expression:
843 unary-expression
844 ( type-id ) cast-expression */
846 static void
847 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
849 switch (TREE_CODE (t))
851 case CAST_EXPR:
852 case IMPLICIT_CONV_EXPR:
853 pp->type_id (TREE_TYPE (t));
854 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
855 break;
857 default:
858 pp_c_cast_expression (pp, t);
859 break;
863 /* pm-expression:
864 cast-expression
865 pm-expression .* cast-expression
866 pm-expression ->* cast-expression */
868 static void
869 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
871 switch (TREE_CODE (t))
873 /* Handle unfortunate OFFSET_REF overloading here. */
874 case OFFSET_REF:
875 if (TYPE_P (TREE_OPERAND (t, 0)))
877 pp_cxx_qualified_id (pp, t);
878 break;
880 /* Fall through. */
881 case MEMBER_REF:
882 case DOTSTAR_EXPR:
883 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
884 if (TREE_CODE (t) == MEMBER_REF)
885 pp_cxx_arrow (pp);
886 else
887 pp_cxx_dot (pp);
888 pp_star(pp);
889 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
890 break;
893 default:
894 pp_cxx_cast_expression (pp, t);
895 break;
899 /* multiplicative-expression:
900 pm-expression
901 multiplicative-expression * pm-expression
902 multiplicative-expression / pm-expression
903 multiplicative-expression % pm-expression */
905 void
906 cxx_pretty_printer::multiplicative_expression (tree e)
908 enum tree_code code = TREE_CODE (e);
909 switch (code)
911 case MULT_EXPR:
912 case TRUNC_DIV_EXPR:
913 case TRUNC_MOD_EXPR:
914 multiplicative_expression (TREE_OPERAND (e, 0));
915 pp_space (this);
916 if (code == MULT_EXPR)
917 pp_star (this);
918 else if (code == TRUNC_DIV_EXPR)
919 pp_slash (this);
920 else
921 pp_modulo (this);
922 pp_space (this);
923 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
924 break;
926 default:
927 pp_cxx_pm_expression (this, e);
928 break;
932 /* conditional-expression:
933 logical-or-expression
934 logical-or-expression ? expression : assignment-expression */
936 void
937 cxx_pretty_printer::conditional_expression (tree e)
939 if (TREE_CODE (e) == COND_EXPR)
941 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
942 pp_space (this);
943 pp_question (this);
944 pp_space (this);
945 expression (TREE_OPERAND (e, 1));
946 pp_space (this);
947 assignment_expression (TREE_OPERAND (e, 2));
949 else
950 pp_c_logical_or_expression (this, e);
953 /* Pretty-print a compound assignment operator token as indicated by T. */
955 static void
956 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
958 const char *op;
960 switch (TREE_CODE (t))
962 case NOP_EXPR:
963 op = "=";
964 break;
966 case PLUS_EXPR:
967 op = "+=";
968 break;
970 case MINUS_EXPR:
971 op = "-=";
972 break;
974 case TRUNC_DIV_EXPR:
975 op = "/=";
976 break;
978 case TRUNC_MOD_EXPR:
979 op = "%=";
980 break;
982 default:
983 op = get_tree_code_name (TREE_CODE (t));
984 break;
987 pp_cxx_ws_string (pp, op);
991 /* assignment-expression:
992 conditional-expression
993 logical-or-expression assignment-operator assignment-expression
994 throw-expression
996 throw-expression:
997 throw assignment-expression(opt)
999 assignment-operator: one of
1000 = *= /= %= += -= >>= <<= &= ^= |= */
1002 void
1003 cxx_pretty_printer::assignment_expression (tree e)
1005 switch (TREE_CODE (e))
1007 case MODIFY_EXPR:
1008 case INIT_EXPR:
1009 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1010 pp_space (this);
1011 pp_equal (this);
1012 pp_space (this);
1013 assignment_expression (TREE_OPERAND (e, 1));
1014 break;
1016 case THROW_EXPR:
1017 pp_cxx_ws_string (this, "throw");
1018 if (TREE_OPERAND (e, 0))
1019 assignment_expression (TREE_OPERAND (e, 0));
1020 break;
1022 case MODOP_EXPR:
1023 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1024 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1025 assignment_expression (TREE_OPERAND (e, 2));
1026 break;
1028 default:
1029 conditional_expression (e);
1030 break;
1034 void
1035 cxx_pretty_printer::expression (tree t)
1037 switch (TREE_CODE (t))
1039 case STRING_CST:
1040 case VOID_CST:
1041 case INTEGER_CST:
1042 case REAL_CST:
1043 case COMPLEX_CST:
1044 constant (t);
1045 break;
1047 case USERDEF_LITERAL:
1048 pp_cxx_userdef_literal (this, t);
1049 break;
1051 case RESULT_DECL:
1052 pp_cxx_unqualified_id (this, t);
1053 break;
1055 #if 0
1056 case OFFSET_REF:
1057 #endif
1058 case SCOPE_REF:
1059 case PTRMEM_CST:
1060 pp_cxx_qualified_id (this, t);
1061 break;
1063 case OVERLOAD:
1064 t = OVL_CURRENT (t);
1065 /* FALLTHRU */
1066 case VAR_DECL:
1067 case PARM_DECL:
1068 case FIELD_DECL:
1069 case CONST_DECL:
1070 case FUNCTION_DECL:
1071 case BASELINK:
1072 case TEMPLATE_DECL:
1073 case TEMPLATE_TYPE_PARM:
1074 case TEMPLATE_PARM_INDEX:
1075 case TEMPLATE_TEMPLATE_PARM:
1076 case STMT_EXPR:
1077 case REQUIRES_EXPR:
1078 primary_expression (t);
1079 break;
1081 case CALL_EXPR:
1082 case DYNAMIC_CAST_EXPR:
1083 case STATIC_CAST_EXPR:
1084 case REINTERPRET_CAST_EXPR:
1085 case CONST_CAST_EXPR:
1086 #if 0
1087 case MEMBER_REF:
1088 #endif
1089 case EMPTY_CLASS_EXPR:
1090 case TYPEID_EXPR:
1091 case PSEUDO_DTOR_EXPR:
1092 case AGGR_INIT_EXPR:
1093 case ARROW_EXPR:
1094 postfix_expression (t);
1095 break;
1097 case NEW_EXPR:
1098 case VEC_NEW_EXPR:
1099 pp_cxx_new_expression (this, t);
1100 break;
1102 case DELETE_EXPR:
1103 case VEC_DELETE_EXPR:
1104 pp_cxx_delete_expression (this, t);
1105 break;
1107 case SIZEOF_EXPR:
1108 case ALIGNOF_EXPR:
1109 case NOEXCEPT_EXPR:
1110 unary_expression (t);
1111 break;
1113 case CAST_EXPR:
1114 case IMPLICIT_CONV_EXPR:
1115 pp_cxx_cast_expression (this, t);
1116 break;
1118 case OFFSET_REF:
1119 case MEMBER_REF:
1120 case DOTSTAR_EXPR:
1121 pp_cxx_pm_expression (this, t);
1122 break;
1124 case MULT_EXPR:
1125 case TRUNC_DIV_EXPR:
1126 case TRUNC_MOD_EXPR:
1127 multiplicative_expression (t);
1128 break;
1130 case COND_EXPR:
1131 conditional_expression (t);
1132 break;
1134 case MODIFY_EXPR:
1135 case INIT_EXPR:
1136 case THROW_EXPR:
1137 case MODOP_EXPR:
1138 assignment_expression (t);
1139 break;
1141 case NON_DEPENDENT_EXPR:
1142 case MUST_NOT_THROW_EXPR:
1143 expression (TREE_OPERAND (t, 0));
1144 break;
1146 case EXPR_PACK_EXPANSION:
1147 expression (PACK_EXPANSION_PATTERN (t));
1148 pp_cxx_ws_string (this, "...");
1149 break;
1151 case UNARY_LEFT_FOLD_EXPR:
1152 pp_cxx_unary_left_fold_expression (this, t);
1153 break;
1155 case UNARY_RIGHT_FOLD_EXPR:
1156 pp_cxx_unary_right_fold_expression (this, t);
1157 break;
1159 case BINARY_LEFT_FOLD_EXPR:
1160 case BINARY_RIGHT_FOLD_EXPR:
1161 pp_cxx_binary_fold_expression (this, t);
1162 break;
1164 case TEMPLATE_ID_EXPR:
1165 pp_cxx_template_id (this, t);
1166 break;
1168 case NONTYPE_ARGUMENT_PACK:
1170 tree args = ARGUMENT_PACK_ARGS (t);
1171 int i, len = TREE_VEC_LENGTH (args);
1172 for (i = 0; i < len; ++i)
1174 if (i > 0)
1175 pp_cxx_separate_with (this, ',');
1176 expression (TREE_VEC_ELT (args, i));
1179 break;
1181 case LAMBDA_EXPR:
1182 pp_cxx_ws_string (this, "<lambda>");
1183 break;
1185 case TRAIT_EXPR:
1186 pp_cxx_trait_expression (this, t);
1187 break;
1189 case PRED_CONSTR:
1190 case CHECK_CONSTR:
1191 case EXPR_CONSTR:
1192 case TYPE_CONSTR:
1193 case ICONV_CONSTR:
1194 case DEDUCT_CONSTR:
1195 case EXCEPT_CONSTR:
1196 case PARM_CONSTR:
1197 case CONJ_CONSTR:
1198 case DISJ_CONSTR:
1199 pp_cxx_constraint (this, t);
1200 break;
1202 case PAREN_EXPR:
1203 pp_cxx_left_paren (this);
1204 expression (TREE_OPERAND (t, 0));
1205 pp_cxx_right_paren (this);
1206 break;
1208 default:
1209 c_pretty_printer::expression (t);
1210 break;
1215 /* Declarations. */
1217 /* function-specifier:
1218 inline
1219 virtual
1220 explicit */
1222 void
1223 cxx_pretty_printer::function_specifier (tree t)
1225 switch (TREE_CODE (t))
1227 case FUNCTION_DECL:
1228 if (DECL_VIRTUAL_P (t))
1229 pp_cxx_ws_string (this, "virtual");
1230 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1231 pp_cxx_ws_string (this, "explicit");
1232 else
1233 c_pretty_printer::function_specifier (t);
1235 default:
1236 break;
1240 /* decl-specifier-seq:
1241 decl-specifier-seq(opt) decl-specifier
1243 decl-specifier:
1244 storage-class-specifier
1245 type-specifier
1246 function-specifier
1247 friend
1248 typedef */
1250 void
1251 cxx_pretty_printer::declaration_specifiers (tree t)
1253 switch (TREE_CODE (t))
1255 case VAR_DECL:
1256 case PARM_DECL:
1257 case CONST_DECL:
1258 case FIELD_DECL:
1259 storage_class_specifier (t);
1260 declaration_specifiers (TREE_TYPE (t));
1261 break;
1263 case TYPE_DECL:
1264 pp_cxx_ws_string (this, "typedef");
1265 declaration_specifiers (TREE_TYPE (t));
1266 break;
1268 case FUNCTION_DECL:
1269 /* Constructors don't have return types. And conversion functions
1270 do not have a type-specifier in their return types. */
1271 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1272 function_specifier (t);
1273 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1274 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1275 else
1276 c_pretty_printer::declaration_specifiers (t);
1277 break;
1278 default:
1279 c_pretty_printer::declaration_specifiers (t);
1280 break;
1284 /* simple-type-specifier:
1285 ::(opt) nested-name-specifier(opt) type-name
1286 ::(opt) nested-name-specifier(opt) template(opt) template-id
1287 char
1288 wchar_t
1289 bool
1290 short
1292 long
1293 signed
1294 unsigned
1295 float
1296 double
1297 void */
1299 void
1300 cxx_pretty_printer::simple_type_specifier (tree t)
1302 switch (TREE_CODE (t))
1304 case RECORD_TYPE:
1305 case UNION_TYPE:
1306 case ENUMERAL_TYPE:
1307 pp_cxx_qualified_id (this, t);
1308 break;
1310 case TEMPLATE_TYPE_PARM:
1311 case TEMPLATE_TEMPLATE_PARM:
1312 case TEMPLATE_PARM_INDEX:
1313 case BOUND_TEMPLATE_TEMPLATE_PARM:
1314 pp_cxx_unqualified_id (this, t);
1315 break;
1317 case TYPENAME_TYPE:
1318 pp_cxx_ws_string (this, "typename");
1319 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1320 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1321 break;
1323 default:
1324 c_pretty_printer::simple_type_specifier (t);
1325 break;
1329 /* type-specifier-seq:
1330 type-specifier type-specifier-seq(opt)
1332 type-specifier:
1333 simple-type-specifier
1334 class-specifier
1335 enum-specifier
1336 elaborated-type-specifier
1337 cv-qualifier */
1339 static void
1340 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1342 switch (TREE_CODE (t))
1344 case TEMPLATE_DECL:
1345 case TEMPLATE_TYPE_PARM:
1346 case TEMPLATE_TEMPLATE_PARM:
1347 case TYPE_DECL:
1348 case BOUND_TEMPLATE_TEMPLATE_PARM:
1349 pp_cxx_cv_qualifier_seq (pp, t);
1350 pp->simple_type_specifier (t);
1351 break;
1353 case METHOD_TYPE:
1354 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1355 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1356 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1357 break;
1359 case DECLTYPE_TYPE:
1360 pp_cxx_ws_string (pp, "decltype");
1361 pp_cxx_left_paren (pp);
1362 pp->expression (DECLTYPE_TYPE_EXPR (t));
1363 pp_cxx_right_paren (pp);
1364 break;
1366 case RECORD_TYPE:
1367 if (TYPE_PTRMEMFUNC_P (t))
1369 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1370 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1371 pp_cxx_whitespace (pp);
1372 pp_cxx_ptr_operator (pp, t);
1373 break;
1375 /* fall through */
1377 default:
1378 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1379 pp_c_specifier_qualifier_list (pp, t);
1383 /* ptr-operator:
1384 * cv-qualifier-seq(opt)
1386 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1388 static void
1389 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1391 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1392 t = TREE_TYPE (t);
1393 switch (TREE_CODE (t))
1395 case REFERENCE_TYPE:
1396 case POINTER_TYPE:
1397 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1398 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1399 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1400 if (TYPE_PTR_P (t))
1402 pp_star (pp);
1403 pp_cxx_cv_qualifier_seq (pp, t);
1405 else
1406 pp_ampersand (pp);
1407 break;
1409 case RECORD_TYPE:
1410 if (TYPE_PTRMEMFUNC_P (t))
1412 pp_cxx_left_paren (pp);
1413 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1414 pp_star (pp);
1415 break;
1417 /* FALLTHRU */
1418 case OFFSET_TYPE:
1419 if (TYPE_PTRMEM_P (t))
1421 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1422 pp_cxx_left_paren (pp);
1423 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1424 pp_star (pp);
1425 pp_cxx_cv_qualifier_seq (pp, t);
1426 break;
1428 /* fall through. */
1430 default:
1431 pp_unsupported_tree (pp, t);
1432 break;
1436 static inline tree
1437 pp_cxx_implicit_parameter_type (tree mf)
1439 return class_of_this_parm (TREE_TYPE (mf));
1443 parameter-declaration:
1444 decl-specifier-seq declarator
1445 decl-specifier-seq declarator = assignment-expression
1446 decl-specifier-seq abstract-declarator(opt)
1447 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1449 static inline void
1450 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1452 pp->declaration_specifiers (t);
1453 if (TYPE_P (t))
1454 pp->abstract_declarator (t);
1455 else
1456 pp->declarator (t);
1459 /* parameter-declaration-clause:
1460 parameter-declaration-list(opt) ...(opt)
1461 parameter-declaration-list , ...
1463 parameter-declaration-list:
1464 parameter-declaration
1465 parameter-declaration-list , parameter-declaration */
1467 static void
1468 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1470 tree args;
1471 tree types;
1472 bool abstract;
1474 // For a requires clause or the explicit printing of a parameter list
1475 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1476 // args and types are taken from the function decl T.
1477 if (TREE_CODE (t) == PARM_DECL)
1479 args = t;
1480 types = t;
1481 abstract = false;
1483 else
1485 bool type_p = TYPE_P (t);
1486 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1487 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1488 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1490 bool first = true;
1492 /* Skip artificial parameter for nonstatic member functions. */
1493 if (TREE_CODE (t) == METHOD_TYPE)
1494 types = TREE_CHAIN (types);
1496 pp_cxx_left_paren (pp);
1497 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1499 if (!first)
1500 pp_cxx_separate_with (pp, ',');
1501 first = false;
1502 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1503 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1505 pp_cxx_whitespace (pp);
1506 pp_equal (pp);
1507 pp_cxx_whitespace (pp);
1508 pp->assignment_expression (TREE_PURPOSE (types));
1511 pp_cxx_right_paren (pp);
1514 /* exception-specification:
1515 throw ( type-id-list(opt) )
1517 type-id-list
1518 type-id
1519 type-id-list , type-id */
1521 static void
1522 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1524 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1525 bool need_comma = false;
1527 if (ex_spec == NULL)
1528 return;
1529 if (TREE_PURPOSE (ex_spec))
1531 pp_cxx_ws_string (pp, "noexcept");
1532 pp_cxx_whitespace (pp);
1533 pp_cxx_left_paren (pp);
1534 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1535 pp_cxx_ws_string (pp, "<uninstantiated>");
1536 else
1537 pp->expression (TREE_PURPOSE (ex_spec));
1538 pp_cxx_right_paren (pp);
1539 return;
1541 pp_cxx_ws_string (pp, "throw");
1542 pp_cxx_left_paren (pp);
1543 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1545 tree type = TREE_VALUE (ex_spec);
1546 tree argpack = NULL_TREE;
1547 int i, len = 1;
1549 if (ARGUMENT_PACK_P (type))
1551 argpack = ARGUMENT_PACK_ARGS (type);
1552 len = TREE_VEC_LENGTH (argpack);
1555 for (i = 0; i < len; ++i)
1557 if (argpack)
1558 type = TREE_VEC_ELT (argpack, i);
1560 if (need_comma)
1561 pp_cxx_separate_with (pp, ',');
1562 else
1563 need_comma = true;
1565 pp->type_id (type);
1568 pp_cxx_right_paren (pp);
1571 /* direct-declarator:
1572 declarator-id
1573 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1574 exception-specification(opt)
1575 direct-declaration [ constant-expression(opt) ]
1576 ( declarator ) */
1578 void
1579 cxx_pretty_printer::direct_declarator (tree t)
1581 switch (TREE_CODE (t))
1583 case VAR_DECL:
1584 case PARM_DECL:
1585 case CONST_DECL:
1586 case FIELD_DECL:
1587 if (DECL_NAME (t))
1589 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1591 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1592 || template_parameter_pack_p (t))
1593 /* A function parameter pack or non-type template
1594 parameter pack. */
1595 pp_cxx_ws_string (this, "...");
1597 id_expression (DECL_NAME (t));
1599 abstract_declarator (TREE_TYPE (t));
1600 break;
1602 case FUNCTION_DECL:
1603 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1604 expression (t);
1605 pp_cxx_parameter_declaration_clause (this, t);
1607 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1609 padding = pp_before;
1610 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1613 pp_cxx_exception_specification (this, TREE_TYPE (t));
1614 break;
1616 case TYPENAME_TYPE:
1617 case TEMPLATE_DECL:
1618 case TEMPLATE_TYPE_PARM:
1619 case TEMPLATE_PARM_INDEX:
1620 case TEMPLATE_TEMPLATE_PARM:
1621 break;
1623 default:
1624 c_pretty_printer::direct_declarator (t);
1625 break;
1629 /* declarator:
1630 direct-declarator
1631 ptr-operator declarator */
1633 void
1634 cxx_pretty_printer::declarator (tree t)
1636 direct_declarator (t);
1638 // Print a requires clause.
1639 if (flag_concepts)
1640 if (tree ci = get_constraints (t))
1641 if (tree reqs = CI_DECLARATOR_REQS (ci))
1642 pp_cxx_requires_clause (this, reqs);
1645 /* ctor-initializer:
1646 : mem-initializer-list
1648 mem-initializer-list:
1649 mem-initializer
1650 mem-initializer , mem-initializer-list
1652 mem-initializer:
1653 mem-initializer-id ( expression-list(opt) )
1655 mem-initializer-id:
1656 ::(opt) nested-name-specifier(opt) class-name
1657 identifier */
1659 static void
1660 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1662 t = TREE_OPERAND (t, 0);
1663 pp_cxx_whitespace (pp);
1664 pp_colon (pp);
1665 pp_cxx_whitespace (pp);
1666 for (; t; t = TREE_CHAIN (t))
1668 tree purpose = TREE_PURPOSE (t);
1669 bool is_pack = PACK_EXPANSION_P (purpose);
1671 if (is_pack)
1672 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1673 else
1674 pp->primary_expression (purpose);
1675 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1676 if (is_pack)
1677 pp_cxx_ws_string (pp, "...");
1678 if (TREE_CHAIN (t))
1679 pp_cxx_separate_with (pp, ',');
1683 /* function-definition:
1684 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1685 decl-specifier-seq(opt) declarator function-try-block */
1687 static void
1688 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1690 tree saved_scope = pp->enclosing_scope;
1691 pp->declaration_specifiers (t);
1692 pp->declarator (t);
1693 pp_needs_newline (pp) = true;
1694 pp->enclosing_scope = DECL_CONTEXT (t);
1695 if (DECL_SAVED_TREE (t))
1696 pp->statement (DECL_SAVED_TREE (t));
1697 else
1698 pp_cxx_semicolon (pp);
1699 pp_newline_and_flush (pp);
1700 pp->enclosing_scope = saved_scope;
1703 /* abstract-declarator:
1704 ptr-operator abstract-declarator(opt)
1705 direct-abstract-declarator */
1707 void
1708 cxx_pretty_printer::abstract_declarator (tree t)
1710 if (TYPE_PTRMEM_P (t))
1711 pp_cxx_right_paren (this);
1712 else if (POINTER_TYPE_P (t))
1714 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1715 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1716 pp_cxx_right_paren (this);
1717 t = TREE_TYPE (t);
1719 direct_abstract_declarator (t);
1722 /* direct-abstract-declarator:
1723 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1724 cv-qualifier-seq(opt) exception-specification(opt)
1725 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1726 ( abstract-declarator ) */
1728 void
1729 cxx_pretty_printer::direct_abstract_declarator (tree t)
1731 switch (TREE_CODE (t))
1733 case REFERENCE_TYPE:
1734 abstract_declarator (t);
1735 break;
1737 case RECORD_TYPE:
1738 if (TYPE_PTRMEMFUNC_P (t))
1739 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1740 break;
1742 case METHOD_TYPE:
1743 case FUNCTION_TYPE:
1744 pp_cxx_parameter_declaration_clause (this, t);
1745 direct_abstract_declarator (TREE_TYPE (t));
1746 if (TREE_CODE (t) == METHOD_TYPE)
1748 padding = pp_before;
1749 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1751 pp_cxx_exception_specification (this, t);
1752 break;
1754 case TYPENAME_TYPE:
1755 case TEMPLATE_TYPE_PARM:
1756 case TEMPLATE_TEMPLATE_PARM:
1757 case BOUND_TEMPLATE_TEMPLATE_PARM:
1758 case UNBOUND_CLASS_TEMPLATE:
1759 break;
1761 default:
1762 c_pretty_printer::direct_abstract_declarator (t);
1763 break;
1767 /* type-id:
1768 type-specifier-seq abstract-declarator(opt) */
1770 void
1771 cxx_pretty_printer::type_id (tree t)
1773 pp_flags saved_flags = flags;
1774 flags |= pp_c_flag_abstract;
1776 switch (TREE_CODE (t))
1778 case TYPE_DECL:
1779 case UNION_TYPE:
1780 case RECORD_TYPE:
1781 case ENUMERAL_TYPE:
1782 case TYPENAME_TYPE:
1783 case BOUND_TEMPLATE_TEMPLATE_PARM:
1784 case UNBOUND_CLASS_TEMPLATE:
1785 case TEMPLATE_TEMPLATE_PARM:
1786 case TEMPLATE_TYPE_PARM:
1787 case TEMPLATE_PARM_INDEX:
1788 case TEMPLATE_DECL:
1789 case TYPEOF_TYPE:
1790 case UNDERLYING_TYPE:
1791 case DECLTYPE_TYPE:
1792 case TEMPLATE_ID_EXPR:
1793 pp_cxx_type_specifier_seq (this, t);
1794 break;
1796 case TYPE_PACK_EXPANSION:
1797 type_id (PACK_EXPANSION_PATTERN (t));
1798 pp_cxx_ws_string (this, "...");
1799 break;
1801 default:
1802 c_pretty_printer::type_id (t);
1803 break;
1806 flags = saved_flags;
1809 /* template-argument-list:
1810 template-argument ...(opt)
1811 template-argument-list, template-argument ...(opt)
1813 template-argument:
1814 assignment-expression
1815 type-id
1816 template-name */
1818 static void
1819 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1821 int i;
1822 bool need_comma = false;
1824 if (t == NULL)
1825 return;
1826 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1828 tree arg = TREE_VEC_ELT (t, i);
1829 tree argpack = NULL_TREE;
1830 int idx, len = 1;
1832 if (ARGUMENT_PACK_P (arg))
1834 argpack = ARGUMENT_PACK_ARGS (arg);
1835 len = TREE_VEC_LENGTH (argpack);
1838 for (idx = 0; idx < len; idx++)
1840 if (argpack)
1841 arg = TREE_VEC_ELT (argpack, idx);
1843 if (need_comma)
1844 pp_cxx_separate_with (pp, ',');
1845 else
1846 need_comma = true;
1848 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1849 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1850 pp->type_id (arg);
1851 else
1852 pp->expression (arg);
1858 static void
1859 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1861 t = DECL_EXPR_DECL (t);
1862 pp_cxx_type_specifier_seq (pp, t);
1863 if (TYPE_P (t))
1864 pp->abstract_declarator (t);
1865 else
1866 pp->declarator (t);
1869 /* Statements. */
1871 void
1872 cxx_pretty_printer::statement (tree t)
1874 switch (TREE_CODE (t))
1876 case CTOR_INITIALIZER:
1877 pp_cxx_ctor_initializer (this, t);
1878 break;
1880 case USING_STMT:
1881 pp_cxx_ws_string (this, "using");
1882 pp_cxx_ws_string (this, "namespace");
1883 if (DECL_CONTEXT (t))
1884 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1885 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1886 break;
1888 case USING_DECL:
1889 pp_cxx_ws_string (this, "using");
1890 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1891 pp_cxx_unqualified_id (this, DECL_NAME (t));
1892 break;
1894 case EH_SPEC_BLOCK:
1895 break;
1897 /* try-block:
1898 try compound-statement handler-seq */
1899 case TRY_BLOCK:
1900 pp_maybe_newline_and_indent (this, 0);
1901 pp_cxx_ws_string (this, "try");
1902 pp_newline_and_indent (this, 3);
1903 statement (TRY_STMTS (t));
1904 pp_newline_and_indent (this, -3);
1905 if (CLEANUP_P (t))
1907 else
1908 statement (TRY_HANDLERS (t));
1909 break;
1912 handler-seq:
1913 handler handler-seq(opt)
1915 handler:
1916 catch ( exception-declaration ) compound-statement
1918 exception-declaration:
1919 type-specifier-seq declarator
1920 type-specifier-seq abstract-declarator
1921 ... */
1922 case HANDLER:
1923 pp_cxx_ws_string (this, "catch");
1924 pp_cxx_left_paren (this);
1925 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1926 pp_cxx_right_paren (this);
1927 pp_indentation (this) += 3;
1928 pp_needs_newline (this) = true;
1929 statement (HANDLER_BODY (t));
1930 pp_indentation (this) -= 3;
1931 pp_needs_newline (this) = true;
1932 break;
1934 /* selection-statement:
1935 if ( expression ) statement
1936 if ( expression ) statement else statement */
1937 case IF_STMT:
1938 pp_cxx_ws_string (this, "if");
1939 pp_cxx_whitespace (this);
1940 pp_cxx_left_paren (this);
1941 expression (IF_COND (t));
1942 pp_cxx_right_paren (this);
1943 pp_newline_and_indent (this, 2);
1944 statement (THEN_CLAUSE (t));
1945 pp_newline_and_indent (this, -2);
1946 if (ELSE_CLAUSE (t))
1948 tree else_clause = ELSE_CLAUSE (t);
1949 pp_cxx_ws_string (this, "else");
1950 if (TREE_CODE (else_clause) == IF_STMT)
1951 pp_cxx_whitespace (this);
1952 else
1953 pp_newline_and_indent (this, 2);
1954 statement (else_clause);
1955 if (TREE_CODE (else_clause) != IF_STMT)
1956 pp_newline_and_indent (this, -2);
1958 break;
1960 case SWITCH_STMT:
1961 pp_cxx_ws_string (this, "switch");
1962 pp_space (this);
1963 pp_cxx_left_paren (this);
1964 expression (SWITCH_STMT_COND (t));
1965 pp_cxx_right_paren (this);
1966 pp_indentation (this) += 3;
1967 pp_needs_newline (this) = true;
1968 statement (SWITCH_STMT_BODY (t));
1969 pp_newline_and_indent (this, -3);
1970 break;
1972 /* iteration-statement:
1973 while ( expression ) statement
1974 do statement while ( expression ) ;
1975 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1976 for ( declaration expression(opt) ; expression(opt) ) statement */
1977 case WHILE_STMT:
1978 pp_cxx_ws_string (this, "while");
1979 pp_space (this);
1980 pp_cxx_left_paren (this);
1981 expression (WHILE_COND (t));
1982 pp_cxx_right_paren (this);
1983 pp_newline_and_indent (this, 3);
1984 statement (WHILE_BODY (t));
1985 pp_indentation (this) -= 3;
1986 pp_needs_newline (this) = true;
1987 break;
1989 case DO_STMT:
1990 pp_cxx_ws_string (this, "do");
1991 pp_newline_and_indent (this, 3);
1992 statement (DO_BODY (t));
1993 pp_newline_and_indent (this, -3);
1994 pp_cxx_ws_string (this, "while");
1995 pp_space (this);
1996 pp_cxx_left_paren (this);
1997 expression (DO_COND (t));
1998 pp_cxx_right_paren (this);
1999 pp_cxx_semicolon (this);
2000 pp_needs_newline (this) = true;
2001 break;
2003 case FOR_STMT:
2004 pp_cxx_ws_string (this, "for");
2005 pp_space (this);
2006 pp_cxx_left_paren (this);
2007 if (FOR_INIT_STMT (t))
2008 statement (FOR_INIT_STMT (t));
2009 else
2010 pp_cxx_semicolon (this);
2011 pp_needs_newline (this) = false;
2012 pp_cxx_whitespace (this);
2013 if (FOR_COND (t))
2014 expression (FOR_COND (t));
2015 pp_cxx_semicolon (this);
2016 pp_needs_newline (this) = false;
2017 pp_cxx_whitespace (this);
2018 if (FOR_EXPR (t))
2019 expression (FOR_EXPR (t));
2020 pp_cxx_right_paren (this);
2021 pp_newline_and_indent (this, 3);
2022 statement (FOR_BODY (t));
2023 pp_indentation (this) -= 3;
2024 pp_needs_newline (this) = true;
2025 break;
2027 case RANGE_FOR_STMT:
2028 pp_cxx_ws_string (this, "for");
2029 pp_space (this);
2030 pp_cxx_left_paren (this);
2031 statement (RANGE_FOR_DECL (t));
2032 pp_space (this);
2033 pp_needs_newline (this) = false;
2034 pp_colon (this);
2035 pp_space (this);
2036 statement (RANGE_FOR_EXPR (t));
2037 pp_cxx_right_paren (this);
2038 pp_newline_and_indent (this, 3);
2039 statement (FOR_BODY (t));
2040 pp_indentation (this) -= 3;
2041 pp_needs_newline (this) = true;
2042 break;
2044 /* jump-statement:
2045 goto identifier;
2046 continue ;
2047 return expression(opt) ; */
2048 case BREAK_STMT:
2049 case CONTINUE_STMT:
2050 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2051 pp_cxx_semicolon (this);
2052 pp_needs_newline (this) = true;
2053 break;
2055 /* expression-statement:
2056 expression(opt) ; */
2057 case EXPR_STMT:
2058 expression (EXPR_STMT_EXPR (t));
2059 pp_cxx_semicolon (this);
2060 pp_needs_newline (this) = true;
2061 break;
2063 case CLEANUP_STMT:
2064 pp_cxx_ws_string (this, "try");
2065 pp_newline_and_indent (this, 2);
2066 statement (CLEANUP_BODY (t));
2067 pp_newline_and_indent (this, -2);
2068 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2069 pp_newline_and_indent (this, 2);
2070 statement (CLEANUP_EXPR (t));
2071 pp_newline_and_indent (this, -2);
2072 break;
2074 case STATIC_ASSERT:
2075 declaration (t);
2076 break;
2078 default:
2079 c_pretty_printer::statement (t);
2080 break;
2084 /* original-namespace-definition:
2085 namespace identifier { namespace-body }
2087 As an edge case, we also handle unnamed namespace definition here. */
2089 static void
2090 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2092 pp_cxx_ws_string (pp, "namespace");
2093 if (DECL_CONTEXT (t))
2094 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2095 if (DECL_NAME (t))
2096 pp_cxx_unqualified_id (pp, t);
2097 pp_cxx_whitespace (pp);
2098 pp_cxx_left_brace (pp);
2099 /* We do not print the namespace-body. */
2100 pp_cxx_whitespace (pp);
2101 pp_cxx_right_brace (pp);
2104 /* namespace-alias:
2105 identifier
2107 namespace-alias-definition:
2108 namespace identifier = qualified-namespace-specifier ;
2110 qualified-namespace-specifier:
2111 ::(opt) nested-name-specifier(opt) namespace-name */
2113 static void
2114 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2116 pp_cxx_ws_string (pp, "namespace");
2117 if (DECL_CONTEXT (t))
2118 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2119 pp_cxx_unqualified_id (pp, t);
2120 pp_cxx_whitespace (pp);
2121 pp_equal (pp);
2122 pp_cxx_whitespace (pp);
2123 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2124 pp_cxx_nested_name_specifier (pp,
2125 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2126 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2127 pp_cxx_semicolon (pp);
2130 /* simple-declaration:
2131 decl-specifier-seq(opt) init-declarator-list(opt) */
2133 static void
2134 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2136 pp->declaration_specifiers (t);
2137 pp_cxx_init_declarator (pp, t);
2138 pp_cxx_semicolon (pp);
2139 pp_needs_newline (pp) = true;
2143 template-parameter-list:
2144 template-parameter
2145 template-parameter-list , template-parameter */
2147 static inline void
2148 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2150 const int n = TREE_VEC_LENGTH (t);
2151 int i;
2152 for (i = 0; i < n; ++i)
2154 if (i)
2155 pp_cxx_separate_with (pp, ',');
2156 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2160 /* template-parameter:
2161 type-parameter
2162 parameter-declaration
2164 type-parameter:
2165 class ...(opt) identifier(opt)
2166 class identifier(opt) = type-id
2167 typename identifier(opt)
2168 typename ...(opt) identifier(opt) = type-id
2169 template < template-parameter-list > class ...(opt) identifier(opt)
2170 template < template-parameter-list > class identifier(opt) = template-name */
2172 static void
2173 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2175 tree parameter = TREE_VALUE (t);
2176 switch (TREE_CODE (parameter))
2178 case TYPE_DECL:
2179 pp_cxx_ws_string (pp, "class");
2180 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2181 pp_cxx_ws_string (pp, "...");
2182 if (DECL_NAME (parameter))
2183 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2184 /* FIXME: Check if we should print also default argument. */
2185 break;
2187 case PARM_DECL:
2188 pp_cxx_parameter_declaration (pp, parameter);
2189 break;
2191 case TEMPLATE_DECL:
2192 break;
2194 default:
2195 pp_unsupported_tree (pp, t);
2196 break;
2200 /* Pretty-print a template parameter in the canonical form
2201 "template-parameter-<level>-<position in parameter list>". */
2203 void
2204 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2206 const enum tree_code code = TREE_CODE (parm);
2208 /* Brings type template parameters to the canonical forms. */
2209 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2210 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2211 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2213 pp_cxx_begin_template_argument_list (pp);
2214 pp->translate_string ("template-parameter-");
2215 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2216 pp_minus (pp);
2217 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2218 pp_cxx_end_template_argument_list (pp);
2221 /* Print a constrained-type-specifier. */
2223 void
2224 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2226 tree t, a;
2227 if (c == error_mark_node)
2229 pp_cxx_ws_string(pp, "<unsatisfied-constrained-placeholder>");
2230 return;
2232 placeholder_extract_concept_and_args (c, t, a);
2233 pp->id_expression (t);
2234 if (TREE_VEC_LENGTH (a) > 1)
2236 pp_cxx_begin_template_argument_list (pp);
2237 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2238 for (int i = TREE_VEC_LENGTH (a) - 1; i > 0; --i)
2239 TREE_VEC_ELT (args, i-1) = TREE_VEC_ELT (a, i);
2240 pp_cxx_template_argument_list (pp, args);
2241 ggc_free (args);
2242 pp_cxx_end_template_argument_list (pp);
2247 template-declaration:
2248 export(opt) template < template-parameter-list > declaration
2250 Concept extensions:
2252 template-declaration:
2253 export(opt) template < template-parameter-list >
2254 requires-clause(opt) declaration */
2256 static void
2257 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2259 tree tmpl = most_general_template (t);
2260 tree level;
2262 pp_maybe_newline_and_indent (pp, 0);
2263 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2265 pp_cxx_ws_string (pp, "template");
2266 pp_cxx_begin_template_argument_list (pp);
2267 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2268 pp_cxx_end_template_argument_list (pp);
2269 pp_newline_and_indent (pp, 3);
2272 if (flag_concepts)
2273 if (tree ci = get_constraints (t))
2274 if (tree reqs = CI_TEMPLATE_REQS (ci))
2276 pp_cxx_requires_clause (pp, reqs);
2277 pp_newline_and_indent (pp, 6);
2280 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2281 pp_cxx_function_definition (pp, t);
2282 else
2283 pp_cxx_simple_declaration (pp, t);
2286 static void
2287 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2289 pp_unsupported_tree (pp, t);
2292 static void
2293 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2295 pp_unsupported_tree (pp, t);
2299 declaration:
2300 block-declaration
2301 function-definition
2302 template-declaration
2303 explicit-instantiation
2304 explicit-specialization
2305 linkage-specification
2306 namespace-definition
2308 block-declaration:
2309 simple-declaration
2310 asm-definition
2311 namespace-alias-definition
2312 using-declaration
2313 using-directive
2314 static_assert-declaration */
2315 void
2316 cxx_pretty_printer::declaration (tree t)
2318 if (TREE_CODE (t) == STATIC_ASSERT)
2320 pp_cxx_ws_string (this, "static_assert");
2321 pp_cxx_left_paren (this);
2322 expression (STATIC_ASSERT_CONDITION (t));
2323 pp_cxx_separate_with (this, ',');
2324 expression (STATIC_ASSERT_MESSAGE (t));
2325 pp_cxx_right_paren (this);
2327 else if (!DECL_LANG_SPECIFIC (t))
2328 pp_cxx_simple_declaration (this, t);
2329 else if (DECL_USE_TEMPLATE (t))
2330 switch (DECL_USE_TEMPLATE (t))
2332 case 1:
2333 pp_cxx_template_declaration (this, t);
2334 break;
2336 case 2:
2337 pp_cxx_explicit_specialization (this, t);
2338 break;
2340 case 3:
2341 pp_cxx_explicit_instantiation (this, t);
2342 break;
2344 default:
2345 break;
2347 else switch (TREE_CODE (t))
2349 case VAR_DECL:
2350 case TYPE_DECL:
2351 pp_cxx_simple_declaration (this, t);
2352 break;
2354 case FUNCTION_DECL:
2355 if (DECL_SAVED_TREE (t))
2356 pp_cxx_function_definition (this, t);
2357 else
2358 pp_cxx_simple_declaration (this, t);
2359 break;
2361 case NAMESPACE_DECL:
2362 if (DECL_NAMESPACE_ALIAS (t))
2363 pp_cxx_namespace_alias_definition (this, t);
2364 else
2365 pp_cxx_original_namespace_definition (this, t);
2366 break;
2368 default:
2369 pp_unsupported_tree (this, t);
2370 break;
2374 static void
2375 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2377 t = TREE_OPERAND (t, 0);
2378 pp_cxx_ws_string (pp, "typeid");
2379 pp_cxx_left_paren (pp);
2380 if (TYPE_P (t))
2381 pp->type_id (t);
2382 else
2383 pp->expression (t);
2384 pp_cxx_right_paren (pp);
2387 void
2388 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2390 pp_cxx_ws_string (pp, "va_arg");
2391 pp_cxx_left_paren (pp);
2392 pp->assignment_expression (TREE_OPERAND (t, 0));
2393 pp_cxx_separate_with (pp, ',');
2394 pp->type_id (TREE_TYPE (t));
2395 pp_cxx_right_paren (pp);
2398 static bool
2399 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2401 switch (TREE_CODE (t))
2403 case ARROW_EXPR:
2404 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2405 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2407 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2408 pp_cxx_separate_with (pp, ',');
2409 return true;
2411 return false;
2412 case COMPONENT_REF:
2413 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2414 return false;
2415 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2416 pp_cxx_dot (pp);
2417 pp->expression (TREE_OPERAND (t, 1));
2418 return true;
2419 case ARRAY_REF:
2420 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2421 return false;
2422 pp_left_bracket (pp);
2423 pp->expression (TREE_OPERAND (t, 1));
2424 pp_right_bracket (pp);
2425 return true;
2426 default:
2427 return false;
2431 void
2432 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2434 pp_cxx_ws_string (pp, "offsetof");
2435 pp_cxx_left_paren (pp);
2436 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2437 pp->expression (TREE_OPERAND (t, 0));
2438 pp_cxx_right_paren (pp);
2441 static char const*
2442 get_fold_operator (tree t)
2444 int op = int_cst_value (FOLD_EXPR_OP (t));
2445 if (FOLD_EXPR_MODIFY_P (t))
2447 switch (op)
2449 case NOP_EXPR: return "=";
2450 case PLUS_EXPR: return "+=";
2451 case MINUS_EXPR: return "-=";
2452 case MULT_EXPR: return "*=";
2453 case TRUNC_DIV_EXPR: return "/=";
2454 case TRUNC_MOD_EXPR: return "%=";
2455 case BIT_XOR_EXPR: return "^=";
2456 case BIT_AND_EXPR: return "&=";
2457 case BIT_IOR_EXPR: return "|=";
2458 case LSHIFT_EXPR: return "<<=";
2459 case RSHIFT_EXPR: return ">>=";
2460 default: gcc_unreachable ();
2463 else
2465 switch (op)
2467 case PLUS_EXPR: return "+";
2468 case MINUS_EXPR: return "-";
2469 case MULT_EXPR: return "*";
2470 case TRUNC_DIV_EXPR: return "/";
2471 case TRUNC_MOD_EXPR: return "%";
2472 case BIT_XOR_EXPR: return "^";
2473 case BIT_AND_EXPR: return "&";
2474 case BIT_IOR_EXPR: return "|";
2475 case LSHIFT_EXPR: return "<<";
2476 case RSHIFT_EXPR: return ">>";
2477 case EQ_EXPR: return "==";
2478 case NE_EXPR: return "!=";
2479 case LT_EXPR: return "<";
2480 case GT_EXPR: return ">";
2481 case LE_EXPR: return "<=";
2482 case GE_EXPR: return ">=";
2483 case TRUTH_ANDIF_EXPR: return "&&";
2484 case TRUTH_ORIF_EXPR: return "||";
2485 case MEMBER_REF: return "->*";
2486 case DOTSTAR_EXPR: return ".*";
2487 case OFFSET_REF: return ".*";
2488 default: return ","; /* FIXME: Not the right default. */
2493 void
2494 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2496 char const* op = get_fold_operator (t);
2497 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2498 pp_cxx_left_paren (pp);
2499 pp_cxx_ws_string (pp, "...");
2500 pp_cxx_ws_string (pp, op);
2501 pp->expression (expr);
2502 pp_cxx_right_paren (pp);
2505 void
2506 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2508 char const* op = get_fold_operator (t);
2509 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2510 pp_cxx_left_paren (pp);
2511 pp->expression (expr);
2512 pp_space (pp);
2513 pp_cxx_ws_string (pp, op);
2514 pp_cxx_ws_string (pp, "...");
2515 pp_cxx_right_paren (pp);
2518 void
2519 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2521 char const* op = get_fold_operator (t);
2522 tree t1 = TREE_OPERAND (t, 1);
2523 tree t2 = TREE_OPERAND (t, 2);
2524 if (t1 == FOLD_EXPR_PACK (t))
2525 t1 = PACK_EXPANSION_PATTERN (t1);
2526 else
2527 t2 = PACK_EXPANSION_PATTERN (t2);
2528 pp_cxx_left_paren (pp);
2529 pp->expression (t1);
2530 pp_cxx_ws_string (pp, op);
2531 pp_cxx_ws_string (pp, "...");
2532 pp_cxx_ws_string (pp, op);
2533 pp->expression (t2);
2534 pp_cxx_right_paren (pp);
2537 void
2538 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2540 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2542 switch (kind)
2544 case CPTK_HAS_NOTHROW_ASSIGN:
2545 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2546 break;
2547 case CPTK_HAS_TRIVIAL_ASSIGN:
2548 pp_cxx_ws_string (pp, "__has_trivial_assign");
2549 break;
2550 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2551 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2552 break;
2553 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2554 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2555 break;
2556 case CPTK_HAS_NOTHROW_COPY:
2557 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2558 break;
2559 case CPTK_HAS_TRIVIAL_COPY:
2560 pp_cxx_ws_string (pp, "__has_trivial_copy");
2561 break;
2562 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2563 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2564 break;
2565 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2566 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2567 break;
2568 case CPTK_IS_ABSTRACT:
2569 pp_cxx_ws_string (pp, "__is_abstract");
2570 break;
2571 case CPTK_IS_BASE_OF:
2572 pp_cxx_ws_string (pp, "__is_base_of");
2573 break;
2574 case CPTK_IS_CLASS:
2575 pp_cxx_ws_string (pp, "__is_class");
2576 break;
2577 case CPTK_IS_EMPTY:
2578 pp_cxx_ws_string (pp, "__is_empty");
2579 break;
2580 case CPTK_IS_ENUM:
2581 pp_cxx_ws_string (pp, "__is_enum");
2582 break;
2583 case CPTK_IS_FINAL:
2584 pp_cxx_ws_string (pp, "__is_final");
2585 break;
2586 case CPTK_IS_POD:
2587 pp_cxx_ws_string (pp, "__is_pod");
2588 break;
2589 case CPTK_IS_POLYMORPHIC:
2590 pp_cxx_ws_string (pp, "__is_polymorphic");
2591 break;
2592 case CPTK_IS_SAME_AS:
2593 pp_cxx_ws_string (pp, "__is_same_as");
2594 break;
2595 case CPTK_IS_STD_LAYOUT:
2596 pp_cxx_ws_string (pp, "__is_std_layout");
2597 break;
2598 case CPTK_IS_TRIVIAL:
2599 pp_cxx_ws_string (pp, "__is_trivial");
2600 break;
2601 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2602 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2603 break;
2604 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2605 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2606 break;
2607 case CPTK_IS_TRIVIALLY_COPYABLE:
2608 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2609 break;
2610 case CPTK_IS_UNION:
2611 pp_cxx_ws_string (pp, "__is_union");
2612 break;
2613 case CPTK_IS_LITERAL_TYPE:
2614 pp_cxx_ws_string (pp, "__is_literal_type");
2615 break;
2617 default:
2618 gcc_unreachable ();
2621 pp_cxx_left_paren (pp);
2622 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2624 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2626 pp_cxx_separate_with (pp, ',');
2627 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2630 pp_cxx_right_paren (pp);
2633 // requires-clause:
2634 // 'requires' logical-or-expression
2635 void
2636 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2638 if (!t)
2639 return;
2640 pp->padding = pp_before;
2641 pp_cxx_ws_string (pp, "requires");
2642 pp_space (pp);
2643 pp->expression (t);
2646 /* requirement:
2647 simple-requirement
2648 compound-requirement
2649 type-requirement
2650 nested-requirement */
2651 static void
2652 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2654 switch (TREE_CODE (t))
2656 case SIMPLE_REQ:
2657 pp_cxx_simple_requirement (pp, t);
2658 break;
2660 case TYPE_REQ:
2661 pp_cxx_type_requirement (pp, t);
2662 break;
2664 case COMPOUND_REQ:
2665 pp_cxx_compound_requirement (pp, t);
2666 break;
2668 case NESTED_REQ:
2669 pp_cxx_nested_requirement (pp, t);
2670 break;
2672 default:
2673 gcc_unreachable ();
2677 // requirement-list:
2678 // requirement
2679 // requirement-list ';' requirement[opt]
2681 static void
2682 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2684 for (; t; t = TREE_CHAIN (t))
2685 pp_cxx_requirement (pp, TREE_VALUE (t));
2688 // requirement-body:
2689 // '{' requirement-list '}'
2690 static void
2691 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2693 pp_cxx_left_brace (pp);
2694 pp_cxx_requirement_list (pp, t);
2695 pp_cxx_right_brace (pp);
2698 // requires-expression:
2699 // 'requires' requirement-parameter-list requirement-body
2700 void
2701 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2703 pp_string (pp, "requires");
2704 if (tree parms = TREE_OPERAND (t, 0))
2706 pp_cxx_parameter_declaration_clause (pp, parms);
2707 pp_cxx_whitespace (pp);
2709 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2712 /* simple-requirement:
2713 expression ';' */
2714 void
2715 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2717 pp->expression (TREE_OPERAND (t, 0));
2718 pp_cxx_semicolon (pp);
2721 /* type-requirement:
2722 typename type-name ';' */
2723 void
2724 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2726 pp->type_id (TREE_OPERAND (t, 0));
2727 pp_cxx_semicolon (pp);
2730 /* compound-requirement:
2731 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2732 void
2733 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2735 pp_cxx_left_brace (pp);
2736 pp->expression (TREE_OPERAND (t, 0));
2737 pp_cxx_right_brace (pp);
2739 if (COMPOUND_REQ_NOEXCEPT_P (t))
2740 pp_cxx_ws_string (pp, "noexcept");
2742 if (tree type = TREE_OPERAND (t, 1))
2744 pp_cxx_ws_string (pp, "->");
2745 pp->type_id (type);
2747 pp_cxx_semicolon (pp);
2750 /* nested requirement:
2751 'requires' constraint-expression */
2752 void
2753 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2755 pp_cxx_ws_string (pp, "requires");
2756 pp->expression (TREE_OPERAND (t, 0));
2757 pp_cxx_semicolon (pp);
2760 void
2761 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2763 pp->expression (TREE_OPERAND (t, 0));
2766 void
2767 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2769 tree decl = CHECK_CONSTR_CONCEPT (t);
2770 tree tmpl = DECL_TI_TEMPLATE (decl);
2771 tree args = CHECK_CONSTR_ARGS (t);
2772 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2774 if (TREE_CODE (decl) == VAR_DECL)
2775 pp->expression (id);
2776 else if (TREE_CODE (decl) == FUNCTION_DECL)
2778 tree call = build_vl_exp (CALL_EXPR, 2);
2779 TREE_OPERAND (call, 0) = integer_two_node;
2780 TREE_OPERAND (call, 1) = id;
2781 pp->expression (call);
2783 else
2784 gcc_unreachable ();
2787 void
2788 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2790 pp_string (pp, "<valid-expression ");
2791 pp_cxx_left_paren (pp);
2792 pp->expression (TREE_OPERAND (t, 0));
2793 pp_cxx_right_paren (pp);
2794 pp_string (pp, ">");
2797 void
2798 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2800 pp_string (pp, "<valid-type ");
2801 pp->type_id (TREE_OPERAND (t, 0));
2802 pp_string (pp, ">");
2805 void
2806 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2808 pp_string (pp, "<implicitly-conversion ");
2809 pp_cxx_left_paren (pp);
2810 pp->expression (ICONV_CONSTR_EXPR (t));
2811 pp_cxx_right_paren (pp);
2812 pp_cxx_ws_string (pp, "to");
2813 pp->type_id (ICONV_CONSTR_TYPE (t));
2814 pp_string (pp, ">");
2817 void
2818 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2820 pp_string (pp, "<argument-deduction ");
2821 pp_cxx_left_paren (pp);
2822 pp->expression (DEDUCT_CONSTR_EXPR (t));
2823 pp_cxx_right_paren (pp);
2824 pp_cxx_ws_string (pp, "as");
2825 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2826 pp_string (pp, ">");
2829 void
2830 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2832 pp_cxx_ws_string (pp, "noexcept");
2833 pp_cxx_whitespace (pp);
2834 pp_cxx_left_paren (pp);
2835 pp->expression (TREE_OPERAND (t, 0));
2836 pp_cxx_right_paren (pp);
2839 void
2840 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2842 pp_left_paren (pp);
2843 pp_string (pp, "<requires ");
2844 if (tree parms = PARM_CONSTR_PARMS (t))
2846 pp_cxx_parameter_declaration_clause (pp, parms);
2847 pp_cxx_whitespace (pp);
2849 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2850 pp_string (pp, ">");
2853 void
2854 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2856 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2857 pp_string (pp, " and ");
2858 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2861 void
2862 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2864 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2865 pp_string (pp, " or ");
2866 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2869 void
2870 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2872 if (t == error_mark_node)
2873 return pp->expression (t);
2875 switch (TREE_CODE (t))
2877 case PRED_CONSTR:
2878 pp_cxx_predicate_constraint (pp, t);
2879 break;
2881 case CHECK_CONSTR:
2882 pp_cxx_check_constraint (pp, t);
2883 break;
2885 case EXPR_CONSTR:
2886 pp_cxx_expression_constraint (pp, t);
2887 break;
2889 case TYPE_CONSTR:
2890 pp_cxx_type_constraint (pp, t);
2891 break;
2893 case ICONV_CONSTR:
2894 pp_cxx_implicit_conversion_constraint (pp, t);
2895 break;
2897 case DEDUCT_CONSTR:
2898 pp_cxx_argument_deduction_constraint (pp, t);
2899 break;
2901 case EXCEPT_CONSTR:
2902 pp_cxx_exception_constraint (pp, t);
2903 break;
2905 case PARM_CONSTR:
2906 pp_cxx_parameterized_constraint (pp, t);
2907 break;
2909 case CONJ_CONSTR:
2910 pp_cxx_conjunction (pp, t);
2911 break;
2913 case DISJ_CONSTR:
2914 pp_cxx_disjunction (pp, t);
2915 break;
2917 case EXPR_PACK_EXPANSION:
2918 pp->expression (TREE_OPERAND (t, 0));
2919 break;
2921 default:
2922 gcc_unreachable ();
2928 typedef c_pretty_print_fn pp_fun;
2930 /* Initialization of a C++ pretty-printer object. */
2932 cxx_pretty_printer::cxx_pretty_printer ()
2933 : c_pretty_printer (),
2934 enclosing_scope (global_namespace)
2936 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2937 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;