* const-elim-1.c: xfail hppa-*-*.
[official-gcc.git] / gcc / cp / cxx-pretty-print.c
bloba07f0090871b43b0b42943fab2ea81fa9bdd9141
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003, 2004 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 2, 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 COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "real.h"
27 #include "cxx-pretty-print.h"
28 #include "cp-tree.h"
29 #include "toplev.h"
31 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
32 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
33 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
34 static void pp_cxx_assignment_expression (cxx_pretty_printer *, tree);
35 static void pp_cxx_expression (cxx_pretty_printer *, tree);
36 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
37 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
38 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
39 static void pp_cxx_type_id (cxx_pretty_printer *, tree);
40 static void pp_cxx_direct_abstract_declarator (cxx_pretty_printer *, tree);
41 static void pp_cxx_declarator (cxx_pretty_printer *, tree);
42 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
43 static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
44 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
46 #define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP))
47 #define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP))
48 #define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP))
49 #define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP))
50 #define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP))
51 #define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP))
52 #define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP))
53 #define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP))
55 static inline void
56 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
58 const char *p = pp_last_position_in_text (pp);
60 if (p != NULL && *p == c)
61 pp_cxx_whitespace (pp);
62 pp_character (pp, c);
63 pp_base (pp)->padding = pp_none;
66 #define pp_cxx_begin_template_argument_list(PP) \
67 pp_cxx_nonconsecutive_character (PP, '<')
68 #define pp_cxx_end_template_argument_list(PP) \
69 pp_cxx_nonconsecutive_character (PP, '>')
71 #define pp_cxx_identifier(PP, ID) pp_c_identifier (pp_c_base (PP), ID)
72 #define pp_cxx_tree_identifier(PP, T) pp_c_tree_identifier (pp_c_base (PP), T)
74 #define pp_cxx_storage_class_specifier(PP, T) \
75 pp_c_storage_class_specifier (pp_c_base (PP), T)
76 #define pp_cxx_expression_list(PP, T) \
77 pp_c_expression_list (pp_c_base (PP), T)
78 #define pp_cxx_space_for_pointer_operator(PP, T) \
79 pp_c_space_for_pointer_operator (pp_c_base (PP), T)
80 #define pp_cxx_init_declarator(PP, T) \
81 pp_c_init_declarator (pp_c_base (PP), T)
82 #define pp_cxx_call_argument_list(PP, T) \
83 pp_c_call_argument_list (pp_c_base (PP), T)
85 static void
86 pp_cxx_colon_colon (cxx_pretty_printer *pp)
88 pp_colon_colon (pp);
89 pp_base (pp)->padding = pp_none;
93 /* Expressions. */
95 static inline bool
96 is_destructor_name (tree name)
98 return name == complete_dtor_identifier
99 || name == base_dtor_identifier
100 || name == deleting_dtor_identifier;
103 /* conversion-function-id:
104 operator conversion-type-id
106 conversion-type-id:
107 type-specifier-seq conversion-declarator(opt)
109 conversion-declarator:
110 ptr-operator conversion-declarator(opt) */
112 static inline void
113 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
115 pp_cxx_identifier (pp, "operator");
116 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
119 static inline void
120 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
122 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
123 pp_cxx_begin_template_argument_list (pp);
124 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
125 pp_cxx_end_template_argument_list (pp);
128 /* unqualified-id:
129 identifier
130 operator-function-id
131 conversion-function-id
132 ~ class-name
133 template-id */
135 static void
136 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
138 enum tree_code code = TREE_CODE (t);
139 switch (code)
141 case RESULT_DECL:
142 pp_cxx_identifier (pp, "<return-value>");
143 break;
145 case OVERLOAD:
146 t = OVL_CURRENT (t);
147 case VAR_DECL:
148 case PARM_DECL:
149 case CONST_DECL:
150 case TYPE_DECL:
151 case FUNCTION_DECL:
152 case NAMESPACE_DECL:
153 case FIELD_DECL:
154 case LABEL_DECL:
155 case USING_DECL:
156 case TEMPLATE_DECL:
157 t = DECL_NAME (t);
159 case IDENTIFIER_NODE:
160 if (t == NULL)
161 pp_cxx_identifier (pp, "<anonymous>");
162 else if (IDENTIFIER_TYPENAME_P (t))
163 pp_cxx_conversion_function_id (pp, t);
164 else
166 if (is_destructor_name (t))
168 pp_complement (pp);
169 /* FIXME: Why is this necessary? */
170 if (TREE_TYPE (t))
171 t = constructor_name (TREE_TYPE (t));
173 pp_cxx_tree_identifier (pp, t);
175 break;
177 case TEMPLATE_ID_EXPR:
178 pp_cxx_template_id (pp, t);
179 break;
181 case RECORD_TYPE:
182 case UNION_TYPE:
183 case ENUMERAL_TYPE:
184 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
185 break;
187 case TEMPLATE_TYPE_PARM:
188 t = TEMPLATE_TYPE_PARM_INDEX (t);
189 case TEMPLATE_PARM_INDEX:
190 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
191 break;
193 default:
194 pp_unsupported_tree (pp, t);
195 break;
199 /* Pretty-print out the token sequence ":: template" in template codes
200 where it is needed to "inline declare" the (following) member as
201 a template. This situation arises when SCOPE of T is dependent
202 on template parameters. */
204 static inline void
205 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
207 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
208 && TYPE_P (scope) && dependent_type_p (scope))
209 pp_cxx_identifier (pp, "template");
212 /* nested-name-specifier:
213 class-or-namespace-name :: nested-name-specifier(opt)
214 class-or-namespace-name :: template nested-name-specifier */
216 static void
217 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
219 if (t != NULL && t != pp->enclosing_scope)
221 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
222 pp_cxx_nested_name_specifier (pp, scope);
223 pp_cxx_template_keyword_if_needed (pp, scope, t);
224 pp_cxx_unqualified_id (pp, t);
225 pp_cxx_colon_colon (pp);
229 /* qualified-id:
230 nested-name-specifier template(opt) unqualified-id */
232 static void
233 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
235 switch (TREE_CODE (t))
237 /* A pointer-to-member is always qualified. */
238 case PTRMEM_CST:
239 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
240 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
241 break;
243 /* In Standard C++, functions cannot possibly be used as
244 nested-name-specifiers. However, there are situations where
245 is "makes sense" to output the surrounding function name for the
246 purpose of emphasizing on the scope kind. Just printing the
247 function name might not be sufficient as it may be overloaded; so,
248 we decorate the function with its signature too.
249 FIXME: This is probably the wrong pretty-printing for conversion
250 functions and some function templates. */
251 case OVERLOAD:
252 t = OVL_CURRENT (t);
253 case FUNCTION_DECL:
254 if (DECL_FUNCTION_MEMBER_P (t))
255 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
256 pp_cxx_unqualified_id
257 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
258 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
259 break;
261 case OFFSET_REF:
262 case SCOPE_REF:
263 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
264 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
265 break;
267 default:
269 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
270 if (scope != pp->enclosing_scope)
272 pp_cxx_nested_name_specifier (pp, scope);
273 pp_cxx_template_keyword_if_needed (pp, scope, t);
275 pp_cxx_unqualified_id (pp, t);
277 break;
281 /* id-expression:
282 unqualified-id
283 qualified-id */
285 static inline void
286 pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
288 if (TREE_CODE (t) == OVERLOAD)
289 t = OVL_CURRENT (t);
290 if (DECL_P (t) && DECL_CONTEXT (t))
291 pp_cxx_qualified_id (pp, t);
292 else
293 pp_cxx_unqualified_id (pp, t);
296 /* primary-expression:
297 literal
298 this
299 :: identifier
300 :: operator-function-id
301 :: qualifier-id
302 ( expression )
303 id-expression */
305 static void
306 pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
308 switch (TREE_CODE (t))
310 case STRING_CST:
311 case INTEGER_CST:
312 case REAL_CST:
313 pp_c_constant (pp_c_base (pp), t);
314 break;
316 case BASELINK:
317 t = BASELINK_FUNCTIONS (t);
318 case VAR_DECL:
319 case PARM_DECL:
320 case FIELD_DECL:
321 case FUNCTION_DECL:
322 case OVERLOAD:
323 case CONST_DECL:
324 case TEMPLATE_DECL:
325 pp_cxx_id_expression (pp, t);
326 break;
328 case RESULT_DECL:
329 case TEMPLATE_TYPE_PARM:
330 case TEMPLATE_PARM_INDEX:
331 pp_cxx_unqualified_id (pp, t);
332 break;
334 default:
335 pp_c_primary_expression (pp_c_base (pp), t);
336 break;
340 /* postfix-expression:
341 primary-expression
342 postfix-expression [ expression ]
343 postfix-expression ( expression-list(opt) )
344 simple-type-specifier ( expression-list(opt) )
345 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
346 typename ::(opt) nested-name-specifier template(opt)
347 template-id ( expression-list(opt) )
348 postfix-expression . template(opt) ::(opt) id-expression
349 postfix-expression -> template(opt) ::(opt) id-expression
350 postfix-expression . pseudo-destructor-name
351 postfix-expression -> pseudo-destructor-name
352 postfix-expression ++
353 postfix-expression --
354 dynamic_cast < type-id > ( expression )
355 static_cast < type-id > ( expression )
356 reinterpret_cast < type-id > ( expression )
357 const_cast < type-id > ( expression )
358 typeid ( expression )
359 typeif ( type-id ) */
361 static void
362 pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
364 enum tree_code code = TREE_CODE (t);
366 switch (code)
368 case AGGR_INIT_EXPR:
369 case CALL_EXPR:
371 tree fun = TREE_OPERAND (t, 0);
372 tree args = TREE_OPERAND (t, 1);
373 tree saved_scope = pp->enclosing_scope;
375 if (TREE_CODE (fun) == ADDR_EXPR)
376 fun = TREE_OPERAND (fun, 0);
378 /* In templates, where there is no way to tell whether a given
379 call uses an actual member function. So the parser builds
380 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
381 instantiation time. */
382 if (TREE_CODE (fun) != FUNCTION_DECL)
384 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
386 tree object = code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
387 ? TREE_OPERAND (t, 2)
388 : TREE_VALUE (args);
390 while (TREE_CODE (object) == NOP_EXPR)
391 object = TREE_OPERAND (object, 0);
393 if (TREE_CODE (object) == ADDR_EXPR)
394 object = TREE_OPERAND (object, 0);
396 if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
398 pp_cxx_postfix_expression (pp, object);
399 pp_cxx_dot (pp);
401 else
403 pp_cxx_postfix_expression (pp, object);
404 pp_cxx_arrow (pp);
406 args = TREE_CHAIN (args);
407 pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
410 pp_cxx_postfix_expression (pp, fun);
411 pp->enclosing_scope = saved_scope;
412 pp_cxx_call_argument_list (pp, args);
414 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
416 pp_separate_with (pp, ',');
417 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 2));
419 break;
421 case BASELINK:
422 case VAR_DECL:
423 case PARM_DECL:
424 case FIELD_DECL:
425 case FUNCTION_DECL:
426 case OVERLOAD:
427 case CONST_DECL:
428 case TEMPLATE_DECL:
429 case RESULT_DECL:
430 pp_cxx_primary_expression (pp, t);
431 break;
433 case DYNAMIC_CAST_EXPR:
434 case STATIC_CAST_EXPR:
435 case REINTERPRET_CAST_EXPR:
436 case CONST_CAST_EXPR:
437 if (code == DYNAMIC_CAST_EXPR)
438 pp_identifier (pp, "dynamic_cast");
439 else if (code == STATIC_CAST_EXPR)
440 pp_identifier (pp, "static_cast");
441 else if (code == REINTERPRET_CAST_EXPR)
442 pp_identifier (pp, "reinterpret_cast");
443 else
444 pp_identifier (pp, "const_cast");
445 pp_cxx_begin_template_argument_list (pp);
446 pp_cxx_type_id (pp, TREE_TYPE (t));
447 pp_cxx_end_template_argument_list (pp);
448 pp_left_paren (pp);
449 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
450 pp_right_paren (pp);
451 break;
453 case EMPTY_CLASS_EXPR:
454 pp_cxx_type_id (pp, TREE_TYPE (t));
455 pp_left_paren (pp);
456 pp_right_paren (pp);
457 break;
459 case TYPEID_EXPR:
460 t = TREE_OPERAND (t, 0);
461 pp_cxx_identifier (pp, "typeid");
462 pp_left_paren (pp);
463 if (TYPE_P (t))
464 pp_cxx_type_id (pp, t);
465 else
466 pp_cxx_expression (pp, t);
467 pp_right_paren (pp);
468 break;
470 case PSEUDO_DTOR_EXPR:
471 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
472 pp_cxx_dot (pp);
473 pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
474 pp_cxx_colon_colon (pp);
475 pp_complement (pp);
476 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
477 break;
479 default:
480 pp_c_postfix_expression (pp_c_base (pp), t);
481 break;
485 /* new-expression:
486 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
487 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
489 new-placement:
490 ( expression-list )
492 new-type-id:
493 type-specifier-seq new-declarator(opt)
495 new-declarator:
496 ptr-operator new-declarator(opt)
497 direct-new-declarator
499 direct-new-declarator
500 [ expression ]
501 direct-new-declarator [ constant-expression ]
503 new-initializer:
504 ( expression-list(opt) ) */
506 static void
507 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
509 enum tree_code code = TREE_CODE (t);
510 switch (code)
512 case NEW_EXPR:
513 case VEC_NEW_EXPR:
514 if (NEW_EXPR_USE_GLOBAL (t))
515 pp_cxx_colon_colon (pp);
516 pp_cxx_identifier (pp, "new");
517 if (TREE_OPERAND (t, 0))
519 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
520 pp_space (pp);
522 /* FIXME: array-types are built with one more element. */
523 pp_cxx_type_id (pp, TREE_OPERAND (t, 1));
524 if (TREE_OPERAND (t, 2))
526 pp_left_paren (pp);
527 t = TREE_OPERAND (t, 2);
528 if (TREE_CODE (t) == TREE_LIST)
529 pp_c_expression_list (pp_c_base (pp), t);
530 else if (t == void_zero_node)
531 ; /* OK, empty initializer list. */
532 else
533 pp_cxx_expression (pp, t);
534 pp_right_paren (pp);
536 break;
538 default:
539 pp_unsupported_tree (pp, t);
543 /* delete-expression:
544 ::(opt) delete cast-expression
545 ::(opt) delete [ ] cast-expression */
547 static void
548 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
550 enum tree_code code = TREE_CODE (t);
551 switch (code)
553 case DELETE_EXPR:
554 case VEC_DELETE_EXPR:
555 if (DELETE_EXPR_USE_GLOBAL (t))
556 pp_cxx_colon_colon (pp);
557 pp_cxx_identifier (pp, "delete");
558 if (code == VEC_DELETE_EXPR)
560 pp_left_bracket (pp);
561 pp_right_bracket (pp);
563 pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
564 break;
566 default:
567 pp_unsupported_tree (pp, t);
571 /* unary-expression:
572 postfix-expression
573 ++ cast-expression
574 -- cast-expression
575 unary-operator cast-expression
576 sizeof unary-expression
577 sizeof ( type-id )
578 new-expression
579 delete-expression
581 unary-operator: one of
582 * & + - !
584 GNU extensions:
585 __alignof__ unary-expression
586 __alignof__ ( type-id ) */
588 static void
589 pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
591 enum tree_code code = TREE_CODE (t);
592 switch (code)
594 case NEW_EXPR:
595 case VEC_NEW_EXPR:
596 pp_cxx_new_expression (pp, t);
597 break;
599 case DELETE_EXPR:
600 case VEC_DELETE_EXPR:
601 pp_cxx_delete_expression (pp, t);
602 break;
604 default:
605 pp_c_unary_expression (pp_c_base (pp), t);
606 break;
610 /* cast-expression:
611 unary-expression
612 ( type-id ) cast-expression */
614 static void
615 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
617 switch (TREE_CODE (t))
619 case CAST_EXPR:
620 pp_cxx_type_id (pp, TREE_TYPE (t));
621 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
622 break;
624 default:
625 pp_c_cast_expression (pp_c_base (pp), t);
626 break;
630 /* pm-expression:
631 cast-expression
632 pm-expression .* cast-expression
633 pm-expression ->* cast-expression */
635 static void
636 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
638 switch (TREE_CODE (t))
640 /* Handle unfortunate OFFESET_REF overloading here. */
641 case OFFSET_REF:
642 if (TYPE_P (TREE_OPERAND (t, 0)))
644 pp_cxx_qualified_id (pp, t);
645 break;
647 /* Else fall through. */
648 case MEMBER_REF:
649 case DOTSTAR_EXPR:
650 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
651 pp_cxx_dot (pp);
652 pp_star(pp);
653 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
654 break;
657 default:
658 pp_cxx_cast_expression (pp, t);
659 break;
663 /* multiplicative-expression:
664 pm-expression
665 multiplicative-expression * pm-expression
666 multiplicative-expression / pm-expression
667 multiplicative-expression % pm-expression */
669 static void
670 pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
672 enum tree_code code = TREE_CODE (e);
673 switch (code)
675 case MULT_EXPR:
676 case TRUNC_DIV_EXPR:
677 case TRUNC_MOD_EXPR:
678 pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
679 pp_space (pp);
680 if (code == MULT_EXPR)
681 pp_star (pp);
682 else if (code == TRUNC_DIV_EXPR)
683 pp_slash (pp);
684 else
685 pp_modulo (pp);
686 pp_space (pp);
687 pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
688 break;
690 default:
691 pp_cxx_pm_expression (pp, e);
692 break;
696 /* conditional-expression:
697 logical-or-expression
698 logical-or-expression ? expression : assignment-expression */
700 static void
701 pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
703 if (TREE_CODE (e) == COND_EXPR)
705 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
706 pp_space (pp);
707 pp_question (pp);
708 pp_space (pp);
709 pp_cxx_expression (pp, TREE_OPERAND (e, 1));
710 pp_space (pp);
711 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
713 else
714 pp_c_logical_or_expression (pp_c_base (pp), e);
717 /* Pretty-print a compound assignment operator token as indicated by T. */
719 static void
720 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
722 const char *op;
724 switch (TREE_CODE (t))
726 case NOP_EXPR:
727 op = "=";
728 break;
730 case PLUS_EXPR:
731 op = "+=";
732 break;
734 case MINUS_EXPR:
735 op = "-=";
736 break;
738 case TRUNC_DIV_EXPR:
739 op = "/=";
740 break;
742 case TRUNC_MOD_EXPR:
743 op = "%=";
744 break;
746 default:
747 op = tree_code_name[TREE_CODE (t)];
748 break;
751 pp_cxx_identifier (pp, op);
755 /* assignment-expression:
756 conditional-expression
757 logical-or-expression assignment-operator assignment-expression
758 throw-expression
760 throw-expression:
761 throw assignment-expression(opt)
763 assignment-operator: one of
764 = *= /= %= += -= >>= <<= &= ^= |= */
766 static void
767 pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
769 switch (TREE_CODE (e))
771 case MODIFY_EXPR:
772 case INIT_EXPR:
773 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
774 pp_space (pp);
775 pp_equal (pp);
776 pp_space (pp);
777 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
778 break;
780 case THROW_EXPR:
781 pp_cxx_identifier (pp, "throw");
782 if (TREE_OPERAND (e, 0))
783 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
784 break;
786 case MODOP_EXPR:
787 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
788 pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
789 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
790 break;
792 default:
793 pp_cxx_conditional_expression (pp, e);
794 break;
798 static void
799 pp_cxx_expression (cxx_pretty_printer *pp, tree t)
801 switch (TREE_CODE (t))
803 case STRING_CST:
804 case INTEGER_CST:
805 case REAL_CST:
806 pp_c_constant (pp_c_base (pp), t);
807 break;
809 case RESULT_DECL:
810 pp_cxx_unqualified_id (pp, t);
811 break;
813 #if 0
814 case OFFSET_REF:
815 #endif
816 case SCOPE_REF:
817 case PTRMEM_CST:
818 pp_cxx_qualified_id (pp, t);
819 break;
821 case OVERLOAD:
822 t = OVL_CURRENT (t);
823 case VAR_DECL:
824 case PARM_DECL:
825 case FIELD_DECL:
826 case CONST_DECL:
827 case FUNCTION_DECL:
828 case BASELINK:
829 case TEMPLATE_DECL:
830 case TEMPLATE_TYPE_PARM:
831 case TEMPLATE_PARM_INDEX:
832 pp_cxx_primary_expression (pp, t);
833 break;
835 case CALL_EXPR:
836 case DYNAMIC_CAST_EXPR:
837 case STATIC_CAST_EXPR:
838 case REINTERPRET_CAST_EXPR:
839 case CONST_CAST_EXPR:
840 #if 0
841 case MEMBER_REF:
842 #endif
843 case EMPTY_CLASS_EXPR:
844 case TYPEID_EXPR:
845 case PSEUDO_DTOR_EXPR:
846 case AGGR_INIT_EXPR:
847 pp_cxx_postfix_expression (pp, t);
848 break;
850 case NEW_EXPR:
851 case VEC_NEW_EXPR:
852 pp_cxx_new_expression (pp, t);
853 break;
855 case DELETE_EXPR:
856 case VEC_DELETE_EXPR:
857 pp_cxx_delete_expression (pp, t);
858 break;
860 case CAST_EXPR:
861 pp_cxx_cast_expression (pp, t);
862 break;
864 case OFFSET_REF:
865 case MEMBER_REF:
866 case DOTSTAR_EXPR:
867 pp_cxx_pm_expression (pp, t);
868 break;
870 case MULT_EXPR:
871 case TRUNC_DIV_EXPR:
872 case TRUNC_MOD_EXPR:
873 pp_cxx_multiplicative_expression (pp, t);
874 break;
876 case COND_EXPR:
877 pp_cxx_conditional_expression (pp, t);
878 break;
880 case MODIFY_EXPR:
881 case INIT_EXPR:
882 case THROW_EXPR:
883 case MODOP_EXPR:
884 pp_cxx_assignment_expression (pp, t);
885 break;
887 case NON_DEPENDENT_EXPR:
888 case MUST_NOT_THROW_EXPR:
889 pp_cxx_expression (pp, t);
890 break;
892 default:
893 pp_c_expression (pp_c_base (pp), t);
894 break;
899 /* Declarations. */
901 /* function-specifier:
902 inline
903 virtual
904 explicit */
906 static void
907 pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
909 switch (TREE_CODE (t))
911 case FUNCTION_DECL:
912 if (DECL_VIRTUAL_P (t))
913 pp_cxx_identifier (pp, "virtual");
914 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
915 pp_cxx_identifier (pp, "explicit");
916 else
917 pp_c_function_specifier (pp_c_base (pp), t);
919 default:
920 break;
924 /* decl-specifier-seq:
925 decl-specifier-seq(opt) decl-specifier
927 decl-specifier:
928 storage-class-specifier
929 type-specifier
930 function-specifier
931 friend
932 typedef */
934 static void
935 pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
937 switch (TREE_CODE (t))
939 case VAR_DECL:
940 case PARM_DECL:
941 case CONST_DECL:
942 case FIELD_DECL:
943 pp_cxx_storage_class_specifier (pp, t);
944 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
945 break;
947 case TYPE_DECL:
948 pp_cxx_identifier (pp, "typedef");
949 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
950 break;
952 case RECORD_TYPE:
953 if (TYPE_PTRMEMFUNC_P (t))
955 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
956 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
957 pp_cxx_whitespace (pp);
958 pp_cxx_ptr_operator (pp, t);
960 break;
962 case FUNCTION_DECL:
963 /* Constructors don't have return types. And conversion functions
964 do not have a type-specifier in their return types. */
965 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
966 pp_cxx_function_specifier (pp, t);
967 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
968 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
969 else
970 default:
971 pp_c_declaration_specifiers (pp_c_base (pp), t);
972 break;
976 /* simple-type-specifier:
977 ::(opt) nested-name-specifier(opt) type-name
978 ::(opt) nested-name-specifier(opt) template(opt) template-id
979 char
980 wchar_t
981 bool
982 short
984 long
985 signed
986 unsigned
987 float
988 double
989 void */
991 static void
992 pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
994 switch (TREE_CODE (t))
996 case RECORD_TYPE:
997 case UNION_TYPE:
998 case ENUMERAL_TYPE:
999 pp_cxx_qualified_id (pp, t);
1000 break;
1002 case TEMPLATE_TYPE_PARM:
1003 case TEMPLATE_PARM_INDEX:
1004 pp_cxx_unqualified_id (pp, t);
1005 break;
1007 case TYPENAME_TYPE:
1008 pp_cxx_identifier (pp, "typename");
1009 pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1010 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1011 break;
1013 default:
1014 pp_c_type_specifier (pp_c_base (pp), t);
1015 break;
1019 /* type-specifier-seq:
1020 type-specifier type-specifier-seq(opt)
1022 type-specifier:
1023 simple-type-specifier
1024 class-specifier
1025 enum-specifier
1026 elaborated-type-specifier
1027 cv-qualifier */
1029 static void
1030 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1032 switch (TREE_CODE (t))
1034 case TEMPLATE_DECL:
1035 case TEMPLATE_TYPE_PARM:
1036 case TYPE_DECL:
1037 case BOUND_TEMPLATE_TEMPLATE_PARM:
1038 pp_c_type_qualifier_list (pp_c_base (pp), t);
1039 pp_cxx_simple_type_specifier (pp, t);
1040 break;
1042 case METHOD_TYPE:
1043 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1044 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1045 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1046 break;
1048 default:
1049 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1050 pp_c_specifier_qualifier_list (pp_c_base (pp), t);
1054 /* ptr-operator:
1055 * cv-qualifier-seq(opt)
1057 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1059 static void
1060 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1062 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1063 t = TREE_TYPE (t);
1064 switch (TREE_CODE (t))
1066 case REFERENCE_TYPE:
1067 case POINTER_TYPE:
1068 if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
1069 || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
1070 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1071 if (TREE_CODE (t) == POINTER_TYPE)
1073 pp_star (pp);
1074 pp_cxx_cv_qualifier_seq (pp, t);
1076 else
1077 pp_ampersand (pp);
1078 break;
1080 case RECORD_TYPE:
1081 if (TYPE_PTRMEMFUNC_P (t))
1083 pp_cxx_left_paren (pp);
1084 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1085 pp_star (pp);
1086 break;
1088 case OFFSET_TYPE:
1089 if (TYPE_PTR_TO_MEMBER_P (t))
1091 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1092 pp_star (pp);
1093 pp_cxx_cv_qualifier_seq (pp, t);
1094 break;
1096 /* else fall through. */
1098 default:
1099 pp_unsupported_tree (pp, t);
1100 break;
1104 static inline tree
1105 pp_cxx_implicit_parameter_type (tree mf)
1107 return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1111 parameter-declaration:
1112 decl-specifier-seq declarator
1113 decl-specifier-seq declarator = assignment-expression
1114 decl-specifier-seq abstract-declarator(opt)
1115 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1117 static inline void
1118 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1120 pp_cxx_decl_specifier_seq (pp, t);
1121 if (TYPE_P (t))
1122 pp_cxx_abstract_declarator (pp, t);
1123 else
1124 pp_cxx_declarator (pp, t);
1127 /* parameter-declaration-clause:
1128 parameter-declaration-list(opt) ...(opt)
1129 parameter-declaration-list , ...
1131 parameter-declaration-list:
1132 parameter-declaration
1133 parameter-declaration-list , parameter-declaration */
1135 static void
1136 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1138 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1139 tree types = TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1140 const bool abstract = args == NULL
1141 || pp_c_base (pp)->flags & pp_c_flag_abstract;
1142 bool first = true;
1144 /* Skip artificial parameter for nonstatic member functions. */
1145 if (TREE_CODE (t) == METHOD_TYPE)
1146 types = TREE_CHAIN (types);
1148 pp_cxx_left_paren (pp);
1149 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1151 if (!first)
1152 pp_separate_with (pp, ',');
1153 first = false;
1154 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1155 if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1157 pp_cxx_whitespace (pp);
1158 pp_equal (pp);
1159 pp_cxx_whitespace (pp);
1160 pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1163 pp_cxx_right_paren (pp);
1166 /* exception-specification:
1167 throw ( type-id-list(opt) )
1169 type-id-list
1170 type-id
1171 type-id-list , type-id */
1173 static void
1174 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1176 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1178 if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1179 return;
1180 pp_cxx_identifier (pp, "throw");
1181 pp_cxx_left_paren (pp);
1182 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1184 pp_cxx_type_id (pp, TREE_VALUE (ex_spec));
1185 if (TREE_CHAIN (ex_spec))
1186 pp_separate_with (pp, ',');
1188 pp_cxx_right_paren (pp);
1191 /* direct-declarator:
1192 declarator-id
1193 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1194 exception-specification(opt)
1195 direct-declaration [ constant-expression(opt) ]
1196 ( declarator ) */
1198 static void
1199 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1201 switch (TREE_CODE (t))
1203 case VAR_DECL:
1204 case PARM_DECL:
1205 case CONST_DECL:
1206 case FIELD_DECL:
1207 if (DECL_NAME (t))
1209 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1210 pp_cxx_id_expression (pp, DECL_NAME (t));
1212 pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1213 break;
1215 case FUNCTION_DECL:
1216 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1217 pp_cxx_id_expression (pp, t);
1218 pp_cxx_parameter_declaration_clause (pp, t);
1220 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1222 pp_base (pp)->padding = pp_before;
1223 pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1226 pp_cxx_exception_specification (pp, TREE_TYPE (t));
1227 break;
1229 case TYPENAME_TYPE:
1230 case TEMPLATE_DECL:
1231 case TEMPLATE_TYPE_PARM:
1232 case TEMPLATE_PARM_INDEX:
1233 break;
1235 default:
1236 pp_c_direct_declarator (pp_c_base (pp), t);
1237 break;
1241 /* declarator:
1242 direct-declarator
1243 ptr-operator declarator */
1245 static void
1246 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1248 pp_cxx_direct_declarator (pp, t);
1251 /* ctor-initializer:
1252 : mem-initializer-list
1254 mem-initializer-list:
1255 mem-initializer
1256 mem-initializer , mem-initializer-list
1258 mem-initializer:
1259 mem-initializer-id ( expression-list(opt) )
1261 mem-initializer-id:
1262 ::(opt) nested-name-specifier(opt) class-name
1263 identifier */
1265 static void
1266 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1268 t = TREE_OPERAND (t, 0);
1269 pp_cxx_whitespace (pp);
1270 pp_colon (pp);
1271 pp_cxx_whitespace (pp);
1272 for (; t; t = TREE_CHAIN (t))
1274 pp_cxx_primary_expression (pp, TREE_PURPOSE (t));
1275 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1276 if (TREE_CHAIN (t))
1277 pp_separate_with (pp, ',');
1281 /* function-definition:
1282 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1283 decl-specifier-seq(opt) declarator function-try-block */
1285 void
1286 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1288 tree saved_scope = pp->enclosing_scope;
1289 pp_cxx_decl_specifier_seq (pp, t);
1290 pp_cxx_declarator (pp, t);
1291 pp_needs_newline (pp) = true;
1292 pp->enclosing_scope = DECL_CONTEXT (t);
1293 if (DECL_SAVED_TREE (t))
1295 tree body = DECL_SAVED_TREE (t);
1296 if (TREE_CODE (body) == COMPOUND_STMT
1297 && TREE_CODE (COMPOUND_BODY (body)) == CTOR_INITIALIZER)
1299 body = COMPOUND_BODY (body);
1300 pp_cxx_ctor_initializer (pp, body);
1301 body = TREE_CHAIN (body);
1303 pp_cxx_statement (pp, body);
1305 else
1307 pp_cxx_semicolon (pp);
1308 pp_needs_newline (pp) = true;
1310 pp_flush (pp);
1311 pp->enclosing_scope = saved_scope;
1314 /* abstract-declarator:
1315 ptr-operator abstract-declarator(opt)
1316 direct-abstract-declarator */
1318 static void
1319 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1321 if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1322 pp_cxx_right_paren (pp);
1323 else if (POINTER_TYPE_P (t))
1325 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1326 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1327 pp_cxx_right_paren (pp);
1328 t = TREE_TYPE (t);
1330 pp_cxx_direct_abstract_declarator (pp, t);
1333 /* direct-abstract-declarator:
1334 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1335 cv-qualifier-seq(opt) exception-specification(opt)
1336 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1337 ( abstract-declarator ) */
1339 static void
1340 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1342 switch (TREE_CODE (t))
1344 case REFERENCE_TYPE:
1345 pp_cxx_abstract_declarator (pp, t);
1346 break;
1348 case RECORD_TYPE:
1349 if (TYPE_PTRMEMFUNC_P (t))
1350 pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1351 break;
1353 case METHOD_TYPE:
1354 case FUNCTION_TYPE:
1355 pp_cxx_parameter_declaration_clause (pp, t);
1356 pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1357 if (TREE_CODE (t) == METHOD_TYPE)
1359 pp_base (pp)->padding = pp_before;
1360 pp_cxx_cv_qualifier_seq
1361 (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1363 pp_cxx_exception_specification (pp, t);
1364 break;
1366 case TYPENAME_TYPE:
1367 case TEMPLATE_TYPE_PARM:
1368 case TEMPLATE_TEMPLATE_PARM:
1369 case BOUND_TEMPLATE_TEMPLATE_PARM:
1370 case UNBOUND_CLASS_TEMPLATE:
1371 break;
1373 default:
1374 pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1375 break;
1379 /* type-id:
1380 type-specifier-seq abstract-declarator(opt) */
1382 static void
1383 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1385 pp_flags saved_flags = pp_c_base (pp)->flags;
1386 pp_c_base (pp)->flags |= pp_c_flag_abstract;
1388 switch (TREE_CODE (t))
1390 case TYPE_DECL:
1391 case UNION_TYPE:
1392 case RECORD_TYPE:
1393 case ENUMERAL_TYPE:
1394 case TYPENAME_TYPE:
1395 case BOUND_TEMPLATE_TEMPLATE_PARM:
1396 case UNBOUND_CLASS_TEMPLATE:
1397 case TEMPLATE_TEMPLATE_PARM:
1398 case TEMPLATE_TYPE_PARM:
1399 case TEMPLATE_PARM_INDEX:
1400 case TEMPLATE_DECL:
1401 case TYPEOF_TYPE:
1402 case TEMPLATE_ID_EXPR:
1403 /* FIXME: Should be pp_cxx_type_specifier_seq. */
1404 pp_cxx_type_specifier_seq (pp, t);
1405 pp_cxx_declarator (pp, t);
1406 break;
1408 default:
1409 pp_c_type_id (pp_c_base (pp), t);
1410 break;
1413 pp_c_base (pp)->flags = saved_flags;
1416 /* template-argument-list:
1417 template-argument
1418 template-argument-list, template-argument
1420 template-argument:
1421 assignment-expression
1422 type-id
1423 template-name */
1425 static void
1426 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1428 int i;
1429 if (t == NULL)
1430 return;
1431 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1433 tree arg = TREE_VEC_ELT (t, i);
1434 if (i != 0)
1435 pp_separate_with (pp, ',');
1436 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1437 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1438 pp_cxx_type_id (pp, arg);
1439 else
1440 pp_cxx_expression (pp, arg);
1445 static void
1446 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1448 t = DECL_STMT_DECL (t);
1449 pp_cxx_type_specifier_seq (pp, t);
1450 if (TYPE_P (t))
1451 pp_cxx_abstract_declarator (pp, t);
1452 else
1453 pp_cxx_declarator (pp, t);
1456 /* Statements. */
1458 void
1459 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1461 switch (TREE_CODE (t))
1463 case USING_STMT:
1464 pp_cxx_identifier (pp, "using");
1465 pp_cxx_identifier (pp, "namespace");
1466 pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1467 break;
1469 case USING_DECL:
1470 pp_cxx_identifier (pp, "using");
1471 pp_cxx_nested_name_specifier (pp, DECL_INITIAL (t));
1472 pp_cxx_unqualified_id (pp, DECL_NAME (t));
1473 break;
1475 case EH_SPEC_BLOCK:
1476 break;
1478 /* try-block:
1479 try compound-statement handler-seq */
1480 case TRY_BLOCK:
1481 pp_maybe_newline_and_indent (pp, 0);
1482 pp_cxx_identifier (pp, "try");
1483 pp_newline_and_indent (pp, 3);
1484 pp_cxx_statement (pp, TRY_STMTS (t));
1485 pp_newline_and_indent (pp, -3);
1486 if (CLEANUP_P (t))
1488 else
1489 pp_cxx_statement (pp, TRY_HANDLERS (t));
1490 break;
1493 handler-seq:
1494 handler handler-seq(opt)
1496 handler:
1497 catch ( exception-declaration ) compound-statement
1499 exception-declaration:
1500 type-specifier-seq declarator
1501 type-specifier-seq abstract-declarator
1502 ... */
1503 case HANDLER:
1504 pp_cxx_identifier (pp, "catch");
1505 pp_cxx_left_paren (pp);
1506 pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1507 pp_cxx_right_paren (pp);
1508 pp_indentation (pp) += 3;
1509 pp_needs_newline (pp) = true;
1510 pp_cxx_statement (pp, HANDLER_BODY (t));
1511 pp_indentation (pp) -= 3;
1512 pp_needs_newline (pp) = true;
1513 break;
1515 default:
1516 pp_c_statement (pp_c_base (pp), t);
1517 break;
1521 /* original-namespace-definition:
1522 namespace identifier { namespace-body }
1524 As an edge case, we also handle unnamed namespace definition here. */
1526 static void
1527 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1529 pp_cxx_identifier (pp, "namespace");
1530 if (DECL_NAME (t))
1531 pp_cxx_unqualified_id (pp, t);
1532 pp_cxx_whitespace (pp);
1533 pp_cxx_left_brace (pp);
1534 /* We do not print the namespace-body. */
1535 pp_cxx_whitespace (pp);
1536 pp_cxx_right_brace (pp);
1539 /* namespace-alias:
1540 identifier
1542 namespace-alias-definition:
1543 namespace identifier = qualified-namespace-specifier ;
1545 qualified-namespace-specifier:
1546 ::(opt) nested-name-specifier(opt) namespace-name */
1548 static void
1549 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1551 pp_cxx_identifier (pp, "namespace");
1552 pp_cxx_unqualified_id (pp, t);
1553 pp_cxx_whitespace (pp);
1554 pp_equal (pp);
1555 pp_cxx_whitespace (pp);
1556 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1557 pp_cxx_semicolon (pp);
1560 /* simple-declaration:
1561 decl-specifier-seq(opt) init-declarator-list(opt) */
1563 static void
1564 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1566 pp_cxx_decl_specifier_seq (pp, t);
1567 pp_cxx_init_declarator (pp, t);
1568 pp_cxx_semicolon (pp);
1569 pp_needs_newline (pp) = true;
1573 template-parameter-list:
1574 template-parameter
1575 template-parameter-list , template-parameter */
1577 static inline void
1578 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1580 const int n = TREE_VEC_LENGTH (t);
1581 int i;
1582 for (i = 0; i < n; ++i)
1584 if (i)
1585 pp_separate_with (pp, ',');
1586 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1590 /* template-parameter:
1591 type-parameter
1592 parameter-declaration
1594 type-parameter:
1595 class identifier(opt)
1596 class identifier(op) = type-id
1597 typename identifier(opt)
1598 typename identifier(opt) = type-id
1599 template < template-parameter-list > class identifier(opt)
1600 template < template-parameter-list > class identifier(opt) = template-name
1603 static void
1604 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
1606 tree parameter = TREE_VALUE (t);
1607 switch (TREE_CODE (parameter))
1609 case TYPE_DECL:
1610 pp_cxx_identifier (pp, "class");
1611 if (DECL_NAME (parameter))
1612 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
1613 /* FIXME: Chech if we should print also default argument. */
1614 break;
1616 case PARM_DECL:
1617 pp_cxx_parameter_declaration (pp, parameter);
1618 break;
1620 case TEMPLATE_DECL:
1621 break;
1623 default:
1624 pp_unsupported_tree (pp, t);
1625 break;
1629 /* Pretty-print a template parameter in the canonical form
1630 "template-parameter-<level>-<position in parameter list>". */
1632 void
1633 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
1635 const enum tree_code code = TREE_CODE (parm);
1637 /* Brings type template parameters to the canonical forms. */
1638 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
1639 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
1640 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
1642 pp_cxx_begin_template_argument_list (pp);
1643 pp_cxx_identifier (pp, "template-parameter-");
1644 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
1645 pp_minus (pp);
1646 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
1647 pp_cxx_end_template_argument_list (pp);
1651 template-declaration:
1652 export(opt) template < template-parameter-list > declaration */
1654 static void
1655 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
1657 tree tmpl = most_general_template (t);
1658 tree level;
1659 int i = 0;
1661 pp_maybe_newline_and_indent (pp, 0);
1662 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
1664 pp_cxx_identifier (pp, "template");
1665 pp_cxx_begin_template_argument_list (pp);
1666 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
1667 pp_cxx_end_template_argument_list (pp);
1668 pp_newline_and_indent (pp, 3);
1669 i += 3;
1671 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
1672 pp_cxx_function_definition (pp, t);
1673 else
1674 pp_cxx_simple_declaration (pp, t);
1677 static void
1678 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
1680 pp_unsupported_tree (pp, t);
1683 static void
1684 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
1686 pp_unsupported_tree (pp, t);
1690 declaration:
1691 block-declaration
1692 function-definition
1693 template-declaration
1694 explicit-instantiation
1695 explicit-specialization
1696 linkage-specification
1697 namespace-definition
1699 block-declaration:
1700 simple-declaration
1701 asm-definition
1702 namespace-alias-definition
1703 using-declaration
1704 using-directive */
1705 void
1706 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
1708 if (!DECL_LANG_SPECIFIC (t))
1709 pp_cxx_simple_declaration (pp, t);
1710 else if (DECL_USE_TEMPLATE (t))
1711 switch (DECL_USE_TEMPLATE (t))
1713 case 1:
1714 pp_cxx_template_declaration (pp, t);
1715 break;
1717 case 2:
1718 pp_cxx_explicit_specialization (pp, t);
1719 break;
1721 case 3:
1722 pp_cxx_explicit_instantiation (pp, t);
1723 break;
1725 default:
1726 break;
1728 else switch (TREE_CODE (t))
1730 case VAR_DECL:
1731 case TYPE_DECL:
1732 pp_cxx_simple_declaration (pp, t);
1733 break;
1735 case FUNCTION_DECL:
1736 if (DECL_SAVED_TREE (t))
1737 pp_cxx_function_definition (pp, t);
1738 else
1739 pp_cxx_simple_declaration (pp, t);
1740 break;
1742 case NAMESPACE_DECL:
1743 if (DECL_NAMESPACE_ALIAS (t))
1744 pp_cxx_namespace_alias_definition (pp, t);
1745 else
1746 pp_cxx_original_namespace_definition (pp, t);
1747 break;
1749 default:
1750 pp_unsupported_tree (pp, t);
1751 break;
1756 typedef c_pretty_print_fn pp_fun;
1758 /* Initialization of a C++ pretty-printer object. */
1760 void
1761 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
1763 pp_c_pretty_printer_init (pp_c_base (pp));
1764 pp_set_line_maximum_length (pp, 0);
1766 pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
1767 pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
1768 pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
1769 pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
1770 pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
1771 pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
1772 pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
1773 pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
1774 pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
1775 pp->c_base.direct_abstract_declarator =
1776 (pp_fun) pp_cxx_direct_abstract_declarator;
1777 pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
1779 /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
1781 pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
1782 pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
1783 pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
1784 pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
1785 pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
1786 pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
1787 pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
1788 pp->c_base.expression = (pp_fun) pp_cxx_expression;
1789 pp->enclosing_scope = global_namespace;