* sv.po: Update.
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blobcc28045eb64ebc5530636f00cf8c976f240493b1
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "cp-tree.h"
25 #include "cxx-pretty-print.h"
26 #include "tree-pretty-print.h"
28 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
29 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
30 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
32 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
33 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
34 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
35 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
36 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
37 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
40 static inline void
41 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
43 const char *p = pp_last_position_in_text (pp);
45 if (p != NULL && *p == c)
46 pp_cxx_whitespace (pp);
47 pp_character (pp, c);
48 pp->padding = pp_none;
51 #define pp_cxx_expression_list(PP, T) \
52 pp_c_expression_list (PP, T)
53 #define pp_cxx_space_for_pointer_operator(PP, T) \
54 pp_c_space_for_pointer_operator (PP, T)
55 #define pp_cxx_init_declarator(PP, T) \
56 pp_c_init_declarator (PP, T)
57 #define pp_cxx_call_argument_list(PP, T) \
58 pp_c_call_argument_list (PP, T)
60 void
61 pp_cxx_colon_colon (cxx_pretty_printer *pp)
63 pp_colon_colon (pp);
64 pp->padding = pp_none;
67 void
68 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
70 pp_cxx_nonconsecutive_character (pp, '<');
73 void
74 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
76 pp_cxx_nonconsecutive_character (pp, '>');
79 void
80 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
82 pp_separate_with (pp, c);
83 pp->padding = pp_none;
86 /* Expressions. */
88 static inline bool
89 is_destructor_name (tree name)
91 return name == complete_dtor_identifier
92 || name == base_dtor_identifier
93 || name == deleting_dtor_identifier;
96 /* conversion-function-id:
97 operator conversion-type-id
99 conversion-type-id:
100 type-specifier-seq conversion-declarator(opt)
102 conversion-declarator:
103 ptr-operator conversion-declarator(opt) */
105 static inline void
106 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
108 pp_cxx_ws_string (pp, "operator");
109 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
112 static inline void
113 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
115 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
116 pp_cxx_begin_template_argument_list (pp);
117 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
118 pp_cxx_end_template_argument_list (pp);
121 /* Prints the unqualified part of the id-expression T.
123 unqualified-id:
124 identifier
125 operator-function-id
126 conversion-function-id
127 ~ class-name
128 template-id */
130 static void
131 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
133 enum tree_code code = TREE_CODE (t);
134 switch (code)
136 case RESULT_DECL:
137 pp->translate_string ("<return-value>");
138 break;
140 case OVERLOAD:
141 t = OVL_CURRENT (t);
142 case VAR_DECL:
143 case PARM_DECL:
144 case CONST_DECL:
145 case TYPE_DECL:
146 case FUNCTION_DECL:
147 case NAMESPACE_DECL:
148 case FIELD_DECL:
149 case LABEL_DECL:
150 case USING_DECL:
151 case TEMPLATE_DECL:
152 t = DECL_NAME (t);
154 case IDENTIFIER_NODE:
155 if (t == NULL)
156 pp->translate_string ("<unnamed>");
157 else if (IDENTIFIER_TYPENAME_P (t))
158 pp_cxx_conversion_function_id (pp, t);
159 else
161 if (is_destructor_name (t))
163 pp_complement (pp);
164 /* FIXME: Why is this necessary? */
165 if (TREE_TYPE (t))
166 t = constructor_name (TREE_TYPE (t));
168 pp_cxx_tree_identifier (pp, t);
170 break;
172 case TEMPLATE_ID_EXPR:
173 pp_cxx_template_id (pp, t);
174 break;
176 case BASELINK:
177 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
178 break;
180 case RECORD_TYPE:
181 case UNION_TYPE:
182 case ENUMERAL_TYPE:
183 case TYPENAME_TYPE:
184 case UNBOUND_CLASS_TEMPLATE:
185 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
186 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
188 pp_cxx_begin_template_argument_list (pp);
189 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
190 (CLASSTYPE_TI_ARGS (t)));
191 pp_cxx_end_template_argument_list (pp);
193 break;
195 case BIT_NOT_EXPR:
196 pp_cxx_complement (pp);
197 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
198 break;
200 case TEMPLATE_TYPE_PARM:
201 case TEMPLATE_TEMPLATE_PARM:
202 if (TYPE_IDENTIFIER (t))
203 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
204 else
205 pp_cxx_canonical_template_parameter (pp, t);
206 break;
208 case TEMPLATE_PARM_INDEX:
209 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
210 break;
212 case BOUND_TEMPLATE_TEMPLATE_PARM:
213 pp_cxx_cv_qualifier_seq (pp, t);
214 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
215 pp_cxx_begin_template_argument_list (pp);
216 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
217 pp_cxx_end_template_argument_list (pp);
218 break;
220 default:
221 pp_unsupported_tree (pp, t);
222 break;
226 /* Pretty-print out the token sequence ":: template" in template codes
227 where it is needed to "inline declare" the (following) member as
228 a template. This situation arises when SCOPE of T is dependent
229 on template parameters. */
231 static inline void
232 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
234 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
235 && TYPE_P (scope) && dependent_type_p (scope))
236 pp_cxx_ws_string (pp, "template");
239 /* nested-name-specifier:
240 class-or-namespace-name :: nested-name-specifier(opt)
241 class-or-namespace-name :: template nested-name-specifier */
243 static void
244 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
246 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
248 tree scope = get_containing_scope (t);
249 pp_cxx_nested_name_specifier (pp, scope);
250 pp_cxx_template_keyword_if_needed (pp, scope, t);
251 pp_cxx_unqualified_id (pp, t);
252 pp_cxx_colon_colon (pp);
256 /* qualified-id:
257 nested-name-specifier template(opt) unqualified-id */
259 static void
260 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
262 switch (TREE_CODE (t))
264 /* A pointer-to-member is always qualified. */
265 case PTRMEM_CST:
266 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
267 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
268 break;
270 /* In Standard C++, functions cannot possibly be used as
271 nested-name-specifiers. However, there are situations where
272 is "makes sense" to output the surrounding function name for the
273 purpose of emphasizing on the scope kind. Just printing the
274 function name might not be sufficient as it may be overloaded; so,
275 we decorate the function with its signature too.
276 FIXME: This is probably the wrong pretty-printing for conversion
277 functions and some function templates. */
278 case OVERLOAD:
279 t = OVL_CURRENT (t);
280 case FUNCTION_DECL:
281 if (DECL_FUNCTION_MEMBER_P (t))
282 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
283 pp_cxx_unqualified_id
284 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
285 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
286 break;
288 case OFFSET_REF:
289 case SCOPE_REF:
290 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
291 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
292 break;
294 default:
296 tree scope = get_containing_scope (t);
297 if (scope != pp->enclosing_scope)
299 pp_cxx_nested_name_specifier (pp, scope);
300 pp_cxx_template_keyword_if_needed (pp, scope, t);
302 pp_cxx_unqualified_id (pp, t);
304 break;
309 void
310 cxx_pretty_printer::constant (tree t)
312 switch (TREE_CODE (t))
314 case STRING_CST:
316 const bool in_parens = PAREN_STRING_LITERAL_P (t);
317 if (in_parens)
318 pp_cxx_left_paren (this);
319 c_pretty_printer::constant (t);
320 if (in_parens)
321 pp_cxx_right_paren (this);
323 break;
325 case INTEGER_CST:
326 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
328 pp_string (this, "nullptr");
329 break;
331 /* else fall through. */
333 default:
334 c_pretty_printer::constant (t);
335 break;
339 /* id-expression:
340 unqualified-id
341 qualified-id */
343 void
344 cxx_pretty_printer::id_expression (tree t)
346 if (TREE_CODE (t) == OVERLOAD)
347 t = OVL_CURRENT (t);
348 if (DECL_P (t) && DECL_CONTEXT (t))
349 pp_cxx_qualified_id (this, t);
350 else
351 pp_cxx_unqualified_id (this, t);
354 /* user-defined literal:
355 literal ud-suffix */
357 void
358 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
360 pp->constant (USERDEF_LITERAL_VALUE (t));
361 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
365 /* primary-expression:
366 literal
367 this
368 :: identifier
369 :: operator-function-id
370 :: qualifier-id
371 ( expression )
372 id-expression
374 GNU Extensions:
375 __builtin_va_arg ( assignment-expression , type-id )
376 __builtin_offsetof ( type-id, offsetof-expression )
378 __has_nothrow_assign ( type-id )
379 __has_nothrow_constructor ( type-id )
380 __has_nothrow_copy ( type-id )
381 __has_trivial_assign ( type-id )
382 __has_trivial_constructor ( type-id )
383 __has_trivial_copy ( type-id )
384 __has_trivial_destructor ( type-id )
385 __has_virtual_destructor ( type-id )
386 __is_abstract ( type-id )
387 __is_base_of ( type-id , type-id )
388 __is_class ( type-id )
389 __is_empty ( type-id )
390 __is_enum ( type-id )
391 __is_literal_type ( type-id )
392 __is_pod ( type-id )
393 __is_polymorphic ( type-id )
394 __is_std_layout ( type-id )
395 __is_trivial ( type-id )
396 __is_union ( type-id ) */
398 void
399 cxx_pretty_printer::primary_expression (tree t)
401 switch (TREE_CODE (t))
403 case VOID_CST:
404 case INTEGER_CST:
405 case REAL_CST:
406 case COMPLEX_CST:
407 case STRING_CST:
408 constant (t);
409 break;
411 case USERDEF_LITERAL:
412 pp_cxx_userdef_literal (this, t);
413 break;
415 case BASELINK:
416 t = BASELINK_FUNCTIONS (t);
417 case VAR_DECL:
418 case PARM_DECL:
419 case FIELD_DECL:
420 case FUNCTION_DECL:
421 case OVERLOAD:
422 case CONST_DECL:
423 case TEMPLATE_DECL:
424 id_expression (t);
425 break;
427 case RESULT_DECL:
428 case TEMPLATE_TYPE_PARM:
429 case TEMPLATE_TEMPLATE_PARM:
430 case TEMPLATE_PARM_INDEX:
431 pp_cxx_unqualified_id (this, t);
432 break;
434 case STMT_EXPR:
435 pp_cxx_left_paren (this);
436 statement (STMT_EXPR_STMT (t));
437 pp_cxx_right_paren (this);
438 break;
440 case TRAIT_EXPR:
441 pp_cxx_trait_expression (this, t);
442 break;
444 case VA_ARG_EXPR:
445 pp_cxx_va_arg_expression (this, t);
446 break;
448 case OFFSETOF_EXPR:
449 pp_cxx_offsetof_expression (this, t);
450 break;
452 case REQUIRES_EXPR:
453 pp_cxx_requires_expr (this, t);
454 break;
456 default:
457 c_pretty_printer::primary_expression (t);
458 break;
462 /* postfix-expression:
463 primary-expression
464 postfix-expression [ expression ]
465 postfix-expression ( expression-list(opt) )
466 simple-type-specifier ( expression-list(opt) )
467 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
468 typename ::(opt) nested-name-specifier template(opt)
469 template-id ( expression-list(opt) )
470 postfix-expression . template(opt) ::(opt) id-expression
471 postfix-expression -> template(opt) ::(opt) id-expression
472 postfix-expression . pseudo-destructor-name
473 postfix-expression -> pseudo-destructor-name
474 postfix-expression ++
475 postfix-expression --
476 dynamic_cast < type-id > ( expression )
477 static_cast < type-id > ( expression )
478 reinterpret_cast < type-id > ( expression )
479 const_cast < type-id > ( expression )
480 typeid ( expression )
481 typeid ( type-id ) */
483 void
484 cxx_pretty_printer::postfix_expression (tree t)
486 enum tree_code code = TREE_CODE (t);
488 switch (code)
490 case AGGR_INIT_EXPR:
491 case CALL_EXPR:
493 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
494 : CALL_EXPR_FN (t));
495 tree saved_scope = enclosing_scope;
496 bool skipfirst = false;
497 tree arg;
499 if (TREE_CODE (fun) == ADDR_EXPR)
500 fun = TREE_OPERAND (fun, 0);
502 /* In templates, where there is no way to tell whether a given
503 call uses an actual member function. So the parser builds
504 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
505 instantiation time. */
506 if (TREE_CODE (fun) != FUNCTION_DECL)
508 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
510 tree object = (code == AGGR_INIT_EXPR
511 ? (AGGR_INIT_VIA_CTOR_P (t)
512 ? AGGR_INIT_EXPR_SLOT (t)
513 : AGGR_INIT_EXPR_ARG (t, 0))
514 : CALL_EXPR_ARG (t, 0));
516 while (TREE_CODE (object) == NOP_EXPR)
517 object = TREE_OPERAND (object, 0);
519 if (TREE_CODE (object) == ADDR_EXPR)
520 object = TREE_OPERAND (object, 0);
522 if (!TYPE_PTR_P (TREE_TYPE (object)))
524 postfix_expression (object);
525 pp_cxx_dot (this);
527 else
529 postfix_expression (object);
530 pp_cxx_arrow (this);
532 skipfirst = true;
533 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
536 postfix_expression (fun);
537 enclosing_scope = saved_scope;
538 pp_cxx_left_paren (this);
539 if (code == AGGR_INIT_EXPR)
541 aggr_init_expr_arg_iterator iter;
542 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
544 if (skipfirst)
545 skipfirst = false;
546 else
548 expression (arg);
549 if (more_aggr_init_expr_args_p (&iter))
550 pp_cxx_separate_with (this, ',');
554 else
556 call_expr_arg_iterator iter;
557 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
559 if (skipfirst)
560 skipfirst = false;
561 else
563 expression (arg);
564 if (more_call_expr_args_p (&iter))
565 pp_cxx_separate_with (this, ',');
569 pp_cxx_right_paren (this);
571 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
573 pp_cxx_separate_with (this, ',');
574 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
576 break;
578 case BASELINK:
579 case VAR_DECL:
580 case PARM_DECL:
581 case FIELD_DECL:
582 case FUNCTION_DECL:
583 case OVERLOAD:
584 case CONST_DECL:
585 case TEMPLATE_DECL:
586 case RESULT_DECL:
587 primary_expression (t);
588 break;
590 case DYNAMIC_CAST_EXPR:
591 case STATIC_CAST_EXPR:
592 case REINTERPRET_CAST_EXPR:
593 case CONST_CAST_EXPR:
594 if (code == DYNAMIC_CAST_EXPR)
595 pp_cxx_ws_string (this, "dynamic_cast");
596 else if (code == STATIC_CAST_EXPR)
597 pp_cxx_ws_string (this, "static_cast");
598 else if (code == REINTERPRET_CAST_EXPR)
599 pp_cxx_ws_string (this, "reinterpret_cast");
600 else
601 pp_cxx_ws_string (this, "const_cast");
602 pp_cxx_begin_template_argument_list (this);
603 type_id (TREE_TYPE (t));
604 pp_cxx_end_template_argument_list (this);
605 pp_left_paren (this);
606 expression (TREE_OPERAND (t, 0));
607 pp_right_paren (this);
608 break;
610 case EMPTY_CLASS_EXPR:
611 type_id (TREE_TYPE (t));
612 pp_left_paren (this);
613 pp_right_paren (this);
614 break;
616 case TYPEID_EXPR:
617 pp_cxx_typeid_expression (this, t);
618 break;
620 case PSEUDO_DTOR_EXPR:
621 postfix_expression (TREE_OPERAND (t, 0));
622 pp_cxx_dot (this);
623 if (TREE_OPERAND (t, 1))
625 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
626 pp_cxx_colon_colon (this);
628 pp_complement (this);
629 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
630 break;
632 case ARROW_EXPR:
633 postfix_expression (TREE_OPERAND (t, 0));
634 pp_cxx_arrow (this);
635 break;
637 default:
638 c_pretty_printer::postfix_expression (t);
639 break;
643 /* new-expression:
644 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
645 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
647 new-placement:
648 ( expression-list )
650 new-type-id:
651 type-specifier-seq new-declarator(opt)
653 new-declarator:
654 ptr-operator new-declarator(opt)
655 direct-new-declarator
657 direct-new-declarator
658 [ expression ]
659 direct-new-declarator [ constant-expression ]
661 new-initializer:
662 ( expression-list(opt) ) */
664 static void
665 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
667 enum tree_code code = TREE_CODE (t);
668 tree type = TREE_OPERAND (t, 1);
669 tree init = TREE_OPERAND (t, 2);
670 switch (code)
672 case NEW_EXPR:
673 case VEC_NEW_EXPR:
674 if (NEW_EXPR_USE_GLOBAL (t))
675 pp_cxx_colon_colon (pp);
676 pp_cxx_ws_string (pp, "new");
677 if (TREE_OPERAND (t, 0))
679 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
680 pp_space (pp);
682 if (TREE_CODE (type) == ARRAY_REF)
683 type = build_cplus_array_type
684 (TREE_OPERAND (type, 0),
685 build_index_type (fold_build2_loc (input_location,
686 MINUS_EXPR, integer_type_node,
687 TREE_OPERAND (type, 1),
688 integer_one_node)));
689 pp->type_id (type);
690 if (init)
692 pp_left_paren (pp);
693 if (TREE_CODE (init) == TREE_LIST)
694 pp_c_expression_list (pp, init);
695 else if (init == void_node)
696 ; /* OK, empty initializer list. */
697 else
698 pp->expression (init);
699 pp_right_paren (pp);
701 break;
703 default:
704 pp_unsupported_tree (pp, t);
708 /* delete-expression:
709 ::(opt) delete cast-expression
710 ::(opt) delete [ ] cast-expression */
712 static void
713 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
715 enum tree_code code = TREE_CODE (t);
716 switch (code)
718 case DELETE_EXPR:
719 case VEC_DELETE_EXPR:
720 if (DELETE_EXPR_USE_GLOBAL (t))
721 pp_cxx_colon_colon (pp);
722 pp_cxx_ws_string (pp, "delete");
723 pp_space (pp);
724 if (code == VEC_DELETE_EXPR
725 || DELETE_EXPR_USE_VEC (t))
727 pp_left_bracket (pp);
728 pp_right_bracket (pp);
729 pp_space (pp);
731 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
732 break;
734 default:
735 pp_unsupported_tree (pp, t);
739 /* unary-expression:
740 postfix-expression
741 ++ cast-expression
742 -- cast-expression
743 unary-operator cast-expression
744 sizeof unary-expression
745 sizeof ( type-id )
746 sizeof ... ( identifier )
747 new-expression
748 delete-expression
750 unary-operator: one of
751 * & + - !
753 GNU extensions:
754 __alignof__ unary-expression
755 __alignof__ ( type-id ) */
757 void
758 cxx_pretty_printer::unary_expression (tree t)
760 enum tree_code code = TREE_CODE (t);
761 switch (code)
763 case NEW_EXPR:
764 case VEC_NEW_EXPR:
765 pp_cxx_new_expression (this, t);
766 break;
768 case DELETE_EXPR:
769 case VEC_DELETE_EXPR:
770 pp_cxx_delete_expression (this, t);
771 break;
773 case SIZEOF_EXPR:
774 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
776 pp_cxx_ws_string (this, "sizeof");
777 pp_cxx_ws_string (this, "...");
778 pp_cxx_whitespace (this);
779 pp_cxx_left_paren (this);
780 if (TYPE_P (TREE_OPERAND (t, 0)))
781 type_id (TREE_OPERAND (t, 0));
782 else
783 unary_expression (TREE_OPERAND (t, 0));
784 pp_cxx_right_paren (this);
785 break;
787 /* Fall through */
789 case ALIGNOF_EXPR:
790 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
791 pp_cxx_whitespace (this);
792 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
794 pp_cxx_left_paren (this);
795 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
796 pp_cxx_right_paren (this);
798 else if (TYPE_P (TREE_OPERAND (t, 0)))
800 pp_cxx_left_paren (this);
801 type_id (TREE_OPERAND (t, 0));
802 pp_cxx_right_paren (this);
804 else
805 unary_expression (TREE_OPERAND (t, 0));
806 break;
808 case AT_ENCODE_EXPR:
809 pp_cxx_ws_string (this, "@encode");
810 pp_cxx_whitespace (this);
811 pp_cxx_left_paren (this);
812 type_id (TREE_OPERAND (t, 0));
813 pp_cxx_right_paren (this);
814 break;
816 case NOEXCEPT_EXPR:
817 pp_cxx_ws_string (this, "noexcept");
818 pp_cxx_whitespace (this);
819 pp_cxx_left_paren (this);
820 expression (TREE_OPERAND (t, 0));
821 pp_cxx_right_paren (this);
822 break;
824 case UNARY_PLUS_EXPR:
825 pp_plus (this);
826 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
827 break;
829 default:
830 c_pretty_printer::unary_expression (t);
831 break;
835 /* cast-expression:
836 unary-expression
837 ( type-id ) cast-expression */
839 static void
840 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
842 switch (TREE_CODE (t))
844 case CAST_EXPR:
845 case IMPLICIT_CONV_EXPR:
846 pp->type_id (TREE_TYPE (t));
847 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
848 break;
850 default:
851 pp_c_cast_expression (pp, t);
852 break;
856 /* pm-expression:
857 cast-expression
858 pm-expression .* cast-expression
859 pm-expression ->* cast-expression */
861 static void
862 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
864 switch (TREE_CODE (t))
866 /* Handle unfortunate OFFSET_REF overloading here. */
867 case OFFSET_REF:
868 if (TYPE_P (TREE_OPERAND (t, 0)))
870 pp_cxx_qualified_id (pp, t);
871 break;
873 /* Else fall through. */
874 case MEMBER_REF:
875 case DOTSTAR_EXPR:
876 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
877 if (TREE_CODE (t) == MEMBER_REF)
878 pp_cxx_arrow (pp);
879 else
880 pp_cxx_dot (pp);
881 pp_star(pp);
882 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
883 break;
886 default:
887 pp_cxx_cast_expression (pp, t);
888 break;
892 /* multiplicative-expression:
893 pm-expression
894 multiplicative-expression * pm-expression
895 multiplicative-expression / pm-expression
896 multiplicative-expression % pm-expression */
898 void
899 cxx_pretty_printer::multiplicative_expression (tree e)
901 enum tree_code code = TREE_CODE (e);
902 switch (code)
904 case MULT_EXPR:
905 case TRUNC_DIV_EXPR:
906 case TRUNC_MOD_EXPR:
907 multiplicative_expression (TREE_OPERAND (e, 0));
908 pp_space (this);
909 if (code == MULT_EXPR)
910 pp_star (this);
911 else if (code == TRUNC_DIV_EXPR)
912 pp_slash (this);
913 else
914 pp_modulo (this);
915 pp_space (this);
916 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
917 break;
919 default:
920 pp_cxx_pm_expression (this, e);
921 break;
925 /* conditional-expression:
926 logical-or-expression
927 logical-or-expression ? expression : assignment-expression */
929 void
930 cxx_pretty_printer::conditional_expression (tree e)
932 if (TREE_CODE (e) == COND_EXPR)
934 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
935 pp_space (this);
936 pp_question (this);
937 pp_space (this);
938 expression (TREE_OPERAND (e, 1));
939 pp_space (this);
940 assignment_expression (TREE_OPERAND (e, 2));
942 else
943 pp_c_logical_or_expression (this, e);
946 /* Pretty-print a compound assignment operator token as indicated by T. */
948 static void
949 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
951 const char *op;
953 switch (TREE_CODE (t))
955 case NOP_EXPR:
956 op = "=";
957 break;
959 case PLUS_EXPR:
960 op = "+=";
961 break;
963 case MINUS_EXPR:
964 op = "-=";
965 break;
967 case TRUNC_DIV_EXPR:
968 op = "/=";
969 break;
971 case TRUNC_MOD_EXPR:
972 op = "%=";
973 break;
975 default:
976 op = get_tree_code_name (TREE_CODE (t));
977 break;
980 pp_cxx_ws_string (pp, op);
984 /* assignment-expression:
985 conditional-expression
986 logical-or-expression assignment-operator assignment-expression
987 throw-expression
989 throw-expression:
990 throw assignment-expression(opt)
992 assignment-operator: one of
993 = *= /= %= += -= >>= <<= &= ^= |= */
995 void
996 cxx_pretty_printer::assignment_expression (tree e)
998 switch (TREE_CODE (e))
1000 case MODIFY_EXPR:
1001 case INIT_EXPR:
1002 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1003 pp_space (this);
1004 pp_equal (this);
1005 pp_space (this);
1006 assignment_expression (TREE_OPERAND (e, 1));
1007 break;
1009 case THROW_EXPR:
1010 pp_cxx_ws_string (this, "throw");
1011 if (TREE_OPERAND (e, 0))
1012 assignment_expression (TREE_OPERAND (e, 0));
1013 break;
1015 case MODOP_EXPR:
1016 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1017 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1018 assignment_expression (TREE_OPERAND (e, 2));
1019 break;
1021 default:
1022 conditional_expression (e);
1023 break;
1027 void
1028 cxx_pretty_printer::expression (tree t)
1030 switch (TREE_CODE (t))
1032 case STRING_CST:
1033 case VOID_CST:
1034 case INTEGER_CST:
1035 case REAL_CST:
1036 case COMPLEX_CST:
1037 constant (t);
1038 break;
1040 case USERDEF_LITERAL:
1041 pp_cxx_userdef_literal (this, t);
1042 break;
1044 case RESULT_DECL:
1045 pp_cxx_unqualified_id (this, t);
1046 break;
1048 #if 0
1049 case OFFSET_REF:
1050 #endif
1051 case SCOPE_REF:
1052 case PTRMEM_CST:
1053 pp_cxx_qualified_id (this, t);
1054 break;
1056 case OVERLOAD:
1057 t = OVL_CURRENT (t);
1058 case VAR_DECL:
1059 case PARM_DECL:
1060 case FIELD_DECL:
1061 case CONST_DECL:
1062 case FUNCTION_DECL:
1063 case BASELINK:
1064 case TEMPLATE_DECL:
1065 case TEMPLATE_TYPE_PARM:
1066 case TEMPLATE_PARM_INDEX:
1067 case TEMPLATE_TEMPLATE_PARM:
1068 case STMT_EXPR:
1069 case REQUIRES_EXPR:
1070 primary_expression (t);
1071 break;
1073 case CALL_EXPR:
1074 case DYNAMIC_CAST_EXPR:
1075 case STATIC_CAST_EXPR:
1076 case REINTERPRET_CAST_EXPR:
1077 case CONST_CAST_EXPR:
1078 #if 0
1079 case MEMBER_REF:
1080 #endif
1081 case EMPTY_CLASS_EXPR:
1082 case TYPEID_EXPR:
1083 case PSEUDO_DTOR_EXPR:
1084 case AGGR_INIT_EXPR:
1085 case ARROW_EXPR:
1086 postfix_expression (t);
1087 break;
1089 case NEW_EXPR:
1090 case VEC_NEW_EXPR:
1091 pp_cxx_new_expression (this, t);
1092 break;
1094 case DELETE_EXPR:
1095 case VEC_DELETE_EXPR:
1096 pp_cxx_delete_expression (this, t);
1097 break;
1099 case SIZEOF_EXPR:
1100 case ALIGNOF_EXPR:
1101 case NOEXCEPT_EXPR:
1102 unary_expression (t);
1103 break;
1105 case CAST_EXPR:
1106 case IMPLICIT_CONV_EXPR:
1107 pp_cxx_cast_expression (this, t);
1108 break;
1110 case OFFSET_REF:
1111 case MEMBER_REF:
1112 case DOTSTAR_EXPR:
1113 pp_cxx_pm_expression (this, t);
1114 break;
1116 case MULT_EXPR:
1117 case TRUNC_DIV_EXPR:
1118 case TRUNC_MOD_EXPR:
1119 multiplicative_expression (t);
1120 break;
1122 case COND_EXPR:
1123 conditional_expression (t);
1124 break;
1126 case MODIFY_EXPR:
1127 case INIT_EXPR:
1128 case THROW_EXPR:
1129 case MODOP_EXPR:
1130 assignment_expression (t);
1131 break;
1133 case NON_DEPENDENT_EXPR:
1134 case MUST_NOT_THROW_EXPR:
1135 expression (TREE_OPERAND (t, 0));
1136 break;
1138 case EXPR_PACK_EXPANSION:
1139 expression (PACK_EXPANSION_PATTERN (t));
1140 pp_cxx_ws_string (this, "...");
1141 break;
1143 case TEMPLATE_ID_EXPR:
1144 pp_cxx_template_id (this, t);
1145 break;
1147 case NONTYPE_ARGUMENT_PACK:
1149 tree args = ARGUMENT_PACK_ARGS (t);
1150 int i, len = TREE_VEC_LENGTH (args);
1151 for (i = 0; i < len; ++i)
1153 if (i > 0)
1154 pp_cxx_separate_with (this, ',');
1155 expression (TREE_VEC_ELT (args, i));
1158 break;
1160 case LAMBDA_EXPR:
1161 pp_cxx_ws_string (this, "<lambda>");
1162 break;
1164 case TRAIT_EXPR:
1165 pp_cxx_trait_expression (this, t);
1166 break;
1168 case PRED_CONSTR:
1169 case EXPR_CONSTR:
1170 case TYPE_CONSTR:
1171 case ICONV_CONSTR:
1172 case DEDUCT_CONSTR:
1173 case EXCEPT_CONSTR:
1174 case PARM_CONSTR:
1175 case CONJ_CONSTR:
1176 case DISJ_CONSTR:
1177 pp_cxx_constraint (this, t);
1178 break;
1180 case PAREN_EXPR:
1181 pp_cxx_left_paren (this);
1182 expression (TREE_OPERAND (t, 0));
1183 pp_cxx_right_paren (this);
1184 break;
1186 default:
1187 c_pretty_printer::expression (t);
1188 break;
1193 /* Declarations. */
1195 /* function-specifier:
1196 inline
1197 virtual
1198 explicit */
1200 void
1201 cxx_pretty_printer::function_specifier (tree t)
1203 switch (TREE_CODE (t))
1205 case FUNCTION_DECL:
1206 if (DECL_VIRTUAL_P (t))
1207 pp_cxx_ws_string (this, "virtual");
1208 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1209 pp_cxx_ws_string (this, "explicit");
1210 else
1211 c_pretty_printer::function_specifier (t);
1213 default:
1214 break;
1218 /* decl-specifier-seq:
1219 decl-specifier-seq(opt) decl-specifier
1221 decl-specifier:
1222 storage-class-specifier
1223 type-specifier
1224 function-specifier
1225 friend
1226 typedef */
1228 void
1229 cxx_pretty_printer::declaration_specifiers (tree t)
1231 switch (TREE_CODE (t))
1233 case VAR_DECL:
1234 case PARM_DECL:
1235 case CONST_DECL:
1236 case FIELD_DECL:
1237 storage_class_specifier (t);
1238 declaration_specifiers (TREE_TYPE (t));
1239 break;
1241 case TYPE_DECL:
1242 pp_cxx_ws_string (this, "typedef");
1243 declaration_specifiers (TREE_TYPE (t));
1244 break;
1246 case FUNCTION_DECL:
1247 /* Constructors don't have return types. And conversion functions
1248 do not have a type-specifier in their return types. */
1249 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1250 function_specifier (t);
1251 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1252 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1253 else
1254 default:
1255 c_pretty_printer::declaration_specifiers (t);
1256 break;
1260 /* simple-type-specifier:
1261 ::(opt) nested-name-specifier(opt) type-name
1262 ::(opt) nested-name-specifier(opt) template(opt) template-id
1263 char
1264 wchar_t
1265 bool
1266 short
1268 long
1269 signed
1270 unsigned
1271 float
1272 double
1273 void */
1275 void
1276 cxx_pretty_printer::simple_type_specifier (tree t)
1278 switch (TREE_CODE (t))
1280 case RECORD_TYPE:
1281 case UNION_TYPE:
1282 case ENUMERAL_TYPE:
1283 pp_cxx_qualified_id (this, t);
1284 break;
1286 case TEMPLATE_TYPE_PARM:
1287 case TEMPLATE_TEMPLATE_PARM:
1288 case TEMPLATE_PARM_INDEX:
1289 case BOUND_TEMPLATE_TEMPLATE_PARM:
1290 pp_cxx_unqualified_id (this, t);
1291 break;
1293 case TYPENAME_TYPE:
1294 pp_cxx_ws_string (this, "typename");
1295 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1296 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1297 break;
1299 default:
1300 c_pretty_printer::simple_type_specifier (t);
1301 break;
1305 /* type-specifier-seq:
1306 type-specifier type-specifier-seq(opt)
1308 type-specifier:
1309 simple-type-specifier
1310 class-specifier
1311 enum-specifier
1312 elaborated-type-specifier
1313 cv-qualifier */
1315 static void
1316 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1318 switch (TREE_CODE (t))
1320 case TEMPLATE_DECL:
1321 case TEMPLATE_TYPE_PARM:
1322 case TEMPLATE_TEMPLATE_PARM:
1323 case TYPE_DECL:
1324 case BOUND_TEMPLATE_TEMPLATE_PARM:
1325 pp_cxx_cv_qualifier_seq (pp, t);
1326 pp->simple_type_specifier (t);
1327 break;
1329 case METHOD_TYPE:
1330 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1331 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1332 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1333 break;
1335 case DECLTYPE_TYPE:
1336 pp_cxx_ws_string (pp, "decltype");
1337 pp_cxx_left_paren (pp);
1338 pp->expression (DECLTYPE_TYPE_EXPR (t));
1339 pp_cxx_right_paren (pp);
1340 break;
1342 case RECORD_TYPE:
1343 if (TYPE_PTRMEMFUNC_P (t))
1345 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1346 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1347 pp_cxx_whitespace (pp);
1348 pp_cxx_ptr_operator (pp, t);
1349 break;
1351 /* else fall through */
1353 default:
1354 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1355 pp_c_specifier_qualifier_list (pp, t);
1359 /* ptr-operator:
1360 * cv-qualifier-seq(opt)
1362 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1364 static void
1365 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1367 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1368 t = TREE_TYPE (t);
1369 switch (TREE_CODE (t))
1371 case REFERENCE_TYPE:
1372 case POINTER_TYPE:
1373 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1374 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1375 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1376 if (TYPE_PTR_P (t))
1378 pp_star (pp);
1379 pp_cxx_cv_qualifier_seq (pp, t);
1381 else
1382 pp_ampersand (pp);
1383 break;
1385 case RECORD_TYPE:
1386 if (TYPE_PTRMEMFUNC_P (t))
1388 pp_cxx_left_paren (pp);
1389 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1390 pp_star (pp);
1391 break;
1393 case OFFSET_TYPE:
1394 if (TYPE_PTRMEM_P (t))
1396 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1397 pp_cxx_left_paren (pp);
1398 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1399 pp_star (pp);
1400 pp_cxx_cv_qualifier_seq (pp, t);
1401 break;
1403 /* else fall through. */
1405 default:
1406 pp_unsupported_tree (pp, t);
1407 break;
1411 static inline tree
1412 pp_cxx_implicit_parameter_type (tree mf)
1414 return class_of_this_parm (TREE_TYPE (mf));
1418 parameter-declaration:
1419 decl-specifier-seq declarator
1420 decl-specifier-seq declarator = assignment-expression
1421 decl-specifier-seq abstract-declarator(opt)
1422 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1424 static inline void
1425 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1427 pp->declaration_specifiers (t);
1428 if (TYPE_P (t))
1429 pp->abstract_declarator (t);
1430 else
1431 pp->declarator (t);
1434 /* parameter-declaration-clause:
1435 parameter-declaration-list(opt) ...(opt)
1436 parameter-declaration-list , ...
1438 parameter-declaration-list:
1439 parameter-declaration
1440 parameter-declaration-list , parameter-declaration */
1442 static void
1443 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1445 tree args;
1446 tree types;
1447 bool abstract;
1449 // For a requires clause or the explicit printing of a parameter list
1450 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1451 // args and types are taken from the function decl T.
1452 if (TREE_CODE (t) == PARM_DECL)
1454 args = t;
1455 types = t;
1456 abstract = false;
1458 else
1460 bool type_p = TYPE_P (t);
1461 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1462 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1463 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1465 bool first = true;
1467 /* Skip artificial parameter for nonstatic member functions. */
1468 if (TREE_CODE (t) == METHOD_TYPE)
1469 types = TREE_CHAIN (types);
1471 pp_cxx_left_paren (pp);
1472 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1474 if (!first)
1475 pp_cxx_separate_with (pp, ',');
1476 first = false;
1477 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1478 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1480 pp_cxx_whitespace (pp);
1481 pp_equal (pp);
1482 pp_cxx_whitespace (pp);
1483 pp->assignment_expression (TREE_PURPOSE (types));
1486 pp_cxx_right_paren (pp);
1489 /* exception-specification:
1490 throw ( type-id-list(opt) )
1492 type-id-list
1493 type-id
1494 type-id-list , type-id */
1496 static void
1497 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1499 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1500 bool need_comma = false;
1502 if (ex_spec == NULL)
1503 return;
1504 if (TREE_PURPOSE (ex_spec))
1506 pp_cxx_ws_string (pp, "noexcept");
1507 pp_cxx_whitespace (pp);
1508 pp_cxx_left_paren (pp);
1509 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1510 pp_cxx_ws_string (pp, "<uninstantiated>");
1511 else
1512 pp->expression (TREE_PURPOSE (ex_spec));
1513 pp_cxx_right_paren (pp);
1514 return;
1516 pp_cxx_ws_string (pp, "throw");
1517 pp_cxx_left_paren (pp);
1518 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1520 tree type = TREE_VALUE (ex_spec);
1521 tree argpack = NULL_TREE;
1522 int i, len = 1;
1524 if (ARGUMENT_PACK_P (type))
1526 argpack = ARGUMENT_PACK_ARGS (type);
1527 len = TREE_VEC_LENGTH (argpack);
1530 for (i = 0; i < len; ++i)
1532 if (argpack)
1533 type = TREE_VEC_ELT (argpack, i);
1535 if (need_comma)
1536 pp_cxx_separate_with (pp, ',');
1537 else
1538 need_comma = true;
1540 pp->type_id (type);
1543 pp_cxx_right_paren (pp);
1546 /* direct-declarator:
1547 declarator-id
1548 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1549 exception-specification(opt)
1550 direct-declaration [ constant-expression(opt) ]
1551 ( declarator ) */
1553 void
1554 cxx_pretty_printer::direct_declarator (tree t)
1556 switch (TREE_CODE (t))
1558 case VAR_DECL:
1559 case PARM_DECL:
1560 case CONST_DECL:
1561 case FIELD_DECL:
1562 if (DECL_NAME (t))
1564 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1566 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1567 || template_parameter_pack_p (t))
1568 /* A function parameter pack or non-type template
1569 parameter pack. */
1570 pp_cxx_ws_string (this, "...");
1572 id_expression (DECL_NAME (t));
1574 abstract_declarator (TREE_TYPE (t));
1575 break;
1577 case FUNCTION_DECL:
1578 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1579 expression (t);
1580 pp_cxx_parameter_declaration_clause (this, t);
1582 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1584 padding = pp_before;
1585 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1588 pp_cxx_exception_specification (this, TREE_TYPE (t));
1589 break;
1591 case TYPENAME_TYPE:
1592 case TEMPLATE_DECL:
1593 case TEMPLATE_TYPE_PARM:
1594 case TEMPLATE_PARM_INDEX:
1595 case TEMPLATE_TEMPLATE_PARM:
1596 break;
1598 default:
1599 c_pretty_printer::direct_declarator (t);
1600 break;
1604 /* declarator:
1605 direct-declarator
1606 ptr-operator declarator */
1608 void
1609 cxx_pretty_printer::declarator (tree t)
1611 direct_declarator (t);
1613 // Print a requires clause.
1614 if (flag_concepts)
1615 if (tree ci = get_constraints (t))
1616 if (tree reqs = CI_DECLARATOR_REQS (ci))
1617 pp_cxx_requires_clause (this, reqs);
1620 /* ctor-initializer:
1621 : mem-initializer-list
1623 mem-initializer-list:
1624 mem-initializer
1625 mem-initializer , mem-initializer-list
1627 mem-initializer:
1628 mem-initializer-id ( expression-list(opt) )
1630 mem-initializer-id:
1631 ::(opt) nested-name-specifier(opt) class-name
1632 identifier */
1634 static void
1635 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1637 t = TREE_OPERAND (t, 0);
1638 pp_cxx_whitespace (pp);
1639 pp_colon (pp);
1640 pp_cxx_whitespace (pp);
1641 for (; t; t = TREE_CHAIN (t))
1643 tree purpose = TREE_PURPOSE (t);
1644 bool is_pack = PACK_EXPANSION_P (purpose);
1646 if (is_pack)
1647 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1648 else
1649 pp->primary_expression (purpose);
1650 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1651 if (is_pack)
1652 pp_cxx_ws_string (pp, "...");
1653 if (TREE_CHAIN (t))
1654 pp_cxx_separate_with (pp, ',');
1658 /* function-definition:
1659 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1660 decl-specifier-seq(opt) declarator function-try-block */
1662 static void
1663 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1665 tree saved_scope = pp->enclosing_scope;
1666 pp->declaration_specifiers (t);
1667 pp->declarator (t);
1668 pp_needs_newline (pp) = true;
1669 pp->enclosing_scope = DECL_CONTEXT (t);
1670 if (DECL_SAVED_TREE (t))
1671 pp->statement (DECL_SAVED_TREE (t));
1672 else
1673 pp_cxx_semicolon (pp);
1674 pp_newline_and_flush (pp);
1675 pp->enclosing_scope = saved_scope;
1678 /* abstract-declarator:
1679 ptr-operator abstract-declarator(opt)
1680 direct-abstract-declarator */
1682 void
1683 cxx_pretty_printer::abstract_declarator (tree t)
1685 if (TYPE_PTRMEM_P (t))
1686 pp_cxx_right_paren (this);
1687 else if (POINTER_TYPE_P (t))
1689 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1690 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1691 pp_cxx_right_paren (this);
1692 t = TREE_TYPE (t);
1694 direct_abstract_declarator (t);
1697 /* direct-abstract-declarator:
1698 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1699 cv-qualifier-seq(opt) exception-specification(opt)
1700 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1701 ( abstract-declarator ) */
1703 void
1704 cxx_pretty_printer::direct_abstract_declarator (tree t)
1706 switch (TREE_CODE (t))
1708 case REFERENCE_TYPE:
1709 abstract_declarator (t);
1710 break;
1712 case RECORD_TYPE:
1713 if (TYPE_PTRMEMFUNC_P (t))
1714 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1715 break;
1717 case METHOD_TYPE:
1718 case FUNCTION_TYPE:
1719 pp_cxx_parameter_declaration_clause (this, t);
1720 direct_abstract_declarator (TREE_TYPE (t));
1721 if (TREE_CODE (t) == METHOD_TYPE)
1723 padding = pp_before;
1724 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1726 pp_cxx_exception_specification (this, t);
1727 break;
1729 case TYPENAME_TYPE:
1730 case TEMPLATE_TYPE_PARM:
1731 case TEMPLATE_TEMPLATE_PARM:
1732 case BOUND_TEMPLATE_TEMPLATE_PARM:
1733 case UNBOUND_CLASS_TEMPLATE:
1734 break;
1736 default:
1737 c_pretty_printer::direct_abstract_declarator (t);
1738 break;
1742 /* type-id:
1743 type-specifier-seq abstract-declarator(opt) */
1745 void
1746 cxx_pretty_printer::type_id (tree t)
1748 pp_flags saved_flags = flags;
1749 flags |= pp_c_flag_abstract;
1751 switch (TREE_CODE (t))
1753 case TYPE_DECL:
1754 case UNION_TYPE:
1755 case RECORD_TYPE:
1756 case ENUMERAL_TYPE:
1757 case TYPENAME_TYPE:
1758 case BOUND_TEMPLATE_TEMPLATE_PARM:
1759 case UNBOUND_CLASS_TEMPLATE:
1760 case TEMPLATE_TEMPLATE_PARM:
1761 case TEMPLATE_TYPE_PARM:
1762 case TEMPLATE_PARM_INDEX:
1763 case TEMPLATE_DECL:
1764 case TYPEOF_TYPE:
1765 case UNDERLYING_TYPE:
1766 case DECLTYPE_TYPE:
1767 case TEMPLATE_ID_EXPR:
1768 pp_cxx_type_specifier_seq (this, t);
1769 break;
1771 case TYPE_PACK_EXPANSION:
1772 type_id (PACK_EXPANSION_PATTERN (t));
1773 pp_cxx_ws_string (this, "...");
1774 break;
1776 default:
1777 c_pretty_printer::type_id (t);
1778 break;
1781 flags = saved_flags;
1784 /* template-argument-list:
1785 template-argument ...(opt)
1786 template-argument-list, template-argument ...(opt)
1788 template-argument:
1789 assignment-expression
1790 type-id
1791 template-name */
1793 static void
1794 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1796 int i;
1797 bool need_comma = false;
1799 if (t == NULL)
1800 return;
1801 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1803 tree arg = TREE_VEC_ELT (t, i);
1804 tree argpack = NULL_TREE;
1805 int idx, len = 1;
1807 if (ARGUMENT_PACK_P (arg))
1809 argpack = ARGUMENT_PACK_ARGS (arg);
1810 len = TREE_VEC_LENGTH (argpack);
1813 for (idx = 0; idx < len; idx++)
1815 if (argpack)
1816 arg = TREE_VEC_ELT (argpack, idx);
1818 if (need_comma)
1819 pp_cxx_separate_with (pp, ',');
1820 else
1821 need_comma = true;
1823 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1824 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1825 pp->type_id (arg);
1826 else
1827 pp->expression (arg);
1833 static void
1834 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1836 t = DECL_EXPR_DECL (t);
1837 pp_cxx_type_specifier_seq (pp, t);
1838 if (TYPE_P (t))
1839 pp->abstract_declarator (t);
1840 else
1841 pp->declarator (t);
1844 /* Statements. */
1846 void
1847 cxx_pretty_printer::statement (tree t)
1849 switch (TREE_CODE (t))
1851 case CTOR_INITIALIZER:
1852 pp_cxx_ctor_initializer (this, t);
1853 break;
1855 case USING_STMT:
1856 pp_cxx_ws_string (this, "using");
1857 pp_cxx_ws_string (this, "namespace");
1858 if (DECL_CONTEXT (t))
1859 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1860 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1861 break;
1863 case USING_DECL:
1864 pp_cxx_ws_string (this, "using");
1865 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1866 pp_cxx_unqualified_id (this, DECL_NAME (t));
1867 break;
1869 case EH_SPEC_BLOCK:
1870 break;
1872 /* try-block:
1873 try compound-statement handler-seq */
1874 case TRY_BLOCK:
1875 pp_maybe_newline_and_indent (this, 0);
1876 pp_cxx_ws_string (this, "try");
1877 pp_newline_and_indent (this, 3);
1878 statement (TRY_STMTS (t));
1879 pp_newline_and_indent (this, -3);
1880 if (CLEANUP_P (t))
1882 else
1883 statement (TRY_HANDLERS (t));
1884 break;
1887 handler-seq:
1888 handler handler-seq(opt)
1890 handler:
1891 catch ( exception-declaration ) compound-statement
1893 exception-declaration:
1894 type-specifier-seq declarator
1895 type-specifier-seq abstract-declarator
1896 ... */
1897 case HANDLER:
1898 pp_cxx_ws_string (this, "catch");
1899 pp_cxx_left_paren (this);
1900 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1901 pp_cxx_right_paren (this);
1902 pp_indentation (this) += 3;
1903 pp_needs_newline (this) = true;
1904 statement (HANDLER_BODY (t));
1905 pp_indentation (this) -= 3;
1906 pp_needs_newline (this) = true;
1907 break;
1909 /* selection-statement:
1910 if ( expression ) statement
1911 if ( expression ) statement else statement */
1912 case IF_STMT:
1913 pp_cxx_ws_string (this, "if");
1914 pp_cxx_whitespace (this);
1915 pp_cxx_left_paren (this);
1916 expression (IF_COND (t));
1917 pp_cxx_right_paren (this);
1918 pp_newline_and_indent (this, 2);
1919 statement (THEN_CLAUSE (t));
1920 pp_newline_and_indent (this, -2);
1921 if (ELSE_CLAUSE (t))
1923 tree else_clause = ELSE_CLAUSE (t);
1924 pp_cxx_ws_string (this, "else");
1925 if (TREE_CODE (else_clause) == IF_STMT)
1926 pp_cxx_whitespace (this);
1927 else
1928 pp_newline_and_indent (this, 2);
1929 statement (else_clause);
1930 if (TREE_CODE (else_clause) != IF_STMT)
1931 pp_newline_and_indent (this, -2);
1933 break;
1935 case SWITCH_STMT:
1936 pp_cxx_ws_string (this, "switch");
1937 pp_space (this);
1938 pp_cxx_left_paren (this);
1939 expression (SWITCH_STMT_COND (t));
1940 pp_cxx_right_paren (this);
1941 pp_indentation (this) += 3;
1942 pp_needs_newline (this) = true;
1943 statement (SWITCH_STMT_BODY (t));
1944 pp_newline_and_indent (this, -3);
1945 break;
1947 /* iteration-statement:
1948 while ( expression ) statement
1949 do statement while ( expression ) ;
1950 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1951 for ( declaration expression(opt) ; expression(opt) ) statement */
1952 case WHILE_STMT:
1953 pp_cxx_ws_string (this, "while");
1954 pp_space (this);
1955 pp_cxx_left_paren (this);
1956 expression (WHILE_COND (t));
1957 pp_cxx_right_paren (this);
1958 pp_newline_and_indent (this, 3);
1959 statement (WHILE_BODY (t));
1960 pp_indentation (this) -= 3;
1961 pp_needs_newline (this) = true;
1962 break;
1964 case DO_STMT:
1965 pp_cxx_ws_string (this, "do");
1966 pp_newline_and_indent (this, 3);
1967 statement (DO_BODY (t));
1968 pp_newline_and_indent (this, -3);
1969 pp_cxx_ws_string (this, "while");
1970 pp_space (this);
1971 pp_cxx_left_paren (this);
1972 expression (DO_COND (t));
1973 pp_cxx_right_paren (this);
1974 pp_cxx_semicolon (this);
1975 pp_needs_newline (this) = true;
1976 break;
1978 case FOR_STMT:
1979 pp_cxx_ws_string (this, "for");
1980 pp_space (this);
1981 pp_cxx_left_paren (this);
1982 if (FOR_INIT_STMT (t))
1983 statement (FOR_INIT_STMT (t));
1984 else
1985 pp_cxx_semicolon (this);
1986 pp_needs_newline (this) = false;
1987 pp_cxx_whitespace (this);
1988 if (FOR_COND (t))
1989 expression (FOR_COND (t));
1990 pp_cxx_semicolon (this);
1991 pp_needs_newline (this) = false;
1992 pp_cxx_whitespace (this);
1993 if (FOR_EXPR (t))
1994 expression (FOR_EXPR (t));
1995 pp_cxx_right_paren (this);
1996 pp_newline_and_indent (this, 3);
1997 statement (FOR_BODY (t));
1998 pp_indentation (this) -= 3;
1999 pp_needs_newline (this) = true;
2000 break;
2002 case RANGE_FOR_STMT:
2003 pp_cxx_ws_string (this, "for");
2004 pp_space (this);
2005 pp_cxx_left_paren (this);
2006 statement (RANGE_FOR_DECL (t));
2007 pp_space (this);
2008 pp_needs_newline (this) = false;
2009 pp_colon (this);
2010 pp_space (this);
2011 statement (RANGE_FOR_EXPR (t));
2012 pp_cxx_right_paren (this);
2013 pp_newline_and_indent (this, 3);
2014 statement (FOR_BODY (t));
2015 pp_indentation (this) -= 3;
2016 pp_needs_newline (this) = true;
2017 break;
2019 /* jump-statement:
2020 goto identifier;
2021 continue ;
2022 return expression(opt) ; */
2023 case BREAK_STMT:
2024 case CONTINUE_STMT:
2025 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2026 pp_cxx_semicolon (this);
2027 pp_needs_newline (this) = true;
2028 break;
2030 /* expression-statement:
2031 expression(opt) ; */
2032 case EXPR_STMT:
2033 expression (EXPR_STMT_EXPR (t));
2034 pp_cxx_semicolon (this);
2035 pp_needs_newline (this) = true;
2036 break;
2038 case CLEANUP_STMT:
2039 pp_cxx_ws_string (this, "try");
2040 pp_newline_and_indent (this, 2);
2041 statement (CLEANUP_BODY (t));
2042 pp_newline_and_indent (this, -2);
2043 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2044 pp_newline_and_indent (this, 2);
2045 statement (CLEANUP_EXPR (t));
2046 pp_newline_and_indent (this, -2);
2047 break;
2049 case STATIC_ASSERT:
2050 declaration (t);
2051 break;
2053 default:
2054 c_pretty_printer::statement (t);
2055 break;
2059 /* original-namespace-definition:
2060 namespace identifier { namespace-body }
2062 As an edge case, we also handle unnamed namespace definition here. */
2064 static void
2065 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2067 pp_cxx_ws_string (pp, "namespace");
2068 if (DECL_CONTEXT (t))
2069 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2070 if (DECL_NAME (t))
2071 pp_cxx_unqualified_id (pp, t);
2072 pp_cxx_whitespace (pp);
2073 pp_cxx_left_brace (pp);
2074 /* We do not print the namespace-body. */
2075 pp_cxx_whitespace (pp);
2076 pp_cxx_right_brace (pp);
2079 /* namespace-alias:
2080 identifier
2082 namespace-alias-definition:
2083 namespace identifier = qualified-namespace-specifier ;
2085 qualified-namespace-specifier:
2086 ::(opt) nested-name-specifier(opt) namespace-name */
2088 static void
2089 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2091 pp_cxx_ws_string (pp, "namespace");
2092 if (DECL_CONTEXT (t))
2093 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2094 pp_cxx_unqualified_id (pp, t);
2095 pp_cxx_whitespace (pp);
2096 pp_equal (pp);
2097 pp_cxx_whitespace (pp);
2098 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2099 pp_cxx_nested_name_specifier (pp,
2100 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2101 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2102 pp_cxx_semicolon (pp);
2105 /* simple-declaration:
2106 decl-specifier-seq(opt) init-declarator-list(opt) */
2108 static void
2109 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2111 pp->declaration_specifiers (t);
2112 pp_cxx_init_declarator (pp, t);
2113 pp_cxx_semicolon (pp);
2114 pp_needs_newline (pp) = true;
2118 template-parameter-list:
2119 template-parameter
2120 template-parameter-list , template-parameter */
2122 static inline void
2123 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2125 const int n = TREE_VEC_LENGTH (t);
2126 int i;
2127 for (i = 0; i < n; ++i)
2129 if (i)
2130 pp_cxx_separate_with (pp, ',');
2131 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2135 /* template-parameter:
2136 type-parameter
2137 parameter-declaration
2139 type-parameter:
2140 class ...(opt) identifier(opt)
2141 class identifier(opt) = type-id
2142 typename identifier(opt)
2143 typename ...(opt) identifier(opt) = type-id
2144 template < template-parameter-list > class ...(opt) identifier(opt)
2145 template < template-parameter-list > class identifier(opt) = template-name */
2147 static void
2148 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2150 tree parameter = TREE_VALUE (t);
2151 switch (TREE_CODE (parameter))
2153 case TYPE_DECL:
2154 pp_cxx_ws_string (pp, "class");
2155 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2156 pp_cxx_ws_string (pp, "...");
2157 if (DECL_NAME (parameter))
2158 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2159 /* FIXME: Check if we should print also default argument. */
2160 break;
2162 case PARM_DECL:
2163 pp_cxx_parameter_declaration (pp, parameter);
2164 break;
2166 case TEMPLATE_DECL:
2167 break;
2169 default:
2170 pp_unsupported_tree (pp, t);
2171 break;
2175 /* Pretty-print a template parameter in the canonical form
2176 "template-parameter-<level>-<position in parameter list>". */
2178 void
2179 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2181 const enum tree_code code = TREE_CODE (parm);
2183 /* Brings type template parameters to the canonical forms. */
2184 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2185 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2186 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2188 pp_cxx_begin_template_argument_list (pp);
2189 pp->translate_string ("template-parameter-");
2190 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2191 pp_minus (pp);
2192 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2193 pp_cxx_end_template_argument_list (pp);
2196 /* Print a constrained-type-specifier. */
2198 void
2199 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2201 tree t, a;
2202 placeholder_extract_concept_and_args (c, t, a);
2203 pp->id_expression (t);
2204 if (TREE_VEC_LENGTH (a) > 1)
2206 pp_cxx_begin_template_argument_list (pp);
2207 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2208 for (int i = TREE_VEC_LENGTH (a) - 1; i > 0; --i)
2209 TREE_VEC_ELT (args, i-1) = TREE_VEC_ELT (a, i);
2210 pp_cxx_template_argument_list (pp, args);
2211 ggc_free (args);
2212 pp_cxx_end_template_argument_list (pp);
2217 template-declaration:
2218 export(opt) template < template-parameter-list > declaration
2220 Concept extensions:
2222 template-declaration:
2223 export(opt) template < template-parameter-list >
2224 requires-clause(opt) declaration */
2226 static void
2227 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2229 tree tmpl = most_general_template (t);
2230 tree level;
2232 pp_maybe_newline_and_indent (pp, 0);
2233 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2235 pp_cxx_ws_string (pp, "template");
2236 pp_cxx_begin_template_argument_list (pp);
2237 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2238 pp_cxx_end_template_argument_list (pp);
2239 pp_newline_and_indent (pp, 3);
2242 if (flag_concepts)
2243 if (tree ci = get_constraints (t))
2244 if (tree reqs = CI_TEMPLATE_REQS (ci))
2246 pp_cxx_requires_clause (pp, reqs);
2247 pp_newline_and_indent (pp, 6);
2250 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2251 pp_cxx_function_definition (pp, t);
2252 else
2253 pp_cxx_simple_declaration (pp, t);
2256 static void
2257 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2259 pp_unsupported_tree (pp, t);
2262 static void
2263 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2265 pp_unsupported_tree (pp, t);
2269 declaration:
2270 block-declaration
2271 function-definition
2272 template-declaration
2273 explicit-instantiation
2274 explicit-specialization
2275 linkage-specification
2276 namespace-definition
2278 block-declaration:
2279 simple-declaration
2280 asm-definition
2281 namespace-alias-definition
2282 using-declaration
2283 using-directive
2284 static_assert-declaration */
2285 void
2286 cxx_pretty_printer::declaration (tree t)
2288 if (TREE_CODE (t) == STATIC_ASSERT)
2290 pp_cxx_ws_string (this, "static_assert");
2291 pp_cxx_left_paren (this);
2292 expression (STATIC_ASSERT_CONDITION (t));
2293 pp_cxx_separate_with (this, ',');
2294 expression (STATIC_ASSERT_MESSAGE (t));
2295 pp_cxx_right_paren (this);
2297 else if (!DECL_LANG_SPECIFIC (t))
2298 pp_cxx_simple_declaration (this, t);
2299 else if (DECL_USE_TEMPLATE (t))
2300 switch (DECL_USE_TEMPLATE (t))
2302 case 1:
2303 pp_cxx_template_declaration (this, t);
2304 break;
2306 case 2:
2307 pp_cxx_explicit_specialization (this, t);
2308 break;
2310 case 3:
2311 pp_cxx_explicit_instantiation (this, t);
2312 break;
2314 default:
2315 break;
2317 else switch (TREE_CODE (t))
2319 case VAR_DECL:
2320 case TYPE_DECL:
2321 pp_cxx_simple_declaration (this, t);
2322 break;
2324 case FUNCTION_DECL:
2325 if (DECL_SAVED_TREE (t))
2326 pp_cxx_function_definition (this, t);
2327 else
2328 pp_cxx_simple_declaration (this, t);
2329 break;
2331 case NAMESPACE_DECL:
2332 if (DECL_NAMESPACE_ALIAS (t))
2333 pp_cxx_namespace_alias_definition (this, t);
2334 else
2335 pp_cxx_original_namespace_definition (this, t);
2336 break;
2338 default:
2339 pp_unsupported_tree (this, t);
2340 break;
2344 static void
2345 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2347 t = TREE_OPERAND (t, 0);
2348 pp_cxx_ws_string (pp, "typeid");
2349 pp_cxx_left_paren (pp);
2350 if (TYPE_P (t))
2351 pp->type_id (t);
2352 else
2353 pp->expression (t);
2354 pp_cxx_right_paren (pp);
2357 void
2358 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2360 pp_cxx_ws_string (pp, "va_arg");
2361 pp_cxx_left_paren (pp);
2362 pp->assignment_expression (TREE_OPERAND (t, 0));
2363 pp_cxx_separate_with (pp, ',');
2364 pp->type_id (TREE_TYPE (t));
2365 pp_cxx_right_paren (pp);
2368 static bool
2369 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2371 switch (TREE_CODE (t))
2373 case ARROW_EXPR:
2374 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2375 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2377 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2378 pp_cxx_separate_with (pp, ',');
2379 return true;
2381 return false;
2382 case COMPONENT_REF:
2383 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2384 return false;
2385 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2386 pp_cxx_dot (pp);
2387 pp->expression (TREE_OPERAND (t, 1));
2388 return true;
2389 case ARRAY_REF:
2390 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2391 return false;
2392 pp_left_bracket (pp);
2393 pp->expression (TREE_OPERAND (t, 1));
2394 pp_right_bracket (pp);
2395 return true;
2396 default:
2397 return false;
2401 void
2402 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2404 pp_cxx_ws_string (pp, "offsetof");
2405 pp_cxx_left_paren (pp);
2406 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2407 pp->expression (TREE_OPERAND (t, 0));
2408 pp_cxx_right_paren (pp);
2411 void
2412 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2414 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2416 switch (kind)
2418 case CPTK_HAS_NOTHROW_ASSIGN:
2419 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2420 break;
2421 case CPTK_HAS_TRIVIAL_ASSIGN:
2422 pp_cxx_ws_string (pp, "__has_trivial_assign");
2423 break;
2424 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2425 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2426 break;
2427 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2428 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2429 break;
2430 case CPTK_HAS_NOTHROW_COPY:
2431 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2432 break;
2433 case CPTK_HAS_TRIVIAL_COPY:
2434 pp_cxx_ws_string (pp, "__has_trivial_copy");
2435 break;
2436 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2437 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2438 break;
2439 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2440 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2441 break;
2442 case CPTK_IS_ABSTRACT:
2443 pp_cxx_ws_string (pp, "__is_abstract");
2444 break;
2445 case CPTK_IS_BASE_OF:
2446 pp_cxx_ws_string (pp, "__is_base_of");
2447 break;
2448 case CPTK_IS_CLASS:
2449 pp_cxx_ws_string (pp, "__is_class");
2450 break;
2451 case CPTK_IS_EMPTY:
2452 pp_cxx_ws_string (pp, "__is_empty");
2453 break;
2454 case CPTK_IS_ENUM:
2455 pp_cxx_ws_string (pp, "__is_enum");
2456 break;
2457 case CPTK_IS_FINAL:
2458 pp_cxx_ws_string (pp, "__is_final");
2459 break;
2460 case CPTK_IS_POD:
2461 pp_cxx_ws_string (pp, "__is_pod");
2462 break;
2463 case CPTK_IS_POLYMORPHIC:
2464 pp_cxx_ws_string (pp, "__is_polymorphic");
2465 break;
2466 case CPTK_IS_SAME_AS:
2467 pp_cxx_ws_string (pp, "__is_same_as");
2468 break;
2469 case CPTK_IS_STD_LAYOUT:
2470 pp_cxx_ws_string (pp, "__is_std_layout");
2471 break;
2472 case CPTK_IS_TRIVIAL:
2473 pp_cxx_ws_string (pp, "__is_trivial");
2474 break;
2475 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2476 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2477 break;
2478 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2479 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2480 break;
2481 case CPTK_IS_TRIVIALLY_COPYABLE:
2482 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2483 break;
2484 case CPTK_IS_UNION:
2485 pp_cxx_ws_string (pp, "__is_union");
2486 break;
2487 case CPTK_IS_LITERAL_TYPE:
2488 pp_cxx_ws_string (pp, "__is_literal_type");
2489 break;
2491 default:
2492 gcc_unreachable ();
2495 pp_cxx_left_paren (pp);
2496 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2498 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2500 pp_cxx_separate_with (pp, ',');
2501 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2504 pp_cxx_right_paren (pp);
2507 // requires-clause:
2508 // 'requires' logical-or-expression
2509 void
2510 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2512 if (!t)
2513 return;
2514 pp->padding = pp_before;
2515 pp_cxx_ws_string (pp, "requires");
2516 pp_space (pp);
2517 pp->expression (t);
2520 /* requirement:
2521 simple-requirement
2522 compound-requirement
2523 type-requirement
2524 nested-requirement */
2525 static void
2526 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2528 switch (TREE_CODE (t))
2530 case SIMPLE_REQ:
2531 pp_cxx_simple_requirement (pp, t);
2532 break;
2534 case TYPE_REQ:
2535 pp_cxx_type_requirement (pp, t);
2536 break;
2538 case COMPOUND_REQ:
2539 pp_cxx_compound_requirement (pp, t);
2540 break;
2542 case NESTED_REQ:
2543 pp_cxx_nested_requirement (pp, t);
2544 break;
2546 default:
2547 gcc_unreachable ();
2551 // requirement-list:
2552 // requirement
2553 // requirement-list ';' requirement[opt]
2555 static void
2556 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2558 for (; t; t = TREE_CHAIN (t))
2559 pp_cxx_requirement (pp, TREE_VALUE (t));
2562 // requirement-body:
2563 // '{' requirement-list '}'
2564 static void
2565 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2567 pp_cxx_left_brace (pp);
2568 pp_cxx_requirement_list (pp, t);
2569 pp_cxx_right_brace (pp);
2572 // requires-expression:
2573 // 'requires' requirement-parameter-list requirement-body
2574 void
2575 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2577 pp_string (pp, "requires");
2578 if (tree parms = TREE_OPERAND (t, 0))
2580 pp_cxx_parameter_declaration_clause (pp, parms);
2581 pp_cxx_whitespace (pp);
2583 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2586 /* simple-requirement:
2587 expression ';' */
2588 void
2589 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2591 pp->expression (TREE_OPERAND (t, 0));
2592 pp_cxx_semicolon (pp);
2595 /* type-requirement:
2596 typename type-name ';' */
2597 void
2598 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2600 pp->type_id (TREE_OPERAND (t, 0));
2601 pp_cxx_semicolon (pp);
2604 /* compound-requirement:
2605 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2606 void
2607 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2609 pp_cxx_left_brace (pp);
2610 pp->expression (TREE_OPERAND (t, 0));
2611 pp_cxx_right_brace (pp);
2613 if (COMPOUND_REQ_NOEXCEPT_P (t))
2614 pp_cxx_ws_string (pp, "noexcept");
2616 if (tree type = TREE_OPERAND (t, 1))
2618 pp_cxx_ws_string (pp, "->");
2619 pp->type_id (type);
2623 /* nested requirement:
2624 'requires' constraint-expression */
2625 void
2626 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2628 pp_cxx_ws_string (pp, "requires");
2629 pp->expression (TREE_OPERAND (t, 0));
2630 pp_cxx_semicolon (pp);
2633 void
2634 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2636 pp_string (pp, "predicate");
2637 pp_left_paren (pp);
2638 pp->expression (TREE_OPERAND (t, 0));
2639 pp_right_paren (pp);
2642 void
2643 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2645 pp_string (pp, "valid_expr");
2646 pp_left_paren (pp);
2647 pp->expression (TREE_OPERAND (t, 0));
2648 pp_right_paren (pp);
2651 void
2652 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2654 pp_string (pp, "valid_type");
2655 pp_left_paren (pp);
2656 pp->type_id (TREE_OPERAND (t, 0));
2657 pp_right_paren (pp);
2660 void
2661 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2663 pp_string (pp, "convertible");
2664 pp_left_paren (pp);
2665 pp->expression (ICONV_CONSTR_EXPR (t));
2666 pp_cxx_separate_with (pp, ',');
2667 pp->expression (ICONV_CONSTR_TYPE (t));
2668 pp_right_paren (pp);
2671 void
2672 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2674 pp_string (pp, "deducible");
2675 pp_left_paren (pp);
2676 pp->expression (DEDUCT_CONSTR_EXPR (t));
2677 pp_cxx_separate_with (pp, ',');
2678 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2679 pp_right_paren (pp);
2682 void
2683 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2685 pp_cxx_ws_string (pp, "noexcept");
2686 pp_left_paren (pp);
2687 pp->expression (TREE_OPERAND (t, 0));
2688 pp_right_paren (pp);
2691 void
2692 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2694 pp_left_paren (pp);
2695 pp_string (pp, "forall");
2696 if (tree parms = PARM_CONSTR_PARMS (t))
2698 if (parms)
2699 pp_cxx_parameter_declaration_clause (pp, parms);
2700 pp_cxx_whitespace (pp);
2702 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2703 pp_right_paren (pp);
2706 void
2707 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2709 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2710 pp_string (pp, " and ");
2711 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2714 void
2715 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2717 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2718 pp_string (pp, " or ");
2719 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2722 void
2723 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2725 if (t == error_mark_node)
2726 return pp->expression (t);
2728 switch (TREE_CODE (t))
2730 case PRED_CONSTR:
2731 pp_cxx_predicate_constraint (pp, t);
2732 break;
2734 case EXPR_CONSTR:
2735 pp_cxx_expression_constraint (pp, t);
2736 break;
2738 case TYPE_CONSTR:
2739 pp_cxx_type_constraint (pp, t);
2740 break;
2742 case ICONV_CONSTR:
2743 pp_cxx_implicit_conversion_constraint (pp, t);
2744 break;
2746 case DEDUCT_CONSTR:
2747 pp_cxx_argument_deduction_constraint (pp, t);
2748 break;
2750 case EXCEPT_CONSTR:
2751 pp_cxx_exception_constraint (pp, t);
2752 break;
2754 case PARM_CONSTR:
2755 pp_cxx_parameterized_constraint (pp, t);
2756 break;
2758 case CONJ_CONSTR:
2759 pp_cxx_conjunction (pp, t);
2760 break;
2762 case DISJ_CONSTR:
2763 pp_cxx_disjunction (pp, t);
2764 break;
2766 default:
2767 gcc_unreachable ();
2773 typedef c_pretty_print_fn pp_fun;
2775 /* Initialization of a C++ pretty-printer object. */
2777 cxx_pretty_printer::cxx_pretty_printer ()
2778 : c_pretty_printer (),
2779 enclosing_scope (global_namespace)
2781 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2782 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;