OSDN Git Service

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