OSDN Git Service

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