OSDN Git Service

PR c++/14123
[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           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1104             pp_cxx_left_paren (pp);
1105           pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1106           pp_star (pp);
1107           pp_cxx_cv_qualifier_seq (pp, t);
1108           break;
1109         }
1110       /* else fall through.  */
1111
1112     default:
1113       pp_unsupported_tree (pp, t);
1114       break;
1115     }
1116 }
1117
1118 static inline tree
1119 pp_cxx_implicit_parameter_type (tree mf)
1120 {
1121   return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1122 }
1123
1124 /*
1125    parameter-declaration:
1126       decl-specifier-seq declarator
1127       decl-specifier-seq declarator = assignment-expression
1128       decl-specifier-seq abstract-declarator(opt)
1129       decl-specifier-seq abstract-declarator(opt) assignment-expression  */
1130
1131 static inline void
1132 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1133 {
1134   pp_cxx_decl_specifier_seq (pp, t);
1135   if (TYPE_P (t))
1136     pp_cxx_abstract_declarator (pp, t);
1137   else
1138     pp_cxx_declarator (pp, t);
1139 }
1140
1141 /* parameter-declaration-clause:
1142       parameter-declaration-list(opt) ...(opt)
1143       parameter-declaration-list , ...
1144
1145    parameter-declaration-list:
1146       parameter-declaration
1147       parameter-declaration-list , parameter-declaration  */
1148
1149 static void
1150 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1151 {
1152   tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1153   tree types = TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1154   const bool abstract = args == NULL
1155     || pp_c_base (pp)->flags & pp_c_flag_abstract;
1156   bool first = true;
1157
1158   /* Skip artificial parameter for nonstatic member functions.  */
1159   if (TREE_CODE (t) == METHOD_TYPE)
1160     types = TREE_CHAIN (types);
1161
1162   pp_cxx_left_paren (pp);
1163   for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1164     {
1165       if (!first)
1166         pp_cxx_separate_with (pp, ',');
1167       first = false;
1168       pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1169       if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1170         {
1171           pp_cxx_whitespace (pp);
1172           pp_equal (pp);
1173           pp_cxx_whitespace (pp);
1174           pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1175         }
1176     }
1177   pp_cxx_right_paren (pp);
1178 }
1179
1180 /* exception-specification:
1181       throw ( type-id-list(opt) )
1182
1183    type-id-list
1184       type-id
1185       type-id-list , type-id   */
1186
1187 static void
1188 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1189 {
1190   tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1191
1192   if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1193     return;
1194   pp_cxx_identifier (pp, "throw");
1195   pp_cxx_left_paren (pp);
1196   for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1197     {
1198       pp_cxx_type_id (pp, TREE_VALUE (ex_spec));
1199       if (TREE_CHAIN (ex_spec))
1200         pp_cxx_separate_with (pp, ',');
1201     }
1202   pp_cxx_right_paren (pp);
1203 }
1204
1205 /* direct-declarator:
1206       declarator-id
1207       direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1208                                             exception-specification(opt)
1209       direct-declaration [ constant-expression(opt) ]
1210       ( declarator )  */
1211
1212 static void
1213 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1214 {
1215   switch (TREE_CODE (t))
1216     {
1217     case VAR_DECL:
1218     case PARM_DECL:
1219     case CONST_DECL:
1220     case FIELD_DECL:
1221       if (DECL_NAME (t))
1222         {
1223           pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1224           pp_cxx_id_expression (pp, DECL_NAME (t));
1225         }
1226       pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1227       break;
1228       
1229     case FUNCTION_DECL:
1230       pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1231       pp_cxx_id_expression (pp, t);
1232       pp_cxx_parameter_declaration_clause (pp, t);
1233       
1234       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1235         {
1236           pp_base (pp)->padding = pp_before;
1237           pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1238         }
1239
1240       pp_cxx_exception_specification (pp, TREE_TYPE (t));
1241       break;
1242
1243     case TYPENAME_TYPE:
1244     case TEMPLATE_DECL:
1245     case TEMPLATE_TYPE_PARM:
1246     case TEMPLATE_PARM_INDEX:
1247     case TEMPLATE_TEMPLATE_PARM:
1248       break;
1249
1250     default:
1251       pp_c_direct_declarator (pp_c_base (pp), t);
1252       break;
1253     }
1254 }
1255
1256 /* declarator:
1257    direct-declarator
1258    ptr-operator declarator  */
1259
1260 static void
1261 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1262 {
1263   pp_cxx_direct_declarator (pp, t);
1264 }
1265
1266 /* ctor-initializer:
1267       : mem-initializer-list
1268
1269    mem-initializer-list:
1270       mem-initializer
1271       mem-initializer , mem-initializer-list
1272
1273    mem-initializer:
1274       mem-initializer-id ( expression-list(opt) )
1275
1276    mem-initializer-id:
1277       ::(opt) nested-name-specifier(opt) class-name
1278       identifier   */
1279
1280 static void
1281 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1282 {
1283   t = TREE_OPERAND (t, 0);
1284   pp_cxx_whitespace (pp);
1285   pp_colon (pp);
1286   pp_cxx_whitespace (pp);
1287   for (; t; t = TREE_CHAIN (t))
1288     {
1289       pp_cxx_primary_expression (pp, TREE_PURPOSE (t));
1290       pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1291       if (TREE_CHAIN (t))
1292         pp_cxx_separate_with (pp, ',');
1293     }
1294 }
1295
1296 /* function-definition:
1297       decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1298       decl-specifier-seq(opt) declarator function-try-block  */
1299
1300 void
1301 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1302 {
1303   tree saved_scope = pp->enclosing_scope;
1304   pp_cxx_decl_specifier_seq (pp, t);
1305   pp_cxx_declarator (pp, t);
1306   pp_needs_newline (pp) = true;
1307   pp->enclosing_scope = DECL_CONTEXT (t);
1308   if (DECL_SAVED_TREE (t))
1309     pp_cxx_statement (pp, DECL_SAVED_TREE (t));
1310   else
1311     {
1312       pp_cxx_semicolon (pp);
1313       pp_needs_newline (pp) = true;
1314     }
1315   pp_flush (pp);
1316   pp->enclosing_scope = saved_scope;
1317 }
1318
1319 /* abstract-declarator:
1320       ptr-operator abstract-declarator(opt)
1321       direct-abstract-declarator  */
1322
1323 static void
1324 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1325 {
1326   if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1327     pp_cxx_right_paren (pp);
1328   else if (POINTER_TYPE_P (t))
1329     {
1330       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1331           || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1332         pp_cxx_right_paren (pp);
1333       t = TREE_TYPE (t);
1334     }
1335   pp_cxx_direct_abstract_declarator (pp, t);
1336 }
1337
1338 /* direct-abstract-declarator:
1339       direct-abstract-declarator(opt) ( parameter-declaration-clause )
1340                            cv-qualifier-seq(opt) exception-specification(opt)
1341       direct-abstract-declarator(opt) [ constant-expression(opt) ]
1342       ( abstract-declarator )  */
1343
1344 static void
1345 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1346 {
1347   switch (TREE_CODE (t))
1348     {
1349     case REFERENCE_TYPE:
1350       pp_cxx_abstract_declarator (pp, t);
1351       break;
1352
1353     case RECORD_TYPE:
1354       if (TYPE_PTRMEMFUNC_P (t))
1355         pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1356       break;
1357
1358     case METHOD_TYPE:
1359     case FUNCTION_TYPE:
1360       pp_cxx_parameter_declaration_clause (pp, t);
1361       pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1362       if (TREE_CODE (t) == METHOD_TYPE)
1363         {
1364           pp_base (pp)->padding = pp_before;
1365           pp_cxx_cv_qualifier_seq
1366             (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1367         }
1368       pp_cxx_exception_specification (pp, t);
1369       break;
1370
1371     case TYPENAME_TYPE:
1372     case TEMPLATE_TYPE_PARM:
1373     case TEMPLATE_TEMPLATE_PARM:
1374     case BOUND_TEMPLATE_TEMPLATE_PARM:
1375     case UNBOUND_CLASS_TEMPLATE:
1376       break;
1377
1378     default:
1379       pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1380       break;      
1381     }
1382 }
1383
1384 /* type-id:
1385      type-specifier-seq abstract-declarator(opt) */
1386
1387 static void
1388 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1389 {
1390   pp_flags saved_flags = pp_c_base (pp)->flags;
1391   pp_c_base (pp)->flags |= pp_c_flag_abstract;
1392
1393   switch (TREE_CODE (t))
1394     {
1395     case TYPE_DECL:
1396     case UNION_TYPE:
1397     case RECORD_TYPE:
1398     case ENUMERAL_TYPE:
1399     case TYPENAME_TYPE:
1400     case BOUND_TEMPLATE_TEMPLATE_PARM:
1401     case UNBOUND_CLASS_TEMPLATE:
1402     case TEMPLATE_TEMPLATE_PARM:
1403     case TEMPLATE_TYPE_PARM:
1404     case TEMPLATE_PARM_INDEX:
1405     case TEMPLATE_DECL:
1406     case TYPEOF_TYPE:
1407     case TEMPLATE_ID_EXPR:
1408       pp_cxx_type_specifier_seq (pp, t);
1409       break;
1410
1411     default:
1412       pp_c_type_id (pp_c_base (pp), t);
1413       break;
1414     }
1415
1416   pp_c_base (pp)->flags = saved_flags;
1417 }
1418
1419 /* template-argument-list:
1420       template-argument
1421       template-argument-list, template-argument
1422
1423    template-argument:
1424       assignment-expression
1425       type-id
1426       template-name   */
1427
1428 static void
1429 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1430 {
1431   int i;
1432   if (t == NULL)
1433     return;
1434   for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1435     {
1436       tree arg = TREE_VEC_ELT (t, i);
1437       if (i != 0)
1438         pp_cxx_separate_with (pp, ',');
1439       if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1440                            && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1441         pp_cxx_type_id (pp, arg);
1442       else
1443         pp_cxx_expression (pp, arg);
1444     }
1445 }
1446
1447
1448 static void
1449 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1450 {
1451   t = DECL_EXPR_DECL (t);
1452   pp_cxx_type_specifier_seq (pp, t);
1453   if (TYPE_P (t))
1454     pp_cxx_abstract_declarator (pp, t);
1455   else
1456     pp_cxx_declarator (pp, t);
1457 }
1458
1459 /* Statements.  */
1460
1461 void
1462 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1463 {
1464   switch (TREE_CODE (t))
1465     {
1466     case CTOR_INITIALIZER:
1467       pp_cxx_ctor_initializer (pp, t);
1468       break;
1469
1470     case USING_STMT:
1471       pp_cxx_identifier (pp, "using");
1472       pp_cxx_identifier (pp, "namespace");
1473       pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1474       break;
1475
1476     case USING_DECL:
1477       pp_cxx_identifier (pp, "using");
1478       pp_cxx_nested_name_specifier (pp, DECL_INITIAL (t));
1479       pp_cxx_unqualified_id (pp, DECL_NAME (t));
1480       break;
1481
1482     case EH_SPEC_BLOCK:
1483       break;
1484
1485       /* try-block:
1486             try compound-statement handler-seq  */
1487     case TRY_BLOCK:
1488       pp_maybe_newline_and_indent (pp, 0);
1489       pp_cxx_identifier (pp, "try");
1490       pp_newline_and_indent (pp, 3);
1491       pp_cxx_statement (pp, TRY_STMTS (t));
1492       pp_newline_and_indent (pp, -3);
1493       if (CLEANUP_P (t))
1494         ;
1495       else
1496         pp_cxx_statement (pp, TRY_HANDLERS (t));
1497       break;
1498
1499       /*
1500          handler-seq:
1501             handler handler-seq(opt)
1502
1503          handler:
1504          catch ( exception-declaration ) compound-statement 
1505
1506          exception-declaration:
1507             type-specifier-seq declarator
1508             type-specifier-seq abstract-declarator
1509             ...   */
1510     case HANDLER:
1511       pp_cxx_identifier (pp, "catch");
1512       pp_cxx_left_paren (pp);
1513       pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1514       pp_cxx_right_paren (pp);
1515       pp_indentation (pp) += 3;
1516       pp_needs_newline (pp) = true;
1517       pp_cxx_statement (pp, HANDLER_BODY (t));
1518       pp_indentation (pp) -= 3;
1519       pp_needs_newline (pp) = true;
1520       break;
1521
1522       /* selection-statement:
1523             if ( expression ) statement
1524             if ( expression ) statement else statement  */
1525     case IF_STMT:
1526       pp_cxx_identifier (pp, "if");
1527       pp_cxx_whitespace (pp);
1528       pp_cxx_left_paren (pp);
1529       pp_cxx_expression (pp, IF_COND (t));
1530       pp_cxx_right_paren (pp);
1531       pp_newline_and_indent (pp, 2);
1532       pp_cxx_statement (pp, THEN_CLAUSE (t));
1533       pp_newline_and_indent (pp, -2);
1534       if (ELSE_CLAUSE (t))
1535         {
1536           tree else_clause = ELSE_CLAUSE (t);
1537           pp_cxx_identifier (pp, "else");
1538           if (TREE_CODE (else_clause) == IF_STMT)
1539             pp_cxx_whitespace (pp);
1540           else
1541             pp_newline_and_indent (pp, 2);
1542           pp_cxx_statement (pp, else_clause);
1543           if (TREE_CODE (else_clause) != IF_STMT)
1544             pp_newline_and_indent (pp, -2);
1545         }
1546       break;
1547
1548     case CLEANUP_STMT:
1549       pp_cxx_identifier (pp, "try");
1550       pp_newline_and_indent (pp, 2);
1551       pp_cxx_statement (pp, CLEANUP_BODY (t));
1552       pp_newline_and_indent (pp, -2);
1553       pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1554       pp_newline_and_indent (pp, 2);
1555       pp_cxx_statement (pp, CLEANUP_EXPR (t));
1556       pp_newline_and_indent (pp, -2);
1557       break;
1558
1559     default:
1560       pp_c_statement (pp_c_base (pp), t);
1561       break;
1562     }
1563 }
1564
1565 /* original-namespace-definition:
1566       namespace identifier { namespace-body }
1567
1568   As an edge case, we also handle unnamed namespace definition here.  */
1569
1570 static void
1571 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1572 {
1573   pp_cxx_identifier (pp, "namespace");
1574   if (DECL_NAME (t))
1575     pp_cxx_unqualified_id (pp, t);
1576   pp_cxx_whitespace (pp);
1577   pp_cxx_left_brace (pp);
1578   /* We do not print the namespace-body.  */
1579   pp_cxx_whitespace (pp);
1580   pp_cxx_right_brace (pp);
1581 }
1582
1583 /* namespace-alias:
1584       identifier
1585
1586    namespace-alias-definition:
1587       namespace identifier = qualified-namespace-specifier ;
1588
1589    qualified-namespace-specifier:
1590       ::(opt) nested-name-specifier(opt) namespace-name   */
1591
1592 static void
1593 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1594 {
1595   pp_cxx_identifier (pp, "namespace");
1596   pp_cxx_unqualified_id (pp, t);
1597   pp_cxx_whitespace (pp);
1598   pp_equal (pp);
1599   pp_cxx_whitespace (pp);
1600   pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1601   pp_cxx_semicolon (pp);
1602 }
1603
1604 /* simple-declaration:
1605       decl-specifier-seq(opt) init-declarator-list(opt)  */
1606
1607 static void
1608 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1609 {
1610   pp_cxx_decl_specifier_seq (pp, t);
1611   pp_cxx_init_declarator (pp, t);
1612   pp_cxx_semicolon (pp);
1613   pp_needs_newline (pp) = true;
1614 }
1615
1616 /*
1617   template-parameter-list:
1618      template-parameter
1619      template-parameter-list , template-parameter  */
1620
1621 static inline void
1622 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1623 {
1624   const int n = TREE_VEC_LENGTH (t);
1625   int i;
1626   for (i = 0; i < n; ++i)
1627     {
1628       if (i)
1629         pp_cxx_separate_with (pp, ',');
1630       pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1631     }
1632 }
1633
1634 /* template-parameter:
1635       type-parameter
1636       parameter-declaration
1637
1638    type-parameter:
1639      class identifier(opt)
1640      class identifier(op) = type-id
1641      typename identifier(opt)
1642      typename identifier(opt) = type-id
1643      template < template-parameter-list > class identifier(opt)
1644      template < template-parameter-list > class identifier(opt) = template-name
1645 */
1646
1647 static void
1648 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
1649 {
1650   tree parameter =  TREE_VALUE (t);
1651   switch (TREE_CODE (parameter))
1652     {
1653     case TYPE_DECL:
1654       pp_cxx_identifier (pp, "class");
1655       if (DECL_NAME (parameter))
1656         pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
1657       /* FIXME: Chech if we should print also default argument.  */
1658       break;
1659
1660     case PARM_DECL:
1661       pp_cxx_parameter_declaration (pp, parameter);
1662       break;
1663
1664     case TEMPLATE_DECL:
1665       break;
1666
1667     default:
1668       pp_unsupported_tree (pp, t);
1669       break;
1670     }
1671 }
1672
1673 /* Pretty-print a template parameter in the canonical form
1674    "template-parameter-<level>-<position in parameter list>".  */
1675
1676 void
1677 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
1678 {
1679   const enum tree_code code = TREE_CODE (parm);
1680
1681   /* Brings type template parameters to the canonical forms.  */
1682   if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
1683       || code == BOUND_TEMPLATE_TEMPLATE_PARM)
1684     parm = TEMPLATE_TYPE_PARM_INDEX (parm);
1685   
1686   pp_cxx_begin_template_argument_list (pp);
1687   pp_cxx_identifier (pp, "template-parameter-");
1688   pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
1689   pp_minus (pp);
1690   pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
1691   pp_cxx_end_template_argument_list (pp);
1692 }
1693
1694 /*
1695   template-declaration:
1696      export(opt) template < template-parameter-list > declaration   */
1697
1698 static void
1699 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
1700 {
1701   tree tmpl = most_general_template (t);
1702   tree level;
1703   int i = 0;
1704
1705   pp_maybe_newline_and_indent (pp, 0);
1706   for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
1707     {
1708       pp_cxx_identifier (pp, "template");
1709       pp_cxx_begin_template_argument_list (pp);
1710       pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
1711       pp_cxx_end_template_argument_list (pp);
1712       pp_newline_and_indent (pp, 3);
1713       i += 3;
1714     }
1715   if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
1716     pp_cxx_function_definition (pp, t);
1717   else
1718     pp_cxx_simple_declaration (pp, t);
1719 }
1720
1721 static void
1722 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
1723 {
1724   pp_unsupported_tree (pp, t);
1725 }
1726
1727 static void
1728 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
1729 {
1730   pp_unsupported_tree (pp, t);
1731 }
1732
1733 /*
1734     declaration:
1735        block-declaration
1736        function-definition
1737        template-declaration
1738        explicit-instantiation
1739        explicit-specialization
1740        linkage-specification
1741        namespace-definition
1742
1743     block-declaration:
1744        simple-declaration
1745        asm-definition
1746        namespace-alias-definition
1747        using-declaration
1748        using-directive  */
1749 void
1750 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
1751 {
1752   if (!DECL_LANG_SPECIFIC (t))
1753     pp_cxx_simple_declaration (pp, t);
1754   else if (DECL_USE_TEMPLATE (t))
1755     switch (DECL_USE_TEMPLATE (t))
1756       {
1757       case 1:
1758         pp_cxx_template_declaration (pp, t);
1759         break;
1760         
1761       case 2:
1762         pp_cxx_explicit_specialization (pp, t);
1763         break;
1764
1765       case 3:
1766         pp_cxx_explicit_instantiation (pp, t);
1767         break;
1768
1769       default:
1770         break;
1771       }
1772   else switch (TREE_CODE (t))
1773     {
1774     case VAR_DECL:
1775     case TYPE_DECL:
1776       pp_cxx_simple_declaration (pp, t);
1777       break;
1778       
1779     case FUNCTION_DECL:
1780       if (DECL_SAVED_TREE (t))
1781         pp_cxx_function_definition (pp, t);
1782       else
1783         pp_cxx_simple_declaration (pp, t);
1784       break;
1785
1786     case NAMESPACE_DECL:
1787       if (DECL_NAMESPACE_ALIAS (t))
1788         pp_cxx_namespace_alias_definition (pp, t);
1789       else
1790         pp_cxx_original_namespace_definition (pp, t);
1791       break;
1792
1793     default:
1794       pp_unsupported_tree (pp, t);
1795       break;
1796     }
1797 }
1798
1799 \f
1800 typedef c_pretty_print_fn pp_fun;
1801
1802 /* Initialization of a C++ pretty-printer object.  */
1803
1804 void
1805 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
1806 {
1807   pp_c_pretty_printer_init (pp_c_base (pp));
1808   pp_set_line_maximum_length (pp, 0);
1809
1810   pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
1811   pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
1812   pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
1813   pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
1814   pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
1815   pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
1816   pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
1817   pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
1818   pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
1819   pp->c_base.direct_abstract_declarator =
1820     (pp_fun) pp_cxx_direct_abstract_declarator;
1821   pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
1822
1823   /* pp->c_base.statement = (pp_fun) pp_cxx_statement;  */
1824
1825   pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
1826   pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
1827   pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
1828   pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
1829   pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
1830   pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
1831   pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
1832   pp->c_base.expression = (pp_fun) pp_cxx_expression;
1833   pp->enclosing_scope = global_namespace;
1834 }