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