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