* gcc.dg/store-motion-fgcse-sm.c (dg-final): Cleanup
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blob02ce34611b31c982c2ed70908044fbbd45a2ea42
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2014 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "intl.h"
26 #include "cp-tree.h"
27 #include "cxx-pretty-print.h"
28 #include "tree-pretty-print.h"
30 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
32 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
33 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
34 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
35 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
36 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
37 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
38 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
39 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
42 static inline void
43 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
45 const char *p = pp_last_position_in_text (pp);
47 if (p != NULL && *p == c)
48 pp_cxx_whitespace (pp);
49 pp_character (pp, c);
50 pp->padding = pp_none;
53 #define pp_cxx_expression_list(PP, T) \
54 pp_c_expression_list (PP, T)
55 #define pp_cxx_space_for_pointer_operator(PP, T) \
56 pp_c_space_for_pointer_operator (PP, T)
57 #define pp_cxx_init_declarator(PP, T) \
58 pp_c_init_declarator (PP, T)
59 #define pp_cxx_call_argument_list(PP, T) \
60 pp_c_call_argument_list (PP, T)
62 void
63 pp_cxx_colon_colon (cxx_pretty_printer *pp)
65 pp_colon_colon (pp);
66 pp->padding = pp_none;
69 void
70 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
72 pp_cxx_nonconsecutive_character (pp, '<');
75 void
76 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
78 pp_cxx_nonconsecutive_character (pp, '>');
81 void
82 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
84 pp_separate_with (pp, c);
85 pp->padding = pp_none;
88 /* Expressions. */
90 static inline bool
91 is_destructor_name (tree name)
93 return name == complete_dtor_identifier
94 || name == base_dtor_identifier
95 || name == deleting_dtor_identifier;
98 /* conversion-function-id:
99 operator conversion-type-id
101 conversion-type-id:
102 type-specifier-seq conversion-declarator(opt)
104 conversion-declarator:
105 ptr-operator conversion-declarator(opt) */
107 static inline void
108 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
110 pp_cxx_ws_string (pp, "operator");
111 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
114 static inline void
115 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
117 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
118 pp_cxx_begin_template_argument_list (pp);
119 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
120 pp_cxx_end_template_argument_list (pp);
123 /* Prints the unqualified part of the id-expression T.
125 unqualified-id:
126 identifier
127 operator-function-id
128 conversion-function-id
129 ~ class-name
130 template-id */
132 static void
133 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
135 enum tree_code code = TREE_CODE (t);
136 switch (code)
138 case RESULT_DECL:
139 pp->translate_string ("<return-value>");
140 break;
142 case OVERLOAD:
143 t = OVL_CURRENT (t);
144 case VAR_DECL:
145 case PARM_DECL:
146 case CONST_DECL:
147 case TYPE_DECL:
148 case FUNCTION_DECL:
149 case NAMESPACE_DECL:
150 case FIELD_DECL:
151 case LABEL_DECL:
152 case USING_DECL:
153 case TEMPLATE_DECL:
154 t = DECL_NAME (t);
156 case IDENTIFIER_NODE:
157 if (t == NULL)
158 pp->translate_string ("<unnamed>");
159 else if (IDENTIFIER_TYPENAME_P (t))
160 pp_cxx_conversion_function_id (pp, t);
161 else
163 if (is_destructor_name (t))
165 pp_complement (pp);
166 /* FIXME: Why is this necessary? */
167 if (TREE_TYPE (t))
168 t = constructor_name (TREE_TYPE (t));
170 pp_cxx_tree_identifier (pp, t);
172 break;
174 case TEMPLATE_ID_EXPR:
175 pp_cxx_template_id (pp, t);
176 break;
178 case BASELINK:
179 pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
180 break;
182 case RECORD_TYPE:
183 case UNION_TYPE:
184 case ENUMERAL_TYPE:
185 case TYPENAME_TYPE:
186 case UNBOUND_CLASS_TEMPLATE:
187 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
188 if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
190 pp_cxx_begin_template_argument_list (pp);
191 pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
192 (CLASSTYPE_TI_ARGS (t)));
193 pp_cxx_end_template_argument_list (pp);
195 break;
197 case BIT_NOT_EXPR:
198 pp_cxx_complement (pp);
199 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
200 break;
202 case TEMPLATE_TYPE_PARM:
203 case TEMPLATE_TEMPLATE_PARM:
204 if (TYPE_IDENTIFIER (t))
205 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
206 else
207 pp_cxx_canonical_template_parameter (pp, t);
208 break;
210 case TEMPLATE_PARM_INDEX:
211 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
212 break;
214 case BOUND_TEMPLATE_TEMPLATE_PARM:
215 pp_cxx_cv_qualifier_seq (pp, t);
216 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
217 pp_cxx_begin_template_argument_list (pp);
218 pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
219 pp_cxx_end_template_argument_list (pp);
220 break;
222 default:
223 pp_unsupported_tree (pp, t);
224 break;
228 /* Pretty-print out the token sequence ":: template" in template codes
229 where it is needed to "inline declare" the (following) member as
230 a template. This situation arises when SCOPE of T is dependent
231 on template parameters. */
233 static inline void
234 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
236 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
237 && TYPE_P (scope) && dependent_type_p (scope))
238 pp_cxx_ws_string (pp, "template");
241 /* nested-name-specifier:
242 class-or-namespace-name :: nested-name-specifier(opt)
243 class-or-namespace-name :: template nested-name-specifier */
245 static void
246 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
248 if (!SCOPE_FILE_SCOPE_P (t) && t != pp->enclosing_scope)
250 tree scope = get_containing_scope (t);
251 pp_cxx_nested_name_specifier (pp, scope);
252 pp_cxx_template_keyword_if_needed (pp, scope, t);
253 pp_cxx_unqualified_id (pp, t);
254 pp_cxx_colon_colon (pp);
258 /* qualified-id:
259 nested-name-specifier template(opt) unqualified-id */
261 static void
262 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
264 switch (TREE_CODE (t))
266 /* A pointer-to-member is always qualified. */
267 case PTRMEM_CST:
268 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
269 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
270 break;
272 /* In Standard C++, functions cannot possibly be used as
273 nested-name-specifiers. However, there are situations where
274 is "makes sense" to output the surrounding function name for the
275 purpose of emphasizing on the scope kind. Just printing the
276 function name might not be sufficient as it may be overloaded; so,
277 we decorate the function with its signature too.
278 FIXME: This is probably the wrong pretty-printing for conversion
279 functions and some function templates. */
280 case OVERLOAD:
281 t = OVL_CURRENT (t);
282 case FUNCTION_DECL:
283 if (DECL_FUNCTION_MEMBER_P (t))
284 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
285 pp_cxx_unqualified_id
286 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
287 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
288 break;
290 case OFFSET_REF:
291 case SCOPE_REF:
292 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
293 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
294 break;
296 default:
298 tree scope = get_containing_scope (t);
299 if (scope != pp->enclosing_scope)
301 pp_cxx_nested_name_specifier (pp, scope);
302 pp_cxx_template_keyword_if_needed (pp, scope, t);
304 pp_cxx_unqualified_id (pp, t);
306 break;
311 void
312 cxx_pretty_printer::constant (tree t)
314 switch (TREE_CODE (t))
316 case STRING_CST:
318 const bool in_parens = PAREN_STRING_LITERAL_P (t);
319 if (in_parens)
320 pp_cxx_left_paren (this);
321 c_pretty_printer::constant (t);
322 if (in_parens)
323 pp_cxx_right_paren (this);
325 break;
327 case INTEGER_CST:
328 if (NULLPTR_TYPE_P (TREE_TYPE (t)))
330 pp_string (this, "nullptr");
331 break;
333 /* else fall through. */
335 default:
336 c_pretty_printer::constant (t);
337 break;
341 /* id-expression:
342 unqualified-id
343 qualified-id */
345 void
346 cxx_pretty_printer::id_expression (tree t)
348 if (TREE_CODE (t) == OVERLOAD)
349 t = OVL_CURRENT (t);
350 if (DECL_P (t) && DECL_CONTEXT (t))
351 pp_cxx_qualified_id (this, t);
352 else
353 pp_cxx_unqualified_id (this, t);
356 /* user-defined literal:
357 literal ud-suffix */
359 void
360 pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
362 pp->constant (USERDEF_LITERAL_VALUE (t));
363 pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
367 /* primary-expression:
368 literal
369 this
370 :: identifier
371 :: operator-function-id
372 :: qualifier-id
373 ( expression )
374 id-expression
376 GNU Extensions:
377 __builtin_va_arg ( assignment-expression , type-id )
378 __builtin_offsetof ( type-id, offsetof-expression )
380 __has_nothrow_assign ( type-id )
381 __has_nothrow_constructor ( type-id )
382 __has_nothrow_copy ( type-id )
383 __has_trivial_assign ( type-id )
384 __has_trivial_constructor ( type-id )
385 __has_trivial_copy ( type-id )
386 __has_trivial_destructor ( type-id )
387 __has_virtual_destructor ( type-id )
388 __is_abstract ( type-id )
389 __is_base_of ( type-id , type-id )
390 __is_class ( type-id )
391 __is_empty ( type-id )
392 __is_enum ( type-id )
393 __is_literal_type ( type-id )
394 __is_pod ( type-id )
395 __is_polymorphic ( type-id )
396 __is_std_layout ( type-id )
397 __is_trivial ( type-id )
398 __is_union ( type-id ) */
400 void
401 cxx_pretty_printer::primary_expression (tree t)
403 switch (TREE_CODE (t))
405 case VOID_CST:
406 case INTEGER_CST:
407 case REAL_CST:
408 case COMPLEX_CST:
409 case STRING_CST:
410 constant (t);
411 break;
413 case USERDEF_LITERAL:
414 pp_cxx_userdef_literal (this, t);
415 break;
417 case BASELINK:
418 t = BASELINK_FUNCTIONS (t);
419 case VAR_DECL:
420 case PARM_DECL:
421 case FIELD_DECL:
422 case FUNCTION_DECL:
423 case OVERLOAD:
424 case CONST_DECL:
425 case TEMPLATE_DECL:
426 id_expression (t);
427 break;
429 case RESULT_DECL:
430 case TEMPLATE_TYPE_PARM:
431 case TEMPLATE_TEMPLATE_PARM:
432 case TEMPLATE_PARM_INDEX:
433 pp_cxx_unqualified_id (this, t);
434 break;
436 case STMT_EXPR:
437 pp_cxx_left_paren (this);
438 statement (STMT_EXPR_STMT (t));
439 pp_cxx_right_paren (this);
440 break;
442 case TRAIT_EXPR:
443 pp_cxx_trait_expression (this, t);
444 break;
446 case VA_ARG_EXPR:
447 pp_cxx_va_arg_expression (this, t);
448 break;
450 case OFFSETOF_EXPR:
451 pp_cxx_offsetof_expression (this, t);
452 break;
454 default:
455 c_pretty_printer::primary_expression (t);
456 break;
460 /* postfix-expression:
461 primary-expression
462 postfix-expression [ expression ]
463 postfix-expression ( expression-list(opt) )
464 simple-type-specifier ( expression-list(opt) )
465 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
466 typename ::(opt) nested-name-specifier template(opt)
467 template-id ( expression-list(opt) )
468 postfix-expression . template(opt) ::(opt) id-expression
469 postfix-expression -> template(opt) ::(opt) id-expression
470 postfix-expression . pseudo-destructor-name
471 postfix-expression -> pseudo-destructor-name
472 postfix-expression ++
473 postfix-expression --
474 dynamic_cast < type-id > ( expression )
475 static_cast < type-id > ( expression )
476 reinterpret_cast < type-id > ( expression )
477 const_cast < type-id > ( expression )
478 typeid ( expression )
479 typeid ( type-id ) */
481 void
482 cxx_pretty_printer::postfix_expression (tree t)
484 enum tree_code code = TREE_CODE (t);
486 switch (code)
488 case AGGR_INIT_EXPR:
489 case CALL_EXPR:
491 tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
492 : CALL_EXPR_FN (t));
493 tree saved_scope = enclosing_scope;
494 bool skipfirst = false;
495 tree arg;
497 if (TREE_CODE (fun) == ADDR_EXPR)
498 fun = TREE_OPERAND (fun, 0);
500 /* In templates, where there is no way to tell whether a given
501 call uses an actual member function. So the parser builds
502 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
503 instantiation time. */
504 if (TREE_CODE (fun) != FUNCTION_DECL)
506 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
508 tree object = (code == AGGR_INIT_EXPR
509 ? (AGGR_INIT_VIA_CTOR_P (t)
510 ? AGGR_INIT_EXPR_SLOT (t)
511 : AGGR_INIT_EXPR_ARG (t, 0))
512 : CALL_EXPR_ARG (t, 0));
514 while (TREE_CODE (object) == NOP_EXPR)
515 object = TREE_OPERAND (object, 0);
517 if (TREE_CODE (object) == ADDR_EXPR)
518 object = TREE_OPERAND (object, 0);
520 if (!TYPE_PTR_P (TREE_TYPE (object)))
522 postfix_expression (object);
523 pp_cxx_dot (this);
525 else
527 postfix_expression (object);
528 pp_cxx_arrow (this);
530 skipfirst = true;
531 enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
534 postfix_expression (fun);
535 enclosing_scope = saved_scope;
536 pp_cxx_left_paren (this);
537 if (code == AGGR_INIT_EXPR)
539 aggr_init_expr_arg_iterator iter;
540 FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
542 if (skipfirst)
543 skipfirst = false;
544 else
546 expression (arg);
547 if (more_aggr_init_expr_args_p (&iter))
548 pp_cxx_separate_with (this, ',');
552 else
554 call_expr_arg_iterator iter;
555 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
557 if (skipfirst)
558 skipfirst = false;
559 else
561 expression (arg);
562 if (more_call_expr_args_p (&iter))
563 pp_cxx_separate_with (this, ',');
567 pp_cxx_right_paren (this);
569 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
571 pp_cxx_separate_with (this, ',');
572 postfix_expression (AGGR_INIT_EXPR_SLOT (t));
574 break;
576 case BASELINK:
577 case VAR_DECL:
578 case PARM_DECL:
579 case FIELD_DECL:
580 case FUNCTION_DECL:
581 case OVERLOAD:
582 case CONST_DECL:
583 case TEMPLATE_DECL:
584 case RESULT_DECL:
585 primary_expression (t);
586 break;
588 case DYNAMIC_CAST_EXPR:
589 case STATIC_CAST_EXPR:
590 case REINTERPRET_CAST_EXPR:
591 case CONST_CAST_EXPR:
592 if (code == DYNAMIC_CAST_EXPR)
593 pp_cxx_ws_string (this, "dynamic_cast");
594 else if (code == STATIC_CAST_EXPR)
595 pp_cxx_ws_string (this, "static_cast");
596 else if (code == REINTERPRET_CAST_EXPR)
597 pp_cxx_ws_string (this, "reinterpret_cast");
598 else
599 pp_cxx_ws_string (this, "const_cast");
600 pp_cxx_begin_template_argument_list (this);
601 type_id (TREE_TYPE (t));
602 pp_cxx_end_template_argument_list (this);
603 pp_left_paren (this);
604 expression (TREE_OPERAND (t, 0));
605 pp_right_paren (this);
606 break;
608 case EMPTY_CLASS_EXPR:
609 type_id (TREE_TYPE (t));
610 pp_left_paren (this);
611 pp_right_paren (this);
612 break;
614 case TYPEID_EXPR:
615 pp_cxx_typeid_expression (this, t);
616 break;
618 case PSEUDO_DTOR_EXPR:
619 postfix_expression (TREE_OPERAND (t, 0));
620 pp_cxx_dot (this);
621 if (TREE_OPERAND (t, 1))
623 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
624 pp_cxx_colon_colon (this);
626 pp_complement (this);
627 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
628 break;
630 case ARROW_EXPR:
631 postfix_expression (TREE_OPERAND (t, 0));
632 pp_cxx_arrow (this);
633 break;
635 default:
636 c_pretty_printer::postfix_expression (t);
637 break;
641 /* new-expression:
642 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
643 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
645 new-placement:
646 ( expression-list )
648 new-type-id:
649 type-specifier-seq new-declarator(opt)
651 new-declarator:
652 ptr-operator new-declarator(opt)
653 direct-new-declarator
655 direct-new-declarator
656 [ expression ]
657 direct-new-declarator [ constant-expression ]
659 new-initializer:
660 ( expression-list(opt) ) */
662 static void
663 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
665 enum tree_code code = TREE_CODE (t);
666 tree type = TREE_OPERAND (t, 1);
667 tree init = TREE_OPERAND (t, 2);
668 switch (code)
670 case NEW_EXPR:
671 case VEC_NEW_EXPR:
672 if (NEW_EXPR_USE_GLOBAL (t))
673 pp_cxx_colon_colon (pp);
674 pp_cxx_ws_string (pp, "new");
675 if (TREE_OPERAND (t, 0))
677 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
678 pp_space (pp);
680 if (TREE_CODE (type) == ARRAY_REF)
681 type = build_cplus_array_type
682 (TREE_OPERAND (type, 0),
683 build_index_type (fold_build2_loc (input_location,
684 MINUS_EXPR, integer_type_node,
685 TREE_OPERAND (type, 1),
686 integer_one_node)));
687 pp->type_id (type);
688 if (init)
690 pp_left_paren (pp);
691 if (TREE_CODE (init) == TREE_LIST)
692 pp_c_expression_list (pp, init);
693 else if (init == void_node)
694 ; /* OK, empty initializer list. */
695 else
696 pp->expression (init);
697 pp_right_paren (pp);
699 break;
701 default:
702 pp_unsupported_tree (pp, t);
706 /* delete-expression:
707 ::(opt) delete cast-expression
708 ::(opt) delete [ ] cast-expression */
710 static void
711 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
713 enum tree_code code = TREE_CODE (t);
714 switch (code)
716 case DELETE_EXPR:
717 case VEC_DELETE_EXPR:
718 if (DELETE_EXPR_USE_GLOBAL (t))
719 pp_cxx_colon_colon (pp);
720 pp_cxx_ws_string (pp, "delete");
721 pp_space (pp);
722 if (code == VEC_DELETE_EXPR
723 || DELETE_EXPR_USE_VEC (t))
725 pp_left_bracket (pp);
726 pp_right_bracket (pp);
727 pp_space (pp);
729 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
730 break;
732 default:
733 pp_unsupported_tree (pp, t);
737 /* unary-expression:
738 postfix-expression
739 ++ cast-expression
740 -- cast-expression
741 unary-operator cast-expression
742 sizeof unary-expression
743 sizeof ( type-id )
744 sizeof ... ( identifier )
745 new-expression
746 delete-expression
748 unary-operator: one of
749 * & + - !
751 GNU extensions:
752 __alignof__ unary-expression
753 __alignof__ ( type-id ) */
755 void
756 cxx_pretty_printer::unary_expression (tree t)
758 enum tree_code code = TREE_CODE (t);
759 switch (code)
761 case NEW_EXPR:
762 case VEC_NEW_EXPR:
763 pp_cxx_new_expression (this, t);
764 break;
766 case DELETE_EXPR:
767 case VEC_DELETE_EXPR:
768 pp_cxx_delete_expression (this, t);
769 break;
771 case SIZEOF_EXPR:
772 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
774 pp_cxx_ws_string (this, "sizeof");
775 pp_cxx_ws_string (this, "...");
776 pp_cxx_whitespace (this);
777 pp_cxx_left_paren (this);
778 if (TYPE_P (TREE_OPERAND (t, 0)))
779 type_id (TREE_OPERAND (t, 0));
780 else
781 unary_expression (TREE_OPERAND (t, 0));
782 pp_cxx_right_paren (this);
783 break;
785 /* Fall through */
787 case ALIGNOF_EXPR:
788 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
789 pp_cxx_whitespace (this);
790 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
792 pp_cxx_left_paren (this);
793 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
794 pp_cxx_right_paren (this);
796 else if (TYPE_P (TREE_OPERAND (t, 0)))
798 pp_cxx_left_paren (this);
799 type_id (TREE_OPERAND (t, 0));
800 pp_cxx_right_paren (this);
802 else
803 unary_expression (TREE_OPERAND (t, 0));
804 break;
806 case AT_ENCODE_EXPR:
807 pp_cxx_ws_string (this, "@encode");
808 pp_cxx_whitespace (this);
809 pp_cxx_left_paren (this);
810 type_id (TREE_OPERAND (t, 0));
811 pp_cxx_right_paren (this);
812 break;
814 case NOEXCEPT_EXPR:
815 pp_cxx_ws_string (this, "noexcept");
816 pp_cxx_whitespace (this);
817 pp_cxx_left_paren (this);
818 expression (TREE_OPERAND (t, 0));
819 pp_cxx_right_paren (this);
820 break;
822 case UNARY_PLUS_EXPR:
823 pp_plus (this);
824 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
825 break;
827 default:
828 c_pretty_printer::unary_expression (t);
829 break;
833 /* cast-expression:
834 unary-expression
835 ( type-id ) cast-expression */
837 static void
838 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
840 switch (TREE_CODE (t))
842 case CAST_EXPR:
843 case IMPLICIT_CONV_EXPR:
844 pp->type_id (TREE_TYPE (t));
845 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
846 break;
848 default:
849 pp_c_cast_expression (pp, t);
850 break;
854 /* pm-expression:
855 cast-expression
856 pm-expression .* cast-expression
857 pm-expression ->* cast-expression */
859 static void
860 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
862 switch (TREE_CODE (t))
864 /* Handle unfortunate OFFSET_REF overloading here. */
865 case OFFSET_REF:
866 if (TYPE_P (TREE_OPERAND (t, 0)))
868 pp_cxx_qualified_id (pp, t);
869 break;
871 /* Else fall through. */
872 case MEMBER_REF:
873 case DOTSTAR_EXPR:
874 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
875 if (TREE_CODE (t) == MEMBER_REF)
876 pp_cxx_arrow (pp);
877 else
878 pp_cxx_dot (pp);
879 pp_star(pp);
880 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
881 break;
884 default:
885 pp_cxx_cast_expression (pp, t);
886 break;
890 /* multiplicative-expression:
891 pm-expression
892 multiplicative-expression * pm-expression
893 multiplicative-expression / pm-expression
894 multiplicative-expression % pm-expression */
896 void
897 cxx_pretty_printer::multiplicative_expression (tree e)
899 enum tree_code code = TREE_CODE (e);
900 switch (code)
902 case MULT_EXPR:
903 case TRUNC_DIV_EXPR:
904 case TRUNC_MOD_EXPR:
905 multiplicative_expression (TREE_OPERAND (e, 0));
906 pp_space (this);
907 if (code == MULT_EXPR)
908 pp_star (this);
909 else if (code == TRUNC_DIV_EXPR)
910 pp_slash (this);
911 else
912 pp_modulo (this);
913 pp_space (this);
914 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
915 break;
917 default:
918 pp_cxx_pm_expression (this, e);
919 break;
923 /* conditional-expression:
924 logical-or-expression
925 logical-or-expression ? expression : assignment-expression */
927 void
928 cxx_pretty_printer::conditional_expression (tree e)
930 if (TREE_CODE (e) == COND_EXPR)
932 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
933 pp_space (this);
934 pp_question (this);
935 pp_space (this);
936 expression (TREE_OPERAND (e, 1));
937 pp_space (this);
938 assignment_expression (TREE_OPERAND (e, 2));
940 else
941 pp_c_logical_or_expression (this, e);
944 /* Pretty-print a compound assignment operator token as indicated by T. */
946 static void
947 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
949 const char *op;
951 switch (TREE_CODE (t))
953 case NOP_EXPR:
954 op = "=";
955 break;
957 case PLUS_EXPR:
958 op = "+=";
959 break;
961 case MINUS_EXPR:
962 op = "-=";
963 break;
965 case TRUNC_DIV_EXPR:
966 op = "/=";
967 break;
969 case TRUNC_MOD_EXPR:
970 op = "%=";
971 break;
973 default:
974 op = get_tree_code_name (TREE_CODE (t));
975 break;
978 pp_cxx_ws_string (pp, op);
982 /* assignment-expression:
983 conditional-expression
984 logical-or-expression assignment-operator assignment-expression
985 throw-expression
987 throw-expression:
988 throw assignment-expression(opt)
990 assignment-operator: one of
991 = *= /= %= += -= >>= <<= &= ^= |= */
993 void
994 cxx_pretty_printer::assignment_expression (tree e)
996 switch (TREE_CODE (e))
998 case MODIFY_EXPR:
999 case INIT_EXPR:
1000 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1001 pp_space (this);
1002 pp_equal (this);
1003 pp_space (this);
1004 assignment_expression (TREE_OPERAND (e, 1));
1005 break;
1007 case THROW_EXPR:
1008 pp_cxx_ws_string (this, "throw");
1009 if (TREE_OPERAND (e, 0))
1010 assignment_expression (TREE_OPERAND (e, 0));
1011 break;
1013 case MODOP_EXPR:
1014 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1015 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1016 assignment_expression (TREE_OPERAND (e, 2));
1017 break;
1019 default:
1020 conditional_expression (e);
1021 break;
1025 void
1026 cxx_pretty_printer::expression (tree t)
1028 switch (TREE_CODE (t))
1030 case STRING_CST:
1031 case VOID_CST:
1032 case INTEGER_CST:
1033 case REAL_CST:
1034 case COMPLEX_CST:
1035 constant (t);
1036 break;
1038 case USERDEF_LITERAL:
1039 pp_cxx_userdef_literal (this, t);
1040 break;
1042 case RESULT_DECL:
1043 pp_cxx_unqualified_id (this, t);
1044 break;
1046 #if 0
1047 case OFFSET_REF:
1048 #endif
1049 case SCOPE_REF:
1050 case PTRMEM_CST:
1051 pp_cxx_qualified_id (this, t);
1052 break;
1054 case OVERLOAD:
1055 t = OVL_CURRENT (t);
1056 case VAR_DECL:
1057 case PARM_DECL:
1058 case FIELD_DECL:
1059 case CONST_DECL:
1060 case FUNCTION_DECL:
1061 case BASELINK:
1062 case TEMPLATE_DECL:
1063 case TEMPLATE_TYPE_PARM:
1064 case TEMPLATE_PARM_INDEX:
1065 case TEMPLATE_TEMPLATE_PARM:
1066 case STMT_EXPR:
1067 primary_expression (t);
1068 break;
1070 case CALL_EXPR:
1071 case DYNAMIC_CAST_EXPR:
1072 case STATIC_CAST_EXPR:
1073 case REINTERPRET_CAST_EXPR:
1074 case CONST_CAST_EXPR:
1075 #if 0
1076 case MEMBER_REF:
1077 #endif
1078 case EMPTY_CLASS_EXPR:
1079 case TYPEID_EXPR:
1080 case PSEUDO_DTOR_EXPR:
1081 case AGGR_INIT_EXPR:
1082 case ARROW_EXPR:
1083 postfix_expression (t);
1084 break;
1086 case NEW_EXPR:
1087 case VEC_NEW_EXPR:
1088 pp_cxx_new_expression (this, t);
1089 break;
1091 case DELETE_EXPR:
1092 case VEC_DELETE_EXPR:
1093 pp_cxx_delete_expression (this, t);
1094 break;
1096 case SIZEOF_EXPR:
1097 case ALIGNOF_EXPR:
1098 case NOEXCEPT_EXPR:
1099 unary_expression (t);
1100 break;
1102 case CAST_EXPR:
1103 case IMPLICIT_CONV_EXPR:
1104 pp_cxx_cast_expression (this, t);
1105 break;
1107 case OFFSET_REF:
1108 case MEMBER_REF:
1109 case DOTSTAR_EXPR:
1110 pp_cxx_pm_expression (this, t);
1111 break;
1113 case MULT_EXPR:
1114 case TRUNC_DIV_EXPR:
1115 case TRUNC_MOD_EXPR:
1116 multiplicative_expression (t);
1117 break;
1119 case COND_EXPR:
1120 conditional_expression (t);
1121 break;
1123 case MODIFY_EXPR:
1124 case INIT_EXPR:
1125 case THROW_EXPR:
1126 case MODOP_EXPR:
1127 assignment_expression (t);
1128 break;
1130 case NON_DEPENDENT_EXPR:
1131 case MUST_NOT_THROW_EXPR:
1132 expression (TREE_OPERAND (t, 0));
1133 break;
1135 case EXPR_PACK_EXPANSION:
1136 expression (PACK_EXPANSION_PATTERN (t));
1137 pp_cxx_ws_string (this, "...");
1138 break;
1140 case TEMPLATE_ID_EXPR:
1141 pp_cxx_template_id (this, t);
1142 break;
1144 case NONTYPE_ARGUMENT_PACK:
1146 tree args = ARGUMENT_PACK_ARGS (t);
1147 int i, len = TREE_VEC_LENGTH (args);
1148 for (i = 0; i < len; ++i)
1150 if (i > 0)
1151 pp_cxx_separate_with (this, ',');
1152 expression (TREE_VEC_ELT (args, i));
1155 break;
1157 case LAMBDA_EXPR:
1158 pp_cxx_ws_string (this, "<lambda>");
1159 break;
1161 case PAREN_EXPR:
1162 pp_cxx_left_paren (this);
1163 expression (TREE_OPERAND (t, 0));
1164 pp_cxx_right_paren (this);
1165 break;
1167 default:
1168 c_pretty_printer::expression (t);
1169 break;
1174 /* Declarations. */
1176 /* function-specifier:
1177 inline
1178 virtual
1179 explicit */
1181 void
1182 cxx_pretty_printer::function_specifier (tree t)
1184 switch (TREE_CODE (t))
1186 case FUNCTION_DECL:
1187 if (DECL_VIRTUAL_P (t))
1188 pp_cxx_ws_string (this, "virtual");
1189 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1190 pp_cxx_ws_string (this, "explicit");
1191 else
1192 c_pretty_printer::function_specifier (t);
1194 default:
1195 break;
1199 /* decl-specifier-seq:
1200 decl-specifier-seq(opt) decl-specifier
1202 decl-specifier:
1203 storage-class-specifier
1204 type-specifier
1205 function-specifier
1206 friend
1207 typedef */
1209 void
1210 cxx_pretty_printer::declaration_specifiers (tree t)
1212 switch (TREE_CODE (t))
1214 case VAR_DECL:
1215 case PARM_DECL:
1216 case CONST_DECL:
1217 case FIELD_DECL:
1218 storage_class_specifier (t);
1219 declaration_specifiers (TREE_TYPE (t));
1220 break;
1222 case TYPE_DECL:
1223 pp_cxx_ws_string (this, "typedef");
1224 declaration_specifiers (TREE_TYPE (t));
1225 break;
1227 case FUNCTION_DECL:
1228 /* Constructors don't have return types. And conversion functions
1229 do not have a type-specifier in their return types. */
1230 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1231 function_specifier (t);
1232 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1233 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1234 else
1235 default:
1236 c_pretty_printer::declaration_specifiers (t);
1237 break;
1241 /* simple-type-specifier:
1242 ::(opt) nested-name-specifier(opt) type-name
1243 ::(opt) nested-name-specifier(opt) template(opt) template-id
1244 char
1245 wchar_t
1246 bool
1247 short
1249 long
1250 signed
1251 unsigned
1252 float
1253 double
1254 void */
1256 void
1257 cxx_pretty_printer::simple_type_specifier (tree t)
1259 switch (TREE_CODE (t))
1261 case RECORD_TYPE:
1262 case UNION_TYPE:
1263 case ENUMERAL_TYPE:
1264 pp_cxx_qualified_id (this, t);
1265 break;
1267 case TEMPLATE_TYPE_PARM:
1268 case TEMPLATE_TEMPLATE_PARM:
1269 case TEMPLATE_PARM_INDEX:
1270 case BOUND_TEMPLATE_TEMPLATE_PARM:
1271 pp_cxx_unqualified_id (this, t);
1272 break;
1274 case TYPENAME_TYPE:
1275 pp_cxx_ws_string (this, "typename");
1276 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1277 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1278 break;
1280 default:
1281 c_pretty_printer::simple_type_specifier (t);
1282 break;
1286 /* type-specifier-seq:
1287 type-specifier type-specifier-seq(opt)
1289 type-specifier:
1290 simple-type-specifier
1291 class-specifier
1292 enum-specifier
1293 elaborated-type-specifier
1294 cv-qualifier */
1296 static void
1297 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1299 switch (TREE_CODE (t))
1301 case TEMPLATE_DECL:
1302 case TEMPLATE_TYPE_PARM:
1303 case TEMPLATE_TEMPLATE_PARM:
1304 case TYPE_DECL:
1305 case BOUND_TEMPLATE_TEMPLATE_PARM:
1306 pp_cxx_cv_qualifier_seq (pp, t);
1307 pp->simple_type_specifier (t);
1308 break;
1310 case METHOD_TYPE:
1311 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1312 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1313 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1314 break;
1316 case DECLTYPE_TYPE:
1317 pp_cxx_ws_string (pp, "decltype");
1318 pp_cxx_left_paren (pp);
1319 pp->expression (DECLTYPE_TYPE_EXPR (t));
1320 pp_cxx_right_paren (pp);
1321 break;
1323 case RECORD_TYPE:
1324 if (TYPE_PTRMEMFUNC_P (t))
1326 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1327 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1328 pp_cxx_whitespace (pp);
1329 pp_cxx_ptr_operator (pp, t);
1330 break;
1332 /* else fall through */
1334 default:
1335 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1336 pp_c_specifier_qualifier_list (pp, t);
1340 /* ptr-operator:
1341 * cv-qualifier-seq(opt)
1343 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1345 static void
1346 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1348 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1349 t = TREE_TYPE (t);
1350 switch (TREE_CODE (t))
1352 case REFERENCE_TYPE:
1353 case POINTER_TYPE:
1354 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1355 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1356 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1357 if (TYPE_PTR_P (t))
1359 pp_star (pp);
1360 pp_cxx_cv_qualifier_seq (pp, t);
1362 else
1363 pp_ampersand (pp);
1364 break;
1366 case RECORD_TYPE:
1367 if (TYPE_PTRMEMFUNC_P (t))
1369 pp_cxx_left_paren (pp);
1370 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1371 pp_star (pp);
1372 break;
1374 case OFFSET_TYPE:
1375 if (TYPE_PTRMEM_P (t))
1377 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1378 pp_cxx_left_paren (pp);
1379 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1380 pp_star (pp);
1381 pp_cxx_cv_qualifier_seq (pp, t);
1382 break;
1384 /* else fall through. */
1386 default:
1387 pp_unsupported_tree (pp, t);
1388 break;
1392 static inline tree
1393 pp_cxx_implicit_parameter_type (tree mf)
1395 return class_of_this_parm (TREE_TYPE (mf));
1399 parameter-declaration:
1400 decl-specifier-seq declarator
1401 decl-specifier-seq declarator = assignment-expression
1402 decl-specifier-seq abstract-declarator(opt)
1403 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1405 static inline void
1406 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1408 pp->declaration_specifiers (t);
1409 if (TYPE_P (t))
1410 pp->abstract_declarator (t);
1411 else
1412 pp->declarator (t);
1415 /* parameter-declaration-clause:
1416 parameter-declaration-list(opt) ...(opt)
1417 parameter-declaration-list , ...
1419 parameter-declaration-list:
1420 parameter-declaration
1421 parameter-declaration-list , parameter-declaration */
1423 static void
1424 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1426 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1427 tree types =
1428 TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1429 const bool abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1430 bool first = true;
1432 /* Skip artificial parameter for nonstatic member functions. */
1433 if (TREE_CODE (t) == METHOD_TYPE)
1434 types = TREE_CHAIN (types);
1436 pp_cxx_left_paren (pp);
1437 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1439 if (!first)
1440 pp_cxx_separate_with (pp, ',');
1441 first = false;
1442 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1443 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1445 pp_cxx_whitespace (pp);
1446 pp_equal (pp);
1447 pp_cxx_whitespace (pp);
1448 pp->assignment_expression (TREE_PURPOSE (types));
1451 pp_cxx_right_paren (pp);
1454 /* exception-specification:
1455 throw ( type-id-list(opt) )
1457 type-id-list
1458 type-id
1459 type-id-list , type-id */
1461 static void
1462 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1464 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1465 bool need_comma = false;
1467 if (ex_spec == NULL)
1468 return;
1469 if (TREE_PURPOSE (ex_spec))
1471 pp_cxx_ws_string (pp, "noexcept");
1472 pp_cxx_whitespace (pp);
1473 pp_cxx_left_paren (pp);
1474 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1475 pp_cxx_ws_string (pp, "<uninstantiated>");
1476 else
1477 pp->expression (TREE_PURPOSE (ex_spec));
1478 pp_cxx_right_paren (pp);
1479 return;
1481 pp_cxx_ws_string (pp, "throw");
1482 pp_cxx_left_paren (pp);
1483 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1485 tree type = TREE_VALUE (ex_spec);
1486 tree argpack = NULL_TREE;
1487 int i, len = 1;
1489 if (ARGUMENT_PACK_P (type))
1491 argpack = ARGUMENT_PACK_ARGS (type);
1492 len = TREE_VEC_LENGTH (argpack);
1495 for (i = 0; i < len; ++i)
1497 if (argpack)
1498 type = TREE_VEC_ELT (argpack, i);
1500 if (need_comma)
1501 pp_cxx_separate_with (pp, ',');
1502 else
1503 need_comma = true;
1505 pp->type_id (type);
1508 pp_cxx_right_paren (pp);
1511 /* direct-declarator:
1512 declarator-id
1513 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1514 exception-specification(opt)
1515 direct-declaration [ constant-expression(opt) ]
1516 ( declarator ) */
1518 void
1519 cxx_pretty_printer::direct_declarator (tree t)
1521 switch (TREE_CODE (t))
1523 case VAR_DECL:
1524 case PARM_DECL:
1525 case CONST_DECL:
1526 case FIELD_DECL:
1527 if (DECL_NAME (t))
1529 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1531 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1532 || template_parameter_pack_p (t))
1533 /* A function parameter pack or non-type template
1534 parameter pack. */
1535 pp_cxx_ws_string (this, "...");
1537 id_expression (DECL_NAME (t));
1539 abstract_declarator (TREE_TYPE (t));
1540 break;
1542 case FUNCTION_DECL:
1543 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1544 expression (t);
1545 pp_cxx_parameter_declaration_clause (this, t);
1547 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1549 padding = pp_before;
1550 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1553 pp_cxx_exception_specification (this, TREE_TYPE (t));
1554 break;
1556 case TYPENAME_TYPE:
1557 case TEMPLATE_DECL:
1558 case TEMPLATE_TYPE_PARM:
1559 case TEMPLATE_PARM_INDEX:
1560 case TEMPLATE_TEMPLATE_PARM:
1561 break;
1563 default:
1564 c_pretty_printer::direct_declarator (t);
1565 break;
1569 /* declarator:
1570 direct-declarator
1571 ptr-operator declarator */
1573 void
1574 cxx_pretty_printer::declarator (tree t)
1576 direct_declarator (t);
1579 /* ctor-initializer:
1580 : mem-initializer-list
1582 mem-initializer-list:
1583 mem-initializer
1584 mem-initializer , mem-initializer-list
1586 mem-initializer:
1587 mem-initializer-id ( expression-list(opt) )
1589 mem-initializer-id:
1590 ::(opt) nested-name-specifier(opt) class-name
1591 identifier */
1593 static void
1594 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1596 t = TREE_OPERAND (t, 0);
1597 pp_cxx_whitespace (pp);
1598 pp_colon (pp);
1599 pp_cxx_whitespace (pp);
1600 for (; t; t = TREE_CHAIN (t))
1602 tree purpose = TREE_PURPOSE (t);
1603 bool is_pack = PACK_EXPANSION_P (purpose);
1605 if (is_pack)
1606 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1607 else
1608 pp->primary_expression (purpose);
1609 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1610 if (is_pack)
1611 pp_cxx_ws_string (pp, "...");
1612 if (TREE_CHAIN (t))
1613 pp_cxx_separate_with (pp, ',');
1617 /* function-definition:
1618 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1619 decl-specifier-seq(opt) declarator function-try-block */
1621 static void
1622 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1624 tree saved_scope = pp->enclosing_scope;
1625 pp->declaration_specifiers (t);
1626 pp->declarator (t);
1627 pp_needs_newline (pp) = true;
1628 pp->enclosing_scope = DECL_CONTEXT (t);
1629 if (DECL_SAVED_TREE (t))
1630 pp->statement (DECL_SAVED_TREE (t));
1631 else
1632 pp_cxx_semicolon (pp);
1633 pp_newline_and_flush (pp);
1634 pp->enclosing_scope = saved_scope;
1637 /* abstract-declarator:
1638 ptr-operator abstract-declarator(opt)
1639 direct-abstract-declarator */
1641 void
1642 cxx_pretty_printer::abstract_declarator (tree t)
1644 if (TYPE_PTRMEM_P (t))
1645 pp_cxx_right_paren (this);
1646 else if (POINTER_TYPE_P (t))
1648 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1649 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1650 pp_cxx_right_paren (this);
1651 t = TREE_TYPE (t);
1653 direct_abstract_declarator (t);
1656 /* direct-abstract-declarator:
1657 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1658 cv-qualifier-seq(opt) exception-specification(opt)
1659 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1660 ( abstract-declarator ) */
1662 void
1663 cxx_pretty_printer::direct_abstract_declarator (tree t)
1665 switch (TREE_CODE (t))
1667 case REFERENCE_TYPE:
1668 abstract_declarator (t);
1669 break;
1671 case RECORD_TYPE:
1672 if (TYPE_PTRMEMFUNC_P (t))
1673 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1674 break;
1676 case METHOD_TYPE:
1677 case FUNCTION_TYPE:
1678 pp_cxx_parameter_declaration_clause (this, t);
1679 direct_abstract_declarator (TREE_TYPE (t));
1680 if (TREE_CODE (t) == METHOD_TYPE)
1682 padding = pp_before;
1683 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1685 pp_cxx_exception_specification (this, t);
1686 break;
1688 case TYPENAME_TYPE:
1689 case TEMPLATE_TYPE_PARM:
1690 case TEMPLATE_TEMPLATE_PARM:
1691 case BOUND_TEMPLATE_TEMPLATE_PARM:
1692 case UNBOUND_CLASS_TEMPLATE:
1693 break;
1695 default:
1696 c_pretty_printer::direct_abstract_declarator (t);
1697 break;
1701 /* type-id:
1702 type-specifier-seq abstract-declarator(opt) */
1704 void
1705 cxx_pretty_printer::type_id (tree t)
1707 pp_flags saved_flags = flags;
1708 flags |= pp_c_flag_abstract;
1710 switch (TREE_CODE (t))
1712 case TYPE_DECL:
1713 case UNION_TYPE:
1714 case RECORD_TYPE:
1715 case ENUMERAL_TYPE:
1716 case TYPENAME_TYPE:
1717 case BOUND_TEMPLATE_TEMPLATE_PARM:
1718 case UNBOUND_CLASS_TEMPLATE:
1719 case TEMPLATE_TEMPLATE_PARM:
1720 case TEMPLATE_TYPE_PARM:
1721 case TEMPLATE_PARM_INDEX:
1722 case TEMPLATE_DECL:
1723 case TYPEOF_TYPE:
1724 case UNDERLYING_TYPE:
1725 case DECLTYPE_TYPE:
1726 case TEMPLATE_ID_EXPR:
1727 pp_cxx_type_specifier_seq (this, t);
1728 break;
1730 case TYPE_PACK_EXPANSION:
1731 type_id (PACK_EXPANSION_PATTERN (t));
1732 pp_cxx_ws_string (this, "...");
1733 break;
1735 default:
1736 c_pretty_printer::type_id (t);
1737 break;
1740 flags = saved_flags;
1743 /* template-argument-list:
1744 template-argument ...(opt)
1745 template-argument-list, template-argument ...(opt)
1747 template-argument:
1748 assignment-expression
1749 type-id
1750 template-name */
1752 static void
1753 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1755 int i;
1756 bool need_comma = false;
1758 if (t == NULL)
1759 return;
1760 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1762 tree arg = TREE_VEC_ELT (t, i);
1763 tree argpack = NULL_TREE;
1764 int idx, len = 1;
1766 if (ARGUMENT_PACK_P (arg))
1768 argpack = ARGUMENT_PACK_ARGS (arg);
1769 len = TREE_VEC_LENGTH (argpack);
1772 for (idx = 0; idx < len; idx++)
1774 if (argpack)
1775 arg = TREE_VEC_ELT (argpack, idx);
1777 if (need_comma)
1778 pp_cxx_separate_with (pp, ',');
1779 else
1780 need_comma = true;
1782 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1783 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1784 pp->type_id (arg);
1785 else
1786 pp->expression (arg);
1792 static void
1793 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1795 t = DECL_EXPR_DECL (t);
1796 pp_cxx_type_specifier_seq (pp, t);
1797 if (TYPE_P (t))
1798 pp->abstract_declarator (t);
1799 else
1800 pp->declarator (t);
1803 /* Statements. */
1805 void
1806 cxx_pretty_printer::statement (tree t)
1808 switch (TREE_CODE (t))
1810 case CTOR_INITIALIZER:
1811 pp_cxx_ctor_initializer (this, t);
1812 break;
1814 case USING_STMT:
1815 pp_cxx_ws_string (this, "using");
1816 pp_cxx_ws_string (this, "namespace");
1817 if (DECL_CONTEXT (t))
1818 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1819 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1820 break;
1822 case USING_DECL:
1823 pp_cxx_ws_string (this, "using");
1824 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1825 pp_cxx_unqualified_id (this, DECL_NAME (t));
1826 break;
1828 case EH_SPEC_BLOCK:
1829 break;
1831 /* try-block:
1832 try compound-statement handler-seq */
1833 case TRY_BLOCK:
1834 pp_maybe_newline_and_indent (this, 0);
1835 pp_cxx_ws_string (this, "try");
1836 pp_newline_and_indent (this, 3);
1837 statement (TRY_STMTS (t));
1838 pp_newline_and_indent (this, -3);
1839 if (CLEANUP_P (t))
1841 else
1842 statement (TRY_HANDLERS (t));
1843 break;
1846 handler-seq:
1847 handler handler-seq(opt)
1849 handler:
1850 catch ( exception-declaration ) compound-statement
1852 exception-declaration:
1853 type-specifier-seq declarator
1854 type-specifier-seq abstract-declarator
1855 ... */
1856 case HANDLER:
1857 pp_cxx_ws_string (this, "catch");
1858 pp_cxx_left_paren (this);
1859 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1860 pp_cxx_right_paren (this);
1861 pp_indentation (this) += 3;
1862 pp_needs_newline (this) = true;
1863 statement (HANDLER_BODY (t));
1864 pp_indentation (this) -= 3;
1865 pp_needs_newline (this) = true;
1866 break;
1868 /* selection-statement:
1869 if ( expression ) statement
1870 if ( expression ) statement else statement */
1871 case IF_STMT:
1872 pp_cxx_ws_string (this, "if");
1873 pp_cxx_whitespace (this);
1874 pp_cxx_left_paren (this);
1875 expression (IF_COND (t));
1876 pp_cxx_right_paren (this);
1877 pp_newline_and_indent (this, 2);
1878 statement (THEN_CLAUSE (t));
1879 pp_newline_and_indent (this, -2);
1880 if (ELSE_CLAUSE (t))
1882 tree else_clause = ELSE_CLAUSE (t);
1883 pp_cxx_ws_string (this, "else");
1884 if (TREE_CODE (else_clause) == IF_STMT)
1885 pp_cxx_whitespace (this);
1886 else
1887 pp_newline_and_indent (this, 2);
1888 statement (else_clause);
1889 if (TREE_CODE (else_clause) != IF_STMT)
1890 pp_newline_and_indent (this, -2);
1892 break;
1894 case SWITCH_STMT:
1895 pp_cxx_ws_string (this, "switch");
1896 pp_space (this);
1897 pp_cxx_left_paren (this);
1898 expression (SWITCH_STMT_COND (t));
1899 pp_cxx_right_paren (this);
1900 pp_indentation (this) += 3;
1901 pp_needs_newline (this) = true;
1902 statement (SWITCH_STMT_BODY (t));
1903 pp_newline_and_indent (this, -3);
1904 break;
1906 /* iteration-statement:
1907 while ( expression ) statement
1908 do statement while ( expression ) ;
1909 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1910 for ( declaration expression(opt) ; expression(opt) ) statement */
1911 case WHILE_STMT:
1912 pp_cxx_ws_string (this, "while");
1913 pp_space (this);
1914 pp_cxx_left_paren (this);
1915 expression (WHILE_COND (t));
1916 pp_cxx_right_paren (this);
1917 pp_newline_and_indent (this, 3);
1918 statement (WHILE_BODY (t));
1919 pp_indentation (this) -= 3;
1920 pp_needs_newline (this) = true;
1921 break;
1923 case DO_STMT:
1924 pp_cxx_ws_string (this, "do");
1925 pp_newline_and_indent (this, 3);
1926 statement (DO_BODY (t));
1927 pp_newline_and_indent (this, -3);
1928 pp_cxx_ws_string (this, "while");
1929 pp_space (this);
1930 pp_cxx_left_paren (this);
1931 expression (DO_COND (t));
1932 pp_cxx_right_paren (this);
1933 pp_cxx_semicolon (this);
1934 pp_needs_newline (this) = true;
1935 break;
1937 case FOR_STMT:
1938 pp_cxx_ws_string (this, "for");
1939 pp_space (this);
1940 pp_cxx_left_paren (this);
1941 if (FOR_INIT_STMT (t))
1942 statement (FOR_INIT_STMT (t));
1943 else
1944 pp_cxx_semicolon (this);
1945 pp_needs_newline (this) = false;
1946 pp_cxx_whitespace (this);
1947 if (FOR_COND (t))
1948 expression (FOR_COND (t));
1949 pp_cxx_semicolon (this);
1950 pp_needs_newline (this) = false;
1951 pp_cxx_whitespace (this);
1952 if (FOR_EXPR (t))
1953 expression (FOR_EXPR (t));
1954 pp_cxx_right_paren (this);
1955 pp_newline_and_indent (this, 3);
1956 statement (FOR_BODY (t));
1957 pp_indentation (this) -= 3;
1958 pp_needs_newline (this) = true;
1959 break;
1961 case RANGE_FOR_STMT:
1962 pp_cxx_ws_string (this, "for");
1963 pp_space (this);
1964 pp_cxx_left_paren (this);
1965 statement (RANGE_FOR_DECL (t));
1966 pp_space (this);
1967 pp_needs_newline (this) = false;
1968 pp_colon (this);
1969 pp_space (this);
1970 statement (RANGE_FOR_EXPR (t));
1971 pp_cxx_right_paren (this);
1972 pp_newline_and_indent (this, 3);
1973 statement (FOR_BODY (t));
1974 pp_indentation (this) -= 3;
1975 pp_needs_newline (this) = true;
1976 break;
1978 /* jump-statement:
1979 goto identifier;
1980 continue ;
1981 return expression(opt) ; */
1982 case BREAK_STMT:
1983 case CONTINUE_STMT:
1984 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1985 pp_cxx_semicolon (this);
1986 pp_needs_newline (this) = true;
1987 break;
1989 /* expression-statement:
1990 expression(opt) ; */
1991 case EXPR_STMT:
1992 expression (EXPR_STMT_EXPR (t));
1993 pp_cxx_semicolon (this);
1994 pp_needs_newline (this) = true;
1995 break;
1997 case CLEANUP_STMT:
1998 pp_cxx_ws_string (this, "try");
1999 pp_newline_and_indent (this, 2);
2000 statement (CLEANUP_BODY (t));
2001 pp_newline_and_indent (this, -2);
2002 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2003 pp_newline_and_indent (this, 2);
2004 statement (CLEANUP_EXPR (t));
2005 pp_newline_and_indent (this, -2);
2006 break;
2008 case STATIC_ASSERT:
2009 declaration (t);
2010 break;
2012 default:
2013 c_pretty_printer::statement (t);
2014 break;
2018 /* original-namespace-definition:
2019 namespace identifier { namespace-body }
2021 As an edge case, we also handle unnamed namespace definition here. */
2023 static void
2024 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2026 pp_cxx_ws_string (pp, "namespace");
2027 if (DECL_CONTEXT (t))
2028 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2029 if (DECL_NAME (t))
2030 pp_cxx_unqualified_id (pp, t);
2031 pp_cxx_whitespace (pp);
2032 pp_cxx_left_brace (pp);
2033 /* We do not print the namespace-body. */
2034 pp_cxx_whitespace (pp);
2035 pp_cxx_right_brace (pp);
2038 /* namespace-alias:
2039 identifier
2041 namespace-alias-definition:
2042 namespace identifier = qualified-namespace-specifier ;
2044 qualified-namespace-specifier:
2045 ::(opt) nested-name-specifier(opt) namespace-name */
2047 static void
2048 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2050 pp_cxx_ws_string (pp, "namespace");
2051 if (DECL_CONTEXT (t))
2052 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2053 pp_cxx_unqualified_id (pp, t);
2054 pp_cxx_whitespace (pp);
2055 pp_equal (pp);
2056 pp_cxx_whitespace (pp);
2057 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2058 pp_cxx_nested_name_specifier (pp,
2059 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2060 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2061 pp_cxx_semicolon (pp);
2064 /* simple-declaration:
2065 decl-specifier-seq(opt) init-declarator-list(opt) */
2067 static void
2068 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2070 pp->declaration_specifiers (t);
2071 pp_cxx_init_declarator (pp, t);
2072 pp_cxx_semicolon (pp);
2073 pp_needs_newline (pp) = true;
2077 template-parameter-list:
2078 template-parameter
2079 template-parameter-list , template-parameter */
2081 static inline void
2082 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2084 const int n = TREE_VEC_LENGTH (t);
2085 int i;
2086 for (i = 0; i < n; ++i)
2088 if (i)
2089 pp_cxx_separate_with (pp, ',');
2090 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2094 /* template-parameter:
2095 type-parameter
2096 parameter-declaration
2098 type-parameter:
2099 class ...(opt) identifier(opt)
2100 class identifier(opt) = type-id
2101 typename identifier(opt)
2102 typename ...(opt) identifier(opt) = type-id
2103 template < template-parameter-list > class ...(opt) identifier(opt)
2104 template < template-parameter-list > class identifier(opt) = template-name */
2106 static void
2107 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2109 tree parameter = TREE_VALUE (t);
2110 switch (TREE_CODE (parameter))
2112 case TYPE_DECL:
2113 pp_cxx_ws_string (pp, "class");
2114 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2115 pp_cxx_ws_string (pp, "...");
2116 if (DECL_NAME (parameter))
2117 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2118 /* FIXME: Check if we should print also default argument. */
2119 break;
2121 case PARM_DECL:
2122 pp_cxx_parameter_declaration (pp, parameter);
2123 break;
2125 case TEMPLATE_DECL:
2126 break;
2128 default:
2129 pp_unsupported_tree (pp, t);
2130 break;
2134 /* Pretty-print a template parameter in the canonical form
2135 "template-parameter-<level>-<position in parameter list>". */
2137 void
2138 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2140 const enum tree_code code = TREE_CODE (parm);
2142 /* Brings type template parameters to the canonical forms. */
2143 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2144 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2145 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2147 pp_cxx_begin_template_argument_list (pp);
2148 pp->translate_string ("template-parameter-");
2149 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2150 pp_minus (pp);
2151 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2152 pp_cxx_end_template_argument_list (pp);
2156 template-declaration:
2157 export(opt) template < template-parameter-list > declaration */
2159 static void
2160 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2162 tree tmpl = most_general_template (t);
2163 tree level;
2165 pp_maybe_newline_and_indent (pp, 0);
2166 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2168 pp_cxx_ws_string (pp, "template");
2169 pp_cxx_begin_template_argument_list (pp);
2170 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2171 pp_cxx_end_template_argument_list (pp);
2172 pp_newline_and_indent (pp, 3);
2174 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2175 pp_cxx_function_definition (pp, t);
2176 else
2177 pp_cxx_simple_declaration (pp, t);
2180 static void
2181 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2183 pp_unsupported_tree (pp, t);
2186 static void
2187 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2189 pp_unsupported_tree (pp, t);
2193 declaration:
2194 block-declaration
2195 function-definition
2196 template-declaration
2197 explicit-instantiation
2198 explicit-specialization
2199 linkage-specification
2200 namespace-definition
2202 block-declaration:
2203 simple-declaration
2204 asm-definition
2205 namespace-alias-definition
2206 using-declaration
2207 using-directive
2208 static_assert-declaration */
2209 void
2210 cxx_pretty_printer::declaration (tree t)
2212 if (TREE_CODE (t) == STATIC_ASSERT)
2214 pp_cxx_ws_string (this, "static_assert");
2215 pp_cxx_left_paren (this);
2216 expression (STATIC_ASSERT_CONDITION (t));
2217 pp_cxx_separate_with (this, ',');
2218 expression (STATIC_ASSERT_MESSAGE (t));
2219 pp_cxx_right_paren (this);
2221 else if (!DECL_LANG_SPECIFIC (t))
2222 pp_cxx_simple_declaration (this, t);
2223 else if (DECL_USE_TEMPLATE (t))
2224 switch (DECL_USE_TEMPLATE (t))
2226 case 1:
2227 pp_cxx_template_declaration (this, t);
2228 break;
2230 case 2:
2231 pp_cxx_explicit_specialization (this, t);
2232 break;
2234 case 3:
2235 pp_cxx_explicit_instantiation (this, t);
2236 break;
2238 default:
2239 break;
2241 else switch (TREE_CODE (t))
2243 case VAR_DECL:
2244 case TYPE_DECL:
2245 pp_cxx_simple_declaration (this, t);
2246 break;
2248 case FUNCTION_DECL:
2249 if (DECL_SAVED_TREE (t))
2250 pp_cxx_function_definition (this, t);
2251 else
2252 pp_cxx_simple_declaration (this, t);
2253 break;
2255 case NAMESPACE_DECL:
2256 if (DECL_NAMESPACE_ALIAS (t))
2257 pp_cxx_namespace_alias_definition (this, t);
2258 else
2259 pp_cxx_original_namespace_definition (this, t);
2260 break;
2262 default:
2263 pp_unsupported_tree (this, t);
2264 break;
2268 static void
2269 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2271 t = TREE_OPERAND (t, 0);
2272 pp_cxx_ws_string (pp, "typeid");
2273 pp_cxx_left_paren (pp);
2274 if (TYPE_P (t))
2275 pp->type_id (t);
2276 else
2277 pp->expression (t);
2278 pp_cxx_right_paren (pp);
2281 void
2282 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2284 pp_cxx_ws_string (pp, "va_arg");
2285 pp_cxx_left_paren (pp);
2286 pp->assignment_expression (TREE_OPERAND (t, 0));
2287 pp_cxx_separate_with (pp, ',');
2288 pp->type_id (TREE_TYPE (t));
2289 pp_cxx_right_paren (pp);
2292 static bool
2293 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2295 switch (TREE_CODE (t))
2297 case ARROW_EXPR:
2298 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2299 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2301 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2302 pp_cxx_separate_with (pp, ',');
2303 return true;
2305 return false;
2306 case COMPONENT_REF:
2307 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2308 return false;
2309 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2310 pp_cxx_dot (pp);
2311 pp->expression (TREE_OPERAND (t, 1));
2312 return true;
2313 case ARRAY_REF:
2314 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2315 return false;
2316 pp_left_bracket (pp);
2317 pp->expression (TREE_OPERAND (t, 1));
2318 pp_right_bracket (pp);
2319 return true;
2320 default:
2321 return false;
2325 void
2326 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2328 pp_cxx_ws_string (pp, "offsetof");
2329 pp_cxx_left_paren (pp);
2330 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2331 pp->expression (TREE_OPERAND (t, 0));
2332 pp_cxx_right_paren (pp);
2335 void
2336 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2338 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2340 switch (kind)
2342 case CPTK_HAS_NOTHROW_ASSIGN:
2343 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2344 break;
2345 case CPTK_HAS_TRIVIAL_ASSIGN:
2346 pp_cxx_ws_string (pp, "__has_trivial_assign");
2347 break;
2348 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2349 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2350 break;
2351 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2352 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2353 break;
2354 case CPTK_HAS_NOTHROW_COPY:
2355 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2356 break;
2357 case CPTK_HAS_TRIVIAL_COPY:
2358 pp_cxx_ws_string (pp, "__has_trivial_copy");
2359 break;
2360 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2361 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2362 break;
2363 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2364 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2365 break;
2366 case CPTK_IS_ABSTRACT:
2367 pp_cxx_ws_string (pp, "__is_abstract");
2368 break;
2369 case CPTK_IS_BASE_OF:
2370 pp_cxx_ws_string (pp, "__is_base_of");
2371 break;
2372 case CPTK_IS_CLASS:
2373 pp_cxx_ws_string (pp, "__is_class");
2374 break;
2375 case CPTK_IS_EMPTY:
2376 pp_cxx_ws_string (pp, "__is_empty");
2377 break;
2378 case CPTK_IS_ENUM:
2379 pp_cxx_ws_string (pp, "__is_enum");
2380 break;
2381 case CPTK_IS_FINAL:
2382 pp_cxx_ws_string (pp, "__is_final");
2383 break;
2384 case CPTK_IS_POD:
2385 pp_cxx_ws_string (pp, "__is_pod");
2386 break;
2387 case CPTK_IS_POLYMORPHIC:
2388 pp_cxx_ws_string (pp, "__is_polymorphic");
2389 break;
2390 case CPTK_IS_STD_LAYOUT:
2391 pp_cxx_ws_string (pp, "__is_std_layout");
2392 break;
2393 case CPTK_IS_TRIVIAL:
2394 pp_cxx_ws_string (pp, "__is_trivial");
2395 break;
2396 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2397 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2398 break;
2399 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2400 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2401 break;
2402 case CPTK_IS_TRIVIALLY_COPYABLE:
2403 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2404 break;
2405 case CPTK_IS_UNION:
2406 pp_cxx_ws_string (pp, "__is_union");
2407 break;
2408 case CPTK_IS_LITERAL_TYPE:
2409 pp_cxx_ws_string (pp, "__is_literal_type");
2410 break;
2412 default:
2413 gcc_unreachable ();
2416 pp_cxx_left_paren (pp);
2417 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2419 if (kind == CPTK_IS_BASE_OF)
2421 pp_cxx_separate_with (pp, ',');
2422 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2425 pp_cxx_right_paren (pp);
2428 typedef c_pretty_print_fn pp_fun;
2430 /* Initialization of a C++ pretty-printer object. */
2432 cxx_pretty_printer::cxx_pretty_printer ()
2433 : c_pretty_printer (),
2434 enclosing_scope (global_namespace)
2436 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2437 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;