OSDN Git Service

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