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