OSDN Git Service

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