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