OSDN Git Service

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