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