OSDN Git Service

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