gcc50/csu: Skip depends step to avoid possible race
[dragonfly.git] / contrib / gcc-4.4 / gcc / cp / cxx-pretty-print.c
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2    Copyright (C) 2003, 2004, 2005, 2007, 2008 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      typeid ( 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   tree type = TREE_OPERAND (t, 1);
640   tree init = TREE_OPERAND (t, 2);
641   switch (code)
642     {
643     case NEW_EXPR:
644     case VEC_NEW_EXPR:
645       if (NEW_EXPR_USE_GLOBAL (t))
646         pp_cxx_colon_colon (pp);
647       pp_cxx_identifier (pp, "new");
648       if (TREE_OPERAND (t, 0))
649         {
650           pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
651           pp_space (pp);
652         }
653       if (TREE_CODE (type) == ARRAY_REF)
654         type = build_cplus_array_type
655           (TREE_OPERAND (type, 0),
656            build_index_type (fold_build2 (MINUS_EXPR, integer_type_node,
657                                           TREE_OPERAND (type, 1),
658                                           integer_one_node)));
659       pp_cxx_type_id (pp, type);
660       if (init)
661         {
662           pp_left_paren (pp);
663           if (TREE_CODE (init) == TREE_LIST)
664             pp_c_expression_list (pp_c_base (pp), init);
665           else if (init == void_zero_node)
666             ;                   /* OK, empty initializer list.  */
667           else
668             pp_cxx_expression (pp, init);
669           pp_right_paren (pp);
670         }
671       break;
672
673     default:
674       pp_unsupported_tree (pp, t);
675     }
676 }
677
678 /* delete-expression:
679       ::(opt) delete cast-expression
680       ::(opt) delete [ ] cast-expression   */
681
682 static void
683 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
684 {
685   enum tree_code code = TREE_CODE (t);
686   switch (code)
687     {
688     case DELETE_EXPR:
689     case VEC_DELETE_EXPR:
690       if (DELETE_EXPR_USE_GLOBAL (t))
691         pp_cxx_colon_colon (pp);
692       pp_cxx_identifier (pp, "delete");
693       pp_space (pp);
694       if (code == VEC_DELETE_EXPR
695           || DELETE_EXPR_USE_VEC (t))
696         {
697           pp_left_bracket (pp);
698           pp_right_bracket (pp);
699           pp_space (pp);
700         }
701       pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
702       break;
703
704     default:
705       pp_unsupported_tree (pp, t);
706     }
707 }
708
709 /* unary-expression:
710       postfix-expression
711       ++ cast-expression
712       -- cast-expression
713       unary-operator cast-expression
714       sizeof unary-expression
715       sizeof ( type-id )
716       sizeof ... ( identifier )
717       new-expression
718       delete-expression
719
720    unary-operator: one of
721       *   &   +   -  !
722
723    GNU extensions:
724       __alignof__ unary-expression
725       __alignof__ ( type-id )  */
726
727 static void
728 pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
729 {
730   enum tree_code code = TREE_CODE (t);
731   switch (code)
732     {
733     case NEW_EXPR:
734     case VEC_NEW_EXPR:
735       pp_cxx_new_expression (pp, t);
736       break;
737
738     case DELETE_EXPR:
739     case VEC_DELETE_EXPR:
740       pp_cxx_delete_expression (pp, t);
741       break;
742
743     case SIZEOF_EXPR:
744       if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
745         {
746           pp_cxx_identifier (pp, "sizeof");
747           pp_cxx_identifier (pp, "...");
748           pp_cxx_whitespace (pp);
749           pp_cxx_left_paren (pp);
750           if (TYPE_P (TREE_OPERAND (t, 0)))
751             pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
752           else
753             pp_unary_expression (pp, TREE_OPERAND (t, 0));
754           pp_cxx_right_paren (pp);
755           break;
756         }
757       /* Fall through  */
758
759     case ALIGNOF_EXPR:
760       pp_cxx_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
761       pp_cxx_whitespace (pp);
762       if (TYPE_P (TREE_OPERAND (t, 0)))
763         {
764           pp_cxx_left_paren (pp);
765           pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
766           pp_cxx_right_paren (pp);
767         }
768       else
769         pp_unary_expression (pp, TREE_OPERAND (t, 0));
770       break;
771
772     case UNARY_PLUS_EXPR:
773       pp_plus (pp);
774       pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
775       break;
776
777     default:
778       pp_c_unary_expression (pp_c_base (pp), t);
779       break;
780     }
781 }
782
783 /* cast-expression:
784       unary-expression
785       ( type-id ) cast-expression  */
786
787 static void
788 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
789 {
790   switch (TREE_CODE (t))
791     {
792     case CAST_EXPR:
793       pp_cxx_type_id (pp, TREE_TYPE (t));
794       pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
795       break;
796
797     default:
798       pp_c_cast_expression (pp_c_base (pp), t);
799       break;
800     }
801 }
802
803 /* pm-expression:
804       cast-expression
805       pm-expression .* cast-expression
806       pm-expression ->* cast-expression  */
807
808 static void
809 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
810 {
811   switch (TREE_CODE (t))
812     {
813       /* Handle unfortunate OFFSET_REF overloading here.  */
814     case OFFSET_REF:
815       if (TYPE_P (TREE_OPERAND (t, 0)))
816         {
817           pp_cxx_qualified_id (pp, t);
818           break;
819         }
820       /* Else fall through.  */
821     case MEMBER_REF:
822     case DOTSTAR_EXPR:
823       pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
824       if (TREE_CODE (t) == MEMBER_REF)
825         pp_cxx_arrow (pp);
826       else
827         pp_cxx_dot (pp);
828       pp_star(pp);
829       pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
830       break;
831
832
833     default:
834       pp_cxx_cast_expression (pp, t);
835       break;
836     }
837 }
838
839 /* multiplicative-expression:
840       pm-expression
841       multiplicative-expression * pm-expression
842       multiplicative-expression / pm-expression
843       multiplicative-expression % pm-expression  */
844
845 static void
846 pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
847 {
848   enum tree_code code = TREE_CODE (e);
849   switch (code)
850     {
851     case MULT_EXPR:
852     case TRUNC_DIV_EXPR:
853     case TRUNC_MOD_EXPR:
854       pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
855       pp_space (pp);
856       if (code == MULT_EXPR)
857         pp_star (pp);
858       else if (code == TRUNC_DIV_EXPR)
859         pp_slash (pp);
860       else
861         pp_modulo (pp);
862       pp_space (pp);
863       pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
864       break;
865
866     default:
867       pp_cxx_pm_expression (pp, e);
868       break;
869     }
870 }
871
872 /* conditional-expression:
873       logical-or-expression
874       logical-or-expression ?  expression  : assignment-expression  */
875
876 static void
877 pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
878 {
879   if (TREE_CODE (e) == COND_EXPR)
880     {
881       pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
882       pp_space (pp);
883       pp_question (pp);
884       pp_space (pp);
885       pp_cxx_expression (pp, TREE_OPERAND (e, 1));
886       pp_space (pp);
887       pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
888     }
889   else
890     pp_c_logical_or_expression (pp_c_base (pp), e);
891 }
892
893 /* Pretty-print a compound assignment operator token as indicated by T.  */
894
895 static void
896 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
897 {
898   const char *op;
899
900   switch (TREE_CODE (t))
901     {
902     case NOP_EXPR:
903       op = "=";
904       break;
905
906     case PLUS_EXPR:
907       op = "+=";
908       break;
909
910     case MINUS_EXPR:
911       op = "-=";
912       break;
913
914     case TRUNC_DIV_EXPR:
915       op = "/=";
916       break;
917
918     case TRUNC_MOD_EXPR:
919       op = "%=";
920       break;
921
922     default:
923       op = tree_code_name[TREE_CODE (t)];
924       break;
925     }
926
927   pp_cxx_identifier (pp, op);
928 }
929
930
931 /* assignment-expression:
932       conditional-expression
933       logical-or-expression assignment-operator assignment-expression
934       throw-expression
935
936    throw-expression:
937        throw assignment-expression(opt)
938
939    assignment-operator: one of
940       =    *=    /=    %=    +=    -=    >>=    <<=    &=    ^=    |=  */
941
942 static void
943 pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
944 {
945   switch (TREE_CODE (e))
946     {
947     case MODIFY_EXPR:
948     case INIT_EXPR:
949       pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
950       pp_space (pp);
951       pp_equal (pp);
952       pp_space (pp);
953       pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
954       break;
955
956     case THROW_EXPR:
957       pp_cxx_identifier (pp, "throw");
958       if (TREE_OPERAND (e, 0))
959         pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
960       break;
961
962     case MODOP_EXPR:
963       pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
964       pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
965       pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
966       break;
967
968     default:
969       pp_cxx_conditional_expression (pp, e);
970       break;
971     }
972 }
973
974 static void
975 pp_cxx_expression (cxx_pretty_printer *pp, tree t)
976 {
977   switch (TREE_CODE (t))
978     {
979     case STRING_CST:
980     case INTEGER_CST:
981     case REAL_CST:
982     case COMPLEX_CST:
983       pp_cxx_constant (pp, t);
984       break;
985
986     case RESULT_DECL:
987       pp_cxx_unqualified_id (pp, t);
988       break;
989
990 #if 0
991     case OFFSET_REF:
992 #endif
993     case SCOPE_REF:
994     case PTRMEM_CST:
995       pp_cxx_qualified_id (pp, t);
996       break;
997
998     case OVERLOAD:
999       t = OVL_CURRENT (t);
1000     case VAR_DECL:
1001     case PARM_DECL:
1002     case FIELD_DECL:
1003     case CONST_DECL:
1004     case FUNCTION_DECL:
1005     case BASELINK:
1006     case TEMPLATE_DECL:
1007     case TEMPLATE_TYPE_PARM:
1008     case TEMPLATE_PARM_INDEX:
1009     case TEMPLATE_TEMPLATE_PARM:
1010     case STMT_EXPR:
1011       pp_cxx_primary_expression (pp, t);
1012       break;
1013
1014     case CALL_EXPR:
1015     case DYNAMIC_CAST_EXPR:
1016     case STATIC_CAST_EXPR:
1017     case REINTERPRET_CAST_EXPR:
1018     case CONST_CAST_EXPR:
1019 #if 0
1020     case MEMBER_REF:
1021 #endif
1022     case EMPTY_CLASS_EXPR:
1023     case TYPEID_EXPR:
1024     case PSEUDO_DTOR_EXPR:
1025     case AGGR_INIT_EXPR:
1026     case ARROW_EXPR:
1027       pp_cxx_postfix_expression (pp, t);
1028       break;
1029
1030     case NEW_EXPR:
1031     case VEC_NEW_EXPR:
1032       pp_cxx_new_expression (pp, t);
1033       break;
1034
1035     case DELETE_EXPR:
1036     case VEC_DELETE_EXPR:
1037       pp_cxx_delete_expression (pp, t);
1038       break;
1039
1040     case SIZEOF_EXPR:
1041     case ALIGNOF_EXPR:
1042       pp_cxx_unary_expression (pp, t);
1043       break;
1044
1045     case CAST_EXPR:
1046       pp_cxx_cast_expression (pp, t);
1047       break;
1048
1049     case OFFSET_REF:
1050     case MEMBER_REF:
1051     case DOTSTAR_EXPR:
1052       pp_cxx_pm_expression (pp, t);
1053       break;
1054
1055     case MULT_EXPR:
1056     case TRUNC_DIV_EXPR:
1057     case TRUNC_MOD_EXPR:
1058       pp_cxx_multiplicative_expression (pp, t);
1059       break;
1060
1061     case COND_EXPR:
1062       pp_cxx_conditional_expression (pp, t);
1063       break;
1064
1065     case MODIFY_EXPR:
1066     case INIT_EXPR:
1067     case THROW_EXPR:
1068     case MODOP_EXPR:
1069       pp_cxx_assignment_expression (pp, t);
1070       break;
1071
1072     case NON_DEPENDENT_EXPR:
1073     case MUST_NOT_THROW_EXPR:
1074       pp_cxx_expression (pp, TREE_OPERAND (t, 0));
1075       break;
1076
1077     case EXPR_PACK_EXPANSION:
1078       pp_cxx_expression (pp, PACK_EXPANSION_PATTERN (t));
1079       pp_cxx_identifier (pp, "...");
1080       break;
1081
1082     case NONTYPE_ARGUMENT_PACK:
1083       {
1084         tree args = ARGUMENT_PACK_ARGS (t);
1085         int i, len = TREE_VEC_LENGTH (args);
1086         for (i = 0; i < len; ++i)
1087           {
1088             if (i > 0)
1089               pp_cxx_separate_with (pp, ',');
1090             pp_cxx_expression (pp, TREE_VEC_ELT (args, i));
1091           }
1092       }
1093       break;
1094
1095     default:
1096       pp_c_expression (pp_c_base (pp), t);
1097       break;
1098     }
1099 }
1100
1101
1102 /* Declarations.  */
1103
1104 /* function-specifier:
1105       inline
1106       virtual
1107       explicit   */
1108
1109 static void
1110 pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
1111 {
1112   switch (TREE_CODE (t))
1113     {
1114     case FUNCTION_DECL:
1115       if (DECL_VIRTUAL_P (t))
1116         pp_cxx_identifier (pp, "virtual");
1117       else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1118         pp_cxx_identifier (pp, "explicit");
1119       else
1120         pp_c_function_specifier (pp_c_base (pp), t);
1121
1122     default:
1123       break;
1124     }
1125 }
1126
1127 /* decl-specifier-seq:
1128       decl-specifier-seq(opt) decl-specifier
1129
1130    decl-specifier:
1131       storage-class-specifier
1132       type-specifier
1133       function-specifier
1134       friend
1135       typedef  */
1136
1137 static void
1138 pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
1139 {
1140   switch (TREE_CODE (t))
1141     {
1142     case VAR_DECL:
1143     case PARM_DECL:
1144     case CONST_DECL:
1145     case FIELD_DECL:
1146       pp_cxx_storage_class_specifier (pp, t);
1147       pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1148       break;
1149
1150     case TYPE_DECL:
1151       pp_cxx_identifier (pp, "typedef");
1152       pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1153       break;
1154
1155     case RECORD_TYPE:
1156       if (TYPE_PTRMEMFUNC_P (t))
1157         {
1158           tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1159           pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
1160           pp_cxx_whitespace (pp);
1161           pp_cxx_ptr_operator (pp, t);
1162         }
1163       break;
1164
1165     case FUNCTION_DECL:
1166       /* Constructors don't have return types.  And conversion functions
1167          do not have a type-specifier in their return types.  */
1168       if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1169         pp_cxx_function_specifier (pp, t);
1170       else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1171         pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
1172       else
1173         default:
1174       pp_c_declaration_specifiers (pp_c_base (pp), t);
1175       break;
1176     }
1177 }
1178
1179 /* simple-type-specifier:
1180       ::(opt) nested-name-specifier(opt) type-name
1181       ::(opt) nested-name-specifier(opt) template(opt) template-id
1182       char
1183       wchar_t
1184       bool
1185       short
1186       int
1187       long
1188       signed
1189       unsigned
1190       float
1191       double
1192       void  */
1193
1194 static void
1195 pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
1196 {
1197   switch (TREE_CODE (t))
1198     {
1199     case RECORD_TYPE:
1200     case UNION_TYPE:
1201     case ENUMERAL_TYPE:
1202       pp_cxx_qualified_id (pp, t);
1203       break;
1204
1205     case TEMPLATE_TYPE_PARM:
1206     case TEMPLATE_TEMPLATE_PARM:
1207     case TEMPLATE_PARM_INDEX:
1208       pp_cxx_unqualified_id (pp, t);
1209       break;
1210
1211     case TYPENAME_TYPE:
1212       pp_cxx_identifier (pp, "typename");
1213       pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1214       pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1215       break;
1216
1217     default:
1218       pp_c_type_specifier (pp_c_base (pp), t);
1219       break;
1220     }
1221 }
1222
1223 /* type-specifier-seq:
1224       type-specifier type-specifier-seq(opt)
1225
1226    type-specifier:
1227       simple-type-specifier
1228       class-specifier
1229       enum-specifier
1230       elaborated-type-specifier
1231       cv-qualifier   */
1232
1233 static void
1234 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1235 {
1236   switch (TREE_CODE (t))
1237     {
1238     case TEMPLATE_DECL:
1239     case TEMPLATE_TYPE_PARM:
1240     case TEMPLATE_TEMPLATE_PARM:
1241     case TYPE_DECL:
1242     case BOUND_TEMPLATE_TEMPLATE_PARM:
1243       pp_cxx_cv_qualifier_seq (pp, t);
1244       pp_cxx_simple_type_specifier (pp, t);
1245       break;
1246
1247     case METHOD_TYPE:
1248       pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1249       pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1250       pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1251       break;
1252
1253     case DECLTYPE_TYPE:
1254       pp_cxx_identifier (pp, "decltype");
1255       pp_cxx_left_paren (pp);
1256       pp_cxx_expression (pp, DECLTYPE_TYPE_EXPR (t));
1257       pp_cxx_right_paren (pp);
1258       break;
1259
1260     default:
1261       if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1262         pp_c_specifier_qualifier_list (pp_c_base (pp), t);
1263     }
1264 }
1265
1266 /* ptr-operator:
1267       * cv-qualifier-seq(opt)
1268       &
1269       ::(opt) nested-name-specifier * cv-qualifier-seq(opt)  */
1270
1271 static void
1272 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1273 {
1274   if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1275     t = TREE_TYPE (t);
1276   switch (TREE_CODE (t))
1277     {
1278     case REFERENCE_TYPE:
1279     case POINTER_TYPE:
1280       if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
1281           || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
1282         pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1283       if (TREE_CODE (t) == POINTER_TYPE)
1284         {
1285           pp_star (pp);
1286           pp_cxx_cv_qualifier_seq (pp, t);
1287         }
1288       else
1289         pp_ampersand (pp);
1290       break;
1291
1292     case RECORD_TYPE:
1293       if (TYPE_PTRMEMFUNC_P (t))
1294         {
1295           pp_cxx_left_paren (pp);
1296           pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1297           pp_star (pp);
1298           break;
1299         }
1300     case OFFSET_TYPE:
1301       if (TYPE_PTR_TO_MEMBER_P (t))
1302         {
1303           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1304             pp_cxx_left_paren (pp);
1305           pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1306           pp_star (pp);
1307           pp_cxx_cv_qualifier_seq (pp, t);
1308           break;
1309         }
1310       /* else fall through.  */
1311
1312     default:
1313       pp_unsupported_tree (pp, t);
1314       break;
1315     }
1316 }
1317
1318 static inline tree
1319 pp_cxx_implicit_parameter_type (tree mf)
1320 {
1321   return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1322 }
1323
1324 /*
1325    parameter-declaration:
1326       decl-specifier-seq declarator
1327       decl-specifier-seq declarator = assignment-expression
1328       decl-specifier-seq abstract-declarator(opt)
1329       decl-specifier-seq abstract-declarator(opt) assignment-expression  */
1330
1331 static inline void
1332 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1333 {
1334   pp_cxx_decl_specifier_seq (pp, t);
1335   if (TYPE_P (t))
1336     pp_cxx_abstract_declarator (pp, t);
1337   else
1338     pp_cxx_declarator (pp, t);
1339 }
1340
1341 /* parameter-declaration-clause:
1342       parameter-declaration-list(opt) ...(opt)
1343       parameter-declaration-list , ...
1344
1345    parameter-declaration-list:
1346       parameter-declaration
1347       parameter-declaration-list , parameter-declaration  */
1348
1349 static void
1350 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1351 {
1352   tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1353   tree types =
1354     TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1355   const bool abstract = args == NULL
1356     || pp_c_base (pp)->flags & pp_c_flag_abstract;
1357   bool first = true;
1358
1359   /* Skip artificial parameter for nonstatic member functions.  */
1360   if (TREE_CODE (t) == METHOD_TYPE)
1361     types = TREE_CHAIN (types);
1362
1363   pp_cxx_left_paren (pp);
1364   for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1365     {
1366       if (!first)
1367         pp_cxx_separate_with (pp, ',');
1368       first = false;
1369       pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1370       if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1371         {
1372           pp_cxx_whitespace (pp);
1373           pp_equal (pp);
1374           pp_cxx_whitespace (pp);
1375           pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1376         }
1377     }
1378   pp_cxx_right_paren (pp);
1379 }
1380
1381 /* exception-specification:
1382       throw ( type-id-list(opt) )
1383
1384    type-id-list
1385       type-id
1386       type-id-list , type-id   */
1387
1388 static void
1389 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1390 {
1391   tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1392   bool need_comma = false;
1393
1394   if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1395     return;
1396   pp_cxx_identifier (pp, "throw");
1397   pp_cxx_left_paren (pp);
1398   for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1399     {
1400       tree type = TREE_VALUE (ex_spec);
1401       tree argpack = NULL_TREE;
1402       int i, len = 1;
1403
1404       if (ARGUMENT_PACK_P (type))
1405         {
1406           argpack = ARGUMENT_PACK_ARGS (type);
1407           len = TREE_VEC_LENGTH (argpack);
1408         }
1409
1410       for (i = 0; i < len; ++i)
1411         {
1412           if (argpack)
1413             type = TREE_VEC_ELT (argpack, i);
1414
1415           if (need_comma)
1416             pp_cxx_separate_with (pp, ',');
1417           else
1418             need_comma = true;
1419
1420           pp_cxx_type_id (pp, type);
1421         }
1422     }
1423   pp_cxx_right_paren (pp);
1424 }
1425
1426 /* direct-declarator:
1427       declarator-id
1428       direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1429                                             exception-specification(opt)
1430       direct-declaration [ constant-expression(opt) ]
1431       ( declarator )  */
1432
1433 static void
1434 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1435 {
1436   switch (TREE_CODE (t))
1437     {
1438     case VAR_DECL:
1439     case PARM_DECL:
1440     case CONST_DECL:
1441     case FIELD_DECL:
1442       if (DECL_NAME (t))
1443         {
1444           pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1445
1446           if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
1447               || template_parameter_pack_p (t))
1448             /* A function parameter pack or non-type template
1449                parameter pack.  */
1450             pp_cxx_identifier (pp, "...");
1451                       
1452           pp_cxx_id_expression (pp, DECL_NAME (t));
1453         }
1454       pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1455       break;
1456
1457     case FUNCTION_DECL:
1458       pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1459       pp_cxx_id_expression (pp, t);
1460       pp_cxx_parameter_declaration_clause (pp, t);
1461
1462       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1463         {
1464           pp_base (pp)->padding = pp_before;
1465           pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1466         }
1467
1468       pp_cxx_exception_specification (pp, TREE_TYPE (t));
1469       break;
1470
1471     case TYPENAME_TYPE:
1472     case TEMPLATE_DECL:
1473     case TEMPLATE_TYPE_PARM:
1474     case TEMPLATE_PARM_INDEX:
1475     case TEMPLATE_TEMPLATE_PARM:
1476       break;
1477
1478     default:
1479       pp_c_direct_declarator (pp_c_base (pp), t);
1480       break;
1481     }
1482 }
1483
1484 /* declarator:
1485    direct-declarator
1486    ptr-operator declarator  */
1487
1488 static void
1489 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1490 {
1491   pp_cxx_direct_declarator (pp, t);
1492 }
1493
1494 /* ctor-initializer:
1495       : mem-initializer-list
1496
1497    mem-initializer-list:
1498       mem-initializer
1499       mem-initializer , mem-initializer-list
1500
1501    mem-initializer:
1502       mem-initializer-id ( expression-list(opt) )
1503
1504    mem-initializer-id:
1505       ::(opt) nested-name-specifier(opt) class-name
1506       identifier   */
1507
1508 static void
1509 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1510 {
1511   t = TREE_OPERAND (t, 0);
1512   pp_cxx_whitespace (pp);
1513   pp_colon (pp);
1514   pp_cxx_whitespace (pp);
1515   for (; t; t = TREE_CHAIN (t))
1516     {
1517       tree purpose = TREE_PURPOSE (t);
1518       bool is_pack = PACK_EXPANSION_P (purpose);
1519
1520       if (is_pack)
1521         pp_cxx_primary_expression (pp, PACK_EXPANSION_PATTERN (purpose));
1522       else
1523         pp_cxx_primary_expression (pp, purpose);
1524       pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1525       if (is_pack)
1526         pp_cxx_identifier (pp, "...");
1527       if (TREE_CHAIN (t))
1528         pp_cxx_separate_with (pp, ',');
1529     }
1530 }
1531
1532 /* function-definition:
1533       decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1534       decl-specifier-seq(opt) declarator function-try-block  */
1535
1536 static void
1537 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1538 {
1539   tree saved_scope = pp->enclosing_scope;
1540   pp_cxx_decl_specifier_seq (pp, t);
1541   pp_cxx_declarator (pp, t);
1542   pp_needs_newline (pp) = true;
1543   pp->enclosing_scope = DECL_CONTEXT (t);
1544   if (DECL_SAVED_TREE (t))
1545     pp_cxx_statement (pp, DECL_SAVED_TREE (t));
1546   else
1547     {
1548       pp_cxx_semicolon (pp);
1549       pp_needs_newline (pp) = true;
1550     }
1551   pp_flush (pp);
1552   pp->enclosing_scope = saved_scope;
1553 }
1554
1555 /* abstract-declarator:
1556       ptr-operator abstract-declarator(opt)
1557       direct-abstract-declarator  */
1558
1559 static void
1560 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1561 {
1562   if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1563     pp_cxx_right_paren (pp);
1564   else if (POINTER_TYPE_P (t))
1565     {
1566       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1567           || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1568         pp_cxx_right_paren (pp);
1569       t = TREE_TYPE (t);
1570     }
1571   pp_cxx_direct_abstract_declarator (pp, t);
1572 }
1573
1574 /* direct-abstract-declarator:
1575       direct-abstract-declarator(opt) ( parameter-declaration-clause )
1576                            cv-qualifier-seq(opt) exception-specification(opt)
1577       direct-abstract-declarator(opt) [ constant-expression(opt) ]
1578       ( abstract-declarator )  */
1579
1580 static void
1581 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1582 {
1583   switch (TREE_CODE (t))
1584     {
1585     case REFERENCE_TYPE:
1586       pp_cxx_abstract_declarator (pp, t);
1587       break;
1588
1589     case RECORD_TYPE:
1590       if (TYPE_PTRMEMFUNC_P (t))
1591         pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1592       break;
1593
1594     case METHOD_TYPE:
1595     case FUNCTION_TYPE:
1596       pp_cxx_parameter_declaration_clause (pp, t);
1597       pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1598       if (TREE_CODE (t) == METHOD_TYPE)
1599         {
1600           pp_base (pp)->padding = pp_before;
1601           pp_cxx_cv_qualifier_seq
1602             (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1603         }
1604       pp_cxx_exception_specification (pp, t);
1605       break;
1606
1607     case TYPENAME_TYPE:
1608     case TEMPLATE_TYPE_PARM:
1609     case TEMPLATE_TEMPLATE_PARM:
1610     case BOUND_TEMPLATE_TEMPLATE_PARM:
1611     case UNBOUND_CLASS_TEMPLATE:
1612       break;
1613
1614     default:
1615       pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1616       break;
1617     }
1618 }
1619
1620 /* type-id:
1621      type-specifier-seq abstract-declarator(opt) */
1622
1623 static void
1624 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1625 {
1626   pp_flags saved_flags = pp_c_base (pp)->flags;
1627   pp_c_base (pp)->flags |= pp_c_flag_abstract;
1628
1629   switch (TREE_CODE (t))
1630     {
1631     case TYPE_DECL:
1632     case UNION_TYPE:
1633     case RECORD_TYPE:
1634     case ENUMERAL_TYPE:
1635     case TYPENAME_TYPE:
1636     case BOUND_TEMPLATE_TEMPLATE_PARM:
1637     case UNBOUND_CLASS_TEMPLATE:
1638     case TEMPLATE_TEMPLATE_PARM:
1639     case TEMPLATE_TYPE_PARM:
1640     case TEMPLATE_PARM_INDEX:
1641     case TEMPLATE_DECL:
1642     case TYPEOF_TYPE:
1643     case DECLTYPE_TYPE:
1644     case TEMPLATE_ID_EXPR:
1645       pp_cxx_type_specifier_seq (pp, t);
1646       break;
1647
1648     case TYPE_PACK_EXPANSION:
1649       pp_cxx_type_id (pp, PACK_EXPANSION_PATTERN (t));
1650       pp_cxx_identifier (pp, "...");
1651       break;
1652
1653     default:
1654       pp_c_type_id (pp_c_base (pp), t);
1655       break;
1656     }
1657
1658   pp_c_base (pp)->flags = saved_flags;
1659 }
1660
1661 /* template-argument-list:
1662       template-argument ...(opt)
1663       template-argument-list, template-argument ...(opt)
1664
1665    template-argument:
1666       assignment-expression
1667       type-id
1668       template-name  */
1669
1670 static void
1671 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1672 {
1673   int i;
1674   bool need_comma = false;
1675
1676   if (t == NULL)
1677     return;
1678   for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1679     {
1680       tree arg = TREE_VEC_ELT (t, i);
1681       tree argpack = NULL_TREE;
1682       int idx, len = 1;
1683
1684       if (ARGUMENT_PACK_P (arg))
1685         {
1686           argpack = ARGUMENT_PACK_ARGS (arg);
1687           len = TREE_VEC_LENGTH (argpack);
1688         }
1689
1690       for (idx = 0; idx < len; idx++)
1691         {
1692           if (argpack)
1693             arg = TREE_VEC_ELT (argpack, idx);
1694           
1695           if (need_comma)
1696             pp_cxx_separate_with (pp, ',');
1697           else
1698             need_comma = true;
1699
1700           if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1701                                && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1702             pp_cxx_type_id (pp, arg);
1703           else
1704             pp_cxx_expression (pp, arg);
1705         }
1706     }
1707 }
1708
1709
1710 static void
1711 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1712 {
1713   t = DECL_EXPR_DECL (t);
1714   pp_cxx_type_specifier_seq (pp, t);
1715   if (TYPE_P (t))
1716     pp_cxx_abstract_declarator (pp, t);
1717   else
1718     pp_cxx_declarator (pp, t);
1719 }
1720
1721 /* Statements.  */
1722
1723 static void
1724 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1725 {
1726   switch (TREE_CODE (t))
1727     {
1728     case CTOR_INITIALIZER:
1729       pp_cxx_ctor_initializer (pp, t);
1730       break;
1731
1732     case USING_STMT:
1733       pp_cxx_identifier (pp, "using");
1734       pp_cxx_identifier (pp, "namespace");
1735       if (DECL_CONTEXT (t))
1736         pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1737       pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1738       break;
1739
1740     case USING_DECL:
1741       pp_cxx_identifier (pp, "using");
1742       pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
1743       pp_cxx_unqualified_id (pp, DECL_NAME (t));
1744       break;
1745
1746     case EH_SPEC_BLOCK:
1747       break;
1748
1749       /* try-block:
1750             try compound-statement handler-seq  */
1751     case TRY_BLOCK:
1752       pp_maybe_newline_and_indent (pp, 0);
1753       pp_cxx_identifier (pp, "try");
1754       pp_newline_and_indent (pp, 3);
1755       pp_cxx_statement (pp, TRY_STMTS (t));
1756       pp_newline_and_indent (pp, -3);
1757       if (CLEANUP_P (t))
1758         ;
1759       else
1760         pp_cxx_statement (pp, TRY_HANDLERS (t));
1761       break;
1762
1763       /*
1764          handler-seq:
1765             handler handler-seq(opt)
1766
1767          handler:
1768          catch ( exception-declaration ) compound-statement
1769
1770          exception-declaration:
1771             type-specifier-seq declarator
1772             type-specifier-seq abstract-declarator
1773             ...   */
1774     case HANDLER:
1775       pp_cxx_identifier (pp, "catch");
1776       pp_cxx_left_paren (pp);
1777       pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1778       pp_cxx_right_paren (pp);
1779       pp_indentation (pp) += 3;
1780       pp_needs_newline (pp) = true;
1781       pp_cxx_statement (pp, HANDLER_BODY (t));
1782       pp_indentation (pp) -= 3;
1783       pp_needs_newline (pp) = true;
1784       break;
1785
1786       /* selection-statement:
1787             if ( expression ) statement
1788             if ( expression ) statement else statement  */
1789     case IF_STMT:
1790       pp_cxx_identifier (pp, "if");
1791       pp_cxx_whitespace (pp);
1792       pp_cxx_left_paren (pp);
1793       pp_cxx_expression (pp, IF_COND (t));
1794       pp_cxx_right_paren (pp);
1795       pp_newline_and_indent (pp, 2);
1796       pp_cxx_statement (pp, THEN_CLAUSE (t));
1797       pp_newline_and_indent (pp, -2);
1798       if (ELSE_CLAUSE (t))
1799         {
1800           tree else_clause = ELSE_CLAUSE (t);
1801           pp_cxx_identifier (pp, "else");
1802           if (TREE_CODE (else_clause) == IF_STMT)
1803             pp_cxx_whitespace (pp);
1804           else
1805             pp_newline_and_indent (pp, 2);
1806           pp_cxx_statement (pp, else_clause);
1807           if (TREE_CODE (else_clause) != IF_STMT)
1808             pp_newline_and_indent (pp, -2);
1809         }
1810       break;
1811
1812     case SWITCH_STMT:
1813       pp_cxx_identifier (pp, "switch");
1814       pp_space (pp);
1815       pp_cxx_left_paren (pp);
1816       pp_cxx_expression (pp, SWITCH_STMT_COND (t));
1817       pp_cxx_right_paren (pp);
1818       pp_indentation (pp) += 3;
1819       pp_needs_newline (pp) = true;
1820       pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
1821       pp_newline_and_indent (pp, -3);
1822       break;
1823
1824       /* iteration-statement:
1825             while ( expression ) statement
1826             do statement while ( expression ) ;
1827             for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1828             for ( declaration expression(opt) ; expression(opt) ) statement  */
1829     case WHILE_STMT:
1830       pp_cxx_identifier (pp, "while");
1831       pp_space (pp);
1832       pp_cxx_left_paren (pp);
1833       pp_cxx_expression (pp, WHILE_COND (t));
1834       pp_cxx_right_paren (pp);
1835       pp_newline_and_indent (pp, 3);
1836       pp_cxx_statement (pp, WHILE_BODY (t));
1837       pp_indentation (pp) -= 3;
1838       pp_needs_newline (pp) = true;
1839       break;
1840
1841     case DO_STMT:
1842       pp_cxx_identifier (pp, "do");
1843       pp_newline_and_indent (pp, 3);
1844       pp_cxx_statement (pp, DO_BODY (t));
1845       pp_newline_and_indent (pp, -3);
1846       pp_cxx_identifier (pp, "while");
1847       pp_space (pp);
1848       pp_cxx_left_paren (pp);
1849       pp_cxx_expression (pp, DO_COND (t));
1850       pp_cxx_right_paren (pp);
1851       pp_cxx_semicolon (pp);
1852       pp_needs_newline (pp) = true;
1853       break;
1854
1855     case FOR_STMT:
1856       pp_cxx_identifier (pp, "for");
1857       pp_space (pp);
1858       pp_cxx_left_paren (pp);
1859       if (FOR_INIT_STMT (t))
1860         pp_cxx_statement (pp, FOR_INIT_STMT (t));
1861       else
1862         pp_cxx_semicolon (pp);
1863       pp_needs_newline (pp) = false;
1864       pp_cxx_whitespace (pp);
1865       if (FOR_COND (t))
1866         pp_cxx_expression (pp, FOR_COND (t));
1867       pp_cxx_semicolon (pp);
1868       pp_needs_newline (pp) = false;
1869       pp_cxx_whitespace (pp);
1870       if (FOR_EXPR (t))
1871         pp_cxx_expression (pp, FOR_EXPR (t));
1872       pp_cxx_right_paren (pp);
1873       pp_newline_and_indent (pp, 3);
1874       pp_cxx_statement (pp, FOR_BODY (t));
1875       pp_indentation (pp) -= 3;
1876       pp_needs_newline (pp) = true;
1877       break;
1878
1879       /* jump-statement:
1880             goto identifier;
1881             continue ;
1882             return expression(opt) ;  */
1883     case BREAK_STMT:
1884     case CONTINUE_STMT:
1885       pp_identifier (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1886       pp_cxx_semicolon (pp);
1887       pp_needs_newline (pp) = true;
1888       break;
1889
1890       /* expression-statement:
1891             expression(opt) ;  */
1892     case EXPR_STMT:
1893       pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
1894       pp_cxx_semicolon (pp);
1895       pp_needs_newline (pp) = true;
1896       break;
1897
1898     case CLEANUP_STMT:
1899       pp_cxx_identifier (pp, "try");
1900       pp_newline_and_indent (pp, 2);
1901       pp_cxx_statement (pp, CLEANUP_BODY (t));
1902       pp_newline_and_indent (pp, -2);
1903       pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1904       pp_newline_and_indent (pp, 2);
1905       pp_cxx_statement (pp, CLEANUP_EXPR (t));
1906       pp_newline_and_indent (pp, -2);
1907       break;
1908
1909     case STATIC_ASSERT:
1910       pp_cxx_declaration (pp, t);
1911       break;
1912
1913     default:
1914       pp_c_statement (pp_c_base (pp), t);
1915       break;
1916     }
1917 }
1918
1919 /* original-namespace-definition:
1920       namespace identifier { namespace-body }
1921
1922   As an edge case, we also handle unnamed namespace definition here.  */
1923
1924 static void
1925 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1926 {
1927   pp_cxx_identifier (pp, "namespace");
1928   if (DECL_CONTEXT (t))
1929     pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1930   if (DECL_NAME (t))
1931     pp_cxx_unqualified_id (pp, t);
1932   pp_cxx_whitespace (pp);
1933   pp_cxx_left_brace (pp);
1934   /* We do not print the namespace-body.  */
1935   pp_cxx_whitespace (pp);
1936   pp_cxx_right_brace (pp);
1937 }
1938
1939 /* namespace-alias:
1940       identifier
1941
1942    namespace-alias-definition:
1943       namespace identifier = qualified-namespace-specifier ;
1944
1945    qualified-namespace-specifier:
1946       ::(opt) nested-name-specifier(opt) namespace-name   */
1947
1948 static void
1949 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1950 {
1951   pp_cxx_identifier (pp, "namespace");
1952   if (DECL_CONTEXT (t))
1953     pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1954   pp_cxx_unqualified_id (pp, t);
1955   pp_cxx_whitespace (pp);
1956   pp_equal (pp);
1957   pp_cxx_whitespace (pp);
1958   if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
1959     pp_cxx_nested_name_specifier (pp,
1960                                   DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
1961   pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1962   pp_cxx_semicolon (pp);
1963 }
1964
1965 /* simple-declaration:
1966       decl-specifier-seq(opt) init-declarator-list(opt)  */
1967
1968 static void
1969 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1970 {
1971   pp_cxx_decl_specifier_seq (pp, t);
1972   pp_cxx_init_declarator (pp, t);
1973   pp_cxx_semicolon (pp);
1974   pp_needs_newline (pp) = true;
1975 }
1976
1977 /*
1978   template-parameter-list:
1979      template-parameter
1980      template-parameter-list , template-parameter  */
1981
1982 static inline void
1983 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1984 {
1985   const int n = TREE_VEC_LENGTH (t);
1986   int i;
1987   for (i = 0; i < n; ++i)
1988     {
1989       if (i)
1990         pp_cxx_separate_with (pp, ',');
1991       pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1992     }
1993 }
1994
1995 /* template-parameter:
1996       type-parameter
1997       parameter-declaration
1998
1999    type-parameter:
2000      class ...(opt) identifier(opt)
2001      class identifier(opt) = type-id
2002      typename identifier(opt)
2003      typename ...(opt) identifier(opt) = type-id
2004      template < template-parameter-list > class ...(opt) identifier(opt)
2005      template < template-parameter-list > class identifier(opt) = template-name  */
2006
2007 static void
2008 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2009 {
2010   tree parameter =  TREE_VALUE (t);
2011   switch (TREE_CODE (parameter))
2012     {
2013     case TYPE_DECL:
2014       pp_cxx_identifier (pp, "class");
2015       if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2016         pp_cxx_identifier (pp, "...");
2017       if (DECL_NAME (parameter))
2018         pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2019       /* FIXME: Check if we should print also default argument.  */
2020       break;
2021
2022     case PARM_DECL:
2023       pp_cxx_parameter_declaration (pp, parameter);
2024       break;
2025
2026     case TEMPLATE_DECL:
2027       break;
2028
2029     default:
2030       pp_unsupported_tree (pp, t);
2031       break;
2032     }
2033 }
2034
2035 /* Pretty-print a template parameter in the canonical form
2036    "template-parameter-<level>-<position in parameter list>".  */
2037
2038 void
2039 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2040 {
2041   const enum tree_code code = TREE_CODE (parm);
2042
2043   /* Brings type template parameters to the canonical forms.  */
2044   if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2045       || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2046     parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2047
2048   pp_cxx_begin_template_argument_list (pp);
2049   pp_cxx_identifier (pp, "template-parameter-");
2050   pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2051   pp_minus (pp);
2052   pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2053   pp_cxx_end_template_argument_list (pp);
2054 }
2055
2056 /*
2057   template-declaration:
2058      export(opt) template < template-parameter-list > declaration   */
2059
2060 static void
2061 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2062 {
2063   tree tmpl = most_general_template (t);
2064   tree level;
2065   int i = 0;
2066
2067   pp_maybe_newline_and_indent (pp, 0);
2068   for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2069     {
2070       pp_cxx_identifier (pp, "template");
2071       pp_cxx_begin_template_argument_list (pp);
2072       pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2073       pp_cxx_end_template_argument_list (pp);
2074       pp_newline_and_indent (pp, 3);
2075       i += 3;
2076     }
2077   if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2078     pp_cxx_function_definition (pp, t);
2079   else
2080     pp_cxx_simple_declaration (pp, t);
2081 }
2082
2083 static void
2084 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2085 {
2086   pp_unsupported_tree (pp, t);
2087 }
2088
2089 static void
2090 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2091 {
2092   pp_unsupported_tree (pp, t);
2093 }
2094
2095 /*
2096     declaration:
2097        block-declaration
2098        function-definition
2099        template-declaration
2100        explicit-instantiation
2101        explicit-specialization
2102        linkage-specification
2103        namespace-definition
2104
2105     block-declaration:
2106        simple-declaration
2107        asm-definition
2108        namespace-alias-definition
2109        using-declaration
2110        using-directive
2111        static_assert-declaration */
2112 void
2113 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
2114 {
2115   if (TREE_CODE (t) == STATIC_ASSERT)
2116     {
2117       pp_cxx_identifier (pp, "static_assert");
2118       pp_cxx_left_paren (pp);
2119       pp_cxx_expression (pp, STATIC_ASSERT_CONDITION (t));
2120       pp_cxx_separate_with (pp, ',');
2121       pp_cxx_expression (pp, STATIC_ASSERT_MESSAGE (t));
2122       pp_cxx_right_paren (pp);
2123     }
2124   else if (!DECL_LANG_SPECIFIC (t))
2125     pp_cxx_simple_declaration (pp, t);
2126   else if (DECL_USE_TEMPLATE (t))
2127     switch (DECL_USE_TEMPLATE (t))
2128       {
2129       case 1:
2130         pp_cxx_template_declaration (pp, t);
2131         break;
2132
2133       case 2:
2134         pp_cxx_explicit_specialization (pp, t);
2135         break;
2136
2137       case 3:
2138         pp_cxx_explicit_instantiation (pp, t);
2139         break;
2140
2141       default:
2142         break;
2143       }
2144   else switch (TREE_CODE (t))
2145     {
2146     case VAR_DECL:
2147     case TYPE_DECL:
2148       pp_cxx_simple_declaration (pp, t);
2149       break;
2150
2151     case FUNCTION_DECL:
2152       if (DECL_SAVED_TREE (t))
2153         pp_cxx_function_definition (pp, t);
2154       else
2155         pp_cxx_simple_declaration (pp, t);
2156       break;
2157
2158     case NAMESPACE_DECL:
2159       if (DECL_NAMESPACE_ALIAS (t))
2160         pp_cxx_namespace_alias_definition (pp, t);
2161       else
2162         pp_cxx_original_namespace_definition (pp, t);
2163       break;
2164
2165     default:
2166       pp_unsupported_tree (pp, t);
2167       break;
2168     }
2169 }
2170
2171 static void
2172 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2173 {
2174   t = TREE_OPERAND (t, 0);
2175   pp_cxx_identifier (pp, "typeid");
2176   pp_cxx_left_paren (pp);
2177   if (TYPE_P (t))
2178     pp_cxx_type_id (pp, t);
2179   else
2180     pp_cxx_expression (pp, t);
2181   pp_cxx_right_paren (pp);
2182 }
2183
2184 void
2185 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2186 {
2187   pp_cxx_identifier (pp, "va_arg");
2188   pp_cxx_left_paren (pp);
2189   pp_cxx_assignment_expression (pp, TREE_OPERAND (t, 0));
2190   pp_cxx_separate_with (pp, ',');
2191   pp_cxx_type_id (pp, TREE_TYPE (t));
2192   pp_cxx_right_paren (pp);
2193 }
2194
2195 static bool
2196 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2197 {
2198   switch (TREE_CODE (t))
2199     {
2200     case ARROW_EXPR:
2201       if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2202           && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2203         {
2204           pp_cxx_type_id (pp, TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2205           pp_cxx_separate_with (pp, ',');
2206           return true;
2207         }
2208       return false;
2209     case COMPONENT_REF:
2210       if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2211         return false;
2212       if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2213         pp_cxx_dot (pp);
2214       pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2215       return true;
2216     case ARRAY_REF:
2217       if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2218         return false;
2219       pp_left_bracket (pp);
2220       pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2221       pp_right_bracket (pp);
2222       return true;
2223     default:
2224       return false;
2225     }
2226 }
2227
2228 void
2229 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2230 {
2231   pp_cxx_identifier (pp, "offsetof");
2232   pp_cxx_left_paren (pp);
2233   if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2234     pp_cxx_expression (pp, TREE_OPERAND (t, 0));
2235   pp_cxx_right_paren (pp);
2236 }
2237
2238 void
2239 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2240 {
2241   cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2242
2243   switch (kind)
2244     {
2245     case CPTK_HAS_NOTHROW_ASSIGN:
2246       pp_cxx_identifier (pp, "__has_nothrow_assign");
2247       break;
2248     case CPTK_HAS_TRIVIAL_ASSIGN:
2249       pp_cxx_identifier (pp, "__has_trivial_assign");
2250       break;
2251     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2252       pp_cxx_identifier (pp, "__has_nothrow_constructor");
2253       break;
2254     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2255       pp_cxx_identifier (pp, "__has_trivial_constructor");
2256       break;
2257     case CPTK_HAS_NOTHROW_COPY:
2258       pp_cxx_identifier (pp, "__has_nothrow_copy");
2259       break;
2260     case CPTK_HAS_TRIVIAL_COPY:
2261       pp_cxx_identifier (pp, "__has_trivial_copy");
2262       break;
2263     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2264       pp_cxx_identifier (pp, "__has_trivial_destructor");
2265       break;
2266     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2267       pp_cxx_identifier (pp, "__has_virtual_destructor");
2268       break;
2269     case CPTK_IS_ABSTRACT:
2270       pp_cxx_identifier (pp, "__is_abstract");
2271       break;
2272     case CPTK_IS_BASE_OF:
2273       pp_cxx_identifier (pp, "__is_base_of");
2274       break;
2275     case CPTK_IS_CLASS:
2276       pp_cxx_identifier (pp, "__is_class");
2277       break;
2278     case CPTK_IS_CONVERTIBLE_TO:
2279       pp_cxx_identifier (pp, "__is_convertible_to");
2280       break;
2281     case CPTK_IS_EMPTY:
2282       pp_cxx_identifier (pp, "__is_empty");
2283       break;
2284     case CPTK_IS_ENUM:
2285       pp_cxx_identifier (pp, "__is_enum");
2286       break;
2287     case CPTK_IS_POD:
2288       pp_cxx_identifier (pp, "__is_pod");
2289       break;
2290     case CPTK_IS_POLYMORPHIC:
2291       pp_cxx_identifier (pp, "__is_polymorphic");
2292       break;
2293     case CPTK_IS_UNION:
2294       pp_cxx_identifier (pp, "__is_union");
2295       break;
2296
2297     default:
2298       gcc_unreachable ();
2299     }
2300
2301   pp_cxx_left_paren (pp);
2302   pp_cxx_type_id (pp, TRAIT_EXPR_TYPE1 (t));
2303
2304   if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2305     {
2306       pp_cxx_separate_with (pp, ',');
2307       pp_cxx_type_id (pp, TRAIT_EXPR_TYPE2 (t));
2308     }
2309
2310   pp_cxx_right_paren (pp);
2311 }
2312 \f
2313 typedef c_pretty_print_fn pp_fun;
2314
2315 /* Initialization of a C++ pretty-printer object.  */
2316
2317 void
2318 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
2319 {
2320   pp_c_pretty_printer_init (pp_c_base (pp));
2321   pp_set_line_maximum_length (pp, 0);
2322
2323   pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
2324   pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
2325   pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
2326   pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2327   pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
2328   pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
2329   pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2330   pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
2331   pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
2332   pp->c_base.direct_abstract_declarator =
2333     (pp_fun) pp_cxx_direct_abstract_declarator;
2334   pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
2335
2336   /* pp->c_base.statement = (pp_fun) pp_cxx_statement;  */
2337
2338   pp->c_base.constant = (pp_fun) pp_cxx_constant;
2339   pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
2340   pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
2341   pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
2342   pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
2343   pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
2344   pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
2345   pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
2346   pp->c_base.expression = (pp_fun) pp_cxx_expression;
2347   pp->enclosing_scope = global_namespace;
2348 }