OSDN Git Service

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