OSDN Git Service

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