OSDN Git Service

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