OSDN Git Service

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