OSDN Git Service

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