libgo: add misc/cgo files
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob5398e3dd87df03ab66b1f431be90233f35e9196e
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_FIRST (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_CONV_OP_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_FIRST (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_FIRST (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_FIRST (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 case UNARY_PLUS_EXPR:
1116 unary_expression (t);
1117 break;
1119 case CAST_EXPR:
1120 case IMPLICIT_CONV_EXPR:
1121 pp_cxx_cast_expression (this, t);
1122 break;
1124 case OFFSET_REF:
1125 case MEMBER_REF:
1126 case DOTSTAR_EXPR:
1127 pp_cxx_pm_expression (this, t);
1128 break;
1130 case MULT_EXPR:
1131 case TRUNC_DIV_EXPR:
1132 case TRUNC_MOD_EXPR:
1133 multiplicative_expression (t);
1134 break;
1136 case COND_EXPR:
1137 conditional_expression (t);
1138 break;
1140 case MODIFY_EXPR:
1141 case INIT_EXPR:
1142 case THROW_EXPR:
1143 case MODOP_EXPR:
1144 assignment_expression (t);
1145 break;
1147 case NON_DEPENDENT_EXPR:
1148 case MUST_NOT_THROW_EXPR:
1149 expression (TREE_OPERAND (t, 0));
1150 break;
1152 case EXPR_PACK_EXPANSION:
1153 expression (PACK_EXPANSION_PATTERN (t));
1154 pp_cxx_ws_string (this, "...");
1155 break;
1157 case UNARY_LEFT_FOLD_EXPR:
1158 pp_cxx_unary_left_fold_expression (this, t);
1159 break;
1161 case UNARY_RIGHT_FOLD_EXPR:
1162 pp_cxx_unary_right_fold_expression (this, t);
1163 break;
1165 case BINARY_LEFT_FOLD_EXPR:
1166 case BINARY_RIGHT_FOLD_EXPR:
1167 pp_cxx_binary_fold_expression (this, t);
1168 break;
1170 case TEMPLATE_ID_EXPR:
1171 pp_cxx_template_id (this, t);
1172 break;
1174 case NONTYPE_ARGUMENT_PACK:
1176 tree args = ARGUMENT_PACK_ARGS (t);
1177 int i, len = TREE_VEC_LENGTH (args);
1178 for (i = 0; i < len; ++i)
1180 if (i > 0)
1181 pp_cxx_separate_with (this, ',');
1182 expression (TREE_VEC_ELT (args, i));
1185 break;
1187 case LAMBDA_EXPR:
1188 pp_cxx_ws_string (this, "<lambda>");
1189 break;
1191 case TRAIT_EXPR:
1192 pp_cxx_trait_expression (this, t);
1193 break;
1195 case PRED_CONSTR:
1196 case CHECK_CONSTR:
1197 case EXPR_CONSTR:
1198 case TYPE_CONSTR:
1199 case ICONV_CONSTR:
1200 case DEDUCT_CONSTR:
1201 case EXCEPT_CONSTR:
1202 case PARM_CONSTR:
1203 case CONJ_CONSTR:
1204 case DISJ_CONSTR:
1205 pp_cxx_constraint (this, t);
1206 break;
1208 case PAREN_EXPR:
1209 pp_cxx_left_paren (this);
1210 expression (TREE_OPERAND (t, 0));
1211 pp_cxx_right_paren (this);
1212 break;
1214 default:
1215 c_pretty_printer::expression (t);
1216 break;
1221 /* Declarations. */
1223 /* function-specifier:
1224 inline
1225 virtual
1226 explicit */
1228 void
1229 cxx_pretty_printer::function_specifier (tree t)
1231 switch (TREE_CODE (t))
1233 case FUNCTION_DECL:
1234 if (DECL_VIRTUAL_P (t))
1235 pp_cxx_ws_string (this, "virtual");
1236 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1237 pp_cxx_ws_string (this, "explicit");
1238 else
1239 c_pretty_printer::function_specifier (t);
1241 default:
1242 break;
1246 /* decl-specifier-seq:
1247 decl-specifier-seq(opt) decl-specifier
1249 decl-specifier:
1250 storage-class-specifier
1251 type-specifier
1252 function-specifier
1253 friend
1254 typedef */
1256 void
1257 cxx_pretty_printer::declaration_specifiers (tree t)
1259 switch (TREE_CODE (t))
1261 case VAR_DECL:
1262 case PARM_DECL:
1263 case CONST_DECL:
1264 case FIELD_DECL:
1265 storage_class_specifier (t);
1266 declaration_specifiers (TREE_TYPE (t));
1267 break;
1269 case TYPE_DECL:
1270 pp_cxx_ws_string (this, "typedef");
1271 declaration_specifiers (TREE_TYPE (t));
1272 break;
1274 case FUNCTION_DECL:
1275 /* Constructors don't have return types. And conversion functions
1276 do not have a type-specifier in their return types. */
1277 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1278 function_specifier (t);
1279 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1280 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1281 else
1282 c_pretty_printer::declaration_specifiers (t);
1283 break;
1284 default:
1285 c_pretty_printer::declaration_specifiers (t);
1286 break;
1290 /* simple-type-specifier:
1291 ::(opt) nested-name-specifier(opt) type-name
1292 ::(opt) nested-name-specifier(opt) template(opt) template-id
1293 char
1294 wchar_t
1295 bool
1296 short
1298 long
1299 signed
1300 unsigned
1301 float
1302 double
1303 void */
1305 void
1306 cxx_pretty_printer::simple_type_specifier (tree t)
1308 switch (TREE_CODE (t))
1310 case RECORD_TYPE:
1311 case UNION_TYPE:
1312 case ENUMERAL_TYPE:
1313 pp_cxx_qualified_id (this, t);
1314 break;
1316 case TEMPLATE_TYPE_PARM:
1317 case TEMPLATE_TEMPLATE_PARM:
1318 case TEMPLATE_PARM_INDEX:
1319 case BOUND_TEMPLATE_TEMPLATE_PARM:
1320 pp_cxx_unqualified_id (this, t);
1321 break;
1323 case TYPENAME_TYPE:
1324 pp_cxx_ws_string (this, "typename");
1325 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1326 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1327 break;
1329 default:
1330 c_pretty_printer::simple_type_specifier (t);
1331 break;
1335 /* type-specifier-seq:
1336 type-specifier type-specifier-seq(opt)
1338 type-specifier:
1339 simple-type-specifier
1340 class-specifier
1341 enum-specifier
1342 elaborated-type-specifier
1343 cv-qualifier */
1345 static void
1346 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1348 switch (TREE_CODE (t))
1350 case TEMPLATE_DECL:
1351 case TEMPLATE_TYPE_PARM:
1352 case TEMPLATE_TEMPLATE_PARM:
1353 case TYPE_DECL:
1354 case BOUND_TEMPLATE_TEMPLATE_PARM:
1355 pp_cxx_cv_qualifier_seq (pp, t);
1356 pp->simple_type_specifier (t);
1357 break;
1359 case METHOD_TYPE:
1360 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1361 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1362 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1363 break;
1365 case DECLTYPE_TYPE:
1366 pp_cxx_ws_string (pp, "decltype");
1367 pp_cxx_left_paren (pp);
1368 pp->expression (DECLTYPE_TYPE_EXPR (t));
1369 pp_cxx_right_paren (pp);
1370 break;
1372 case RECORD_TYPE:
1373 if (TYPE_PTRMEMFUNC_P (t))
1375 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1376 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1377 pp_cxx_whitespace (pp);
1378 pp_cxx_ptr_operator (pp, t);
1379 break;
1381 /* fall through */
1383 default:
1384 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1385 pp_c_specifier_qualifier_list (pp, t);
1389 /* ptr-operator:
1390 * cv-qualifier-seq(opt)
1392 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1394 static void
1395 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1397 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1398 t = TREE_TYPE (t);
1399 switch (TREE_CODE (t))
1401 case REFERENCE_TYPE:
1402 case POINTER_TYPE:
1403 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1404 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1405 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1406 if (TYPE_PTR_P (t))
1408 pp_star (pp);
1409 pp_cxx_cv_qualifier_seq (pp, t);
1411 else
1412 pp_ampersand (pp);
1413 break;
1415 case RECORD_TYPE:
1416 if (TYPE_PTRMEMFUNC_P (t))
1418 pp_cxx_left_paren (pp);
1419 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1420 pp_star (pp);
1421 break;
1423 /* FALLTHRU */
1424 case OFFSET_TYPE:
1425 if (TYPE_PTRMEM_P (t))
1427 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1428 pp_cxx_left_paren (pp);
1429 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1430 pp_star (pp);
1431 pp_cxx_cv_qualifier_seq (pp, t);
1432 break;
1434 /* fall through. */
1436 default:
1437 pp_unsupported_tree (pp, t);
1438 break;
1442 static inline tree
1443 pp_cxx_implicit_parameter_type (tree mf)
1445 return class_of_this_parm (TREE_TYPE (mf));
1449 parameter-declaration:
1450 decl-specifier-seq declarator
1451 decl-specifier-seq declarator = assignment-expression
1452 decl-specifier-seq abstract-declarator(opt)
1453 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1455 static inline void
1456 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1458 pp->declaration_specifiers (t);
1459 if (TYPE_P (t))
1460 pp->abstract_declarator (t);
1461 else
1462 pp->declarator (t);
1465 /* parameter-declaration-clause:
1466 parameter-declaration-list(opt) ...(opt)
1467 parameter-declaration-list , ...
1469 parameter-declaration-list:
1470 parameter-declaration
1471 parameter-declaration-list , parameter-declaration */
1473 static void
1474 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1476 tree args;
1477 tree types;
1478 bool abstract;
1480 // For a requires clause or the explicit printing of a parameter list
1481 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1482 // args and types are taken from the function decl T.
1483 if (TREE_CODE (t) == PARM_DECL)
1485 args = t;
1486 types = t;
1487 abstract = false;
1489 else
1491 bool type_p = TYPE_P (t);
1492 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1493 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1494 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1496 bool first = true;
1498 /* Skip artificial parameter for nonstatic member functions. */
1499 if (TREE_CODE (t) == METHOD_TYPE)
1500 types = TREE_CHAIN (types);
1502 pp_cxx_left_paren (pp);
1503 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1505 if (!first)
1506 pp_cxx_separate_with (pp, ',');
1507 first = false;
1508 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1509 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1511 pp_cxx_whitespace (pp);
1512 pp_equal (pp);
1513 pp_cxx_whitespace (pp);
1514 pp->assignment_expression (TREE_PURPOSE (types));
1517 pp_cxx_right_paren (pp);
1520 /* exception-specification:
1521 throw ( type-id-list(opt) )
1523 type-id-list
1524 type-id
1525 type-id-list , type-id */
1527 static void
1528 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1530 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1531 bool need_comma = false;
1533 if (ex_spec == NULL)
1534 return;
1535 if (TREE_PURPOSE (ex_spec))
1537 pp_cxx_ws_string (pp, "noexcept");
1538 pp_cxx_whitespace (pp);
1539 pp_cxx_left_paren (pp);
1540 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1541 pp_cxx_ws_string (pp, "<uninstantiated>");
1542 else
1543 pp->expression (TREE_PURPOSE (ex_spec));
1544 pp_cxx_right_paren (pp);
1545 return;
1547 pp_cxx_ws_string (pp, "throw");
1548 pp_cxx_left_paren (pp);
1549 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1551 tree type = TREE_VALUE (ex_spec);
1552 tree argpack = NULL_TREE;
1553 int i, len = 1;
1555 if (ARGUMENT_PACK_P (type))
1557 argpack = ARGUMENT_PACK_ARGS (type);
1558 len = TREE_VEC_LENGTH (argpack);
1561 for (i = 0; i < len; ++i)
1563 if (argpack)
1564 type = TREE_VEC_ELT (argpack, i);
1566 if (need_comma)
1567 pp_cxx_separate_with (pp, ',');
1568 else
1569 need_comma = true;
1571 pp->type_id (type);
1574 pp_cxx_right_paren (pp);
1577 /* direct-declarator:
1578 declarator-id
1579 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1580 exception-specification(opt)
1581 direct-declaration [ constant-expression(opt) ]
1582 ( declarator ) */
1584 void
1585 cxx_pretty_printer::direct_declarator (tree t)
1587 switch (TREE_CODE (t))
1589 case VAR_DECL:
1590 case PARM_DECL:
1591 case CONST_DECL:
1592 case FIELD_DECL:
1593 if (DECL_NAME (t))
1595 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1597 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1598 || template_parameter_pack_p (t))
1599 /* A function parameter pack or non-type template
1600 parameter pack. */
1601 pp_cxx_ws_string (this, "...");
1603 id_expression (DECL_NAME (t));
1605 abstract_declarator (TREE_TYPE (t));
1606 break;
1608 case FUNCTION_DECL:
1609 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1610 expression (t);
1611 pp_cxx_parameter_declaration_clause (this, t);
1613 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1615 padding = pp_before;
1616 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1619 pp_cxx_exception_specification (this, TREE_TYPE (t));
1620 break;
1622 case TYPENAME_TYPE:
1623 case TEMPLATE_DECL:
1624 case TEMPLATE_TYPE_PARM:
1625 case TEMPLATE_PARM_INDEX:
1626 case TEMPLATE_TEMPLATE_PARM:
1627 break;
1629 default:
1630 c_pretty_printer::direct_declarator (t);
1631 break;
1635 /* declarator:
1636 direct-declarator
1637 ptr-operator declarator */
1639 void
1640 cxx_pretty_printer::declarator (tree t)
1642 direct_declarator (t);
1644 // Print a requires clause.
1645 if (flag_concepts)
1646 if (tree ci = get_constraints (t))
1647 if (tree reqs = CI_DECLARATOR_REQS (ci))
1648 pp_cxx_requires_clause (this, reqs);
1651 /* ctor-initializer:
1652 : mem-initializer-list
1654 mem-initializer-list:
1655 mem-initializer
1656 mem-initializer , mem-initializer-list
1658 mem-initializer:
1659 mem-initializer-id ( expression-list(opt) )
1661 mem-initializer-id:
1662 ::(opt) nested-name-specifier(opt) class-name
1663 identifier */
1665 static void
1666 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1668 t = TREE_OPERAND (t, 0);
1669 pp_cxx_whitespace (pp);
1670 pp_colon (pp);
1671 pp_cxx_whitespace (pp);
1672 for (; t; t = TREE_CHAIN (t))
1674 tree purpose = TREE_PURPOSE (t);
1675 bool is_pack = PACK_EXPANSION_P (purpose);
1677 if (is_pack)
1678 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1679 else
1680 pp->primary_expression (purpose);
1681 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1682 if (is_pack)
1683 pp_cxx_ws_string (pp, "...");
1684 if (TREE_CHAIN (t))
1685 pp_cxx_separate_with (pp, ',');
1689 /* function-definition:
1690 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1691 decl-specifier-seq(opt) declarator function-try-block */
1693 static void
1694 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1696 tree saved_scope = pp->enclosing_scope;
1697 pp->declaration_specifiers (t);
1698 pp->declarator (t);
1699 pp_needs_newline (pp) = true;
1700 pp->enclosing_scope = DECL_CONTEXT (t);
1701 if (DECL_SAVED_TREE (t))
1702 pp->statement (DECL_SAVED_TREE (t));
1703 else
1704 pp_cxx_semicolon (pp);
1705 pp_newline_and_flush (pp);
1706 pp->enclosing_scope = saved_scope;
1709 /* abstract-declarator:
1710 ptr-operator abstract-declarator(opt)
1711 direct-abstract-declarator */
1713 void
1714 cxx_pretty_printer::abstract_declarator (tree t)
1716 if (TYPE_PTRMEM_P (t))
1717 pp_cxx_right_paren (this);
1718 else if (POINTER_TYPE_P (t))
1720 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1721 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1722 pp_cxx_right_paren (this);
1723 t = TREE_TYPE (t);
1725 direct_abstract_declarator (t);
1728 /* direct-abstract-declarator:
1729 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1730 cv-qualifier-seq(opt) exception-specification(opt)
1731 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1732 ( abstract-declarator ) */
1734 void
1735 cxx_pretty_printer::direct_abstract_declarator (tree t)
1737 switch (TREE_CODE (t))
1739 case REFERENCE_TYPE:
1740 abstract_declarator (t);
1741 break;
1743 case RECORD_TYPE:
1744 if (TYPE_PTRMEMFUNC_P (t))
1745 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1746 break;
1748 case METHOD_TYPE:
1749 case FUNCTION_TYPE:
1750 pp_cxx_parameter_declaration_clause (this, t);
1751 direct_abstract_declarator (TREE_TYPE (t));
1752 if (TREE_CODE (t) == METHOD_TYPE)
1754 padding = pp_before;
1755 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1757 pp_cxx_exception_specification (this, t);
1758 break;
1760 case TYPENAME_TYPE:
1761 case TEMPLATE_TYPE_PARM:
1762 case TEMPLATE_TEMPLATE_PARM:
1763 case BOUND_TEMPLATE_TEMPLATE_PARM:
1764 case UNBOUND_CLASS_TEMPLATE:
1765 break;
1767 default:
1768 c_pretty_printer::direct_abstract_declarator (t);
1769 break;
1773 /* type-id:
1774 type-specifier-seq abstract-declarator(opt) */
1776 void
1777 cxx_pretty_printer::type_id (tree t)
1779 pp_flags saved_flags = flags;
1780 flags |= pp_c_flag_abstract;
1782 switch (TREE_CODE (t))
1784 case TYPE_DECL:
1785 case UNION_TYPE:
1786 case RECORD_TYPE:
1787 case ENUMERAL_TYPE:
1788 case TYPENAME_TYPE:
1789 case BOUND_TEMPLATE_TEMPLATE_PARM:
1790 case UNBOUND_CLASS_TEMPLATE:
1791 case TEMPLATE_TEMPLATE_PARM:
1792 case TEMPLATE_TYPE_PARM:
1793 case TEMPLATE_PARM_INDEX:
1794 case TEMPLATE_DECL:
1795 case TYPEOF_TYPE:
1796 case UNDERLYING_TYPE:
1797 case DECLTYPE_TYPE:
1798 case TEMPLATE_ID_EXPR:
1799 pp_cxx_type_specifier_seq (this, t);
1800 break;
1802 case TYPE_PACK_EXPANSION:
1803 type_id (PACK_EXPANSION_PATTERN (t));
1804 pp_cxx_ws_string (this, "...");
1805 break;
1807 default:
1808 c_pretty_printer::type_id (t);
1809 break;
1812 flags = saved_flags;
1815 /* template-argument-list:
1816 template-argument ...(opt)
1817 template-argument-list, template-argument ...(opt)
1819 template-argument:
1820 assignment-expression
1821 type-id
1822 template-name */
1824 static void
1825 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1827 int i;
1828 bool need_comma = false;
1830 if (t == NULL)
1831 return;
1832 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1834 tree arg = TREE_VEC_ELT (t, i);
1835 tree argpack = NULL_TREE;
1836 int idx, len = 1;
1838 if (ARGUMENT_PACK_P (arg))
1840 argpack = ARGUMENT_PACK_ARGS (arg);
1841 len = TREE_VEC_LENGTH (argpack);
1844 for (idx = 0; idx < len; idx++)
1846 if (argpack)
1847 arg = TREE_VEC_ELT (argpack, idx);
1849 if (need_comma)
1850 pp_cxx_separate_with (pp, ',');
1851 else
1852 need_comma = true;
1854 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1855 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1856 pp->type_id (arg);
1857 else
1858 pp->expression (arg);
1864 static void
1865 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1867 t = DECL_EXPR_DECL (t);
1868 pp_cxx_type_specifier_seq (pp, t);
1869 if (TYPE_P (t))
1870 pp->abstract_declarator (t);
1871 else
1872 pp->declarator (t);
1875 /* Statements. */
1877 void
1878 cxx_pretty_printer::statement (tree t)
1880 switch (TREE_CODE (t))
1882 case CTOR_INITIALIZER:
1883 pp_cxx_ctor_initializer (this, t);
1884 break;
1886 case USING_STMT:
1887 pp_cxx_ws_string (this, "using");
1888 pp_cxx_ws_string (this, "namespace");
1889 if (DECL_CONTEXT (t))
1890 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1891 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1892 break;
1894 case USING_DECL:
1895 pp_cxx_ws_string (this, "using");
1896 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1897 pp_cxx_unqualified_id (this, DECL_NAME (t));
1898 break;
1900 case EH_SPEC_BLOCK:
1901 break;
1903 /* try-block:
1904 try compound-statement handler-seq */
1905 case TRY_BLOCK:
1906 pp_maybe_newline_and_indent (this, 0);
1907 pp_cxx_ws_string (this, "try");
1908 pp_newline_and_indent (this, 3);
1909 statement (TRY_STMTS (t));
1910 pp_newline_and_indent (this, -3);
1911 if (CLEANUP_P (t))
1913 else
1914 statement (TRY_HANDLERS (t));
1915 break;
1918 handler-seq:
1919 handler handler-seq(opt)
1921 handler:
1922 catch ( exception-declaration ) compound-statement
1924 exception-declaration:
1925 type-specifier-seq declarator
1926 type-specifier-seq abstract-declarator
1927 ... */
1928 case HANDLER:
1929 pp_cxx_ws_string (this, "catch");
1930 pp_cxx_left_paren (this);
1931 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1932 pp_cxx_right_paren (this);
1933 pp_indentation (this) += 3;
1934 pp_needs_newline (this) = true;
1935 statement (HANDLER_BODY (t));
1936 pp_indentation (this) -= 3;
1937 pp_needs_newline (this) = true;
1938 break;
1940 /* selection-statement:
1941 if ( expression ) statement
1942 if ( expression ) statement else statement */
1943 case IF_STMT:
1944 pp_cxx_ws_string (this, "if");
1945 pp_cxx_whitespace (this);
1946 pp_cxx_left_paren (this);
1947 expression (IF_COND (t));
1948 pp_cxx_right_paren (this);
1949 pp_newline_and_indent (this, 2);
1950 statement (THEN_CLAUSE (t));
1951 pp_newline_and_indent (this, -2);
1952 if (ELSE_CLAUSE (t))
1954 tree else_clause = ELSE_CLAUSE (t);
1955 pp_cxx_ws_string (this, "else");
1956 if (TREE_CODE (else_clause) == IF_STMT)
1957 pp_cxx_whitespace (this);
1958 else
1959 pp_newline_and_indent (this, 2);
1960 statement (else_clause);
1961 if (TREE_CODE (else_clause) != IF_STMT)
1962 pp_newline_and_indent (this, -2);
1964 break;
1966 case SWITCH_STMT:
1967 pp_cxx_ws_string (this, "switch");
1968 pp_space (this);
1969 pp_cxx_left_paren (this);
1970 expression (SWITCH_STMT_COND (t));
1971 pp_cxx_right_paren (this);
1972 pp_indentation (this) += 3;
1973 pp_needs_newline (this) = true;
1974 statement (SWITCH_STMT_BODY (t));
1975 pp_newline_and_indent (this, -3);
1976 break;
1978 /* iteration-statement:
1979 while ( expression ) statement
1980 do statement while ( expression ) ;
1981 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1982 for ( declaration expression(opt) ; expression(opt) ) statement */
1983 case WHILE_STMT:
1984 pp_cxx_ws_string (this, "while");
1985 pp_space (this);
1986 pp_cxx_left_paren (this);
1987 expression (WHILE_COND (t));
1988 pp_cxx_right_paren (this);
1989 pp_newline_and_indent (this, 3);
1990 statement (WHILE_BODY (t));
1991 pp_indentation (this) -= 3;
1992 pp_needs_newline (this) = true;
1993 break;
1995 case DO_STMT:
1996 pp_cxx_ws_string (this, "do");
1997 pp_newline_and_indent (this, 3);
1998 statement (DO_BODY (t));
1999 pp_newline_and_indent (this, -3);
2000 pp_cxx_ws_string (this, "while");
2001 pp_space (this);
2002 pp_cxx_left_paren (this);
2003 expression (DO_COND (t));
2004 pp_cxx_right_paren (this);
2005 pp_cxx_semicolon (this);
2006 pp_needs_newline (this) = true;
2007 break;
2009 case FOR_STMT:
2010 pp_cxx_ws_string (this, "for");
2011 pp_space (this);
2012 pp_cxx_left_paren (this);
2013 if (FOR_INIT_STMT (t))
2014 statement (FOR_INIT_STMT (t));
2015 else
2016 pp_cxx_semicolon (this);
2017 pp_needs_newline (this) = false;
2018 pp_cxx_whitespace (this);
2019 if (FOR_COND (t))
2020 expression (FOR_COND (t));
2021 pp_cxx_semicolon (this);
2022 pp_needs_newline (this) = false;
2023 pp_cxx_whitespace (this);
2024 if (FOR_EXPR (t))
2025 expression (FOR_EXPR (t));
2026 pp_cxx_right_paren (this);
2027 pp_newline_and_indent (this, 3);
2028 statement (FOR_BODY (t));
2029 pp_indentation (this) -= 3;
2030 pp_needs_newline (this) = true;
2031 break;
2033 case RANGE_FOR_STMT:
2034 pp_cxx_ws_string (this, "for");
2035 pp_space (this);
2036 pp_cxx_left_paren (this);
2037 statement (RANGE_FOR_DECL (t));
2038 pp_space (this);
2039 pp_needs_newline (this) = false;
2040 pp_colon (this);
2041 pp_space (this);
2042 statement (RANGE_FOR_EXPR (t));
2043 pp_cxx_right_paren (this);
2044 pp_newline_and_indent (this, 3);
2045 statement (FOR_BODY (t));
2046 pp_indentation (this) -= 3;
2047 pp_needs_newline (this) = true;
2048 break;
2050 /* jump-statement:
2051 goto identifier;
2052 continue ;
2053 return expression(opt) ; */
2054 case BREAK_STMT:
2055 case CONTINUE_STMT:
2056 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2057 pp_cxx_semicolon (this);
2058 pp_needs_newline (this) = true;
2059 break;
2061 /* expression-statement:
2062 expression(opt) ; */
2063 case EXPR_STMT:
2064 expression (EXPR_STMT_EXPR (t));
2065 pp_cxx_semicolon (this);
2066 pp_needs_newline (this) = true;
2067 break;
2069 case CLEANUP_STMT:
2070 pp_cxx_ws_string (this, "try");
2071 pp_newline_and_indent (this, 2);
2072 statement (CLEANUP_BODY (t));
2073 pp_newline_and_indent (this, -2);
2074 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2075 pp_newline_and_indent (this, 2);
2076 statement (CLEANUP_EXPR (t));
2077 pp_newline_and_indent (this, -2);
2078 break;
2080 case STATIC_ASSERT:
2081 declaration (t);
2082 break;
2084 default:
2085 c_pretty_printer::statement (t);
2086 break;
2090 /* original-namespace-definition:
2091 namespace identifier { namespace-body }
2093 As an edge case, we also handle unnamed namespace definition here. */
2095 static void
2096 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2098 pp_cxx_ws_string (pp, "namespace");
2099 if (DECL_CONTEXT (t))
2100 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2101 if (DECL_NAME (t))
2102 pp_cxx_unqualified_id (pp, t);
2103 pp_cxx_whitespace (pp);
2104 pp_cxx_left_brace (pp);
2105 /* We do not print the namespace-body. */
2106 pp_cxx_whitespace (pp);
2107 pp_cxx_right_brace (pp);
2110 /* namespace-alias:
2111 identifier
2113 namespace-alias-definition:
2114 namespace identifier = qualified-namespace-specifier ;
2116 qualified-namespace-specifier:
2117 ::(opt) nested-name-specifier(opt) namespace-name */
2119 static void
2120 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2122 pp_cxx_ws_string (pp, "namespace");
2123 if (DECL_CONTEXT (t))
2124 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2125 pp_cxx_unqualified_id (pp, t);
2126 pp_cxx_whitespace (pp);
2127 pp_equal (pp);
2128 pp_cxx_whitespace (pp);
2129 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2130 pp_cxx_nested_name_specifier (pp,
2131 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2132 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2133 pp_cxx_semicolon (pp);
2136 /* simple-declaration:
2137 decl-specifier-seq(opt) init-declarator-list(opt) */
2139 static void
2140 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2142 pp->declaration_specifiers (t);
2143 pp_cxx_init_declarator (pp, t);
2144 pp_cxx_semicolon (pp);
2145 pp_needs_newline (pp) = true;
2149 template-parameter-list:
2150 template-parameter
2151 template-parameter-list , template-parameter */
2153 static inline void
2154 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2156 const int n = TREE_VEC_LENGTH (t);
2157 int i;
2158 for (i = 0; i < n; ++i)
2160 if (i)
2161 pp_cxx_separate_with (pp, ',');
2162 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2166 /* template-parameter:
2167 type-parameter
2168 parameter-declaration
2170 type-parameter:
2171 class ...(opt) identifier(opt)
2172 class identifier(opt) = type-id
2173 typename identifier(opt)
2174 typename ...(opt) identifier(opt) = type-id
2175 template < template-parameter-list > class ...(opt) identifier(opt)
2176 template < template-parameter-list > class identifier(opt) = template-name */
2178 static void
2179 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2181 tree parameter = TREE_VALUE (t);
2182 switch (TREE_CODE (parameter))
2184 case TYPE_DECL:
2185 pp_cxx_ws_string (pp, "class");
2186 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2187 pp_cxx_ws_string (pp, "...");
2188 if (DECL_NAME (parameter))
2189 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2190 /* FIXME: Check if we should print also default argument. */
2191 break;
2193 case PARM_DECL:
2194 pp_cxx_parameter_declaration (pp, parameter);
2195 break;
2197 case TEMPLATE_DECL:
2198 break;
2200 default:
2201 pp_unsupported_tree (pp, t);
2202 break;
2206 /* Pretty-print a template parameter in the canonical form
2207 "template-parameter-<level>-<position in parameter list>". */
2209 void
2210 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2212 const enum tree_code code = TREE_CODE (parm);
2214 /* Brings type template parameters to the canonical forms. */
2215 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2216 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2217 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2219 pp_cxx_begin_template_argument_list (pp);
2220 pp->translate_string ("template-parameter-");
2221 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2222 pp_minus (pp);
2223 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2224 pp_cxx_end_template_argument_list (pp);
2227 /* Print a constrained-type-specifier. */
2229 void
2230 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2232 tree t, a;
2233 if (c == error_mark_node)
2235 pp_cxx_ws_string(pp, "<unsatisfied-constrained-placeholder>");
2236 return;
2238 placeholder_extract_concept_and_args (c, t, a);
2239 pp->id_expression (t);
2240 if (TREE_VEC_LENGTH (a) > 1)
2242 pp_cxx_begin_template_argument_list (pp);
2243 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2244 for (int i = TREE_VEC_LENGTH (a) - 1; i > 0; --i)
2245 TREE_VEC_ELT (args, i-1) = TREE_VEC_ELT (a, i);
2246 pp_cxx_template_argument_list (pp, args);
2247 ggc_free (args);
2248 pp_cxx_end_template_argument_list (pp);
2253 template-declaration:
2254 export(opt) template < template-parameter-list > declaration
2256 Concept extensions:
2258 template-declaration:
2259 export(opt) template < template-parameter-list >
2260 requires-clause(opt) declaration */
2262 static void
2263 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2265 tree tmpl = most_general_template (t);
2266 tree level;
2268 pp_maybe_newline_and_indent (pp, 0);
2269 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2271 pp_cxx_ws_string (pp, "template");
2272 pp_cxx_begin_template_argument_list (pp);
2273 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2274 pp_cxx_end_template_argument_list (pp);
2275 pp_newline_and_indent (pp, 3);
2278 if (flag_concepts)
2279 if (tree ci = get_constraints (t))
2280 if (tree reqs = CI_TEMPLATE_REQS (ci))
2282 pp_cxx_requires_clause (pp, reqs);
2283 pp_newline_and_indent (pp, 6);
2286 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2287 pp_cxx_function_definition (pp, t);
2288 else
2289 pp_cxx_simple_declaration (pp, t);
2292 static void
2293 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2295 pp_unsupported_tree (pp, t);
2298 static void
2299 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2301 pp_unsupported_tree (pp, t);
2305 declaration:
2306 block-declaration
2307 function-definition
2308 template-declaration
2309 explicit-instantiation
2310 explicit-specialization
2311 linkage-specification
2312 namespace-definition
2314 block-declaration:
2315 simple-declaration
2316 asm-definition
2317 namespace-alias-definition
2318 using-declaration
2319 using-directive
2320 static_assert-declaration */
2321 void
2322 cxx_pretty_printer::declaration (tree t)
2324 if (TREE_CODE (t) == STATIC_ASSERT)
2326 pp_cxx_ws_string (this, "static_assert");
2327 pp_cxx_left_paren (this);
2328 expression (STATIC_ASSERT_CONDITION (t));
2329 pp_cxx_separate_with (this, ',');
2330 expression (STATIC_ASSERT_MESSAGE (t));
2331 pp_cxx_right_paren (this);
2333 else if (!DECL_LANG_SPECIFIC (t))
2334 pp_cxx_simple_declaration (this, t);
2335 else if (DECL_USE_TEMPLATE (t))
2336 switch (DECL_USE_TEMPLATE (t))
2338 case 1:
2339 pp_cxx_template_declaration (this, t);
2340 break;
2342 case 2:
2343 pp_cxx_explicit_specialization (this, t);
2344 break;
2346 case 3:
2347 pp_cxx_explicit_instantiation (this, t);
2348 break;
2350 default:
2351 break;
2353 else switch (TREE_CODE (t))
2355 case VAR_DECL:
2356 case TYPE_DECL:
2357 pp_cxx_simple_declaration (this, t);
2358 break;
2360 case FUNCTION_DECL:
2361 if (DECL_SAVED_TREE (t))
2362 pp_cxx_function_definition (this, t);
2363 else
2364 pp_cxx_simple_declaration (this, t);
2365 break;
2367 case NAMESPACE_DECL:
2368 if (DECL_NAMESPACE_ALIAS (t))
2369 pp_cxx_namespace_alias_definition (this, t);
2370 else
2371 pp_cxx_original_namespace_definition (this, t);
2372 break;
2374 default:
2375 pp_unsupported_tree (this, t);
2376 break;
2380 static void
2381 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2383 t = TREE_OPERAND (t, 0);
2384 pp_cxx_ws_string (pp, "typeid");
2385 pp_cxx_left_paren (pp);
2386 if (TYPE_P (t))
2387 pp->type_id (t);
2388 else
2389 pp->expression (t);
2390 pp_cxx_right_paren (pp);
2393 void
2394 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2396 pp_cxx_ws_string (pp, "va_arg");
2397 pp_cxx_left_paren (pp);
2398 pp->assignment_expression (TREE_OPERAND (t, 0));
2399 pp_cxx_separate_with (pp, ',');
2400 pp->type_id (TREE_TYPE (t));
2401 pp_cxx_right_paren (pp);
2404 static bool
2405 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2407 switch (TREE_CODE (t))
2409 case ARROW_EXPR:
2410 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2411 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2413 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2414 pp_cxx_separate_with (pp, ',');
2415 return true;
2417 return false;
2418 case COMPONENT_REF:
2419 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2420 return false;
2421 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2422 pp_cxx_dot (pp);
2423 pp->expression (TREE_OPERAND (t, 1));
2424 return true;
2425 case ARRAY_REF:
2426 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2427 return false;
2428 pp_left_bracket (pp);
2429 pp->expression (TREE_OPERAND (t, 1));
2430 pp_right_bracket (pp);
2431 return true;
2432 default:
2433 return false;
2437 void
2438 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2440 pp_cxx_ws_string (pp, "offsetof");
2441 pp_cxx_left_paren (pp);
2442 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2443 pp->expression (TREE_OPERAND (t, 0));
2444 pp_cxx_right_paren (pp);
2447 void
2448 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2450 pp_cxx_ws_string (pp, "__builtin_addressof");
2451 pp_cxx_left_paren (pp);
2452 pp->expression (TREE_OPERAND (t, 0));
2453 pp_cxx_right_paren (pp);
2456 static char const*
2457 get_fold_operator (tree t)
2459 int op = int_cst_value (FOLD_EXPR_OP (t));
2460 if (FOLD_EXPR_MODIFY_P (t))
2462 switch (op)
2464 case NOP_EXPR: return "=";
2465 case PLUS_EXPR: return "+=";
2466 case MINUS_EXPR: return "-=";
2467 case MULT_EXPR: return "*=";
2468 case TRUNC_DIV_EXPR: return "/=";
2469 case TRUNC_MOD_EXPR: return "%=";
2470 case BIT_XOR_EXPR: return "^=";
2471 case BIT_AND_EXPR: return "&=";
2472 case BIT_IOR_EXPR: return "|=";
2473 case LSHIFT_EXPR: return "<<=";
2474 case RSHIFT_EXPR: return ">>=";
2475 default: gcc_unreachable ();
2478 else
2480 switch (op)
2482 case PLUS_EXPR: return "+";
2483 case MINUS_EXPR: return "-";
2484 case MULT_EXPR: return "*";
2485 case TRUNC_DIV_EXPR: return "/";
2486 case TRUNC_MOD_EXPR: return "%";
2487 case BIT_XOR_EXPR: return "^";
2488 case BIT_AND_EXPR: return "&";
2489 case BIT_IOR_EXPR: return "|";
2490 case LSHIFT_EXPR: return "<<";
2491 case RSHIFT_EXPR: return ">>";
2492 case EQ_EXPR: return "==";
2493 case NE_EXPR: return "!=";
2494 case LT_EXPR: return "<";
2495 case GT_EXPR: return ">";
2496 case LE_EXPR: return "<=";
2497 case GE_EXPR: return ">=";
2498 case TRUTH_ANDIF_EXPR: return "&&";
2499 case TRUTH_ORIF_EXPR: return "||";
2500 case MEMBER_REF: return "->*";
2501 case DOTSTAR_EXPR: return ".*";
2502 case OFFSET_REF: return ".*";
2503 default: return ","; /* FIXME: Not the right default. */
2508 void
2509 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2511 char const* op = get_fold_operator (t);
2512 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2513 pp_cxx_left_paren (pp);
2514 pp_cxx_ws_string (pp, "...");
2515 pp_cxx_ws_string (pp, op);
2516 pp->expression (expr);
2517 pp_cxx_right_paren (pp);
2520 void
2521 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2523 char const* op = get_fold_operator (t);
2524 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2525 pp_cxx_left_paren (pp);
2526 pp->expression (expr);
2527 pp_space (pp);
2528 pp_cxx_ws_string (pp, op);
2529 pp_cxx_ws_string (pp, "...");
2530 pp_cxx_right_paren (pp);
2533 void
2534 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2536 char const* op = get_fold_operator (t);
2537 tree t1 = TREE_OPERAND (t, 1);
2538 tree t2 = TREE_OPERAND (t, 2);
2539 if (t1 == FOLD_EXPR_PACK (t))
2540 t1 = PACK_EXPANSION_PATTERN (t1);
2541 else
2542 t2 = PACK_EXPANSION_PATTERN (t2);
2543 pp_cxx_left_paren (pp);
2544 pp->expression (t1);
2545 pp_cxx_ws_string (pp, op);
2546 pp_cxx_ws_string (pp, "...");
2547 pp_cxx_ws_string (pp, op);
2548 pp->expression (t2);
2549 pp_cxx_right_paren (pp);
2552 void
2553 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2555 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2557 switch (kind)
2559 case CPTK_HAS_NOTHROW_ASSIGN:
2560 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2561 break;
2562 case CPTK_HAS_TRIVIAL_ASSIGN:
2563 pp_cxx_ws_string (pp, "__has_trivial_assign");
2564 break;
2565 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2566 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2567 break;
2568 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2569 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2570 break;
2571 case CPTK_HAS_NOTHROW_COPY:
2572 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2573 break;
2574 case CPTK_HAS_TRIVIAL_COPY:
2575 pp_cxx_ws_string (pp, "__has_trivial_copy");
2576 break;
2577 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2578 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2579 break;
2580 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
2581 pp_cxx_ws_string (pp, "__has_unique_object_representations");
2582 break;
2583 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2584 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2585 break;
2586 case CPTK_IS_ABSTRACT:
2587 pp_cxx_ws_string (pp, "__is_abstract");
2588 break;
2589 case CPTK_IS_AGGREGATE:
2590 pp_cxx_ws_string (pp, "__is_aggregate");
2591 break;
2592 case CPTK_IS_BASE_OF:
2593 pp_cxx_ws_string (pp, "__is_base_of");
2594 break;
2595 case CPTK_IS_CLASS:
2596 pp_cxx_ws_string (pp, "__is_class");
2597 break;
2598 case CPTK_IS_EMPTY:
2599 pp_cxx_ws_string (pp, "__is_empty");
2600 break;
2601 case CPTK_IS_ENUM:
2602 pp_cxx_ws_string (pp, "__is_enum");
2603 break;
2604 case CPTK_IS_FINAL:
2605 pp_cxx_ws_string (pp, "__is_final");
2606 break;
2607 case CPTK_IS_POD:
2608 pp_cxx_ws_string (pp, "__is_pod");
2609 break;
2610 case CPTK_IS_POLYMORPHIC:
2611 pp_cxx_ws_string (pp, "__is_polymorphic");
2612 break;
2613 case CPTK_IS_SAME_AS:
2614 pp_cxx_ws_string (pp, "__is_same_as");
2615 break;
2616 case CPTK_IS_STD_LAYOUT:
2617 pp_cxx_ws_string (pp, "__is_std_layout");
2618 break;
2619 case CPTK_IS_TRIVIAL:
2620 pp_cxx_ws_string (pp, "__is_trivial");
2621 break;
2622 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2623 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2624 break;
2625 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2626 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2627 break;
2628 case CPTK_IS_TRIVIALLY_COPYABLE:
2629 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2630 break;
2631 case CPTK_IS_UNION:
2632 pp_cxx_ws_string (pp, "__is_union");
2633 break;
2634 case CPTK_IS_LITERAL_TYPE:
2635 pp_cxx_ws_string (pp, "__is_literal_type");
2636 break;
2637 case CPTK_IS_ASSIGNABLE:
2638 pp_cxx_ws_string (pp, "__is_assignable");
2639 break;
2640 case CPTK_IS_CONSTRUCTIBLE:
2641 pp_cxx_ws_string (pp, "__is_constructible");
2642 break;
2644 default:
2645 gcc_unreachable ();
2648 pp_cxx_left_paren (pp);
2649 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2651 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2653 pp_cxx_separate_with (pp, ',');
2654 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2657 pp_cxx_right_paren (pp);
2660 // requires-clause:
2661 // 'requires' logical-or-expression
2662 void
2663 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2665 if (!t)
2666 return;
2667 pp->padding = pp_before;
2668 pp_cxx_ws_string (pp, "requires");
2669 pp_space (pp);
2670 pp->expression (t);
2673 /* requirement:
2674 simple-requirement
2675 compound-requirement
2676 type-requirement
2677 nested-requirement */
2678 static void
2679 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2681 switch (TREE_CODE (t))
2683 case SIMPLE_REQ:
2684 pp_cxx_simple_requirement (pp, t);
2685 break;
2687 case TYPE_REQ:
2688 pp_cxx_type_requirement (pp, t);
2689 break;
2691 case COMPOUND_REQ:
2692 pp_cxx_compound_requirement (pp, t);
2693 break;
2695 case NESTED_REQ:
2696 pp_cxx_nested_requirement (pp, t);
2697 break;
2699 default:
2700 gcc_unreachable ();
2704 // requirement-list:
2705 // requirement
2706 // requirement-list ';' requirement[opt]
2708 static void
2709 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2711 for (; t; t = TREE_CHAIN (t))
2712 pp_cxx_requirement (pp, TREE_VALUE (t));
2715 // requirement-body:
2716 // '{' requirement-list '}'
2717 static void
2718 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2720 pp_cxx_left_brace (pp);
2721 pp_cxx_requirement_list (pp, t);
2722 pp_cxx_right_brace (pp);
2725 // requires-expression:
2726 // 'requires' requirement-parameter-list requirement-body
2727 void
2728 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2730 pp_string (pp, "requires");
2731 if (tree parms = TREE_OPERAND (t, 0))
2733 pp_cxx_parameter_declaration_clause (pp, parms);
2734 pp_cxx_whitespace (pp);
2736 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2739 /* simple-requirement:
2740 expression ';' */
2741 void
2742 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2744 pp->expression (TREE_OPERAND (t, 0));
2745 pp_cxx_semicolon (pp);
2748 /* type-requirement:
2749 typename type-name ';' */
2750 void
2751 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2753 pp->type_id (TREE_OPERAND (t, 0));
2754 pp_cxx_semicolon (pp);
2757 /* compound-requirement:
2758 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2759 void
2760 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2762 pp_cxx_left_brace (pp);
2763 pp->expression (TREE_OPERAND (t, 0));
2764 pp_cxx_right_brace (pp);
2766 if (COMPOUND_REQ_NOEXCEPT_P (t))
2767 pp_cxx_ws_string (pp, "noexcept");
2769 if (tree type = TREE_OPERAND (t, 1))
2771 pp_cxx_ws_string (pp, "->");
2772 pp->type_id (type);
2774 pp_cxx_semicolon (pp);
2777 /* nested requirement:
2778 'requires' constraint-expression */
2779 void
2780 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2782 pp_cxx_ws_string (pp, "requires");
2783 pp->expression (TREE_OPERAND (t, 0));
2784 pp_cxx_semicolon (pp);
2787 void
2788 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2790 pp->expression (TREE_OPERAND (t, 0));
2793 void
2794 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2796 tree decl = CHECK_CONSTR_CONCEPT (t);
2797 tree tmpl = DECL_TI_TEMPLATE (decl);
2798 tree args = CHECK_CONSTR_ARGS (t);
2799 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2801 if (VAR_P (decl))
2802 pp->expression (id);
2803 else if (TREE_CODE (decl) == FUNCTION_DECL)
2805 tree call = build_vl_exp (CALL_EXPR, 2);
2806 TREE_OPERAND (call, 0) = integer_two_node;
2807 TREE_OPERAND (call, 1) = id;
2808 pp->expression (call);
2810 else
2811 gcc_unreachable ();
2814 void
2815 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2817 pp_string (pp, "<valid-expression ");
2818 pp_cxx_left_paren (pp);
2819 pp->expression (TREE_OPERAND (t, 0));
2820 pp_cxx_right_paren (pp);
2821 pp_string (pp, ">");
2824 void
2825 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2827 pp_string (pp, "<valid-type ");
2828 pp->type_id (TREE_OPERAND (t, 0));
2829 pp_string (pp, ">");
2832 void
2833 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2835 pp_string (pp, "<implicitly-conversion ");
2836 pp_cxx_left_paren (pp);
2837 pp->expression (ICONV_CONSTR_EXPR (t));
2838 pp_cxx_right_paren (pp);
2839 pp_cxx_ws_string (pp, "to");
2840 pp->type_id (ICONV_CONSTR_TYPE (t));
2841 pp_string (pp, ">");
2844 void
2845 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2847 pp_string (pp, "<argument-deduction ");
2848 pp_cxx_left_paren (pp);
2849 pp->expression (DEDUCT_CONSTR_EXPR (t));
2850 pp_cxx_right_paren (pp);
2851 pp_cxx_ws_string (pp, "as");
2852 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2853 pp_string (pp, ">");
2856 void
2857 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2859 pp_cxx_ws_string (pp, "noexcept");
2860 pp_cxx_whitespace (pp);
2861 pp_cxx_left_paren (pp);
2862 pp->expression (TREE_OPERAND (t, 0));
2863 pp_cxx_right_paren (pp);
2866 void
2867 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2869 pp_left_paren (pp);
2870 pp_string (pp, "<requires ");
2871 if (tree parms = PARM_CONSTR_PARMS (t))
2873 pp_cxx_parameter_declaration_clause (pp, parms);
2874 pp_cxx_whitespace (pp);
2876 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2877 pp_string (pp, ">");
2880 void
2881 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2883 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2884 pp_string (pp, " and ");
2885 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2888 void
2889 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2891 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2892 pp_string (pp, " or ");
2893 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2896 void
2897 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2899 if (t == error_mark_node)
2900 return pp->expression (t);
2902 switch (TREE_CODE (t))
2904 case PRED_CONSTR:
2905 pp_cxx_predicate_constraint (pp, t);
2906 break;
2908 case CHECK_CONSTR:
2909 pp_cxx_check_constraint (pp, t);
2910 break;
2912 case EXPR_CONSTR:
2913 pp_cxx_expression_constraint (pp, t);
2914 break;
2916 case TYPE_CONSTR:
2917 pp_cxx_type_constraint (pp, t);
2918 break;
2920 case ICONV_CONSTR:
2921 pp_cxx_implicit_conversion_constraint (pp, t);
2922 break;
2924 case DEDUCT_CONSTR:
2925 pp_cxx_argument_deduction_constraint (pp, t);
2926 break;
2928 case EXCEPT_CONSTR:
2929 pp_cxx_exception_constraint (pp, t);
2930 break;
2932 case PARM_CONSTR:
2933 pp_cxx_parameterized_constraint (pp, t);
2934 break;
2936 case CONJ_CONSTR:
2937 pp_cxx_conjunction (pp, t);
2938 break;
2940 case DISJ_CONSTR:
2941 pp_cxx_disjunction (pp, t);
2942 break;
2944 case EXPR_PACK_EXPANSION:
2945 pp->expression (TREE_OPERAND (t, 0));
2946 break;
2948 default:
2949 gcc_unreachable ();
2955 typedef c_pretty_print_fn pp_fun;
2957 /* Initialization of a C++ pretty-printer object. */
2959 cxx_pretty_printer::cxx_pretty_printer ()
2960 : c_pretty_printer (),
2961 enclosing_scope (global_namespace)
2963 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2964 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;