OSDN Git Service

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