OSDN Git Service

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