2018-03-26 Thomas Koenig <tkoenig@gcc.gnu.org>
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob9a5545cb5ccbea15983118c0430ef6429e3a0e9b
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2018 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 /* conversion-function-id:
92 operator conversion-type-id
94 conversion-type-id:
95 type-specifier-seq conversion-declarator(opt)
97 conversion-declarator:
98 ptr-operator conversion-declarator(opt) */
100 static inline void
101 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
103 pp_cxx_ws_string (pp, "operator");
104 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
107 static inline void
108 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
110 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
111 pp_cxx_begin_template_argument_list (pp);
112 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
113 pp_cxx_end_template_argument_list (pp);
116 /* Prints the unqualified part of the id-expression T.
118 unqualified-id:
119 identifier
120 operator-function-id
121 conversion-function-id
122 ~ class-name
123 template-id */
125 static void
126 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
128 enum tree_code code = TREE_CODE (t);
129 switch (code)
131 case RESULT_DECL:
132 pp->translate_string ("<return-value>");
133 break;
135 case OVERLOAD:
136 t = OVL_FIRST (t);
137 /* FALLTHRU */
138 case VAR_DECL:
139 case PARM_DECL:
140 case CONST_DECL:
141 case TYPE_DECL:
142 case FUNCTION_DECL:
143 case NAMESPACE_DECL:
144 case FIELD_DECL:
145 case LABEL_DECL:
146 case USING_DECL:
147 case TEMPLATE_DECL:
148 t = DECL_NAME (t);
149 /* FALLTHRU */
151 case IDENTIFIER_NODE:
152 if (t == NULL)
153 pp->translate_string ("<unnamed>");
154 else if (IDENTIFIER_CONV_OP_P (t))
155 pp_cxx_conversion_function_id (pp, t);
156 else
157 pp_cxx_tree_identifier (pp, t);
158 break;
160 case TEMPLATE_ID_EXPR:
161 pp_cxx_template_id (pp, t);
162 break;
164 case BASELINK:
165 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
166 break;
168 case RECORD_TYPE:
169 case UNION_TYPE:
170 case ENUMERAL_TYPE:
171 case TYPENAME_TYPE:
172 case UNBOUND_CLASS_TEMPLATE:
173 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
174 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
176 pp_cxx_begin_template_argument_list (pp);
177 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
178 (CLASSTYPE_TI_ARGS (t)));
179 pp_cxx_end_template_argument_list (pp);
181 break;
183 case BIT_NOT_EXPR:
184 pp_cxx_complement (pp);
185 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
186 break;
188 case TEMPLATE_TYPE_PARM:
189 case TEMPLATE_TEMPLATE_PARM:
190 if (TYPE_IDENTIFIER (t))
191 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
192 else
193 pp_cxx_canonical_template_parameter (pp, t);
194 break;
196 case TEMPLATE_PARM_INDEX:
197 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
198 break;
200 case BOUND_TEMPLATE_TEMPLATE_PARM:
201 pp_cxx_cv_qualifier_seq (pp, t);
202 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
203 pp_cxx_begin_template_argument_list (pp);
204 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
205 pp_cxx_end_template_argument_list (pp);
206 break;
208 default:
209 pp_unsupported_tree (pp, t);
210 break;
214 /* Pretty-print out the token sequence ":: template" in template codes
215 where it is needed to "inline declare" the (following) member as
216 a template. This situation arises when SCOPE of T is dependent
217 on template parameters. */
219 static inline void
220 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
222 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
223 && TYPE_P (scope) && dependent_type_p (scope))
224 pp_cxx_ws_string (pp, "template");
227 /* nested-name-specifier:
228 class-or-namespace-name :: nested-name-specifier(opt)
229 class-or-namespace-name :: template nested-name-specifier */
231 static void
232 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
234 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
236 tree scope = get_containing_scope (t);
237 pp_cxx_nested_name_specifier (pp, scope);
238 pp_cxx_template_keyword_if_needed (pp, scope, t);
239 pp_cxx_unqualified_id (pp, t);
240 pp_cxx_colon_colon (pp);
244 /* qualified-id:
245 nested-name-specifier template(opt) unqualified-id */
247 static void
248 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
250 switch (TREE_CODE (t))
252 /* A pointer-to-member is always qualified. */
253 case PTRMEM_CST:
254 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
255 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
256 break;
258 /* In Standard C++, functions cannot possibly be used as
259 nested-name-specifiers. However, there are situations where
260 is "makes sense" to output the surrounding function name for the
261 purpose of emphasizing on the scope kind. Just printing the
262 function name might not be sufficient as it may be overloaded; so,
263 we decorate the function with its signature too.
264 FIXME: This is probably the wrong pretty-printing for conversion
265 functions and some function templates. */
266 case OVERLOAD:
267 t = OVL_FIRST (t);
268 /* FALLTHRU */
269 case FUNCTION_DECL:
270 if (DECL_FUNCTION_MEMBER_P (t))
271 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
272 pp_cxx_unqualified_id
273 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
274 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
275 break;
277 case OFFSET_REF:
278 case SCOPE_REF:
279 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
280 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
281 break;
283 default:
285 tree scope = get_containing_scope (t);
286 if (scope != pp->enclosing_scope)
288 pp_cxx_nested_name_specifier (pp, scope);
289 pp_cxx_template_keyword_if_needed (pp, scope, t);
291 pp_cxx_unqualified_id (pp, t);
293 break;
298 void
299 cxx_pretty_printer::constant (tree t)
301 switch (TREE_CODE (t))
303 case STRING_CST:
305 const bool in_parens = PAREN_STRING_LITERAL_P (t);
306 if (in_parens)
307 pp_cxx_left_paren (this);
308 c_pretty_printer::constant (t);
309 if (in_parens)
310 pp_cxx_right_paren (this);
312 break;
314 case INTEGER_CST:
315 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
317 pp_string (this, "nullptr");
318 break;
320 /* fall through. */
322 default:
323 c_pretty_printer::constant (t);
324 break;
328 /* id-expression:
329 unqualified-id
330 qualified-id */
332 void
333 cxx_pretty_printer::id_expression (tree t)
335 if (TREE_CODE (t) == OVERLOAD)
336 t = OVL_FIRST (t);
337 if (DECL_P (t) && DECL_CONTEXT (t))
338 pp_cxx_qualified_id (this, t);
339 else
340 pp_cxx_unqualified_id (this, t);
343 /* user-defined literal:
344 literal ud-suffix */
346 void
347 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
349 pp->constant (USERDEF_LITERAL_VALUE (t));
350 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
354 /* primary-expression:
355 literal
356 this
357 :: identifier
358 :: operator-function-id
359 :: qualifier-id
360 ( expression )
361 id-expression
363 GNU Extensions:
364 __builtin_va_arg ( assignment-expression , type-id )
365 __builtin_offsetof ( type-id, offsetof-expression )
366 __builtin_addressof ( expression )
368 __has_nothrow_assign ( type-id )
369 __has_nothrow_constructor ( type-id )
370 __has_nothrow_copy ( type-id )
371 __has_trivial_assign ( type-id )
372 __has_trivial_constructor ( type-id )
373 __has_trivial_copy ( type-id )
374 __has_unique_object_representations ( type-id )
375 __has_trivial_destructor ( type-id )
376 __has_virtual_destructor ( type-id )
377 __is_abstract ( type-id )
378 __is_base_of ( type-id , type-id )
379 __is_class ( type-id )
380 __is_empty ( type-id )
381 __is_enum ( type-id )
382 __is_literal_type ( type-id )
383 __is_pod ( type-id )
384 __is_polymorphic ( type-id )
385 __is_std_layout ( type-id )
386 __is_trivial ( type-id )
387 __is_union ( type-id ) */
389 void
390 cxx_pretty_printer::primary_expression (tree t)
392 switch (TREE_CODE (t))
394 case VOID_CST:
395 case INTEGER_CST:
396 case REAL_CST:
397 case COMPLEX_CST:
398 case STRING_CST:
399 constant (t);
400 break;
402 case USERDEF_LITERAL:
403 pp_cxx_userdef_literal (this, t);
404 break;
406 case BASELINK:
407 t = BASELINK_FUNCTIONS (t);
408 /* FALLTHRU */
409 case VAR_DECL:
410 case PARM_DECL:
411 case FIELD_DECL:
412 case FUNCTION_DECL:
413 case OVERLOAD:
414 case CONST_DECL:
415 case TEMPLATE_DECL:
416 id_expression (t);
417 break;
419 case RESULT_DECL:
420 case TEMPLATE_TYPE_PARM:
421 case TEMPLATE_TEMPLATE_PARM:
422 case TEMPLATE_PARM_INDEX:
423 pp_cxx_unqualified_id (this, t);
424 break;
426 case STMT_EXPR:
427 pp_cxx_left_paren (this);
428 statement (STMT_EXPR_STMT (t));
429 pp_cxx_right_paren (this);
430 break;
432 case TRAIT_EXPR:
433 pp_cxx_trait_expression (this, t);
434 break;
436 case VA_ARG_EXPR:
437 pp_cxx_va_arg_expression (this, t);
438 break;
440 case OFFSETOF_EXPR:
441 pp_cxx_offsetof_expression (this, t);
442 break;
444 case ADDRESSOF_EXPR:
445 pp_cxx_addressof_expression (this, t);
446 break;
448 case REQUIRES_EXPR:
449 pp_cxx_requires_expr (this, t);
450 break;
452 default:
453 c_pretty_printer::primary_expression (t);
454 break;
458 /* postfix-expression:
459 primary-expression
460 postfix-expression [ expression ]
461 postfix-expression ( expression-list(opt) )
462 simple-type-specifier ( expression-list(opt) )
463 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
464 typename ::(opt) nested-name-specifier template(opt)
465 template-id ( expression-list(opt) )
466 postfix-expression . template(opt) ::(opt) id-expression
467 postfix-expression -> template(opt) ::(opt) id-expression
468 postfix-expression . pseudo-destructor-name
469 postfix-expression -> pseudo-destructor-name
470 postfix-expression ++
471 postfix-expression --
472 dynamic_cast < type-id > ( expression )
473 static_cast < type-id > ( expression )
474 reinterpret_cast < type-id > ( expression )
475 const_cast < type-id > ( expression )
476 typeid ( expression )
477 typeid ( type-id ) */
479 void
480 cxx_pretty_printer::postfix_expression (tree t)
482 enum tree_code code = TREE_CODE (t);
484 switch (code)
486 case AGGR_INIT_EXPR:
487 case CALL_EXPR:
489 tree fun = cp_get_callee (t);
490 tree saved_scope = enclosing_scope;
491 bool skipfirst = false;
492 tree arg;
494 if (TREE_CODE (fun) == ADDR_EXPR)
495 fun = TREE_OPERAND (fun, 0);
497 /* In templates, where there is no way to tell whether a given
498 call uses an actual member function. So the parser builds
499 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
500 instantiation time. */
501 if (TREE_CODE (fun) != FUNCTION_DECL)
503 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
505 tree object = (code == AGGR_INIT_EXPR
506 ? (AGGR_INIT_VIA_CTOR_P (t)
507 ? AGGR_INIT_EXPR_SLOT (t)
508 : AGGR_INIT_EXPR_ARG (t, 0))
509 : CALL_EXPR_ARG (t, 0));
511 while (TREE_CODE (object) == NOP_EXPR)
512 object = TREE_OPERAND (object, 0);
514 if (TREE_CODE (object) == ADDR_EXPR)
515 object = TREE_OPERAND (object, 0);
517 if (!TYPE_PTR_P (TREE_TYPE (object)))
519 postfix_expression (object);
520 pp_cxx_dot (this);
522 else
524 postfix_expression (object);
525 pp_cxx_arrow (this);
527 skipfirst = true;
528 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
531 postfix_expression (fun);
532 enclosing_scope = saved_scope;
533 pp_cxx_left_paren (this);
534 if (code == AGGR_INIT_EXPR)
536 aggr_init_expr_arg_iterator iter;
537 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
539 if (skipfirst)
540 skipfirst = false;
541 else
543 expression (arg);
544 if (more_aggr_init_expr_args_p (&iter))
545 pp_cxx_separate_with (this, ',');
549 else
551 call_expr_arg_iterator iter;
552 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
554 if (skipfirst)
555 skipfirst = false;
556 else
558 expression (arg);
559 if (more_call_expr_args_p (&iter))
560 pp_cxx_separate_with (this, ',');
564 pp_cxx_right_paren (this);
566 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
568 pp_cxx_separate_with (this, ',');
569 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
571 break;
573 case BASELINK:
574 case VAR_DECL:
575 case PARM_DECL:
576 case FIELD_DECL:
577 case FUNCTION_DECL:
578 case OVERLOAD:
579 case CONST_DECL:
580 case TEMPLATE_DECL:
581 case RESULT_DECL:
582 primary_expression (t);
583 break;
585 case DYNAMIC_CAST_EXPR:
586 case STATIC_CAST_EXPR:
587 case REINTERPRET_CAST_EXPR:
588 case CONST_CAST_EXPR:
589 if (code == DYNAMIC_CAST_EXPR)
590 pp_cxx_ws_string (this, "dynamic_cast");
591 else if (code == STATIC_CAST_EXPR)
592 pp_cxx_ws_string (this, "static_cast");
593 else if (code == REINTERPRET_CAST_EXPR)
594 pp_cxx_ws_string (this, "reinterpret_cast");
595 else
596 pp_cxx_ws_string (this, "const_cast");
597 pp_cxx_begin_template_argument_list (this);
598 type_id (TREE_TYPE (t));
599 pp_cxx_end_template_argument_list (this);
600 pp_left_paren (this);
601 expression (TREE_OPERAND (t, 0));
602 pp_right_paren (this);
603 break;
605 case EMPTY_CLASS_EXPR:
606 type_id (TREE_TYPE (t));
607 pp_left_paren (this);
608 pp_right_paren (this);
609 break;
611 case TYPEID_EXPR:
612 pp_cxx_typeid_expression (this, t);
613 break;
615 case PSEUDO_DTOR_EXPR:
616 postfix_expression (TREE_OPERAND (t, 0));
617 pp_cxx_dot (this);
618 if (TREE_OPERAND (t, 1))
620 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
621 pp_cxx_colon_colon (this);
623 pp_complement (this);
624 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
625 break;
627 case ARROW_EXPR:
628 postfix_expression (TREE_OPERAND (t, 0));
629 pp_cxx_arrow (this);
630 break;
632 default:
633 c_pretty_printer::postfix_expression (t);
634 break;
638 /* new-expression:
639 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
640 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
642 new-placement:
643 ( expression-list )
645 new-type-id:
646 type-specifier-seq new-declarator(opt)
648 new-declarator:
649 ptr-operator new-declarator(opt)
650 direct-new-declarator
652 direct-new-declarator
653 [ expression ]
654 direct-new-declarator [ constant-expression ]
656 new-initializer:
657 ( expression-list(opt) ) */
659 static void
660 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
662 enum tree_code code = TREE_CODE (t);
663 tree type = TREE_OPERAND (t, 1);
664 tree init = TREE_OPERAND (t, 2);
665 switch (code)
667 case NEW_EXPR:
668 case VEC_NEW_EXPR:
669 if (NEW_EXPR_USE_GLOBAL (t))
670 pp_cxx_colon_colon (pp);
671 pp_cxx_ws_string (pp, "new");
672 if (TREE_OPERAND (t, 0))
674 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
675 pp_space (pp);
677 if (TREE_CODE (type) == ARRAY_REF)
678 type = build_cplus_array_type
679 (TREE_OPERAND (type, 0),
680 build_index_type (fold_build2_loc (input_location,
681 MINUS_EXPR, integer_type_node,
682 TREE_OPERAND (type, 1),
683 integer_one_node)));
684 pp->type_id (type);
685 if (init)
687 pp_left_paren (pp);
688 if (TREE_CODE (init) == TREE_LIST)
689 pp_c_expression_list (pp, init);
690 else if (init == void_node)
691 ; /* OK, empty initializer list. */
692 else
693 pp->expression (init);
694 pp_right_paren (pp);
696 break;
698 default:
699 pp_unsupported_tree (pp, t);
703 /* delete-expression:
704 ::(opt) delete cast-expression
705 ::(opt) delete [ ] cast-expression */
707 static void
708 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
710 enum tree_code code = TREE_CODE (t);
711 switch (code)
713 case DELETE_EXPR:
714 case VEC_DELETE_EXPR:
715 if (DELETE_EXPR_USE_GLOBAL (t))
716 pp_cxx_colon_colon (pp);
717 pp_cxx_ws_string (pp, "delete");
718 pp_space (pp);
719 if (code == VEC_DELETE_EXPR
720 || DELETE_EXPR_USE_VEC (t))
722 pp_left_bracket (pp);
723 pp_right_bracket (pp);
724 pp_space (pp);
726 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
727 break;
729 default:
730 pp_unsupported_tree (pp, t);
734 /* unary-expression:
735 postfix-expression
736 ++ cast-expression
737 -- cast-expression
738 unary-operator cast-expression
739 sizeof unary-expression
740 sizeof ( type-id )
741 sizeof ... ( identifier )
742 new-expression
743 delete-expression
745 unary-operator: one of
746 * & + - !
748 GNU extensions:
749 __alignof__ unary-expression
750 __alignof__ ( type-id ) */
752 void
753 cxx_pretty_printer::unary_expression (tree t)
755 enum tree_code code = TREE_CODE (t);
756 switch (code)
758 case NEW_EXPR:
759 case VEC_NEW_EXPR:
760 pp_cxx_new_expression (this, t);
761 break;
763 case DELETE_EXPR:
764 case VEC_DELETE_EXPR:
765 pp_cxx_delete_expression (this, t);
766 break;
768 case SIZEOF_EXPR:
769 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
771 pp_cxx_ws_string (this, "sizeof");
772 pp_cxx_ws_string (this, "...");
773 pp_cxx_whitespace (this);
774 pp_cxx_left_paren (this);
775 if (TYPE_P (TREE_OPERAND (t, 0)))
776 type_id (TREE_OPERAND (t, 0));
777 else
778 unary_expression (TREE_OPERAND (t, 0));
779 pp_cxx_right_paren (this);
780 break;
782 /* Fall through */
784 case ALIGNOF_EXPR:
785 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
786 pp_cxx_whitespace (this);
787 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
789 pp_cxx_left_paren (this);
790 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
791 pp_cxx_right_paren (this);
793 else if (TYPE_P (TREE_OPERAND (t, 0)))
795 pp_cxx_left_paren (this);
796 type_id (TREE_OPERAND (t, 0));
797 pp_cxx_right_paren (this);
799 else
800 unary_expression (TREE_OPERAND (t, 0));
801 break;
803 case AT_ENCODE_EXPR:
804 pp_cxx_ws_string (this, "@encode");
805 pp_cxx_whitespace (this);
806 pp_cxx_left_paren (this);
807 type_id (TREE_OPERAND (t, 0));
808 pp_cxx_right_paren (this);
809 break;
811 case NOEXCEPT_EXPR:
812 pp_cxx_ws_string (this, "noexcept");
813 pp_cxx_whitespace (this);
814 pp_cxx_left_paren (this);
815 expression (TREE_OPERAND (t, 0));
816 pp_cxx_right_paren (this);
817 break;
819 case UNARY_PLUS_EXPR:
820 pp_plus (this);
821 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
822 break;
824 default:
825 c_pretty_printer::unary_expression (t);
826 break;
830 /* cast-expression:
831 unary-expression
832 ( type-id ) cast-expression */
834 static void
835 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
837 switch (TREE_CODE (t))
839 case CAST_EXPR:
840 case IMPLICIT_CONV_EXPR:
841 pp->type_id (TREE_TYPE (t));
842 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
843 break;
845 default:
846 pp_c_cast_expression (pp, t);
847 break;
851 /* pm-expression:
852 cast-expression
853 pm-expression .* cast-expression
854 pm-expression ->* cast-expression */
856 static void
857 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
859 switch (TREE_CODE (t))
861 /* Handle unfortunate OFFSET_REF overloading here. */
862 case OFFSET_REF:
863 if (TYPE_P (TREE_OPERAND (t, 0)))
865 pp_cxx_qualified_id (pp, t);
866 break;
868 /* Fall through. */
869 case MEMBER_REF:
870 case DOTSTAR_EXPR:
871 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
872 if (TREE_CODE (t) == MEMBER_REF)
873 pp_cxx_arrow (pp);
874 else
875 pp_cxx_dot (pp);
876 pp_star(pp);
877 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
878 break;
881 default:
882 pp_cxx_cast_expression (pp, t);
883 break;
887 /* multiplicative-expression:
888 pm-expression
889 multiplicative-expression * pm-expression
890 multiplicative-expression / pm-expression
891 multiplicative-expression % pm-expression */
893 void
894 cxx_pretty_printer::multiplicative_expression (tree e)
896 enum tree_code code = TREE_CODE (e);
897 switch (code)
899 case MULT_EXPR:
900 case TRUNC_DIV_EXPR:
901 case TRUNC_MOD_EXPR:
902 case EXACT_DIV_EXPR:
903 case RDIV_EXPR:
904 multiplicative_expression (TREE_OPERAND (e, 0));
905 pp_space (this);
906 if (code == MULT_EXPR)
907 pp_star (this);
908 else if (code != TRUNC_MOD_EXPR)
909 pp_slash (this);
910 else
911 pp_modulo (this);
912 pp_space (this);
913 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
914 break;
916 default:
917 pp_cxx_pm_expression (this, e);
918 break;
922 /* conditional-expression:
923 logical-or-expression
924 logical-or-expression ? expression : assignment-expression */
926 void
927 cxx_pretty_printer::conditional_expression (tree e)
929 if (TREE_CODE (e) == COND_EXPR)
931 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
932 pp_space (this);
933 pp_question (this);
934 pp_space (this);
935 expression (TREE_OPERAND (e, 1));
936 pp_space (this);
937 assignment_expression (TREE_OPERAND (e, 2));
939 else
940 pp_c_logical_or_expression (this, e);
943 /* Pretty-print a compound assignment operator token as indicated by T. */
945 static void
946 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
948 const char *op;
950 switch (TREE_CODE (t))
952 case NOP_EXPR:
953 op = "=";
954 break;
956 case PLUS_EXPR:
957 op = "+=";
958 break;
960 case MINUS_EXPR:
961 op = "-=";
962 break;
964 case TRUNC_DIV_EXPR:
965 op = "/=";
966 break;
968 case TRUNC_MOD_EXPR:
969 op = "%=";
970 break;
972 default:
973 op = get_tree_code_name (TREE_CODE (t));
974 break;
977 pp_cxx_ws_string (pp, op);
981 /* assignment-expression:
982 conditional-expression
983 logical-or-expression assignment-operator assignment-expression
984 throw-expression
986 throw-expression:
987 throw assignment-expression(opt)
989 assignment-operator: one of
990 = *= /= %= += -= >>= <<= &= ^= |= */
992 void
993 cxx_pretty_printer::assignment_expression (tree e)
995 switch (TREE_CODE (e))
997 case MODIFY_EXPR:
998 case INIT_EXPR:
999 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1000 pp_space (this);
1001 pp_equal (this);
1002 pp_space (this);
1003 assignment_expression (TREE_OPERAND (e, 1));
1004 break;
1006 case THROW_EXPR:
1007 pp_cxx_ws_string (this, "throw");
1008 if (TREE_OPERAND (e, 0))
1009 assignment_expression (TREE_OPERAND (e, 0));
1010 break;
1012 case MODOP_EXPR:
1013 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1014 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1015 assignment_expression (TREE_OPERAND (e, 2));
1016 break;
1018 default:
1019 conditional_expression (e);
1020 break;
1024 void
1025 cxx_pretty_printer::expression (tree t)
1027 switch (TREE_CODE (t))
1029 case STRING_CST:
1030 case VOID_CST:
1031 case INTEGER_CST:
1032 case REAL_CST:
1033 case COMPLEX_CST:
1034 constant (t);
1035 break;
1037 case USERDEF_LITERAL:
1038 pp_cxx_userdef_literal (this, t);
1039 break;
1041 case RESULT_DECL:
1042 pp_cxx_unqualified_id (this, t);
1043 break;
1045 #if 0
1046 case OFFSET_REF:
1047 #endif
1048 case SCOPE_REF:
1049 case PTRMEM_CST:
1050 pp_cxx_qualified_id (this, t);
1051 break;
1053 case OVERLOAD:
1054 t = OVL_FIRST (t);
1055 /* FALLTHRU */
1056 case VAR_DECL:
1057 case PARM_DECL:
1058 case FIELD_DECL:
1059 case CONST_DECL:
1060 case FUNCTION_DECL:
1061 case BASELINK:
1062 case TEMPLATE_DECL:
1063 case TEMPLATE_TYPE_PARM:
1064 case TEMPLATE_PARM_INDEX:
1065 case TEMPLATE_TEMPLATE_PARM:
1066 case STMT_EXPR:
1067 case REQUIRES_EXPR:
1068 primary_expression (t);
1069 break;
1071 case CALL_EXPR:
1072 case DYNAMIC_CAST_EXPR:
1073 case STATIC_CAST_EXPR:
1074 case REINTERPRET_CAST_EXPR:
1075 case CONST_CAST_EXPR:
1076 #if 0
1077 case MEMBER_REF:
1078 #endif
1079 case EMPTY_CLASS_EXPR:
1080 case TYPEID_EXPR:
1081 case PSEUDO_DTOR_EXPR:
1082 case AGGR_INIT_EXPR:
1083 case ARROW_EXPR:
1084 postfix_expression (t);
1085 break;
1087 case NEW_EXPR:
1088 case VEC_NEW_EXPR:
1089 pp_cxx_new_expression (this, t);
1090 break;
1092 case DELETE_EXPR:
1093 case VEC_DELETE_EXPR:
1094 pp_cxx_delete_expression (this, t);
1095 break;
1097 case SIZEOF_EXPR:
1098 case ALIGNOF_EXPR:
1099 case NOEXCEPT_EXPR:
1100 case UNARY_PLUS_EXPR:
1101 unary_expression (t);
1102 break;
1104 case CAST_EXPR:
1105 case IMPLICIT_CONV_EXPR:
1106 pp_cxx_cast_expression (this, t);
1107 break;
1109 case OFFSET_REF:
1110 case MEMBER_REF:
1111 case DOTSTAR_EXPR:
1112 pp_cxx_pm_expression (this, t);
1113 break;
1115 case MULT_EXPR:
1116 case TRUNC_DIV_EXPR:
1117 case TRUNC_MOD_EXPR:
1118 case EXACT_DIV_EXPR:
1119 case RDIV_EXPR:
1120 multiplicative_expression (t);
1121 break;
1123 case COND_EXPR:
1124 conditional_expression (t);
1125 break;
1127 case MODIFY_EXPR:
1128 case INIT_EXPR:
1129 case THROW_EXPR:
1130 case MODOP_EXPR:
1131 assignment_expression (t);
1132 break;
1134 case NON_DEPENDENT_EXPR:
1135 case MUST_NOT_THROW_EXPR:
1136 expression (TREE_OPERAND (t, 0));
1137 break;
1139 case EXPR_PACK_EXPANSION:
1140 expression (PACK_EXPANSION_PATTERN (t));
1141 pp_cxx_ws_string (this, "...");
1142 break;
1144 case UNARY_LEFT_FOLD_EXPR:
1145 pp_cxx_unary_left_fold_expression (this, t);
1146 break;
1148 case UNARY_RIGHT_FOLD_EXPR:
1149 pp_cxx_unary_right_fold_expression (this, t);
1150 break;
1152 case BINARY_LEFT_FOLD_EXPR:
1153 case BINARY_RIGHT_FOLD_EXPR:
1154 pp_cxx_binary_fold_expression (this, t);
1155 break;
1157 case TEMPLATE_ID_EXPR:
1158 pp_cxx_template_id (this, t);
1159 break;
1161 case NONTYPE_ARGUMENT_PACK:
1163 tree args = ARGUMENT_PACK_ARGS (t);
1164 int i, len = TREE_VEC_LENGTH (args);
1165 for (i = 0; i < len; ++i)
1167 if (i > 0)
1168 pp_cxx_separate_with (this, ',');
1169 expression (TREE_VEC_ELT (args, i));
1172 break;
1174 case LAMBDA_EXPR:
1175 pp_cxx_ws_string (this, "<lambda>");
1176 break;
1178 case TRAIT_EXPR:
1179 pp_cxx_trait_expression (this, t);
1180 break;
1182 case PRED_CONSTR:
1183 case CHECK_CONSTR:
1184 case EXPR_CONSTR:
1185 case TYPE_CONSTR:
1186 case ICONV_CONSTR:
1187 case DEDUCT_CONSTR:
1188 case EXCEPT_CONSTR:
1189 case PARM_CONSTR:
1190 case CONJ_CONSTR:
1191 case DISJ_CONSTR:
1192 pp_cxx_constraint (this, t);
1193 break;
1195 case PAREN_EXPR:
1196 pp_cxx_left_paren (this);
1197 expression (TREE_OPERAND (t, 0));
1198 pp_cxx_right_paren (this);
1199 break;
1201 default:
1202 c_pretty_printer::expression (t);
1203 break;
1208 /* Declarations. */
1210 /* function-specifier:
1211 inline
1212 virtual
1213 explicit */
1215 void
1216 cxx_pretty_printer::function_specifier (tree t)
1218 switch (TREE_CODE (t))
1220 case FUNCTION_DECL:
1221 if (DECL_VIRTUAL_P (t))
1222 pp_cxx_ws_string (this, "virtual");
1223 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1224 pp_cxx_ws_string (this, "explicit");
1225 else
1226 c_pretty_printer::function_specifier (t);
1228 default:
1229 break;
1233 /* decl-specifier-seq:
1234 decl-specifier-seq(opt) decl-specifier
1236 decl-specifier:
1237 storage-class-specifier
1238 type-specifier
1239 function-specifier
1240 friend
1241 typedef */
1243 void
1244 cxx_pretty_printer::declaration_specifiers (tree t)
1246 switch (TREE_CODE (t))
1248 case VAR_DECL:
1249 case PARM_DECL:
1250 case CONST_DECL:
1251 case FIELD_DECL:
1252 storage_class_specifier (t);
1253 declaration_specifiers (TREE_TYPE (t));
1254 break;
1256 case TYPE_DECL:
1257 pp_cxx_ws_string (this, "typedef");
1258 declaration_specifiers (TREE_TYPE (t));
1259 break;
1261 case FUNCTION_DECL:
1262 /* Constructors don't have return types. And conversion functions
1263 do not have a type-specifier in their return types. */
1264 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1265 function_specifier (t);
1266 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1267 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1268 else
1269 c_pretty_printer::declaration_specifiers (t);
1270 break;
1271 default:
1272 c_pretty_printer::declaration_specifiers (t);
1273 break;
1277 /* simple-type-specifier:
1278 ::(opt) nested-name-specifier(opt) type-name
1279 ::(opt) nested-name-specifier(opt) template(opt) template-id
1280 char
1281 wchar_t
1282 bool
1283 short
1285 long
1286 signed
1287 unsigned
1288 float
1289 double
1290 void */
1292 void
1293 cxx_pretty_printer::simple_type_specifier (tree t)
1295 switch (TREE_CODE (t))
1297 case RECORD_TYPE:
1298 case UNION_TYPE:
1299 case ENUMERAL_TYPE:
1300 pp_cxx_qualified_id (this, t);
1301 break;
1303 case TEMPLATE_TYPE_PARM:
1304 case TEMPLATE_TEMPLATE_PARM:
1305 case TEMPLATE_PARM_INDEX:
1306 case BOUND_TEMPLATE_TEMPLATE_PARM:
1307 pp_cxx_unqualified_id (this, t);
1308 break;
1310 case TYPENAME_TYPE:
1311 pp_cxx_ws_string (this, "typename");
1312 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1313 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1314 break;
1316 default:
1317 c_pretty_printer::simple_type_specifier (t);
1318 break;
1322 /* type-specifier-seq:
1323 type-specifier type-specifier-seq(opt)
1325 type-specifier:
1326 simple-type-specifier
1327 class-specifier
1328 enum-specifier
1329 elaborated-type-specifier
1330 cv-qualifier */
1332 static void
1333 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1335 switch (TREE_CODE (t))
1337 case TEMPLATE_DECL:
1338 case TEMPLATE_TYPE_PARM:
1339 case TEMPLATE_TEMPLATE_PARM:
1340 case TYPE_DECL:
1341 case BOUND_TEMPLATE_TEMPLATE_PARM:
1342 pp_cxx_cv_qualifier_seq (pp, t);
1343 pp->simple_type_specifier (t);
1344 break;
1346 case METHOD_TYPE:
1347 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1348 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1349 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1350 break;
1352 case DECLTYPE_TYPE:
1353 pp_cxx_ws_string (pp, "decltype");
1354 pp_cxx_left_paren (pp);
1355 pp->expression (DECLTYPE_TYPE_EXPR (t));
1356 pp_cxx_right_paren (pp);
1357 break;
1359 case RECORD_TYPE:
1360 if (TYPE_PTRMEMFUNC_P (t))
1362 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1363 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1364 pp_cxx_whitespace (pp);
1365 pp_cxx_ptr_operator (pp, t);
1366 break;
1368 /* fall through */
1370 default:
1371 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1372 pp_c_specifier_qualifier_list (pp, t);
1376 /* ptr-operator:
1377 * cv-qualifier-seq(opt)
1379 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1381 static void
1382 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1384 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1385 t = TREE_TYPE (t);
1386 switch (TREE_CODE (t))
1388 case REFERENCE_TYPE:
1389 case POINTER_TYPE:
1390 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1391 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1392 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1393 if (TYPE_PTR_P (t))
1395 pp_star (pp);
1396 pp_cxx_cv_qualifier_seq (pp, t);
1398 else
1399 pp_ampersand (pp);
1400 break;
1402 case RECORD_TYPE:
1403 if (TYPE_PTRMEMFUNC_P (t))
1405 pp_cxx_left_paren (pp);
1406 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1407 pp_star (pp);
1408 break;
1410 /* FALLTHRU */
1411 case OFFSET_TYPE:
1412 if (TYPE_PTRMEM_P (t))
1414 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1415 pp_cxx_left_paren (pp);
1416 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1417 pp_star (pp);
1418 pp_cxx_cv_qualifier_seq (pp, t);
1419 break;
1421 /* fall through. */
1423 default:
1424 pp_unsupported_tree (pp, t);
1425 break;
1429 static inline tree
1430 pp_cxx_implicit_parameter_type (tree mf)
1432 return class_of_this_parm (TREE_TYPE (mf));
1436 parameter-declaration:
1437 decl-specifier-seq declarator
1438 decl-specifier-seq declarator = assignment-expression
1439 decl-specifier-seq abstract-declarator(opt)
1440 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1442 static inline void
1443 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1445 pp->declaration_specifiers (t);
1446 if (TYPE_P (t))
1447 pp->abstract_declarator (t);
1448 else
1449 pp->declarator (t);
1452 /* parameter-declaration-clause:
1453 parameter-declaration-list(opt) ...(opt)
1454 parameter-declaration-list , ...
1456 parameter-declaration-list:
1457 parameter-declaration
1458 parameter-declaration-list , parameter-declaration */
1460 static void
1461 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1463 tree args;
1464 tree types;
1465 bool abstract;
1467 // For a requires clause or the explicit printing of a parameter list
1468 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1469 // args and types are taken from the function decl T.
1470 if (TREE_CODE (t) == PARM_DECL)
1472 args = t;
1473 types = t;
1474 abstract = false;
1476 else
1478 bool type_p = TYPE_P (t);
1479 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1480 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1481 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1483 bool first = true;
1485 /* Skip artificial parameter for nonstatic member functions. */
1486 if (TREE_CODE (t) == METHOD_TYPE)
1487 types = TREE_CHAIN (types);
1489 pp_cxx_left_paren (pp);
1490 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1492 if (!first)
1493 pp_cxx_separate_with (pp, ',');
1494 first = false;
1495 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1496 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1498 pp_cxx_whitespace (pp);
1499 pp_equal (pp);
1500 pp_cxx_whitespace (pp);
1501 pp->assignment_expression (TREE_PURPOSE (types));
1504 pp_cxx_right_paren (pp);
1507 /* exception-specification:
1508 throw ( type-id-list(opt) )
1510 type-id-list
1511 type-id
1512 type-id-list , type-id */
1514 static void
1515 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1517 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1518 bool need_comma = false;
1520 if (ex_spec == NULL)
1521 return;
1522 if (TREE_PURPOSE (ex_spec))
1524 pp_cxx_ws_string (pp, "noexcept");
1525 pp_cxx_whitespace (pp);
1526 pp_cxx_left_paren (pp);
1527 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1528 pp_cxx_ws_string (pp, "<uninstantiated>");
1529 else
1530 pp->expression (TREE_PURPOSE (ex_spec));
1531 pp_cxx_right_paren (pp);
1532 return;
1534 pp_cxx_ws_string (pp, "throw");
1535 pp_cxx_left_paren (pp);
1536 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1538 tree type = TREE_VALUE (ex_spec);
1539 tree argpack = NULL_TREE;
1540 int i, len = 1;
1542 if (ARGUMENT_PACK_P (type))
1544 argpack = ARGUMENT_PACK_ARGS (type);
1545 len = TREE_VEC_LENGTH (argpack);
1548 for (i = 0; i < len; ++i)
1550 if (argpack)
1551 type = TREE_VEC_ELT (argpack, i);
1553 if (need_comma)
1554 pp_cxx_separate_with (pp, ',');
1555 else
1556 need_comma = true;
1558 pp->type_id (type);
1561 pp_cxx_right_paren (pp);
1564 /* direct-declarator:
1565 declarator-id
1566 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1567 exception-specification(opt)
1568 direct-declaration [ constant-expression(opt) ]
1569 ( declarator ) */
1571 void
1572 cxx_pretty_printer::direct_declarator (tree t)
1574 switch (TREE_CODE (t))
1576 case VAR_DECL:
1577 case PARM_DECL:
1578 case CONST_DECL:
1579 case FIELD_DECL:
1580 if (DECL_NAME (t))
1582 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1584 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1585 || template_parameter_pack_p (t))
1586 /* A function parameter pack or non-type template
1587 parameter pack. */
1588 pp_cxx_ws_string (this, "...");
1590 id_expression (DECL_NAME (t));
1592 abstract_declarator (TREE_TYPE (t));
1593 break;
1595 case FUNCTION_DECL:
1596 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1597 expression (t);
1598 pp_cxx_parameter_declaration_clause (this, t);
1600 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1602 padding = pp_before;
1603 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1606 pp_cxx_exception_specification (this, TREE_TYPE (t));
1607 break;
1609 case TYPENAME_TYPE:
1610 case TEMPLATE_DECL:
1611 case TEMPLATE_TYPE_PARM:
1612 case TEMPLATE_PARM_INDEX:
1613 case TEMPLATE_TEMPLATE_PARM:
1614 break;
1616 default:
1617 c_pretty_printer::direct_declarator (t);
1618 break;
1622 /* declarator:
1623 direct-declarator
1624 ptr-operator declarator */
1626 void
1627 cxx_pretty_printer::declarator (tree t)
1629 direct_declarator (t);
1631 // Print a requires clause.
1632 if (flag_concepts)
1633 if (tree ci = get_constraints (t))
1634 if (tree reqs = CI_DECLARATOR_REQS (ci))
1635 pp_cxx_requires_clause (this, reqs);
1638 /* ctor-initializer:
1639 : mem-initializer-list
1641 mem-initializer-list:
1642 mem-initializer
1643 mem-initializer , mem-initializer-list
1645 mem-initializer:
1646 mem-initializer-id ( expression-list(opt) )
1648 mem-initializer-id:
1649 ::(opt) nested-name-specifier(opt) class-name
1650 identifier */
1652 static void
1653 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1655 t = TREE_OPERAND (t, 0);
1656 pp_cxx_whitespace (pp);
1657 pp_colon (pp);
1658 pp_cxx_whitespace (pp);
1659 for (; t; t = TREE_CHAIN (t))
1661 tree purpose = TREE_PURPOSE (t);
1662 bool is_pack = PACK_EXPANSION_P (purpose);
1664 if (is_pack)
1665 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1666 else
1667 pp->primary_expression (purpose);
1668 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1669 if (is_pack)
1670 pp_cxx_ws_string (pp, "...");
1671 if (TREE_CHAIN (t))
1672 pp_cxx_separate_with (pp, ',');
1676 /* function-definition:
1677 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1678 decl-specifier-seq(opt) declarator function-try-block */
1680 static void
1681 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1683 tree saved_scope = pp->enclosing_scope;
1684 pp->declaration_specifiers (t);
1685 pp->declarator (t);
1686 pp_needs_newline (pp) = true;
1687 pp->enclosing_scope = DECL_CONTEXT (t);
1688 if (DECL_SAVED_TREE (t))
1689 pp->statement (DECL_SAVED_TREE (t));
1690 else
1691 pp_cxx_semicolon (pp);
1692 pp_newline_and_flush (pp);
1693 pp->enclosing_scope = saved_scope;
1696 /* abstract-declarator:
1697 ptr-operator abstract-declarator(opt)
1698 direct-abstract-declarator */
1700 void
1701 cxx_pretty_printer::abstract_declarator (tree t)
1703 if (TYPE_PTRMEM_P (t))
1704 pp_cxx_right_paren (this);
1705 else if (POINTER_TYPE_P (t))
1707 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1708 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1709 pp_cxx_right_paren (this);
1710 t = TREE_TYPE (t);
1712 direct_abstract_declarator (t);
1715 /* direct-abstract-declarator:
1716 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1717 cv-qualifier-seq(opt) exception-specification(opt)
1718 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1719 ( abstract-declarator ) */
1721 void
1722 cxx_pretty_printer::direct_abstract_declarator (tree t)
1724 switch (TREE_CODE (t))
1726 case REFERENCE_TYPE:
1727 abstract_declarator (t);
1728 break;
1730 case RECORD_TYPE:
1731 if (TYPE_PTRMEMFUNC_P (t))
1732 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1733 break;
1735 case METHOD_TYPE:
1736 case FUNCTION_TYPE:
1737 pp_cxx_parameter_declaration_clause (this, t);
1738 direct_abstract_declarator (TREE_TYPE (t));
1739 if (TREE_CODE (t) == METHOD_TYPE)
1741 padding = pp_before;
1742 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1744 pp_cxx_exception_specification (this, t);
1745 break;
1747 case TYPENAME_TYPE:
1748 case TEMPLATE_TYPE_PARM:
1749 case TEMPLATE_TEMPLATE_PARM:
1750 case BOUND_TEMPLATE_TEMPLATE_PARM:
1751 case UNBOUND_CLASS_TEMPLATE:
1752 break;
1754 default:
1755 c_pretty_printer::direct_abstract_declarator (t);
1756 break;
1760 /* type-id:
1761 type-specifier-seq abstract-declarator(opt) */
1763 void
1764 cxx_pretty_printer::type_id (tree t)
1766 pp_flags saved_flags = flags;
1767 flags |= pp_c_flag_abstract;
1769 switch (TREE_CODE (t))
1771 case TYPE_DECL:
1772 case UNION_TYPE:
1773 case RECORD_TYPE:
1774 case ENUMERAL_TYPE:
1775 case TYPENAME_TYPE:
1776 case BOUND_TEMPLATE_TEMPLATE_PARM:
1777 case UNBOUND_CLASS_TEMPLATE:
1778 case TEMPLATE_TEMPLATE_PARM:
1779 case TEMPLATE_TYPE_PARM:
1780 case TEMPLATE_PARM_INDEX:
1781 case TEMPLATE_DECL:
1782 case TYPEOF_TYPE:
1783 case UNDERLYING_TYPE:
1784 case DECLTYPE_TYPE:
1785 case TEMPLATE_ID_EXPR:
1786 pp_cxx_type_specifier_seq (this, t);
1787 break;
1789 case TYPE_PACK_EXPANSION:
1790 type_id (PACK_EXPANSION_PATTERN (t));
1791 pp_cxx_ws_string (this, "...");
1792 break;
1794 default:
1795 c_pretty_printer::type_id (t);
1796 break;
1799 flags = saved_flags;
1802 /* template-argument-list:
1803 template-argument ...(opt)
1804 template-argument-list, template-argument ...(opt)
1806 template-argument:
1807 assignment-expression
1808 type-id
1809 template-name */
1811 static void
1812 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1814 int i;
1815 bool need_comma = false;
1817 if (t == NULL)
1818 return;
1819 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1821 tree arg = TREE_VEC_ELT (t, i);
1822 tree argpack = NULL_TREE;
1823 int idx, len = 1;
1825 if (ARGUMENT_PACK_P (arg))
1827 argpack = ARGUMENT_PACK_ARGS (arg);
1828 len = TREE_VEC_LENGTH (argpack);
1831 for (idx = 0; idx < len; idx++)
1833 if (argpack)
1834 arg = TREE_VEC_ELT (argpack, idx);
1836 if (need_comma)
1837 pp_cxx_separate_with (pp, ',');
1838 else
1839 need_comma = true;
1841 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1842 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1843 pp->type_id (arg);
1844 else
1845 pp->expression (arg);
1851 static void
1852 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1854 t = DECL_EXPR_DECL (t);
1855 pp_cxx_type_specifier_seq (pp, t);
1856 if (TYPE_P (t))
1857 pp->abstract_declarator (t);
1858 else
1859 pp->declarator (t);
1862 /* Statements. */
1864 void
1865 cxx_pretty_printer::statement (tree t)
1867 switch (TREE_CODE (t))
1869 case CTOR_INITIALIZER:
1870 pp_cxx_ctor_initializer (this, t);
1871 break;
1873 case USING_STMT:
1874 pp_cxx_ws_string (this, "using");
1875 pp_cxx_ws_string (this, "namespace");
1876 if (DECL_CONTEXT (t))
1877 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1878 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1879 break;
1881 case USING_DECL:
1882 pp_cxx_ws_string (this, "using");
1883 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1884 pp_cxx_unqualified_id (this, DECL_NAME (t));
1885 break;
1887 case EH_SPEC_BLOCK:
1888 break;
1890 /* try-block:
1891 try compound-statement handler-seq */
1892 case TRY_BLOCK:
1893 pp_maybe_newline_and_indent (this, 0);
1894 pp_cxx_ws_string (this, "try");
1895 pp_newline_and_indent (this, 3);
1896 statement (TRY_STMTS (t));
1897 pp_newline_and_indent (this, -3);
1898 if (CLEANUP_P (t))
1900 else
1901 statement (TRY_HANDLERS (t));
1902 break;
1905 handler-seq:
1906 handler handler-seq(opt)
1908 handler:
1909 catch ( exception-declaration ) compound-statement
1911 exception-declaration:
1912 type-specifier-seq declarator
1913 type-specifier-seq abstract-declarator
1914 ... */
1915 case HANDLER:
1916 pp_cxx_ws_string (this, "catch");
1917 pp_cxx_left_paren (this);
1918 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1919 pp_cxx_right_paren (this);
1920 pp_indentation (this) += 3;
1921 pp_needs_newline (this) = true;
1922 statement (HANDLER_BODY (t));
1923 pp_indentation (this) -= 3;
1924 pp_needs_newline (this) = true;
1925 break;
1927 /* selection-statement:
1928 if ( expression ) statement
1929 if ( expression ) statement else statement */
1930 case IF_STMT:
1931 pp_cxx_ws_string (this, "if");
1932 pp_cxx_whitespace (this);
1933 pp_cxx_left_paren (this);
1934 expression (IF_COND (t));
1935 pp_cxx_right_paren (this);
1936 pp_newline_and_indent (this, 2);
1937 statement (THEN_CLAUSE (t));
1938 pp_newline_and_indent (this, -2);
1939 if (ELSE_CLAUSE (t))
1941 tree else_clause = ELSE_CLAUSE (t);
1942 pp_cxx_ws_string (this, "else");
1943 if (TREE_CODE (else_clause) == IF_STMT)
1944 pp_cxx_whitespace (this);
1945 else
1946 pp_newline_and_indent (this, 2);
1947 statement (else_clause);
1948 if (TREE_CODE (else_clause) != IF_STMT)
1949 pp_newline_and_indent (this, -2);
1951 break;
1953 case SWITCH_STMT:
1954 pp_cxx_ws_string (this, "switch");
1955 pp_space (this);
1956 pp_cxx_left_paren (this);
1957 expression (SWITCH_STMT_COND (t));
1958 pp_cxx_right_paren (this);
1959 pp_indentation (this) += 3;
1960 pp_needs_newline (this) = true;
1961 statement (SWITCH_STMT_BODY (t));
1962 pp_newline_and_indent (this, -3);
1963 break;
1965 /* iteration-statement:
1966 while ( expression ) statement
1967 do statement while ( expression ) ;
1968 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1969 for ( declaration expression(opt) ; expression(opt) ) statement */
1970 case WHILE_STMT:
1971 pp_cxx_ws_string (this, "while");
1972 pp_space (this);
1973 pp_cxx_left_paren (this);
1974 expression (WHILE_COND (t));
1975 pp_cxx_right_paren (this);
1976 pp_newline_and_indent (this, 3);
1977 statement (WHILE_BODY (t));
1978 pp_indentation (this) -= 3;
1979 pp_needs_newline (this) = true;
1980 break;
1982 case DO_STMT:
1983 pp_cxx_ws_string (this, "do");
1984 pp_newline_and_indent (this, 3);
1985 statement (DO_BODY (t));
1986 pp_newline_and_indent (this, -3);
1987 pp_cxx_ws_string (this, "while");
1988 pp_space (this);
1989 pp_cxx_left_paren (this);
1990 expression (DO_COND (t));
1991 pp_cxx_right_paren (this);
1992 pp_cxx_semicolon (this);
1993 pp_needs_newline (this) = true;
1994 break;
1996 case FOR_STMT:
1997 pp_cxx_ws_string (this, "for");
1998 pp_space (this);
1999 pp_cxx_left_paren (this);
2000 if (FOR_INIT_STMT (t))
2001 statement (FOR_INIT_STMT (t));
2002 else
2003 pp_cxx_semicolon (this);
2004 pp_needs_newline (this) = false;
2005 pp_cxx_whitespace (this);
2006 if (FOR_COND (t))
2007 expression (FOR_COND (t));
2008 pp_cxx_semicolon (this);
2009 pp_needs_newline (this) = false;
2010 pp_cxx_whitespace (this);
2011 if (FOR_EXPR (t))
2012 expression (FOR_EXPR (t));
2013 pp_cxx_right_paren (this);
2014 pp_newline_and_indent (this, 3);
2015 statement (FOR_BODY (t));
2016 pp_indentation (this) -= 3;
2017 pp_needs_newline (this) = true;
2018 break;
2020 case RANGE_FOR_STMT:
2021 pp_cxx_ws_string (this, "for");
2022 pp_space (this);
2023 pp_cxx_left_paren (this);
2024 statement (RANGE_FOR_DECL (t));
2025 pp_space (this);
2026 pp_needs_newline (this) = false;
2027 pp_colon (this);
2028 pp_space (this);
2029 statement (RANGE_FOR_EXPR (t));
2030 pp_cxx_right_paren (this);
2031 pp_newline_and_indent (this, 3);
2032 statement (FOR_BODY (t));
2033 pp_indentation (this) -= 3;
2034 pp_needs_newline (this) = true;
2035 break;
2037 /* jump-statement:
2038 goto identifier;
2039 continue ;
2040 return expression(opt) ; */
2041 case BREAK_STMT:
2042 case CONTINUE_STMT:
2043 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2044 pp_cxx_semicolon (this);
2045 pp_needs_newline (this) = true;
2046 break;
2048 /* expression-statement:
2049 expression(opt) ; */
2050 case EXPR_STMT:
2051 expression (EXPR_STMT_EXPR (t));
2052 pp_cxx_semicolon (this);
2053 pp_needs_newline (this) = true;
2054 break;
2056 case CLEANUP_STMT:
2057 pp_cxx_ws_string (this, "try");
2058 pp_newline_and_indent (this, 2);
2059 statement (CLEANUP_BODY (t));
2060 pp_newline_and_indent (this, -2);
2061 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2062 pp_newline_and_indent (this, 2);
2063 statement (CLEANUP_EXPR (t));
2064 pp_newline_and_indent (this, -2);
2065 break;
2067 case STATIC_ASSERT:
2068 declaration (t);
2069 break;
2071 default:
2072 c_pretty_printer::statement (t);
2073 break;
2077 /* original-namespace-definition:
2078 namespace identifier { namespace-body }
2080 As an edge case, we also handle unnamed namespace definition here. */
2082 static void
2083 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2085 pp_cxx_ws_string (pp, "namespace");
2086 if (DECL_CONTEXT (t))
2087 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2088 if (DECL_NAME (t))
2089 pp_cxx_unqualified_id (pp, t);
2090 pp_cxx_whitespace (pp);
2091 pp_cxx_left_brace (pp);
2092 /* We do not print the namespace-body. */
2093 pp_cxx_whitespace (pp);
2094 pp_cxx_right_brace (pp);
2097 /* namespace-alias:
2098 identifier
2100 namespace-alias-definition:
2101 namespace identifier = qualified-namespace-specifier ;
2103 qualified-namespace-specifier:
2104 ::(opt) nested-name-specifier(opt) namespace-name */
2106 static void
2107 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2109 pp_cxx_ws_string (pp, "namespace");
2110 if (DECL_CONTEXT (t))
2111 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2112 pp_cxx_unqualified_id (pp, t);
2113 pp_cxx_whitespace (pp);
2114 pp_equal (pp);
2115 pp_cxx_whitespace (pp);
2116 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2117 pp_cxx_nested_name_specifier (pp,
2118 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2119 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2120 pp_cxx_semicolon (pp);
2123 /* simple-declaration:
2124 decl-specifier-seq(opt) init-declarator-list(opt) */
2126 static void
2127 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2129 pp->declaration_specifiers (t);
2130 pp_cxx_init_declarator (pp, t);
2131 pp_cxx_semicolon (pp);
2132 pp_needs_newline (pp) = true;
2136 template-parameter-list:
2137 template-parameter
2138 template-parameter-list , template-parameter */
2140 static inline void
2141 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2143 const int n = TREE_VEC_LENGTH (t);
2144 int i;
2145 for (i = 0; i < n; ++i)
2147 if (i)
2148 pp_cxx_separate_with (pp, ',');
2149 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2153 /* template-parameter:
2154 type-parameter
2155 parameter-declaration
2157 type-parameter:
2158 class ...(opt) identifier(opt)
2159 class identifier(opt) = type-id
2160 typename identifier(opt)
2161 typename ...(opt) identifier(opt) = type-id
2162 template < template-parameter-list > class ...(opt) identifier(opt)
2163 template < template-parameter-list > class identifier(opt) = template-name */
2165 static void
2166 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2168 tree parameter = TREE_VALUE (t);
2169 switch (TREE_CODE (parameter))
2171 case TYPE_DECL:
2172 pp_cxx_ws_string (pp, "class");
2173 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2174 pp_cxx_ws_string (pp, "...");
2175 if (DECL_NAME (parameter))
2176 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2177 /* FIXME: Check if we should print also default argument. */
2178 break;
2180 case PARM_DECL:
2181 pp_cxx_parameter_declaration (pp, parameter);
2182 break;
2184 case TEMPLATE_DECL:
2185 break;
2187 default:
2188 pp_unsupported_tree (pp, t);
2189 break;
2193 /* Pretty-print a template parameter in the canonical form
2194 "template-parameter-<level>-<position in parameter list>". */
2196 void
2197 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2199 const enum tree_code code = TREE_CODE (parm);
2201 /* Brings type template parameters to the canonical forms. */
2202 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2203 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2204 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2206 pp_cxx_begin_template_argument_list (pp);
2207 pp->translate_string ("template-parameter-");
2208 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2209 pp_minus (pp);
2210 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2211 pp_cxx_end_template_argument_list (pp);
2214 /* Print a constrained-type-specifier. */
2216 void
2217 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2219 tree t, a;
2220 if (c == error_mark_node)
2222 pp_cxx_ws_string(pp, "<unsatisfied-constrained-placeholder>");
2223 return;
2225 placeholder_extract_concept_and_args (c, t, a);
2226 pp->id_expression (t);
2227 if (TREE_VEC_LENGTH (a) > 1)
2229 pp_cxx_begin_template_argument_list (pp);
2230 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2231 for (int i = TREE_VEC_LENGTH (a) - 1; i > 0; --i)
2232 TREE_VEC_ELT (args, i-1) = TREE_VEC_ELT (a, i);
2233 pp_cxx_template_argument_list (pp, args);
2234 ggc_free (args);
2235 pp_cxx_end_template_argument_list (pp);
2240 template-declaration:
2241 export(opt) template < template-parameter-list > declaration
2243 Concept extensions:
2245 template-declaration:
2246 export(opt) template < template-parameter-list >
2247 requires-clause(opt) declaration */
2249 static void
2250 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2252 tree tmpl = most_general_template (t);
2253 tree level;
2255 pp_maybe_newline_and_indent (pp, 0);
2256 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2258 pp_cxx_ws_string (pp, "template");
2259 pp_cxx_begin_template_argument_list (pp);
2260 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2261 pp_cxx_end_template_argument_list (pp);
2262 pp_newline_and_indent (pp, 3);
2265 if (flag_concepts)
2266 if (tree ci = get_constraints (t))
2267 if (tree reqs = CI_TEMPLATE_REQS (ci))
2269 pp_cxx_requires_clause (pp, reqs);
2270 pp_newline_and_indent (pp, 6);
2273 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2274 pp_cxx_function_definition (pp, t);
2275 else
2276 pp_cxx_simple_declaration (pp, t);
2279 static void
2280 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2282 pp_unsupported_tree (pp, t);
2285 static void
2286 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2288 pp_unsupported_tree (pp, t);
2292 declaration:
2293 block-declaration
2294 function-definition
2295 template-declaration
2296 explicit-instantiation
2297 explicit-specialization
2298 linkage-specification
2299 namespace-definition
2301 block-declaration:
2302 simple-declaration
2303 asm-definition
2304 namespace-alias-definition
2305 using-declaration
2306 using-directive
2307 static_assert-declaration */
2308 void
2309 cxx_pretty_printer::declaration (tree t)
2311 if (TREE_CODE (t) == STATIC_ASSERT)
2313 pp_cxx_ws_string (this, "static_assert");
2314 pp_cxx_left_paren (this);
2315 expression (STATIC_ASSERT_CONDITION (t));
2316 pp_cxx_separate_with (this, ',');
2317 expression (STATIC_ASSERT_MESSAGE (t));
2318 pp_cxx_right_paren (this);
2320 else if (!DECL_LANG_SPECIFIC (t))
2321 pp_cxx_simple_declaration (this, t);
2322 else if (DECL_USE_TEMPLATE (t))
2323 switch (DECL_USE_TEMPLATE (t))
2325 case 1:
2326 pp_cxx_template_declaration (this, t);
2327 break;
2329 case 2:
2330 pp_cxx_explicit_specialization (this, t);
2331 break;
2333 case 3:
2334 pp_cxx_explicit_instantiation (this, t);
2335 break;
2337 default:
2338 break;
2340 else switch (TREE_CODE (t))
2342 case VAR_DECL:
2343 case TYPE_DECL:
2344 pp_cxx_simple_declaration (this, t);
2345 break;
2347 case FUNCTION_DECL:
2348 if (DECL_SAVED_TREE (t))
2349 pp_cxx_function_definition (this, t);
2350 else
2351 pp_cxx_simple_declaration (this, t);
2352 break;
2354 case NAMESPACE_DECL:
2355 if (DECL_NAMESPACE_ALIAS (t))
2356 pp_cxx_namespace_alias_definition (this, t);
2357 else
2358 pp_cxx_original_namespace_definition (this, t);
2359 break;
2361 default:
2362 pp_unsupported_tree (this, t);
2363 break;
2367 static void
2368 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2370 t = TREE_OPERAND (t, 0);
2371 pp_cxx_ws_string (pp, "typeid");
2372 pp_cxx_left_paren (pp);
2373 if (TYPE_P (t))
2374 pp->type_id (t);
2375 else
2376 pp->expression (t);
2377 pp_cxx_right_paren (pp);
2380 void
2381 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2383 pp_cxx_ws_string (pp, "va_arg");
2384 pp_cxx_left_paren (pp);
2385 pp->assignment_expression (TREE_OPERAND (t, 0));
2386 pp_cxx_separate_with (pp, ',');
2387 pp->type_id (TREE_TYPE (t));
2388 pp_cxx_right_paren (pp);
2391 static bool
2392 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2394 switch (TREE_CODE (t))
2396 case ARROW_EXPR:
2397 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2398 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2400 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2401 pp_cxx_separate_with (pp, ',');
2402 return true;
2404 return false;
2405 case COMPONENT_REF:
2406 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2407 return false;
2408 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2409 pp_cxx_dot (pp);
2410 pp->expression (TREE_OPERAND (t, 1));
2411 return true;
2412 case ARRAY_REF:
2413 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2414 return false;
2415 pp_left_bracket (pp);
2416 pp->expression (TREE_OPERAND (t, 1));
2417 pp_right_bracket (pp);
2418 return true;
2419 default:
2420 return false;
2424 void
2425 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2427 pp_cxx_ws_string (pp, "offsetof");
2428 pp_cxx_left_paren (pp);
2429 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2430 pp->expression (TREE_OPERAND (t, 0));
2431 pp_cxx_right_paren (pp);
2434 void
2435 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2437 pp_cxx_ws_string (pp, "__builtin_addressof");
2438 pp_cxx_left_paren (pp);
2439 pp->expression (TREE_OPERAND (t, 0));
2440 pp_cxx_right_paren (pp);
2443 static char const*
2444 get_fold_operator (tree t)
2446 int op = int_cst_value (FOLD_EXPR_OP (t));
2447 if (FOLD_EXPR_MODIFY_P (t))
2449 switch (op)
2451 case NOP_EXPR: return "=";
2452 case PLUS_EXPR: return "+=";
2453 case MINUS_EXPR: return "-=";
2454 case MULT_EXPR: return "*=";
2455 case TRUNC_DIV_EXPR: return "/=";
2456 case TRUNC_MOD_EXPR: return "%=";
2457 case BIT_XOR_EXPR: return "^=";
2458 case BIT_AND_EXPR: return "&=";
2459 case BIT_IOR_EXPR: return "|=";
2460 case LSHIFT_EXPR: return "<<=";
2461 case RSHIFT_EXPR: return ">>=";
2462 default: gcc_unreachable ();
2465 else
2467 switch (op)
2469 case PLUS_EXPR: return "+";
2470 case MINUS_EXPR: return "-";
2471 case MULT_EXPR: return "*";
2472 case TRUNC_DIV_EXPR: return "/";
2473 case TRUNC_MOD_EXPR: return "%";
2474 case BIT_XOR_EXPR: return "^";
2475 case BIT_AND_EXPR: return "&";
2476 case BIT_IOR_EXPR: return "|";
2477 case LSHIFT_EXPR: return "<<";
2478 case RSHIFT_EXPR: return ">>";
2479 case EQ_EXPR: return "==";
2480 case NE_EXPR: return "!=";
2481 case LT_EXPR: return "<";
2482 case GT_EXPR: return ">";
2483 case LE_EXPR: return "<=";
2484 case GE_EXPR: return ">=";
2485 case TRUTH_ANDIF_EXPR: return "&&";
2486 case TRUTH_ORIF_EXPR: return "||";
2487 case MEMBER_REF: return "->*";
2488 case DOTSTAR_EXPR: return ".*";
2489 case OFFSET_REF: return ".*";
2490 default: return ","; /* FIXME: Not the right default. */
2495 void
2496 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2498 char const* op = get_fold_operator (t);
2499 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2500 pp_cxx_left_paren (pp);
2501 pp_cxx_ws_string (pp, "...");
2502 pp_cxx_ws_string (pp, op);
2503 pp->expression (expr);
2504 pp_cxx_right_paren (pp);
2507 void
2508 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2510 char const* op = get_fold_operator (t);
2511 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2512 pp_cxx_left_paren (pp);
2513 pp->expression (expr);
2514 pp_space (pp);
2515 pp_cxx_ws_string (pp, op);
2516 pp_cxx_ws_string (pp, "...");
2517 pp_cxx_right_paren (pp);
2520 void
2521 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2523 char const* op = get_fold_operator (t);
2524 tree t1 = TREE_OPERAND (t, 1);
2525 tree t2 = TREE_OPERAND (t, 2);
2526 if (t1 == FOLD_EXPR_PACK (t))
2527 t1 = PACK_EXPANSION_PATTERN (t1);
2528 else
2529 t2 = PACK_EXPANSION_PATTERN (t2);
2530 pp_cxx_left_paren (pp);
2531 pp->expression (t1);
2532 pp_cxx_ws_string (pp, op);
2533 pp_cxx_ws_string (pp, "...");
2534 pp_cxx_ws_string (pp, op);
2535 pp->expression (t2);
2536 pp_cxx_right_paren (pp);
2539 void
2540 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2542 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2544 switch (kind)
2546 case CPTK_HAS_NOTHROW_ASSIGN:
2547 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2548 break;
2549 case CPTK_HAS_TRIVIAL_ASSIGN:
2550 pp_cxx_ws_string (pp, "__has_trivial_assign");
2551 break;
2552 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2553 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2554 break;
2555 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2556 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2557 break;
2558 case CPTK_HAS_NOTHROW_COPY:
2559 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2560 break;
2561 case CPTK_HAS_TRIVIAL_COPY:
2562 pp_cxx_ws_string (pp, "__has_trivial_copy");
2563 break;
2564 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2565 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2566 break;
2567 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
2568 pp_cxx_ws_string (pp, "__has_unique_object_representations");
2569 break;
2570 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2571 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2572 break;
2573 case CPTK_IS_ABSTRACT:
2574 pp_cxx_ws_string (pp, "__is_abstract");
2575 break;
2576 case CPTK_IS_AGGREGATE:
2577 pp_cxx_ws_string (pp, "__is_aggregate");
2578 break;
2579 case CPTK_IS_BASE_OF:
2580 pp_cxx_ws_string (pp, "__is_base_of");
2581 break;
2582 case CPTK_IS_CLASS:
2583 pp_cxx_ws_string (pp, "__is_class");
2584 break;
2585 case CPTK_IS_EMPTY:
2586 pp_cxx_ws_string (pp, "__is_empty");
2587 break;
2588 case CPTK_IS_ENUM:
2589 pp_cxx_ws_string (pp, "__is_enum");
2590 break;
2591 case CPTK_IS_FINAL:
2592 pp_cxx_ws_string (pp, "__is_final");
2593 break;
2594 case CPTK_IS_POD:
2595 pp_cxx_ws_string (pp, "__is_pod");
2596 break;
2597 case CPTK_IS_POLYMORPHIC:
2598 pp_cxx_ws_string (pp, "__is_polymorphic");
2599 break;
2600 case CPTK_IS_SAME_AS:
2601 pp_cxx_ws_string (pp, "__is_same_as");
2602 break;
2603 case CPTK_IS_STD_LAYOUT:
2604 pp_cxx_ws_string (pp, "__is_std_layout");
2605 break;
2606 case CPTK_IS_TRIVIAL:
2607 pp_cxx_ws_string (pp, "__is_trivial");
2608 break;
2609 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2610 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2611 break;
2612 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2613 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2614 break;
2615 case CPTK_IS_TRIVIALLY_COPYABLE:
2616 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2617 break;
2618 case CPTK_IS_UNION:
2619 pp_cxx_ws_string (pp, "__is_union");
2620 break;
2621 case CPTK_IS_LITERAL_TYPE:
2622 pp_cxx_ws_string (pp, "__is_literal_type");
2623 break;
2624 case CPTK_IS_ASSIGNABLE:
2625 pp_cxx_ws_string (pp, "__is_assignable");
2626 break;
2627 case CPTK_IS_CONSTRUCTIBLE:
2628 pp_cxx_ws_string (pp, "__is_constructible");
2629 break;
2631 default:
2632 gcc_unreachable ();
2635 pp_cxx_left_paren (pp);
2636 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2638 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2640 pp_cxx_separate_with (pp, ',');
2641 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2644 pp_cxx_right_paren (pp);
2647 // requires-clause:
2648 // 'requires' logical-or-expression
2649 void
2650 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2652 if (!t)
2653 return;
2654 pp->padding = pp_before;
2655 pp_cxx_ws_string (pp, "requires");
2656 pp_space (pp);
2657 pp->expression (t);
2660 /* requirement:
2661 simple-requirement
2662 compound-requirement
2663 type-requirement
2664 nested-requirement */
2665 static void
2666 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2668 switch (TREE_CODE (t))
2670 case SIMPLE_REQ:
2671 pp_cxx_simple_requirement (pp, t);
2672 break;
2674 case TYPE_REQ:
2675 pp_cxx_type_requirement (pp, t);
2676 break;
2678 case COMPOUND_REQ:
2679 pp_cxx_compound_requirement (pp, t);
2680 break;
2682 case NESTED_REQ:
2683 pp_cxx_nested_requirement (pp, t);
2684 break;
2686 default:
2687 gcc_unreachable ();
2691 // requirement-list:
2692 // requirement
2693 // requirement-list ';' requirement[opt]
2695 static void
2696 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2698 for (; t; t = TREE_CHAIN (t))
2699 pp_cxx_requirement (pp, TREE_VALUE (t));
2702 // requirement-body:
2703 // '{' requirement-list '}'
2704 static void
2705 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2707 pp_cxx_left_brace (pp);
2708 pp_cxx_requirement_list (pp, t);
2709 pp_cxx_right_brace (pp);
2712 // requires-expression:
2713 // 'requires' requirement-parameter-list requirement-body
2714 void
2715 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2717 pp_string (pp, "requires");
2718 if (tree parms = TREE_OPERAND (t, 0))
2720 pp_cxx_parameter_declaration_clause (pp, parms);
2721 pp_cxx_whitespace (pp);
2723 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2726 /* simple-requirement:
2727 expression ';' */
2728 void
2729 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2731 pp->expression (TREE_OPERAND (t, 0));
2732 pp_cxx_semicolon (pp);
2735 /* type-requirement:
2736 typename type-name ';' */
2737 void
2738 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2740 pp->type_id (TREE_OPERAND (t, 0));
2741 pp_cxx_semicolon (pp);
2744 /* compound-requirement:
2745 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2746 void
2747 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2749 pp_cxx_left_brace (pp);
2750 pp->expression (TREE_OPERAND (t, 0));
2751 pp_cxx_right_brace (pp);
2753 if (COMPOUND_REQ_NOEXCEPT_P (t))
2754 pp_cxx_ws_string (pp, "noexcept");
2756 if (tree type = TREE_OPERAND (t, 1))
2758 pp_cxx_ws_string (pp, "->");
2759 pp->type_id (type);
2761 pp_cxx_semicolon (pp);
2764 /* nested requirement:
2765 'requires' constraint-expression */
2766 void
2767 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2769 pp_cxx_ws_string (pp, "requires");
2770 pp->expression (TREE_OPERAND (t, 0));
2771 pp_cxx_semicolon (pp);
2774 void
2775 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2777 pp->expression (TREE_OPERAND (t, 0));
2780 void
2781 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2783 tree decl = CHECK_CONSTR_CONCEPT (t);
2784 tree tmpl = DECL_TI_TEMPLATE (decl);
2785 tree args = CHECK_CONSTR_ARGS (t);
2786 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2788 if (VAR_P (decl))
2789 pp->expression (id);
2790 else if (TREE_CODE (decl) == FUNCTION_DECL)
2792 tree call = build_vl_exp (CALL_EXPR, 2);
2793 TREE_OPERAND (call, 0) = integer_two_node;
2794 TREE_OPERAND (call, 1) = id;
2795 pp->expression (call);
2797 else
2798 gcc_unreachable ();
2801 void
2802 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2804 pp_string (pp, "<valid-expression ");
2805 pp_cxx_left_paren (pp);
2806 pp->expression (TREE_OPERAND (t, 0));
2807 pp_cxx_right_paren (pp);
2808 pp_string (pp, ">");
2811 void
2812 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2814 pp_string (pp, "<valid-type ");
2815 pp->type_id (TREE_OPERAND (t, 0));
2816 pp_string (pp, ">");
2819 void
2820 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2822 pp_string (pp, "<implicitly-conversion ");
2823 pp_cxx_left_paren (pp);
2824 pp->expression (ICONV_CONSTR_EXPR (t));
2825 pp_cxx_right_paren (pp);
2826 pp_cxx_ws_string (pp, "to");
2827 pp->type_id (ICONV_CONSTR_TYPE (t));
2828 pp_string (pp, ">");
2831 void
2832 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2834 pp_string (pp, "<argument-deduction ");
2835 pp_cxx_left_paren (pp);
2836 pp->expression (DEDUCT_CONSTR_EXPR (t));
2837 pp_cxx_right_paren (pp);
2838 pp_cxx_ws_string (pp, "as");
2839 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2840 pp_string (pp, ">");
2843 void
2844 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2846 pp_cxx_ws_string (pp, "noexcept");
2847 pp_cxx_whitespace (pp);
2848 pp_cxx_left_paren (pp);
2849 pp->expression (TREE_OPERAND (t, 0));
2850 pp_cxx_right_paren (pp);
2853 void
2854 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2856 pp_left_paren (pp);
2857 pp_string (pp, "<requires ");
2858 if (tree parms = PARM_CONSTR_PARMS (t))
2860 pp_cxx_parameter_declaration_clause (pp, parms);
2861 pp_cxx_whitespace (pp);
2863 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2864 pp_string (pp, ">");
2867 void
2868 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2870 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2871 pp_string (pp, " and ");
2872 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2875 void
2876 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2878 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2879 pp_string (pp, " or ");
2880 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2883 void
2884 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2886 if (t == error_mark_node)
2887 return pp->expression (t);
2889 switch (TREE_CODE (t))
2891 case PRED_CONSTR:
2892 pp_cxx_predicate_constraint (pp, t);
2893 break;
2895 case CHECK_CONSTR:
2896 pp_cxx_check_constraint (pp, t);
2897 break;
2899 case EXPR_CONSTR:
2900 pp_cxx_expression_constraint (pp, t);
2901 break;
2903 case TYPE_CONSTR:
2904 pp_cxx_type_constraint (pp, t);
2905 break;
2907 case ICONV_CONSTR:
2908 pp_cxx_implicit_conversion_constraint (pp, t);
2909 break;
2911 case DEDUCT_CONSTR:
2912 pp_cxx_argument_deduction_constraint (pp, t);
2913 break;
2915 case EXCEPT_CONSTR:
2916 pp_cxx_exception_constraint (pp, t);
2917 break;
2919 case PARM_CONSTR:
2920 pp_cxx_parameterized_constraint (pp, t);
2921 break;
2923 case CONJ_CONSTR:
2924 pp_cxx_conjunction (pp, t);
2925 break;
2927 case DISJ_CONSTR:
2928 pp_cxx_disjunction (pp, t);
2929 break;
2931 case EXPR_PACK_EXPANSION:
2932 pp->expression (TREE_OPERAND (t, 0));
2933 break;
2935 default:
2936 gcc_unreachable ();
2942 typedef c_pretty_print_fn pp_fun;
2944 /* Initialization of a C++ pretty-printer object. */
2946 cxx_pretty_printer::cxx_pretty_printer ()
2947 : c_pretty_printer (),
2948 enclosing_scope (global_namespace)
2950 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2951 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;