c5e667d9495f9efbaff808f07c0a5e467558d6e8
[gcc.git] / gcc / cp / cxx-pretty-print.c
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>
4
5 This file is part of GCC.
6
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.
11
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.
16
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. */
21
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"
30
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);
45 \f
46
47 static inline void
48 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
49 {
50 const char *p = pp_last_position_in_text (pp);
51
52 if (p != NULL && *p == c)
53 pp_cxx_whitespace (pp);
54 pp_character (pp, c);
55 pp_base (pp)->padding = pp_none;
56 }
57
58 #define pp_cxx_storage_class_specifier(PP, T) \
59 pp_c_storage_class_specifier (pp_c_base (PP), T)
60 #define pp_cxx_expression_list(PP, T) \
61 pp_c_expression_list (pp_c_base (PP), T)
62 #define pp_cxx_space_for_pointer_operator(PP, T) \
63 pp_c_space_for_pointer_operator (pp_c_base (PP), T)
64 #define pp_cxx_init_declarator(PP, T) \
65 pp_c_init_declarator (pp_c_base (PP), T)
66 #define pp_cxx_call_argument_list(PP, T) \
67 pp_c_call_argument_list (pp_c_base (PP), T)
68
69 void
70 pp_cxx_colon_colon (cxx_pretty_printer *pp)
71 {
72 pp_colon_colon (pp);
73 pp_base (pp)->padding = pp_none;
74 }
75
76 void
77 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
78 {
79 pp_cxx_nonconsecutive_character (pp, '<');
80 }
81
82 void
83 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
84 {
85 pp_cxx_nonconsecutive_character (pp, '>');
86 }
87
88 void
89 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
90 {
91 pp_separate_with (pp, c);
92 pp_base (pp)->padding = pp_none;
93 }
94
95 /* Expressions. */
96
97 static inline bool
98 is_destructor_name (tree name)
99 {
100 return name == complete_dtor_identifier
101 || name == base_dtor_identifier
102 || name == deleting_dtor_identifier;
103 }
104
105 /* conversion-function-id:
106 operator conversion-type-id
107
108 conversion-type-id:
109 type-specifier-seq conversion-declarator(opt)
110
111 conversion-declarator:
112 ptr-operator conversion-declarator(opt) */
113
114 static inline void
115 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
116 {
117 pp_cxx_identifier (pp, "operator");
118 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
119 }
120
121 static inline void
122 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
123 {
124 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
125 pp_cxx_begin_template_argument_list (pp);
126 pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
127 pp_cxx_end_template_argument_list (pp);
128 }
129
130 /* unqualified-id:
131 identifier
132 operator-function-id
133 conversion-function-id
134 ~ class-name
135 template-id */
136
137 static void
138 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
139 {
140 enum tree_code code = TREE_CODE (t);
141 switch (code)
142 {
143 case RESULT_DECL:
144 pp_cxx_identifier (pp, "<return-value>");
145 break;
146
147 case OVERLOAD:
148 t = OVL_CURRENT (t);
149 case VAR_DECL:
150 case PARM_DECL:
151 case CONST_DECL:
152 case TYPE_DECL:
153 case FUNCTION_DECL:
154 case NAMESPACE_DECL:
155 case FIELD_DECL:
156 case LABEL_DECL:
157 case USING_DECL:
158 case TEMPLATE_DECL:
159 t = DECL_NAME (t);
160
161 case IDENTIFIER_NODE:
162 if (t == NULL)
163 pp_cxx_identifier (pp, "<unnamed>");
164 else if (IDENTIFIER_TYPENAME_P (t))
165 pp_cxx_conversion_function_id (pp, t);
166 else
167 {
168 if (is_destructor_name (t))
169 {
170 pp_complement (pp);
171 /* FIXME: Why is this necessary? */
172 if (TREE_TYPE (t))
173 t = constructor_name (TREE_TYPE (t));
174 }
175 pp_cxx_tree_identifier (pp, t);
176 }
177 break;
178
179 case TEMPLATE_ID_EXPR:
180 pp_cxx_template_id (pp, t);
181 break;
182
183 case RECORD_TYPE:
184 case UNION_TYPE:
185 case ENUMERAL_TYPE:
186 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
187 break;
188
189 case TEMPLATE_TYPE_PARM:
190 case TEMPLATE_TEMPLATE_PARM:
191 if (TYPE_IDENTIFIER (t))
192 pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
193 else
194 pp_cxx_canonical_template_parameter (pp, t);
195 break;
196
197 case TEMPLATE_PARM_INDEX:
198 pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
199 break;
200
201 default:
202 pp_unsupported_tree (pp, t);
203 break;
204 }
205 }
206
207 /* Pretty-print out the token sequence ":: template" in template codes
208 where it is needed to "inline declare" the (following) member as
209 a template. This situation arises when SCOPE of T is dependent
210 on template parameters. */
211
212 static inline void
213 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
214 {
215 if (TREE_CODE (t) == TEMPLATE_ID_EXPR
216 && TYPE_P (scope) && dependent_type_p (scope))
217 pp_cxx_identifier (pp, "template");
218 }
219
220 /* nested-name-specifier:
221 class-or-namespace-name :: nested-name-specifier(opt)
222 class-or-namespace-name :: template nested-name-specifier */
223
224 static void
225 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
226 {
227 if (t != NULL && t != pp->enclosing_scope)
228 {
229 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
230 pp_cxx_nested_name_specifier (pp, scope);
231 pp_cxx_template_keyword_if_needed (pp, scope, t);
232 pp_cxx_unqualified_id (pp, t);
233 pp_cxx_colon_colon (pp);
234 }
235 }
236
237 /* qualified-id:
238 nested-name-specifier template(opt) unqualified-id */
239
240 static void
241 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
242 {
243 switch (TREE_CODE (t))
244 {
245 /* A pointer-to-member is always qualified. */
246 case PTRMEM_CST:
247 pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
248 pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
249 break;
250
251 /* In Standard C++, functions cannot possibly be used as
252 nested-name-specifiers. However, there are situations where
253 is "makes sense" to output the surrounding function name for the
254 purpose of emphasizing on the scope kind. Just printing the
255 function name might not be sufficient as it may be overloaded; so,
256 we decorate the function with its signature too.
257 FIXME: This is probably the wrong pretty-printing for conversion
258 functions and some function templates. */
259 case OVERLOAD:
260 t = OVL_CURRENT (t);
261 case FUNCTION_DECL:
262 if (DECL_FUNCTION_MEMBER_P (t))
263 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
264 pp_cxx_unqualified_id
265 (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
266 pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
267 break;
268
269 case OFFSET_REF:
270 case SCOPE_REF:
271 pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
272 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
273 break;
274
275 default:
276 {
277 tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
278 if (scope != pp->enclosing_scope)
279 {
280 pp_cxx_nested_name_specifier (pp, scope);
281 pp_cxx_template_keyword_if_needed (pp, scope, t);
282 }
283 pp_cxx_unqualified_id (pp, t);
284 }
285 break;
286 }
287 }
288
289 /* id-expression:
290 unqualified-id
291 qualified-id */
292
293 static inline void
294 pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
295 {
296 if (TREE_CODE (t) == OVERLOAD)
297 t = OVL_CURRENT (t);
298 if (DECL_P (t) && DECL_CONTEXT (t))
299 pp_cxx_qualified_id (pp, t);
300 else
301 pp_cxx_unqualified_id (pp, t);
302 }
303
304 /* primary-expression:
305 literal
306 this
307 :: identifier
308 :: operator-function-id
309 :: qualifier-id
310 ( expression )
311 id-expression */
312
313 static void
314 pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
315 {
316 switch (TREE_CODE (t))
317 {
318 case STRING_CST:
319 case INTEGER_CST:
320 case REAL_CST:
321 pp_c_constant (pp_c_base (pp), t);
322 break;
323
324 case BASELINK:
325 t = BASELINK_FUNCTIONS (t);
326 case VAR_DECL:
327 case PARM_DECL:
328 case FIELD_DECL:
329 case FUNCTION_DECL:
330 case OVERLOAD:
331 case CONST_DECL:
332 case TEMPLATE_DECL:
333 pp_cxx_id_expression (pp, t);
334 break;
335
336 case RESULT_DECL:
337 case TEMPLATE_TYPE_PARM:
338 case TEMPLATE_TEMPLATE_PARM:
339 case TEMPLATE_PARM_INDEX:
340 pp_cxx_unqualified_id (pp, t);
341 break;
342
343 default:
344 pp_c_primary_expression (pp_c_base (pp), t);
345 break;
346 }
347 }
348
349 /* postfix-expression:
350 primary-expression
351 postfix-expression [ expression ]
352 postfix-expression ( expression-list(opt) )
353 simple-type-specifier ( expression-list(opt) )
354 typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
355 typename ::(opt) nested-name-specifier template(opt)
356 template-id ( expression-list(opt) )
357 postfix-expression . template(opt) ::(opt) id-expression
358 postfix-expression -> template(opt) ::(opt) id-expression
359 postfix-expression . pseudo-destructor-name
360 postfix-expression -> pseudo-destructor-name
361 postfix-expression ++
362 postfix-expression --
363 dynamic_cast < type-id > ( expression )
364 static_cast < type-id > ( expression )
365 reinterpret_cast < type-id > ( expression )
366 const_cast < type-id > ( expression )
367 typeid ( expression )
368 typeif ( type-id ) */
369
370 static void
371 pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
372 {
373 enum tree_code code = TREE_CODE (t);
374
375 switch (code)
376 {
377 case AGGR_INIT_EXPR:
378 case CALL_EXPR:
379 {
380 tree fun = TREE_OPERAND (t, 0);
381 tree args = TREE_OPERAND (t, 1);
382 tree saved_scope = pp->enclosing_scope;
383
384 if (TREE_CODE (fun) == ADDR_EXPR)
385 fun = TREE_OPERAND (fun, 0);
386
387 /* In templates, where there is no way to tell whether a given
388 call uses an actual member function. So the parser builds
389 FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
390 instantiation time. */
391 if (TREE_CODE (fun) != FUNCTION_DECL)
392 ;
393 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
394 {
395 tree object = code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
396 ? TREE_OPERAND (t, 2)
397 : TREE_VALUE (args);
398
399 while (TREE_CODE (object) == NOP_EXPR)
400 object = TREE_OPERAND (object, 0);
401
402 if (TREE_CODE (object) == ADDR_EXPR)
403 object = TREE_OPERAND (object, 0);
404
405 if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
406 {
407 pp_cxx_postfix_expression (pp, object);
408 pp_cxx_dot (pp);
409 }
410 else
411 {
412 pp_cxx_postfix_expression (pp, object);
413 pp_cxx_arrow (pp);
414 }
415 args = TREE_CHAIN (args);
416 pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
417 }
418
419 pp_cxx_postfix_expression (pp, fun);
420 pp->enclosing_scope = saved_scope;
421 pp_cxx_call_argument_list (pp, args);
422 }
423 if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
424 {
425 pp_cxx_separate_with (pp, ',');
426 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 2));
427 }
428 break;
429
430 case BASELINK:
431 case VAR_DECL:
432 case PARM_DECL:
433 case FIELD_DECL:
434 case FUNCTION_DECL:
435 case OVERLOAD:
436 case CONST_DECL:
437 case TEMPLATE_DECL:
438 case RESULT_DECL:
439 pp_cxx_primary_expression (pp, t);
440 break;
441
442 case DYNAMIC_CAST_EXPR:
443 case STATIC_CAST_EXPR:
444 case REINTERPRET_CAST_EXPR:
445 case CONST_CAST_EXPR:
446 if (code == DYNAMIC_CAST_EXPR)
447 pp_cxx_identifier (pp, "dynamic_cast");
448 else if (code == STATIC_CAST_EXPR)
449 pp_cxx_identifier (pp, "static_cast");
450 else if (code == REINTERPRET_CAST_EXPR)
451 pp_cxx_identifier (pp, "reinterpret_cast");
452 else
453 pp_cxx_identifier (pp, "const_cast");
454 pp_cxx_begin_template_argument_list (pp);
455 pp_cxx_type_id (pp, TREE_TYPE (t));
456 pp_cxx_end_template_argument_list (pp);
457 pp_left_paren (pp);
458 pp_cxx_expression (pp, TREE_OPERAND (t, 0));
459 pp_right_paren (pp);
460 break;
461
462 case EMPTY_CLASS_EXPR:
463 pp_cxx_type_id (pp, TREE_TYPE (t));
464 pp_left_paren (pp);
465 pp_right_paren (pp);
466 break;
467
468 case TYPEID_EXPR:
469 t = TREE_OPERAND (t, 0);
470 pp_cxx_identifier (pp, "typeid");
471 pp_left_paren (pp);
472 if (TYPE_P (t))
473 pp_cxx_type_id (pp, t);
474 else
475 pp_cxx_expression (pp, t);
476 pp_right_paren (pp);
477 break;
478
479 case PSEUDO_DTOR_EXPR:
480 pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
481 pp_cxx_dot (pp);
482 pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
483 pp_cxx_colon_colon (pp);
484 pp_complement (pp);
485 pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
486 break;
487
488 default:
489 pp_c_postfix_expression (pp_c_base (pp), t);
490 break;
491 }
492 }
493
494 /* new-expression:
495 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
496 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
497
498 new-placement:
499 ( expression-list )
500
501 new-type-id:
502 type-specifier-seq new-declarator(opt)
503
504 new-declarator:
505 ptr-operator new-declarator(opt)
506 direct-new-declarator
507
508 direct-new-declarator
509 [ expression ]
510 direct-new-declarator [ constant-expression ]
511
512 new-initializer:
513 ( expression-list(opt) ) */
514
515 static void
516 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
517 {
518 enum tree_code code = TREE_CODE (t);
519 switch (code)
520 {
521 case NEW_EXPR:
522 case VEC_NEW_EXPR:
523 if (NEW_EXPR_USE_GLOBAL (t))
524 pp_cxx_colon_colon (pp);
525 pp_cxx_identifier (pp, "new");
526 if (TREE_OPERAND (t, 0))
527 {
528 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
529 pp_space (pp);
530 }
531 /* FIXME: array-types are built with one more element. */
532 pp_cxx_type_id (pp, TREE_OPERAND (t, 1));
533 if (TREE_OPERAND (t, 2))
534 {
535 pp_left_paren (pp);
536 t = TREE_OPERAND (t, 2);
537 if (TREE_CODE (t) == TREE_LIST)
538 pp_c_expression_list (pp_c_base (pp), t);
539 else if (t == void_zero_node)
540 ; /* OK, empty initializer list. */
541 else
542 pp_cxx_expression (pp, t);
543 pp_right_paren (pp);
544 }
545 break;
546
547 default:
548 pp_unsupported_tree (pp, t);
549 }
550 }
551
552 /* delete-expression:
553 ::(opt) delete cast-expression
554 ::(opt) delete [ ] cast-expression */
555
556 static void
557 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
558 {
559 enum tree_code code = TREE_CODE (t);
560 switch (code)
561 {
562 case DELETE_EXPR:
563 case VEC_DELETE_EXPR:
564 if (DELETE_EXPR_USE_GLOBAL (t))
565 pp_cxx_colon_colon (pp);
566 pp_cxx_identifier (pp, "delete");
567 if (code == VEC_DELETE_EXPR)
568 {
569 pp_left_bracket (pp);
570 pp_right_bracket (pp);
571 }
572 pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
573 break;
574
575 default:
576 pp_unsupported_tree (pp, t);
577 }
578 }
579
580 /* unary-expression:
581 postfix-expression
582 ++ cast-expression
583 -- cast-expression
584 unary-operator cast-expression
585 sizeof unary-expression
586 sizeof ( type-id )
587 new-expression
588 delete-expression
589
590 unary-operator: one of
591 * & + - !
592
593 GNU extensions:
594 __alignof__ unary-expression
595 __alignof__ ( type-id ) */
596
597 static void
598 pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
599 {
600 enum tree_code code = TREE_CODE (t);
601 switch (code)
602 {
603 case NEW_EXPR:
604 case VEC_NEW_EXPR:
605 pp_cxx_new_expression (pp, t);
606 break;
607
608 case DELETE_EXPR:
609 case VEC_DELETE_EXPR:
610 pp_cxx_delete_expression (pp, t);
611 break;
612
613 default:
614 pp_c_unary_expression (pp_c_base (pp), t);
615 break;
616 }
617 }
618
619 /* cast-expression:
620 unary-expression
621 ( type-id ) cast-expression */
622
623 static void
624 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
625 {
626 switch (TREE_CODE (t))
627 {
628 case CAST_EXPR:
629 pp_cxx_type_id (pp, TREE_TYPE (t));
630 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
631 break;
632
633 default:
634 pp_c_cast_expression (pp_c_base (pp), t);
635 break;
636 }
637 }
638
639 /* pm-expression:
640 cast-expression
641 pm-expression .* cast-expression
642 pm-expression ->* cast-expression */
643
644 static void
645 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
646 {
647 switch (TREE_CODE (t))
648 {
649 /* Handle unfortunate OFFESET_REF overloading here. */
650 case OFFSET_REF:
651 if (TYPE_P (TREE_OPERAND (t, 0)))
652 {
653 pp_cxx_qualified_id (pp, t);
654 break;
655 }
656 /* Else fall through. */
657 case MEMBER_REF:
658 case DOTSTAR_EXPR:
659 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
660 pp_cxx_dot (pp);
661 pp_star(pp);
662 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
663 break;
664
665
666 default:
667 pp_cxx_cast_expression (pp, t);
668 break;
669 }
670 }
671
672 /* multiplicative-expression:
673 pm-expression
674 multiplicative-expression * pm-expression
675 multiplicative-expression / pm-expression
676 multiplicative-expression % pm-expression */
677
678 static void
679 pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
680 {
681 enum tree_code code = TREE_CODE (e);
682 switch (code)
683 {
684 case MULT_EXPR:
685 case TRUNC_DIV_EXPR:
686 case TRUNC_MOD_EXPR:
687 pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
688 pp_space (pp);
689 if (code == MULT_EXPR)
690 pp_star (pp);
691 else if (code == TRUNC_DIV_EXPR)
692 pp_slash (pp);
693 else
694 pp_modulo (pp);
695 pp_space (pp);
696 pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
697 break;
698
699 default:
700 pp_cxx_pm_expression (pp, e);
701 break;
702 }
703 }
704
705 /* conditional-expression:
706 logical-or-expression
707 logical-or-expression ? expression : assignment-expression */
708
709 static void
710 pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
711 {
712 if (TREE_CODE (e) == COND_EXPR)
713 {
714 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
715 pp_space (pp);
716 pp_question (pp);
717 pp_space (pp);
718 pp_cxx_expression (pp, TREE_OPERAND (e, 1));
719 pp_space (pp);
720 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
721 }
722 else
723 pp_c_logical_or_expression (pp_c_base (pp), e);
724 }
725
726 /* Pretty-print a compound assignment operator token as indicated by T. */
727
728 static void
729 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
730 {
731 const char *op;
732
733 switch (TREE_CODE (t))
734 {
735 case NOP_EXPR:
736 op = "=";
737 break;
738
739 case PLUS_EXPR:
740 op = "+=";
741 break;
742
743 case MINUS_EXPR:
744 op = "-=";
745 break;
746
747 case TRUNC_DIV_EXPR:
748 op = "/=";
749 break;
750
751 case TRUNC_MOD_EXPR:
752 op = "%=";
753 break;
754
755 default:
756 op = tree_code_name[TREE_CODE (t)];
757 break;
758 }
759
760 pp_cxx_identifier (pp, op);
761 }
762
763
764 /* assignment-expression:
765 conditional-expression
766 logical-or-expression assignment-operator assignment-expression
767 throw-expression
768
769 throw-expression:
770 throw assignment-expression(opt)
771
772 assignment-operator: one of
773 = *= /= %= += -= >>= <<= &= ^= |= */
774
775 static void
776 pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
777 {
778 switch (TREE_CODE (e))
779 {
780 case MODIFY_EXPR:
781 case INIT_EXPR:
782 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
783 pp_space (pp);
784 pp_equal (pp);
785 pp_space (pp);
786 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
787 break;
788
789 case THROW_EXPR:
790 pp_cxx_identifier (pp, "throw");
791 if (TREE_OPERAND (e, 0))
792 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
793 break;
794
795 case MODOP_EXPR:
796 pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
797 pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
798 pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
799 break;
800
801 default:
802 pp_cxx_conditional_expression (pp, e);
803 break;
804 }
805 }
806
807 static void
808 pp_cxx_expression (cxx_pretty_printer *pp, tree t)
809 {
810 switch (TREE_CODE (t))
811 {
812 case STRING_CST:
813 case INTEGER_CST:
814 case REAL_CST:
815 pp_c_constant (pp_c_base (pp), t);
816 break;
817
818 case RESULT_DECL:
819 pp_cxx_unqualified_id (pp, t);
820 break;
821
822 #if 0
823 case OFFSET_REF:
824 #endif
825 case SCOPE_REF:
826 case PTRMEM_CST:
827 pp_cxx_qualified_id (pp, t);
828 break;
829
830 case OVERLOAD:
831 t = OVL_CURRENT (t);
832 case VAR_DECL:
833 case PARM_DECL:
834 case FIELD_DECL:
835 case CONST_DECL:
836 case FUNCTION_DECL:
837 case BASELINK:
838 case TEMPLATE_DECL:
839 case TEMPLATE_TYPE_PARM:
840 case TEMPLATE_PARM_INDEX:
841 case TEMPLATE_TEMPLATE_PARM:
842 pp_cxx_primary_expression (pp, t);
843 break;
844
845 case CALL_EXPR:
846 case DYNAMIC_CAST_EXPR:
847 case STATIC_CAST_EXPR:
848 case REINTERPRET_CAST_EXPR:
849 case CONST_CAST_EXPR:
850 #if 0
851 case MEMBER_REF:
852 #endif
853 case EMPTY_CLASS_EXPR:
854 case TYPEID_EXPR:
855 case PSEUDO_DTOR_EXPR:
856 case AGGR_INIT_EXPR:
857 pp_cxx_postfix_expression (pp, t);
858 break;
859
860 case NEW_EXPR:
861 case VEC_NEW_EXPR:
862 pp_cxx_new_expression (pp, t);
863 break;
864
865 case DELETE_EXPR:
866 case VEC_DELETE_EXPR:
867 pp_cxx_delete_expression (pp, t);
868 break;
869
870 case CAST_EXPR:
871 pp_cxx_cast_expression (pp, t);
872 break;
873
874 case OFFSET_REF:
875 case MEMBER_REF:
876 case DOTSTAR_EXPR:
877 pp_cxx_pm_expression (pp, t);
878 break;
879
880 case MULT_EXPR:
881 case TRUNC_DIV_EXPR:
882 case TRUNC_MOD_EXPR:
883 pp_cxx_multiplicative_expression (pp, t);
884 break;
885
886 case COND_EXPR:
887 pp_cxx_conditional_expression (pp, t);
888 break;
889
890 case MODIFY_EXPR:
891 case INIT_EXPR:
892 case THROW_EXPR:
893 case MODOP_EXPR:
894 pp_cxx_assignment_expression (pp, t);
895 break;
896
897 case NON_DEPENDENT_EXPR:
898 case MUST_NOT_THROW_EXPR:
899 pp_cxx_expression (pp, t);
900 break;
901
902 default:
903 pp_c_expression (pp_c_base (pp), t);
904 break;
905 }
906 }
907
908
909 /* Declarations. */
910
911 /* function-specifier:
912 inline
913 virtual
914 explicit */
915
916 static void
917 pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
918 {
919 switch (TREE_CODE (t))
920 {
921 case FUNCTION_DECL:
922 if (DECL_VIRTUAL_P (t))
923 pp_cxx_identifier (pp, "virtual");
924 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
925 pp_cxx_identifier (pp, "explicit");
926 else
927 pp_c_function_specifier (pp_c_base (pp), t);
928
929 default:
930 break;
931 }
932 }
933
934 /* decl-specifier-seq:
935 decl-specifier-seq(opt) decl-specifier
936
937 decl-specifier:
938 storage-class-specifier
939 type-specifier
940 function-specifier
941 friend
942 typedef */
943
944 static void
945 pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
946 {
947 switch (TREE_CODE (t))
948 {
949 case VAR_DECL:
950 case PARM_DECL:
951 case CONST_DECL:
952 case FIELD_DECL:
953 pp_cxx_storage_class_specifier (pp, t);
954 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
955 break;
956
957 case TYPE_DECL:
958 pp_cxx_identifier (pp, "typedef");
959 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
960 break;
961
962 case RECORD_TYPE:
963 if (TYPE_PTRMEMFUNC_P (t))
964 {
965 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
966 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
967 pp_cxx_whitespace (pp);
968 pp_cxx_ptr_operator (pp, t);
969 }
970 break;
971
972 case FUNCTION_DECL:
973 /* Constructors don't have return types. And conversion functions
974 do not have a type-specifier in their return types. */
975 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
976 pp_cxx_function_specifier (pp, t);
977 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
978 pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
979 else
980 default:
981 pp_c_declaration_specifiers (pp_c_base (pp), t);
982 break;
983 }
984 }
985
986 /* simple-type-specifier:
987 ::(opt) nested-name-specifier(opt) type-name
988 ::(opt) nested-name-specifier(opt) template(opt) template-id
989 char
990 wchar_t
991 bool
992 short
993 int
994 long
995 signed
996 unsigned
997 float
998 double
999 void */
1000
1001 static void
1002 pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
1003 {
1004 switch (TREE_CODE (t))
1005 {
1006 case RECORD_TYPE:
1007 case UNION_TYPE:
1008 case ENUMERAL_TYPE:
1009 pp_cxx_qualified_id (pp, t);
1010 break;
1011
1012 case TEMPLATE_TYPE_PARM:
1013 case TEMPLATE_TEMPLATE_PARM:
1014 case TEMPLATE_PARM_INDEX:
1015 pp_cxx_unqualified_id (pp, t);
1016 break;
1017
1018 case TYPENAME_TYPE:
1019 pp_cxx_identifier (pp, "typename");
1020 pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1021 pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1022 break;
1023
1024 default:
1025 pp_c_type_specifier (pp_c_base (pp), t);
1026 break;
1027 }
1028 }
1029
1030 /* type-specifier-seq:
1031 type-specifier type-specifier-seq(opt)
1032
1033 type-specifier:
1034 simple-type-specifier
1035 class-specifier
1036 enum-specifier
1037 elaborated-type-specifier
1038 cv-qualifier */
1039
1040 static void
1041 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1042 {
1043 switch (TREE_CODE (t))
1044 {
1045 case TEMPLATE_DECL:
1046 case TEMPLATE_TYPE_PARM:
1047 case TEMPLATE_TEMPLATE_PARM:
1048 case TYPE_DECL:
1049 case BOUND_TEMPLATE_TEMPLATE_PARM:
1050 pp_cxx_cv_qualifier_seq (pp, t);
1051 pp_cxx_simple_type_specifier (pp, t);
1052 break;
1053
1054 case METHOD_TYPE:
1055 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1056 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1057 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1058 break;
1059
1060 default:
1061 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1062 pp_c_specifier_qualifier_list (pp_c_base (pp), t);
1063 }
1064 }
1065
1066 /* ptr-operator:
1067 * cv-qualifier-seq(opt)
1068 &
1069 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1070
1071 static void
1072 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1073 {
1074 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1075 t = TREE_TYPE (t);
1076 switch (TREE_CODE (t))
1077 {
1078 case REFERENCE_TYPE:
1079 case POINTER_TYPE:
1080 if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
1081 || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
1082 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1083 if (TREE_CODE (t) == POINTER_TYPE)
1084 {
1085 pp_star (pp);
1086 pp_cxx_cv_qualifier_seq (pp, t);
1087 }
1088 else
1089 pp_ampersand (pp);
1090 break;
1091
1092 case RECORD_TYPE:
1093 if (TYPE_PTRMEMFUNC_P (t))
1094 {
1095 pp_cxx_left_paren (pp);
1096 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1097 pp_star (pp);
1098 break;
1099 }
1100 case OFFSET_TYPE:
1101 if (TYPE_PTR_TO_MEMBER_P (t))
1102 {
1103 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1104 pp_star (pp);
1105 pp_cxx_cv_qualifier_seq (pp, t);
1106 break;
1107 }
1108 /* else fall through. */
1109
1110 default:
1111 pp_unsupported_tree (pp, t);
1112 break;
1113 }
1114 }
1115
1116 static inline tree
1117 pp_cxx_implicit_parameter_type (tree mf)
1118 {
1119 return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1120 }
1121
1122 /*
1123 parameter-declaration:
1124 decl-specifier-seq declarator
1125 decl-specifier-seq declarator = assignment-expression
1126 decl-specifier-seq abstract-declarator(opt)
1127 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1128
1129 static inline void
1130 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1131 {
1132 pp_cxx_decl_specifier_seq (pp, t);
1133 if (TYPE_P (t))
1134 pp_cxx_abstract_declarator (pp, t);
1135 else
1136 pp_cxx_declarator (pp, t);
1137 }
1138
1139 /* parameter-declaration-clause:
1140 parameter-declaration-list(opt) ...(opt)
1141 parameter-declaration-list , ...
1142
1143 parameter-declaration-list:
1144 parameter-declaration
1145 parameter-declaration-list , parameter-declaration */
1146
1147 static void
1148 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1149 {
1150 tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1151 tree types = TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1152 const bool abstract = args == NULL
1153 || pp_c_base (pp)->flags & pp_c_flag_abstract;
1154 bool first = true;
1155
1156 /* Skip artificial parameter for nonstatic member functions. */
1157 if (TREE_CODE (t) == METHOD_TYPE)
1158 types = TREE_CHAIN (types);
1159
1160 pp_cxx_left_paren (pp);
1161 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1162 {
1163 if (!first)
1164 pp_cxx_separate_with (pp, ',');
1165 first = false;
1166 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1167 if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1168 {
1169 pp_cxx_whitespace (pp);
1170 pp_equal (pp);
1171 pp_cxx_whitespace (pp);
1172 pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1173 }
1174 }
1175 pp_cxx_right_paren (pp);
1176 }
1177
1178 /* exception-specification:
1179 throw ( type-id-list(opt) )
1180
1181 type-id-list
1182 type-id
1183 type-id-list , type-id */
1184
1185 static void
1186 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1187 {
1188 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1189
1190 if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1191 return;
1192 pp_cxx_identifier (pp, "throw");
1193 pp_cxx_left_paren (pp);
1194 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1195 {
1196 pp_cxx_type_id (pp, TREE_VALUE (ex_spec));
1197 if (TREE_CHAIN (ex_spec))
1198 pp_cxx_separate_with (pp, ',');
1199 }
1200 pp_cxx_right_paren (pp);
1201 }
1202
1203 /* direct-declarator:
1204 declarator-id
1205 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1206 exception-specification(opt)
1207 direct-declaration [ constant-expression(opt) ]
1208 ( declarator ) */
1209
1210 static void
1211 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1212 {
1213 switch (TREE_CODE (t))
1214 {
1215 case VAR_DECL:
1216 case PARM_DECL:
1217 case CONST_DECL:
1218 case FIELD_DECL:
1219 if (DECL_NAME (t))
1220 {
1221 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1222 pp_cxx_id_expression (pp, DECL_NAME (t));
1223 }
1224 pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1225 break;
1226
1227 case FUNCTION_DECL:
1228 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1229 pp_cxx_id_expression (pp, t);
1230 pp_cxx_parameter_declaration_clause (pp, t);
1231
1232 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1233 {
1234 pp_base (pp)->padding = pp_before;
1235 pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1236 }
1237
1238 pp_cxx_exception_specification (pp, TREE_TYPE (t));
1239 break;
1240
1241 case TYPENAME_TYPE:
1242 case TEMPLATE_DECL:
1243 case TEMPLATE_TYPE_PARM:
1244 case TEMPLATE_PARM_INDEX:
1245 case TEMPLATE_TEMPLATE_PARM:
1246 break;
1247
1248 default:
1249 pp_c_direct_declarator (pp_c_base (pp), t);
1250 break;
1251 }
1252 }
1253
1254 /* declarator:
1255 direct-declarator
1256 ptr-operator declarator */
1257
1258 static void
1259 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1260 {
1261 pp_cxx_direct_declarator (pp, t);
1262 }
1263
1264 /* ctor-initializer:
1265 : mem-initializer-list
1266
1267 mem-initializer-list:
1268 mem-initializer
1269 mem-initializer , mem-initializer-list
1270
1271 mem-initializer:
1272 mem-initializer-id ( expression-list(opt) )
1273
1274 mem-initializer-id:
1275 ::(opt) nested-name-specifier(opt) class-name
1276 identifier */
1277
1278 static void
1279 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1280 {
1281 t = TREE_OPERAND (t, 0);
1282 pp_cxx_whitespace (pp);
1283 pp_colon (pp);
1284 pp_cxx_whitespace (pp);
1285 for (; t; t = TREE_CHAIN (t))
1286 {
1287 pp_cxx_primary_expression (pp, TREE_PURPOSE (t));
1288 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1289 if (TREE_CHAIN (t))
1290 pp_cxx_separate_with (pp, ',');
1291 }
1292 }
1293
1294 /* function-definition:
1295 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1296 decl-specifier-seq(opt) declarator function-try-block */
1297
1298 void
1299 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1300 {
1301 tree saved_scope = pp->enclosing_scope;
1302 pp_cxx_decl_specifier_seq (pp, t);
1303 pp_cxx_declarator (pp, t);
1304 pp_needs_newline (pp) = true;
1305 pp->enclosing_scope = DECL_CONTEXT (t);
1306 if (DECL_SAVED_TREE (t))
1307 {
1308 tree body = DECL_SAVED_TREE (t);
1309 if (TREE_CODE (body) == COMPOUND_STMT
1310 && TREE_CODE (COMPOUND_BODY (body)) == CTOR_INITIALIZER)
1311 {
1312 body = COMPOUND_BODY (body);
1313 pp_cxx_ctor_initializer (pp, body);
1314 body = TREE_CHAIN (body);
1315 }
1316 pp_cxx_statement (pp, body);
1317 }
1318 else
1319 {
1320 pp_cxx_semicolon (pp);
1321 pp_needs_newline (pp) = true;
1322 }
1323 pp_flush (pp);
1324 pp->enclosing_scope = saved_scope;
1325 }
1326
1327 /* abstract-declarator:
1328 ptr-operator abstract-declarator(opt)
1329 direct-abstract-declarator */
1330
1331 static void
1332 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1333 {
1334 if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1335 pp_cxx_right_paren (pp);
1336 else if (POINTER_TYPE_P (t))
1337 {
1338 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1339 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1340 pp_cxx_right_paren (pp);
1341 t = TREE_TYPE (t);
1342 }
1343 pp_cxx_direct_abstract_declarator (pp, t);
1344 }
1345
1346 /* direct-abstract-declarator:
1347 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1348 cv-qualifier-seq(opt) exception-specification(opt)
1349 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1350 ( abstract-declarator ) */
1351
1352 static void
1353 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1354 {
1355 switch (TREE_CODE (t))
1356 {
1357 case REFERENCE_TYPE:
1358 pp_cxx_abstract_declarator (pp, t);
1359 break;
1360
1361 case RECORD_TYPE:
1362 if (TYPE_PTRMEMFUNC_P (t))
1363 pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1364 break;
1365
1366 case METHOD_TYPE:
1367 case FUNCTION_TYPE:
1368 pp_cxx_parameter_declaration_clause (pp, t);
1369 pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1370 if (TREE_CODE (t) == METHOD_TYPE)
1371 {
1372 pp_base (pp)->padding = pp_before;
1373 pp_cxx_cv_qualifier_seq
1374 (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1375 }
1376 pp_cxx_exception_specification (pp, t);
1377 break;
1378
1379 case TYPENAME_TYPE:
1380 case TEMPLATE_TYPE_PARM:
1381 case TEMPLATE_TEMPLATE_PARM:
1382 case BOUND_TEMPLATE_TEMPLATE_PARM:
1383 case UNBOUND_CLASS_TEMPLATE:
1384 break;
1385
1386 default:
1387 pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1388 break;
1389 }
1390 }
1391
1392 /* type-id:
1393 type-specifier-seq abstract-declarator(opt) */
1394
1395 static void
1396 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1397 {
1398 pp_flags saved_flags = pp_c_base (pp)->flags;
1399 pp_c_base (pp)->flags |= pp_c_flag_abstract;
1400
1401 switch (TREE_CODE (t))
1402 {
1403 case TYPE_DECL:
1404 case UNION_TYPE:
1405 case RECORD_TYPE:
1406 case ENUMERAL_TYPE:
1407 case TYPENAME_TYPE:
1408 case BOUND_TEMPLATE_TEMPLATE_PARM:
1409 case UNBOUND_CLASS_TEMPLATE:
1410 case TEMPLATE_TEMPLATE_PARM:
1411 case TEMPLATE_TYPE_PARM:
1412 case TEMPLATE_PARM_INDEX:
1413 case TEMPLATE_DECL:
1414 case TYPEOF_TYPE:
1415 case TEMPLATE_ID_EXPR:
1416 pp_cxx_type_specifier_seq (pp, t);
1417 break;
1418
1419 default:
1420 pp_c_type_id (pp_c_base (pp), t);
1421 break;
1422 }
1423
1424 pp_c_base (pp)->flags = saved_flags;
1425 }
1426
1427 /* template-argument-list:
1428 template-argument
1429 template-argument-list, template-argument
1430
1431 template-argument:
1432 assignment-expression
1433 type-id
1434 template-name */
1435
1436 static void
1437 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1438 {
1439 int i;
1440 if (t == NULL)
1441 return;
1442 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1443 {
1444 tree arg = TREE_VEC_ELT (t, i);
1445 if (i != 0)
1446 pp_cxx_separate_with (pp, ',');
1447 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1448 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1449 pp_cxx_type_id (pp, arg);
1450 else
1451 pp_cxx_expression (pp, arg);
1452 }
1453 }
1454
1455
1456 static void
1457 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1458 {
1459 t = DECL_STMT_DECL (t);
1460 pp_cxx_type_specifier_seq (pp, t);
1461 if (TYPE_P (t))
1462 pp_cxx_abstract_declarator (pp, t);
1463 else
1464 pp_cxx_declarator (pp, t);
1465 }
1466
1467 /* Statements. */
1468
1469 void
1470 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1471 {
1472 switch (TREE_CODE (t))
1473 {
1474 case USING_STMT:
1475 pp_cxx_identifier (pp, "using");
1476 pp_cxx_identifier (pp, "namespace");
1477 pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1478 break;
1479
1480 case USING_DECL:
1481 pp_cxx_identifier (pp, "using");
1482 pp_cxx_nested_name_specifier (pp, DECL_INITIAL (t));
1483 pp_cxx_unqualified_id (pp, DECL_NAME (t));
1484 break;
1485
1486 case EH_SPEC_BLOCK:
1487 break;
1488
1489 /* try-block:
1490 try compound-statement handler-seq */
1491 case TRY_BLOCK:
1492 pp_maybe_newline_and_indent (pp, 0);
1493 pp_cxx_identifier (pp, "try");
1494 pp_newline_and_indent (pp, 3);
1495 pp_cxx_statement (pp, TRY_STMTS (t));
1496 pp_newline_and_indent (pp, -3);
1497 if (CLEANUP_P (t))
1498 ;
1499 else
1500 pp_cxx_statement (pp, TRY_HANDLERS (t));
1501 break;
1502
1503 /*
1504 handler-seq:
1505 handler handler-seq(opt)
1506
1507 handler:
1508 catch ( exception-declaration ) compound-statement
1509
1510 exception-declaration:
1511 type-specifier-seq declarator
1512 type-specifier-seq abstract-declarator
1513 ... */
1514 case HANDLER:
1515 pp_cxx_identifier (pp, "catch");
1516 pp_cxx_left_paren (pp);
1517 pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1518 pp_cxx_right_paren (pp);
1519 pp_indentation (pp) += 3;
1520 pp_needs_newline (pp) = true;
1521 pp_cxx_statement (pp, HANDLER_BODY (t));
1522 pp_indentation (pp) -= 3;
1523 pp_needs_newline (pp) = true;
1524 break;
1525
1526 default:
1527 pp_c_statement (pp_c_base (pp), t);
1528 break;
1529 }
1530 }
1531
1532 /* original-namespace-definition:
1533 namespace identifier { namespace-body }
1534
1535 As an edge case, we also handle unnamed namespace definition here. */
1536
1537 static void
1538 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1539 {
1540 pp_cxx_identifier (pp, "namespace");
1541 if (DECL_NAME (t))
1542 pp_cxx_unqualified_id (pp, t);
1543 pp_cxx_whitespace (pp);
1544 pp_cxx_left_brace (pp);
1545 /* We do not print the namespace-body. */
1546 pp_cxx_whitespace (pp);
1547 pp_cxx_right_brace (pp);
1548 }
1549
1550 /* namespace-alias:
1551 identifier
1552
1553 namespace-alias-definition:
1554 namespace identifier = qualified-namespace-specifier ;
1555
1556 qualified-namespace-specifier:
1557 ::(opt) nested-name-specifier(opt) namespace-name */
1558
1559 static void
1560 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1561 {
1562 pp_cxx_identifier (pp, "namespace");
1563 pp_cxx_unqualified_id (pp, t);
1564 pp_cxx_whitespace (pp);
1565 pp_equal (pp);
1566 pp_cxx_whitespace (pp);
1567 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1568 pp_cxx_semicolon (pp);
1569 }
1570
1571 /* simple-declaration:
1572 decl-specifier-seq(opt) init-declarator-list(opt) */
1573
1574 static void
1575 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1576 {
1577 pp_cxx_decl_specifier_seq (pp, t);
1578 pp_cxx_init_declarator (pp, t);
1579 pp_cxx_semicolon (pp);
1580 pp_needs_newline (pp) = true;
1581 }
1582
1583 /*
1584 template-parameter-list:
1585 template-parameter
1586 template-parameter-list , template-parameter */
1587
1588 static inline void
1589 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1590 {
1591 const int n = TREE_VEC_LENGTH (t);
1592 int i;
1593 for (i = 0; i < n; ++i)
1594 {
1595 if (i)
1596 pp_cxx_separate_with (pp, ',');
1597 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1598 }
1599 }
1600
1601 /* template-parameter:
1602 type-parameter
1603 parameter-declaration
1604
1605 type-parameter:
1606 class identifier(opt)
1607 class identifier(op) = type-id
1608 typename identifier(opt)
1609 typename identifier(opt) = type-id
1610 template < template-parameter-list > class identifier(opt)
1611 template < template-parameter-list > class identifier(opt) = template-name
1612 */
1613
1614 static void
1615 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
1616 {
1617 tree parameter = TREE_VALUE (t);
1618 switch (TREE_CODE (parameter))
1619 {
1620 case TYPE_DECL:
1621 pp_cxx_identifier (pp, "class");
1622 if (DECL_NAME (parameter))
1623 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
1624 /* FIXME: Chech if we should print also default argument. */
1625 break;
1626
1627 case PARM_DECL:
1628 pp_cxx_parameter_declaration (pp, parameter);
1629 break;
1630
1631 case TEMPLATE_DECL:
1632 break;
1633
1634 default:
1635 pp_unsupported_tree (pp, t);
1636 break;
1637 }
1638 }
1639
1640 /* Pretty-print a template parameter in the canonical form
1641 "template-parameter-<level>-<position in parameter list>". */
1642
1643 void
1644 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
1645 {
1646 const enum tree_code code = TREE_CODE (parm);
1647
1648 /* Brings type template parameters to the canonical forms. */
1649 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
1650 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
1651 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
1652
1653 pp_cxx_begin_template_argument_list (pp);
1654 pp_cxx_identifier (pp, "template-parameter-");
1655 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
1656 pp_minus (pp);
1657 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
1658 pp_cxx_end_template_argument_list (pp);
1659 }
1660
1661 /*
1662 template-declaration:
1663 export(opt) template < template-parameter-list > declaration */
1664
1665 static void
1666 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
1667 {
1668 tree tmpl = most_general_template (t);
1669 tree level;
1670 int i = 0;
1671
1672 pp_maybe_newline_and_indent (pp, 0);
1673 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
1674 {
1675 pp_cxx_identifier (pp, "template");
1676 pp_cxx_begin_template_argument_list (pp);
1677 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
1678 pp_cxx_end_template_argument_list (pp);
1679 pp_newline_and_indent (pp, 3);
1680 i += 3;
1681 }
1682 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
1683 pp_cxx_function_definition (pp, t);
1684 else
1685 pp_cxx_simple_declaration (pp, t);
1686 }
1687
1688 static void
1689 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
1690 {
1691 pp_unsupported_tree (pp, t);
1692 }
1693
1694 static void
1695 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
1696 {
1697 pp_unsupported_tree (pp, t);
1698 }
1699
1700 /*
1701 declaration:
1702 block-declaration
1703 function-definition
1704 template-declaration
1705 explicit-instantiation
1706 explicit-specialization
1707 linkage-specification
1708 namespace-definition
1709
1710 block-declaration:
1711 simple-declaration
1712 asm-definition
1713 namespace-alias-definition
1714 using-declaration
1715 using-directive */
1716 void
1717 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
1718 {
1719 if (!DECL_LANG_SPECIFIC (t))
1720 pp_cxx_simple_declaration (pp, t);
1721 else if (DECL_USE_TEMPLATE (t))
1722 switch (DECL_USE_TEMPLATE (t))
1723 {
1724 case 1:
1725 pp_cxx_template_declaration (pp, t);
1726 break;
1727
1728 case 2:
1729 pp_cxx_explicit_specialization (pp, t);
1730 break;
1731
1732 case 3:
1733 pp_cxx_explicit_instantiation (pp, t);
1734 break;
1735
1736 default:
1737 break;
1738 }
1739 else switch (TREE_CODE (t))
1740 {
1741 case VAR_DECL:
1742 case TYPE_DECL:
1743 pp_cxx_simple_declaration (pp, t);
1744 break;
1745
1746 case FUNCTION_DECL:
1747 if (DECL_SAVED_TREE (t))
1748 pp_cxx_function_definition (pp, t);
1749 else
1750 pp_cxx_simple_declaration (pp, t);
1751 break;
1752
1753 case NAMESPACE_DECL:
1754 if (DECL_NAMESPACE_ALIAS (t))
1755 pp_cxx_namespace_alias_definition (pp, t);
1756 else
1757 pp_cxx_original_namespace_definition (pp, t);
1758 break;
1759
1760 default:
1761 pp_unsupported_tree (pp, t);
1762 break;
1763 }
1764 }
1765
1766 \f
1767 typedef c_pretty_print_fn pp_fun;
1768
1769 /* Initialization of a C++ pretty-printer object. */
1770
1771 void
1772 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
1773 {
1774 pp_c_pretty_printer_init (pp_c_base (pp));
1775 pp_set_line_maximum_length (pp, 0);
1776
1777 pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
1778 pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
1779 pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
1780 pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
1781 pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
1782 pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
1783 pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
1784 pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
1785 pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
1786 pp->c_base.direct_abstract_declarator =
1787 (pp_fun) pp_cxx_direct_abstract_declarator;
1788 pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
1789
1790 /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
1791
1792 pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
1793 pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
1794 pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
1795 pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
1796 pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
1797 pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
1798 pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
1799 pp->c_base.expression = (pp_fun) pp_cxx_expression;
1800 pp->enclosing_scope = global_namespace;
1801 }