OSDN Git Service

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