[ARM] fix big.LITTLE spec rewriting
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
blobc39fb7d7165a9e7f792c791ff8a3f31fc2152142
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_convertible_to ( type-id , type-id )
392 __is_empty ( type-id )
393 __is_enum ( type-id )
394 __is_literal_type ( type-id )
395 __is_pod ( type-id )
396 __is_polymorphic ( type-id )
397 __is_std_layout ( type-id )
398 __is_trivial ( type-id )
399 __is_union ( type-id ) */
401 void
402 cxx_pretty_printer::primary_expression (tree t)
404 switch (TREE_CODE (t))
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_zero_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 INTEGER_CST:
1032 case REAL_CST:
1033 case COMPLEX_CST:
1034 constant (t);
1035 break;
1037 case USERDEF_LITERAL:
1038 pp_cxx_userdef_literal (this, t);
1039 break;
1041 case RESULT_DECL:
1042 pp_cxx_unqualified_id (this, t);
1043 break;
1045 #if 0
1046 case OFFSET_REF:
1047 #endif
1048 case SCOPE_REF:
1049 case PTRMEM_CST:
1050 pp_cxx_qualified_id (this, t);
1051 break;
1053 case OVERLOAD:
1054 t = OVL_CURRENT (t);
1055 case VAR_DECL:
1056 case PARM_DECL:
1057 case FIELD_DECL:
1058 case CONST_DECL:
1059 case FUNCTION_DECL:
1060 case BASELINK:
1061 case TEMPLATE_DECL:
1062 case TEMPLATE_TYPE_PARM:
1063 case TEMPLATE_PARM_INDEX:
1064 case TEMPLATE_TEMPLATE_PARM:
1065 case STMT_EXPR:
1066 primary_expression (t);
1067 break;
1069 case CALL_EXPR:
1070 case DYNAMIC_CAST_EXPR:
1071 case STATIC_CAST_EXPR:
1072 case REINTERPRET_CAST_EXPR:
1073 case CONST_CAST_EXPR:
1074 #if 0
1075 case MEMBER_REF:
1076 #endif
1077 case EMPTY_CLASS_EXPR:
1078 case TYPEID_EXPR:
1079 case PSEUDO_DTOR_EXPR:
1080 case AGGR_INIT_EXPR:
1081 case ARROW_EXPR:
1082 postfix_expression (t);
1083 break;
1085 case NEW_EXPR:
1086 case VEC_NEW_EXPR:
1087 pp_cxx_new_expression (this, t);
1088 break;
1090 case DELETE_EXPR:
1091 case VEC_DELETE_EXPR:
1092 pp_cxx_delete_expression (this, t);
1093 break;
1095 case SIZEOF_EXPR:
1096 case ALIGNOF_EXPR:
1097 case NOEXCEPT_EXPR:
1098 unary_expression (t);
1099 break;
1101 case CAST_EXPR:
1102 case IMPLICIT_CONV_EXPR:
1103 pp_cxx_cast_expression (this, t);
1104 break;
1106 case OFFSET_REF:
1107 case MEMBER_REF:
1108 case DOTSTAR_EXPR:
1109 pp_cxx_pm_expression (this, t);
1110 break;
1112 case MULT_EXPR:
1113 case TRUNC_DIV_EXPR:
1114 case TRUNC_MOD_EXPR:
1115 multiplicative_expression (t);
1116 break;
1118 case COND_EXPR:
1119 conditional_expression (t);
1120 break;
1122 case MODIFY_EXPR:
1123 case INIT_EXPR:
1124 case THROW_EXPR:
1125 case MODOP_EXPR:
1126 assignment_expression (t);
1127 break;
1129 case NON_DEPENDENT_EXPR:
1130 case MUST_NOT_THROW_EXPR:
1131 expression (TREE_OPERAND (t, 0));
1132 break;
1134 case EXPR_PACK_EXPANSION:
1135 expression (PACK_EXPANSION_PATTERN (t));
1136 pp_cxx_ws_string (this, "...");
1137 break;
1139 case TEMPLATE_ID_EXPR:
1140 pp_cxx_template_id (this, t);
1141 break;
1143 case NONTYPE_ARGUMENT_PACK:
1145 tree args = ARGUMENT_PACK_ARGS (t);
1146 int i, len = TREE_VEC_LENGTH (args);
1147 for (i = 0; i < len; ++i)
1149 if (i > 0)
1150 pp_cxx_separate_with (this, ',');
1151 expression (TREE_VEC_ELT (args, i));
1154 break;
1156 case LAMBDA_EXPR:
1157 pp_cxx_ws_string (this, "<lambda>");
1158 break;
1160 case PAREN_EXPR:
1161 pp_cxx_left_paren (this);
1162 expression (TREE_OPERAND (t, 0));
1163 pp_cxx_right_paren (this);
1164 break;
1166 default:
1167 c_pretty_printer::expression (t);
1168 break;
1173 /* Declarations. */
1175 /* function-specifier:
1176 inline
1177 virtual
1178 explicit */
1180 void
1181 cxx_pretty_printer::function_specifier (tree t)
1183 switch (TREE_CODE (t))
1185 case FUNCTION_DECL:
1186 if (DECL_VIRTUAL_P (t))
1187 pp_cxx_ws_string (this, "virtual");
1188 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1189 pp_cxx_ws_string (this, "explicit");
1190 else
1191 c_pretty_printer::function_specifier (t);
1193 default:
1194 break;
1198 /* decl-specifier-seq:
1199 decl-specifier-seq(opt) decl-specifier
1201 decl-specifier:
1202 storage-class-specifier
1203 type-specifier
1204 function-specifier
1205 friend
1206 typedef */
1208 void
1209 cxx_pretty_printer::declaration_specifiers (tree t)
1211 switch (TREE_CODE (t))
1213 case VAR_DECL:
1214 case PARM_DECL:
1215 case CONST_DECL:
1216 case FIELD_DECL:
1217 storage_class_specifier (t);
1218 declaration_specifiers (TREE_TYPE (t));
1219 break;
1221 case TYPE_DECL:
1222 pp_cxx_ws_string (this, "typedef");
1223 declaration_specifiers (TREE_TYPE (t));
1224 break;
1226 case FUNCTION_DECL:
1227 /* Constructors don't have return types. And conversion functions
1228 do not have a type-specifier in their return types. */
1229 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1230 function_specifier (t);
1231 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1232 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1233 else
1234 default:
1235 c_pretty_printer::declaration_specifiers (t);
1236 break;
1240 /* simple-type-specifier:
1241 ::(opt) nested-name-specifier(opt) type-name
1242 ::(opt) nested-name-specifier(opt) template(opt) template-id
1243 char
1244 wchar_t
1245 bool
1246 short
1248 long
1249 signed
1250 unsigned
1251 float
1252 double
1253 void */
1255 void
1256 cxx_pretty_printer::simple_type_specifier (tree t)
1258 switch (TREE_CODE (t))
1260 case RECORD_TYPE:
1261 case UNION_TYPE:
1262 case ENUMERAL_TYPE:
1263 pp_cxx_qualified_id (this, t);
1264 break;
1266 case TEMPLATE_TYPE_PARM:
1267 case TEMPLATE_TEMPLATE_PARM:
1268 case TEMPLATE_PARM_INDEX:
1269 case BOUND_TEMPLATE_TEMPLATE_PARM:
1270 pp_cxx_unqualified_id (this, t);
1271 break;
1273 case TYPENAME_TYPE:
1274 pp_cxx_ws_string (this, "typename");
1275 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1276 pp_cxx_unqualified_id (this, TYPE_NAME (t));
1277 break;
1279 default:
1280 c_pretty_printer::simple_type_specifier (t);
1281 break;
1285 /* type-specifier-seq:
1286 type-specifier type-specifier-seq(opt)
1288 type-specifier:
1289 simple-type-specifier
1290 class-specifier
1291 enum-specifier
1292 elaborated-type-specifier
1293 cv-qualifier */
1295 static void
1296 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1298 switch (TREE_CODE (t))
1300 case TEMPLATE_DECL:
1301 case TEMPLATE_TYPE_PARM:
1302 case TEMPLATE_TEMPLATE_PARM:
1303 case TYPE_DECL:
1304 case BOUND_TEMPLATE_TEMPLATE_PARM:
1305 pp_cxx_cv_qualifier_seq (pp, t);
1306 pp->simple_type_specifier (t);
1307 break;
1309 case METHOD_TYPE:
1310 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1311 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1312 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1313 break;
1315 case DECLTYPE_TYPE:
1316 pp_cxx_ws_string (pp, "decltype");
1317 pp_cxx_left_paren (pp);
1318 pp->expression (DECLTYPE_TYPE_EXPR (t));
1319 pp_cxx_right_paren (pp);
1320 break;
1322 case RECORD_TYPE:
1323 if (TYPE_PTRMEMFUNC_P (t))
1325 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1326 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1327 pp_cxx_whitespace (pp);
1328 pp_cxx_ptr_operator (pp, t);
1329 break;
1331 /* else fall through */
1333 default:
1334 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1335 pp_c_specifier_qualifier_list (pp, t);
1339 /* ptr-operator:
1340 * cv-qualifier-seq(opt)
1342 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1344 static void
1345 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1347 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1348 t = TREE_TYPE (t);
1349 switch (TREE_CODE (t))
1351 case REFERENCE_TYPE:
1352 case POINTER_TYPE:
1353 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1354 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1355 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1356 if (TYPE_PTR_P (t))
1358 pp_star (pp);
1359 pp_cxx_cv_qualifier_seq (pp, t);
1361 else
1362 pp_ampersand (pp);
1363 break;
1365 case RECORD_TYPE:
1366 if (TYPE_PTRMEMFUNC_P (t))
1368 pp_cxx_left_paren (pp);
1369 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1370 pp_star (pp);
1371 break;
1373 case OFFSET_TYPE:
1374 if (TYPE_PTRMEM_P (t))
1376 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1377 pp_cxx_left_paren (pp);
1378 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1379 pp_star (pp);
1380 pp_cxx_cv_qualifier_seq (pp, t);
1381 break;
1383 /* else fall through. */
1385 default:
1386 pp_unsupported_tree (pp, t);
1387 break;
1391 static inline tree
1392 pp_cxx_implicit_parameter_type (tree mf)
1394 return class_of_this_parm (TREE_TYPE (mf));
1398 parameter-declaration:
1399 decl-specifier-seq declarator
1400 decl-specifier-seq declarator = assignment-expression
1401 decl-specifier-seq abstract-declarator(opt)
1402 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1404 static inline void
1405 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1407 pp->declaration_specifiers (t);
1408 if (TYPE_P (t))
1409 pp->abstract_declarator (t);
1410 else
1411 pp->declarator (t);
1414 /* parameter-declaration-clause:
1415 parameter-declaration-list(opt) ...(opt)
1416 parameter-declaration-list , ...
1418 parameter-declaration-list:
1419 parameter-declaration
1420 parameter-declaration-list , parameter-declaration */
1422 static void
1423 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1425 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1426 tree types =
1427 TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1428 const bool abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1429 bool first = true;
1431 /* Skip artificial parameter for nonstatic member functions. */
1432 if (TREE_CODE (t) == METHOD_TYPE)
1433 types = TREE_CHAIN (types);
1435 pp_cxx_left_paren (pp);
1436 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1438 if (!first)
1439 pp_cxx_separate_with (pp, ',');
1440 first = false;
1441 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1442 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1444 pp_cxx_whitespace (pp);
1445 pp_equal (pp);
1446 pp_cxx_whitespace (pp);
1447 pp->assignment_expression (TREE_PURPOSE (types));
1450 pp_cxx_right_paren (pp);
1453 /* exception-specification:
1454 throw ( type-id-list(opt) )
1456 type-id-list
1457 type-id
1458 type-id-list , type-id */
1460 static void
1461 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1463 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1464 bool need_comma = false;
1466 if (ex_spec == NULL)
1467 return;
1468 if (TREE_PURPOSE (ex_spec))
1470 pp_cxx_ws_string (pp, "noexcept");
1471 pp_cxx_whitespace (pp);
1472 pp_cxx_left_paren (pp);
1473 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1474 pp_cxx_ws_string (pp, "<uninstantiated>");
1475 else
1476 pp->expression (TREE_PURPOSE (ex_spec));
1477 pp_cxx_right_paren (pp);
1478 return;
1480 pp_cxx_ws_string (pp, "throw");
1481 pp_cxx_left_paren (pp);
1482 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1484 tree type = TREE_VALUE (ex_spec);
1485 tree argpack = NULL_TREE;
1486 int i, len = 1;
1488 if (ARGUMENT_PACK_P (type))
1490 argpack = ARGUMENT_PACK_ARGS (type);
1491 len = TREE_VEC_LENGTH (argpack);
1494 for (i = 0; i < len; ++i)
1496 if (argpack)
1497 type = TREE_VEC_ELT (argpack, i);
1499 if (need_comma)
1500 pp_cxx_separate_with (pp, ',');
1501 else
1502 need_comma = true;
1504 pp->type_id (type);
1507 pp_cxx_right_paren (pp);
1510 /* direct-declarator:
1511 declarator-id
1512 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1513 exception-specification(opt)
1514 direct-declaration [ constant-expression(opt) ]
1515 ( declarator ) */
1517 void
1518 cxx_pretty_printer::direct_declarator (tree t)
1520 switch (TREE_CODE (t))
1522 case VAR_DECL:
1523 case PARM_DECL:
1524 case CONST_DECL:
1525 case FIELD_DECL:
1526 if (DECL_NAME (t))
1528 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1530 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1531 || template_parameter_pack_p (t))
1532 /* A function parameter pack or non-type template
1533 parameter pack. */
1534 pp_cxx_ws_string (this, "...");
1536 id_expression (DECL_NAME (t));
1538 abstract_declarator (TREE_TYPE (t));
1539 break;
1541 case FUNCTION_DECL:
1542 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1543 expression (t);
1544 pp_cxx_parameter_declaration_clause (this, t);
1546 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1548 padding = pp_before;
1549 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1552 pp_cxx_exception_specification (this, TREE_TYPE (t));
1553 break;
1555 case TYPENAME_TYPE:
1556 case TEMPLATE_DECL:
1557 case TEMPLATE_TYPE_PARM:
1558 case TEMPLATE_PARM_INDEX:
1559 case TEMPLATE_TEMPLATE_PARM:
1560 break;
1562 default:
1563 c_pretty_printer::direct_declarator (t);
1564 break;
1568 /* declarator:
1569 direct-declarator
1570 ptr-operator declarator */
1572 void
1573 cxx_pretty_printer::declarator (tree t)
1575 direct_declarator (t);
1578 /* ctor-initializer:
1579 : mem-initializer-list
1581 mem-initializer-list:
1582 mem-initializer
1583 mem-initializer , mem-initializer-list
1585 mem-initializer:
1586 mem-initializer-id ( expression-list(opt) )
1588 mem-initializer-id:
1589 ::(opt) nested-name-specifier(opt) class-name
1590 identifier */
1592 static void
1593 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1595 t = TREE_OPERAND (t, 0);
1596 pp_cxx_whitespace (pp);
1597 pp_colon (pp);
1598 pp_cxx_whitespace (pp);
1599 for (; t; t = TREE_CHAIN (t))
1601 tree purpose = TREE_PURPOSE (t);
1602 bool is_pack = PACK_EXPANSION_P (purpose);
1604 if (is_pack)
1605 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1606 else
1607 pp->primary_expression (purpose);
1608 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1609 if (is_pack)
1610 pp_cxx_ws_string (pp, "...");
1611 if (TREE_CHAIN (t))
1612 pp_cxx_separate_with (pp, ',');
1616 /* function-definition:
1617 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1618 decl-specifier-seq(opt) declarator function-try-block */
1620 static void
1621 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1623 tree saved_scope = pp->enclosing_scope;
1624 pp->declaration_specifiers (t);
1625 pp->declarator (t);
1626 pp_needs_newline (pp) = true;
1627 pp->enclosing_scope = DECL_CONTEXT (t);
1628 if (DECL_SAVED_TREE (t))
1629 pp->statement (DECL_SAVED_TREE (t));
1630 else
1631 pp_cxx_semicolon (pp);
1632 pp_newline_and_flush (pp);
1633 pp->enclosing_scope = saved_scope;
1636 /* abstract-declarator:
1637 ptr-operator abstract-declarator(opt)
1638 direct-abstract-declarator */
1640 void
1641 cxx_pretty_printer::abstract_declarator (tree t)
1643 if (TYPE_PTRMEM_P (t))
1644 pp_cxx_right_paren (this);
1645 else if (POINTER_TYPE_P (t))
1647 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1648 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1649 pp_cxx_right_paren (this);
1650 t = TREE_TYPE (t);
1652 direct_abstract_declarator (t);
1655 /* direct-abstract-declarator:
1656 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1657 cv-qualifier-seq(opt) exception-specification(opt)
1658 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1659 ( abstract-declarator ) */
1661 void
1662 cxx_pretty_printer::direct_abstract_declarator (tree t)
1664 switch (TREE_CODE (t))
1666 case REFERENCE_TYPE:
1667 abstract_declarator (t);
1668 break;
1670 case RECORD_TYPE:
1671 if (TYPE_PTRMEMFUNC_P (t))
1672 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1673 break;
1675 case METHOD_TYPE:
1676 case FUNCTION_TYPE:
1677 pp_cxx_parameter_declaration_clause (this, t);
1678 direct_abstract_declarator (TREE_TYPE (t));
1679 if (TREE_CODE (t) == METHOD_TYPE)
1681 padding = pp_before;
1682 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1684 pp_cxx_exception_specification (this, t);
1685 break;
1687 case TYPENAME_TYPE:
1688 case TEMPLATE_TYPE_PARM:
1689 case TEMPLATE_TEMPLATE_PARM:
1690 case BOUND_TEMPLATE_TEMPLATE_PARM:
1691 case UNBOUND_CLASS_TEMPLATE:
1692 break;
1694 default:
1695 c_pretty_printer::direct_abstract_declarator (t);
1696 break;
1700 /* type-id:
1701 type-specifier-seq abstract-declarator(opt) */
1703 void
1704 cxx_pretty_printer::type_id (tree t)
1706 pp_flags saved_flags = flags;
1707 flags |= pp_c_flag_abstract;
1709 switch (TREE_CODE (t))
1711 case TYPE_DECL:
1712 case UNION_TYPE:
1713 case RECORD_TYPE:
1714 case ENUMERAL_TYPE:
1715 case TYPENAME_TYPE:
1716 case BOUND_TEMPLATE_TEMPLATE_PARM:
1717 case UNBOUND_CLASS_TEMPLATE:
1718 case TEMPLATE_TEMPLATE_PARM:
1719 case TEMPLATE_TYPE_PARM:
1720 case TEMPLATE_PARM_INDEX:
1721 case TEMPLATE_DECL:
1722 case TYPEOF_TYPE:
1723 case UNDERLYING_TYPE:
1724 case DECLTYPE_TYPE:
1725 case TEMPLATE_ID_EXPR:
1726 pp_cxx_type_specifier_seq (this, t);
1727 break;
1729 case TYPE_PACK_EXPANSION:
1730 type_id (PACK_EXPANSION_PATTERN (t));
1731 pp_cxx_ws_string (this, "...");
1732 break;
1734 default:
1735 c_pretty_printer::type_id (t);
1736 break;
1739 flags = saved_flags;
1742 /* template-argument-list:
1743 template-argument ...(opt)
1744 template-argument-list, template-argument ...(opt)
1746 template-argument:
1747 assignment-expression
1748 type-id
1749 template-name */
1751 static void
1752 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1754 int i;
1755 bool need_comma = false;
1757 if (t == NULL)
1758 return;
1759 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1761 tree arg = TREE_VEC_ELT (t, i);
1762 tree argpack = NULL_TREE;
1763 int idx, len = 1;
1765 if (ARGUMENT_PACK_P (arg))
1767 argpack = ARGUMENT_PACK_ARGS (arg);
1768 len = TREE_VEC_LENGTH (argpack);
1771 for (idx = 0; idx < len; idx++)
1773 if (argpack)
1774 arg = TREE_VEC_ELT (argpack, idx);
1776 if (need_comma)
1777 pp_cxx_separate_with (pp, ',');
1778 else
1779 need_comma = true;
1781 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1782 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1783 pp->type_id (arg);
1784 else
1785 pp->expression (arg);
1791 static void
1792 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1794 t = DECL_EXPR_DECL (t);
1795 pp_cxx_type_specifier_seq (pp, t);
1796 if (TYPE_P (t))
1797 pp->abstract_declarator (t);
1798 else
1799 pp->declarator (t);
1802 /* Statements. */
1804 void
1805 cxx_pretty_printer::statement (tree t)
1807 switch (TREE_CODE (t))
1809 case CTOR_INITIALIZER:
1810 pp_cxx_ctor_initializer (this, t);
1811 break;
1813 case USING_STMT:
1814 pp_cxx_ws_string (this, "using");
1815 pp_cxx_ws_string (this, "namespace");
1816 if (DECL_CONTEXT (t))
1817 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1818 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1819 break;
1821 case USING_DECL:
1822 pp_cxx_ws_string (this, "using");
1823 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1824 pp_cxx_unqualified_id (this, DECL_NAME (t));
1825 break;
1827 case EH_SPEC_BLOCK:
1828 break;
1830 /* try-block:
1831 try compound-statement handler-seq */
1832 case TRY_BLOCK:
1833 pp_maybe_newline_and_indent (this, 0);
1834 pp_cxx_ws_string (this, "try");
1835 pp_newline_and_indent (this, 3);
1836 statement (TRY_STMTS (t));
1837 pp_newline_and_indent (this, -3);
1838 if (CLEANUP_P (t))
1840 else
1841 statement (TRY_HANDLERS (t));
1842 break;
1845 handler-seq:
1846 handler handler-seq(opt)
1848 handler:
1849 catch ( exception-declaration ) compound-statement
1851 exception-declaration:
1852 type-specifier-seq declarator
1853 type-specifier-seq abstract-declarator
1854 ... */
1855 case HANDLER:
1856 pp_cxx_ws_string (this, "catch");
1857 pp_cxx_left_paren (this);
1858 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1859 pp_cxx_right_paren (this);
1860 pp_indentation (this) += 3;
1861 pp_needs_newline (this) = true;
1862 statement (HANDLER_BODY (t));
1863 pp_indentation (this) -= 3;
1864 pp_needs_newline (this) = true;
1865 break;
1867 /* selection-statement:
1868 if ( expression ) statement
1869 if ( expression ) statement else statement */
1870 case IF_STMT:
1871 pp_cxx_ws_string (this, "if");
1872 pp_cxx_whitespace (this);
1873 pp_cxx_left_paren (this);
1874 expression (IF_COND (t));
1875 pp_cxx_right_paren (this);
1876 pp_newline_and_indent (this, 2);
1877 statement (THEN_CLAUSE (t));
1878 pp_newline_and_indent (this, -2);
1879 if (ELSE_CLAUSE (t))
1881 tree else_clause = ELSE_CLAUSE (t);
1882 pp_cxx_ws_string (this, "else");
1883 if (TREE_CODE (else_clause) == IF_STMT)
1884 pp_cxx_whitespace (this);
1885 else
1886 pp_newline_and_indent (this, 2);
1887 statement (else_clause);
1888 if (TREE_CODE (else_clause) != IF_STMT)
1889 pp_newline_and_indent (this, -2);
1891 break;
1893 case SWITCH_STMT:
1894 pp_cxx_ws_string (this, "switch");
1895 pp_space (this);
1896 pp_cxx_left_paren (this);
1897 expression (SWITCH_STMT_COND (t));
1898 pp_cxx_right_paren (this);
1899 pp_indentation (this) += 3;
1900 pp_needs_newline (this) = true;
1901 statement (SWITCH_STMT_BODY (t));
1902 pp_newline_and_indent (this, -3);
1903 break;
1905 /* iteration-statement:
1906 while ( expression ) statement
1907 do statement while ( expression ) ;
1908 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1909 for ( declaration expression(opt) ; expression(opt) ) statement */
1910 case WHILE_STMT:
1911 pp_cxx_ws_string (this, "while");
1912 pp_space (this);
1913 pp_cxx_left_paren (this);
1914 expression (WHILE_COND (t));
1915 pp_cxx_right_paren (this);
1916 pp_newline_and_indent (this, 3);
1917 statement (WHILE_BODY (t));
1918 pp_indentation (this) -= 3;
1919 pp_needs_newline (this) = true;
1920 break;
1922 case DO_STMT:
1923 pp_cxx_ws_string (this, "do");
1924 pp_newline_and_indent (this, 3);
1925 statement (DO_BODY (t));
1926 pp_newline_and_indent (this, -3);
1927 pp_cxx_ws_string (this, "while");
1928 pp_space (this);
1929 pp_cxx_left_paren (this);
1930 expression (DO_COND (t));
1931 pp_cxx_right_paren (this);
1932 pp_cxx_semicolon (this);
1933 pp_needs_newline (this) = true;
1934 break;
1936 case FOR_STMT:
1937 pp_cxx_ws_string (this, "for");
1938 pp_space (this);
1939 pp_cxx_left_paren (this);
1940 if (FOR_INIT_STMT (t))
1941 statement (FOR_INIT_STMT (t));
1942 else
1943 pp_cxx_semicolon (this);
1944 pp_needs_newline (this) = false;
1945 pp_cxx_whitespace (this);
1946 if (FOR_COND (t))
1947 expression (FOR_COND (t));
1948 pp_cxx_semicolon (this);
1949 pp_needs_newline (this) = false;
1950 pp_cxx_whitespace (this);
1951 if (FOR_EXPR (t))
1952 expression (FOR_EXPR (t));
1953 pp_cxx_right_paren (this);
1954 pp_newline_and_indent (this, 3);
1955 statement (FOR_BODY (t));
1956 pp_indentation (this) -= 3;
1957 pp_needs_newline (this) = true;
1958 break;
1960 case RANGE_FOR_STMT:
1961 pp_cxx_ws_string (this, "for");
1962 pp_space (this);
1963 pp_cxx_left_paren (this);
1964 statement (RANGE_FOR_DECL (t));
1965 pp_space (this);
1966 pp_needs_newline (this) = false;
1967 pp_colon (this);
1968 pp_space (this);
1969 statement (RANGE_FOR_EXPR (t));
1970 pp_cxx_right_paren (this);
1971 pp_newline_and_indent (this, 3);
1972 statement (FOR_BODY (t));
1973 pp_indentation (this) -= 3;
1974 pp_needs_newline (this) = true;
1975 break;
1977 /* jump-statement:
1978 goto identifier;
1979 continue ;
1980 return expression(opt) ; */
1981 case BREAK_STMT:
1982 case CONTINUE_STMT:
1983 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1984 pp_cxx_semicolon (this);
1985 pp_needs_newline (this) = true;
1986 break;
1988 /* expression-statement:
1989 expression(opt) ; */
1990 case EXPR_STMT:
1991 expression (EXPR_STMT_EXPR (t));
1992 pp_cxx_semicolon (this);
1993 pp_needs_newline (this) = true;
1994 break;
1996 case CLEANUP_STMT:
1997 pp_cxx_ws_string (this, "try");
1998 pp_newline_and_indent (this, 2);
1999 statement (CLEANUP_BODY (t));
2000 pp_newline_and_indent (this, -2);
2001 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2002 pp_newline_and_indent (this, 2);
2003 statement (CLEANUP_EXPR (t));
2004 pp_newline_and_indent (this, -2);
2005 break;
2007 case STATIC_ASSERT:
2008 declaration (t);
2009 break;
2011 default:
2012 c_pretty_printer::statement (t);
2013 break;
2017 /* original-namespace-definition:
2018 namespace identifier { namespace-body }
2020 As an edge case, we also handle unnamed namespace definition here. */
2022 static void
2023 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2025 pp_cxx_ws_string (pp, "namespace");
2026 if (DECL_CONTEXT (t))
2027 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2028 if (DECL_NAME (t))
2029 pp_cxx_unqualified_id (pp, t);
2030 pp_cxx_whitespace (pp);
2031 pp_cxx_left_brace (pp);
2032 /* We do not print the namespace-body. */
2033 pp_cxx_whitespace (pp);
2034 pp_cxx_right_brace (pp);
2037 /* namespace-alias:
2038 identifier
2040 namespace-alias-definition:
2041 namespace identifier = qualified-namespace-specifier ;
2043 qualified-namespace-specifier:
2044 ::(opt) nested-name-specifier(opt) namespace-name */
2046 static void
2047 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2049 pp_cxx_ws_string (pp, "namespace");
2050 if (DECL_CONTEXT (t))
2051 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2052 pp_cxx_unqualified_id (pp, t);
2053 pp_cxx_whitespace (pp);
2054 pp_equal (pp);
2055 pp_cxx_whitespace (pp);
2056 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2057 pp_cxx_nested_name_specifier (pp,
2058 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2059 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2060 pp_cxx_semicolon (pp);
2063 /* simple-declaration:
2064 decl-specifier-seq(opt) init-declarator-list(opt) */
2066 static void
2067 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2069 pp->declaration_specifiers (t);
2070 pp_cxx_init_declarator (pp, t);
2071 pp_cxx_semicolon (pp);
2072 pp_needs_newline (pp) = true;
2076 template-parameter-list:
2077 template-parameter
2078 template-parameter-list , template-parameter */
2080 static inline void
2081 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2083 const int n = TREE_VEC_LENGTH (t);
2084 int i;
2085 for (i = 0; i < n; ++i)
2087 if (i)
2088 pp_cxx_separate_with (pp, ',');
2089 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2093 /* template-parameter:
2094 type-parameter
2095 parameter-declaration
2097 type-parameter:
2098 class ...(opt) identifier(opt)
2099 class identifier(opt) = type-id
2100 typename identifier(opt)
2101 typename ...(opt) identifier(opt) = type-id
2102 template < template-parameter-list > class ...(opt) identifier(opt)
2103 template < template-parameter-list > class identifier(opt) = template-name */
2105 static void
2106 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2108 tree parameter = TREE_VALUE (t);
2109 switch (TREE_CODE (parameter))
2111 case TYPE_DECL:
2112 pp_cxx_ws_string (pp, "class");
2113 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2114 pp_cxx_ws_string (pp, "...");
2115 if (DECL_NAME (parameter))
2116 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2117 /* FIXME: Check if we should print also default argument. */
2118 break;
2120 case PARM_DECL:
2121 pp_cxx_parameter_declaration (pp, parameter);
2122 break;
2124 case TEMPLATE_DECL:
2125 break;
2127 default:
2128 pp_unsupported_tree (pp, t);
2129 break;
2133 /* Pretty-print a template parameter in the canonical form
2134 "template-parameter-<level>-<position in parameter list>". */
2136 void
2137 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2139 const enum tree_code code = TREE_CODE (parm);
2141 /* Brings type template parameters to the canonical forms. */
2142 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2143 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2144 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2146 pp_cxx_begin_template_argument_list (pp);
2147 pp->translate_string ("template-parameter-");
2148 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2149 pp_minus (pp);
2150 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2151 pp_cxx_end_template_argument_list (pp);
2155 template-declaration:
2156 export(opt) template < template-parameter-list > declaration */
2158 static void
2159 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2161 tree tmpl = most_general_template (t);
2162 tree level;
2164 pp_maybe_newline_and_indent (pp, 0);
2165 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2167 pp_cxx_ws_string (pp, "template");
2168 pp_cxx_begin_template_argument_list (pp);
2169 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2170 pp_cxx_end_template_argument_list (pp);
2171 pp_newline_and_indent (pp, 3);
2173 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2174 pp_cxx_function_definition (pp, t);
2175 else
2176 pp_cxx_simple_declaration (pp, t);
2179 static void
2180 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2182 pp_unsupported_tree (pp, t);
2185 static void
2186 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2188 pp_unsupported_tree (pp, t);
2192 declaration:
2193 block-declaration
2194 function-definition
2195 template-declaration
2196 explicit-instantiation
2197 explicit-specialization
2198 linkage-specification
2199 namespace-definition
2201 block-declaration:
2202 simple-declaration
2203 asm-definition
2204 namespace-alias-definition
2205 using-declaration
2206 using-directive
2207 static_assert-declaration */
2208 void
2209 cxx_pretty_printer::declaration (tree t)
2211 if (TREE_CODE (t) == STATIC_ASSERT)
2213 pp_cxx_ws_string (this, "static_assert");
2214 pp_cxx_left_paren (this);
2215 expression (STATIC_ASSERT_CONDITION (t));
2216 pp_cxx_separate_with (this, ',');
2217 expression (STATIC_ASSERT_MESSAGE (t));
2218 pp_cxx_right_paren (this);
2220 else if (!DECL_LANG_SPECIFIC (t))
2221 pp_cxx_simple_declaration (this, t);
2222 else if (DECL_USE_TEMPLATE (t))
2223 switch (DECL_USE_TEMPLATE (t))
2225 case 1:
2226 pp_cxx_template_declaration (this, t);
2227 break;
2229 case 2:
2230 pp_cxx_explicit_specialization (this, t);
2231 break;
2233 case 3:
2234 pp_cxx_explicit_instantiation (this, t);
2235 break;
2237 default:
2238 break;
2240 else switch (TREE_CODE (t))
2242 case VAR_DECL:
2243 case TYPE_DECL:
2244 pp_cxx_simple_declaration (this, t);
2245 break;
2247 case FUNCTION_DECL:
2248 if (DECL_SAVED_TREE (t))
2249 pp_cxx_function_definition (this, t);
2250 else
2251 pp_cxx_simple_declaration (this, t);
2252 break;
2254 case NAMESPACE_DECL:
2255 if (DECL_NAMESPACE_ALIAS (t))
2256 pp_cxx_namespace_alias_definition (this, t);
2257 else
2258 pp_cxx_original_namespace_definition (this, t);
2259 break;
2261 default:
2262 pp_unsupported_tree (this, t);
2263 break;
2267 static void
2268 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2270 t = TREE_OPERAND (t, 0);
2271 pp_cxx_ws_string (pp, "typeid");
2272 pp_cxx_left_paren (pp);
2273 if (TYPE_P (t))
2274 pp->type_id (t);
2275 else
2276 pp->expression (t);
2277 pp_cxx_right_paren (pp);
2280 void
2281 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2283 pp_cxx_ws_string (pp, "va_arg");
2284 pp_cxx_left_paren (pp);
2285 pp->assignment_expression (TREE_OPERAND (t, 0));
2286 pp_cxx_separate_with (pp, ',');
2287 pp->type_id (TREE_TYPE (t));
2288 pp_cxx_right_paren (pp);
2291 static bool
2292 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2294 switch (TREE_CODE (t))
2296 case ARROW_EXPR:
2297 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2298 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2300 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2301 pp_cxx_separate_with (pp, ',');
2302 return true;
2304 return false;
2305 case COMPONENT_REF:
2306 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2307 return false;
2308 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2309 pp_cxx_dot (pp);
2310 pp->expression (TREE_OPERAND (t, 1));
2311 return true;
2312 case ARRAY_REF:
2313 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2314 return false;
2315 pp_left_bracket (pp);
2316 pp->expression (TREE_OPERAND (t, 1));
2317 pp_right_bracket (pp);
2318 return true;
2319 default:
2320 return false;
2324 void
2325 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2327 pp_cxx_ws_string (pp, "offsetof");
2328 pp_cxx_left_paren (pp);
2329 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2330 pp->expression (TREE_OPERAND (t, 0));
2331 pp_cxx_right_paren (pp);
2334 void
2335 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2337 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2339 switch (kind)
2341 case CPTK_HAS_NOTHROW_ASSIGN:
2342 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2343 break;
2344 case CPTK_HAS_TRIVIAL_ASSIGN:
2345 pp_cxx_ws_string (pp, "__has_trivial_assign");
2346 break;
2347 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2348 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2349 break;
2350 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2351 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2352 break;
2353 case CPTK_HAS_NOTHROW_COPY:
2354 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2355 break;
2356 case CPTK_HAS_TRIVIAL_COPY:
2357 pp_cxx_ws_string (pp, "__has_trivial_copy");
2358 break;
2359 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2360 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2361 break;
2362 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2363 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2364 break;
2365 case CPTK_IS_ABSTRACT:
2366 pp_cxx_ws_string (pp, "__is_abstract");
2367 break;
2368 case CPTK_IS_BASE_OF:
2369 pp_cxx_ws_string (pp, "__is_base_of");
2370 break;
2371 case CPTK_IS_CLASS:
2372 pp_cxx_ws_string (pp, "__is_class");
2373 break;
2374 case CPTK_IS_CONVERTIBLE_TO:
2375 pp_cxx_ws_string (pp, "__is_convertible_to");
2376 break;
2377 case CPTK_IS_EMPTY:
2378 pp_cxx_ws_string (pp, "__is_empty");
2379 break;
2380 case CPTK_IS_ENUM:
2381 pp_cxx_ws_string (pp, "__is_enum");
2382 break;
2383 case CPTK_IS_FINAL:
2384 pp_cxx_ws_string (pp, "__is_final");
2385 break;
2386 case CPTK_IS_POD:
2387 pp_cxx_ws_string (pp, "__is_pod");
2388 break;
2389 case CPTK_IS_POLYMORPHIC:
2390 pp_cxx_ws_string (pp, "__is_polymorphic");
2391 break;
2392 case CPTK_IS_STD_LAYOUT:
2393 pp_cxx_ws_string (pp, "__is_std_layout");
2394 break;
2395 case CPTK_IS_TRIVIAL:
2396 pp_cxx_ws_string (pp, "__is_trivial");
2397 break;
2398 case CPTK_IS_UNION:
2399 pp_cxx_ws_string (pp, "__is_union");
2400 break;
2401 case CPTK_IS_LITERAL_TYPE:
2402 pp_cxx_ws_string (pp, "__is_literal_type");
2403 break;
2405 default:
2406 gcc_unreachable ();
2409 pp_cxx_left_paren (pp);
2410 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2412 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2414 pp_cxx_separate_with (pp, ',');
2415 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2418 pp_cxx_right_paren (pp);
2421 typedef c_pretty_print_fn pp_fun;
2423 /* Initialization of a C++ pretty-printer object. */
2425 cxx_pretty_printer::cxx_pretty_printer ()
2426 : c_pretty_printer (),
2427 enclosing_scope (global_namespace)
2429 pp_set_line_maximum_length (this, 0);
2431 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2432 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;