2017-03-06 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob150b6031e8020b73eb2bd1ee43dbb6dbecd24446
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2017 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 /* FALLTHRU */
146 case VAR_DECL:
147 case PARM_DECL:
148 case CONST_DECL:
149 case TYPE_DECL:
150 case FUNCTION_DECL:
151 case NAMESPACE_DECL:
152 case FIELD_DECL:
153 case LABEL_DECL:
154 case USING_DECL:
155 case TEMPLATE_DECL:
156 t = DECL_NAME (t);
157 /* FALLTHRU */
159 case IDENTIFIER_NODE:
160 if (t == NULL)
161 pp->translate_string ("<unnamed>");
162 else if (IDENTIFIER_TYPENAME_P (t))
163 pp_cxx_conversion_function_id (pp, t);
164 else
166 if (is_destructor_name (t))
168 pp_complement (pp);
169 /* FIXME: Why is this necessary? */
170 if (TREE_TYPE (t))
171 t = constructor_name (TREE_TYPE (t));
173 pp_cxx_tree_identifier (pp, t);
175 break;
177 case TEMPLATE_ID_EXPR:
178 pp_cxx_template_id (pp, t);
179 break;
181 case BASELINK:
182 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
183 break;
185 case RECORD_TYPE:
186 case UNION_TYPE:
187 case ENUMERAL_TYPE:
188 case TYPENAME_TYPE:
189 case UNBOUND_CLASS_TEMPLATE:
190 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
191 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
193 pp_cxx_begin_template_argument_list (pp);
194 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
195 (CLASSTYPE_TI_ARGS (t)));
196 pp_cxx_end_template_argument_list (pp);
198 break;
200 case BIT_NOT_EXPR:
201 pp_cxx_complement (pp);
202 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
203 break;
205 case TEMPLATE_TYPE_PARM:
206 case TEMPLATE_TEMPLATE_PARM:
207 if (TYPE_IDENTIFIER (t))
208 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
209 else
210 pp_cxx_canonical_template_parameter (pp, t);
211 break;
213 case TEMPLATE_PARM_INDEX:
214 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
215 break;
217 case BOUND_TEMPLATE_TEMPLATE_PARM:
218 pp_cxx_cv_qualifier_seq (pp, t);
219 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
220 pp_cxx_begin_template_argument_list (pp);
221 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
222 pp_cxx_end_template_argument_list (pp);
223 break;
225 default:
226 pp_unsupported_tree (pp, t);
227 break;
231 /* Pretty-print out the token sequence ":: template" in template codes
232 where it is needed to "inline declare" the (following) member as
233 a template. This situation arises when SCOPE of T is dependent
234 on template parameters. */
236 static inline void
237 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
239 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
240 && TYPE_P (scope) && dependent_type_p (scope))
241 pp_cxx_ws_string (pp, "template");
244 /* nested-name-specifier:
245 class-or-namespace-name :: nested-name-specifier(opt)
246 class-or-namespace-name :: template nested-name-specifier */
248 static void
249 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
251 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
253 tree scope = get_containing_scope (t);
254 pp_cxx_nested_name_specifier (pp, scope);
255 pp_cxx_template_keyword_if_needed (pp, scope, t);
256 pp_cxx_unqualified_id (pp, t);
257 pp_cxx_colon_colon (pp);
261 /* qualified-id:
262 nested-name-specifier template(opt) unqualified-id */
264 static void
265 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
267 switch (TREE_CODE (t))
269 /* A pointer-to-member is always qualified. */
270 case PTRMEM_CST:
271 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
272 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
273 break;
275 /* In Standard C++, functions cannot possibly be used as
276 nested-name-specifiers. However, there are situations where
277 is "makes sense" to output the surrounding function name for the
278 purpose of emphasizing on the scope kind. Just printing the
279 function name might not be sufficient as it may be overloaded; so,
280 we decorate the function with its signature too.
281 FIXME: This is probably the wrong pretty-printing for conversion
282 functions and some function templates. */
283 case OVERLOAD:
284 t = OVL_CURRENT (t);
285 /* FALLTHRU */
286 case FUNCTION_DECL:
287 if (DECL_FUNCTION_MEMBER_P (t))
288 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
289 pp_cxx_unqualified_id
290 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
291 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
292 break;
294 case OFFSET_REF:
295 case SCOPE_REF:
296 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
297 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
298 break;
300 default:
302 tree scope = get_containing_scope (t);
303 if (scope != pp->enclosing_scope)
305 pp_cxx_nested_name_specifier (pp, scope);
306 pp_cxx_template_keyword_if_needed (pp, scope, t);
308 pp_cxx_unqualified_id (pp, t);
310 break;
315 void
316 cxx_pretty_printer::constant (tree t)
318 switch (TREE_CODE (t))
320 case STRING_CST:
322 const bool in_parens = PAREN_STRING_LITERAL_P (t);
323 if (in_parens)
324 pp_cxx_left_paren (this);
325 c_pretty_printer::constant (t);
326 if (in_parens)
327 pp_cxx_right_paren (this);
329 break;
331 case INTEGER_CST:
332 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
334 pp_string (this, "nullptr");
335 break;
337 /* fall through. */
339 default:
340 c_pretty_printer::constant (t);
341 break;
345 /* id-expression:
346 unqualified-id
347 qualified-id */
349 void
350 cxx_pretty_printer::id_expression (tree t)
352 if (TREE_CODE (t) == OVERLOAD)
353 t = OVL_CURRENT (t);
354 if (DECL_P (t) && DECL_CONTEXT (t))
355 pp_cxx_qualified_id (this, t);
356 else
357 pp_cxx_unqualified_id (this, t);
360 /* user-defined literal:
361 literal ud-suffix */
363 void
364 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
366 pp->constant (USERDEF_LITERAL_VALUE (t));
367 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
371 /* primary-expression:
372 literal
373 this
374 :: identifier
375 :: operator-function-id
376 :: qualifier-id
377 ( expression )
378 id-expression
380 GNU Extensions:
381 __builtin_va_arg ( assignment-expression , type-id )
382 __builtin_offsetof ( type-id, offsetof-expression )
383 __builtin_addressof ( 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_unique_object_representations ( type-id )
392 __has_trivial_destructor ( type-id )
393 __has_virtual_destructor ( type-id )
394 __is_abstract ( type-id )
395 __is_base_of ( type-id , type-id )
396 __is_class ( type-id )
397 __is_empty ( type-id )
398 __is_enum ( type-id )
399 __is_literal_type ( type-id )
400 __is_pod ( type-id )
401 __is_polymorphic ( type-id )
402 __is_std_layout ( type-id )
403 __is_trivial ( type-id )
404 __is_union ( type-id ) */
406 void
407 cxx_pretty_printer::primary_expression (tree t)
409 switch (TREE_CODE (t))
411 case VOID_CST:
412 case INTEGER_CST:
413 case REAL_CST:
414 case COMPLEX_CST:
415 case STRING_CST:
416 constant (t);
417 break;
419 case USERDEF_LITERAL:
420 pp_cxx_userdef_literal (this, t);
421 break;
423 case BASELINK:
424 t = BASELINK_FUNCTIONS (t);
425 /* FALLTHRU */
426 case VAR_DECL:
427 case PARM_DECL:
428 case FIELD_DECL:
429 case FUNCTION_DECL:
430 case OVERLOAD:
431 case CONST_DECL:
432 case TEMPLATE_DECL:
433 id_expression (t);
434 break;
436 case RESULT_DECL:
437 case TEMPLATE_TYPE_PARM:
438 case TEMPLATE_TEMPLATE_PARM:
439 case TEMPLATE_PARM_INDEX:
440 pp_cxx_unqualified_id (this, t);
441 break;
443 case STMT_EXPR:
444 pp_cxx_left_paren (this);
445 statement (STMT_EXPR_STMT (t));
446 pp_cxx_right_paren (this);
447 break;
449 case TRAIT_EXPR:
450 pp_cxx_trait_expression (this, t);
451 break;
453 case VA_ARG_EXPR:
454 pp_cxx_va_arg_expression (this, t);
455 break;
457 case OFFSETOF_EXPR:
458 pp_cxx_offsetof_expression (this, t);
459 break;
461 case ADDRESSOF_EXPR:
462 pp_cxx_addressof_expression (this, t);
463 break;
465 case REQUIRES_EXPR:
466 pp_cxx_requires_expr (this, t);
467 break;
469 default:
470 c_pretty_printer::primary_expression (t);
471 break;
475 /* postfix-expression:
476 primary-expression
477 postfix-expression [ expression ]
478 postfix-expression ( expression-list(opt) )
479 simple-type-specifier ( expression-list(opt) )
480 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
481 typename ::(opt) nested-name-specifier template(opt)
482 template-id ( expression-list(opt) )
483 postfix-expression . template(opt) ::(opt) id-expression
484 postfix-expression -> template(opt) ::(opt) id-expression
485 postfix-expression . pseudo-destructor-name
486 postfix-expression -> pseudo-destructor-name
487 postfix-expression ++
488 postfix-expression --
489 dynamic_cast < type-id > ( expression )
490 static_cast < type-id > ( expression )
491 reinterpret_cast < type-id > ( expression )
492 const_cast < type-id > ( expression )
493 typeid ( expression )
494 typeid ( type-id ) */
496 void
497 cxx_pretty_printer::postfix_expression (tree t)
499 enum tree_code code = TREE_CODE (t);
501 switch (code)
503 case AGGR_INIT_EXPR:
504 case CALL_EXPR:
506 tree fun = cp_get_callee (t);
507 tree saved_scope = enclosing_scope;
508 bool skipfirst = false;
509 tree arg;
511 if (TREE_CODE (fun) == ADDR_EXPR)
512 fun = TREE_OPERAND (fun, 0);
514 /* In templates, where there is no way to tell whether a given
515 call uses an actual member function. So the parser builds
516 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
517 instantiation time. */
518 if (TREE_CODE (fun) != FUNCTION_DECL)
520 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
522 tree object = (code == AGGR_INIT_EXPR
523 ? (AGGR_INIT_VIA_CTOR_P (t)
524 ? AGGR_INIT_EXPR_SLOT (t)
525 : AGGR_INIT_EXPR_ARG (t, 0))
526 : CALL_EXPR_ARG (t, 0));
528 while (TREE_CODE (object) == NOP_EXPR)
529 object = TREE_OPERAND (object, 0);
531 if (TREE_CODE (object) == ADDR_EXPR)
532 object = TREE_OPERAND (object, 0);
534 if (!TYPE_PTR_P (TREE_TYPE (object)))
536 postfix_expression (object);
537 pp_cxx_dot (this);
539 else
541 postfix_expression (object);
542 pp_cxx_arrow (this);
544 skipfirst = true;
545 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
548 postfix_expression (fun);
549 enclosing_scope = saved_scope;
550 pp_cxx_left_paren (this);
551 if (code == AGGR_INIT_EXPR)
553 aggr_init_expr_arg_iterator iter;
554 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
556 if (skipfirst)
557 skipfirst = false;
558 else
560 expression (arg);
561 if (more_aggr_init_expr_args_p (&iter))
562 pp_cxx_separate_with (this, ',');
566 else
568 call_expr_arg_iterator iter;
569 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
571 if (skipfirst)
572 skipfirst = false;
573 else
575 expression (arg);
576 if (more_call_expr_args_p (&iter))
577 pp_cxx_separate_with (this, ',');
581 pp_cxx_right_paren (this);
583 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
585 pp_cxx_separate_with (this, ',');
586 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
588 break;
590 case BASELINK:
591 case VAR_DECL:
592 case PARM_DECL:
593 case FIELD_DECL:
594 case FUNCTION_DECL:
595 case OVERLOAD:
596 case CONST_DECL:
597 case TEMPLATE_DECL:
598 case RESULT_DECL:
599 primary_expression (t);
600 break;
602 case DYNAMIC_CAST_EXPR:
603 case STATIC_CAST_EXPR:
604 case REINTERPRET_CAST_EXPR:
605 case CONST_CAST_EXPR:
606 if (code == DYNAMIC_CAST_EXPR)
607 pp_cxx_ws_string (this, "dynamic_cast");
608 else if (code == STATIC_CAST_EXPR)
609 pp_cxx_ws_string (this, "static_cast");
610 else if (code == REINTERPRET_CAST_EXPR)
611 pp_cxx_ws_string (this, "reinterpret_cast");
612 else
613 pp_cxx_ws_string (this, "const_cast");
614 pp_cxx_begin_template_argument_list (this);
615 type_id (TREE_TYPE (t));
616 pp_cxx_end_template_argument_list (this);
617 pp_left_paren (this);
618 expression (TREE_OPERAND (t, 0));
619 pp_right_paren (this);
620 break;
622 case EMPTY_CLASS_EXPR:
623 type_id (TREE_TYPE (t));
624 pp_left_paren (this);
625 pp_right_paren (this);
626 break;
628 case TYPEID_EXPR:
629 pp_cxx_typeid_expression (this, t);
630 break;
632 case PSEUDO_DTOR_EXPR:
633 postfix_expression (TREE_OPERAND (t, 0));
634 pp_cxx_dot (this);
635 if (TREE_OPERAND (t, 1))
637 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
638 pp_cxx_colon_colon (this);
640 pp_complement (this);
641 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
642 break;
644 case ARROW_EXPR:
645 postfix_expression (TREE_OPERAND (t, 0));
646 pp_cxx_arrow (this);
647 break;
649 default:
650 c_pretty_printer::postfix_expression (t);
651 break;
655 /* new-expression:
656 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
657 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
659 new-placement:
660 ( expression-list )
662 new-type-id:
663 type-specifier-seq new-declarator(opt)
665 new-declarator:
666 ptr-operator new-declarator(opt)
667 direct-new-declarator
669 direct-new-declarator
670 [ expression ]
671 direct-new-declarator [ constant-expression ]
673 new-initializer:
674 ( expression-list(opt) ) */
676 static void
677 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
679 enum tree_code code = TREE_CODE (t);
680 tree type = TREE_OPERAND (t, 1);
681 tree init = TREE_OPERAND (t, 2);
682 switch (code)
684 case NEW_EXPR:
685 case VEC_NEW_EXPR:
686 if (NEW_EXPR_USE_GLOBAL (t))
687 pp_cxx_colon_colon (pp);
688 pp_cxx_ws_string (pp, "new");
689 if (TREE_OPERAND (t, 0))
691 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
692 pp_space (pp);
694 if (TREE_CODE (type) == ARRAY_REF)
695 type = build_cplus_array_type
696 (TREE_OPERAND (type, 0),
697 build_index_type (fold_build2_loc (input_location,
698 MINUS_EXPR, integer_type_node,
699 TREE_OPERAND (type, 1),
700 integer_one_node)));
701 pp->type_id (type);
702 if (init)
704 pp_left_paren (pp);
705 if (TREE_CODE (init) == TREE_LIST)
706 pp_c_expression_list (pp, init);
707 else if (init == void_node)
708 ; /* OK, empty initializer list. */
709 else
710 pp->expression (init);
711 pp_right_paren (pp);
713 break;
715 default:
716 pp_unsupported_tree (pp, t);
720 /* delete-expression:
721 ::(opt) delete cast-expression
722 ::(opt) delete [ ] cast-expression */
724 static void
725 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
727 enum tree_code code = TREE_CODE (t);
728 switch (code)
730 case DELETE_EXPR:
731 case VEC_DELETE_EXPR:
732 if (DELETE_EXPR_USE_GLOBAL (t))
733 pp_cxx_colon_colon (pp);
734 pp_cxx_ws_string (pp, "delete");
735 pp_space (pp);
736 if (code == VEC_DELETE_EXPR
737 || DELETE_EXPR_USE_VEC (t))
739 pp_left_bracket (pp);
740 pp_right_bracket (pp);
741 pp_space (pp);
743 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
744 break;
746 default:
747 pp_unsupported_tree (pp, t);
751 /* unary-expression:
752 postfix-expression
753 ++ cast-expression
754 -- cast-expression
755 unary-operator cast-expression
756 sizeof unary-expression
757 sizeof ( type-id )
758 sizeof ... ( identifier )
759 new-expression
760 delete-expression
762 unary-operator: one of
763 * & + - !
765 GNU extensions:
766 __alignof__ unary-expression
767 __alignof__ ( type-id ) */
769 void
770 cxx_pretty_printer::unary_expression (tree t)
772 enum tree_code code = TREE_CODE (t);
773 switch (code)
775 case NEW_EXPR:
776 case VEC_NEW_EXPR:
777 pp_cxx_new_expression (this, t);
778 break;
780 case DELETE_EXPR:
781 case VEC_DELETE_EXPR:
782 pp_cxx_delete_expression (this, t);
783 break;
785 case SIZEOF_EXPR:
786 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
788 pp_cxx_ws_string (this, "sizeof");
789 pp_cxx_ws_string (this, "...");
790 pp_cxx_whitespace (this);
791 pp_cxx_left_paren (this);
792 if (TYPE_P (TREE_OPERAND (t, 0)))
793 type_id (TREE_OPERAND (t, 0));
794 else
795 unary_expression (TREE_OPERAND (t, 0));
796 pp_cxx_right_paren (this);
797 break;
799 /* Fall through */
801 case ALIGNOF_EXPR:
802 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
803 pp_cxx_whitespace (this);
804 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
806 pp_cxx_left_paren (this);
807 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
808 pp_cxx_right_paren (this);
810 else if (TYPE_P (TREE_OPERAND (t, 0)))
812 pp_cxx_left_paren (this);
813 type_id (TREE_OPERAND (t, 0));
814 pp_cxx_right_paren (this);
816 else
817 unary_expression (TREE_OPERAND (t, 0));
818 break;
820 case AT_ENCODE_EXPR:
821 pp_cxx_ws_string (this, "@encode");
822 pp_cxx_whitespace (this);
823 pp_cxx_left_paren (this);
824 type_id (TREE_OPERAND (t, 0));
825 pp_cxx_right_paren (this);
826 break;
828 case NOEXCEPT_EXPR:
829 pp_cxx_ws_string (this, "noexcept");
830 pp_cxx_whitespace (this);
831 pp_cxx_left_paren (this);
832 expression (TREE_OPERAND (t, 0));
833 pp_cxx_right_paren (this);
834 break;
836 case UNARY_PLUS_EXPR:
837 pp_plus (this);
838 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
839 break;
841 default:
842 c_pretty_printer::unary_expression (t);
843 break;
847 /* cast-expression:
848 unary-expression
849 ( type-id ) cast-expression */
851 static void
852 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
854 switch (TREE_CODE (t))
856 case CAST_EXPR:
857 case IMPLICIT_CONV_EXPR:
858 pp->type_id (TREE_TYPE (t));
859 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
860 break;
862 default:
863 pp_c_cast_expression (pp, t);
864 break;
868 /* pm-expression:
869 cast-expression
870 pm-expression .* cast-expression
871 pm-expression ->* cast-expression */
873 static void
874 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
876 switch (TREE_CODE (t))
878 /* Handle unfortunate OFFSET_REF overloading here. */
879 case OFFSET_REF:
880 if (TYPE_P (TREE_OPERAND (t, 0)))
882 pp_cxx_qualified_id (pp, t);
883 break;
885 /* Fall through. */
886 case MEMBER_REF:
887 case DOTSTAR_EXPR:
888 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
889 if (TREE_CODE (t) == MEMBER_REF)
890 pp_cxx_arrow (pp);
891 else
892 pp_cxx_dot (pp);
893 pp_star(pp);
894 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
895 break;
898 default:
899 pp_cxx_cast_expression (pp, t);
900 break;
904 /* multiplicative-expression:
905 pm-expression
906 multiplicative-expression * pm-expression
907 multiplicative-expression / pm-expression
908 multiplicative-expression % pm-expression */
910 void
911 cxx_pretty_printer::multiplicative_expression (tree e)
913 enum tree_code code = TREE_CODE (e);
914 switch (code)
916 case MULT_EXPR:
917 case TRUNC_DIV_EXPR:
918 case TRUNC_MOD_EXPR:
919 multiplicative_expression (TREE_OPERAND (e, 0));
920 pp_space (this);
921 if (code == MULT_EXPR)
922 pp_star (this);
923 else if (code == TRUNC_DIV_EXPR)
924 pp_slash (this);
925 else
926 pp_modulo (this);
927 pp_space (this);
928 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
929 break;
931 default:
932 pp_cxx_pm_expression (this, e);
933 break;
937 /* conditional-expression:
938 logical-or-expression
939 logical-or-expression ? expression : assignment-expression */
941 void
942 cxx_pretty_printer::conditional_expression (tree e)
944 if (TREE_CODE (e) == COND_EXPR)
946 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
947 pp_space (this);
948 pp_question (this);
949 pp_space (this);
950 expression (TREE_OPERAND (e, 1));
951 pp_space (this);
952 assignment_expression (TREE_OPERAND (e, 2));
954 else
955 pp_c_logical_or_expression (this, e);
958 /* Pretty-print a compound assignment operator token as indicated by T. */
960 static void
961 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
963 const char *op;
965 switch (TREE_CODE (t))
967 case NOP_EXPR:
968 op = "=";
969 break;
971 case PLUS_EXPR:
972 op = "+=";
973 break;
975 case MINUS_EXPR:
976 op = "-=";
977 break;
979 case TRUNC_DIV_EXPR:
980 op = "/=";
981 break;
983 case TRUNC_MOD_EXPR:
984 op = "%=";
985 break;
987 default:
988 op = get_tree_code_name (TREE_CODE (t));
989 break;
992 pp_cxx_ws_string (pp, op);
996 /* assignment-expression:
997 conditional-expression
998 logical-or-expression assignment-operator assignment-expression
999 throw-expression
1001 throw-expression:
1002 throw assignment-expression(opt)
1004 assignment-operator: one of
1005 = *= /= %= += -= >>= <<= &= ^= |= */
1007 void
1008 cxx_pretty_printer::assignment_expression (tree e)
1010 switch (TREE_CODE (e))
1012 case MODIFY_EXPR:
1013 case INIT_EXPR:
1014 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1015 pp_space (this);
1016 pp_equal (this);
1017 pp_space (this);
1018 assignment_expression (TREE_OPERAND (e, 1));
1019 break;
1021 case THROW_EXPR:
1022 pp_cxx_ws_string (this, "throw");
1023 if (TREE_OPERAND (e, 0))
1024 assignment_expression (TREE_OPERAND (e, 0));
1025 break;
1027 case MODOP_EXPR:
1028 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1029 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1030 assignment_expression (TREE_OPERAND (e, 2));
1031 break;
1033 default:
1034 conditional_expression (e);
1035 break;
1039 void
1040 cxx_pretty_printer::expression (tree t)
1042 switch (TREE_CODE (t))
1044 case STRING_CST:
1045 case VOID_CST:
1046 case INTEGER_CST:
1047 case REAL_CST:
1048 case COMPLEX_CST:
1049 constant (t);
1050 break;
1052 case USERDEF_LITERAL:
1053 pp_cxx_userdef_literal (this, t);
1054 break;
1056 case RESULT_DECL:
1057 pp_cxx_unqualified_id (this, t);
1058 break;
1060 #if 0
1061 case OFFSET_REF:
1062 #endif
1063 case SCOPE_REF:
1064 case PTRMEM_CST:
1065 pp_cxx_qualified_id (this, t);
1066 break;
1068 case OVERLOAD:
1069 t = OVL_CURRENT (t);
1070 /* FALLTHRU */
1071 case VAR_DECL:
1072 case PARM_DECL:
1073 case FIELD_DECL:
1074 case CONST_DECL:
1075 case FUNCTION_DECL:
1076 case BASELINK:
1077 case TEMPLATE_DECL:
1078 case TEMPLATE_TYPE_PARM:
1079 case TEMPLATE_PARM_INDEX:
1080 case TEMPLATE_TEMPLATE_PARM:
1081 case STMT_EXPR:
1082 case REQUIRES_EXPR:
1083 primary_expression (t);
1084 break;
1086 case CALL_EXPR:
1087 case DYNAMIC_CAST_EXPR:
1088 case STATIC_CAST_EXPR:
1089 case REINTERPRET_CAST_EXPR:
1090 case CONST_CAST_EXPR:
1091 #if 0
1092 case MEMBER_REF:
1093 #endif
1094 case EMPTY_CLASS_EXPR:
1095 case TYPEID_EXPR:
1096 case PSEUDO_DTOR_EXPR:
1097 case AGGR_INIT_EXPR:
1098 case ARROW_EXPR:
1099 postfix_expression (t);
1100 break;
1102 case NEW_EXPR:
1103 case VEC_NEW_EXPR:
1104 pp_cxx_new_expression (this, t);
1105 break;
1107 case DELETE_EXPR:
1108 case VEC_DELETE_EXPR:
1109 pp_cxx_delete_expression (this, t);
1110 break;
1112 case SIZEOF_EXPR:
1113 case ALIGNOF_EXPR:
1114 case NOEXCEPT_EXPR:
1115 unary_expression (t);
1116 break;
1118 case CAST_EXPR:
1119 case IMPLICIT_CONV_EXPR:
1120 pp_cxx_cast_expression (this, t);
1121 break;
1123 case OFFSET_REF:
1124 case MEMBER_REF:
1125 case DOTSTAR_EXPR:
1126 pp_cxx_pm_expression (this, t);
1127 break;
1129 case MULT_EXPR:
1130 case TRUNC_DIV_EXPR:
1131 case TRUNC_MOD_EXPR:
1132 multiplicative_expression (t);
1133 break;
1135 case COND_EXPR:
1136 conditional_expression (t);
1137 break;
1139 case MODIFY_EXPR:
1140 case INIT_EXPR:
1141 case THROW_EXPR:
1142 case MODOP_EXPR:
1143 assignment_expression (t);
1144 break;
1146 case NON_DEPENDENT_EXPR:
1147 case MUST_NOT_THROW_EXPR:
1148 expression (TREE_OPERAND (t, 0));
1149 break;
1151 case EXPR_PACK_EXPANSION:
1152 expression (PACK_EXPANSION_PATTERN (t));
1153 pp_cxx_ws_string (this, "...");
1154 break;
1156 case UNARY_LEFT_FOLD_EXPR:
1157 pp_cxx_unary_left_fold_expression (this, t);
1158 break;
1160 case UNARY_RIGHT_FOLD_EXPR:
1161 pp_cxx_unary_right_fold_expression (this, t);
1162 break;
1164 case BINARY_LEFT_FOLD_EXPR:
1165 case BINARY_RIGHT_FOLD_EXPR:
1166 pp_cxx_binary_fold_expression (this, t);
1167 break;
1169 case TEMPLATE_ID_EXPR:
1170 pp_cxx_template_id (this, t);
1171 break;
1173 case NONTYPE_ARGUMENT_PACK:
1175 tree args = ARGUMENT_PACK_ARGS (t);
1176 int i, len = TREE_VEC_LENGTH (args);
1177 for (i = 0; i < len; ++i)
1179 if (i > 0)
1180 pp_cxx_separate_with (this, ',');
1181 expression (TREE_VEC_ELT (args, i));
1184 break;
1186 case LAMBDA_EXPR:
1187 pp_cxx_ws_string (this, "<lambda>");
1188 break;
1190 case TRAIT_EXPR:
1191 pp_cxx_trait_expression (this, t);
1192 break;
1194 case PRED_CONSTR:
1195 case CHECK_CONSTR:
1196 case EXPR_CONSTR:
1197 case TYPE_CONSTR:
1198 case ICONV_CONSTR:
1199 case DEDUCT_CONSTR:
1200 case EXCEPT_CONSTR:
1201 case PARM_CONSTR:
1202 case CONJ_CONSTR:
1203 case DISJ_CONSTR:
1204 pp_cxx_constraint (this, t);
1205 break;
1207 case PAREN_EXPR:
1208 pp_cxx_left_paren (this);
1209 expression (TREE_OPERAND (t, 0));
1210 pp_cxx_right_paren (this);
1211 break;
1213 default:
1214 c_pretty_printer::expression (t);
1215 break;
1220 /* Declarations. */
1222 /* function-specifier:
1223 inline
1224 virtual
1225 explicit */
1227 void
1228 cxx_pretty_printer::function_specifier (tree t)
1230 switch (TREE_CODE (t))
1232 case FUNCTION_DECL:
1233 if (DECL_VIRTUAL_P (t))
1234 pp_cxx_ws_string (this, "virtual");
1235 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1236 pp_cxx_ws_string (this, "explicit");
1237 else
1238 c_pretty_printer::function_specifier (t);
1240 default:
1241 break;
1245 /* decl-specifier-seq:
1246 decl-specifier-seq(opt) decl-specifier
1248 decl-specifier:
1249 storage-class-specifier
1250 type-specifier
1251 function-specifier
1252 friend
1253 typedef */
1255 void
1256 cxx_pretty_printer::declaration_specifiers (tree t)
1258 switch (TREE_CODE (t))
1260 case VAR_DECL:
1261 case PARM_DECL:
1262 case CONST_DECL:
1263 case FIELD_DECL:
1264 storage_class_specifier (t);
1265 declaration_specifiers (TREE_TYPE (t));
1266 break;
1268 case TYPE_DECL:
1269 pp_cxx_ws_string (this, "typedef");
1270 declaration_specifiers (TREE_TYPE (t));
1271 break;
1273 case FUNCTION_DECL:
1274 /* Constructors don't have return types. And conversion functions
1275 do not have a type-specifier in their return types. */
1276 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1277 function_specifier (t);
1278 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1279 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1280 else
1281 c_pretty_printer::declaration_specifiers (t);
1282 break;
1283 default:
1284 c_pretty_printer::declaration_specifiers (t);
1285 break;
1289 /* simple-type-specifier:
1290 ::(opt) nested-name-specifier(opt) type-name
1291 ::(opt) nested-name-specifier(opt) template(opt) template-id
1292 char
1293 wchar_t
1294 bool
1295 short
1297 long
1298 signed
1299 unsigned
1300 float
1301 double
1302 void */
1304 void
1305 cxx_pretty_printer::simple_type_specifier (tree t)
1307 switch (TREE_CODE (t))
1309 case RECORD_TYPE:
1310 case UNION_TYPE:
1311 case ENUMERAL_TYPE:
1312 pp_cxx_qualified_id (this, t);
1313 break;
1315 case TEMPLATE_TYPE_PARM:
1316 case TEMPLATE_TEMPLATE_PARM:
1317 case TEMPLATE_PARM_INDEX:
1318 case BOUND_TEMPLATE_TEMPLATE_PARM:
1319 pp_cxx_unqualified_id (this, t);
1320 break;
1322 case TYPENAME_TYPE:
1323 pp_cxx_ws_string (this, "typename");
1324 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1325 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1326 break;
1328 default:
1329 c_pretty_printer::simple_type_specifier (t);
1330 break;
1334 /* type-specifier-seq:
1335 type-specifier type-specifier-seq(opt)
1337 type-specifier:
1338 simple-type-specifier
1339 class-specifier
1340 enum-specifier
1341 elaborated-type-specifier
1342 cv-qualifier */
1344 static void
1345 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1347 switch (TREE_CODE (t))
1349 case TEMPLATE_DECL:
1350 case TEMPLATE_TYPE_PARM:
1351 case TEMPLATE_TEMPLATE_PARM:
1352 case TYPE_DECL:
1353 case BOUND_TEMPLATE_TEMPLATE_PARM:
1354 pp_cxx_cv_qualifier_seq (pp, t);
1355 pp->simple_type_specifier (t);
1356 break;
1358 case METHOD_TYPE:
1359 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1360 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1361 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1362 break;
1364 case DECLTYPE_TYPE:
1365 pp_cxx_ws_string (pp, "decltype");
1366 pp_cxx_left_paren (pp);
1367 pp->expression (DECLTYPE_TYPE_EXPR (t));
1368 pp_cxx_right_paren (pp);
1369 break;
1371 case RECORD_TYPE:
1372 if (TYPE_PTRMEMFUNC_P (t))
1374 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1375 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1376 pp_cxx_whitespace (pp);
1377 pp_cxx_ptr_operator (pp, t);
1378 break;
1380 /* fall through */
1382 default:
1383 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1384 pp_c_specifier_qualifier_list (pp, t);
1388 /* ptr-operator:
1389 * cv-qualifier-seq(opt)
1391 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1393 static void
1394 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1396 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1397 t = TREE_TYPE (t);
1398 switch (TREE_CODE (t))
1400 case REFERENCE_TYPE:
1401 case POINTER_TYPE:
1402 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1403 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1404 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1405 if (TYPE_PTR_P (t))
1407 pp_star (pp);
1408 pp_cxx_cv_qualifier_seq (pp, t);
1410 else
1411 pp_ampersand (pp);
1412 break;
1414 case RECORD_TYPE:
1415 if (TYPE_PTRMEMFUNC_P (t))
1417 pp_cxx_left_paren (pp);
1418 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1419 pp_star (pp);
1420 break;
1422 /* FALLTHRU */
1423 case OFFSET_TYPE:
1424 if (TYPE_PTRMEM_P (t))
1426 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1427 pp_cxx_left_paren (pp);
1428 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1429 pp_star (pp);
1430 pp_cxx_cv_qualifier_seq (pp, t);
1431 break;
1433 /* fall through. */
1435 default:
1436 pp_unsupported_tree (pp, t);
1437 break;
1441 static inline tree
1442 pp_cxx_implicit_parameter_type (tree mf)
1444 return class_of_this_parm (TREE_TYPE (mf));
1448 parameter-declaration:
1449 decl-specifier-seq declarator
1450 decl-specifier-seq declarator = assignment-expression
1451 decl-specifier-seq abstract-declarator(opt)
1452 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1454 static inline void
1455 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1457 pp->declaration_specifiers (t);
1458 if (TYPE_P (t))
1459 pp->abstract_declarator (t);
1460 else
1461 pp->declarator (t);
1464 /* parameter-declaration-clause:
1465 parameter-declaration-list(opt) ...(opt)
1466 parameter-declaration-list , ...
1468 parameter-declaration-list:
1469 parameter-declaration
1470 parameter-declaration-list , parameter-declaration */
1472 static void
1473 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1475 tree args;
1476 tree types;
1477 bool abstract;
1479 // For a requires clause or the explicit printing of a parameter list
1480 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1481 // args and types are taken from the function decl T.
1482 if (TREE_CODE (t) == PARM_DECL)
1484 args = t;
1485 types = t;
1486 abstract = false;
1488 else
1490 bool type_p = TYPE_P (t);
1491 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1492 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1493 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1495 bool first = true;
1497 /* Skip artificial parameter for nonstatic member functions. */
1498 if (TREE_CODE (t) == METHOD_TYPE)
1499 types = TREE_CHAIN (types);
1501 pp_cxx_left_paren (pp);
1502 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1504 if (!first)
1505 pp_cxx_separate_with (pp, ',');
1506 first = false;
1507 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1508 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1510 pp_cxx_whitespace (pp);
1511 pp_equal (pp);
1512 pp_cxx_whitespace (pp);
1513 pp->assignment_expression (TREE_PURPOSE (types));
1516 pp_cxx_right_paren (pp);
1519 /* exception-specification:
1520 throw ( type-id-list(opt) )
1522 type-id-list
1523 type-id
1524 type-id-list , type-id */
1526 static void
1527 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1529 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1530 bool need_comma = false;
1532 if (ex_spec == NULL)
1533 return;
1534 if (TREE_PURPOSE (ex_spec))
1536 pp_cxx_ws_string (pp, "noexcept");
1537 pp_cxx_whitespace (pp);
1538 pp_cxx_left_paren (pp);
1539 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1540 pp_cxx_ws_string (pp, "<uninstantiated>");
1541 else
1542 pp->expression (TREE_PURPOSE (ex_spec));
1543 pp_cxx_right_paren (pp);
1544 return;
1546 pp_cxx_ws_string (pp, "throw");
1547 pp_cxx_left_paren (pp);
1548 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1550 tree type = TREE_VALUE (ex_spec);
1551 tree argpack = NULL_TREE;
1552 int i, len = 1;
1554 if (ARGUMENT_PACK_P (type))
1556 argpack = ARGUMENT_PACK_ARGS (type);
1557 len = TREE_VEC_LENGTH (argpack);
1560 for (i = 0; i < len; ++i)
1562 if (argpack)
1563 type = TREE_VEC_ELT (argpack, i);
1565 if (need_comma)
1566 pp_cxx_separate_with (pp, ',');
1567 else
1568 need_comma = true;
1570 pp->type_id (type);
1573 pp_cxx_right_paren (pp);
1576 /* direct-declarator:
1577 declarator-id
1578 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1579 exception-specification(opt)
1580 direct-declaration [ constant-expression(opt) ]
1581 ( declarator ) */
1583 void
1584 cxx_pretty_printer::direct_declarator (tree t)
1586 switch (TREE_CODE (t))
1588 case VAR_DECL:
1589 case PARM_DECL:
1590 case CONST_DECL:
1591 case FIELD_DECL:
1592 if (DECL_NAME (t))
1594 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1596 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1597 || template_parameter_pack_p (t))
1598 /* A function parameter pack or non-type template
1599 parameter pack. */
1600 pp_cxx_ws_string (this, "...");
1602 id_expression (DECL_NAME (t));
1604 abstract_declarator (TREE_TYPE (t));
1605 break;
1607 case FUNCTION_DECL:
1608 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1609 expression (t);
1610 pp_cxx_parameter_declaration_clause (this, t);
1612 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1614 padding = pp_before;
1615 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1618 pp_cxx_exception_specification (this, TREE_TYPE (t));
1619 break;
1621 case TYPENAME_TYPE:
1622 case TEMPLATE_DECL:
1623 case TEMPLATE_TYPE_PARM:
1624 case TEMPLATE_PARM_INDEX:
1625 case TEMPLATE_TEMPLATE_PARM:
1626 break;
1628 default:
1629 c_pretty_printer::direct_declarator (t);
1630 break;
1634 /* declarator:
1635 direct-declarator
1636 ptr-operator declarator */
1638 void
1639 cxx_pretty_printer::declarator (tree t)
1641 direct_declarator (t);
1643 // Print a requires clause.
1644 if (flag_concepts)
1645 if (tree ci = get_constraints (t))
1646 if (tree reqs = CI_DECLARATOR_REQS (ci))
1647 pp_cxx_requires_clause (this, reqs);
1650 /* ctor-initializer:
1651 : mem-initializer-list
1653 mem-initializer-list:
1654 mem-initializer
1655 mem-initializer , mem-initializer-list
1657 mem-initializer:
1658 mem-initializer-id ( expression-list(opt) )
1660 mem-initializer-id:
1661 ::(opt) nested-name-specifier(opt) class-name
1662 identifier */
1664 static void
1665 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1667 t = TREE_OPERAND (t, 0);
1668 pp_cxx_whitespace (pp);
1669 pp_colon (pp);
1670 pp_cxx_whitespace (pp);
1671 for (; t; t = TREE_CHAIN (t))
1673 tree purpose = TREE_PURPOSE (t);
1674 bool is_pack = PACK_EXPANSION_P (purpose);
1676 if (is_pack)
1677 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1678 else
1679 pp->primary_expression (purpose);
1680 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1681 if (is_pack)
1682 pp_cxx_ws_string (pp, "...");
1683 if (TREE_CHAIN (t))
1684 pp_cxx_separate_with (pp, ',');
1688 /* function-definition:
1689 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1690 decl-specifier-seq(opt) declarator function-try-block */
1692 static void
1693 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1695 tree saved_scope = pp->enclosing_scope;
1696 pp->declaration_specifiers (t);
1697 pp->declarator (t);
1698 pp_needs_newline (pp) = true;
1699 pp->enclosing_scope = DECL_CONTEXT (t);
1700 if (DECL_SAVED_TREE (t))
1701 pp->statement (DECL_SAVED_TREE (t));
1702 else
1703 pp_cxx_semicolon (pp);
1704 pp_newline_and_flush (pp);
1705 pp->enclosing_scope = saved_scope;
1708 /* abstract-declarator:
1709 ptr-operator abstract-declarator(opt)
1710 direct-abstract-declarator */
1712 void
1713 cxx_pretty_printer::abstract_declarator (tree t)
1715 if (TYPE_PTRMEM_P (t))
1716 pp_cxx_right_paren (this);
1717 else if (POINTER_TYPE_P (t))
1719 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1720 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1721 pp_cxx_right_paren (this);
1722 t = TREE_TYPE (t);
1724 direct_abstract_declarator (t);
1727 /* direct-abstract-declarator:
1728 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1729 cv-qualifier-seq(opt) exception-specification(opt)
1730 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1731 ( abstract-declarator ) */
1733 void
1734 cxx_pretty_printer::direct_abstract_declarator (tree t)
1736 switch (TREE_CODE (t))
1738 case REFERENCE_TYPE:
1739 abstract_declarator (t);
1740 break;
1742 case RECORD_TYPE:
1743 if (TYPE_PTRMEMFUNC_P (t))
1744 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1745 break;
1747 case METHOD_TYPE:
1748 case FUNCTION_TYPE:
1749 pp_cxx_parameter_declaration_clause (this, t);
1750 direct_abstract_declarator (TREE_TYPE (t));
1751 if (TREE_CODE (t) == METHOD_TYPE)
1753 padding = pp_before;
1754 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1756 pp_cxx_exception_specification (this, t);
1757 break;
1759 case TYPENAME_TYPE:
1760 case TEMPLATE_TYPE_PARM:
1761 case TEMPLATE_TEMPLATE_PARM:
1762 case BOUND_TEMPLATE_TEMPLATE_PARM:
1763 case UNBOUND_CLASS_TEMPLATE:
1764 break;
1766 default:
1767 c_pretty_printer::direct_abstract_declarator (t);
1768 break;
1772 /* type-id:
1773 type-specifier-seq abstract-declarator(opt) */
1775 void
1776 cxx_pretty_printer::type_id (tree t)
1778 pp_flags saved_flags = flags;
1779 flags |= pp_c_flag_abstract;
1781 switch (TREE_CODE (t))
1783 case TYPE_DECL:
1784 case UNION_TYPE:
1785 case RECORD_TYPE:
1786 case ENUMERAL_TYPE:
1787 case TYPENAME_TYPE:
1788 case BOUND_TEMPLATE_TEMPLATE_PARM:
1789 case UNBOUND_CLASS_TEMPLATE:
1790 case TEMPLATE_TEMPLATE_PARM:
1791 case TEMPLATE_TYPE_PARM:
1792 case TEMPLATE_PARM_INDEX:
1793 case TEMPLATE_DECL:
1794 case TYPEOF_TYPE:
1795 case UNDERLYING_TYPE:
1796 case DECLTYPE_TYPE:
1797 case TEMPLATE_ID_EXPR:
1798 pp_cxx_type_specifier_seq (this, t);
1799 break;
1801 case TYPE_PACK_EXPANSION:
1802 type_id (PACK_EXPANSION_PATTERN (t));
1803 pp_cxx_ws_string (this, "...");
1804 break;
1806 default:
1807 c_pretty_printer::type_id (t);
1808 break;
1811 flags = saved_flags;
1814 /* template-argument-list:
1815 template-argument ...(opt)
1816 template-argument-list, template-argument ...(opt)
1818 template-argument:
1819 assignment-expression
1820 type-id
1821 template-name */
1823 static void
1824 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1826 int i;
1827 bool need_comma = false;
1829 if (t == NULL)
1830 return;
1831 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1833 tree arg = TREE_VEC_ELT (t, i);
1834 tree argpack = NULL_TREE;
1835 int idx, len = 1;
1837 if (ARGUMENT_PACK_P (arg))
1839 argpack = ARGUMENT_PACK_ARGS (arg);
1840 len = TREE_VEC_LENGTH (argpack);
1843 for (idx = 0; idx < len; idx++)
1845 if (argpack)
1846 arg = TREE_VEC_ELT (argpack, idx);
1848 if (need_comma)
1849 pp_cxx_separate_with (pp, ',');
1850 else
1851 need_comma = true;
1853 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1854 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1855 pp->type_id (arg);
1856 else
1857 pp->expression (arg);
1863 static void
1864 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1866 t = DECL_EXPR_DECL (t);
1867 pp_cxx_type_specifier_seq (pp, t);
1868 if (TYPE_P (t))
1869 pp->abstract_declarator (t);
1870 else
1871 pp->declarator (t);
1874 /* Statements. */
1876 void
1877 cxx_pretty_printer::statement (tree t)
1879 switch (TREE_CODE (t))
1881 case CTOR_INITIALIZER:
1882 pp_cxx_ctor_initializer (this, t);
1883 break;
1885 case USING_STMT:
1886 pp_cxx_ws_string (this, "using");
1887 pp_cxx_ws_string (this, "namespace");
1888 if (DECL_CONTEXT (t))
1889 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1890 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1891 break;
1893 case USING_DECL:
1894 pp_cxx_ws_string (this, "using");
1895 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1896 pp_cxx_unqualified_id (this, DECL_NAME (t));
1897 break;
1899 case EH_SPEC_BLOCK:
1900 break;
1902 /* try-block:
1903 try compound-statement handler-seq */
1904 case TRY_BLOCK:
1905 pp_maybe_newline_and_indent (this, 0);
1906 pp_cxx_ws_string (this, "try");
1907 pp_newline_and_indent (this, 3);
1908 statement (TRY_STMTS (t));
1909 pp_newline_and_indent (this, -3);
1910 if (CLEANUP_P (t))
1912 else
1913 statement (TRY_HANDLERS (t));
1914 break;
1917 handler-seq:
1918 handler handler-seq(opt)
1920 handler:
1921 catch ( exception-declaration ) compound-statement
1923 exception-declaration:
1924 type-specifier-seq declarator
1925 type-specifier-seq abstract-declarator
1926 ... */
1927 case HANDLER:
1928 pp_cxx_ws_string (this, "catch");
1929 pp_cxx_left_paren (this);
1930 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1931 pp_cxx_right_paren (this);
1932 pp_indentation (this) += 3;
1933 pp_needs_newline (this) = true;
1934 statement (HANDLER_BODY (t));
1935 pp_indentation (this) -= 3;
1936 pp_needs_newline (this) = true;
1937 break;
1939 /* selection-statement:
1940 if ( expression ) statement
1941 if ( expression ) statement else statement */
1942 case IF_STMT:
1943 pp_cxx_ws_string (this, "if");
1944 pp_cxx_whitespace (this);
1945 pp_cxx_left_paren (this);
1946 expression (IF_COND (t));
1947 pp_cxx_right_paren (this);
1948 pp_newline_and_indent (this, 2);
1949 statement (THEN_CLAUSE (t));
1950 pp_newline_and_indent (this, -2);
1951 if (ELSE_CLAUSE (t))
1953 tree else_clause = ELSE_CLAUSE (t);
1954 pp_cxx_ws_string (this, "else");
1955 if (TREE_CODE (else_clause) == IF_STMT)
1956 pp_cxx_whitespace (this);
1957 else
1958 pp_newline_and_indent (this, 2);
1959 statement (else_clause);
1960 if (TREE_CODE (else_clause) != IF_STMT)
1961 pp_newline_and_indent (this, -2);
1963 break;
1965 case SWITCH_STMT:
1966 pp_cxx_ws_string (this, "switch");
1967 pp_space (this);
1968 pp_cxx_left_paren (this);
1969 expression (SWITCH_STMT_COND (t));
1970 pp_cxx_right_paren (this);
1971 pp_indentation (this) += 3;
1972 pp_needs_newline (this) = true;
1973 statement (SWITCH_STMT_BODY (t));
1974 pp_newline_and_indent (this, -3);
1975 break;
1977 /* iteration-statement:
1978 while ( expression ) statement
1979 do statement while ( expression ) ;
1980 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1981 for ( declaration expression(opt) ; expression(opt) ) statement */
1982 case WHILE_STMT:
1983 pp_cxx_ws_string (this, "while");
1984 pp_space (this);
1985 pp_cxx_left_paren (this);
1986 expression (WHILE_COND (t));
1987 pp_cxx_right_paren (this);
1988 pp_newline_and_indent (this, 3);
1989 statement (WHILE_BODY (t));
1990 pp_indentation (this) -= 3;
1991 pp_needs_newline (this) = true;
1992 break;
1994 case DO_STMT:
1995 pp_cxx_ws_string (this, "do");
1996 pp_newline_and_indent (this, 3);
1997 statement (DO_BODY (t));
1998 pp_newline_and_indent (this, -3);
1999 pp_cxx_ws_string (this, "while");
2000 pp_space (this);
2001 pp_cxx_left_paren (this);
2002 expression (DO_COND (t));
2003 pp_cxx_right_paren (this);
2004 pp_cxx_semicolon (this);
2005 pp_needs_newline (this) = true;
2006 break;
2008 case FOR_STMT:
2009 pp_cxx_ws_string (this, "for");
2010 pp_space (this);
2011 pp_cxx_left_paren (this);
2012 if (FOR_INIT_STMT (t))
2013 statement (FOR_INIT_STMT (t));
2014 else
2015 pp_cxx_semicolon (this);
2016 pp_needs_newline (this) = false;
2017 pp_cxx_whitespace (this);
2018 if (FOR_COND (t))
2019 expression (FOR_COND (t));
2020 pp_cxx_semicolon (this);
2021 pp_needs_newline (this) = false;
2022 pp_cxx_whitespace (this);
2023 if (FOR_EXPR (t))
2024 expression (FOR_EXPR (t));
2025 pp_cxx_right_paren (this);
2026 pp_newline_and_indent (this, 3);
2027 statement (FOR_BODY (t));
2028 pp_indentation (this) -= 3;
2029 pp_needs_newline (this) = true;
2030 break;
2032 case RANGE_FOR_STMT:
2033 pp_cxx_ws_string (this, "for");
2034 pp_space (this);
2035 pp_cxx_left_paren (this);
2036 statement (RANGE_FOR_DECL (t));
2037 pp_space (this);
2038 pp_needs_newline (this) = false;
2039 pp_colon (this);
2040 pp_space (this);
2041 statement (RANGE_FOR_EXPR (t));
2042 pp_cxx_right_paren (this);
2043 pp_newline_and_indent (this, 3);
2044 statement (FOR_BODY (t));
2045 pp_indentation (this) -= 3;
2046 pp_needs_newline (this) = true;
2047 break;
2049 /* jump-statement:
2050 goto identifier;
2051 continue ;
2052 return expression(opt) ; */
2053 case BREAK_STMT:
2054 case CONTINUE_STMT:
2055 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2056 pp_cxx_semicolon (this);
2057 pp_needs_newline (this) = true;
2058 break;
2060 /* expression-statement:
2061 expression(opt) ; */
2062 case EXPR_STMT:
2063 expression (EXPR_STMT_EXPR (t));
2064 pp_cxx_semicolon (this);
2065 pp_needs_newline (this) = true;
2066 break;
2068 case CLEANUP_STMT:
2069 pp_cxx_ws_string (this, "try");
2070 pp_newline_and_indent (this, 2);
2071 statement (CLEANUP_BODY (t));
2072 pp_newline_and_indent (this, -2);
2073 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2074 pp_newline_and_indent (this, 2);
2075 statement (CLEANUP_EXPR (t));
2076 pp_newline_and_indent (this, -2);
2077 break;
2079 case STATIC_ASSERT:
2080 declaration (t);
2081 break;
2083 default:
2084 c_pretty_printer::statement (t);
2085 break;
2089 /* original-namespace-definition:
2090 namespace identifier { namespace-body }
2092 As an edge case, we also handle unnamed namespace definition here. */
2094 static void
2095 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2097 pp_cxx_ws_string (pp, "namespace");
2098 if (DECL_CONTEXT (t))
2099 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2100 if (DECL_NAME (t))
2101 pp_cxx_unqualified_id (pp, t);
2102 pp_cxx_whitespace (pp);
2103 pp_cxx_left_brace (pp);
2104 /* We do not print the namespace-body. */
2105 pp_cxx_whitespace (pp);
2106 pp_cxx_right_brace (pp);
2109 /* namespace-alias:
2110 identifier
2112 namespace-alias-definition:
2113 namespace identifier = qualified-namespace-specifier ;
2115 qualified-namespace-specifier:
2116 ::(opt) nested-name-specifier(opt) namespace-name */
2118 static void
2119 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2121 pp_cxx_ws_string (pp, "namespace");
2122 if (DECL_CONTEXT (t))
2123 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2124 pp_cxx_unqualified_id (pp, t);
2125 pp_cxx_whitespace (pp);
2126 pp_equal (pp);
2127 pp_cxx_whitespace (pp);
2128 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2129 pp_cxx_nested_name_specifier (pp,
2130 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2131 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2132 pp_cxx_semicolon (pp);
2135 /* simple-declaration:
2136 decl-specifier-seq(opt) init-declarator-list(opt) */
2138 static void
2139 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2141 pp->declaration_specifiers (t);
2142 pp_cxx_init_declarator (pp, t);
2143 pp_cxx_semicolon (pp);
2144 pp_needs_newline (pp) = true;
2148 template-parameter-list:
2149 template-parameter
2150 template-parameter-list , template-parameter */
2152 static inline void
2153 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2155 const int n = TREE_VEC_LENGTH (t);
2156 int i;
2157 for (i = 0; i < n; ++i)
2159 if (i)
2160 pp_cxx_separate_with (pp, ',');
2161 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2165 /* template-parameter:
2166 type-parameter
2167 parameter-declaration
2169 type-parameter:
2170 class ...(opt) identifier(opt)
2171 class identifier(opt) = type-id
2172 typename identifier(opt)
2173 typename ...(opt) identifier(opt) = type-id
2174 template < template-parameter-list > class ...(opt) identifier(opt)
2175 template < template-parameter-list > class identifier(opt) = template-name */
2177 static void
2178 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2180 tree parameter = TREE_VALUE (t);
2181 switch (TREE_CODE (parameter))
2183 case TYPE_DECL:
2184 pp_cxx_ws_string (pp, "class");
2185 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2186 pp_cxx_ws_string (pp, "...");
2187 if (DECL_NAME (parameter))
2188 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2189 /* FIXME: Check if we should print also default argument. */
2190 break;
2192 case PARM_DECL:
2193 pp_cxx_parameter_declaration (pp, parameter);
2194 break;
2196 case TEMPLATE_DECL:
2197 break;
2199 default:
2200 pp_unsupported_tree (pp, t);
2201 break;
2205 /* Pretty-print a template parameter in the canonical form
2206 "template-parameter-<level>-<position in parameter list>". */
2208 void
2209 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2211 const enum tree_code code = TREE_CODE (parm);
2213 /* Brings type template parameters to the canonical forms. */
2214 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2215 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2216 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2218 pp_cxx_begin_template_argument_list (pp);
2219 pp->translate_string ("template-parameter-");
2220 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2221 pp_minus (pp);
2222 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2223 pp_cxx_end_template_argument_list (pp);
2226 /* Print a constrained-type-specifier. */
2228 void
2229 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2231 tree t, a;
2232 if (c == error_mark_node)
2234 pp_cxx_ws_string(pp, "<unsatisfied-constrained-placeholder>");
2235 return;
2237 placeholder_extract_concept_and_args (c, t, a);
2238 pp->id_expression (t);
2239 if (TREE_VEC_LENGTH (a) > 1)
2241 pp_cxx_begin_template_argument_list (pp);
2242 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2243 for (int i = TREE_VEC_LENGTH (a) - 1; i > 0; --i)
2244 TREE_VEC_ELT (args, i-1) = TREE_VEC_ELT (a, i);
2245 pp_cxx_template_argument_list (pp, args);
2246 ggc_free (args);
2247 pp_cxx_end_template_argument_list (pp);
2252 template-declaration:
2253 export(opt) template < template-parameter-list > declaration
2255 Concept extensions:
2257 template-declaration:
2258 export(opt) template < template-parameter-list >
2259 requires-clause(opt) declaration */
2261 static void
2262 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2264 tree tmpl = most_general_template (t);
2265 tree level;
2267 pp_maybe_newline_and_indent (pp, 0);
2268 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2270 pp_cxx_ws_string (pp, "template");
2271 pp_cxx_begin_template_argument_list (pp);
2272 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2273 pp_cxx_end_template_argument_list (pp);
2274 pp_newline_and_indent (pp, 3);
2277 if (flag_concepts)
2278 if (tree ci = get_constraints (t))
2279 if (tree reqs = CI_TEMPLATE_REQS (ci))
2281 pp_cxx_requires_clause (pp, reqs);
2282 pp_newline_and_indent (pp, 6);
2285 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2286 pp_cxx_function_definition (pp, t);
2287 else
2288 pp_cxx_simple_declaration (pp, t);
2291 static void
2292 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2294 pp_unsupported_tree (pp, t);
2297 static void
2298 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2300 pp_unsupported_tree (pp, t);
2304 declaration:
2305 block-declaration
2306 function-definition
2307 template-declaration
2308 explicit-instantiation
2309 explicit-specialization
2310 linkage-specification
2311 namespace-definition
2313 block-declaration:
2314 simple-declaration
2315 asm-definition
2316 namespace-alias-definition
2317 using-declaration
2318 using-directive
2319 static_assert-declaration */
2320 void
2321 cxx_pretty_printer::declaration (tree t)
2323 if (TREE_CODE (t) == STATIC_ASSERT)
2325 pp_cxx_ws_string (this, "static_assert");
2326 pp_cxx_left_paren (this);
2327 expression (STATIC_ASSERT_CONDITION (t));
2328 pp_cxx_separate_with (this, ',');
2329 expression (STATIC_ASSERT_MESSAGE (t));
2330 pp_cxx_right_paren (this);
2332 else if (!DECL_LANG_SPECIFIC (t))
2333 pp_cxx_simple_declaration (this, t);
2334 else if (DECL_USE_TEMPLATE (t))
2335 switch (DECL_USE_TEMPLATE (t))
2337 case 1:
2338 pp_cxx_template_declaration (this, t);
2339 break;
2341 case 2:
2342 pp_cxx_explicit_specialization (this, t);
2343 break;
2345 case 3:
2346 pp_cxx_explicit_instantiation (this, t);
2347 break;
2349 default:
2350 break;
2352 else switch (TREE_CODE (t))
2354 case VAR_DECL:
2355 case TYPE_DECL:
2356 pp_cxx_simple_declaration (this, t);
2357 break;
2359 case FUNCTION_DECL:
2360 if (DECL_SAVED_TREE (t))
2361 pp_cxx_function_definition (this, t);
2362 else
2363 pp_cxx_simple_declaration (this, t);
2364 break;
2366 case NAMESPACE_DECL:
2367 if (DECL_NAMESPACE_ALIAS (t))
2368 pp_cxx_namespace_alias_definition (this, t);
2369 else
2370 pp_cxx_original_namespace_definition (this, t);
2371 break;
2373 default:
2374 pp_unsupported_tree (this, t);
2375 break;
2379 static void
2380 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2382 t = TREE_OPERAND (t, 0);
2383 pp_cxx_ws_string (pp, "typeid");
2384 pp_cxx_left_paren (pp);
2385 if (TYPE_P (t))
2386 pp->type_id (t);
2387 else
2388 pp->expression (t);
2389 pp_cxx_right_paren (pp);
2392 void
2393 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2395 pp_cxx_ws_string (pp, "va_arg");
2396 pp_cxx_left_paren (pp);
2397 pp->assignment_expression (TREE_OPERAND (t, 0));
2398 pp_cxx_separate_with (pp, ',');
2399 pp->type_id (TREE_TYPE (t));
2400 pp_cxx_right_paren (pp);
2403 static bool
2404 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2406 switch (TREE_CODE (t))
2408 case ARROW_EXPR:
2409 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2410 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2412 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2413 pp_cxx_separate_with (pp, ',');
2414 return true;
2416 return false;
2417 case COMPONENT_REF:
2418 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2419 return false;
2420 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2421 pp_cxx_dot (pp);
2422 pp->expression (TREE_OPERAND (t, 1));
2423 return true;
2424 case ARRAY_REF:
2425 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2426 return false;
2427 pp_left_bracket (pp);
2428 pp->expression (TREE_OPERAND (t, 1));
2429 pp_right_bracket (pp);
2430 return true;
2431 default:
2432 return false;
2436 void
2437 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2439 pp_cxx_ws_string (pp, "offsetof");
2440 pp_cxx_left_paren (pp);
2441 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2442 pp->expression (TREE_OPERAND (t, 0));
2443 pp_cxx_right_paren (pp);
2446 void
2447 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2449 pp_cxx_ws_string (pp, "__builtin_addressof");
2450 pp_cxx_left_paren (pp);
2451 pp->expression (TREE_OPERAND (t, 0));
2452 pp_cxx_right_paren (pp);
2455 static char const*
2456 get_fold_operator (tree t)
2458 int op = int_cst_value (FOLD_EXPR_OP (t));
2459 if (FOLD_EXPR_MODIFY_P (t))
2461 switch (op)
2463 case NOP_EXPR: return "=";
2464 case PLUS_EXPR: return "+=";
2465 case MINUS_EXPR: return "-=";
2466 case MULT_EXPR: return "*=";
2467 case TRUNC_DIV_EXPR: return "/=";
2468 case TRUNC_MOD_EXPR: return "%=";
2469 case BIT_XOR_EXPR: return "^=";
2470 case BIT_AND_EXPR: return "&=";
2471 case BIT_IOR_EXPR: return "|=";
2472 case LSHIFT_EXPR: return "<<=";
2473 case RSHIFT_EXPR: return ">>=";
2474 default: gcc_unreachable ();
2477 else
2479 switch (op)
2481 case PLUS_EXPR: return "+";
2482 case MINUS_EXPR: return "-";
2483 case MULT_EXPR: return "*";
2484 case TRUNC_DIV_EXPR: return "/";
2485 case TRUNC_MOD_EXPR: return "%";
2486 case BIT_XOR_EXPR: return "^";
2487 case BIT_AND_EXPR: return "&";
2488 case BIT_IOR_EXPR: return "|";
2489 case LSHIFT_EXPR: return "<<";
2490 case RSHIFT_EXPR: return ">>";
2491 case EQ_EXPR: return "==";
2492 case NE_EXPR: return "!=";
2493 case LT_EXPR: return "<";
2494 case GT_EXPR: return ">";
2495 case LE_EXPR: return "<=";
2496 case GE_EXPR: return ">=";
2497 case TRUTH_ANDIF_EXPR: return "&&";
2498 case TRUTH_ORIF_EXPR: return "||";
2499 case MEMBER_REF: return "->*";
2500 case DOTSTAR_EXPR: return ".*";
2501 case OFFSET_REF: return ".*";
2502 default: return ","; /* FIXME: Not the right default. */
2507 void
2508 pp_cxx_unary_left_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_cxx_ws_string (pp, "...");
2514 pp_cxx_ws_string (pp, op);
2515 pp->expression (expr);
2516 pp_cxx_right_paren (pp);
2519 void
2520 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2522 char const* op = get_fold_operator (t);
2523 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2524 pp_cxx_left_paren (pp);
2525 pp->expression (expr);
2526 pp_space (pp);
2527 pp_cxx_ws_string (pp, op);
2528 pp_cxx_ws_string (pp, "...");
2529 pp_cxx_right_paren (pp);
2532 void
2533 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2535 char const* op = get_fold_operator (t);
2536 tree t1 = TREE_OPERAND (t, 1);
2537 tree t2 = TREE_OPERAND (t, 2);
2538 if (t1 == FOLD_EXPR_PACK (t))
2539 t1 = PACK_EXPANSION_PATTERN (t1);
2540 else
2541 t2 = PACK_EXPANSION_PATTERN (t2);
2542 pp_cxx_left_paren (pp);
2543 pp->expression (t1);
2544 pp_cxx_ws_string (pp, op);
2545 pp_cxx_ws_string (pp, "...");
2546 pp_cxx_ws_string (pp, op);
2547 pp->expression (t2);
2548 pp_cxx_right_paren (pp);
2551 void
2552 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2554 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2556 switch (kind)
2558 case CPTK_HAS_NOTHROW_ASSIGN:
2559 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2560 break;
2561 case CPTK_HAS_TRIVIAL_ASSIGN:
2562 pp_cxx_ws_string (pp, "__has_trivial_assign");
2563 break;
2564 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2565 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2566 break;
2567 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2568 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2569 break;
2570 case CPTK_HAS_NOTHROW_COPY:
2571 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2572 break;
2573 case CPTK_HAS_TRIVIAL_COPY:
2574 pp_cxx_ws_string (pp, "__has_trivial_copy");
2575 break;
2576 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2577 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2578 break;
2579 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
2580 pp_cxx_ws_string (pp, "__has_unique_object_representations");
2581 break;
2582 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2583 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2584 break;
2585 case CPTK_IS_ABSTRACT:
2586 pp_cxx_ws_string (pp, "__is_abstract");
2587 break;
2588 case CPTK_IS_BASE_OF:
2589 pp_cxx_ws_string (pp, "__is_base_of");
2590 break;
2591 case CPTK_IS_CLASS:
2592 pp_cxx_ws_string (pp, "__is_class");
2593 break;
2594 case CPTK_IS_EMPTY:
2595 pp_cxx_ws_string (pp, "__is_empty");
2596 break;
2597 case CPTK_IS_ENUM:
2598 pp_cxx_ws_string (pp, "__is_enum");
2599 break;
2600 case CPTK_IS_FINAL:
2601 pp_cxx_ws_string (pp, "__is_final");
2602 break;
2603 case CPTK_IS_POD:
2604 pp_cxx_ws_string (pp, "__is_pod");
2605 break;
2606 case CPTK_IS_POLYMORPHIC:
2607 pp_cxx_ws_string (pp, "__is_polymorphic");
2608 break;
2609 case CPTK_IS_SAME_AS:
2610 pp_cxx_ws_string (pp, "__is_same_as");
2611 break;
2612 case CPTK_IS_STD_LAYOUT:
2613 pp_cxx_ws_string (pp, "__is_std_layout");
2614 break;
2615 case CPTK_IS_TRIVIAL:
2616 pp_cxx_ws_string (pp, "__is_trivial");
2617 break;
2618 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2619 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2620 break;
2621 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2622 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2623 break;
2624 case CPTK_IS_TRIVIALLY_COPYABLE:
2625 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2626 break;
2627 case CPTK_IS_UNION:
2628 pp_cxx_ws_string (pp, "__is_union");
2629 break;
2630 case CPTK_IS_LITERAL_TYPE:
2631 pp_cxx_ws_string (pp, "__is_literal_type");
2632 break;
2634 default:
2635 gcc_unreachable ();
2638 pp_cxx_left_paren (pp);
2639 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2641 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2643 pp_cxx_separate_with (pp, ',');
2644 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2647 pp_cxx_right_paren (pp);
2650 // requires-clause:
2651 // 'requires' logical-or-expression
2652 void
2653 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2655 if (!t)
2656 return;
2657 pp->padding = pp_before;
2658 pp_cxx_ws_string (pp, "requires");
2659 pp_space (pp);
2660 pp->expression (t);
2663 /* requirement:
2664 simple-requirement
2665 compound-requirement
2666 type-requirement
2667 nested-requirement */
2668 static void
2669 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2671 switch (TREE_CODE (t))
2673 case SIMPLE_REQ:
2674 pp_cxx_simple_requirement (pp, t);
2675 break;
2677 case TYPE_REQ:
2678 pp_cxx_type_requirement (pp, t);
2679 break;
2681 case COMPOUND_REQ:
2682 pp_cxx_compound_requirement (pp, t);
2683 break;
2685 case NESTED_REQ:
2686 pp_cxx_nested_requirement (pp, t);
2687 break;
2689 default:
2690 gcc_unreachable ();
2694 // requirement-list:
2695 // requirement
2696 // requirement-list ';' requirement[opt]
2698 static void
2699 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2701 for (; t; t = TREE_CHAIN (t))
2702 pp_cxx_requirement (pp, TREE_VALUE (t));
2705 // requirement-body:
2706 // '{' requirement-list '}'
2707 static void
2708 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2710 pp_cxx_left_brace (pp);
2711 pp_cxx_requirement_list (pp, t);
2712 pp_cxx_right_brace (pp);
2715 // requires-expression:
2716 // 'requires' requirement-parameter-list requirement-body
2717 void
2718 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2720 pp_string (pp, "requires");
2721 if (tree parms = TREE_OPERAND (t, 0))
2723 pp_cxx_parameter_declaration_clause (pp, parms);
2724 pp_cxx_whitespace (pp);
2726 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2729 /* simple-requirement:
2730 expression ';' */
2731 void
2732 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2734 pp->expression (TREE_OPERAND (t, 0));
2735 pp_cxx_semicolon (pp);
2738 /* type-requirement:
2739 typename type-name ';' */
2740 void
2741 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2743 pp->type_id (TREE_OPERAND (t, 0));
2744 pp_cxx_semicolon (pp);
2747 /* compound-requirement:
2748 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2749 void
2750 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2752 pp_cxx_left_brace (pp);
2753 pp->expression (TREE_OPERAND (t, 0));
2754 pp_cxx_right_brace (pp);
2756 if (COMPOUND_REQ_NOEXCEPT_P (t))
2757 pp_cxx_ws_string (pp, "noexcept");
2759 if (tree type = TREE_OPERAND (t, 1))
2761 pp_cxx_ws_string (pp, "->");
2762 pp->type_id (type);
2764 pp_cxx_semicolon (pp);
2767 /* nested requirement:
2768 'requires' constraint-expression */
2769 void
2770 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2772 pp_cxx_ws_string (pp, "requires");
2773 pp->expression (TREE_OPERAND (t, 0));
2774 pp_cxx_semicolon (pp);
2777 void
2778 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2780 pp->expression (TREE_OPERAND (t, 0));
2783 void
2784 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2786 tree decl = CHECK_CONSTR_CONCEPT (t);
2787 tree tmpl = DECL_TI_TEMPLATE (decl);
2788 tree args = CHECK_CONSTR_ARGS (t);
2789 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2791 if (VAR_P (decl))
2792 pp->expression (id);
2793 else if (TREE_CODE (decl) == FUNCTION_DECL)
2795 tree call = build_vl_exp (CALL_EXPR, 2);
2796 TREE_OPERAND (call, 0) = integer_two_node;
2797 TREE_OPERAND (call, 1) = id;
2798 pp->expression (call);
2800 else
2801 gcc_unreachable ();
2804 void
2805 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2807 pp_string (pp, "<valid-expression ");
2808 pp_cxx_left_paren (pp);
2809 pp->expression (TREE_OPERAND (t, 0));
2810 pp_cxx_right_paren (pp);
2811 pp_string (pp, ">");
2814 void
2815 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2817 pp_string (pp, "<valid-type ");
2818 pp->type_id (TREE_OPERAND (t, 0));
2819 pp_string (pp, ">");
2822 void
2823 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2825 pp_string (pp, "<implicitly-conversion ");
2826 pp_cxx_left_paren (pp);
2827 pp->expression (ICONV_CONSTR_EXPR (t));
2828 pp_cxx_right_paren (pp);
2829 pp_cxx_ws_string (pp, "to");
2830 pp->type_id (ICONV_CONSTR_TYPE (t));
2831 pp_string (pp, ">");
2834 void
2835 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2837 pp_string (pp, "<argument-deduction ");
2838 pp_cxx_left_paren (pp);
2839 pp->expression (DEDUCT_CONSTR_EXPR (t));
2840 pp_cxx_right_paren (pp);
2841 pp_cxx_ws_string (pp, "as");
2842 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2843 pp_string (pp, ">");
2846 void
2847 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2849 pp_cxx_ws_string (pp, "noexcept");
2850 pp_cxx_whitespace (pp);
2851 pp_cxx_left_paren (pp);
2852 pp->expression (TREE_OPERAND (t, 0));
2853 pp_cxx_right_paren (pp);
2856 void
2857 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2859 pp_left_paren (pp);
2860 pp_string (pp, "<requires ");
2861 if (tree parms = PARM_CONSTR_PARMS (t))
2863 pp_cxx_parameter_declaration_clause (pp, parms);
2864 pp_cxx_whitespace (pp);
2866 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2867 pp_string (pp, ">");
2870 void
2871 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2873 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2874 pp_string (pp, " and ");
2875 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2878 void
2879 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2881 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2882 pp_string (pp, " or ");
2883 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2886 void
2887 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2889 if (t == error_mark_node)
2890 return pp->expression (t);
2892 switch (TREE_CODE (t))
2894 case PRED_CONSTR:
2895 pp_cxx_predicate_constraint (pp, t);
2896 break;
2898 case CHECK_CONSTR:
2899 pp_cxx_check_constraint (pp, t);
2900 break;
2902 case EXPR_CONSTR:
2903 pp_cxx_expression_constraint (pp, t);
2904 break;
2906 case TYPE_CONSTR:
2907 pp_cxx_type_constraint (pp, t);
2908 break;
2910 case ICONV_CONSTR:
2911 pp_cxx_implicit_conversion_constraint (pp, t);
2912 break;
2914 case DEDUCT_CONSTR:
2915 pp_cxx_argument_deduction_constraint (pp, t);
2916 break;
2918 case EXCEPT_CONSTR:
2919 pp_cxx_exception_constraint (pp, t);
2920 break;
2922 case PARM_CONSTR:
2923 pp_cxx_parameterized_constraint (pp, t);
2924 break;
2926 case CONJ_CONSTR:
2927 pp_cxx_conjunction (pp, t);
2928 break;
2930 case DISJ_CONSTR:
2931 pp_cxx_disjunction (pp, t);
2932 break;
2934 case EXPR_PACK_EXPANSION:
2935 pp->expression (TREE_OPERAND (t, 0));
2936 break;
2938 default:
2939 gcc_unreachable ();
2945 typedef c_pretty_print_fn pp_fun;
2947 /* Initialization of a C++ pretty-printer object. */
2949 cxx_pretty_printer::cxx_pretty_printer ()
2950 : c_pretty_printer (),
2951 enclosing_scope (global_namespace)
2953 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2954 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;