PR c++/27177
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob9c5a85ff0b4f60f7196eb764f54c4736b2533025
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);
46 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
49 static inline void
50 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
52 const char *p = pp_last_position_in_text (pp);
54 if (p != NULL && *p == c)
55 pp_cxx_whitespace (pp);
56 pp_character (pp, c);
57 pp_base (pp)->padding = pp_none;
60 #define pp_cxx_storage_class_specifier(PP, T) \
61 pp_c_storage_class_specifier (pp_c_base (PP), T)
62 #define pp_cxx_expression_list(PP, T) \
63 pp_c_expression_list (pp_c_base (PP), T)
64 #define pp_cxx_space_for_pointer_operator(PP, T) \
65 pp_c_space_for_pointer_operator (pp_c_base (PP), T)
66 #define pp_cxx_init_declarator(PP, T) \
67 pp_c_init_declarator (pp_c_base (PP), T)
68 #define pp_cxx_call_argument_list(PP, T) \
69 pp_c_call_argument_list (pp_c_base (PP), T)
71 void
72 pp_cxx_colon_colon (cxx_pretty_printer *pp)
74 pp_colon_colon (pp);
75 pp_base (pp)->padding = pp_none;
78 void
79 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
81 pp_cxx_nonconsecutive_character (pp, '<');
84 void
85 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
87 pp_cxx_nonconsecutive_character (pp, '>');
90 void
91 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
93 pp_separate_with (pp, c);
94 pp_base (pp)->padding = pp_none;
97 /* Expressions. */
99 static inline bool
100 is_destructor_name (tree name)
102 return name == complete_dtor_identifier
103 || name == base_dtor_identifier
104 || name == deleting_dtor_identifier;
107 /* conversion-function-id:
108 operator conversion-type-id
110 conversion-type-id:
111 type-specifier-seq conversion-declarator(opt)
113 conversion-declarator:
114 ptr-operator conversion-declarator(opt) */
116 static inline void
117 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
119 pp_cxx_identifier (pp, "operator");
120 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
123 static inline void
124 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
126 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
127 pp_cxx_begin_template_argument_list (pp);
128 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
129 pp_cxx_end_template_argument_list (pp);
132 /* Prints the unqualified part of the id-expression T.
134 unqualified-id:
135 identifier
136 operator-function-id
137 conversion-function-id
138 ~ class-name
139 template-id */
141 static void
142 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
144 enum tree_code code = TREE_CODE (t);
145 switch (code)
147 case RESULT_DECL:
148 pp_cxx_identifier (pp, "<return-value>");
149 break;
151 case OVERLOAD:
152 t = OVL_CURRENT (t);
153 case VAR_DECL:
154 case PARM_DECL:
155 case CONST_DECL:
156 case TYPE_DECL:
157 case FUNCTION_DECL:
158 case NAMESPACE_DECL:
159 case FIELD_DECL:
160 case LABEL_DECL:
161 case USING_DECL:
162 case TEMPLATE_DECL:
163 t = DECL_NAME (t);
165 case IDENTIFIER_NODE:
166 if (t == NULL)
167 pp_cxx_identifier (pp, "<unnamed>");
168 else if (IDENTIFIER_TYPENAME_P (t))
169 pp_cxx_conversion_function_id (pp, t);
170 else
172 if (is_destructor_name (t))
174 pp_complement (pp);
175 /* FIXME: Why is this necessary? */
176 if (TREE_TYPE (t))
177 t = constructor_name (TREE_TYPE (t));
179 pp_cxx_tree_identifier (pp, t);
181 break;
183 case TEMPLATE_ID_EXPR:
184 pp_cxx_template_id (pp, t);
185 break;
187 case BASELINK:
188 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
189 break;
191 case RECORD_TYPE:
192 case UNION_TYPE:
193 case ENUMERAL_TYPE:
194 case TYPENAME_TYPE:
195 case UNBOUND_CLASS_TEMPLATE:
196 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
197 break;
199 case BIT_NOT_EXPR:
200 pp_cxx_complement (pp);
201 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
202 break;
204 case TEMPLATE_TYPE_PARM:
205 case TEMPLATE_TEMPLATE_PARM:
206 if (TYPE_IDENTIFIER (t))
207 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
208 else
209 pp_cxx_canonical_template_parameter (pp, t);
210 break;
212 case TEMPLATE_PARM_INDEX:
213 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
214 break;
216 case BOUND_TEMPLATE_TEMPLATE_PARM:
217 pp_cxx_cv_qualifier_seq (pp, t);
218 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
219 pp_cxx_begin_template_argument_list (pp);
220 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
221 pp_cxx_end_template_argument_list (pp);
222 break;
224 default:
225 pp_unsupported_tree (pp, t);
226 break;
230 /* Pretty-print out the token sequence ":: template" in template codes
231 where it is needed to "inline declare" the (following) member as
232 a template. This situation arises when SCOPE of T is dependent
233 on template parameters. */
235 static inline void
236 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
238 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
239 && TYPE_P (scope) && dependent_type_p (scope))
240 pp_cxx_identifier (pp, "template");
243 /* nested-name-specifier:
244 class-or-namespace-name :: nested-name-specifier(opt)
245 class-or-namespace-name :: template nested-name-specifier */
247 static void
248 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
250 if (t != NULL && t != pp->enclosing_scope)
252 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
253 pp_cxx_nested_name_specifier (pp, scope);
254 pp_cxx_template_keyword_if_needed (pp, scope, t);
255 pp_cxx_unqualified_id (pp, t);
256 pp_cxx_colon_colon (pp);
260 /* qualified-id:
261 nested-name-specifier template(opt) unqualified-id */
263 static void
264 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
266 switch (TREE_CODE (t))
268 /* A pointer-to-member is always qualified. */
269 case PTRMEM_CST:
270 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
271 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
272 break;
274 /* In Standard C++, functions cannot possibly be used as
275 nested-name-specifiers. However, there are situations where
276 is "makes sense" to output the surrounding function name for the
277 purpose of emphasizing on the scope kind. Just printing the
278 function name might not be sufficient as it may be overloaded; so,
279 we decorate the function with its signature too.
280 FIXME: This is probably the wrong pretty-printing for conversion
281 functions and some function templates. */
282 case OVERLOAD:
283 t = OVL_CURRENT (t);
284 case FUNCTION_DECL:
285 if (DECL_FUNCTION_MEMBER_P (t))
286 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
287 pp_cxx_unqualified_id
288 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
289 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
290 break;
292 case OFFSET_REF:
293 case SCOPE_REF:
294 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
295 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
296 break;
298 default:
300 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
301 if (scope != pp->enclosing_scope)
303 pp_cxx_nested_name_specifier (pp, scope);
304 pp_cxx_template_keyword_if_needed (pp, scope, t);
306 pp_cxx_unqualified_id (pp, t);
308 break;
313 static void
314 pp_cxx_constant (cxx_pretty_printer *pp, tree t)
316 switch (TREE_CODE (t))
318 case STRING_CST:
320 const bool in_parens = PAREN_STRING_LITERAL_P (t);
321 if (in_parens)
322 pp_cxx_left_paren (pp);
323 pp_c_constant (pp_c_base (pp), t);
324 if (in_parens)
325 pp_cxx_right_paren (pp);
327 break;
329 default:
330 pp_c_constant (pp_c_base (pp), t);
331 break;
335 /* id-expression:
336 unqualified-id
337 qualified-id */
339 static inline void
340 pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
342 if (TREE_CODE (t) == OVERLOAD)
343 t = OVL_CURRENT (t);
344 if (DECL_P (t) && DECL_CONTEXT (t))
345 pp_cxx_qualified_id (pp, t);
346 else
347 pp_cxx_unqualified_id (pp, t);
350 /* primary-expression:
351 literal
352 this
353 :: identifier
354 :: operator-function-id
355 :: qualifier-id
356 ( expression )
357 id-expression
359 GNU Extensions:
360 __builtin_va_arg ( assignment-expression , type-id )
361 __builtin_offsetof ( type-id, offsetof-expression )
363 __has_nothrow_assign ( type-id )
364 __has_nothrow_constructor ( type-id )
365 __has_nothrow_copy ( type-id )
366 __has_trivial_assign ( type-id )
367 __has_trivial_constructor ( type-id )
368 __has_trivial_copy ( type-id )
369 __has_trivial_destructor ( type-id )
370 __has_virtual_destructor ( type-id )
371 __is_abstract ( type-id )
372 __is_base_of ( type-id , type-id )
373 __is_class ( type-id )
374 __is_convertible_to ( type-id , type-id )
375 __is_empty ( type-id )
376 __is_enum ( type-id )
377 __is_pod ( type-id )
378 __is_polymorphic ( type-id )
379 __is_union ( type-id ) */
381 static void
382 pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
384 switch (TREE_CODE (t))
386 case INTEGER_CST:
387 case REAL_CST:
388 case COMPLEX_CST:
389 case STRING_CST:
390 pp_cxx_constant (pp, t);
391 break;
393 case BASELINK:
394 t = BASELINK_FUNCTIONS (t);
395 case VAR_DECL:
396 case PARM_DECL:
397 case FIELD_DECL:
398 case FUNCTION_DECL:
399 case OVERLOAD:
400 case CONST_DECL:
401 case TEMPLATE_DECL:
402 pp_cxx_id_expression (pp, t);
403 break;
405 case RESULT_DECL:
406 case TEMPLATE_TYPE_PARM:
407 case TEMPLATE_TEMPLATE_PARM:
408 case TEMPLATE_PARM_INDEX:
409 pp_cxx_unqualified_id (pp, t);
410 break;
412 case STMT_EXPR:
413 pp_cxx_left_paren (pp);
414 pp_cxx_statement (pp, STMT_EXPR_STMT (t));
415 pp_cxx_right_paren (pp);
416 break;
418 case TRAIT_EXPR:
419 pp_cxx_trait_expression (pp, t);
420 break;
422 case VA_ARG_EXPR:
423 pp_cxx_va_arg_expression (pp, t);
424 break;
426 case OFFSETOF_EXPR:
427 pp_cxx_offsetof_expression (pp, t);
428 break;
430 default:
431 pp_c_primary_expression (pp_c_base (pp), t);
432 break;
436 /* postfix-expression:
437 primary-expression
438 postfix-expression [ expression ]
439 postfix-expression ( expression-list(opt) )
440 simple-type-specifier ( expression-list(opt) )
441 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
442 typename ::(opt) nested-name-specifier template(opt)
443 template-id ( expression-list(opt) )
444 postfix-expression . template(opt) ::(opt) id-expression
445 postfix-expression -> template(opt) ::(opt) id-expression
446 postfix-expression . pseudo-destructor-name
447 postfix-expression -> pseudo-destructor-name
448 postfix-expression ++
449 postfix-expression --
450 dynamic_cast < type-id > ( expression )
451 static_cast < type-id > ( expression )
452 reinterpret_cast < type-id > ( expression )
453 const_cast < type-id > ( expression )
454 typeid ( expression )
455 typeif ( type-id ) */
457 static void
458 pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
460 enum tree_code code = TREE_CODE (t);
462 switch (code)
464 case AGGR_INIT_EXPR:
465 case CALL_EXPR:
467 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
468 : CALL_EXPR_FN (t));
469 tree saved_scope = pp->enclosing_scope;
470 bool skipfirst = false;
471 tree arg;
473 if (TREE_CODE (fun) == ADDR_EXPR)
474 fun = TREE_OPERAND (fun, 0);
476 /* In templates, where there is no way to tell whether a given
477 call uses an actual member function. So the parser builds
478 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
479 instantiation time. */
480 if (TREE_CODE (fun) != FUNCTION_DECL)
482 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
484 tree object = (code == AGGR_INIT_EXPR
485 ? (AGGR_INIT_VIA_CTOR_P (t)
486 ? AGGR_INIT_EXPR_SLOT (t)
487 : AGGR_INIT_EXPR_ARG (t, 0))
488 : CALL_EXPR_ARG (t, 0));
490 while (TREE_CODE (object) == NOP_EXPR)
491 object = TREE_OPERAND (object, 0);
493 if (TREE_CODE (object) == ADDR_EXPR)
494 object = TREE_OPERAND (object, 0);
496 if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
498 pp_cxx_postfix_expression (pp, object);
499 pp_cxx_dot (pp);
501 else
503 pp_cxx_postfix_expression (pp, object);
504 pp_cxx_arrow (pp);
506 skipfirst = true;
507 pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
510 pp_cxx_postfix_expression (pp, fun);
511 pp->enclosing_scope = saved_scope;
512 pp_cxx_left_paren (pp);
513 if (code == AGGR_INIT_EXPR)
515 aggr_init_expr_arg_iterator iter;
516 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
518 if (skipfirst)
519 skipfirst = false;
520 else
522 pp_cxx_expression (pp, arg);
523 if (more_aggr_init_expr_args_p (&iter))
524 pp_cxx_separate_with (pp, ',');
528 else
530 call_expr_arg_iterator iter;
531 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
533 if (skipfirst)
534 skipfirst = false;
535 else
537 pp_cxx_expression (pp, arg);
538 if (more_call_expr_args_p (&iter))
539 pp_cxx_separate_with (pp, ',');
543 pp_cxx_right_paren (pp);
545 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
547 pp_cxx_separate_with (pp, ',');
548 pp_cxx_postfix_expression (pp, AGGR_INIT_EXPR_SLOT (t));
550 break;
552 case BASELINK:
553 case VAR_DECL:
554 case PARM_DECL:
555 case FIELD_DECL:
556 case FUNCTION_DECL:
557 case OVERLOAD:
558 case CONST_DECL:
559 case TEMPLATE_DECL:
560 case RESULT_DECL:
561 pp_cxx_primary_expression (pp, t);
562 break;
564 case DYNAMIC_CAST_EXPR:
565 case STATIC_CAST_EXPR:
566 case REINTERPRET_CAST_EXPR:
567 case CONST_CAST_EXPR:
568 if (code == DYNAMIC_CAST_EXPR)
569 pp_cxx_identifier (pp, "dynamic_cast");
570 else if (code == STATIC_CAST_EXPR)
571 pp_cxx_identifier (pp, "static_cast");
572 else if (code == REINTERPRET_CAST_EXPR)
573 pp_cxx_identifier (pp, "reinterpret_cast");
574 else
575 pp_cxx_identifier (pp, "const_cast");
576 pp_cxx_begin_template_argument_list (pp);
577 pp_cxx_type_id (pp, TREE_TYPE (t));
578 pp_cxx_end_template_argument_list (pp);
579 pp_left_paren (pp);
580 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
581 pp_right_paren (pp);
582 break;
584 case EMPTY_CLASS_EXPR:
585 pp_cxx_type_id (pp, TREE_TYPE (t));
586 pp_left_paren (pp);
587 pp_right_paren (pp);
588 break;
590 case TYPEID_EXPR:
591 pp_cxx_typeid_expression (pp, t);
592 break;
594 case PSEUDO_DTOR_EXPR:
595 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
596 pp_cxx_dot (pp);
597 pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
598 pp_cxx_colon_colon (pp);
599 pp_complement (pp);
600 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
601 break;
603 case ARROW_EXPR:
604 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
605 pp_cxx_arrow (pp);
606 break;
608 default:
609 pp_c_postfix_expression (pp_c_base (pp), t);
610 break;
614 /* new-expression:
615 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
616 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
618 new-placement:
619 ( expression-list )
621 new-type-id:
622 type-specifier-seq new-declarator(opt)
624 new-declarator:
625 ptr-operator new-declarator(opt)
626 direct-new-declarator
628 direct-new-declarator
629 [ expression ]
630 direct-new-declarator [ constant-expression ]
632 new-initializer:
633 ( expression-list(opt) ) */
635 static void
636 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
638 enum tree_code code = TREE_CODE (t);
639 switch (code)
641 case NEW_EXPR:
642 case VEC_NEW_EXPR:
643 if (NEW_EXPR_USE_GLOBAL (t))
644 pp_cxx_colon_colon (pp);
645 pp_cxx_identifier (pp, "new");
646 if (TREE_OPERAND (t, 0))
648 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
649 pp_space (pp);
651 /* FIXME: array-types are built with one more element. */
652 pp_cxx_type_id (pp, TREE_OPERAND (t, 1));
653 if (TREE_OPERAND (t, 2))
655 pp_left_paren (pp);
656 t = TREE_OPERAND (t, 2);
657 if (TREE_CODE (t) == TREE_LIST)
658 pp_c_expression_list (pp_c_base (pp), t);
659 else if (t == void_zero_node)
660 ; /* OK, empty initializer list. */
661 else
662 pp_cxx_expression (pp, t);
663 pp_right_paren (pp);
665 break;
667 default:
668 pp_unsupported_tree (pp, t);
672 /* delete-expression:
673 ::(opt) delete cast-expression
674 ::(opt) delete [ ] cast-expression */
676 static void
677 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
679 enum tree_code code = TREE_CODE (t);
680 switch (code)
682 case DELETE_EXPR:
683 case VEC_DELETE_EXPR:
684 if (DELETE_EXPR_USE_GLOBAL (t))
685 pp_cxx_colon_colon (pp);
686 pp_cxx_identifier (pp, "delete");
687 pp_space (pp);
688 if (code == VEC_DELETE_EXPR
689 || DELETE_EXPR_USE_VEC (t))
691 pp_left_bracket (pp);
692 pp_right_bracket (pp);
693 pp_space (pp);
695 pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
696 break;
698 default:
699 pp_unsupported_tree (pp, t);
703 /* unary-expression:
704 postfix-expression
705 ++ cast-expression
706 -- cast-expression
707 unary-operator cast-expression
708 sizeof unary-expression
709 sizeof ( type-id )
710 sizeof ... ( identifier )
711 new-expression
712 delete-expression
714 unary-operator: one of
715 * & + - !
717 GNU extensions:
718 __alignof__ unary-expression
719 __alignof__ ( type-id ) */
721 static void
722 pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
724 enum tree_code code = TREE_CODE (t);
725 switch (code)
727 case NEW_EXPR:
728 case VEC_NEW_EXPR:
729 pp_cxx_new_expression (pp, t);
730 break;
732 case DELETE_EXPR:
733 case VEC_DELETE_EXPR:
734 pp_cxx_delete_expression (pp, t);
735 break;
737 case SIZEOF_EXPR:
738 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
740 pp_cxx_identifier (pp, "sizeof");
741 pp_cxx_identifier (pp, "...");
742 pp_cxx_whitespace (pp);
743 pp_cxx_left_paren (pp);
744 if (TYPE_P (TREE_OPERAND (t, 0)))
745 pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
746 else
747 pp_unary_expression (pp, TREE_OPERAND (t, 0));
748 pp_cxx_right_paren (pp);
749 break;
751 /* Fall through */
753 case ALIGNOF_EXPR:
754 pp_cxx_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
755 pp_cxx_whitespace (pp);
756 if (TYPE_P (TREE_OPERAND (t, 0)))
758 pp_cxx_left_paren (pp);
759 pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
760 pp_cxx_right_paren (pp);
762 else
763 pp_unary_expression (pp, TREE_OPERAND (t, 0));
764 break;
766 case UNARY_PLUS_EXPR:
767 pp_plus (pp);
768 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
769 break;
771 default:
772 pp_c_unary_expression (pp_c_base (pp), t);
773 break;
777 /* cast-expression:
778 unary-expression
779 ( type-id ) cast-expression */
781 static void
782 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
784 switch (TREE_CODE (t))
786 case CAST_EXPR:
787 pp_cxx_type_id (pp, TREE_TYPE (t));
788 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
789 break;
791 default:
792 pp_c_cast_expression (pp_c_base (pp), t);
793 break;
797 /* pm-expression:
798 cast-expression
799 pm-expression .* cast-expression
800 pm-expression ->* cast-expression */
802 static void
803 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
805 switch (TREE_CODE (t))
807 /* Handle unfortunate OFFESET_REF overloading here. */
808 case OFFSET_REF:
809 if (TYPE_P (TREE_OPERAND (t, 0)))
811 pp_cxx_qualified_id (pp, t);
812 break;
814 /* Else fall through. */
815 case MEMBER_REF:
816 case DOTSTAR_EXPR:
817 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
818 if (TREE_CODE (t) == MEMBER_REF)
819 pp_cxx_arrow (pp);
820 else
821 pp_cxx_dot (pp);
822 pp_star(pp);
823 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
824 break;
827 default:
828 pp_cxx_cast_expression (pp, t);
829 break;
833 /* multiplicative-expression:
834 pm-expression
835 multiplicative-expression * pm-expression
836 multiplicative-expression / pm-expression
837 multiplicative-expression % pm-expression */
839 static void
840 pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
842 enum tree_code code = TREE_CODE (e);
843 switch (code)
845 case MULT_EXPR:
846 case TRUNC_DIV_EXPR:
847 case TRUNC_MOD_EXPR:
848 pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
849 pp_space (pp);
850 if (code == MULT_EXPR)
851 pp_star (pp);
852 else if (code == TRUNC_DIV_EXPR)
853 pp_slash (pp);
854 else
855 pp_modulo (pp);
856 pp_space (pp);
857 pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
858 break;
860 default:
861 pp_cxx_pm_expression (pp, e);
862 break;
866 /* conditional-expression:
867 logical-or-expression
868 logical-or-expression ? expression : assignment-expression */
870 static void
871 pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
873 if (TREE_CODE (e) == COND_EXPR)
875 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
876 pp_space (pp);
877 pp_question (pp);
878 pp_space (pp);
879 pp_cxx_expression (pp, TREE_OPERAND (e, 1));
880 pp_space (pp);
881 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
883 else
884 pp_c_logical_or_expression (pp_c_base (pp), e);
887 /* Pretty-print a compound assignment operator token as indicated by T. */
889 static void
890 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
892 const char *op;
894 switch (TREE_CODE (t))
896 case NOP_EXPR:
897 op = "=";
898 break;
900 case PLUS_EXPR:
901 op = "+=";
902 break;
904 case MINUS_EXPR:
905 op = "-=";
906 break;
908 case TRUNC_DIV_EXPR:
909 op = "/=";
910 break;
912 case TRUNC_MOD_EXPR:
913 op = "%=";
914 break;
916 default:
917 op = tree_code_name[TREE_CODE (t)];
918 break;
921 pp_cxx_identifier (pp, op);
925 /* assignment-expression:
926 conditional-expression
927 logical-or-expression assignment-operator assignment-expression
928 throw-expression
930 throw-expression:
931 throw assignment-expression(opt)
933 assignment-operator: one of
934 = *= /= %= += -= >>= <<= &= ^= |= */
936 static void
937 pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
939 switch (TREE_CODE (e))
941 case MODIFY_EXPR:
942 case INIT_EXPR:
943 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
944 pp_space (pp);
945 pp_equal (pp);
946 pp_space (pp);
947 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
948 break;
950 case THROW_EXPR:
951 pp_cxx_identifier (pp, "throw");
952 if (TREE_OPERAND (e, 0))
953 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
954 break;
956 case MODOP_EXPR:
957 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
958 pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
959 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
960 break;
962 default:
963 pp_cxx_conditional_expression (pp, e);
964 break;
968 static void
969 pp_cxx_expression (cxx_pretty_printer *pp, tree t)
971 switch (TREE_CODE (t))
973 case STRING_CST:
974 case INTEGER_CST:
975 case REAL_CST:
976 case COMPLEX_CST:
977 pp_cxx_constant (pp, t);
978 break;
980 case RESULT_DECL:
981 pp_cxx_unqualified_id (pp, t);
982 break;
984 #if 0
985 case OFFSET_REF:
986 #endif
987 case SCOPE_REF:
988 case PTRMEM_CST:
989 pp_cxx_qualified_id (pp, t);
990 break;
992 case OVERLOAD:
993 t = OVL_CURRENT (t);
994 case VAR_DECL:
995 case PARM_DECL:
996 case FIELD_DECL:
997 case CONST_DECL:
998 case FUNCTION_DECL:
999 case BASELINK:
1000 case TEMPLATE_DECL:
1001 case TEMPLATE_TYPE_PARM:
1002 case TEMPLATE_PARM_INDEX:
1003 case TEMPLATE_TEMPLATE_PARM:
1004 case STMT_EXPR:
1005 pp_cxx_primary_expression (pp, t);
1006 break;
1008 case CALL_EXPR:
1009 case DYNAMIC_CAST_EXPR:
1010 case STATIC_CAST_EXPR:
1011 case REINTERPRET_CAST_EXPR:
1012 case CONST_CAST_EXPR:
1013 #if 0
1014 case MEMBER_REF:
1015 #endif
1016 case EMPTY_CLASS_EXPR:
1017 case TYPEID_EXPR:
1018 case PSEUDO_DTOR_EXPR:
1019 case AGGR_INIT_EXPR:
1020 case ARROW_EXPR:
1021 pp_cxx_postfix_expression (pp, t);
1022 break;
1024 case NEW_EXPR:
1025 case VEC_NEW_EXPR:
1026 pp_cxx_new_expression (pp, t);
1027 break;
1029 case DELETE_EXPR:
1030 case VEC_DELETE_EXPR:
1031 pp_cxx_delete_expression (pp, t);
1032 break;
1034 case SIZEOF_EXPR:
1035 case ALIGNOF_EXPR:
1036 pp_cxx_unary_expression (pp, t);
1037 break;
1039 case CAST_EXPR:
1040 pp_cxx_cast_expression (pp, t);
1041 break;
1043 case OFFSET_REF:
1044 case MEMBER_REF:
1045 case DOTSTAR_EXPR:
1046 pp_cxx_pm_expression (pp, t);
1047 break;
1049 case MULT_EXPR:
1050 case TRUNC_DIV_EXPR:
1051 case TRUNC_MOD_EXPR:
1052 pp_cxx_multiplicative_expression (pp, t);
1053 break;
1055 case COND_EXPR:
1056 pp_cxx_conditional_expression (pp, t);
1057 break;
1059 case MODIFY_EXPR:
1060 case INIT_EXPR:
1061 case THROW_EXPR:
1062 case MODOP_EXPR:
1063 pp_cxx_assignment_expression (pp, t);
1064 break;
1066 case NON_DEPENDENT_EXPR:
1067 case MUST_NOT_THROW_EXPR:
1068 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
1069 break;
1071 case EXPR_PACK_EXPANSION:
1072 pp_cxx_expression (pp, PACK_EXPANSION_PATTERN (t));
1073 pp_cxx_identifier (pp, "...");
1074 break;
1076 case NONTYPE_ARGUMENT_PACK:
1078 tree args = ARGUMENT_PACK_ARGS (t);
1079 int i, len = TREE_VEC_LENGTH (args);
1080 for (i = 0; i < len; ++i)
1082 if (i > 0)
1083 pp_cxx_separate_with (pp, ',');
1084 pp_cxx_expression (pp, TREE_VEC_ELT (args, i));
1087 break;
1089 default:
1090 pp_c_expression (pp_c_base (pp), t);
1091 break;
1096 /* Declarations. */
1098 /* function-specifier:
1099 inline
1100 virtual
1101 explicit */
1103 static void
1104 pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
1106 switch (TREE_CODE (t))
1108 case FUNCTION_DECL:
1109 if (DECL_VIRTUAL_P (t))
1110 pp_cxx_identifier (pp, "virtual");
1111 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1112 pp_cxx_identifier (pp, "explicit");
1113 else
1114 pp_c_function_specifier (pp_c_base (pp), t);
1116 default:
1117 break;
1121 /* decl-specifier-seq:
1122 decl-specifier-seq(opt) decl-specifier
1124 decl-specifier:
1125 storage-class-specifier
1126 type-specifier
1127 function-specifier
1128 friend
1129 typedef */
1131 static void
1132 pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
1134 switch (TREE_CODE (t))
1136 case VAR_DECL:
1137 case PARM_DECL:
1138 case CONST_DECL:
1139 case FIELD_DECL:
1140 pp_cxx_storage_class_specifier (pp, t);
1141 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1142 break;
1144 case TYPE_DECL:
1145 pp_cxx_identifier (pp, "typedef");
1146 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1147 break;
1149 case RECORD_TYPE:
1150 if (TYPE_PTRMEMFUNC_P (t))
1152 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1153 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
1154 pp_cxx_whitespace (pp);
1155 pp_cxx_ptr_operator (pp, t);
1157 break;
1159 case FUNCTION_DECL:
1160 /* Constructors don't have return types. And conversion functions
1161 do not have a type-specifier in their return types. */
1162 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1163 pp_cxx_function_specifier (pp, t);
1164 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1165 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
1166 else
1167 default:
1168 pp_c_declaration_specifiers (pp_c_base (pp), t);
1169 break;
1173 /* simple-type-specifier:
1174 ::(opt) nested-name-specifier(opt) type-name
1175 ::(opt) nested-name-specifier(opt) template(opt) template-id
1176 char
1177 wchar_t
1178 bool
1179 short
1181 long
1182 signed
1183 unsigned
1184 float
1185 double
1186 void */
1188 static void
1189 pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
1191 switch (TREE_CODE (t))
1193 case RECORD_TYPE:
1194 case UNION_TYPE:
1195 case ENUMERAL_TYPE:
1196 pp_cxx_qualified_id (pp, t);
1197 break;
1199 case TEMPLATE_TYPE_PARM:
1200 case TEMPLATE_TEMPLATE_PARM:
1201 case TEMPLATE_PARM_INDEX:
1202 pp_cxx_unqualified_id (pp, t);
1203 break;
1205 case TYPENAME_TYPE:
1206 pp_cxx_identifier (pp, "typename");
1207 pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1208 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1209 break;
1211 default:
1212 pp_c_type_specifier (pp_c_base (pp), t);
1213 break;
1217 /* type-specifier-seq:
1218 type-specifier type-specifier-seq(opt)
1220 type-specifier:
1221 simple-type-specifier
1222 class-specifier
1223 enum-specifier
1224 elaborated-type-specifier
1225 cv-qualifier */
1227 static void
1228 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1230 switch (TREE_CODE (t))
1232 case TEMPLATE_DECL:
1233 case TEMPLATE_TYPE_PARM:
1234 case TEMPLATE_TEMPLATE_PARM:
1235 case TYPE_DECL:
1236 case BOUND_TEMPLATE_TEMPLATE_PARM:
1237 pp_cxx_cv_qualifier_seq (pp, t);
1238 pp_cxx_simple_type_specifier (pp, t);
1239 break;
1241 case METHOD_TYPE:
1242 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1243 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1244 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1245 break;
1247 case DECLTYPE_TYPE:
1248 pp_cxx_identifier (pp, "decltype");
1249 pp_cxx_left_paren (pp);
1250 pp_cxx_expression (pp, DECLTYPE_TYPE_EXPR (t));
1251 pp_cxx_right_paren (pp);
1252 break;
1254 default:
1255 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1256 pp_c_specifier_qualifier_list (pp_c_base (pp), t);
1260 /* ptr-operator:
1261 * cv-qualifier-seq(opt)
1263 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1265 static void
1266 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1268 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1269 t = TREE_TYPE (t);
1270 switch (TREE_CODE (t))
1272 case REFERENCE_TYPE:
1273 case POINTER_TYPE:
1274 if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
1275 || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
1276 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1277 if (TREE_CODE (t) == POINTER_TYPE)
1279 pp_star (pp);
1280 pp_cxx_cv_qualifier_seq (pp, t);
1282 else
1283 pp_ampersand (pp);
1284 break;
1286 case RECORD_TYPE:
1287 if (TYPE_PTRMEMFUNC_P (t))
1289 pp_cxx_left_paren (pp);
1290 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1291 pp_star (pp);
1292 break;
1294 case OFFSET_TYPE:
1295 if (TYPE_PTR_TO_MEMBER_P (t))
1297 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1298 pp_cxx_left_paren (pp);
1299 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1300 pp_star (pp);
1301 pp_cxx_cv_qualifier_seq (pp, t);
1302 break;
1304 /* else fall through. */
1306 default:
1307 pp_unsupported_tree (pp, t);
1308 break;
1312 static inline tree
1313 pp_cxx_implicit_parameter_type (tree mf)
1315 return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1319 parameter-declaration:
1320 decl-specifier-seq declarator
1321 decl-specifier-seq declarator = assignment-expression
1322 decl-specifier-seq abstract-declarator(opt)
1323 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1325 static inline void
1326 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1328 pp_cxx_decl_specifier_seq (pp, t);
1329 if (TYPE_P (t))
1330 pp_cxx_abstract_declarator (pp, t);
1331 else
1332 pp_cxx_declarator (pp, t);
1335 /* parameter-declaration-clause:
1336 parameter-declaration-list(opt) ...(opt)
1337 parameter-declaration-list , ...
1339 parameter-declaration-list:
1340 parameter-declaration
1341 parameter-declaration-list , parameter-declaration */
1343 static void
1344 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1346 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1347 tree types =
1348 TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1349 const bool abstract = args == NULL
1350 || pp_c_base (pp)->flags & pp_c_flag_abstract;
1351 bool first = true;
1353 /* Skip artificial parameter for nonstatic member functions. */
1354 if (TREE_CODE (t) == METHOD_TYPE)
1355 types = TREE_CHAIN (types);
1357 pp_cxx_left_paren (pp);
1358 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1360 if (!first)
1361 pp_cxx_separate_with (pp, ',');
1362 first = false;
1363 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1364 if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1366 pp_cxx_whitespace (pp);
1367 pp_equal (pp);
1368 pp_cxx_whitespace (pp);
1369 pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1372 pp_cxx_right_paren (pp);
1375 /* exception-specification:
1376 throw ( type-id-list(opt) )
1378 type-id-list
1379 type-id
1380 type-id-list , type-id */
1382 static void
1383 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1385 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1386 bool need_comma = false;
1388 if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1389 return;
1390 pp_cxx_identifier (pp, "throw");
1391 pp_cxx_left_paren (pp);
1392 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1394 tree type = TREE_VALUE (ex_spec);
1395 tree argpack = NULL_TREE;
1396 int i, len = 1;
1398 if (ARGUMENT_PACK_P (type))
1400 argpack = ARGUMENT_PACK_ARGS (type);
1401 len = TREE_VEC_LENGTH (argpack);
1404 for (i = 0; i < len; ++i)
1406 if (argpack)
1407 type = TREE_VEC_ELT (argpack, i);
1409 if (need_comma)
1410 pp_cxx_separate_with (pp, ',');
1411 else
1412 need_comma = true;
1414 pp_cxx_type_id (pp, type);
1417 pp_cxx_right_paren (pp);
1420 /* direct-declarator:
1421 declarator-id
1422 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1423 exception-specification(opt)
1424 direct-declaration [ constant-expression(opt) ]
1425 ( declarator ) */
1427 static void
1428 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1430 switch (TREE_CODE (t))
1432 case VAR_DECL:
1433 case PARM_DECL:
1434 case CONST_DECL:
1435 case FIELD_DECL:
1436 if (DECL_NAME (t))
1438 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1440 if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
1441 || template_parameter_pack_p (t))
1442 /* A function parameter pack or non-type template
1443 parameter pack. */
1444 pp_cxx_identifier (pp, "...");
1446 pp_cxx_id_expression (pp, DECL_NAME (t));
1448 pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1449 break;
1451 case FUNCTION_DECL:
1452 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1453 pp_cxx_id_expression (pp, t);
1454 pp_cxx_parameter_declaration_clause (pp, t);
1456 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1458 pp_base (pp)->padding = pp_before;
1459 pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1462 pp_cxx_exception_specification (pp, TREE_TYPE (t));
1463 break;
1465 case TYPENAME_TYPE:
1466 case TEMPLATE_DECL:
1467 case TEMPLATE_TYPE_PARM:
1468 case TEMPLATE_PARM_INDEX:
1469 case TEMPLATE_TEMPLATE_PARM:
1470 break;
1472 default:
1473 pp_c_direct_declarator (pp_c_base (pp), t);
1474 break;
1478 /* declarator:
1479 direct-declarator
1480 ptr-operator declarator */
1482 static void
1483 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1485 pp_cxx_direct_declarator (pp, t);
1488 /* ctor-initializer:
1489 : mem-initializer-list
1491 mem-initializer-list:
1492 mem-initializer
1493 mem-initializer , mem-initializer-list
1495 mem-initializer:
1496 mem-initializer-id ( expression-list(opt) )
1498 mem-initializer-id:
1499 ::(opt) nested-name-specifier(opt) class-name
1500 identifier */
1502 static void
1503 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1505 t = TREE_OPERAND (t, 0);
1506 pp_cxx_whitespace (pp);
1507 pp_colon (pp);
1508 pp_cxx_whitespace (pp);
1509 for (; t; t = TREE_CHAIN (t))
1511 tree purpose = TREE_PURPOSE (t);
1512 bool is_pack = PACK_EXPANSION_P (purpose);
1514 if (is_pack)
1515 pp_cxx_primary_expression (pp, PACK_EXPANSION_PATTERN (purpose));
1516 else
1517 pp_cxx_primary_expression (pp, purpose);
1518 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1519 if (is_pack)
1520 pp_cxx_identifier (pp, "...");
1521 if (TREE_CHAIN (t))
1522 pp_cxx_separate_with (pp, ',');
1526 /* function-definition:
1527 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1528 decl-specifier-seq(opt) declarator function-try-block */
1530 static void
1531 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1533 tree saved_scope = pp->enclosing_scope;
1534 pp_cxx_decl_specifier_seq (pp, t);
1535 pp_cxx_declarator (pp, t);
1536 pp_needs_newline (pp) = true;
1537 pp->enclosing_scope = DECL_CONTEXT (t);
1538 if (DECL_SAVED_TREE (t))
1539 pp_cxx_statement (pp, DECL_SAVED_TREE (t));
1540 else
1542 pp_cxx_semicolon (pp);
1543 pp_needs_newline (pp) = true;
1545 pp_flush (pp);
1546 pp->enclosing_scope = saved_scope;
1549 /* abstract-declarator:
1550 ptr-operator abstract-declarator(opt)
1551 direct-abstract-declarator */
1553 static void
1554 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1556 if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1557 pp_cxx_right_paren (pp);
1558 else if (POINTER_TYPE_P (t))
1560 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1561 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1562 pp_cxx_right_paren (pp);
1563 t = TREE_TYPE (t);
1565 pp_cxx_direct_abstract_declarator (pp, t);
1568 /* direct-abstract-declarator:
1569 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1570 cv-qualifier-seq(opt) exception-specification(opt)
1571 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1572 ( abstract-declarator ) */
1574 static void
1575 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1577 switch (TREE_CODE (t))
1579 case REFERENCE_TYPE:
1580 pp_cxx_abstract_declarator (pp, t);
1581 break;
1583 case RECORD_TYPE:
1584 if (TYPE_PTRMEMFUNC_P (t))
1585 pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1586 break;
1588 case METHOD_TYPE:
1589 case FUNCTION_TYPE:
1590 pp_cxx_parameter_declaration_clause (pp, t);
1591 pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1592 if (TREE_CODE (t) == METHOD_TYPE)
1594 pp_base (pp)->padding = pp_before;
1595 pp_cxx_cv_qualifier_seq
1596 (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1598 pp_cxx_exception_specification (pp, t);
1599 break;
1601 case TYPENAME_TYPE:
1602 case TEMPLATE_TYPE_PARM:
1603 case TEMPLATE_TEMPLATE_PARM:
1604 case BOUND_TEMPLATE_TEMPLATE_PARM:
1605 case UNBOUND_CLASS_TEMPLATE:
1606 break;
1608 default:
1609 pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1610 break;
1614 /* type-id:
1615 type-specifier-seq abstract-declarator(opt) */
1617 static void
1618 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1620 pp_flags saved_flags = pp_c_base (pp)->flags;
1621 pp_c_base (pp)->flags |= pp_c_flag_abstract;
1623 switch (TREE_CODE (t))
1625 case TYPE_DECL:
1626 case UNION_TYPE:
1627 case RECORD_TYPE:
1628 case ENUMERAL_TYPE:
1629 case TYPENAME_TYPE:
1630 case BOUND_TEMPLATE_TEMPLATE_PARM:
1631 case UNBOUND_CLASS_TEMPLATE:
1632 case TEMPLATE_TEMPLATE_PARM:
1633 case TEMPLATE_TYPE_PARM:
1634 case TEMPLATE_PARM_INDEX:
1635 case TEMPLATE_DECL:
1636 case TYPEOF_TYPE:
1637 case DECLTYPE_TYPE:
1638 case TEMPLATE_ID_EXPR:
1639 pp_cxx_type_specifier_seq (pp, t);
1640 break;
1642 case TYPE_PACK_EXPANSION:
1643 pp_cxx_type_id (pp, PACK_EXPANSION_PATTERN (t));
1644 pp_cxx_identifier (pp, "...");
1645 break;
1647 default:
1648 pp_c_type_id (pp_c_base (pp), t);
1649 break;
1652 pp_c_base (pp)->flags = saved_flags;
1655 /* template-argument-list:
1656 template-argument ...(opt)
1657 template-argument-list, template-argument ...(opt)
1659 template-argument:
1660 assignment-expression
1661 type-id
1662 template-name */
1664 static void
1665 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1667 int i;
1668 bool need_comma = false;
1670 if (t == NULL)
1671 return;
1672 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1674 tree arg = TREE_VEC_ELT (t, i);
1675 tree argpack = NULL_TREE;
1676 int idx, len = 1;
1678 if (ARGUMENT_PACK_P (arg))
1680 argpack = ARGUMENT_PACK_ARGS (arg);
1681 len = TREE_VEC_LENGTH (argpack);
1684 for (idx = 0; idx < len; idx++)
1686 if (argpack)
1687 arg = TREE_VEC_ELT (argpack, idx);
1689 if (need_comma)
1690 pp_cxx_separate_with (pp, ',');
1691 else
1692 need_comma = true;
1694 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1695 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1696 pp_cxx_type_id (pp, arg);
1697 else
1698 pp_cxx_expression (pp, arg);
1704 static void
1705 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1707 t = DECL_EXPR_DECL (t);
1708 pp_cxx_type_specifier_seq (pp, t);
1709 if (TYPE_P (t))
1710 pp_cxx_abstract_declarator (pp, t);
1711 else
1712 pp_cxx_declarator (pp, t);
1715 /* Statements. */
1717 static void
1718 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1720 switch (TREE_CODE (t))
1722 case CTOR_INITIALIZER:
1723 pp_cxx_ctor_initializer (pp, t);
1724 break;
1726 case USING_STMT:
1727 pp_cxx_identifier (pp, "using");
1728 pp_cxx_identifier (pp, "namespace");
1729 if (DECL_CONTEXT (t))
1730 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1731 pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1732 break;
1734 case USING_DECL:
1735 pp_cxx_identifier (pp, "using");
1736 pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
1737 pp_cxx_unqualified_id (pp, DECL_NAME (t));
1738 break;
1740 case EH_SPEC_BLOCK:
1741 break;
1743 /* try-block:
1744 try compound-statement handler-seq */
1745 case TRY_BLOCK:
1746 pp_maybe_newline_and_indent (pp, 0);
1747 pp_cxx_identifier (pp, "try");
1748 pp_newline_and_indent (pp, 3);
1749 pp_cxx_statement (pp, TRY_STMTS (t));
1750 pp_newline_and_indent (pp, -3);
1751 if (CLEANUP_P (t))
1753 else
1754 pp_cxx_statement (pp, TRY_HANDLERS (t));
1755 break;
1758 handler-seq:
1759 handler handler-seq(opt)
1761 handler:
1762 catch ( exception-declaration ) compound-statement
1764 exception-declaration:
1765 type-specifier-seq declarator
1766 type-specifier-seq abstract-declarator
1767 ... */
1768 case HANDLER:
1769 pp_cxx_identifier (pp, "catch");
1770 pp_cxx_left_paren (pp);
1771 pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1772 pp_cxx_right_paren (pp);
1773 pp_indentation (pp) += 3;
1774 pp_needs_newline (pp) = true;
1775 pp_cxx_statement (pp, HANDLER_BODY (t));
1776 pp_indentation (pp) -= 3;
1777 pp_needs_newline (pp) = true;
1778 break;
1780 /* selection-statement:
1781 if ( expression ) statement
1782 if ( expression ) statement else statement */
1783 case IF_STMT:
1784 pp_cxx_identifier (pp, "if");
1785 pp_cxx_whitespace (pp);
1786 pp_cxx_left_paren (pp);
1787 pp_cxx_expression (pp, IF_COND (t));
1788 pp_cxx_right_paren (pp);
1789 pp_newline_and_indent (pp, 2);
1790 pp_cxx_statement (pp, THEN_CLAUSE (t));
1791 pp_newline_and_indent (pp, -2);
1792 if (ELSE_CLAUSE (t))
1794 tree else_clause = ELSE_CLAUSE (t);
1795 pp_cxx_identifier (pp, "else");
1796 if (TREE_CODE (else_clause) == IF_STMT)
1797 pp_cxx_whitespace (pp);
1798 else
1799 pp_newline_and_indent (pp, 2);
1800 pp_cxx_statement (pp, else_clause);
1801 if (TREE_CODE (else_clause) != IF_STMT)
1802 pp_newline_and_indent (pp, -2);
1804 break;
1806 case SWITCH_STMT:
1807 pp_cxx_identifier (pp, "switch");
1808 pp_space (pp);
1809 pp_cxx_left_paren (pp);
1810 pp_cxx_expression (pp, SWITCH_STMT_COND (t));
1811 pp_cxx_right_paren (pp);
1812 pp_indentation (pp) += 3;
1813 pp_needs_newline (pp) = true;
1814 pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
1815 pp_newline_and_indent (pp, -3);
1816 break;
1818 /* iteration-statement:
1819 while ( expression ) statement
1820 do statement while ( expression ) ;
1821 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1822 for ( declaration expression(opt) ; expression(opt) ) statement */
1823 case WHILE_STMT:
1824 pp_cxx_identifier (pp, "while");
1825 pp_space (pp);
1826 pp_cxx_left_paren (pp);
1827 pp_cxx_expression (pp, WHILE_COND (t));
1828 pp_cxx_right_paren (pp);
1829 pp_newline_and_indent (pp, 3);
1830 pp_cxx_statement (pp, WHILE_BODY (t));
1831 pp_indentation (pp) -= 3;
1832 pp_needs_newline (pp) = true;
1833 break;
1835 case DO_STMT:
1836 pp_cxx_identifier (pp, "do");
1837 pp_newline_and_indent (pp, 3);
1838 pp_cxx_statement (pp, DO_BODY (t));
1839 pp_newline_and_indent (pp, -3);
1840 pp_cxx_identifier (pp, "while");
1841 pp_space (pp);
1842 pp_cxx_left_paren (pp);
1843 pp_cxx_expression (pp, DO_COND (t));
1844 pp_cxx_right_paren (pp);
1845 pp_cxx_semicolon (pp);
1846 pp_needs_newline (pp) = true;
1847 break;
1849 case FOR_STMT:
1850 pp_cxx_identifier (pp, "for");
1851 pp_space (pp);
1852 pp_cxx_left_paren (pp);
1853 if (FOR_INIT_STMT (t))
1854 pp_cxx_statement (pp, FOR_INIT_STMT (t));
1855 else
1856 pp_cxx_semicolon (pp);
1857 pp_needs_newline (pp) = false;
1858 pp_cxx_whitespace (pp);
1859 if (FOR_COND (t))
1860 pp_cxx_expression (pp, FOR_COND (t));
1861 pp_cxx_semicolon (pp);
1862 pp_needs_newline (pp) = false;
1863 pp_cxx_whitespace (pp);
1864 if (FOR_EXPR (t))
1865 pp_cxx_expression (pp, FOR_EXPR (t));
1866 pp_cxx_right_paren (pp);
1867 pp_newline_and_indent (pp, 3);
1868 pp_cxx_statement (pp, FOR_BODY (t));
1869 pp_indentation (pp) -= 3;
1870 pp_needs_newline (pp) = true;
1871 break;
1873 /* jump-statement:
1874 goto identifier;
1875 continue ;
1876 return expression(opt) ; */
1877 case BREAK_STMT:
1878 case CONTINUE_STMT:
1879 pp_identifier (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1880 pp_cxx_semicolon (pp);
1881 pp_needs_newline (pp) = true;
1882 break;
1884 /* expression-statement:
1885 expression(opt) ; */
1886 case EXPR_STMT:
1887 pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
1888 pp_cxx_semicolon (pp);
1889 pp_needs_newline (pp) = true;
1890 break;
1892 case CLEANUP_STMT:
1893 pp_cxx_identifier (pp, "try");
1894 pp_newline_and_indent (pp, 2);
1895 pp_cxx_statement (pp, CLEANUP_BODY (t));
1896 pp_newline_and_indent (pp, -2);
1897 pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1898 pp_newline_and_indent (pp, 2);
1899 pp_cxx_statement (pp, CLEANUP_EXPR (t));
1900 pp_newline_and_indent (pp, -2);
1901 break;
1903 case STATIC_ASSERT:
1904 pp_cxx_declaration (pp, t);
1905 break;
1907 default:
1908 pp_c_statement (pp_c_base (pp), t);
1909 break;
1913 /* original-namespace-definition:
1914 namespace identifier { namespace-body }
1916 As an edge case, we also handle unnamed namespace definition here. */
1918 static void
1919 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1921 pp_cxx_identifier (pp, "namespace");
1922 if (DECL_CONTEXT (t))
1923 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1924 if (DECL_NAME (t))
1925 pp_cxx_unqualified_id (pp, t);
1926 pp_cxx_whitespace (pp);
1927 pp_cxx_left_brace (pp);
1928 /* We do not print the namespace-body. */
1929 pp_cxx_whitespace (pp);
1930 pp_cxx_right_brace (pp);
1933 /* namespace-alias:
1934 identifier
1936 namespace-alias-definition:
1937 namespace identifier = qualified-namespace-specifier ;
1939 qualified-namespace-specifier:
1940 ::(opt) nested-name-specifier(opt) namespace-name */
1942 static void
1943 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1945 pp_cxx_identifier (pp, "namespace");
1946 if (DECL_CONTEXT (t))
1947 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1948 pp_cxx_unqualified_id (pp, t);
1949 pp_cxx_whitespace (pp);
1950 pp_equal (pp);
1951 pp_cxx_whitespace (pp);
1952 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
1953 pp_cxx_nested_name_specifier (pp,
1954 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
1955 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1956 pp_cxx_semicolon (pp);
1959 /* simple-declaration:
1960 decl-specifier-seq(opt) init-declarator-list(opt) */
1962 static void
1963 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1965 pp_cxx_decl_specifier_seq (pp, t);
1966 pp_cxx_init_declarator (pp, t);
1967 pp_cxx_semicolon (pp);
1968 pp_needs_newline (pp) = true;
1972 template-parameter-list:
1973 template-parameter
1974 template-parameter-list , template-parameter */
1976 static inline void
1977 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1979 const int n = TREE_VEC_LENGTH (t);
1980 int i;
1981 for (i = 0; i < n; ++i)
1983 if (i)
1984 pp_cxx_separate_with (pp, ',');
1985 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1989 /* template-parameter:
1990 type-parameter
1991 parameter-declaration
1993 type-parameter:
1994 class ...(opt) identifier(opt)
1995 class identifier(opt) = type-id
1996 typename identifier(opt)
1997 typename ...(opt) identifier(opt) = type-id
1998 template < template-parameter-list > class ...(opt) identifier(opt)
1999 template < template-parameter-list > class identifier(opt) = template-name */
2001 static void
2002 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2004 tree parameter = TREE_VALUE (t);
2005 switch (TREE_CODE (parameter))
2007 case TYPE_DECL:
2008 pp_cxx_identifier (pp, "class");
2009 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2010 pp_cxx_identifier (pp, "...");
2011 if (DECL_NAME (parameter))
2012 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2013 /* FIXME: Chech if we should print also default argument. */
2014 break;
2016 case PARM_DECL:
2017 pp_cxx_parameter_declaration (pp, parameter);
2018 break;
2020 case TEMPLATE_DECL:
2021 break;
2023 default:
2024 pp_unsupported_tree (pp, t);
2025 break;
2029 /* Pretty-print a template parameter in the canonical form
2030 "template-parameter-<level>-<position in parameter list>". */
2032 void
2033 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2035 const enum tree_code code = TREE_CODE (parm);
2037 /* Brings type template parameters to the canonical forms. */
2038 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2039 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2040 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2042 pp_cxx_begin_template_argument_list (pp);
2043 pp_cxx_identifier (pp, "template-parameter-");
2044 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2045 pp_minus (pp);
2046 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2047 pp_cxx_end_template_argument_list (pp);
2051 template-declaration:
2052 export(opt) template < template-parameter-list > declaration */
2054 static void
2055 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2057 tree tmpl = most_general_template (t);
2058 tree level;
2059 int i = 0;
2061 pp_maybe_newline_and_indent (pp, 0);
2062 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2064 pp_cxx_identifier (pp, "template");
2065 pp_cxx_begin_template_argument_list (pp);
2066 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2067 pp_cxx_end_template_argument_list (pp);
2068 pp_newline_and_indent (pp, 3);
2069 i += 3;
2071 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2072 pp_cxx_function_definition (pp, t);
2073 else
2074 pp_cxx_simple_declaration (pp, t);
2077 static void
2078 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2080 pp_unsupported_tree (pp, t);
2083 static void
2084 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2086 pp_unsupported_tree (pp, t);
2090 declaration:
2091 block-declaration
2092 function-definition
2093 template-declaration
2094 explicit-instantiation
2095 explicit-specialization
2096 linkage-specification
2097 namespace-definition
2099 block-declaration:
2100 simple-declaration
2101 asm-definition
2102 namespace-alias-definition
2103 using-declaration
2104 using-directive
2105 static_assert-declaration */
2106 void
2107 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
2109 if (TREE_CODE (t) == STATIC_ASSERT)
2111 pp_cxx_identifier (pp, "static_assert");
2112 pp_cxx_left_paren (pp);
2113 pp_cxx_expression (pp, STATIC_ASSERT_CONDITION (t));
2114 pp_cxx_separate_with (pp, ',');
2115 pp_cxx_expression (pp, STATIC_ASSERT_MESSAGE (t));
2116 pp_cxx_right_paren (pp);
2118 else if (!DECL_LANG_SPECIFIC (t))
2119 pp_cxx_simple_declaration (pp, t);
2120 else if (DECL_USE_TEMPLATE (t))
2121 switch (DECL_USE_TEMPLATE (t))
2123 case 1:
2124 pp_cxx_template_declaration (pp, t);
2125 break;
2127 case 2:
2128 pp_cxx_explicit_specialization (pp, t);
2129 break;
2131 case 3:
2132 pp_cxx_explicit_instantiation (pp, t);
2133 break;
2135 default:
2136 break;
2138 else switch (TREE_CODE (t))
2140 case VAR_DECL:
2141 case TYPE_DECL:
2142 pp_cxx_simple_declaration (pp, t);
2143 break;
2145 case FUNCTION_DECL:
2146 if (DECL_SAVED_TREE (t))
2147 pp_cxx_function_definition (pp, t);
2148 else
2149 pp_cxx_simple_declaration (pp, t);
2150 break;
2152 case NAMESPACE_DECL:
2153 if (DECL_NAMESPACE_ALIAS (t))
2154 pp_cxx_namespace_alias_definition (pp, t);
2155 else
2156 pp_cxx_original_namespace_definition (pp, t);
2157 break;
2159 default:
2160 pp_unsupported_tree (pp, t);
2161 break;
2165 static void
2166 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2168 t = TREE_OPERAND (t, 0);
2169 pp_cxx_identifier (pp, "typeid");
2170 pp_cxx_left_paren (pp);
2171 if (TYPE_P (t))
2172 pp_cxx_type_id (pp, t);
2173 else
2174 pp_cxx_expression (pp, t);
2175 pp_cxx_right_paren (pp);
2178 void
2179 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2181 pp_cxx_identifier (pp, "va_arg");
2182 pp_cxx_left_paren (pp);
2183 pp_cxx_assignment_expression (pp, TREE_OPERAND (t, 0));
2184 pp_cxx_separate_with (pp, ',');
2185 pp_cxx_type_id (pp, TREE_TYPE (t));
2186 pp_cxx_right_paren (pp);
2189 static bool
2190 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2192 switch (TREE_CODE (t))
2194 case ARROW_EXPR:
2195 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2196 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2198 pp_cxx_type_id (pp, TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2199 pp_cxx_separate_with (pp, ',');
2200 return true;
2202 return false;
2203 case COMPONENT_REF:
2204 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2205 return false;
2206 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2207 pp_cxx_dot (pp);
2208 pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2209 return true;
2210 case ARRAY_REF:
2211 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2212 return false;
2213 pp_left_bracket (pp);
2214 pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2215 pp_right_bracket (pp);
2216 return true;
2217 default:
2218 return false;
2222 void
2223 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2225 pp_cxx_identifier (pp, "offsetof");
2226 pp_cxx_left_paren (pp);
2227 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2228 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
2229 pp_cxx_right_paren (pp);
2232 void
2233 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2235 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2237 switch (kind)
2239 case CPTK_HAS_NOTHROW_ASSIGN:
2240 pp_cxx_identifier (pp, "__has_nothrow_assign");
2241 break;
2242 case CPTK_HAS_TRIVIAL_ASSIGN:
2243 pp_cxx_identifier (pp, "__has_trivial_assign");
2244 break;
2245 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2246 pp_cxx_identifier (pp, "__has_nothrow_constructor");
2247 break;
2248 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2249 pp_cxx_identifier (pp, "__has_trivial_constructor");
2250 break;
2251 case CPTK_HAS_NOTHROW_COPY:
2252 pp_cxx_identifier (pp, "__has_nothrow_copy");
2253 break;
2254 case CPTK_HAS_TRIVIAL_COPY:
2255 pp_cxx_identifier (pp, "__has_trivial_copy");
2256 break;
2257 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2258 pp_cxx_identifier (pp, "__has_trivial_destructor");
2259 break;
2260 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2261 pp_cxx_identifier (pp, "__has_virtual_destructor");
2262 break;
2263 case CPTK_IS_ABSTRACT:
2264 pp_cxx_identifier (pp, "__is_abstract");
2265 break;
2266 case CPTK_IS_BASE_OF:
2267 pp_cxx_identifier (pp, "__is_base_of");
2268 break;
2269 case CPTK_IS_CLASS:
2270 pp_cxx_identifier (pp, "__is_class");
2271 break;
2272 case CPTK_IS_CONVERTIBLE_TO:
2273 pp_cxx_identifier (pp, "__is_convertible_to");
2274 break;
2275 case CPTK_IS_EMPTY:
2276 pp_cxx_identifier (pp, "__is_empty");
2277 break;
2278 case CPTK_IS_ENUM:
2279 pp_cxx_identifier (pp, "__is_enum");
2280 break;
2281 case CPTK_IS_POD:
2282 pp_cxx_identifier (pp, "__is_pod");
2283 break;
2284 case CPTK_IS_POLYMORPHIC:
2285 pp_cxx_identifier (pp, "__is_polymorphic");
2286 break;
2287 case CPTK_IS_UNION:
2288 pp_cxx_identifier (pp, "__is_union");
2289 break;
2291 default:
2292 gcc_unreachable ();
2295 pp_cxx_left_paren (pp);
2296 pp_cxx_type_id (pp, TRAIT_EXPR_TYPE1 (t));
2298 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2300 pp_cxx_separate_with (pp, ',');
2301 pp_cxx_type_id (pp, TRAIT_EXPR_TYPE2 (t));
2304 pp_cxx_right_paren (pp);
2307 typedef c_pretty_print_fn pp_fun;
2309 /* Initialization of a C++ pretty-printer object. */
2311 void
2312 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
2314 pp_c_pretty_printer_init (pp_c_base (pp));
2315 pp_set_line_maximum_length (pp, 0);
2317 pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
2318 pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
2319 pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
2320 pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2321 pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
2322 pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
2323 pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2324 pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
2325 pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
2326 pp->c_base.direct_abstract_declarator =
2327 (pp_fun) pp_cxx_direct_abstract_declarator;
2328 pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
2330 /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
2332 pp->c_base.constant = (pp_fun) pp_cxx_constant;
2333 pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
2334 pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
2335 pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
2336 pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
2337 pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
2338 pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
2339 pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
2340 pp->c_base.expression = (pp_fun) pp_cxx_expression;
2341 pp->enclosing_scope = global_namespace;