Merge from trunk @ 138209
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blobcf9ed482e8468ea7b71eaac364da0287dc8d0348
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003, 2004, 2005, 2007, 2008 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 typeid ( 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 tree type = TREE_OPERAND (t, 1);
640 tree init = TREE_OPERAND (t, 2);
641 switch (code)
643 case NEW_EXPR:
644 case VEC_NEW_EXPR:
645 if (NEW_EXPR_USE_GLOBAL (t))
646 pp_cxx_colon_colon (pp);
647 pp_cxx_identifier (pp, "new");
648 if (TREE_OPERAND (t, 0))
650 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
651 pp_space (pp);
653 if (TREE_CODE (type) == ARRAY_REF)
654 type = build_cplus_array_type
655 (TREE_OPERAND (type, 0),
656 build_index_type (fold_build2 (MINUS_EXPR, integer_type_node,
657 TREE_OPERAND (type, 1),
658 integer_one_node)));
659 pp_cxx_type_id (pp, type);
660 if (init)
662 pp_left_paren (pp);
663 if (TREE_CODE (init) == TREE_LIST)
664 pp_c_expression_list (pp_c_base (pp), init);
665 else if (init == void_zero_node)
666 ; /* OK, empty initializer list. */
667 else
668 pp_cxx_expression (pp, init);
669 pp_right_paren (pp);
671 break;
673 default:
674 pp_unsupported_tree (pp, t);
678 /* delete-expression:
679 ::(opt) delete cast-expression
680 ::(opt) delete [ ] cast-expression */
682 static void
683 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
685 enum tree_code code = TREE_CODE (t);
686 switch (code)
688 case DELETE_EXPR:
689 case VEC_DELETE_EXPR:
690 if (DELETE_EXPR_USE_GLOBAL (t))
691 pp_cxx_colon_colon (pp);
692 pp_cxx_identifier (pp, "delete");
693 pp_space (pp);
694 if (code == VEC_DELETE_EXPR
695 || DELETE_EXPR_USE_VEC (t))
697 pp_left_bracket (pp);
698 pp_right_bracket (pp);
699 pp_space (pp);
701 pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
702 break;
704 default:
705 pp_unsupported_tree (pp, t);
709 /* unary-expression:
710 postfix-expression
711 ++ cast-expression
712 -- cast-expression
713 unary-operator cast-expression
714 sizeof unary-expression
715 sizeof ( type-id )
716 sizeof ... ( identifier )
717 new-expression
718 delete-expression
720 unary-operator: one of
721 * & + - !
723 GNU extensions:
724 __alignof__ unary-expression
725 __alignof__ ( type-id ) */
727 static void
728 pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
730 enum tree_code code = TREE_CODE (t);
731 switch (code)
733 case NEW_EXPR:
734 case VEC_NEW_EXPR:
735 pp_cxx_new_expression (pp, t);
736 break;
738 case DELETE_EXPR:
739 case VEC_DELETE_EXPR:
740 pp_cxx_delete_expression (pp, t);
741 break;
743 case SIZEOF_EXPR:
744 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
746 pp_cxx_identifier (pp, "sizeof");
747 pp_cxx_identifier (pp, "...");
748 pp_cxx_whitespace (pp);
749 pp_cxx_left_paren (pp);
750 if (TYPE_P (TREE_OPERAND (t, 0)))
751 pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
752 else
753 pp_unary_expression (pp, TREE_OPERAND (t, 0));
754 pp_cxx_right_paren (pp);
755 break;
757 /* Fall through */
759 case ALIGNOF_EXPR:
760 pp_cxx_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
761 pp_cxx_whitespace (pp);
762 if (TYPE_P (TREE_OPERAND (t, 0)))
764 pp_cxx_left_paren (pp);
765 pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
766 pp_cxx_right_paren (pp);
768 else
769 pp_unary_expression (pp, TREE_OPERAND (t, 0));
770 break;
772 case UNARY_PLUS_EXPR:
773 pp_plus (pp);
774 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
775 break;
777 default:
778 pp_c_unary_expression (pp_c_base (pp), t);
779 break;
783 /* cast-expression:
784 unary-expression
785 ( type-id ) cast-expression */
787 static void
788 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
790 switch (TREE_CODE (t))
792 case CAST_EXPR:
793 pp_cxx_type_id (pp, TREE_TYPE (t));
794 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
795 break;
797 default:
798 pp_c_cast_expression (pp_c_base (pp), t);
799 break;
803 /* pm-expression:
804 cast-expression
805 pm-expression .* cast-expression
806 pm-expression ->* cast-expression */
808 static void
809 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
811 switch (TREE_CODE (t))
813 /* Handle unfortunate OFFSET_REF overloading here. */
814 case OFFSET_REF:
815 if (TYPE_P (TREE_OPERAND (t, 0)))
817 pp_cxx_qualified_id (pp, t);
818 break;
820 /* Else fall through. */
821 case MEMBER_REF:
822 case DOTSTAR_EXPR:
823 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
824 if (TREE_CODE (t) == MEMBER_REF)
825 pp_cxx_arrow (pp);
826 else
827 pp_cxx_dot (pp);
828 pp_star(pp);
829 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
830 break;
833 default:
834 pp_cxx_cast_expression (pp, t);
835 break;
839 /* multiplicative-expression:
840 pm-expression
841 multiplicative-expression * pm-expression
842 multiplicative-expression / pm-expression
843 multiplicative-expression % pm-expression */
845 static void
846 pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
848 enum tree_code code = TREE_CODE (e);
849 switch (code)
851 case MULT_EXPR:
852 case TRUNC_DIV_EXPR:
853 case TRUNC_MOD_EXPR:
854 pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
855 pp_space (pp);
856 if (code == MULT_EXPR)
857 pp_star (pp);
858 else if (code == TRUNC_DIV_EXPR)
859 pp_slash (pp);
860 else
861 pp_modulo (pp);
862 pp_space (pp);
863 pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
864 break;
866 default:
867 pp_cxx_pm_expression (pp, e);
868 break;
872 /* conditional-expression:
873 logical-or-expression
874 logical-or-expression ? expression : assignment-expression */
876 static void
877 pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
879 if (TREE_CODE (e) == COND_EXPR)
881 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
882 pp_space (pp);
883 pp_question (pp);
884 pp_space (pp);
885 pp_cxx_expression (pp, TREE_OPERAND (e, 1));
886 pp_space (pp);
887 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
889 else
890 pp_c_logical_or_expression (pp_c_base (pp), e);
893 /* Pretty-print a compound assignment operator token as indicated by T. */
895 static void
896 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
898 const char *op;
900 switch (TREE_CODE (t))
902 case NOP_EXPR:
903 op = "=";
904 break;
906 case PLUS_EXPR:
907 op = "+=";
908 break;
910 case MINUS_EXPR:
911 op = "-=";
912 break;
914 case TRUNC_DIV_EXPR:
915 op = "/=";
916 break;
918 case TRUNC_MOD_EXPR:
919 op = "%=";
920 break;
922 default:
923 op = tree_code_name[TREE_CODE (t)];
924 break;
927 pp_cxx_identifier (pp, op);
931 /* assignment-expression:
932 conditional-expression
933 logical-or-expression assignment-operator assignment-expression
934 throw-expression
936 throw-expression:
937 throw assignment-expression(opt)
939 assignment-operator: one of
940 = *= /= %= += -= >>= <<= &= ^= |= */
942 static void
943 pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
945 switch (TREE_CODE (e))
947 case MODIFY_EXPR:
948 case INIT_EXPR:
949 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
950 pp_space (pp);
951 pp_equal (pp);
952 pp_space (pp);
953 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
954 break;
956 case THROW_EXPR:
957 pp_cxx_identifier (pp, "throw");
958 if (TREE_OPERAND (e, 0))
959 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
960 break;
962 case MODOP_EXPR:
963 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
964 pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
965 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
966 break;
968 default:
969 pp_cxx_conditional_expression (pp, e);
970 break;
974 static void
975 pp_cxx_expression (cxx_pretty_printer *pp, tree t)
977 switch (TREE_CODE (t))
979 case STRING_CST:
980 case INTEGER_CST:
981 case REAL_CST:
982 case COMPLEX_CST:
983 pp_cxx_constant (pp, t);
984 break;
986 case RESULT_DECL:
987 pp_cxx_unqualified_id (pp, t);
988 break;
990 #if 0
991 case OFFSET_REF:
992 #endif
993 case SCOPE_REF:
994 case PTRMEM_CST:
995 pp_cxx_qualified_id (pp, t);
996 break;
998 case OVERLOAD:
999 t = OVL_CURRENT (t);
1000 case VAR_DECL:
1001 case PARM_DECL:
1002 case FIELD_DECL:
1003 case CONST_DECL:
1004 case FUNCTION_DECL:
1005 case BASELINK:
1006 case TEMPLATE_DECL:
1007 case TEMPLATE_TYPE_PARM:
1008 case TEMPLATE_PARM_INDEX:
1009 case TEMPLATE_TEMPLATE_PARM:
1010 case STMT_EXPR:
1011 pp_cxx_primary_expression (pp, t);
1012 break;
1014 case CALL_EXPR:
1015 case DYNAMIC_CAST_EXPR:
1016 case STATIC_CAST_EXPR:
1017 case REINTERPRET_CAST_EXPR:
1018 case CONST_CAST_EXPR:
1019 #if 0
1020 case MEMBER_REF:
1021 #endif
1022 case EMPTY_CLASS_EXPR:
1023 case TYPEID_EXPR:
1024 case PSEUDO_DTOR_EXPR:
1025 case AGGR_INIT_EXPR:
1026 case ARROW_EXPR:
1027 pp_cxx_postfix_expression (pp, t);
1028 break;
1030 case NEW_EXPR:
1031 case VEC_NEW_EXPR:
1032 pp_cxx_new_expression (pp, t);
1033 break;
1035 case DELETE_EXPR:
1036 case VEC_DELETE_EXPR:
1037 pp_cxx_delete_expression (pp, t);
1038 break;
1040 case SIZEOF_EXPR:
1041 case ALIGNOF_EXPR:
1042 pp_cxx_unary_expression (pp, t);
1043 break;
1045 case CAST_EXPR:
1046 pp_cxx_cast_expression (pp, t);
1047 break;
1049 case OFFSET_REF:
1050 case MEMBER_REF:
1051 case DOTSTAR_EXPR:
1052 pp_cxx_pm_expression (pp, t);
1053 break;
1055 case MULT_EXPR:
1056 case TRUNC_DIV_EXPR:
1057 case TRUNC_MOD_EXPR:
1058 pp_cxx_multiplicative_expression (pp, t);
1059 break;
1061 case COND_EXPR:
1062 pp_cxx_conditional_expression (pp, t);
1063 break;
1065 case MODIFY_EXPR:
1066 case INIT_EXPR:
1067 case THROW_EXPR:
1068 case MODOP_EXPR:
1069 pp_cxx_assignment_expression (pp, t);
1070 break;
1072 case NON_DEPENDENT_EXPR:
1073 case MUST_NOT_THROW_EXPR:
1074 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
1075 break;
1077 case EXPR_PACK_EXPANSION:
1078 pp_cxx_expression (pp, PACK_EXPANSION_PATTERN (t));
1079 pp_cxx_identifier (pp, "...");
1080 break;
1082 case NONTYPE_ARGUMENT_PACK:
1084 tree args = ARGUMENT_PACK_ARGS (t);
1085 int i, len = TREE_VEC_LENGTH (args);
1086 for (i = 0; i < len; ++i)
1088 if (i > 0)
1089 pp_cxx_separate_with (pp, ',');
1090 pp_cxx_expression (pp, TREE_VEC_ELT (args, i));
1093 break;
1095 default:
1096 pp_c_expression (pp_c_base (pp), t);
1097 break;
1102 /* Declarations. */
1104 /* function-specifier:
1105 inline
1106 virtual
1107 explicit */
1109 static void
1110 pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
1112 switch (TREE_CODE (t))
1114 case FUNCTION_DECL:
1115 if (DECL_VIRTUAL_P (t))
1116 pp_cxx_identifier (pp, "virtual");
1117 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1118 pp_cxx_identifier (pp, "explicit");
1119 else
1120 pp_c_function_specifier (pp_c_base (pp), t);
1122 default:
1123 break;
1127 /* decl-specifier-seq:
1128 decl-specifier-seq(opt) decl-specifier
1130 decl-specifier:
1131 storage-class-specifier
1132 type-specifier
1133 function-specifier
1134 friend
1135 typedef */
1137 static void
1138 pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
1140 switch (TREE_CODE (t))
1142 case VAR_DECL:
1143 case PARM_DECL:
1144 case CONST_DECL:
1145 case FIELD_DECL:
1146 pp_cxx_storage_class_specifier (pp, t);
1147 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1148 break;
1150 case TYPE_DECL:
1151 pp_cxx_identifier (pp, "typedef");
1152 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1153 break;
1155 case RECORD_TYPE:
1156 if (TYPE_PTRMEMFUNC_P (t))
1158 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1159 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
1160 pp_cxx_whitespace (pp);
1161 pp_cxx_ptr_operator (pp, t);
1163 break;
1165 case FUNCTION_DECL:
1166 /* Constructors don't have return types. And conversion functions
1167 do not have a type-specifier in their return types. */
1168 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1169 pp_cxx_function_specifier (pp, t);
1170 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1171 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
1172 else
1173 default:
1174 pp_c_declaration_specifiers (pp_c_base (pp), t);
1175 break;
1179 /* simple-type-specifier:
1180 ::(opt) nested-name-specifier(opt) type-name
1181 ::(opt) nested-name-specifier(opt) template(opt) template-id
1182 char
1183 wchar_t
1184 bool
1185 short
1187 long
1188 signed
1189 unsigned
1190 float
1191 double
1192 void */
1194 static void
1195 pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
1197 switch (TREE_CODE (t))
1199 case RECORD_TYPE:
1200 case UNION_TYPE:
1201 case ENUMERAL_TYPE:
1202 pp_cxx_qualified_id (pp, t);
1203 break;
1205 case TEMPLATE_TYPE_PARM:
1206 case TEMPLATE_TEMPLATE_PARM:
1207 case TEMPLATE_PARM_INDEX:
1208 pp_cxx_unqualified_id (pp, t);
1209 break;
1211 case TYPENAME_TYPE:
1212 pp_cxx_identifier (pp, "typename");
1213 pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1214 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1215 break;
1217 default:
1218 pp_c_type_specifier (pp_c_base (pp), t);
1219 break;
1223 /* type-specifier-seq:
1224 type-specifier type-specifier-seq(opt)
1226 type-specifier:
1227 simple-type-specifier
1228 class-specifier
1229 enum-specifier
1230 elaborated-type-specifier
1231 cv-qualifier */
1233 static void
1234 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1236 switch (TREE_CODE (t))
1238 case TEMPLATE_DECL:
1239 case TEMPLATE_TYPE_PARM:
1240 case TEMPLATE_TEMPLATE_PARM:
1241 case TYPE_DECL:
1242 case BOUND_TEMPLATE_TEMPLATE_PARM:
1243 pp_cxx_cv_qualifier_seq (pp, t);
1244 pp_cxx_simple_type_specifier (pp, t);
1245 break;
1247 case METHOD_TYPE:
1248 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1249 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1250 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1251 break;
1253 case DECLTYPE_TYPE:
1254 pp_cxx_identifier (pp, "decltype");
1255 pp_cxx_left_paren (pp);
1256 pp_cxx_expression (pp, DECLTYPE_TYPE_EXPR (t));
1257 pp_cxx_right_paren (pp);
1258 break;
1260 default:
1261 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1262 pp_c_specifier_qualifier_list (pp_c_base (pp), t);
1266 /* ptr-operator:
1267 * cv-qualifier-seq(opt)
1269 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1271 static void
1272 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1274 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1275 t = TREE_TYPE (t);
1276 switch (TREE_CODE (t))
1278 case REFERENCE_TYPE:
1279 case POINTER_TYPE:
1280 if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
1281 || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
1282 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1283 if (TREE_CODE (t) == POINTER_TYPE)
1285 pp_star (pp);
1286 pp_cxx_cv_qualifier_seq (pp, t);
1288 else
1289 pp_ampersand (pp);
1290 break;
1292 case RECORD_TYPE:
1293 if (TYPE_PTRMEMFUNC_P (t))
1295 pp_cxx_left_paren (pp);
1296 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1297 pp_star (pp);
1298 break;
1300 case OFFSET_TYPE:
1301 if (TYPE_PTR_TO_MEMBER_P (t))
1303 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1304 pp_cxx_left_paren (pp);
1305 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1306 pp_star (pp);
1307 pp_cxx_cv_qualifier_seq (pp, t);
1308 break;
1310 /* else fall through. */
1312 default:
1313 pp_unsupported_tree (pp, t);
1314 break;
1318 static inline tree
1319 pp_cxx_implicit_parameter_type (tree mf)
1321 return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1325 parameter-declaration:
1326 decl-specifier-seq declarator
1327 decl-specifier-seq declarator = assignment-expression
1328 decl-specifier-seq abstract-declarator(opt)
1329 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1331 static inline void
1332 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1334 pp_cxx_decl_specifier_seq (pp, t);
1335 if (TYPE_P (t))
1336 pp_cxx_abstract_declarator (pp, t);
1337 else
1338 pp_cxx_declarator (pp, t);
1341 /* parameter-declaration-clause:
1342 parameter-declaration-list(opt) ...(opt)
1343 parameter-declaration-list , ...
1345 parameter-declaration-list:
1346 parameter-declaration
1347 parameter-declaration-list , parameter-declaration */
1349 static void
1350 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1352 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1353 tree types =
1354 TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1355 const bool abstract = args == NULL
1356 || pp_c_base (pp)->flags & pp_c_flag_abstract;
1357 bool first = true;
1359 /* Skip artificial parameter for nonstatic member functions. */
1360 if (TREE_CODE (t) == METHOD_TYPE)
1361 types = TREE_CHAIN (types);
1363 pp_cxx_left_paren (pp);
1364 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1366 if (!first)
1367 pp_cxx_separate_with (pp, ',');
1368 first = false;
1369 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1370 if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1372 pp_cxx_whitespace (pp);
1373 pp_equal (pp);
1374 pp_cxx_whitespace (pp);
1375 pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1378 pp_cxx_right_paren (pp);
1381 /* exception-specification:
1382 throw ( type-id-list(opt) )
1384 type-id-list
1385 type-id
1386 type-id-list , type-id */
1388 static void
1389 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1391 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1392 bool need_comma = false;
1394 if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1395 return;
1396 pp_cxx_identifier (pp, "throw");
1397 pp_cxx_left_paren (pp);
1398 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1400 tree type = TREE_VALUE (ex_spec);
1401 tree argpack = NULL_TREE;
1402 int i, len = 1;
1404 if (ARGUMENT_PACK_P (type))
1406 argpack = ARGUMENT_PACK_ARGS (type);
1407 len = TREE_VEC_LENGTH (argpack);
1410 for (i = 0; i < len; ++i)
1412 if (argpack)
1413 type = TREE_VEC_ELT (argpack, i);
1415 if (need_comma)
1416 pp_cxx_separate_with (pp, ',');
1417 else
1418 need_comma = true;
1420 pp_cxx_type_id (pp, type);
1423 pp_cxx_right_paren (pp);
1426 /* direct-declarator:
1427 declarator-id
1428 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1429 exception-specification(opt)
1430 direct-declaration [ constant-expression(opt) ]
1431 ( declarator ) */
1433 static void
1434 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1436 switch (TREE_CODE (t))
1438 case VAR_DECL:
1439 case PARM_DECL:
1440 case CONST_DECL:
1441 case FIELD_DECL:
1442 if (DECL_NAME (t))
1444 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1446 if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
1447 || template_parameter_pack_p (t))
1448 /* A function parameter pack or non-type template
1449 parameter pack. */
1450 pp_cxx_identifier (pp, "...");
1452 pp_cxx_id_expression (pp, DECL_NAME (t));
1454 pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1455 break;
1457 case FUNCTION_DECL:
1458 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1459 pp_cxx_id_expression (pp, t);
1460 pp_cxx_parameter_declaration_clause (pp, t);
1462 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1464 pp_base (pp)->padding = pp_before;
1465 pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1468 pp_cxx_exception_specification (pp, TREE_TYPE (t));
1469 break;
1471 case TYPENAME_TYPE:
1472 case TEMPLATE_DECL:
1473 case TEMPLATE_TYPE_PARM:
1474 case TEMPLATE_PARM_INDEX:
1475 case TEMPLATE_TEMPLATE_PARM:
1476 break;
1478 default:
1479 pp_c_direct_declarator (pp_c_base (pp), t);
1480 break;
1484 /* declarator:
1485 direct-declarator
1486 ptr-operator declarator */
1488 static void
1489 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1491 pp_cxx_direct_declarator (pp, t);
1494 /* ctor-initializer:
1495 : mem-initializer-list
1497 mem-initializer-list:
1498 mem-initializer
1499 mem-initializer , mem-initializer-list
1501 mem-initializer:
1502 mem-initializer-id ( expression-list(opt) )
1504 mem-initializer-id:
1505 ::(opt) nested-name-specifier(opt) class-name
1506 identifier */
1508 static void
1509 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1511 t = TREE_OPERAND (t, 0);
1512 pp_cxx_whitespace (pp);
1513 pp_colon (pp);
1514 pp_cxx_whitespace (pp);
1515 for (; t; t = TREE_CHAIN (t))
1517 tree purpose = TREE_PURPOSE (t);
1518 bool is_pack = PACK_EXPANSION_P (purpose);
1520 if (is_pack)
1521 pp_cxx_primary_expression (pp, PACK_EXPANSION_PATTERN (purpose));
1522 else
1523 pp_cxx_primary_expression (pp, purpose);
1524 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1525 if (is_pack)
1526 pp_cxx_identifier (pp, "...");
1527 if (TREE_CHAIN (t))
1528 pp_cxx_separate_with (pp, ',');
1532 /* function-definition:
1533 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1534 decl-specifier-seq(opt) declarator function-try-block */
1536 static void
1537 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1539 tree saved_scope = pp->enclosing_scope;
1540 pp_cxx_decl_specifier_seq (pp, t);
1541 pp_cxx_declarator (pp, t);
1542 pp_needs_newline (pp) = true;
1543 pp->enclosing_scope = DECL_CONTEXT (t);
1544 if (DECL_SAVED_TREE (t))
1545 pp_cxx_statement (pp, DECL_SAVED_TREE (t));
1546 else
1548 pp_cxx_semicolon (pp);
1549 pp_needs_newline (pp) = true;
1551 pp_flush (pp);
1552 pp->enclosing_scope = saved_scope;
1555 /* abstract-declarator:
1556 ptr-operator abstract-declarator(opt)
1557 direct-abstract-declarator */
1559 static void
1560 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1562 if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1563 pp_cxx_right_paren (pp);
1564 else if (POINTER_TYPE_P (t))
1566 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1567 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1568 pp_cxx_right_paren (pp);
1569 t = TREE_TYPE (t);
1571 pp_cxx_direct_abstract_declarator (pp, t);
1574 /* direct-abstract-declarator:
1575 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1576 cv-qualifier-seq(opt) exception-specification(opt)
1577 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1578 ( abstract-declarator ) */
1580 static void
1581 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1583 switch (TREE_CODE (t))
1585 case REFERENCE_TYPE:
1586 pp_cxx_abstract_declarator (pp, t);
1587 break;
1589 case RECORD_TYPE:
1590 if (TYPE_PTRMEMFUNC_P (t))
1591 pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1592 break;
1594 case METHOD_TYPE:
1595 case FUNCTION_TYPE:
1596 pp_cxx_parameter_declaration_clause (pp, t);
1597 pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1598 if (TREE_CODE (t) == METHOD_TYPE)
1600 pp_base (pp)->padding = pp_before;
1601 pp_cxx_cv_qualifier_seq
1602 (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1604 pp_cxx_exception_specification (pp, t);
1605 break;
1607 case TYPENAME_TYPE:
1608 case TEMPLATE_TYPE_PARM:
1609 case TEMPLATE_TEMPLATE_PARM:
1610 case BOUND_TEMPLATE_TEMPLATE_PARM:
1611 case UNBOUND_CLASS_TEMPLATE:
1612 break;
1614 default:
1615 pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1616 break;
1620 /* type-id:
1621 type-specifier-seq abstract-declarator(opt) */
1623 static void
1624 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1626 pp_flags saved_flags = pp_c_base (pp)->flags;
1627 pp_c_base (pp)->flags |= pp_c_flag_abstract;
1629 switch (TREE_CODE (t))
1631 case TYPE_DECL:
1632 case UNION_TYPE:
1633 case RECORD_TYPE:
1634 case ENUMERAL_TYPE:
1635 case TYPENAME_TYPE:
1636 case BOUND_TEMPLATE_TEMPLATE_PARM:
1637 case UNBOUND_CLASS_TEMPLATE:
1638 case TEMPLATE_TEMPLATE_PARM:
1639 case TEMPLATE_TYPE_PARM:
1640 case TEMPLATE_PARM_INDEX:
1641 case TEMPLATE_DECL:
1642 case TYPEOF_TYPE:
1643 case DECLTYPE_TYPE:
1644 case TEMPLATE_ID_EXPR:
1645 pp_cxx_type_specifier_seq (pp, t);
1646 break;
1648 case TYPE_PACK_EXPANSION:
1649 pp_cxx_type_id (pp, PACK_EXPANSION_PATTERN (t));
1650 pp_cxx_identifier (pp, "...");
1651 break;
1653 default:
1654 pp_c_type_id (pp_c_base (pp), t);
1655 break;
1658 pp_c_base (pp)->flags = saved_flags;
1661 /* template-argument-list:
1662 template-argument ...(opt)
1663 template-argument-list, template-argument ...(opt)
1665 template-argument:
1666 assignment-expression
1667 type-id
1668 template-name */
1670 static void
1671 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1673 int i;
1674 bool need_comma = false;
1676 if (t == NULL)
1677 return;
1678 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1680 tree arg = TREE_VEC_ELT (t, i);
1681 tree argpack = NULL_TREE;
1682 int idx, len = 1;
1684 if (ARGUMENT_PACK_P (arg))
1686 argpack = ARGUMENT_PACK_ARGS (arg);
1687 len = TREE_VEC_LENGTH (argpack);
1690 for (idx = 0; idx < len; idx++)
1692 if (argpack)
1693 arg = TREE_VEC_ELT (argpack, idx);
1695 if (need_comma)
1696 pp_cxx_separate_with (pp, ',');
1697 else
1698 need_comma = true;
1700 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1701 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1702 pp_cxx_type_id (pp, arg);
1703 else
1704 pp_cxx_expression (pp, arg);
1710 static void
1711 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1713 t = DECL_EXPR_DECL (t);
1714 pp_cxx_type_specifier_seq (pp, t);
1715 if (TYPE_P (t))
1716 pp_cxx_abstract_declarator (pp, t);
1717 else
1718 pp_cxx_declarator (pp, t);
1721 /* Statements. */
1723 static void
1724 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1726 switch (TREE_CODE (t))
1728 case CTOR_INITIALIZER:
1729 pp_cxx_ctor_initializer (pp, t);
1730 break;
1732 case USING_STMT:
1733 pp_cxx_identifier (pp, "using");
1734 pp_cxx_identifier (pp, "namespace");
1735 if (DECL_CONTEXT (t))
1736 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1737 pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1738 break;
1740 case USING_DECL:
1741 pp_cxx_identifier (pp, "using");
1742 pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
1743 pp_cxx_unqualified_id (pp, DECL_NAME (t));
1744 break;
1746 case EH_SPEC_BLOCK:
1747 break;
1749 /* try-block:
1750 try compound-statement handler-seq */
1751 case TRY_BLOCK:
1752 pp_maybe_newline_and_indent (pp, 0);
1753 pp_cxx_identifier (pp, "try");
1754 pp_newline_and_indent (pp, 3);
1755 pp_cxx_statement (pp, TRY_STMTS (t));
1756 pp_newline_and_indent (pp, -3);
1757 if (CLEANUP_P (t))
1759 else
1760 pp_cxx_statement (pp, TRY_HANDLERS (t));
1761 break;
1764 handler-seq:
1765 handler handler-seq(opt)
1767 handler:
1768 catch ( exception-declaration ) compound-statement
1770 exception-declaration:
1771 type-specifier-seq declarator
1772 type-specifier-seq abstract-declarator
1773 ... */
1774 case HANDLER:
1775 pp_cxx_identifier (pp, "catch");
1776 pp_cxx_left_paren (pp);
1777 pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1778 pp_cxx_right_paren (pp);
1779 pp_indentation (pp) += 3;
1780 pp_needs_newline (pp) = true;
1781 pp_cxx_statement (pp, HANDLER_BODY (t));
1782 pp_indentation (pp) -= 3;
1783 pp_needs_newline (pp) = true;
1784 break;
1786 /* selection-statement:
1787 if ( expression ) statement
1788 if ( expression ) statement else statement */
1789 case IF_STMT:
1790 pp_cxx_identifier (pp, "if");
1791 pp_cxx_whitespace (pp);
1792 pp_cxx_left_paren (pp);
1793 pp_cxx_expression (pp, IF_COND (t));
1794 pp_cxx_right_paren (pp);
1795 pp_newline_and_indent (pp, 2);
1796 pp_cxx_statement (pp, THEN_CLAUSE (t));
1797 pp_newline_and_indent (pp, -2);
1798 if (ELSE_CLAUSE (t))
1800 tree else_clause = ELSE_CLAUSE (t);
1801 pp_cxx_identifier (pp, "else");
1802 if (TREE_CODE (else_clause) == IF_STMT)
1803 pp_cxx_whitespace (pp);
1804 else
1805 pp_newline_and_indent (pp, 2);
1806 pp_cxx_statement (pp, else_clause);
1807 if (TREE_CODE (else_clause) != IF_STMT)
1808 pp_newline_and_indent (pp, -2);
1810 break;
1812 case SWITCH_STMT:
1813 pp_cxx_identifier (pp, "switch");
1814 pp_space (pp);
1815 pp_cxx_left_paren (pp);
1816 pp_cxx_expression (pp, SWITCH_STMT_COND (t));
1817 pp_cxx_right_paren (pp);
1818 pp_indentation (pp) += 3;
1819 pp_needs_newline (pp) = true;
1820 pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
1821 pp_newline_and_indent (pp, -3);
1822 break;
1824 /* iteration-statement:
1825 while ( expression ) statement
1826 do statement while ( expression ) ;
1827 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1828 for ( declaration expression(opt) ; expression(opt) ) statement */
1829 case WHILE_STMT:
1830 pp_cxx_identifier (pp, "while");
1831 pp_space (pp);
1832 pp_cxx_left_paren (pp);
1833 pp_cxx_expression (pp, WHILE_COND (t));
1834 pp_cxx_right_paren (pp);
1835 pp_newline_and_indent (pp, 3);
1836 pp_cxx_statement (pp, WHILE_BODY (t));
1837 pp_indentation (pp) -= 3;
1838 pp_needs_newline (pp) = true;
1839 break;
1841 case DO_STMT:
1842 pp_cxx_identifier (pp, "do");
1843 pp_newline_and_indent (pp, 3);
1844 pp_cxx_statement (pp, DO_BODY (t));
1845 pp_newline_and_indent (pp, -3);
1846 pp_cxx_identifier (pp, "while");
1847 pp_space (pp);
1848 pp_cxx_left_paren (pp);
1849 pp_cxx_expression (pp, DO_COND (t));
1850 pp_cxx_right_paren (pp);
1851 pp_cxx_semicolon (pp);
1852 pp_needs_newline (pp) = true;
1853 break;
1855 case FOR_STMT:
1856 pp_cxx_identifier (pp, "for");
1857 pp_space (pp);
1858 pp_cxx_left_paren (pp);
1859 if (FOR_INIT_STMT (t))
1860 pp_cxx_statement (pp, FOR_INIT_STMT (t));
1861 else
1862 pp_cxx_semicolon (pp);
1863 pp_needs_newline (pp) = false;
1864 pp_cxx_whitespace (pp);
1865 if (FOR_COND (t))
1866 pp_cxx_expression (pp, FOR_COND (t));
1867 pp_cxx_semicolon (pp);
1868 pp_needs_newline (pp) = false;
1869 pp_cxx_whitespace (pp);
1870 if (FOR_EXPR (t))
1871 pp_cxx_expression (pp, FOR_EXPR (t));
1872 pp_cxx_right_paren (pp);
1873 pp_newline_and_indent (pp, 3);
1874 pp_cxx_statement (pp, FOR_BODY (t));
1875 pp_indentation (pp) -= 3;
1876 pp_needs_newline (pp) = true;
1877 break;
1879 /* jump-statement:
1880 goto identifier;
1881 continue ;
1882 return expression(opt) ; */
1883 case BREAK_STMT:
1884 case CONTINUE_STMT:
1885 pp_identifier (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1886 pp_cxx_semicolon (pp);
1887 pp_needs_newline (pp) = true;
1888 break;
1890 /* expression-statement:
1891 expression(opt) ; */
1892 case EXPR_STMT:
1893 pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
1894 pp_cxx_semicolon (pp);
1895 pp_needs_newline (pp) = true;
1896 break;
1898 case CLEANUP_STMT:
1899 pp_cxx_identifier (pp, "try");
1900 pp_newline_and_indent (pp, 2);
1901 pp_cxx_statement (pp, CLEANUP_BODY (t));
1902 pp_newline_and_indent (pp, -2);
1903 pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1904 pp_newline_and_indent (pp, 2);
1905 pp_cxx_statement (pp, CLEANUP_EXPR (t));
1906 pp_newline_and_indent (pp, -2);
1907 break;
1909 case STATIC_ASSERT:
1910 pp_cxx_declaration (pp, t);
1911 break;
1913 default:
1914 pp_c_statement (pp_c_base (pp), t);
1915 break;
1919 /* original-namespace-definition:
1920 namespace identifier { namespace-body }
1922 As an edge case, we also handle unnamed namespace definition here. */
1924 static void
1925 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1927 pp_cxx_identifier (pp, "namespace");
1928 if (DECL_CONTEXT (t))
1929 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1930 if (DECL_NAME (t))
1931 pp_cxx_unqualified_id (pp, t);
1932 pp_cxx_whitespace (pp);
1933 pp_cxx_left_brace (pp);
1934 /* We do not print the namespace-body. */
1935 pp_cxx_whitespace (pp);
1936 pp_cxx_right_brace (pp);
1939 /* namespace-alias:
1940 identifier
1942 namespace-alias-definition:
1943 namespace identifier = qualified-namespace-specifier ;
1945 qualified-namespace-specifier:
1946 ::(opt) nested-name-specifier(opt) namespace-name */
1948 static void
1949 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1951 pp_cxx_identifier (pp, "namespace");
1952 if (DECL_CONTEXT (t))
1953 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1954 pp_cxx_unqualified_id (pp, t);
1955 pp_cxx_whitespace (pp);
1956 pp_equal (pp);
1957 pp_cxx_whitespace (pp);
1958 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
1959 pp_cxx_nested_name_specifier (pp,
1960 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
1961 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1962 pp_cxx_semicolon (pp);
1965 /* simple-declaration:
1966 decl-specifier-seq(opt) init-declarator-list(opt) */
1968 static void
1969 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1971 pp_cxx_decl_specifier_seq (pp, t);
1972 pp_cxx_init_declarator (pp, t);
1973 pp_cxx_semicolon (pp);
1974 pp_needs_newline (pp) = true;
1978 template-parameter-list:
1979 template-parameter
1980 template-parameter-list , template-parameter */
1982 static inline void
1983 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1985 const int n = TREE_VEC_LENGTH (t);
1986 int i;
1987 for (i = 0; i < n; ++i)
1989 if (i)
1990 pp_cxx_separate_with (pp, ',');
1991 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1995 /* template-parameter:
1996 type-parameter
1997 parameter-declaration
1999 type-parameter:
2000 class ...(opt) identifier(opt)
2001 class identifier(opt) = type-id
2002 typename identifier(opt)
2003 typename ...(opt) identifier(opt) = type-id
2004 template < template-parameter-list > class ...(opt) identifier(opt)
2005 template < template-parameter-list > class identifier(opt) = template-name */
2007 static void
2008 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2010 tree parameter = TREE_VALUE (t);
2011 switch (TREE_CODE (parameter))
2013 case TYPE_DECL:
2014 pp_cxx_identifier (pp, "class");
2015 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2016 pp_cxx_identifier (pp, "...");
2017 if (DECL_NAME (parameter))
2018 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2019 /* FIXME: Check if we should print also default argument. */
2020 break;
2022 case PARM_DECL:
2023 pp_cxx_parameter_declaration (pp, parameter);
2024 break;
2026 case TEMPLATE_DECL:
2027 break;
2029 default:
2030 pp_unsupported_tree (pp, t);
2031 break;
2035 /* Pretty-print a template parameter in the canonical form
2036 "template-parameter-<level>-<position in parameter list>". */
2038 void
2039 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2041 const enum tree_code code = TREE_CODE (parm);
2043 /* Brings type template parameters to the canonical forms. */
2044 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2045 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2046 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2048 pp_cxx_begin_template_argument_list (pp);
2049 pp_cxx_identifier (pp, "template-parameter-");
2050 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2051 pp_minus (pp);
2052 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2053 pp_cxx_end_template_argument_list (pp);
2057 template-declaration:
2058 export(opt) template < template-parameter-list > declaration */
2060 static void
2061 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2063 tree tmpl = most_general_template (t);
2064 tree level;
2065 int i = 0;
2067 pp_maybe_newline_and_indent (pp, 0);
2068 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2070 pp_cxx_identifier (pp, "template");
2071 pp_cxx_begin_template_argument_list (pp);
2072 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2073 pp_cxx_end_template_argument_list (pp);
2074 pp_newline_and_indent (pp, 3);
2075 i += 3;
2077 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2078 pp_cxx_function_definition (pp, t);
2079 else
2080 pp_cxx_simple_declaration (pp, t);
2083 static void
2084 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2086 pp_unsupported_tree (pp, t);
2089 static void
2090 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2092 pp_unsupported_tree (pp, t);
2096 declaration:
2097 block-declaration
2098 function-definition
2099 template-declaration
2100 explicit-instantiation
2101 explicit-specialization
2102 linkage-specification
2103 namespace-definition
2105 block-declaration:
2106 simple-declaration
2107 asm-definition
2108 namespace-alias-definition
2109 using-declaration
2110 using-directive
2111 static_assert-declaration */
2112 void
2113 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
2115 if (TREE_CODE (t) == STATIC_ASSERT)
2117 pp_cxx_identifier (pp, "static_assert");
2118 pp_cxx_left_paren (pp);
2119 pp_cxx_expression (pp, STATIC_ASSERT_CONDITION (t));
2120 pp_cxx_separate_with (pp, ',');
2121 pp_cxx_expression (pp, STATIC_ASSERT_MESSAGE (t));
2122 pp_cxx_right_paren (pp);
2124 else if (!DECL_LANG_SPECIFIC (t))
2125 pp_cxx_simple_declaration (pp, t);
2126 else if (DECL_USE_TEMPLATE (t))
2127 switch (DECL_USE_TEMPLATE (t))
2129 case 1:
2130 pp_cxx_template_declaration (pp, t);
2131 break;
2133 case 2:
2134 pp_cxx_explicit_specialization (pp, t);
2135 break;
2137 case 3:
2138 pp_cxx_explicit_instantiation (pp, t);
2139 break;
2141 default:
2142 break;
2144 else switch (TREE_CODE (t))
2146 case VAR_DECL:
2147 case TYPE_DECL:
2148 pp_cxx_simple_declaration (pp, t);
2149 break;
2151 case FUNCTION_DECL:
2152 if (DECL_SAVED_TREE (t))
2153 pp_cxx_function_definition (pp, t);
2154 else
2155 pp_cxx_simple_declaration (pp, t);
2156 break;
2158 case NAMESPACE_DECL:
2159 if (DECL_NAMESPACE_ALIAS (t))
2160 pp_cxx_namespace_alias_definition (pp, t);
2161 else
2162 pp_cxx_original_namespace_definition (pp, t);
2163 break;
2165 default:
2166 pp_unsupported_tree (pp, t);
2167 break;
2171 static void
2172 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2174 t = TREE_OPERAND (t, 0);
2175 pp_cxx_identifier (pp, "typeid");
2176 pp_cxx_left_paren (pp);
2177 if (TYPE_P (t))
2178 pp_cxx_type_id (pp, t);
2179 else
2180 pp_cxx_expression (pp, t);
2181 pp_cxx_right_paren (pp);
2184 void
2185 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2187 pp_cxx_identifier (pp, "va_arg");
2188 pp_cxx_left_paren (pp);
2189 pp_cxx_assignment_expression (pp, TREE_OPERAND (t, 0));
2190 pp_cxx_separate_with (pp, ',');
2191 pp_cxx_type_id (pp, TREE_TYPE (t));
2192 pp_cxx_right_paren (pp);
2195 static bool
2196 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2198 switch (TREE_CODE (t))
2200 case ARROW_EXPR:
2201 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2202 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2204 pp_cxx_type_id (pp, TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2205 pp_cxx_separate_with (pp, ',');
2206 return true;
2208 return false;
2209 case COMPONENT_REF:
2210 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2211 return false;
2212 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2213 pp_cxx_dot (pp);
2214 pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2215 return true;
2216 case ARRAY_REF:
2217 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2218 return false;
2219 pp_left_bracket (pp);
2220 pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2221 pp_right_bracket (pp);
2222 return true;
2223 default:
2224 return false;
2228 void
2229 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2231 pp_cxx_identifier (pp, "offsetof");
2232 pp_cxx_left_paren (pp);
2233 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2234 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
2235 pp_cxx_right_paren (pp);
2238 void
2239 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2241 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2243 switch (kind)
2245 case CPTK_HAS_NOTHROW_ASSIGN:
2246 pp_cxx_identifier (pp, "__has_nothrow_assign");
2247 break;
2248 case CPTK_HAS_TRIVIAL_ASSIGN:
2249 pp_cxx_identifier (pp, "__has_trivial_assign");
2250 break;
2251 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2252 pp_cxx_identifier (pp, "__has_nothrow_constructor");
2253 break;
2254 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2255 pp_cxx_identifier (pp, "__has_trivial_constructor");
2256 break;
2257 case CPTK_HAS_NOTHROW_COPY:
2258 pp_cxx_identifier (pp, "__has_nothrow_copy");
2259 break;
2260 case CPTK_HAS_TRIVIAL_COPY:
2261 pp_cxx_identifier (pp, "__has_trivial_copy");
2262 break;
2263 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2264 pp_cxx_identifier (pp, "__has_trivial_destructor");
2265 break;
2266 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2267 pp_cxx_identifier (pp, "__has_virtual_destructor");
2268 break;
2269 case CPTK_IS_ABSTRACT:
2270 pp_cxx_identifier (pp, "__is_abstract");
2271 break;
2272 case CPTK_IS_BASE_OF:
2273 pp_cxx_identifier (pp, "__is_base_of");
2274 break;
2275 case CPTK_IS_CLASS:
2276 pp_cxx_identifier (pp, "__is_class");
2277 break;
2278 case CPTK_IS_CONVERTIBLE_TO:
2279 pp_cxx_identifier (pp, "__is_convertible_to");
2280 break;
2281 case CPTK_IS_EMPTY:
2282 pp_cxx_identifier (pp, "__is_empty");
2283 break;
2284 case CPTK_IS_ENUM:
2285 pp_cxx_identifier (pp, "__is_enum");
2286 break;
2287 case CPTK_IS_POD:
2288 pp_cxx_identifier (pp, "__is_pod");
2289 break;
2290 case CPTK_IS_POLYMORPHIC:
2291 pp_cxx_identifier (pp, "__is_polymorphic");
2292 break;
2293 case CPTK_IS_UNION:
2294 pp_cxx_identifier (pp, "__is_union");
2295 break;
2297 default:
2298 gcc_unreachable ();
2301 pp_cxx_left_paren (pp);
2302 pp_cxx_type_id (pp, TRAIT_EXPR_TYPE1 (t));
2304 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2306 pp_cxx_separate_with (pp, ',');
2307 pp_cxx_type_id (pp, TRAIT_EXPR_TYPE2 (t));
2310 pp_cxx_right_paren (pp);
2313 typedef c_pretty_print_fn pp_fun;
2315 /* Initialization of a C++ pretty-printer object. */
2317 void
2318 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
2320 pp_c_pretty_printer_init (pp_c_base (pp));
2321 pp_set_line_maximum_length (pp, 0);
2323 pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
2324 pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
2325 pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
2326 pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2327 pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
2328 pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
2329 pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2330 pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
2331 pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
2332 pp->c_base.direct_abstract_declarator =
2333 (pp_fun) pp_cxx_direct_abstract_declarator;
2334 pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
2336 /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
2338 pp->c_base.constant = (pp_fun) pp_cxx_constant;
2339 pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
2340 pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
2341 pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
2342 pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
2343 pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
2344 pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
2345 pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
2346 pp->c_base.expression = (pp_fun) pp_cxx_expression;
2347 pp->enclosing_scope = global_namespace;