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