OSDN Git Service

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