Merged with mainline at revision 128810.
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob9a27ae81a185fb78d0feaf22516bd01039cc8ad8
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003, 2004, 2005, 2007 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 "real.h"
26 #include "cxx-pretty-print.h"
27 #include "cp-tree.h"
28 #include "toplev.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_assignment_expression (cxx_pretty_printer *, tree);
34 static void pp_cxx_expression (cxx_pretty_printer *, tree);
35 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
36 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
37 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
38 static void pp_cxx_type_id (cxx_pretty_printer *, tree);
39 static void pp_cxx_direct_abstract_declarator (cxx_pretty_printer *, tree);
40 static void pp_cxx_declarator (cxx_pretty_printer *, tree);
41 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
42 static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
43 static void pp_cxx_statement (cxx_pretty_printer *, tree);
44 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
45 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
48 static inline void
49 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
51 const char *p = pp_last_position_in_text (pp);
53 if (p != NULL && *p == c)
54 pp_cxx_whitespace (pp);
55 pp_character (pp, c);
56 pp_base (pp)->padding = pp_none;
59 #define pp_cxx_storage_class_specifier(PP, T) \
60 pp_c_storage_class_specifier (pp_c_base (PP), T)
61 #define pp_cxx_expression_list(PP, T) \
62 pp_c_expression_list (pp_c_base (PP), T)
63 #define pp_cxx_space_for_pointer_operator(PP, T) \
64 pp_c_space_for_pointer_operator (pp_c_base (PP), T)
65 #define pp_cxx_init_declarator(PP, T) \
66 pp_c_init_declarator (pp_c_base (PP), T)
67 #define pp_cxx_call_argument_list(PP, T) \
68 pp_c_call_argument_list (pp_c_base (PP), T)
70 void
71 pp_cxx_colon_colon (cxx_pretty_printer *pp)
73 pp_colon_colon (pp);
74 pp_base (pp)->padding = pp_none;
77 void
78 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
80 pp_cxx_nonconsecutive_character (pp, '<');
83 void
84 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
86 pp_cxx_nonconsecutive_character (pp, '>');
89 void
90 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
92 pp_separate_with (pp, c);
93 pp_base (pp)->padding = pp_none;
96 /* Expressions. */
98 static inline bool
99 is_destructor_name (tree name)
101 return name == complete_dtor_identifier
102 || name == base_dtor_identifier
103 || name == deleting_dtor_identifier;
106 /* conversion-function-id:
107 operator conversion-type-id
109 conversion-type-id:
110 type-specifier-seq conversion-declarator(opt)
112 conversion-declarator:
113 ptr-operator conversion-declarator(opt) */
115 static inline void
116 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
118 pp_cxx_identifier (pp, "operator");
119 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
122 static inline void
123 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
125 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
126 pp_cxx_begin_template_argument_list (pp);
127 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
128 pp_cxx_end_template_argument_list (pp);
131 /* Prints the unqualified part of the id-expression T.
133 unqualified-id:
134 identifier
135 operator-function-id
136 conversion-function-id
137 ~ class-name
138 template-id */
140 static void
141 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
143 enum tree_code code = TREE_CODE (t);
144 switch (code)
146 case RESULT_DECL:
147 pp_cxx_identifier (pp, "<return-value>");
148 break;
150 case OVERLOAD:
151 t = OVL_CURRENT (t);
152 case VAR_DECL:
153 case PARM_DECL:
154 case CONST_DECL:
155 case TYPE_DECL:
156 case FUNCTION_DECL:
157 case NAMESPACE_DECL:
158 case FIELD_DECL:
159 case LABEL_DECL:
160 case USING_DECL:
161 case TEMPLATE_DECL:
162 t = DECL_NAME (t);
164 case IDENTIFIER_NODE:
165 if (t == NULL)
166 pp_cxx_identifier (pp, "<unnamed>");
167 else if (IDENTIFIER_TYPENAME_P (t))
168 pp_cxx_conversion_function_id (pp, t);
169 else
171 if (is_destructor_name (t))
173 pp_complement (pp);
174 /* FIXME: Why is this necessary? */
175 if (TREE_TYPE (t))
176 t = constructor_name (TREE_TYPE (t));
178 pp_cxx_tree_identifier (pp, t);
180 break;
182 case TEMPLATE_ID_EXPR:
183 pp_cxx_template_id (pp, t);
184 break;
186 case BASELINK:
187 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
188 break;
190 case RECORD_TYPE:
191 case UNION_TYPE:
192 case ENUMERAL_TYPE:
193 case TYPENAME_TYPE:
194 case UNBOUND_CLASS_TEMPLATE:
195 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
196 break;
198 case TEMPLATE_TYPE_PARM:
199 case TEMPLATE_TEMPLATE_PARM:
200 if (TYPE_IDENTIFIER (t))
201 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
202 else
203 pp_cxx_canonical_template_parameter (pp, t);
204 break;
206 case TEMPLATE_PARM_INDEX:
207 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
208 break;
210 case BOUND_TEMPLATE_TEMPLATE_PARM:
211 pp_cxx_cv_qualifier_seq (pp, t);
212 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
213 pp_cxx_begin_template_argument_list (pp);
214 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
215 pp_cxx_end_template_argument_list (pp);
216 break;
218 default:
219 pp_unsupported_tree (pp, t);
220 break;
224 /* Pretty-print out the token sequence ":: template" in template codes
225 where it is needed to "inline declare" the (following) member as
226 a template. This situation arises when SCOPE of T is dependent
227 on template parameters. */
229 static inline void
230 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
232 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
233 && TYPE_P (scope) && dependent_type_p (scope))
234 pp_cxx_identifier (pp, "template");
237 /* nested-name-specifier:
238 class-or-namespace-name :: nested-name-specifier(opt)
239 class-or-namespace-name :: template nested-name-specifier */
241 static void
242 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
244 if (t != NULL && t != pp->enclosing_scope)
246 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
247 pp_cxx_nested_name_specifier (pp, scope);
248 pp_cxx_template_keyword_if_needed (pp, scope, t);
249 pp_cxx_unqualified_id (pp, t);
250 pp_cxx_colon_colon (pp);
254 /* qualified-id:
255 nested-name-specifier template(opt) unqualified-id */
257 static void
258 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
260 switch (TREE_CODE (t))
262 /* A pointer-to-member is always qualified. */
263 case PTRMEM_CST:
264 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
265 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
266 break;
268 /* In Standard C++, functions cannot possibly be used as
269 nested-name-specifiers. However, there are situations where
270 is "makes sense" to output the surrounding function name for the
271 purpose of emphasizing on the scope kind. Just printing the
272 function name might not be sufficient as it may be overloaded; so,
273 we decorate the function with its signature too.
274 FIXME: This is probably the wrong pretty-printing for conversion
275 functions and some function templates. */
276 case OVERLOAD:
277 t = OVL_CURRENT (t);
278 case FUNCTION_DECL:
279 if (DECL_FUNCTION_MEMBER_P (t))
280 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
281 pp_cxx_unqualified_id
282 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
283 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
284 break;
286 case OFFSET_REF:
287 case SCOPE_REF:
288 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
289 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
290 break;
292 default:
294 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
295 if (scope != pp->enclosing_scope)
297 pp_cxx_nested_name_specifier (pp, scope);
298 pp_cxx_template_keyword_if_needed (pp, scope, t);
300 pp_cxx_unqualified_id (pp, t);
302 break;
307 static void
308 pp_cxx_constant (cxx_pretty_printer *pp, tree t)
310 switch (TREE_CODE (t))
312 case STRING_CST:
314 const bool in_parens = PAREN_STRING_LITERAL_P (t);
315 if (in_parens)
316 pp_cxx_left_paren (pp);
317 pp_c_constant (pp_c_base (pp), t);
318 if (in_parens)
319 pp_cxx_right_paren (pp);
321 break;
323 default:
324 pp_c_constant (pp_c_base (pp), t);
325 break;
329 /* id-expression:
330 unqualified-id
331 qualified-id */
333 static inline void
334 pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
336 if (TREE_CODE (t) == OVERLOAD)
337 t = OVL_CURRENT (t);
338 if (DECL_P (t) && DECL_CONTEXT (t))
339 pp_cxx_qualified_id (pp, t);
340 else
341 pp_cxx_unqualified_id (pp, t);
344 /* primary-expression:
345 literal
346 this
347 :: identifier
348 :: operator-function-id
349 :: qualifier-id
350 ( expression )
351 id-expression
353 GNU Extensions:
354 __builtin_va_arg ( assignment-expression , type-id )
356 __has_nothrow_assign ( type-id )
357 __has_nothrow_constructor ( type-id )
358 __has_nothrow_copy ( type-id )
359 __has_trivial_assign ( type-id )
360 __has_trivial_constructor ( type-id )
361 __has_trivial_copy ( type-id )
362 __has_trivial_destructor ( type-id )
363 __has_virtual_destructor ( type-id )
364 __is_abstract ( type-id )
365 __is_base_of ( type-id , type-id )
366 __is_class ( type-id )
367 __is_convertible_to ( type-id , type-id )
368 __is_empty ( type-id )
369 __is_enum ( type-id )
370 __is_pod ( type-id )
371 __is_polymorphic ( type-id )
372 __is_union ( type-id ) */
374 static void
375 pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
377 switch (TREE_CODE (t))
379 case INTEGER_CST:
380 case REAL_CST:
381 case COMPLEX_CST:
382 case STRING_CST:
383 pp_cxx_constant (pp, t);
384 break;
386 case BASELINK:
387 t = BASELINK_FUNCTIONS (t);
388 case VAR_DECL:
389 case PARM_DECL:
390 case FIELD_DECL:
391 case FUNCTION_DECL:
392 case OVERLOAD:
393 case CONST_DECL:
394 case TEMPLATE_DECL:
395 pp_cxx_id_expression (pp, t);
396 break;
398 case RESULT_DECL:
399 case TEMPLATE_TYPE_PARM:
400 case TEMPLATE_TEMPLATE_PARM:
401 case TEMPLATE_PARM_INDEX:
402 pp_cxx_unqualified_id (pp, t);
403 break;
405 case STMT_EXPR:
406 pp_cxx_left_paren (pp);
407 pp_cxx_statement (pp, STMT_EXPR_STMT (t));
408 pp_cxx_right_paren (pp);
409 break;
411 case TRAIT_EXPR:
412 pp_cxx_trait_expression (pp, t);
413 break;
415 case VA_ARG_EXPR:
416 pp_cxx_va_arg_expression (pp, t);
417 break;
419 default:
420 pp_c_primary_expression (pp_c_base (pp), t);
421 break;
425 /* postfix-expression:
426 primary-expression
427 postfix-expression [ expression ]
428 postfix-expression ( expression-list(opt) )
429 simple-type-specifier ( expression-list(opt) )
430 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
431 typename ::(opt) nested-name-specifier template(opt)
432 template-id ( expression-list(opt) )
433 postfix-expression . template(opt) ::(opt) id-expression
434 postfix-expression -> template(opt) ::(opt) id-expression
435 postfix-expression . pseudo-destructor-name
436 postfix-expression -> pseudo-destructor-name
437 postfix-expression ++
438 postfix-expression --
439 dynamic_cast < type-id > ( expression )
440 static_cast < type-id > ( expression )
441 reinterpret_cast < type-id > ( expression )
442 const_cast < type-id > ( expression )
443 typeid ( expression )
444 typeif ( type-id ) */
446 static void
447 pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
449 enum tree_code code = TREE_CODE (t);
451 switch (code)
453 case AGGR_INIT_EXPR:
454 case CALL_EXPR:
456 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
457 : CALL_EXPR_FN (t));
458 tree saved_scope = pp->enclosing_scope;
459 bool skipfirst = false;
460 tree arg;
462 if (TREE_CODE (fun) == ADDR_EXPR)
463 fun = TREE_OPERAND (fun, 0);
465 /* In templates, where there is no way to tell whether a given
466 call uses an actual member function. So the parser builds
467 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
468 instantiation time. */
469 if (TREE_CODE (fun) != FUNCTION_DECL)
471 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
473 tree object = (code == AGGR_INIT_EXPR
474 ? (AGGR_INIT_VIA_CTOR_P (t)
475 ? AGGR_INIT_EXPR_SLOT (t)
476 : AGGR_INIT_EXPR_ARG (t, 0))
477 : CALL_EXPR_ARG (t, 0));
479 while (TREE_CODE (object) == NOP_EXPR)
480 object = TREE_OPERAND (object, 0);
482 if (TREE_CODE (object) == ADDR_EXPR)
483 object = TREE_OPERAND (object, 0);
485 if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
487 pp_cxx_postfix_expression (pp, object);
488 pp_cxx_dot (pp);
490 else
492 pp_cxx_postfix_expression (pp, object);
493 pp_cxx_arrow (pp);
495 skipfirst = true;
496 pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
499 pp_cxx_postfix_expression (pp, fun);
500 pp->enclosing_scope = saved_scope;
501 pp_cxx_left_paren (pp);
502 if (code == AGGR_INIT_EXPR)
504 aggr_init_expr_arg_iterator iter;
505 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
507 if (skipfirst)
508 skipfirst = false;
509 else
511 pp_cxx_expression (pp, arg);
512 if (more_aggr_init_expr_args_p (&iter))
513 pp_cxx_separate_with (pp, ',');
517 else
519 call_expr_arg_iterator iter;
520 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
522 if (skipfirst)
523 skipfirst = false;
524 else
526 pp_cxx_expression (pp, arg);
527 if (more_call_expr_args_p (&iter))
528 pp_cxx_separate_with (pp, ',');
532 pp_cxx_right_paren (pp);
534 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
536 pp_cxx_separate_with (pp, ',');
537 pp_cxx_postfix_expression (pp, AGGR_INIT_EXPR_SLOT (t));
539 break;
541 case BASELINK:
542 case VAR_DECL:
543 case PARM_DECL:
544 case FIELD_DECL:
545 case FUNCTION_DECL:
546 case OVERLOAD:
547 case CONST_DECL:
548 case TEMPLATE_DECL:
549 case RESULT_DECL:
550 pp_cxx_primary_expression (pp, t);
551 break;
553 case DYNAMIC_CAST_EXPR:
554 case STATIC_CAST_EXPR:
555 case REINTERPRET_CAST_EXPR:
556 case CONST_CAST_EXPR:
557 if (code == DYNAMIC_CAST_EXPR)
558 pp_cxx_identifier (pp, "dynamic_cast");
559 else if (code == STATIC_CAST_EXPR)
560 pp_cxx_identifier (pp, "static_cast");
561 else if (code == REINTERPRET_CAST_EXPR)
562 pp_cxx_identifier (pp, "reinterpret_cast");
563 else
564 pp_cxx_identifier (pp, "const_cast");
565 pp_cxx_begin_template_argument_list (pp);
566 pp_cxx_type_id (pp, TREE_TYPE (t));
567 pp_cxx_end_template_argument_list (pp);
568 pp_left_paren (pp);
569 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
570 pp_right_paren (pp);
571 break;
573 case EMPTY_CLASS_EXPR:
574 pp_cxx_type_id (pp, TREE_TYPE (t));
575 pp_left_paren (pp);
576 pp_right_paren (pp);
577 break;
579 case TYPEID_EXPR:
580 pp_cxx_typeid_expression (pp, t);
581 break;
583 case PSEUDO_DTOR_EXPR:
584 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
585 pp_cxx_dot (pp);
586 pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
587 pp_cxx_colon_colon (pp);
588 pp_complement (pp);
589 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
590 break;
592 case ARROW_EXPR:
593 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
594 pp_cxx_arrow (pp);
595 break;
597 default:
598 pp_c_postfix_expression (pp_c_base (pp), t);
599 break;
603 /* new-expression:
604 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
605 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
607 new-placement:
608 ( expression-list )
610 new-type-id:
611 type-specifier-seq new-declarator(opt)
613 new-declarator:
614 ptr-operator new-declarator(opt)
615 direct-new-declarator
617 direct-new-declarator
618 [ expression ]
619 direct-new-declarator [ constant-expression ]
621 new-initializer:
622 ( expression-list(opt) ) */
624 static void
625 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
627 enum tree_code code = TREE_CODE (t);
628 switch (code)
630 case NEW_EXPR:
631 case VEC_NEW_EXPR:
632 if (NEW_EXPR_USE_GLOBAL (t))
633 pp_cxx_colon_colon (pp);
634 pp_cxx_identifier (pp, "new");
635 if (TREE_OPERAND (t, 0))
637 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
638 pp_space (pp);
640 /* FIXME: array-types are built with one more element. */
641 pp_cxx_type_id (pp, TREE_OPERAND (t, 1));
642 if (TREE_OPERAND (t, 2))
644 pp_left_paren (pp);
645 t = TREE_OPERAND (t, 2);
646 if (TREE_CODE (t) == TREE_LIST)
647 pp_c_expression_list (pp_c_base (pp), t);
648 else if (t == void_zero_node)
649 ; /* OK, empty initializer list. */
650 else
651 pp_cxx_expression (pp, t);
652 pp_right_paren (pp);
654 break;
656 default:
657 pp_unsupported_tree (pp, t);
661 /* delete-expression:
662 ::(opt) delete cast-expression
663 ::(opt) delete [ ] cast-expression */
665 static void
666 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
668 enum tree_code code = TREE_CODE (t);
669 switch (code)
671 case DELETE_EXPR:
672 case VEC_DELETE_EXPR:
673 if (DELETE_EXPR_USE_GLOBAL (t))
674 pp_cxx_colon_colon (pp);
675 pp_cxx_identifier (pp, "delete");
676 if (code == VEC_DELETE_EXPR)
678 pp_left_bracket (pp);
679 pp_right_bracket (pp);
681 pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
682 break;
684 default:
685 pp_unsupported_tree (pp, t);
689 /* unary-expression:
690 postfix-expression
691 ++ cast-expression
692 -- cast-expression
693 unary-operator cast-expression
694 sizeof unary-expression
695 sizeof ( type-id )
696 sizeof ... ( identifier )
697 new-expression
698 delete-expression
700 unary-operator: one of
701 * & + - !
703 GNU extensions:
704 __alignof__ unary-expression
705 __alignof__ ( type-id ) */
707 static void
708 pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
710 enum tree_code code = TREE_CODE (t);
711 switch (code)
713 case NEW_EXPR:
714 case VEC_NEW_EXPR:
715 pp_cxx_new_expression (pp, t);
716 break;
718 case DELETE_EXPR:
719 case VEC_DELETE_EXPR:
720 pp_cxx_delete_expression (pp, t);
721 break;
723 case SIZEOF_EXPR:
724 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
726 pp_cxx_identifier (pp, "sizeof");
727 pp_cxx_identifier (pp, "...");
728 pp_cxx_whitespace (pp);
729 pp_cxx_left_paren (pp);
730 if (TYPE_P (TREE_OPERAND (t, 0)))
731 pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
732 else
733 pp_unary_expression (pp, TREE_OPERAND (t, 0));
734 pp_cxx_right_paren (pp);
735 break;
737 /* Fall through */
739 case ALIGNOF_EXPR:
740 pp_cxx_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
741 pp_cxx_whitespace (pp);
742 if (TYPE_P (TREE_OPERAND (t, 0)))
744 pp_cxx_left_paren (pp);
745 pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
746 pp_cxx_right_paren (pp);
748 else
749 pp_unary_expression (pp, TREE_OPERAND (t, 0));
750 break;
752 case UNARY_PLUS_EXPR:
753 pp_plus (pp);
754 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
755 break;
757 default:
758 pp_c_unary_expression (pp_c_base (pp), t);
759 break;
763 /* cast-expression:
764 unary-expression
765 ( type-id ) cast-expression */
767 static void
768 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
770 switch (TREE_CODE (t))
772 case CAST_EXPR:
773 pp_cxx_type_id (pp, TREE_TYPE (t));
774 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
775 break;
777 default:
778 pp_c_cast_expression (pp_c_base (pp), t);
779 break;
783 /* pm-expression:
784 cast-expression
785 pm-expression .* cast-expression
786 pm-expression ->* cast-expression */
788 static void
789 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
791 switch (TREE_CODE (t))
793 /* Handle unfortunate OFFESET_REF overloading here. */
794 case OFFSET_REF:
795 if (TYPE_P (TREE_OPERAND (t, 0)))
797 pp_cxx_qualified_id (pp, t);
798 break;
800 /* Else fall through. */
801 case MEMBER_REF:
802 case DOTSTAR_EXPR:
803 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
804 pp_cxx_dot (pp);
805 pp_star(pp);
806 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
807 break;
810 default:
811 pp_cxx_cast_expression (pp, t);
812 break;
816 /* multiplicative-expression:
817 pm-expression
818 multiplicative-expression * pm-expression
819 multiplicative-expression / pm-expression
820 multiplicative-expression % pm-expression */
822 static void
823 pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
825 enum tree_code code = TREE_CODE (e);
826 switch (code)
828 case MULT_EXPR:
829 case TRUNC_DIV_EXPR:
830 case TRUNC_MOD_EXPR:
831 pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
832 pp_space (pp);
833 if (code == MULT_EXPR)
834 pp_star (pp);
835 else if (code == TRUNC_DIV_EXPR)
836 pp_slash (pp);
837 else
838 pp_modulo (pp);
839 pp_space (pp);
840 pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
841 break;
843 default:
844 pp_cxx_pm_expression (pp, e);
845 break;
849 /* conditional-expression:
850 logical-or-expression
851 logical-or-expression ? expression : assignment-expression */
853 static void
854 pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
856 if (TREE_CODE (e) == COND_EXPR)
858 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
859 pp_space (pp);
860 pp_question (pp);
861 pp_space (pp);
862 pp_cxx_expression (pp, TREE_OPERAND (e, 1));
863 pp_space (pp);
864 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
866 else
867 pp_c_logical_or_expression (pp_c_base (pp), e);
870 /* Pretty-print a compound assignment operator token as indicated by T. */
872 static void
873 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
875 const char *op;
877 switch (TREE_CODE (t))
879 case NOP_EXPR:
880 op = "=";
881 break;
883 case PLUS_EXPR:
884 op = "+=";
885 break;
887 case MINUS_EXPR:
888 op = "-=";
889 break;
891 case TRUNC_DIV_EXPR:
892 op = "/=";
893 break;
895 case TRUNC_MOD_EXPR:
896 op = "%=";
897 break;
899 default:
900 op = tree_code_name[TREE_CODE (t)];
901 break;
904 pp_cxx_identifier (pp, op);
908 /* assignment-expression:
909 conditional-expression
910 logical-or-expression assignment-operator assignment-expression
911 throw-expression
913 throw-expression:
914 throw assignment-expression(opt)
916 assignment-operator: one of
917 = *= /= %= += -= >>= <<= &= ^= |= */
919 static void
920 pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
922 switch (TREE_CODE (e))
924 case MODIFY_EXPR:
925 case INIT_EXPR:
926 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
927 pp_space (pp);
928 pp_equal (pp);
929 pp_space (pp);
930 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
931 break;
933 case THROW_EXPR:
934 pp_cxx_identifier (pp, "throw");
935 if (TREE_OPERAND (e, 0))
936 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
937 break;
939 case MODOP_EXPR:
940 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
941 pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
942 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
943 break;
945 default:
946 pp_cxx_conditional_expression (pp, e);
947 break;
951 static void
952 pp_cxx_expression (cxx_pretty_printer *pp, tree t)
954 switch (TREE_CODE (t))
956 case STRING_CST:
957 case INTEGER_CST:
958 case REAL_CST:
959 case COMPLEX_CST:
960 pp_cxx_constant (pp, t);
961 break;
963 case RESULT_DECL:
964 pp_cxx_unqualified_id (pp, t);
965 break;
967 #if 0
968 case OFFSET_REF:
969 #endif
970 case SCOPE_REF:
971 case PTRMEM_CST:
972 pp_cxx_qualified_id (pp, t);
973 break;
975 case OVERLOAD:
976 t = OVL_CURRENT (t);
977 case VAR_DECL:
978 case PARM_DECL:
979 case FIELD_DECL:
980 case CONST_DECL:
981 case FUNCTION_DECL:
982 case BASELINK:
983 case TEMPLATE_DECL:
984 case TEMPLATE_TYPE_PARM:
985 case TEMPLATE_PARM_INDEX:
986 case TEMPLATE_TEMPLATE_PARM:
987 case STMT_EXPR:
988 pp_cxx_primary_expression (pp, t);
989 break;
991 case CALL_EXPR:
992 case DYNAMIC_CAST_EXPR:
993 case STATIC_CAST_EXPR:
994 case REINTERPRET_CAST_EXPR:
995 case CONST_CAST_EXPR:
996 #if 0
997 case MEMBER_REF:
998 #endif
999 case EMPTY_CLASS_EXPR:
1000 case TYPEID_EXPR:
1001 case PSEUDO_DTOR_EXPR:
1002 case AGGR_INIT_EXPR:
1003 case ARROW_EXPR:
1004 pp_cxx_postfix_expression (pp, t);
1005 break;
1007 case NEW_EXPR:
1008 case VEC_NEW_EXPR:
1009 pp_cxx_new_expression (pp, t);
1010 break;
1012 case DELETE_EXPR:
1013 case VEC_DELETE_EXPR:
1014 pp_cxx_delete_expression (pp, t);
1015 break;
1017 case SIZEOF_EXPR:
1018 case ALIGNOF_EXPR:
1019 pp_cxx_unary_expression (pp, t);
1020 break;
1022 case CAST_EXPR:
1023 pp_cxx_cast_expression (pp, t);
1024 break;
1026 case OFFSET_REF:
1027 case MEMBER_REF:
1028 case DOTSTAR_EXPR:
1029 pp_cxx_pm_expression (pp, t);
1030 break;
1032 case MULT_EXPR:
1033 case TRUNC_DIV_EXPR:
1034 case TRUNC_MOD_EXPR:
1035 pp_cxx_multiplicative_expression (pp, t);
1036 break;
1038 case COND_EXPR:
1039 pp_cxx_conditional_expression (pp, t);
1040 break;
1042 case MODIFY_EXPR:
1043 case INIT_EXPR:
1044 case THROW_EXPR:
1045 case MODOP_EXPR:
1046 pp_cxx_assignment_expression (pp, t);
1047 break;
1049 case NON_DEPENDENT_EXPR:
1050 case MUST_NOT_THROW_EXPR:
1051 pp_cxx_expression (pp, t);
1052 break;
1054 case EXPR_PACK_EXPANSION:
1055 pp_cxx_expression (pp, PACK_EXPANSION_PATTERN (t));
1056 pp_cxx_identifier (pp, "...");
1057 break;
1059 case NONTYPE_ARGUMENT_PACK:
1061 tree args = ARGUMENT_PACK_ARGS (t);
1062 int i, len = TREE_VEC_LENGTH (args);
1063 for (i = 0; i < len; ++i)
1065 if (i > 0)
1066 pp_cxx_separate_with (pp, ',');
1067 pp_cxx_expression (pp, TREE_VEC_ELT (args, i));
1070 break;
1072 default:
1073 pp_c_expression (pp_c_base (pp), t);
1074 break;
1079 /* Declarations. */
1081 /* function-specifier:
1082 inline
1083 virtual
1084 explicit */
1086 static void
1087 pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
1089 switch (TREE_CODE (t))
1091 case FUNCTION_DECL:
1092 if (DECL_VIRTUAL_P (t))
1093 pp_cxx_identifier (pp, "virtual");
1094 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1095 pp_cxx_identifier (pp, "explicit");
1096 else
1097 pp_c_function_specifier (pp_c_base (pp), t);
1099 default:
1100 break;
1104 /* decl-specifier-seq:
1105 decl-specifier-seq(opt) decl-specifier
1107 decl-specifier:
1108 storage-class-specifier
1109 type-specifier
1110 function-specifier
1111 friend
1112 typedef */
1114 static void
1115 pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
1117 switch (TREE_CODE (t))
1119 case VAR_DECL:
1120 case PARM_DECL:
1121 case CONST_DECL:
1122 case FIELD_DECL:
1123 pp_cxx_storage_class_specifier (pp, t);
1124 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1125 break;
1127 case TYPE_DECL:
1128 pp_cxx_identifier (pp, "typedef");
1129 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1130 break;
1132 case RECORD_TYPE:
1133 if (TYPE_PTRMEMFUNC_P (t))
1135 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1136 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
1137 pp_cxx_whitespace (pp);
1138 pp_cxx_ptr_operator (pp, t);
1140 break;
1142 case FUNCTION_DECL:
1143 /* Constructors don't have return types. And conversion functions
1144 do not have a type-specifier in their return types. */
1145 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1146 pp_cxx_function_specifier (pp, t);
1147 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1148 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
1149 else
1150 default:
1151 pp_c_declaration_specifiers (pp_c_base (pp), t);
1152 break;
1156 /* simple-type-specifier:
1157 ::(opt) nested-name-specifier(opt) type-name
1158 ::(opt) nested-name-specifier(opt) template(opt) template-id
1159 char
1160 wchar_t
1161 bool
1162 short
1164 long
1165 signed
1166 unsigned
1167 float
1168 double
1169 void */
1171 static void
1172 pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
1174 switch (TREE_CODE (t))
1176 case RECORD_TYPE:
1177 case UNION_TYPE:
1178 case ENUMERAL_TYPE:
1179 pp_cxx_qualified_id (pp, t);
1180 break;
1182 case TEMPLATE_TYPE_PARM:
1183 case TEMPLATE_TEMPLATE_PARM:
1184 case TEMPLATE_PARM_INDEX:
1185 pp_cxx_unqualified_id (pp, t);
1186 break;
1188 case TYPENAME_TYPE:
1189 pp_cxx_identifier (pp, "typename");
1190 pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1191 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1192 break;
1194 default:
1195 pp_c_type_specifier (pp_c_base (pp), t);
1196 break;
1200 /* type-specifier-seq:
1201 type-specifier type-specifier-seq(opt)
1203 type-specifier:
1204 simple-type-specifier
1205 class-specifier
1206 enum-specifier
1207 elaborated-type-specifier
1208 cv-qualifier */
1210 static void
1211 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1213 switch (TREE_CODE (t))
1215 case TEMPLATE_DECL:
1216 case TEMPLATE_TYPE_PARM:
1217 case TEMPLATE_TEMPLATE_PARM:
1218 case TYPE_DECL:
1219 case BOUND_TEMPLATE_TEMPLATE_PARM:
1220 pp_cxx_cv_qualifier_seq (pp, t);
1221 pp_cxx_simple_type_specifier (pp, t);
1222 break;
1224 case METHOD_TYPE:
1225 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1226 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1227 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1228 break;
1230 case DECLTYPE_TYPE:
1231 pp_cxx_identifier (pp, "decltype");
1232 pp_cxx_left_paren (pp);
1233 pp_cxx_expression (pp, DECLTYPE_TYPE_EXPR (t));
1234 pp_cxx_right_paren (pp);
1235 break;
1237 default:
1238 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1239 pp_c_specifier_qualifier_list (pp_c_base (pp), t);
1243 /* ptr-operator:
1244 * cv-qualifier-seq(opt)
1246 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1248 static void
1249 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1251 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1252 t = TREE_TYPE (t);
1253 switch (TREE_CODE (t))
1255 case REFERENCE_TYPE:
1256 case POINTER_TYPE:
1257 if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
1258 || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
1259 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1260 if (TREE_CODE (t) == POINTER_TYPE)
1262 pp_star (pp);
1263 pp_cxx_cv_qualifier_seq (pp, t);
1265 else
1266 pp_ampersand (pp);
1267 break;
1269 case RECORD_TYPE:
1270 if (TYPE_PTRMEMFUNC_P (t))
1272 pp_cxx_left_paren (pp);
1273 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1274 pp_star (pp);
1275 break;
1277 case OFFSET_TYPE:
1278 if (TYPE_PTR_TO_MEMBER_P (t))
1280 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1281 pp_cxx_left_paren (pp);
1282 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1283 pp_star (pp);
1284 pp_cxx_cv_qualifier_seq (pp, t);
1285 break;
1287 /* else fall through. */
1289 default:
1290 pp_unsupported_tree (pp, t);
1291 break;
1295 static inline tree
1296 pp_cxx_implicit_parameter_type (tree mf)
1298 return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1302 parameter-declaration:
1303 decl-specifier-seq declarator
1304 decl-specifier-seq declarator = assignment-expression
1305 decl-specifier-seq abstract-declarator(opt)
1306 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1308 static inline void
1309 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1311 pp_cxx_decl_specifier_seq (pp, t);
1312 if (TYPE_P (t))
1313 pp_cxx_abstract_declarator (pp, t);
1314 else
1315 pp_cxx_declarator (pp, t);
1318 /* parameter-declaration-clause:
1319 parameter-declaration-list(opt) ...(opt)
1320 parameter-declaration-list , ...
1322 parameter-declaration-list:
1323 parameter-declaration
1324 parameter-declaration-list , parameter-declaration */
1326 static void
1327 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1329 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1330 tree types =
1331 TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1332 const bool abstract = args == NULL
1333 || pp_c_base (pp)->flags & pp_c_flag_abstract;
1334 bool first = true;
1336 /* Skip artificial parameter for nonstatic member functions. */
1337 if (TREE_CODE (t) == METHOD_TYPE)
1338 types = TREE_CHAIN (types);
1340 pp_cxx_left_paren (pp);
1341 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1343 if (!first)
1344 pp_cxx_separate_with (pp, ',');
1345 first = false;
1346 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1347 if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1349 pp_cxx_whitespace (pp);
1350 pp_equal (pp);
1351 pp_cxx_whitespace (pp);
1352 pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1355 pp_cxx_right_paren (pp);
1358 /* exception-specification:
1359 throw ( type-id-list(opt) )
1361 type-id-list
1362 type-id
1363 type-id-list , type-id */
1365 static void
1366 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1368 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1369 bool need_comma = false;
1371 if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1372 return;
1373 pp_cxx_identifier (pp, "throw");
1374 pp_cxx_left_paren (pp);
1375 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1377 tree type = TREE_VALUE (ex_spec);
1378 tree argpack = NULL_TREE;
1379 int i, len = 1;
1381 if (ARGUMENT_PACK_P (type))
1383 argpack = ARGUMENT_PACK_ARGS (type);
1384 len = TREE_VEC_LENGTH (argpack);
1387 for (i = 0; i < len; ++i)
1389 if (argpack)
1390 type = TREE_VEC_ELT (argpack, i);
1392 if (need_comma)
1393 pp_cxx_separate_with (pp, ',');
1394 else
1395 need_comma = true;
1397 pp_cxx_type_id (pp, type);
1400 pp_cxx_right_paren (pp);
1403 /* direct-declarator:
1404 declarator-id
1405 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1406 exception-specification(opt)
1407 direct-declaration [ constant-expression(opt) ]
1408 ( declarator ) */
1410 static void
1411 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1413 switch (TREE_CODE (t))
1415 case VAR_DECL:
1416 case PARM_DECL:
1417 case CONST_DECL:
1418 case FIELD_DECL:
1419 if (DECL_NAME (t))
1421 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1423 if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
1424 || template_parameter_pack_p (t))
1425 /* A function parameter pack or non-type template
1426 parameter pack. */
1427 pp_cxx_identifier (pp, "...");
1429 pp_cxx_id_expression (pp, DECL_NAME (t));
1431 pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1432 break;
1434 case FUNCTION_DECL:
1435 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1436 pp_cxx_id_expression (pp, t);
1437 pp_cxx_parameter_declaration_clause (pp, t);
1439 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1441 pp_base (pp)->padding = pp_before;
1442 pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1445 pp_cxx_exception_specification (pp, TREE_TYPE (t));
1446 break;
1448 case TYPENAME_TYPE:
1449 case TEMPLATE_DECL:
1450 case TEMPLATE_TYPE_PARM:
1451 case TEMPLATE_PARM_INDEX:
1452 case TEMPLATE_TEMPLATE_PARM:
1453 break;
1455 default:
1456 pp_c_direct_declarator (pp_c_base (pp), t);
1457 break;
1461 /* declarator:
1462 direct-declarator
1463 ptr-operator declarator */
1465 static void
1466 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1468 pp_cxx_direct_declarator (pp, t);
1471 /* ctor-initializer:
1472 : mem-initializer-list
1474 mem-initializer-list:
1475 mem-initializer
1476 mem-initializer , mem-initializer-list
1478 mem-initializer:
1479 mem-initializer-id ( expression-list(opt) )
1481 mem-initializer-id:
1482 ::(opt) nested-name-specifier(opt) class-name
1483 identifier */
1485 static void
1486 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1488 t = TREE_OPERAND (t, 0);
1489 pp_cxx_whitespace (pp);
1490 pp_colon (pp);
1491 pp_cxx_whitespace (pp);
1492 for (; t; t = TREE_CHAIN (t))
1494 tree purpose = TREE_PURPOSE (t);
1495 bool is_pack = PACK_EXPANSION_P (purpose);
1497 if (is_pack)
1498 pp_cxx_primary_expression (pp, PACK_EXPANSION_PATTERN (purpose));
1499 else
1500 pp_cxx_primary_expression (pp, purpose);
1501 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1502 if (is_pack)
1503 pp_cxx_identifier (pp, "...");
1504 if (TREE_CHAIN (t))
1505 pp_cxx_separate_with (pp, ',');
1509 /* function-definition:
1510 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1511 decl-specifier-seq(opt) declarator function-try-block */
1513 static void
1514 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1516 tree saved_scope = pp->enclosing_scope;
1517 pp_cxx_decl_specifier_seq (pp, t);
1518 pp_cxx_declarator (pp, t);
1519 pp_needs_newline (pp) = true;
1520 pp->enclosing_scope = DECL_CONTEXT (t);
1521 if (DECL_SAVED_TREE (t))
1522 pp_cxx_statement (pp, DECL_SAVED_TREE (t));
1523 else
1525 pp_cxx_semicolon (pp);
1526 pp_needs_newline (pp) = true;
1528 pp_flush (pp);
1529 pp->enclosing_scope = saved_scope;
1532 /* abstract-declarator:
1533 ptr-operator abstract-declarator(opt)
1534 direct-abstract-declarator */
1536 static void
1537 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1539 if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1540 pp_cxx_right_paren (pp);
1541 else if (POINTER_TYPE_P (t))
1543 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1544 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1545 pp_cxx_right_paren (pp);
1546 t = TREE_TYPE (t);
1548 pp_cxx_direct_abstract_declarator (pp, t);
1551 /* direct-abstract-declarator:
1552 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1553 cv-qualifier-seq(opt) exception-specification(opt)
1554 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1555 ( abstract-declarator ) */
1557 static void
1558 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1560 switch (TREE_CODE (t))
1562 case REFERENCE_TYPE:
1563 pp_cxx_abstract_declarator (pp, t);
1564 break;
1566 case RECORD_TYPE:
1567 if (TYPE_PTRMEMFUNC_P (t))
1568 pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1569 break;
1571 case METHOD_TYPE:
1572 case FUNCTION_TYPE:
1573 pp_cxx_parameter_declaration_clause (pp, t);
1574 pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1575 if (TREE_CODE (t) == METHOD_TYPE)
1577 pp_base (pp)->padding = pp_before;
1578 pp_cxx_cv_qualifier_seq
1579 (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1581 pp_cxx_exception_specification (pp, t);
1582 break;
1584 case TYPENAME_TYPE:
1585 case TEMPLATE_TYPE_PARM:
1586 case TEMPLATE_TEMPLATE_PARM:
1587 case BOUND_TEMPLATE_TEMPLATE_PARM:
1588 case UNBOUND_CLASS_TEMPLATE:
1589 break;
1591 default:
1592 pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1593 break;
1597 /* type-id:
1598 type-specifier-seq abstract-declarator(opt) */
1600 static void
1601 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1603 pp_flags saved_flags = pp_c_base (pp)->flags;
1604 pp_c_base (pp)->flags |= pp_c_flag_abstract;
1606 switch (TREE_CODE (t))
1608 case TYPE_DECL:
1609 case UNION_TYPE:
1610 case RECORD_TYPE:
1611 case ENUMERAL_TYPE:
1612 case TYPENAME_TYPE:
1613 case BOUND_TEMPLATE_TEMPLATE_PARM:
1614 case UNBOUND_CLASS_TEMPLATE:
1615 case TEMPLATE_TEMPLATE_PARM:
1616 case TEMPLATE_TYPE_PARM:
1617 case TEMPLATE_PARM_INDEX:
1618 case TEMPLATE_DECL:
1619 case TYPEOF_TYPE:
1620 case DECLTYPE_TYPE:
1621 case TEMPLATE_ID_EXPR:
1622 pp_cxx_type_specifier_seq (pp, t);
1623 break;
1625 case TYPE_PACK_EXPANSION:
1626 pp_cxx_type_id (pp, PACK_EXPANSION_PATTERN (t));
1627 pp_cxx_identifier (pp, "...");
1628 break;
1630 default:
1631 pp_c_type_id (pp_c_base (pp), t);
1632 break;
1635 pp_c_base (pp)->flags = saved_flags;
1638 /* template-argument-list:
1639 template-argument ...(opt)
1640 template-argument-list, template-argument ...(opt)
1642 template-argument:
1643 assignment-expression
1644 type-id
1645 template-name */
1647 static void
1648 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1650 int i;
1651 bool need_comma = false;
1653 if (t == NULL)
1654 return;
1655 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1657 tree arg = TREE_VEC_ELT (t, i);
1658 tree argpack = NULL_TREE;
1659 int idx, len = 1;
1661 if (ARGUMENT_PACK_P (arg))
1663 argpack = ARGUMENT_PACK_ARGS (arg);
1664 len = TREE_VEC_LENGTH (argpack);
1667 for (idx = 0; idx < len; idx++)
1669 if (argpack)
1670 arg = TREE_VEC_ELT (argpack, idx);
1672 if (need_comma)
1673 pp_cxx_separate_with (pp, ',');
1674 else
1675 need_comma = true;
1677 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1678 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1679 pp_cxx_type_id (pp, arg);
1680 else
1681 pp_cxx_expression (pp, arg);
1687 static void
1688 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1690 t = DECL_EXPR_DECL (t);
1691 pp_cxx_type_specifier_seq (pp, t);
1692 if (TYPE_P (t))
1693 pp_cxx_abstract_declarator (pp, t);
1694 else
1695 pp_cxx_declarator (pp, t);
1698 /* Statements. */
1700 static void
1701 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1703 switch (TREE_CODE (t))
1705 case CTOR_INITIALIZER:
1706 pp_cxx_ctor_initializer (pp, t);
1707 break;
1709 case USING_STMT:
1710 pp_cxx_identifier (pp, "using");
1711 pp_cxx_identifier (pp, "namespace");
1712 if (DECL_CONTEXT (t))
1713 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1714 pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1715 break;
1717 case USING_DECL:
1718 pp_cxx_identifier (pp, "using");
1719 pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
1720 pp_cxx_unqualified_id (pp, DECL_NAME (t));
1721 break;
1723 case EH_SPEC_BLOCK:
1724 break;
1726 /* try-block:
1727 try compound-statement handler-seq */
1728 case TRY_BLOCK:
1729 pp_maybe_newline_and_indent (pp, 0);
1730 pp_cxx_identifier (pp, "try");
1731 pp_newline_and_indent (pp, 3);
1732 pp_cxx_statement (pp, TRY_STMTS (t));
1733 pp_newline_and_indent (pp, -3);
1734 if (CLEANUP_P (t))
1736 else
1737 pp_cxx_statement (pp, TRY_HANDLERS (t));
1738 break;
1741 handler-seq:
1742 handler handler-seq(opt)
1744 handler:
1745 catch ( exception-declaration ) compound-statement
1747 exception-declaration:
1748 type-specifier-seq declarator
1749 type-specifier-seq abstract-declarator
1750 ... */
1751 case HANDLER:
1752 pp_cxx_identifier (pp, "catch");
1753 pp_cxx_left_paren (pp);
1754 pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1755 pp_cxx_right_paren (pp);
1756 pp_indentation (pp) += 3;
1757 pp_needs_newline (pp) = true;
1758 pp_cxx_statement (pp, HANDLER_BODY (t));
1759 pp_indentation (pp) -= 3;
1760 pp_needs_newline (pp) = true;
1761 break;
1763 /* selection-statement:
1764 if ( expression ) statement
1765 if ( expression ) statement else statement */
1766 case IF_STMT:
1767 pp_cxx_identifier (pp, "if");
1768 pp_cxx_whitespace (pp);
1769 pp_cxx_left_paren (pp);
1770 pp_cxx_expression (pp, IF_COND (t));
1771 pp_cxx_right_paren (pp);
1772 pp_newline_and_indent (pp, 2);
1773 pp_cxx_statement (pp, THEN_CLAUSE (t));
1774 pp_newline_and_indent (pp, -2);
1775 if (ELSE_CLAUSE (t))
1777 tree else_clause = ELSE_CLAUSE (t);
1778 pp_cxx_identifier (pp, "else");
1779 if (TREE_CODE (else_clause) == IF_STMT)
1780 pp_cxx_whitespace (pp);
1781 else
1782 pp_newline_and_indent (pp, 2);
1783 pp_cxx_statement (pp, else_clause);
1784 if (TREE_CODE (else_clause) != IF_STMT)
1785 pp_newline_and_indent (pp, -2);
1787 break;
1789 case SWITCH_STMT:
1790 pp_cxx_identifier (pp, "switch");
1791 pp_space (pp);
1792 pp_cxx_left_paren (pp);
1793 pp_cxx_expression (pp, SWITCH_STMT_COND (t));
1794 pp_cxx_right_paren (pp);
1795 pp_indentation (pp) += 3;
1796 pp_needs_newline (pp) = true;
1797 pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
1798 pp_newline_and_indent (pp, -3);
1799 break;
1801 /* iteration-statement:
1802 while ( expression ) statement
1803 do statement while ( expression ) ;
1804 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1805 for ( declaration expression(opt) ; expression(opt) ) statement */
1806 case WHILE_STMT:
1807 pp_cxx_identifier (pp, "while");
1808 pp_space (pp);
1809 pp_cxx_left_paren (pp);
1810 pp_cxx_expression (pp, WHILE_COND (t));
1811 pp_cxx_right_paren (pp);
1812 pp_newline_and_indent (pp, 3);
1813 pp_cxx_statement (pp, WHILE_BODY (t));
1814 pp_indentation (pp) -= 3;
1815 pp_needs_newline (pp) = true;
1816 break;
1818 case DO_STMT:
1819 pp_cxx_identifier (pp, "do");
1820 pp_newline_and_indent (pp, 3);
1821 pp_cxx_statement (pp, DO_BODY (t));
1822 pp_newline_and_indent (pp, -3);
1823 pp_cxx_identifier (pp, "while");
1824 pp_space (pp);
1825 pp_cxx_left_paren (pp);
1826 pp_cxx_expression (pp, DO_COND (t));
1827 pp_cxx_right_paren (pp);
1828 pp_cxx_semicolon (pp);
1829 pp_needs_newline (pp) = true;
1830 break;
1832 case FOR_STMT:
1833 pp_cxx_identifier (pp, "for");
1834 pp_space (pp);
1835 pp_cxx_left_paren (pp);
1836 if (FOR_INIT_STMT (t))
1837 pp_cxx_statement (pp, FOR_INIT_STMT (t));
1838 else
1839 pp_cxx_semicolon (pp);
1840 pp_needs_newline (pp) = false;
1841 pp_cxx_whitespace (pp);
1842 if (FOR_COND (t))
1843 pp_cxx_expression (pp, FOR_COND (t));
1844 pp_cxx_semicolon (pp);
1845 pp_needs_newline (pp) = false;
1846 pp_cxx_whitespace (pp);
1847 if (FOR_EXPR (t))
1848 pp_cxx_expression (pp, FOR_EXPR (t));
1849 pp_cxx_right_paren (pp);
1850 pp_newline_and_indent (pp, 3);
1851 pp_cxx_statement (pp, FOR_BODY (t));
1852 pp_indentation (pp) -= 3;
1853 pp_needs_newline (pp) = true;
1854 break;
1856 /* jump-statement:
1857 goto identifier;
1858 continue ;
1859 return expression(opt) ; */
1860 case BREAK_STMT:
1861 case CONTINUE_STMT:
1862 pp_identifier (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1863 pp_cxx_semicolon (pp);
1864 pp_needs_newline (pp) = true;
1865 break;
1867 /* expression-statement:
1868 expression(opt) ; */
1869 case EXPR_STMT:
1870 pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
1871 pp_cxx_semicolon (pp);
1872 pp_needs_newline (pp) = true;
1873 break;
1875 case CLEANUP_STMT:
1876 pp_cxx_identifier (pp, "try");
1877 pp_newline_and_indent (pp, 2);
1878 pp_cxx_statement (pp, CLEANUP_BODY (t));
1879 pp_newline_and_indent (pp, -2);
1880 pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1881 pp_newline_and_indent (pp, 2);
1882 pp_cxx_statement (pp, CLEANUP_EXPR (t));
1883 pp_newline_and_indent (pp, -2);
1884 break;
1886 case STATIC_ASSERT:
1887 pp_cxx_declaration (pp, t);
1888 break;
1890 default:
1891 pp_c_statement (pp_c_base (pp), t);
1892 break;
1896 /* original-namespace-definition:
1897 namespace identifier { namespace-body }
1899 As an edge case, we also handle unnamed namespace definition here. */
1901 static void
1902 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1904 pp_cxx_identifier (pp, "namespace");
1905 if (DECL_CONTEXT (t))
1906 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1907 if (DECL_NAME (t))
1908 pp_cxx_unqualified_id (pp, t);
1909 pp_cxx_whitespace (pp);
1910 pp_cxx_left_brace (pp);
1911 /* We do not print the namespace-body. */
1912 pp_cxx_whitespace (pp);
1913 pp_cxx_right_brace (pp);
1916 /* namespace-alias:
1917 identifier
1919 namespace-alias-definition:
1920 namespace identifier = qualified-namespace-specifier ;
1922 qualified-namespace-specifier:
1923 ::(opt) nested-name-specifier(opt) namespace-name */
1925 static void
1926 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1928 pp_cxx_identifier (pp, "namespace");
1929 if (DECL_CONTEXT (t))
1930 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1931 pp_cxx_unqualified_id (pp, t);
1932 pp_cxx_whitespace (pp);
1933 pp_equal (pp);
1934 pp_cxx_whitespace (pp);
1935 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
1936 pp_cxx_nested_name_specifier (pp,
1937 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
1938 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1939 pp_cxx_semicolon (pp);
1942 /* simple-declaration:
1943 decl-specifier-seq(opt) init-declarator-list(opt) */
1945 static void
1946 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1948 pp_cxx_decl_specifier_seq (pp, t);
1949 pp_cxx_init_declarator (pp, t);
1950 pp_cxx_semicolon (pp);
1951 pp_needs_newline (pp) = true;
1955 template-parameter-list:
1956 template-parameter
1957 template-parameter-list , template-parameter */
1959 static inline void
1960 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1962 const int n = TREE_VEC_LENGTH (t);
1963 int i;
1964 for (i = 0; i < n; ++i)
1966 if (i)
1967 pp_cxx_separate_with (pp, ',');
1968 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1972 /* template-parameter:
1973 type-parameter
1974 parameter-declaration
1976 type-parameter:
1977 class ...(opt) identifier(opt)
1978 class identifier(opt) = type-id
1979 typename identifier(opt)
1980 typename ...(opt) identifier(opt) = type-id
1981 template < template-parameter-list > class ...(opt) identifier(opt)
1982 template < template-parameter-list > class identifier(opt) = template-name */
1984 static void
1985 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
1987 tree parameter = TREE_VALUE (t);
1988 switch (TREE_CODE (parameter))
1990 case TYPE_DECL:
1991 pp_cxx_identifier (pp, "class");
1992 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
1993 pp_cxx_identifier (pp, "...");
1994 if (DECL_NAME (parameter))
1995 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
1996 /* FIXME: Chech if we should print also default argument. */
1997 break;
1999 case PARM_DECL:
2000 pp_cxx_parameter_declaration (pp, parameter);
2001 break;
2003 case TEMPLATE_DECL:
2004 break;
2006 default:
2007 pp_unsupported_tree (pp, t);
2008 break;
2012 /* Pretty-print a template parameter in the canonical form
2013 "template-parameter-<level>-<position in parameter list>". */
2015 void
2016 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2018 const enum tree_code code = TREE_CODE (parm);
2020 /* Brings type template parameters to the canonical forms. */
2021 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2022 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2023 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2025 pp_cxx_begin_template_argument_list (pp);
2026 pp_cxx_identifier (pp, "template-parameter-");
2027 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2028 pp_minus (pp);
2029 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2030 pp_cxx_end_template_argument_list (pp);
2034 template-declaration:
2035 export(opt) template < template-parameter-list > declaration */
2037 static void
2038 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2040 tree tmpl = most_general_template (t);
2041 tree level;
2042 int i = 0;
2044 pp_maybe_newline_and_indent (pp, 0);
2045 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2047 pp_cxx_identifier (pp, "template");
2048 pp_cxx_begin_template_argument_list (pp);
2049 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2050 pp_cxx_end_template_argument_list (pp);
2051 pp_newline_and_indent (pp, 3);
2052 i += 3;
2054 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2055 pp_cxx_function_definition (pp, t);
2056 else
2057 pp_cxx_simple_declaration (pp, t);
2060 static void
2061 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2063 pp_unsupported_tree (pp, t);
2066 static void
2067 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2069 pp_unsupported_tree (pp, t);
2073 declaration:
2074 block-declaration
2075 function-definition
2076 template-declaration
2077 explicit-instantiation
2078 explicit-specialization
2079 linkage-specification
2080 namespace-definition
2082 block-declaration:
2083 simple-declaration
2084 asm-definition
2085 namespace-alias-definition
2086 using-declaration
2087 using-directive
2088 static_assert-declaration */
2089 void
2090 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
2092 if (TREE_CODE (t) == STATIC_ASSERT)
2094 pp_cxx_identifier (pp, "static_assert");
2095 pp_cxx_left_paren (pp);
2096 pp_cxx_expression (pp, STATIC_ASSERT_CONDITION (t));
2097 pp_cxx_separate_with (pp, ',');
2098 pp_cxx_expression (pp, STATIC_ASSERT_MESSAGE (t));
2099 pp_cxx_right_paren (pp);
2101 else if (!DECL_LANG_SPECIFIC (t))
2102 pp_cxx_simple_declaration (pp, t);
2103 else if (DECL_USE_TEMPLATE (t))
2104 switch (DECL_USE_TEMPLATE (t))
2106 case 1:
2107 pp_cxx_template_declaration (pp, t);
2108 break;
2110 case 2:
2111 pp_cxx_explicit_specialization (pp, t);
2112 break;
2114 case 3:
2115 pp_cxx_explicit_instantiation (pp, t);
2116 break;
2118 default:
2119 break;
2121 else switch (TREE_CODE (t))
2123 case VAR_DECL:
2124 case TYPE_DECL:
2125 pp_cxx_simple_declaration (pp, t);
2126 break;
2128 case FUNCTION_DECL:
2129 if (DECL_SAVED_TREE (t))
2130 pp_cxx_function_definition (pp, t);
2131 else
2132 pp_cxx_simple_declaration (pp, t);
2133 break;
2135 case NAMESPACE_DECL:
2136 if (DECL_NAMESPACE_ALIAS (t))
2137 pp_cxx_namespace_alias_definition (pp, t);
2138 else
2139 pp_cxx_original_namespace_definition (pp, t);
2140 break;
2142 default:
2143 pp_unsupported_tree (pp, t);
2144 break;
2148 void
2149 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2151 t = TREE_OPERAND (t, 0);
2152 pp_cxx_identifier (pp, "typeid");
2153 pp_cxx_left_paren (pp);
2154 if (TYPE_P (t))
2155 pp_cxx_type_id (pp, t);
2156 else
2157 pp_cxx_expression (pp, t);
2158 pp_cxx_right_paren (pp);
2161 void
2162 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2164 pp_cxx_identifier (pp, "va_arg");
2165 pp_cxx_left_paren (pp);
2166 pp_cxx_assignment_expression (pp, TREE_OPERAND (t, 0));
2167 pp_cxx_separate_with (pp, ',');
2168 pp_cxx_type_id (pp, TREE_TYPE (t));
2169 pp_cxx_right_paren (pp);
2172 void
2173 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2175 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2177 switch (kind)
2179 case CPTK_HAS_NOTHROW_ASSIGN:
2180 pp_cxx_identifier (pp, "__has_nothrow_assign");
2181 break;
2182 case CPTK_HAS_TRIVIAL_ASSIGN:
2183 pp_cxx_identifier (pp, "__has_trivial_assign");
2184 break;
2185 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2186 pp_cxx_identifier (pp, "__has_nothrow_constructor");
2187 break;
2188 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2189 pp_cxx_identifier (pp, "__has_trivial_constructor");
2190 break;
2191 case CPTK_HAS_NOTHROW_COPY:
2192 pp_cxx_identifier (pp, "__has_nothrow_copy");
2193 break;
2194 case CPTK_HAS_TRIVIAL_COPY:
2195 pp_cxx_identifier (pp, "__has_trivial_copy");
2196 break;
2197 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2198 pp_cxx_identifier (pp, "__has_trivial_destructor");
2199 break;
2200 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2201 pp_cxx_identifier (pp, "__has_virtual_destructor");
2202 break;
2203 case CPTK_IS_ABSTRACT:
2204 pp_cxx_identifier (pp, "__is_abstract");
2205 break;
2206 case CPTK_IS_BASE_OF:
2207 pp_cxx_identifier (pp, "__is_base_of");
2208 break;
2209 case CPTK_IS_CLASS:
2210 pp_cxx_identifier (pp, "__is_class");
2211 break;
2212 case CPTK_IS_CONVERTIBLE_TO:
2213 pp_cxx_identifier (pp, "__is_convertible_to");
2214 break;
2215 case CPTK_IS_EMPTY:
2216 pp_cxx_identifier (pp, "__is_empty");
2217 break;
2218 case CPTK_IS_ENUM:
2219 pp_cxx_identifier (pp, "__is_enum");
2220 break;
2221 case CPTK_IS_POD:
2222 pp_cxx_identifier (pp, "__is_pod");
2223 break;
2224 case CPTK_IS_POLYMORPHIC:
2225 pp_cxx_identifier (pp, "__is_polymorphic");
2226 break;
2227 case CPTK_IS_UNION:
2228 pp_cxx_identifier (pp, "__is_union");
2229 break;
2231 default:
2232 gcc_unreachable ();
2235 pp_cxx_left_paren (pp);
2236 pp_cxx_type_id (pp, TRAIT_EXPR_TYPE1 (t));
2238 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2240 pp_cxx_separate_with (pp, ',');
2241 pp_cxx_type_id (pp, TRAIT_EXPR_TYPE2 (t));
2244 pp_cxx_right_paren (pp);
2247 typedef c_pretty_print_fn pp_fun;
2249 /* Initialization of a C++ pretty-printer object. */
2251 void
2252 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
2254 pp_c_pretty_printer_init (pp_c_base (pp));
2255 pp_set_line_maximum_length (pp, 0);
2257 pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
2258 pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
2259 pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
2260 pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2261 pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
2262 pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
2263 pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2264 pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
2265 pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
2266 pp->c_base.direct_abstract_declarator =
2267 (pp_fun) pp_cxx_direct_abstract_declarator;
2268 pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
2270 /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
2272 pp->c_base.constant = (pp_fun) pp_cxx_constant;
2273 pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
2274 pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
2275 pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
2276 pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
2277 pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
2278 pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
2279 pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
2280 pp->c_base.expression = (pp_fun) pp_cxx_expression;
2281 pp->enclosing_scope = global_namespace;