OSDN Git Service

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