2015-10-18 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob879eb71fc3ab51328feeaf8990f34e599b6906c1
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2015 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 "tm.h"
25 #include "intl.h"
26 #include "cp-tree.h"
27 #include "cxx-pretty-print.h"
28 #include "tree-pretty-print.h"
30 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
32 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
33 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
34 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
35 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
36 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
37 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
38 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
39 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
42 static inline void
43 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
45 const char *p = pp_last_position_in_text (pp);
47 if (p != NULL && *p == c)
48 pp_cxx_whitespace (pp);
49 pp_character (pp, c);
50 pp->padding = pp_none;
53 #define pp_cxx_expression_list(PP, T) \
54 pp_c_expression_list (PP, T)
55 #define pp_cxx_space_for_pointer_operator(PP, T) \
56 pp_c_space_for_pointer_operator (PP, T)
57 #define pp_cxx_init_declarator(PP, T) \
58 pp_c_init_declarator (PP, T)
59 #define pp_cxx_call_argument_list(PP, T) \
60 pp_c_call_argument_list (PP, T)
62 void
63 pp_cxx_colon_colon (cxx_pretty_printer *pp)
65 pp_colon_colon (pp);
66 pp->padding = pp_none;
69 void
70 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
72 pp_cxx_nonconsecutive_character (pp, '<');
75 void
76 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
78 pp_cxx_nonconsecutive_character (pp, '>');
81 void
82 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
84 pp_separate_with (pp, c);
85 pp->padding = pp_none;
88 /* Expressions. */
90 static inline bool
91 is_destructor_name (tree name)
93 return name == complete_dtor_identifier
94 || name == base_dtor_identifier
95 || name == deleting_dtor_identifier;
98 /* conversion-function-id:
99 operator conversion-type-id
101 conversion-type-id:
102 type-specifier-seq conversion-declarator(opt)
104 conversion-declarator:
105 ptr-operator conversion-declarator(opt) */
107 static inline void
108 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
110 pp_cxx_ws_string (pp, "operator");
111 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
114 static inline void
115 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
117 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
118 pp_cxx_begin_template_argument_list (pp);
119 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
120 pp_cxx_end_template_argument_list (pp);
123 /* Prints the unqualified part of the id-expression T.
125 unqualified-id:
126 identifier
127 operator-function-id
128 conversion-function-id
129 ~ class-name
130 template-id */
132 static void
133 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
135 enum tree_code code = TREE_CODE (t);
136 switch (code)
138 case RESULT_DECL:
139 pp->translate_string ("<return-value>");
140 break;
142 case OVERLOAD:
143 t = OVL_CURRENT (t);
144 case VAR_DECL:
145 case PARM_DECL:
146 case CONST_DECL:
147 case TYPE_DECL:
148 case FUNCTION_DECL:
149 case NAMESPACE_DECL:
150 case FIELD_DECL:
151 case LABEL_DECL:
152 case USING_DECL:
153 case TEMPLATE_DECL:
154 t = DECL_NAME (t);
156 case IDENTIFIER_NODE:
157 if (t == NULL)
158 pp->translate_string ("<unnamed>");
159 else if (IDENTIFIER_TYPENAME_P (t))
160 pp_cxx_conversion_function_id (pp, t);
161 else
163 if (is_destructor_name (t))
165 pp_complement (pp);
166 /* FIXME: Why is this necessary? */
167 if (TREE_TYPE (t))
168 t = constructor_name (TREE_TYPE (t));
170 pp_cxx_tree_identifier (pp, t);
172 break;
174 case TEMPLATE_ID_EXPR:
175 pp_cxx_template_id (pp, t);
176 break;
178 case BASELINK:
179 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
180 break;
182 case RECORD_TYPE:
183 case UNION_TYPE:
184 case ENUMERAL_TYPE:
185 case TYPENAME_TYPE:
186 case UNBOUND_CLASS_TEMPLATE:
187 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
188 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
190 pp_cxx_begin_template_argument_list (pp);
191 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
192 (CLASSTYPE_TI_ARGS (t)));
193 pp_cxx_end_template_argument_list (pp);
195 break;
197 case BIT_NOT_EXPR:
198 pp_cxx_complement (pp);
199 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
200 break;
202 case TEMPLATE_TYPE_PARM:
203 case TEMPLATE_TEMPLATE_PARM:
204 if (TYPE_IDENTIFIER (t))
205 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
206 else
207 pp_cxx_canonical_template_parameter (pp, t);
208 break;
210 case TEMPLATE_PARM_INDEX:
211 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
212 break;
214 case BOUND_TEMPLATE_TEMPLATE_PARM:
215 pp_cxx_cv_qualifier_seq (pp, t);
216 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
217 pp_cxx_begin_template_argument_list (pp);
218 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
219 pp_cxx_end_template_argument_list (pp);
220 break;
222 default:
223 pp_unsupported_tree (pp, t);
224 break;
228 /* Pretty-print out the token sequence ":: template" in template codes
229 where it is needed to "inline declare" the (following) member as
230 a template. This situation arises when SCOPE of T is dependent
231 on template parameters. */
233 static inline void
234 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
236 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
237 && TYPE_P (scope) && dependent_type_p (scope))
238 pp_cxx_ws_string (pp, "template");
241 /* nested-name-specifier:
242 class-or-namespace-name :: nested-name-specifier(opt)
243 class-or-namespace-name :: template nested-name-specifier */
245 static void
246 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
248 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
250 tree scope = get_containing_scope (t);
251 pp_cxx_nested_name_specifier (pp, scope);
252 pp_cxx_template_keyword_if_needed (pp, scope, t);
253 pp_cxx_unqualified_id (pp, t);
254 pp_cxx_colon_colon (pp);
258 /* qualified-id:
259 nested-name-specifier template(opt) unqualified-id */
261 static void
262 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
264 switch (TREE_CODE (t))
266 /* A pointer-to-member is always qualified. */
267 case PTRMEM_CST:
268 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
269 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
270 break;
272 /* In Standard C++, functions cannot possibly be used as
273 nested-name-specifiers. However, there are situations where
274 is "makes sense" to output the surrounding function name for the
275 purpose of emphasizing on the scope kind. Just printing the
276 function name might not be sufficient as it may be overloaded; so,
277 we decorate the function with its signature too.
278 FIXME: This is probably the wrong pretty-printing for conversion
279 functions and some function templates. */
280 case OVERLOAD:
281 t = OVL_CURRENT (t);
282 case FUNCTION_DECL:
283 if (DECL_FUNCTION_MEMBER_P (t))
284 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
285 pp_cxx_unqualified_id
286 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
287 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
288 break;
290 case OFFSET_REF:
291 case SCOPE_REF:
292 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
293 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
294 break;
296 default:
298 tree scope = get_containing_scope (t);
299 if (scope != pp->enclosing_scope)
301 pp_cxx_nested_name_specifier (pp, scope);
302 pp_cxx_template_keyword_if_needed (pp, scope, t);
304 pp_cxx_unqualified_id (pp, t);
306 break;
311 void
312 cxx_pretty_printer::constant (tree t)
314 switch (TREE_CODE (t))
316 case STRING_CST:
318 const bool in_parens = PAREN_STRING_LITERAL_P (t);
319 if (in_parens)
320 pp_cxx_left_paren (this);
321 c_pretty_printer::constant (t);
322 if (in_parens)
323 pp_cxx_right_paren (this);
325 break;
327 case INTEGER_CST:
328 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
330 pp_string (this, "nullptr");
331 break;
333 /* else fall through. */
335 default:
336 c_pretty_printer::constant (t);
337 break;
341 /* id-expression:
342 unqualified-id
343 qualified-id */
345 void
346 cxx_pretty_printer::id_expression (tree t)
348 if (TREE_CODE (t) == OVERLOAD)
349 t = OVL_CURRENT (t);
350 if (DECL_P (t) && DECL_CONTEXT (t))
351 pp_cxx_qualified_id (this, t);
352 else
353 pp_cxx_unqualified_id (this, t);
356 /* user-defined literal:
357 literal ud-suffix */
359 void
360 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
362 pp->constant (USERDEF_LITERAL_VALUE (t));
363 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
367 /* primary-expression:
368 literal
369 this
370 :: identifier
371 :: operator-function-id
372 :: qualifier-id
373 ( expression )
374 id-expression
376 GNU Extensions:
377 __builtin_va_arg ( assignment-expression , type-id )
378 __builtin_offsetof ( type-id, offsetof-expression )
380 __has_nothrow_assign ( type-id )
381 __has_nothrow_constructor ( type-id )
382 __has_nothrow_copy ( type-id )
383 __has_trivial_assign ( type-id )
384 __has_trivial_constructor ( type-id )
385 __has_trivial_copy ( type-id )
386 __has_trivial_destructor ( type-id )
387 __has_virtual_destructor ( type-id )
388 __is_abstract ( type-id )
389 __is_base_of ( type-id , type-id )
390 __is_class ( type-id )
391 __is_empty ( type-id )
392 __is_enum ( type-id )
393 __is_literal_type ( type-id )
394 __is_pod ( type-id )
395 __is_polymorphic ( type-id )
396 __is_std_layout ( type-id )
397 __is_trivial ( type-id )
398 __is_union ( type-id ) */
400 void
401 cxx_pretty_printer::primary_expression (tree t)
403 switch (TREE_CODE (t))
405 case VOID_CST:
406 case INTEGER_CST:
407 case REAL_CST:
408 case COMPLEX_CST:
409 case STRING_CST:
410 constant (t);
411 break;
413 case USERDEF_LITERAL:
414 pp_cxx_userdef_literal (this, t);
415 break;
417 case BASELINK:
418 t = BASELINK_FUNCTIONS (t);
419 case VAR_DECL:
420 case PARM_DECL:
421 case FIELD_DECL:
422 case FUNCTION_DECL:
423 case OVERLOAD:
424 case CONST_DECL:
425 case TEMPLATE_DECL:
426 id_expression (t);
427 break;
429 case RESULT_DECL:
430 case TEMPLATE_TYPE_PARM:
431 case TEMPLATE_TEMPLATE_PARM:
432 case TEMPLATE_PARM_INDEX:
433 pp_cxx_unqualified_id (this, t);
434 break;
436 case STMT_EXPR:
437 pp_cxx_left_paren (this);
438 statement (STMT_EXPR_STMT (t));
439 pp_cxx_right_paren (this);
440 break;
442 case TRAIT_EXPR:
443 pp_cxx_trait_expression (this, t);
444 break;
446 case VA_ARG_EXPR:
447 pp_cxx_va_arg_expression (this, t);
448 break;
450 case OFFSETOF_EXPR:
451 pp_cxx_offsetof_expression (this, t);
452 break;
454 case REQUIRES_EXPR:
455 pp_cxx_requires_expr (this, t);
456 break;
458 default:
459 c_pretty_printer::primary_expression (t);
460 break;
464 /* postfix-expression:
465 primary-expression
466 postfix-expression [ expression ]
467 postfix-expression ( expression-list(opt) )
468 simple-type-specifier ( expression-list(opt) )
469 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
470 typename ::(opt) nested-name-specifier template(opt)
471 template-id ( expression-list(opt) )
472 postfix-expression . template(opt) ::(opt) id-expression
473 postfix-expression -> template(opt) ::(opt) id-expression
474 postfix-expression . pseudo-destructor-name
475 postfix-expression -> pseudo-destructor-name
476 postfix-expression ++
477 postfix-expression --
478 dynamic_cast < type-id > ( expression )
479 static_cast < type-id > ( expression )
480 reinterpret_cast < type-id > ( expression )
481 const_cast < type-id > ( expression )
482 typeid ( expression )
483 typeid ( type-id ) */
485 void
486 cxx_pretty_printer::postfix_expression (tree t)
488 enum tree_code code = TREE_CODE (t);
490 switch (code)
492 case AGGR_INIT_EXPR:
493 case CALL_EXPR:
495 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
496 : CALL_EXPR_FN (t));
497 tree saved_scope = enclosing_scope;
498 bool skipfirst = false;
499 tree arg;
501 if (TREE_CODE (fun) == ADDR_EXPR)
502 fun = TREE_OPERAND (fun, 0);
504 /* In templates, where there is no way to tell whether a given
505 call uses an actual member function. So the parser builds
506 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
507 instantiation time. */
508 if (TREE_CODE (fun) != FUNCTION_DECL)
510 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
512 tree object = (code == AGGR_INIT_EXPR
513 ? (AGGR_INIT_VIA_CTOR_P (t)
514 ? AGGR_INIT_EXPR_SLOT (t)
515 : AGGR_INIT_EXPR_ARG (t, 0))
516 : CALL_EXPR_ARG (t, 0));
518 while (TREE_CODE (object) == NOP_EXPR)
519 object = TREE_OPERAND (object, 0);
521 if (TREE_CODE (object) == ADDR_EXPR)
522 object = TREE_OPERAND (object, 0);
524 if (!TYPE_PTR_P (TREE_TYPE (object)))
526 postfix_expression (object);
527 pp_cxx_dot (this);
529 else
531 postfix_expression (object);
532 pp_cxx_arrow (this);
534 skipfirst = true;
535 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
538 postfix_expression (fun);
539 enclosing_scope = saved_scope;
540 pp_cxx_left_paren (this);
541 if (code == AGGR_INIT_EXPR)
543 aggr_init_expr_arg_iterator iter;
544 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
546 if (skipfirst)
547 skipfirst = false;
548 else
550 expression (arg);
551 if (more_aggr_init_expr_args_p (&iter))
552 pp_cxx_separate_with (this, ',');
556 else
558 call_expr_arg_iterator iter;
559 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
561 if (skipfirst)
562 skipfirst = false;
563 else
565 expression (arg);
566 if (more_call_expr_args_p (&iter))
567 pp_cxx_separate_with (this, ',');
571 pp_cxx_right_paren (this);
573 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
575 pp_cxx_separate_with (this, ',');
576 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
578 break;
580 case BASELINK:
581 case VAR_DECL:
582 case PARM_DECL:
583 case FIELD_DECL:
584 case FUNCTION_DECL:
585 case OVERLOAD:
586 case CONST_DECL:
587 case TEMPLATE_DECL:
588 case RESULT_DECL:
589 primary_expression (t);
590 break;
592 case DYNAMIC_CAST_EXPR:
593 case STATIC_CAST_EXPR:
594 case REINTERPRET_CAST_EXPR:
595 case CONST_CAST_EXPR:
596 if (code == DYNAMIC_CAST_EXPR)
597 pp_cxx_ws_string (this, "dynamic_cast");
598 else if (code == STATIC_CAST_EXPR)
599 pp_cxx_ws_string (this, "static_cast");
600 else if (code == REINTERPRET_CAST_EXPR)
601 pp_cxx_ws_string (this, "reinterpret_cast");
602 else
603 pp_cxx_ws_string (this, "const_cast");
604 pp_cxx_begin_template_argument_list (this);
605 type_id (TREE_TYPE (t));
606 pp_cxx_end_template_argument_list (this);
607 pp_left_paren (this);
608 expression (TREE_OPERAND (t, 0));
609 pp_right_paren (this);
610 break;
612 case EMPTY_CLASS_EXPR:
613 type_id (TREE_TYPE (t));
614 pp_left_paren (this);
615 pp_right_paren (this);
616 break;
618 case TYPEID_EXPR:
619 pp_cxx_typeid_expression (this, t);
620 break;
622 case PSEUDO_DTOR_EXPR:
623 postfix_expression (TREE_OPERAND (t, 0));
624 pp_cxx_dot (this);
625 if (TREE_OPERAND (t, 1))
627 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
628 pp_cxx_colon_colon (this);
630 pp_complement (this);
631 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
632 break;
634 case ARROW_EXPR:
635 postfix_expression (TREE_OPERAND (t, 0));
636 pp_cxx_arrow (this);
637 break;
639 default:
640 c_pretty_printer::postfix_expression (t);
641 break;
645 /* new-expression:
646 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
647 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
649 new-placement:
650 ( expression-list )
652 new-type-id:
653 type-specifier-seq new-declarator(opt)
655 new-declarator:
656 ptr-operator new-declarator(opt)
657 direct-new-declarator
659 direct-new-declarator
660 [ expression ]
661 direct-new-declarator [ constant-expression ]
663 new-initializer:
664 ( expression-list(opt) ) */
666 static void
667 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
669 enum tree_code code = TREE_CODE (t);
670 tree type = TREE_OPERAND (t, 1);
671 tree init = TREE_OPERAND (t, 2);
672 switch (code)
674 case NEW_EXPR:
675 case VEC_NEW_EXPR:
676 if (NEW_EXPR_USE_GLOBAL (t))
677 pp_cxx_colon_colon (pp);
678 pp_cxx_ws_string (pp, "new");
679 if (TREE_OPERAND (t, 0))
681 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
682 pp_space (pp);
684 if (TREE_CODE (type) == ARRAY_REF)
685 type = build_cplus_array_type
686 (TREE_OPERAND (type, 0),
687 build_index_type (fold_build2_loc (input_location,
688 MINUS_EXPR, integer_type_node,
689 TREE_OPERAND (type, 1),
690 integer_one_node)));
691 pp->type_id (type);
692 if (init)
694 pp_left_paren (pp);
695 if (TREE_CODE (init) == TREE_LIST)
696 pp_c_expression_list (pp, init);
697 else if (init == void_node)
698 ; /* OK, empty initializer list. */
699 else
700 pp->expression (init);
701 pp_right_paren (pp);
703 break;
705 default:
706 pp_unsupported_tree (pp, t);
710 /* delete-expression:
711 ::(opt) delete cast-expression
712 ::(opt) delete [ ] cast-expression */
714 static void
715 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
717 enum tree_code code = TREE_CODE (t);
718 switch (code)
720 case DELETE_EXPR:
721 case VEC_DELETE_EXPR:
722 if (DELETE_EXPR_USE_GLOBAL (t))
723 pp_cxx_colon_colon (pp);
724 pp_cxx_ws_string (pp, "delete");
725 pp_space (pp);
726 if (code == VEC_DELETE_EXPR
727 || DELETE_EXPR_USE_VEC (t))
729 pp_left_bracket (pp);
730 pp_right_bracket (pp);
731 pp_space (pp);
733 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
734 break;
736 default:
737 pp_unsupported_tree (pp, t);
741 /* unary-expression:
742 postfix-expression
743 ++ cast-expression
744 -- cast-expression
745 unary-operator cast-expression
746 sizeof unary-expression
747 sizeof ( type-id )
748 sizeof ... ( identifier )
749 new-expression
750 delete-expression
752 unary-operator: one of
753 * & + - !
755 GNU extensions:
756 __alignof__ unary-expression
757 __alignof__ ( type-id ) */
759 void
760 cxx_pretty_printer::unary_expression (tree t)
762 enum tree_code code = TREE_CODE (t);
763 switch (code)
765 case NEW_EXPR:
766 case VEC_NEW_EXPR:
767 pp_cxx_new_expression (this, t);
768 break;
770 case DELETE_EXPR:
771 case VEC_DELETE_EXPR:
772 pp_cxx_delete_expression (this, t);
773 break;
775 case SIZEOF_EXPR:
776 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
778 pp_cxx_ws_string (this, "sizeof");
779 pp_cxx_ws_string (this, "...");
780 pp_cxx_whitespace (this);
781 pp_cxx_left_paren (this);
782 if (TYPE_P (TREE_OPERAND (t, 0)))
783 type_id (TREE_OPERAND (t, 0));
784 else
785 unary_expression (TREE_OPERAND (t, 0));
786 pp_cxx_right_paren (this);
787 break;
789 /* Fall through */
791 case ALIGNOF_EXPR:
792 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
793 pp_cxx_whitespace (this);
794 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
796 pp_cxx_left_paren (this);
797 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
798 pp_cxx_right_paren (this);
800 else if (TYPE_P (TREE_OPERAND (t, 0)))
802 pp_cxx_left_paren (this);
803 type_id (TREE_OPERAND (t, 0));
804 pp_cxx_right_paren (this);
806 else
807 unary_expression (TREE_OPERAND (t, 0));
808 break;
810 case AT_ENCODE_EXPR:
811 pp_cxx_ws_string (this, "@encode");
812 pp_cxx_whitespace (this);
813 pp_cxx_left_paren (this);
814 type_id (TREE_OPERAND (t, 0));
815 pp_cxx_right_paren (this);
816 break;
818 case NOEXCEPT_EXPR:
819 pp_cxx_ws_string (this, "noexcept");
820 pp_cxx_whitespace (this);
821 pp_cxx_left_paren (this);
822 expression (TREE_OPERAND (t, 0));
823 pp_cxx_right_paren (this);
824 break;
826 case UNARY_PLUS_EXPR:
827 pp_plus (this);
828 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
829 break;
831 default:
832 c_pretty_printer::unary_expression (t);
833 break;
837 /* cast-expression:
838 unary-expression
839 ( type-id ) cast-expression */
841 static void
842 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
844 switch (TREE_CODE (t))
846 case CAST_EXPR:
847 case IMPLICIT_CONV_EXPR:
848 pp->type_id (TREE_TYPE (t));
849 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
850 break;
852 default:
853 pp_c_cast_expression (pp, t);
854 break;
858 /* pm-expression:
859 cast-expression
860 pm-expression .* cast-expression
861 pm-expression ->* cast-expression */
863 static void
864 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
866 switch (TREE_CODE (t))
868 /* Handle unfortunate OFFSET_REF overloading here. */
869 case OFFSET_REF:
870 if (TYPE_P (TREE_OPERAND (t, 0)))
872 pp_cxx_qualified_id (pp, t);
873 break;
875 /* Else fall through. */
876 case MEMBER_REF:
877 case DOTSTAR_EXPR:
878 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
879 if (TREE_CODE (t) == MEMBER_REF)
880 pp_cxx_arrow (pp);
881 else
882 pp_cxx_dot (pp);
883 pp_star(pp);
884 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
885 break;
888 default:
889 pp_cxx_cast_expression (pp, t);
890 break;
894 /* multiplicative-expression:
895 pm-expression
896 multiplicative-expression * pm-expression
897 multiplicative-expression / pm-expression
898 multiplicative-expression % pm-expression */
900 void
901 cxx_pretty_printer::multiplicative_expression (tree e)
903 enum tree_code code = TREE_CODE (e);
904 switch (code)
906 case MULT_EXPR:
907 case TRUNC_DIV_EXPR:
908 case TRUNC_MOD_EXPR:
909 multiplicative_expression (TREE_OPERAND (e, 0));
910 pp_space (this);
911 if (code == MULT_EXPR)
912 pp_star (this);
913 else if (code == TRUNC_DIV_EXPR)
914 pp_slash (this);
915 else
916 pp_modulo (this);
917 pp_space (this);
918 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
919 break;
921 default:
922 pp_cxx_pm_expression (this, e);
923 break;
927 /* conditional-expression:
928 logical-or-expression
929 logical-or-expression ? expression : assignment-expression */
931 void
932 cxx_pretty_printer::conditional_expression (tree e)
934 if (TREE_CODE (e) == COND_EXPR)
936 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
937 pp_space (this);
938 pp_question (this);
939 pp_space (this);
940 expression (TREE_OPERAND (e, 1));
941 pp_space (this);
942 assignment_expression (TREE_OPERAND (e, 2));
944 else
945 pp_c_logical_or_expression (this, e);
948 /* Pretty-print a compound assignment operator token as indicated by T. */
950 static void
951 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
953 const char *op;
955 switch (TREE_CODE (t))
957 case NOP_EXPR:
958 op = "=";
959 break;
961 case PLUS_EXPR:
962 op = "+=";
963 break;
965 case MINUS_EXPR:
966 op = "-=";
967 break;
969 case TRUNC_DIV_EXPR:
970 op = "/=";
971 break;
973 case TRUNC_MOD_EXPR:
974 op = "%=";
975 break;
977 default:
978 op = get_tree_code_name (TREE_CODE (t));
979 break;
982 pp_cxx_ws_string (pp, op);
986 /* assignment-expression:
987 conditional-expression
988 logical-or-expression assignment-operator assignment-expression
989 throw-expression
991 throw-expression:
992 throw assignment-expression(opt)
994 assignment-operator: one of
995 = *= /= %= += -= >>= <<= &= ^= |= */
997 void
998 cxx_pretty_printer::assignment_expression (tree e)
1000 switch (TREE_CODE (e))
1002 case MODIFY_EXPR:
1003 case INIT_EXPR:
1004 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1005 pp_space (this);
1006 pp_equal (this);
1007 pp_space (this);
1008 assignment_expression (TREE_OPERAND (e, 1));
1009 break;
1011 case THROW_EXPR:
1012 pp_cxx_ws_string (this, "throw");
1013 if (TREE_OPERAND (e, 0))
1014 assignment_expression (TREE_OPERAND (e, 0));
1015 break;
1017 case MODOP_EXPR:
1018 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1019 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1020 assignment_expression (TREE_OPERAND (e, 2));
1021 break;
1023 default:
1024 conditional_expression (e);
1025 break;
1029 void
1030 cxx_pretty_printer::expression (tree t)
1032 switch (TREE_CODE (t))
1034 case STRING_CST:
1035 case VOID_CST:
1036 case INTEGER_CST:
1037 case REAL_CST:
1038 case COMPLEX_CST:
1039 constant (t);
1040 break;
1042 case USERDEF_LITERAL:
1043 pp_cxx_userdef_literal (this, t);
1044 break;
1046 case RESULT_DECL:
1047 pp_cxx_unqualified_id (this, t);
1048 break;
1050 #if 0
1051 case OFFSET_REF:
1052 #endif
1053 case SCOPE_REF:
1054 case PTRMEM_CST:
1055 pp_cxx_qualified_id (this, t);
1056 break;
1058 case OVERLOAD:
1059 t = OVL_CURRENT (t);
1060 case VAR_DECL:
1061 case PARM_DECL:
1062 case FIELD_DECL:
1063 case CONST_DECL:
1064 case FUNCTION_DECL:
1065 case BASELINK:
1066 case TEMPLATE_DECL:
1067 case TEMPLATE_TYPE_PARM:
1068 case TEMPLATE_PARM_INDEX:
1069 case TEMPLATE_TEMPLATE_PARM:
1070 case STMT_EXPR:
1071 case REQUIRES_EXPR:
1072 primary_expression (t);
1073 break;
1075 case CALL_EXPR:
1076 case DYNAMIC_CAST_EXPR:
1077 case STATIC_CAST_EXPR:
1078 case REINTERPRET_CAST_EXPR:
1079 case CONST_CAST_EXPR:
1080 #if 0
1081 case MEMBER_REF:
1082 #endif
1083 case EMPTY_CLASS_EXPR:
1084 case TYPEID_EXPR:
1085 case PSEUDO_DTOR_EXPR:
1086 case AGGR_INIT_EXPR:
1087 case ARROW_EXPR:
1088 postfix_expression (t);
1089 break;
1091 case NEW_EXPR:
1092 case VEC_NEW_EXPR:
1093 pp_cxx_new_expression (this, t);
1094 break;
1096 case DELETE_EXPR:
1097 case VEC_DELETE_EXPR:
1098 pp_cxx_delete_expression (this, t);
1099 break;
1101 case SIZEOF_EXPR:
1102 case ALIGNOF_EXPR:
1103 case NOEXCEPT_EXPR:
1104 unary_expression (t);
1105 break;
1107 case CAST_EXPR:
1108 case IMPLICIT_CONV_EXPR:
1109 pp_cxx_cast_expression (this, t);
1110 break;
1112 case OFFSET_REF:
1113 case MEMBER_REF:
1114 case DOTSTAR_EXPR:
1115 pp_cxx_pm_expression (this, t);
1116 break;
1118 case MULT_EXPR:
1119 case TRUNC_DIV_EXPR:
1120 case TRUNC_MOD_EXPR:
1121 multiplicative_expression (t);
1122 break;
1124 case COND_EXPR:
1125 conditional_expression (t);
1126 break;
1128 case MODIFY_EXPR:
1129 case INIT_EXPR:
1130 case THROW_EXPR:
1131 case MODOP_EXPR:
1132 assignment_expression (t);
1133 break;
1135 case NON_DEPENDENT_EXPR:
1136 case MUST_NOT_THROW_EXPR:
1137 expression (TREE_OPERAND (t, 0));
1138 break;
1140 case EXPR_PACK_EXPANSION:
1141 expression (PACK_EXPANSION_PATTERN (t));
1142 pp_cxx_ws_string (this, "...");
1143 break;
1145 case TEMPLATE_ID_EXPR:
1146 pp_cxx_template_id (this, t);
1147 break;
1149 case NONTYPE_ARGUMENT_PACK:
1151 tree args = ARGUMENT_PACK_ARGS (t);
1152 int i, len = TREE_VEC_LENGTH (args);
1153 for (i = 0; i < len; ++i)
1155 if (i > 0)
1156 pp_cxx_separate_with (this, ',');
1157 expression (TREE_VEC_ELT (args, i));
1160 break;
1162 case LAMBDA_EXPR:
1163 pp_cxx_ws_string (this, "<lambda>");
1164 break;
1166 case TRAIT_EXPR:
1167 pp_cxx_trait_expression (this, t);
1168 break;
1170 case PRED_CONSTR:
1171 case EXPR_CONSTR:
1172 case TYPE_CONSTR:
1173 case ICONV_CONSTR:
1174 case DEDUCT_CONSTR:
1175 case EXCEPT_CONSTR:
1176 case PARM_CONSTR:
1177 case CONJ_CONSTR:
1178 case DISJ_CONSTR:
1179 pp_cxx_constraint (this, t);
1180 break;
1182 case PAREN_EXPR:
1183 pp_cxx_left_paren (this);
1184 expression (TREE_OPERAND (t, 0));
1185 pp_cxx_right_paren (this);
1186 break;
1188 default:
1189 c_pretty_printer::expression (t);
1190 break;
1195 /* Declarations. */
1197 /* function-specifier:
1198 inline
1199 virtual
1200 explicit */
1202 void
1203 cxx_pretty_printer::function_specifier (tree t)
1205 switch (TREE_CODE (t))
1207 case FUNCTION_DECL:
1208 if (DECL_VIRTUAL_P (t))
1209 pp_cxx_ws_string (this, "virtual");
1210 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1211 pp_cxx_ws_string (this, "explicit");
1212 else
1213 c_pretty_printer::function_specifier (t);
1215 default:
1216 break;
1220 /* decl-specifier-seq:
1221 decl-specifier-seq(opt) decl-specifier
1223 decl-specifier:
1224 storage-class-specifier
1225 type-specifier
1226 function-specifier
1227 friend
1228 typedef */
1230 void
1231 cxx_pretty_printer::declaration_specifiers (tree t)
1233 switch (TREE_CODE (t))
1235 case VAR_DECL:
1236 case PARM_DECL:
1237 case CONST_DECL:
1238 case FIELD_DECL:
1239 storage_class_specifier (t);
1240 declaration_specifiers (TREE_TYPE (t));
1241 break;
1243 case TYPE_DECL:
1244 pp_cxx_ws_string (this, "typedef");
1245 declaration_specifiers (TREE_TYPE (t));
1246 break;
1248 case FUNCTION_DECL:
1249 /* Constructors don't have return types. And conversion functions
1250 do not have a type-specifier in their return types. */
1251 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1252 function_specifier (t);
1253 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1254 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1255 else
1256 default:
1257 c_pretty_printer::declaration_specifiers (t);
1258 break;
1262 /* simple-type-specifier:
1263 ::(opt) nested-name-specifier(opt) type-name
1264 ::(opt) nested-name-specifier(opt) template(opt) template-id
1265 char
1266 wchar_t
1267 bool
1268 short
1270 long
1271 signed
1272 unsigned
1273 float
1274 double
1275 void */
1277 void
1278 cxx_pretty_printer::simple_type_specifier (tree t)
1280 switch (TREE_CODE (t))
1282 case RECORD_TYPE:
1283 case UNION_TYPE:
1284 case ENUMERAL_TYPE:
1285 pp_cxx_qualified_id (this, t);
1286 break;
1288 case TEMPLATE_TYPE_PARM:
1289 case TEMPLATE_TEMPLATE_PARM:
1290 case TEMPLATE_PARM_INDEX:
1291 case BOUND_TEMPLATE_TEMPLATE_PARM:
1292 pp_cxx_unqualified_id (this, t);
1293 break;
1295 case TYPENAME_TYPE:
1296 pp_cxx_ws_string (this, "typename");
1297 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1298 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1299 break;
1301 default:
1302 c_pretty_printer::simple_type_specifier (t);
1303 break;
1307 /* type-specifier-seq:
1308 type-specifier type-specifier-seq(opt)
1310 type-specifier:
1311 simple-type-specifier
1312 class-specifier
1313 enum-specifier
1314 elaborated-type-specifier
1315 cv-qualifier */
1317 static void
1318 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1320 switch (TREE_CODE (t))
1322 case TEMPLATE_DECL:
1323 case TEMPLATE_TYPE_PARM:
1324 case TEMPLATE_TEMPLATE_PARM:
1325 case TYPE_DECL:
1326 case BOUND_TEMPLATE_TEMPLATE_PARM:
1327 pp_cxx_cv_qualifier_seq (pp, t);
1328 pp->simple_type_specifier (t);
1329 break;
1331 case METHOD_TYPE:
1332 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1333 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1334 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1335 break;
1337 case DECLTYPE_TYPE:
1338 pp_cxx_ws_string (pp, "decltype");
1339 pp_cxx_left_paren (pp);
1340 pp->expression (DECLTYPE_TYPE_EXPR (t));
1341 pp_cxx_right_paren (pp);
1342 break;
1344 case RECORD_TYPE:
1345 if (TYPE_PTRMEMFUNC_P (t))
1347 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1348 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1349 pp_cxx_whitespace (pp);
1350 pp_cxx_ptr_operator (pp, t);
1351 break;
1353 /* else fall through */
1355 default:
1356 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1357 pp_c_specifier_qualifier_list (pp, t);
1361 /* ptr-operator:
1362 * cv-qualifier-seq(opt)
1364 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1366 static void
1367 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1369 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1370 t = TREE_TYPE (t);
1371 switch (TREE_CODE (t))
1373 case REFERENCE_TYPE:
1374 case POINTER_TYPE:
1375 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1376 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1377 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1378 if (TYPE_PTR_P (t))
1380 pp_star (pp);
1381 pp_cxx_cv_qualifier_seq (pp, t);
1383 else
1384 pp_ampersand (pp);
1385 break;
1387 case RECORD_TYPE:
1388 if (TYPE_PTRMEMFUNC_P (t))
1390 pp_cxx_left_paren (pp);
1391 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1392 pp_star (pp);
1393 break;
1395 case OFFSET_TYPE:
1396 if (TYPE_PTRMEM_P (t))
1398 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1399 pp_cxx_left_paren (pp);
1400 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1401 pp_star (pp);
1402 pp_cxx_cv_qualifier_seq (pp, t);
1403 break;
1405 /* else fall through. */
1407 default:
1408 pp_unsupported_tree (pp, t);
1409 break;
1413 static inline tree
1414 pp_cxx_implicit_parameter_type (tree mf)
1416 return class_of_this_parm (TREE_TYPE (mf));
1420 parameter-declaration:
1421 decl-specifier-seq declarator
1422 decl-specifier-seq declarator = assignment-expression
1423 decl-specifier-seq abstract-declarator(opt)
1424 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1426 static inline void
1427 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1429 pp->declaration_specifiers (t);
1430 if (TYPE_P (t))
1431 pp->abstract_declarator (t);
1432 else
1433 pp->declarator (t);
1436 /* parameter-declaration-clause:
1437 parameter-declaration-list(opt) ...(opt)
1438 parameter-declaration-list , ...
1440 parameter-declaration-list:
1441 parameter-declaration
1442 parameter-declaration-list , parameter-declaration */
1444 static void
1445 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1447 tree args;
1448 tree types;
1449 bool abstract;
1451 // For a requires clause or the explicit printing of a parameter list
1452 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1453 // args and types are taken from the function decl T.
1454 if (TREE_CODE (t) == PARM_DECL)
1456 args = t;
1457 types = t;
1458 abstract = false;
1460 else
1462 bool type_p = TYPE_P (t);
1463 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1464 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1465 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1467 bool first = true;
1469 /* Skip artificial parameter for nonstatic member functions. */
1470 if (TREE_CODE (t) == METHOD_TYPE)
1471 types = TREE_CHAIN (types);
1473 pp_cxx_left_paren (pp);
1474 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1476 if (!first)
1477 pp_cxx_separate_with (pp, ',');
1478 first = false;
1479 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1480 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1482 pp_cxx_whitespace (pp);
1483 pp_equal (pp);
1484 pp_cxx_whitespace (pp);
1485 pp->assignment_expression (TREE_PURPOSE (types));
1488 pp_cxx_right_paren (pp);
1491 /* exception-specification:
1492 throw ( type-id-list(opt) )
1494 type-id-list
1495 type-id
1496 type-id-list , type-id */
1498 static void
1499 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1501 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1502 bool need_comma = false;
1504 if (ex_spec == NULL)
1505 return;
1506 if (TREE_PURPOSE (ex_spec))
1508 pp_cxx_ws_string (pp, "noexcept");
1509 pp_cxx_whitespace (pp);
1510 pp_cxx_left_paren (pp);
1511 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1512 pp_cxx_ws_string (pp, "<uninstantiated>");
1513 else
1514 pp->expression (TREE_PURPOSE (ex_spec));
1515 pp_cxx_right_paren (pp);
1516 return;
1518 pp_cxx_ws_string (pp, "throw");
1519 pp_cxx_left_paren (pp);
1520 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1522 tree type = TREE_VALUE (ex_spec);
1523 tree argpack = NULL_TREE;
1524 int i, len = 1;
1526 if (ARGUMENT_PACK_P (type))
1528 argpack = ARGUMENT_PACK_ARGS (type);
1529 len = TREE_VEC_LENGTH (argpack);
1532 for (i = 0; i < len; ++i)
1534 if (argpack)
1535 type = TREE_VEC_ELT (argpack, i);
1537 if (need_comma)
1538 pp_cxx_separate_with (pp, ',');
1539 else
1540 need_comma = true;
1542 pp->type_id (type);
1545 pp_cxx_right_paren (pp);
1548 /* direct-declarator:
1549 declarator-id
1550 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1551 exception-specification(opt)
1552 direct-declaration [ constant-expression(opt) ]
1553 ( declarator ) */
1555 void
1556 cxx_pretty_printer::direct_declarator (tree t)
1558 switch (TREE_CODE (t))
1560 case VAR_DECL:
1561 case PARM_DECL:
1562 case CONST_DECL:
1563 case FIELD_DECL:
1564 if (DECL_NAME (t))
1566 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1568 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1569 || template_parameter_pack_p (t))
1570 /* A function parameter pack or non-type template
1571 parameter pack. */
1572 pp_cxx_ws_string (this, "...");
1574 id_expression (DECL_NAME (t));
1576 abstract_declarator (TREE_TYPE (t));
1577 break;
1579 case FUNCTION_DECL:
1580 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1581 expression (t);
1582 pp_cxx_parameter_declaration_clause (this, t);
1584 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1586 padding = pp_before;
1587 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1590 pp_cxx_exception_specification (this, TREE_TYPE (t));
1591 break;
1593 case TYPENAME_TYPE:
1594 case TEMPLATE_DECL:
1595 case TEMPLATE_TYPE_PARM:
1596 case TEMPLATE_PARM_INDEX:
1597 case TEMPLATE_TEMPLATE_PARM:
1598 break;
1600 default:
1601 c_pretty_printer::direct_declarator (t);
1602 break;
1606 /* declarator:
1607 direct-declarator
1608 ptr-operator declarator */
1610 void
1611 cxx_pretty_printer::declarator (tree t)
1613 direct_declarator (t);
1615 // Print a requires clause.
1616 if (flag_concepts)
1617 if (tree ci = get_constraints (t))
1618 if (tree reqs = CI_DECLARATOR_REQS (ci))
1619 pp_cxx_requires_clause (this, reqs);
1622 /* ctor-initializer:
1623 : mem-initializer-list
1625 mem-initializer-list:
1626 mem-initializer
1627 mem-initializer , mem-initializer-list
1629 mem-initializer:
1630 mem-initializer-id ( expression-list(opt) )
1632 mem-initializer-id:
1633 ::(opt) nested-name-specifier(opt) class-name
1634 identifier */
1636 static void
1637 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1639 t = TREE_OPERAND (t, 0);
1640 pp_cxx_whitespace (pp);
1641 pp_colon (pp);
1642 pp_cxx_whitespace (pp);
1643 for (; t; t = TREE_CHAIN (t))
1645 tree purpose = TREE_PURPOSE (t);
1646 bool is_pack = PACK_EXPANSION_P (purpose);
1648 if (is_pack)
1649 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1650 else
1651 pp->primary_expression (purpose);
1652 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1653 if (is_pack)
1654 pp_cxx_ws_string (pp, "...");
1655 if (TREE_CHAIN (t))
1656 pp_cxx_separate_with (pp, ',');
1660 /* function-definition:
1661 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1662 decl-specifier-seq(opt) declarator function-try-block */
1664 static void
1665 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1667 tree saved_scope = pp->enclosing_scope;
1668 pp->declaration_specifiers (t);
1669 pp->declarator (t);
1670 pp_needs_newline (pp) = true;
1671 pp->enclosing_scope = DECL_CONTEXT (t);
1672 if (DECL_SAVED_TREE (t))
1673 pp->statement (DECL_SAVED_TREE (t));
1674 else
1675 pp_cxx_semicolon (pp);
1676 pp_newline_and_flush (pp);
1677 pp->enclosing_scope = saved_scope;
1680 /* abstract-declarator:
1681 ptr-operator abstract-declarator(opt)
1682 direct-abstract-declarator */
1684 void
1685 cxx_pretty_printer::abstract_declarator (tree t)
1687 if (TYPE_PTRMEM_P (t))
1688 pp_cxx_right_paren (this);
1689 else if (POINTER_TYPE_P (t))
1691 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1692 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1693 pp_cxx_right_paren (this);
1694 t = TREE_TYPE (t);
1696 direct_abstract_declarator (t);
1699 /* direct-abstract-declarator:
1700 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1701 cv-qualifier-seq(opt) exception-specification(opt)
1702 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1703 ( abstract-declarator ) */
1705 void
1706 cxx_pretty_printer::direct_abstract_declarator (tree t)
1708 switch (TREE_CODE (t))
1710 case REFERENCE_TYPE:
1711 abstract_declarator (t);
1712 break;
1714 case RECORD_TYPE:
1715 if (TYPE_PTRMEMFUNC_P (t))
1716 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1717 break;
1719 case METHOD_TYPE:
1720 case FUNCTION_TYPE:
1721 pp_cxx_parameter_declaration_clause (this, t);
1722 direct_abstract_declarator (TREE_TYPE (t));
1723 if (TREE_CODE (t) == METHOD_TYPE)
1725 padding = pp_before;
1726 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1728 pp_cxx_exception_specification (this, t);
1729 break;
1731 case TYPENAME_TYPE:
1732 case TEMPLATE_TYPE_PARM:
1733 case TEMPLATE_TEMPLATE_PARM:
1734 case BOUND_TEMPLATE_TEMPLATE_PARM:
1735 case UNBOUND_CLASS_TEMPLATE:
1736 break;
1738 default:
1739 c_pretty_printer::direct_abstract_declarator (t);
1740 break;
1744 /* type-id:
1745 type-specifier-seq abstract-declarator(opt) */
1747 void
1748 cxx_pretty_printer::type_id (tree t)
1750 pp_flags saved_flags = flags;
1751 flags |= pp_c_flag_abstract;
1753 switch (TREE_CODE (t))
1755 case TYPE_DECL:
1756 case UNION_TYPE:
1757 case RECORD_TYPE:
1758 case ENUMERAL_TYPE:
1759 case TYPENAME_TYPE:
1760 case BOUND_TEMPLATE_TEMPLATE_PARM:
1761 case UNBOUND_CLASS_TEMPLATE:
1762 case TEMPLATE_TEMPLATE_PARM:
1763 case TEMPLATE_TYPE_PARM:
1764 case TEMPLATE_PARM_INDEX:
1765 case TEMPLATE_DECL:
1766 case TYPEOF_TYPE:
1767 case UNDERLYING_TYPE:
1768 case DECLTYPE_TYPE:
1769 case TEMPLATE_ID_EXPR:
1770 pp_cxx_type_specifier_seq (this, t);
1771 break;
1773 case TYPE_PACK_EXPANSION:
1774 type_id (PACK_EXPANSION_PATTERN (t));
1775 pp_cxx_ws_string (this, "...");
1776 break;
1778 default:
1779 c_pretty_printer::type_id (t);
1780 break;
1783 flags = saved_flags;
1786 /* template-argument-list:
1787 template-argument ...(opt)
1788 template-argument-list, template-argument ...(opt)
1790 template-argument:
1791 assignment-expression
1792 type-id
1793 template-name */
1795 static void
1796 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1798 int i;
1799 bool need_comma = false;
1801 if (t == NULL)
1802 return;
1803 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1805 tree arg = TREE_VEC_ELT (t, i);
1806 tree argpack = NULL_TREE;
1807 int idx, len = 1;
1809 if (ARGUMENT_PACK_P (arg))
1811 argpack = ARGUMENT_PACK_ARGS (arg);
1812 len = TREE_VEC_LENGTH (argpack);
1815 for (idx = 0; idx < len; idx++)
1817 if (argpack)
1818 arg = TREE_VEC_ELT (argpack, idx);
1820 if (need_comma)
1821 pp_cxx_separate_with (pp, ',');
1822 else
1823 need_comma = true;
1825 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1826 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1827 pp->type_id (arg);
1828 else
1829 pp->expression (arg);
1835 static void
1836 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1838 t = DECL_EXPR_DECL (t);
1839 pp_cxx_type_specifier_seq (pp, t);
1840 if (TYPE_P (t))
1841 pp->abstract_declarator (t);
1842 else
1843 pp->declarator (t);
1846 /* Statements. */
1848 void
1849 cxx_pretty_printer::statement (tree t)
1851 switch (TREE_CODE (t))
1853 case CTOR_INITIALIZER:
1854 pp_cxx_ctor_initializer (this, t);
1855 break;
1857 case USING_STMT:
1858 pp_cxx_ws_string (this, "using");
1859 pp_cxx_ws_string (this, "namespace");
1860 if (DECL_CONTEXT (t))
1861 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1862 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1863 break;
1865 case USING_DECL:
1866 pp_cxx_ws_string (this, "using");
1867 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1868 pp_cxx_unqualified_id (this, DECL_NAME (t));
1869 break;
1871 case EH_SPEC_BLOCK:
1872 break;
1874 /* try-block:
1875 try compound-statement handler-seq */
1876 case TRY_BLOCK:
1877 pp_maybe_newline_and_indent (this, 0);
1878 pp_cxx_ws_string (this, "try");
1879 pp_newline_and_indent (this, 3);
1880 statement (TRY_STMTS (t));
1881 pp_newline_and_indent (this, -3);
1882 if (CLEANUP_P (t))
1884 else
1885 statement (TRY_HANDLERS (t));
1886 break;
1889 handler-seq:
1890 handler handler-seq(opt)
1892 handler:
1893 catch ( exception-declaration ) compound-statement
1895 exception-declaration:
1896 type-specifier-seq declarator
1897 type-specifier-seq abstract-declarator
1898 ... */
1899 case HANDLER:
1900 pp_cxx_ws_string (this, "catch");
1901 pp_cxx_left_paren (this);
1902 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1903 pp_cxx_right_paren (this);
1904 pp_indentation (this) += 3;
1905 pp_needs_newline (this) = true;
1906 statement (HANDLER_BODY (t));
1907 pp_indentation (this) -= 3;
1908 pp_needs_newline (this) = true;
1909 break;
1911 /* selection-statement:
1912 if ( expression ) statement
1913 if ( expression ) statement else statement */
1914 case IF_STMT:
1915 pp_cxx_ws_string (this, "if");
1916 pp_cxx_whitespace (this);
1917 pp_cxx_left_paren (this);
1918 expression (IF_COND (t));
1919 pp_cxx_right_paren (this);
1920 pp_newline_and_indent (this, 2);
1921 statement (THEN_CLAUSE (t));
1922 pp_newline_and_indent (this, -2);
1923 if (ELSE_CLAUSE (t))
1925 tree else_clause = ELSE_CLAUSE (t);
1926 pp_cxx_ws_string (this, "else");
1927 if (TREE_CODE (else_clause) == IF_STMT)
1928 pp_cxx_whitespace (this);
1929 else
1930 pp_newline_and_indent (this, 2);
1931 statement (else_clause);
1932 if (TREE_CODE (else_clause) != IF_STMT)
1933 pp_newline_and_indent (this, -2);
1935 break;
1937 case SWITCH_STMT:
1938 pp_cxx_ws_string (this, "switch");
1939 pp_space (this);
1940 pp_cxx_left_paren (this);
1941 expression (SWITCH_STMT_COND (t));
1942 pp_cxx_right_paren (this);
1943 pp_indentation (this) += 3;
1944 pp_needs_newline (this) = true;
1945 statement (SWITCH_STMT_BODY (t));
1946 pp_newline_and_indent (this, -3);
1947 break;
1949 /* iteration-statement:
1950 while ( expression ) statement
1951 do statement while ( expression ) ;
1952 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1953 for ( declaration expression(opt) ; expression(opt) ) statement */
1954 case WHILE_STMT:
1955 pp_cxx_ws_string (this, "while");
1956 pp_space (this);
1957 pp_cxx_left_paren (this);
1958 expression (WHILE_COND (t));
1959 pp_cxx_right_paren (this);
1960 pp_newline_and_indent (this, 3);
1961 statement (WHILE_BODY (t));
1962 pp_indentation (this) -= 3;
1963 pp_needs_newline (this) = true;
1964 break;
1966 case DO_STMT:
1967 pp_cxx_ws_string (this, "do");
1968 pp_newline_and_indent (this, 3);
1969 statement (DO_BODY (t));
1970 pp_newline_and_indent (this, -3);
1971 pp_cxx_ws_string (this, "while");
1972 pp_space (this);
1973 pp_cxx_left_paren (this);
1974 expression (DO_COND (t));
1975 pp_cxx_right_paren (this);
1976 pp_cxx_semicolon (this);
1977 pp_needs_newline (this) = true;
1978 break;
1980 case FOR_STMT:
1981 pp_cxx_ws_string (this, "for");
1982 pp_space (this);
1983 pp_cxx_left_paren (this);
1984 if (FOR_INIT_STMT (t))
1985 statement (FOR_INIT_STMT (t));
1986 else
1987 pp_cxx_semicolon (this);
1988 pp_needs_newline (this) = false;
1989 pp_cxx_whitespace (this);
1990 if (FOR_COND (t))
1991 expression (FOR_COND (t));
1992 pp_cxx_semicolon (this);
1993 pp_needs_newline (this) = false;
1994 pp_cxx_whitespace (this);
1995 if (FOR_EXPR (t))
1996 expression (FOR_EXPR (t));
1997 pp_cxx_right_paren (this);
1998 pp_newline_and_indent (this, 3);
1999 statement (FOR_BODY (t));
2000 pp_indentation (this) -= 3;
2001 pp_needs_newline (this) = true;
2002 break;
2004 case RANGE_FOR_STMT:
2005 pp_cxx_ws_string (this, "for");
2006 pp_space (this);
2007 pp_cxx_left_paren (this);
2008 statement (RANGE_FOR_DECL (t));
2009 pp_space (this);
2010 pp_needs_newline (this) = false;
2011 pp_colon (this);
2012 pp_space (this);
2013 statement (RANGE_FOR_EXPR (t));
2014 pp_cxx_right_paren (this);
2015 pp_newline_and_indent (this, 3);
2016 statement (FOR_BODY (t));
2017 pp_indentation (this) -= 3;
2018 pp_needs_newline (this) = true;
2019 break;
2021 /* jump-statement:
2022 goto identifier;
2023 continue ;
2024 return expression(opt) ; */
2025 case BREAK_STMT:
2026 case CONTINUE_STMT:
2027 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2028 pp_cxx_semicolon (this);
2029 pp_needs_newline (this) = true;
2030 break;
2032 /* expression-statement:
2033 expression(opt) ; */
2034 case EXPR_STMT:
2035 expression (EXPR_STMT_EXPR (t));
2036 pp_cxx_semicolon (this);
2037 pp_needs_newline (this) = true;
2038 break;
2040 case CLEANUP_STMT:
2041 pp_cxx_ws_string (this, "try");
2042 pp_newline_and_indent (this, 2);
2043 statement (CLEANUP_BODY (t));
2044 pp_newline_and_indent (this, -2);
2045 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2046 pp_newline_and_indent (this, 2);
2047 statement (CLEANUP_EXPR (t));
2048 pp_newline_and_indent (this, -2);
2049 break;
2051 case STATIC_ASSERT:
2052 declaration (t);
2053 break;
2055 default:
2056 c_pretty_printer::statement (t);
2057 break;
2061 /* original-namespace-definition:
2062 namespace identifier { namespace-body }
2064 As an edge case, we also handle unnamed namespace definition here. */
2066 static void
2067 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2069 pp_cxx_ws_string (pp, "namespace");
2070 if (DECL_CONTEXT (t))
2071 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2072 if (DECL_NAME (t))
2073 pp_cxx_unqualified_id (pp, t);
2074 pp_cxx_whitespace (pp);
2075 pp_cxx_left_brace (pp);
2076 /* We do not print the namespace-body. */
2077 pp_cxx_whitespace (pp);
2078 pp_cxx_right_brace (pp);
2081 /* namespace-alias:
2082 identifier
2084 namespace-alias-definition:
2085 namespace identifier = qualified-namespace-specifier ;
2087 qualified-namespace-specifier:
2088 ::(opt) nested-name-specifier(opt) namespace-name */
2090 static void
2091 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2093 pp_cxx_ws_string (pp, "namespace");
2094 if (DECL_CONTEXT (t))
2095 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2096 pp_cxx_unqualified_id (pp, t);
2097 pp_cxx_whitespace (pp);
2098 pp_equal (pp);
2099 pp_cxx_whitespace (pp);
2100 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2101 pp_cxx_nested_name_specifier (pp,
2102 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2103 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2104 pp_cxx_semicolon (pp);
2107 /* simple-declaration:
2108 decl-specifier-seq(opt) init-declarator-list(opt) */
2110 static void
2111 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2113 pp->declaration_specifiers (t);
2114 pp_cxx_init_declarator (pp, t);
2115 pp_cxx_semicolon (pp);
2116 pp_needs_newline (pp) = true;
2120 template-parameter-list:
2121 template-parameter
2122 template-parameter-list , template-parameter */
2124 static inline void
2125 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2127 const int n = TREE_VEC_LENGTH (t);
2128 int i;
2129 for (i = 0; i < n; ++i)
2131 if (i)
2132 pp_cxx_separate_with (pp, ',');
2133 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2137 /* template-parameter:
2138 type-parameter
2139 parameter-declaration
2141 type-parameter:
2142 class ...(opt) identifier(opt)
2143 class identifier(opt) = type-id
2144 typename identifier(opt)
2145 typename ...(opt) identifier(opt) = type-id
2146 template < template-parameter-list > class ...(opt) identifier(opt)
2147 template < template-parameter-list > class identifier(opt) = template-name */
2149 static void
2150 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2152 tree parameter = TREE_VALUE (t);
2153 switch (TREE_CODE (parameter))
2155 case TYPE_DECL:
2156 pp_cxx_ws_string (pp, "class");
2157 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2158 pp_cxx_ws_string (pp, "...");
2159 if (DECL_NAME (parameter))
2160 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2161 /* FIXME: Check if we should print also default argument. */
2162 break;
2164 case PARM_DECL:
2165 pp_cxx_parameter_declaration (pp, parameter);
2166 break;
2168 case TEMPLATE_DECL:
2169 break;
2171 default:
2172 pp_unsupported_tree (pp, t);
2173 break;
2177 /* Pretty-print a template parameter in the canonical form
2178 "template-parameter-<level>-<position in parameter list>". */
2180 void
2181 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2183 const enum tree_code code = TREE_CODE (parm);
2185 /* Brings type template parameters to the canonical forms. */
2186 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2187 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2188 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2190 pp_cxx_begin_template_argument_list (pp);
2191 pp->translate_string ("template-parameter-");
2192 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2193 pp_minus (pp);
2194 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2195 pp_cxx_end_template_argument_list (pp);
2199 template-declaration:
2200 export(opt) template < template-parameter-list > declaration
2202 Concept extensions:
2204 template-declaration:
2205 export(opt) template < template-parameter-list >
2206 requires-clause(opt) declaration */
2208 static void
2209 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2211 tree tmpl = most_general_template (t);
2212 tree level;
2214 pp_maybe_newline_and_indent (pp, 0);
2215 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2217 pp_cxx_ws_string (pp, "template");
2218 pp_cxx_begin_template_argument_list (pp);
2219 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2220 pp_cxx_end_template_argument_list (pp);
2221 pp_newline_and_indent (pp, 3);
2224 if (flag_concepts)
2225 if (tree ci = get_constraints (t))
2226 if (tree reqs = CI_TEMPLATE_REQS (ci))
2228 pp_cxx_requires_clause (pp, reqs);
2229 pp_newline_and_indent (pp, 6);
2232 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2233 pp_cxx_function_definition (pp, t);
2234 else
2235 pp_cxx_simple_declaration (pp, t);
2238 static void
2239 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2241 pp_unsupported_tree (pp, t);
2244 static void
2245 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2247 pp_unsupported_tree (pp, t);
2251 declaration:
2252 block-declaration
2253 function-definition
2254 template-declaration
2255 explicit-instantiation
2256 explicit-specialization
2257 linkage-specification
2258 namespace-definition
2260 block-declaration:
2261 simple-declaration
2262 asm-definition
2263 namespace-alias-definition
2264 using-declaration
2265 using-directive
2266 static_assert-declaration */
2267 void
2268 cxx_pretty_printer::declaration (tree t)
2270 if (TREE_CODE (t) == STATIC_ASSERT)
2272 pp_cxx_ws_string (this, "static_assert");
2273 pp_cxx_left_paren (this);
2274 expression (STATIC_ASSERT_CONDITION (t));
2275 pp_cxx_separate_with (this, ',');
2276 expression (STATIC_ASSERT_MESSAGE (t));
2277 pp_cxx_right_paren (this);
2279 else if (!DECL_LANG_SPECIFIC (t))
2280 pp_cxx_simple_declaration (this, t);
2281 else if (DECL_USE_TEMPLATE (t))
2282 switch (DECL_USE_TEMPLATE (t))
2284 case 1:
2285 pp_cxx_template_declaration (this, t);
2286 break;
2288 case 2:
2289 pp_cxx_explicit_specialization (this, t);
2290 break;
2292 case 3:
2293 pp_cxx_explicit_instantiation (this, t);
2294 break;
2296 default:
2297 break;
2299 else switch (TREE_CODE (t))
2301 case VAR_DECL:
2302 case TYPE_DECL:
2303 pp_cxx_simple_declaration (this, t);
2304 break;
2306 case FUNCTION_DECL:
2307 if (DECL_SAVED_TREE (t))
2308 pp_cxx_function_definition (this, t);
2309 else
2310 pp_cxx_simple_declaration (this, t);
2311 break;
2313 case NAMESPACE_DECL:
2314 if (DECL_NAMESPACE_ALIAS (t))
2315 pp_cxx_namespace_alias_definition (this, t);
2316 else
2317 pp_cxx_original_namespace_definition (this, t);
2318 break;
2320 default:
2321 pp_unsupported_tree (this, t);
2322 break;
2326 static void
2327 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2329 t = TREE_OPERAND (t, 0);
2330 pp_cxx_ws_string (pp, "typeid");
2331 pp_cxx_left_paren (pp);
2332 if (TYPE_P (t))
2333 pp->type_id (t);
2334 else
2335 pp->expression (t);
2336 pp_cxx_right_paren (pp);
2339 void
2340 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2342 pp_cxx_ws_string (pp, "va_arg");
2343 pp_cxx_left_paren (pp);
2344 pp->assignment_expression (TREE_OPERAND (t, 0));
2345 pp_cxx_separate_with (pp, ',');
2346 pp->type_id (TREE_TYPE (t));
2347 pp_cxx_right_paren (pp);
2350 static bool
2351 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2353 switch (TREE_CODE (t))
2355 case ARROW_EXPR:
2356 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2357 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2359 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2360 pp_cxx_separate_with (pp, ',');
2361 return true;
2363 return false;
2364 case COMPONENT_REF:
2365 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2366 return false;
2367 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2368 pp_cxx_dot (pp);
2369 pp->expression (TREE_OPERAND (t, 1));
2370 return true;
2371 case ARRAY_REF:
2372 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2373 return false;
2374 pp_left_bracket (pp);
2375 pp->expression (TREE_OPERAND (t, 1));
2376 pp_right_bracket (pp);
2377 return true;
2378 default:
2379 return false;
2383 void
2384 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2386 pp_cxx_ws_string (pp, "offsetof");
2387 pp_cxx_left_paren (pp);
2388 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2389 pp->expression (TREE_OPERAND (t, 0));
2390 pp_cxx_right_paren (pp);
2393 void
2394 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2396 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2398 switch (kind)
2400 case CPTK_HAS_NOTHROW_ASSIGN:
2401 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2402 break;
2403 case CPTK_HAS_TRIVIAL_ASSIGN:
2404 pp_cxx_ws_string (pp, "__has_trivial_assign");
2405 break;
2406 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2407 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2408 break;
2409 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2410 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2411 break;
2412 case CPTK_HAS_NOTHROW_COPY:
2413 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2414 break;
2415 case CPTK_HAS_TRIVIAL_COPY:
2416 pp_cxx_ws_string (pp, "__has_trivial_copy");
2417 break;
2418 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2419 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2420 break;
2421 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2422 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2423 break;
2424 case CPTK_IS_ABSTRACT:
2425 pp_cxx_ws_string (pp, "__is_abstract");
2426 break;
2427 case CPTK_IS_BASE_OF:
2428 pp_cxx_ws_string (pp, "__is_base_of");
2429 break;
2430 case CPTK_IS_CLASS:
2431 pp_cxx_ws_string (pp, "__is_class");
2432 break;
2433 case CPTK_IS_EMPTY:
2434 pp_cxx_ws_string (pp, "__is_empty");
2435 break;
2436 case CPTK_IS_ENUM:
2437 pp_cxx_ws_string (pp, "__is_enum");
2438 break;
2439 case CPTK_IS_FINAL:
2440 pp_cxx_ws_string (pp, "__is_final");
2441 break;
2442 case CPTK_IS_POD:
2443 pp_cxx_ws_string (pp, "__is_pod");
2444 break;
2445 case CPTK_IS_POLYMORPHIC:
2446 pp_cxx_ws_string (pp, "__is_polymorphic");
2447 break;
2448 case CPTK_IS_SAME_AS:
2449 pp_cxx_ws_string (pp, "__is_same_as");
2450 break;
2451 case CPTK_IS_STD_LAYOUT:
2452 pp_cxx_ws_string (pp, "__is_std_layout");
2453 break;
2454 case CPTK_IS_TRIVIAL:
2455 pp_cxx_ws_string (pp, "__is_trivial");
2456 break;
2457 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2458 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2459 break;
2460 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2461 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2462 break;
2463 case CPTK_IS_TRIVIALLY_COPYABLE:
2464 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2465 break;
2466 case CPTK_IS_UNION:
2467 pp_cxx_ws_string (pp, "__is_union");
2468 break;
2469 case CPTK_IS_LITERAL_TYPE:
2470 pp_cxx_ws_string (pp, "__is_literal_type");
2471 break;
2473 default:
2474 gcc_unreachable ();
2477 pp_cxx_left_paren (pp);
2478 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2480 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2482 pp_cxx_separate_with (pp, ',');
2483 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2486 pp_cxx_right_paren (pp);
2489 // requires-clause:
2490 // 'requires' logical-or-expression
2491 void
2492 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2494 if (!t)
2495 return;
2496 pp->padding = pp_before;
2497 pp_cxx_ws_string (pp, "requires");
2498 pp_space (pp);
2499 pp->expression (t);
2502 /* requirement:
2503 simple-requirement
2504 compound-requirement
2505 type-requirement
2506 nested-requirement */
2507 static void
2508 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2510 switch (TREE_CODE (t))
2512 case SIMPLE_REQ:
2513 pp_cxx_simple_requirement (pp, t);
2514 break;
2516 case TYPE_REQ:
2517 pp_cxx_type_requirement (pp, t);
2518 break;
2520 case COMPOUND_REQ:
2521 pp_cxx_compound_requirement (pp, t);
2522 break;
2524 case NESTED_REQ:
2525 pp_cxx_nested_requirement (pp, t);
2526 break;
2528 default:
2529 gcc_unreachable ();
2533 // requirement-list:
2534 // requirement
2535 // requirement-list ';' requirement[opt]
2537 static void
2538 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2540 for (; t; t = TREE_CHAIN (t))
2541 pp_cxx_requirement (pp, TREE_VALUE (t));
2544 // requirement-body:
2545 // '{' requirement-list '}'
2546 static void
2547 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2549 pp_cxx_left_brace (pp);
2550 pp_cxx_requirement_list (pp, t);
2551 pp_cxx_right_brace (pp);
2554 // requires-expression:
2555 // 'requires' requirement-parameter-list requirement-body
2556 void
2557 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2559 pp_string (pp, "requires");
2560 if (tree parms = TREE_OPERAND (t, 0))
2562 pp_cxx_parameter_declaration_clause (pp, parms);
2563 pp_cxx_whitespace (pp);
2565 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2568 /* simple-requirement:
2569 expression ';' */
2570 void
2571 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2573 pp->expression (TREE_OPERAND (t, 0));
2574 pp_cxx_semicolon (pp);
2577 /* type-requirement:
2578 typename type-name ';' */
2579 void
2580 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2582 pp->type_id (TREE_OPERAND (t, 0));
2583 pp_cxx_semicolon (pp);
2586 /* compound-requirement:
2587 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2588 void
2589 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2591 pp_cxx_left_brace (pp);
2592 pp->expression (TREE_OPERAND (t, 0));
2593 pp_cxx_right_brace (pp);
2595 if (COMPOUND_REQ_NOEXCEPT_P (t))
2596 pp_cxx_ws_string (pp, "noexcept");
2598 if (tree type = TREE_OPERAND (t, 1))
2600 pp_cxx_ws_string (pp, "->");
2601 pp->type_id (type);
2605 /* nested requirement:
2606 'requires' constraint-expression */
2607 void
2608 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2610 pp_cxx_ws_string (pp, "requires");
2611 pp->expression (TREE_OPERAND (t, 0));
2612 pp_cxx_semicolon (pp);
2615 void
2616 pp_cxx_predicate_constraint (cxx_pretty_printer *pp, tree t)
2618 pp_string (pp, "predicate");
2619 pp_left_paren (pp);
2620 pp->expression (TREE_OPERAND (t, 0));
2621 pp_right_paren (pp);
2624 void
2625 pp_cxx_expression_constraint (cxx_pretty_printer *pp, tree t)
2627 pp_string (pp, "valid_expr");
2628 pp_left_paren (pp);
2629 pp->expression (TREE_OPERAND (t, 0));
2630 pp_right_paren (pp);
2633 void
2634 pp_cxx_type_constraint (cxx_pretty_printer *pp, tree t)
2636 pp_string (pp, "valid_type");
2637 pp_left_paren (pp);
2638 pp->type_id (TREE_OPERAND (t, 0));
2639 pp_right_paren (pp);
2642 void
2643 pp_cxx_implicit_conversion_constraint (cxx_pretty_printer *pp, tree t)
2645 pp_string (pp, "convertible");
2646 pp_left_paren (pp);
2647 pp->expression (ICONV_CONSTR_EXPR (t));
2648 pp_cxx_separate_with (pp, ',');
2649 pp->expression (ICONV_CONSTR_TYPE (t));
2650 pp_right_paren (pp);
2653 void
2654 pp_cxx_argument_deduction_constraint (cxx_pretty_printer *pp, tree t)
2656 pp_string (pp, "deducible");
2657 pp_left_paren (pp);
2658 pp->expression (DEDUCT_CONSTR_EXPR (t));
2659 pp_cxx_separate_with (pp, ',');
2660 pp->expression (DEDUCT_CONSTR_PATTERN (t));
2661 pp_right_paren (pp);
2664 void
2665 pp_cxx_exception_constraint (cxx_pretty_printer *pp, tree t)
2667 pp_cxx_ws_string (pp, "noexcept");
2668 pp_left_paren (pp);
2669 pp->expression (TREE_OPERAND (t, 0));
2670 pp_right_paren (pp);
2673 void
2674 pp_cxx_parameterized_constraint (cxx_pretty_printer *pp, tree t)
2676 pp_left_paren (pp);
2677 pp_string (pp, "forall");
2678 if (tree parms = PARM_CONSTR_PARMS (t))
2680 if (parms)
2681 pp_cxx_parameter_declaration_clause (pp, parms);
2682 pp_cxx_whitespace (pp);
2684 pp_cxx_constraint (pp, PARM_CONSTR_OPERAND (t));
2685 pp_right_paren (pp);
2688 void
2689 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2691 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2692 pp_string (pp, " and ");
2693 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2696 void
2697 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2699 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2700 pp_string (pp, " or ");
2701 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2704 void
2705 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2707 if (t == error_mark_node)
2708 return pp->expression (t);
2710 switch (TREE_CODE (t))
2712 case PRED_CONSTR:
2713 pp_cxx_predicate_constraint (pp, t);
2714 break;
2716 case EXPR_CONSTR:
2717 pp_cxx_expression_constraint (pp, t);
2718 break;
2720 case TYPE_CONSTR:
2721 pp_cxx_type_constraint (pp, t);
2722 break;
2724 case ICONV_CONSTR:
2725 pp_cxx_implicit_conversion_constraint (pp, t);
2726 break;
2728 case DEDUCT_CONSTR:
2729 pp_cxx_argument_deduction_constraint (pp, t);
2730 break;
2732 case EXCEPT_CONSTR:
2733 pp_cxx_exception_constraint (pp, t);
2734 break;
2736 case PARM_CONSTR:
2737 pp_cxx_parameterized_constraint (pp, t);
2738 break;
2740 case CONJ_CONSTR:
2741 pp_cxx_conjunction (pp, t);
2742 break;
2744 case DISJ_CONSTR:
2745 pp_cxx_disjunction (pp, t);
2746 break;
2748 default:
2749 gcc_unreachable ();
2755 typedef c_pretty_print_fn pp_fun;
2757 /* Initialization of a C++ pretty-printer object. */
2759 cxx_pretty_printer::cxx_pretty_printer ()
2760 : c_pretty_printer (),
2761 enclosing_scope (global_namespace)
2763 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2764 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;