OSDN Git Service

PR c++/25811
[pf3gnuchains/gcc-fork.git] / gcc / cp / cxx-pretty-print.c
1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2    Copyright (C) 2003, 2004, 2005, 2007, 2008,
3    2009 Free Software Foundation, Inc.
4    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "real.h"
27 #include "intl.h"
28 #include "cxx-pretty-print.h"
29 #include "cp-tree.h"
30 #include "toplev.h"
31
32 /* Translate if being used for diagnostics, but not for dump files or
33    __PRETTY_FUNCTION.  */
34 #define M_(msgid) (pp_translate_identifiers (pp) ? _(msgid) : (msgid))
35
36 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
37 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
38 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
39 static void pp_cxx_assignment_expression (cxx_pretty_printer *, tree);
40 static void pp_cxx_expression (cxx_pretty_printer *, tree);
41 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
42 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
43 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
44 static void pp_cxx_type_id (cxx_pretty_printer *, tree);
45 static void pp_cxx_direct_abstract_declarator (cxx_pretty_printer *, tree);
46 static void pp_cxx_declarator (cxx_pretty_printer *, tree);
47 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
48 static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
49 static void pp_cxx_statement (cxx_pretty_printer *, tree);
50 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
51 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
52 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
53 \f
54
55 static inline void
56 pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
57 {
58   const char *p = pp_last_position_in_text (pp);
59
60   if (p != NULL && *p == c)
61     pp_cxx_whitespace (pp);
62   pp_character (pp, c);
63   pp_base (pp)->padding = pp_none;
64 }
65
66 #define pp_cxx_storage_class_specifier(PP, T) \
67    pp_c_storage_class_specifier (pp_c_base (PP), T)
68 #define pp_cxx_expression_list(PP, T)    \
69    pp_c_expression_list (pp_c_base (PP), T)
70 #define pp_cxx_space_for_pointer_operator(PP, T)  \
71    pp_c_space_for_pointer_operator (pp_c_base (PP), T)
72 #define pp_cxx_init_declarator(PP, T)    \
73    pp_c_init_declarator (pp_c_base (PP), T)
74 #define pp_cxx_call_argument_list(PP, T) \
75    pp_c_call_argument_list (pp_c_base (PP), T)
76
77 void
78 pp_cxx_colon_colon (cxx_pretty_printer *pp)
79 {
80   pp_colon_colon (pp);
81   pp_base (pp)->padding = pp_none;
82 }
83
84 void
85 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
86 {
87   pp_cxx_nonconsecutive_character (pp, '<');
88 }
89
90 void
91 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
92 {
93   pp_cxx_nonconsecutive_character (pp, '>');
94 }
95
96 void
97 pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
98 {
99   pp_separate_with (pp, c);
100   pp_base (pp)->padding = pp_none;
101 }
102
103 /* Expressions.  */
104
105 static inline bool
106 is_destructor_name (tree name)
107 {
108   return name == complete_dtor_identifier
109     || name == base_dtor_identifier
110     || name == deleting_dtor_identifier;
111 }
112
113 /* conversion-function-id:
114       operator conversion-type-id
115
116    conversion-type-id:
117       type-specifier-seq conversion-declarator(opt)
118
119    conversion-declarator:
120       ptr-operator conversion-declarator(opt)  */
121
122 static inline void
123 pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
124 {
125   pp_cxx_ws_string (pp, "operator");
126   pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
127 }
128
129 static inline void
130 pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
131 {
132   pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
133   pp_cxx_begin_template_argument_list (pp);
134   pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
135   pp_cxx_end_template_argument_list (pp);
136 }
137
138 /* Prints the unqualified part of the id-expression T.
139
140    unqualified-id:
141      identifier
142      operator-function-id
143      conversion-function-id
144      ~ class-name
145      template-id  */
146
147 static void
148 pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
149 {
150   enum tree_code code = TREE_CODE (t);
151   switch (code)
152     {
153     case RESULT_DECL:
154       pp_cxx_ws_string (pp, M_("<return-value>"));
155       break;
156
157     case OVERLOAD:
158       t = OVL_CURRENT (t);
159     case VAR_DECL:
160     case PARM_DECL:
161     case CONST_DECL:
162     case TYPE_DECL:
163     case FUNCTION_DECL:
164     case NAMESPACE_DECL:
165     case FIELD_DECL:
166     case LABEL_DECL:
167     case USING_DECL:
168     case TEMPLATE_DECL:
169       t = DECL_NAME (t);
170
171     case IDENTIFIER_NODE:
172       if (t == NULL)
173         pp_cxx_ws_string (pp, M_("<unnamed>"));
174       else if (IDENTIFIER_TYPENAME_P (t))
175         pp_cxx_conversion_function_id (pp, t);
176       else
177         {
178           if (is_destructor_name (t))
179             {
180               pp_complement (pp);
181               /* FIXME: Why is this necessary? */
182               if (TREE_TYPE (t))
183                 t = constructor_name (TREE_TYPE (t));
184             }
185           pp_cxx_tree_identifier (pp, t);
186         }
187       break;
188
189     case TEMPLATE_ID_EXPR:
190       pp_cxx_template_id (pp, t);
191       break;
192
193     case BASELINK:
194       pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
195       break;
196
197     case RECORD_TYPE:
198     case UNION_TYPE:
199     case ENUMERAL_TYPE:
200     case TYPENAME_TYPE:
201     case UNBOUND_CLASS_TEMPLATE:
202       pp_cxx_unqualified_id (pp, TYPE_NAME (t));
203       if (CLASS_TYPE_P (t) && CLASSTYPE_USE_TEMPLATE (t))
204         {
205           pp_cxx_begin_template_argument_list (pp);
206           pp_cxx_template_argument_list (pp, INNERMOST_TEMPLATE_ARGS
207                                                  (CLASSTYPE_TI_ARGS (t)));
208           pp_cxx_end_template_argument_list (pp);
209         }
210       break;
211
212     case BIT_NOT_EXPR:
213       pp_cxx_complement (pp);
214       pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
215       break;
216
217     case TEMPLATE_TYPE_PARM:
218     case TEMPLATE_TEMPLATE_PARM:
219       if (TYPE_IDENTIFIER (t))
220         pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
221       else
222         pp_cxx_canonical_template_parameter (pp, t);
223       break;
224
225     case TEMPLATE_PARM_INDEX:
226       pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
227       break;
228
229     case BOUND_TEMPLATE_TEMPLATE_PARM:
230       pp_cxx_cv_qualifier_seq (pp, t);
231       pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
232       pp_cxx_begin_template_argument_list (pp);
233       pp_cxx_template_argument_list (pp, TYPE_TI_ARGS (t));
234       pp_cxx_end_template_argument_list (pp);
235       break;
236
237     default:
238       pp_unsupported_tree (pp, t);
239       break;
240     }
241 }
242
243 /* Pretty-print out the token sequence ":: template" in template codes
244    where it is needed to "inline declare" the (following) member as
245    a template.  This situation arises when SCOPE of T is dependent
246    on template parameters.  */
247
248 static inline void
249 pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
250 {
251   if (TREE_CODE (t) == TEMPLATE_ID_EXPR
252       && TYPE_P (scope) && dependent_type_p (scope))
253     pp_cxx_ws_string (pp, "template");
254 }
255
256 /* nested-name-specifier:
257       class-or-namespace-name :: nested-name-specifier(opt)
258       class-or-namespace-name :: template nested-name-specifier   */
259
260 static void
261 pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
262 {
263   if (t != NULL && t != pp->enclosing_scope)
264     {
265       tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
266       pp_cxx_nested_name_specifier (pp, scope);
267       pp_cxx_template_keyword_if_needed (pp, scope, t);
268       pp_cxx_unqualified_id (pp, t);
269       pp_cxx_colon_colon (pp);
270     }
271 }
272
273 /* qualified-id:
274       nested-name-specifier template(opt) unqualified-id  */
275
276 static void
277 pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
278 {
279   switch (TREE_CODE (t))
280     {
281       /* A pointer-to-member is always qualified.  */
282     case PTRMEM_CST:
283       pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
284       pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
285       break;
286
287       /* In Standard C++, functions cannot possibly be used as
288          nested-name-specifiers.  However, there are situations where
289          is "makes sense" to output the surrounding function name for the
290          purpose of emphasizing on the scope kind.  Just printing the
291          function name might not be sufficient as it may be overloaded; so,
292          we decorate the function with its signature too.
293          FIXME:  This is probably the wrong pretty-printing for conversion
294          functions and some function templates.  */
295     case OVERLOAD:
296       t = OVL_CURRENT (t);
297     case FUNCTION_DECL:
298       if (DECL_FUNCTION_MEMBER_P (t))
299         pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
300       pp_cxx_unqualified_id
301         (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
302       pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
303       break;
304
305     case OFFSET_REF:
306     case SCOPE_REF:
307       pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
308       pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
309       break;
310
311     default:
312       {
313         tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
314         if (scope != pp->enclosing_scope)
315           {
316             pp_cxx_nested_name_specifier (pp, scope);
317             pp_cxx_template_keyword_if_needed (pp, scope, t);
318           }
319         pp_cxx_unqualified_id (pp, t);
320       }
321       break;
322     }
323 }
324
325
326 static void
327 pp_cxx_constant (cxx_pretty_printer *pp, tree t)
328 {
329   switch (TREE_CODE (t))
330     {
331     case STRING_CST:
332       {
333         const bool in_parens = PAREN_STRING_LITERAL_P (t);
334         if (in_parens)
335           pp_cxx_left_paren (pp);
336         pp_c_constant (pp_c_base (pp), t);
337         if (in_parens)
338           pp_cxx_right_paren (pp);
339       }
340       break;
341
342     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 (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1422     return;
1423   pp_cxx_ws_string (pp, "throw");
1424   pp_cxx_left_paren (pp);
1425   for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1426     {
1427       tree type = TREE_VALUE (ex_spec);
1428       tree argpack = NULL_TREE;
1429       int i, len = 1;
1430
1431       if (ARGUMENT_PACK_P (type))
1432         {
1433           argpack = ARGUMENT_PACK_ARGS (type);
1434           len = TREE_VEC_LENGTH (argpack);
1435         }
1436
1437       for (i = 0; i < len; ++i)
1438         {
1439           if (argpack)
1440             type = TREE_VEC_ELT (argpack, i);
1441
1442           if (need_comma)
1443             pp_cxx_separate_with (pp, ',');
1444           else
1445             need_comma = true;
1446
1447           pp_cxx_type_id (pp, type);
1448         }
1449     }
1450   pp_cxx_right_paren (pp);
1451 }
1452
1453 /* direct-declarator:
1454       declarator-id
1455       direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1456                                             exception-specification(opt)
1457       direct-declaration [ constant-expression(opt) ]
1458       ( declarator )  */
1459
1460 static void
1461 pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1462 {
1463   switch (TREE_CODE (t))
1464     {
1465     case VAR_DECL:
1466     case PARM_DECL:
1467     case CONST_DECL:
1468     case FIELD_DECL:
1469       if (DECL_NAME (t))
1470         {
1471           pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1472
1473           if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
1474               || template_parameter_pack_p (t))
1475             /* A function parameter pack or non-type template
1476                parameter pack.  */
1477             pp_cxx_ws_string (pp, "...");
1478                       
1479           pp_cxx_id_expression (pp, DECL_NAME (t));
1480         }
1481       pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1482       break;
1483
1484     case FUNCTION_DECL:
1485       pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1486       pp_cxx_id_expression (pp, t);
1487       pp_cxx_parameter_declaration_clause (pp, t);
1488
1489       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1490         {
1491           pp_base (pp)->padding = pp_before;
1492           pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1493         }
1494
1495       pp_cxx_exception_specification (pp, TREE_TYPE (t));
1496       break;
1497
1498     case TYPENAME_TYPE:
1499     case TEMPLATE_DECL:
1500     case TEMPLATE_TYPE_PARM:
1501     case TEMPLATE_PARM_INDEX:
1502     case TEMPLATE_TEMPLATE_PARM:
1503       break;
1504
1505     default:
1506       pp_c_direct_declarator (pp_c_base (pp), t);
1507       break;
1508     }
1509 }
1510
1511 /* declarator:
1512    direct-declarator
1513    ptr-operator declarator  */
1514
1515 static void
1516 pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1517 {
1518   pp_cxx_direct_declarator (pp, t);
1519 }
1520
1521 /* ctor-initializer:
1522       : mem-initializer-list
1523
1524    mem-initializer-list:
1525       mem-initializer
1526       mem-initializer , mem-initializer-list
1527
1528    mem-initializer:
1529       mem-initializer-id ( expression-list(opt) )
1530
1531    mem-initializer-id:
1532       ::(opt) nested-name-specifier(opt) class-name
1533       identifier   */
1534
1535 static void
1536 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1537 {
1538   t = TREE_OPERAND (t, 0);
1539   pp_cxx_whitespace (pp);
1540   pp_colon (pp);
1541   pp_cxx_whitespace (pp);
1542   for (; t; t = TREE_CHAIN (t))
1543     {
1544       tree purpose = TREE_PURPOSE (t);
1545       bool is_pack = PACK_EXPANSION_P (purpose);
1546
1547       if (is_pack)
1548         pp_cxx_primary_expression (pp, PACK_EXPANSION_PATTERN (purpose));
1549       else
1550         pp_cxx_primary_expression (pp, purpose);
1551       pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1552       if (is_pack)
1553         pp_cxx_ws_string (pp, "...");
1554       if (TREE_CHAIN (t))
1555         pp_cxx_separate_with (pp, ',');
1556     }
1557 }
1558
1559 /* function-definition:
1560       decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1561       decl-specifier-seq(opt) declarator function-try-block  */
1562
1563 static void
1564 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1565 {
1566   tree saved_scope = pp->enclosing_scope;
1567   pp_cxx_decl_specifier_seq (pp, t);
1568   pp_cxx_declarator (pp, t);
1569   pp_needs_newline (pp) = true;
1570   pp->enclosing_scope = DECL_CONTEXT (t);
1571   if (DECL_SAVED_TREE (t))
1572     pp_cxx_statement (pp, DECL_SAVED_TREE (t));
1573   else
1574     {
1575       pp_cxx_semicolon (pp);
1576       pp_needs_newline (pp) = true;
1577     }
1578   pp_flush (pp);
1579   pp->enclosing_scope = saved_scope;
1580 }
1581
1582 /* abstract-declarator:
1583       ptr-operator abstract-declarator(opt)
1584       direct-abstract-declarator  */
1585
1586 static void
1587 pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1588 {
1589   if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1590     pp_cxx_right_paren (pp);
1591   else if (POINTER_TYPE_P (t))
1592     {
1593       if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1594           || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1595         pp_cxx_right_paren (pp);
1596       t = TREE_TYPE (t);
1597     }
1598   pp_cxx_direct_abstract_declarator (pp, t);
1599 }
1600
1601 /* direct-abstract-declarator:
1602       direct-abstract-declarator(opt) ( parameter-declaration-clause )
1603                            cv-qualifier-seq(opt) exception-specification(opt)
1604       direct-abstract-declarator(opt) [ constant-expression(opt) ]
1605       ( abstract-declarator )  */
1606
1607 static void
1608 pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1609 {
1610   switch (TREE_CODE (t))
1611     {
1612     case REFERENCE_TYPE:
1613       pp_cxx_abstract_declarator (pp, t);
1614       break;
1615
1616     case RECORD_TYPE:
1617       if (TYPE_PTRMEMFUNC_P (t))
1618         pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1619       break;
1620
1621     case METHOD_TYPE:
1622     case FUNCTION_TYPE:
1623       pp_cxx_parameter_declaration_clause (pp, t);
1624       pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1625       if (TREE_CODE (t) == METHOD_TYPE)
1626         {
1627           pp_base (pp)->padding = pp_before;
1628           pp_cxx_cv_qualifier_seq
1629             (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1630         }
1631       pp_cxx_exception_specification (pp, t);
1632       break;
1633
1634     case TYPENAME_TYPE:
1635     case TEMPLATE_TYPE_PARM:
1636     case TEMPLATE_TEMPLATE_PARM:
1637     case BOUND_TEMPLATE_TEMPLATE_PARM:
1638     case UNBOUND_CLASS_TEMPLATE:
1639       break;
1640
1641     default:
1642       pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1643       break;
1644     }
1645 }
1646
1647 /* type-id:
1648      type-specifier-seq abstract-declarator(opt) */
1649
1650 static void
1651 pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1652 {
1653   pp_flags saved_flags = pp_c_base (pp)->flags;
1654   pp_c_base (pp)->flags |= pp_c_flag_abstract;
1655
1656   switch (TREE_CODE (t))
1657     {
1658     case TYPE_DECL:
1659     case UNION_TYPE:
1660     case RECORD_TYPE:
1661     case ENUMERAL_TYPE:
1662     case TYPENAME_TYPE:
1663     case BOUND_TEMPLATE_TEMPLATE_PARM:
1664     case UNBOUND_CLASS_TEMPLATE:
1665     case TEMPLATE_TEMPLATE_PARM:
1666     case TEMPLATE_TYPE_PARM:
1667     case TEMPLATE_PARM_INDEX:
1668     case TEMPLATE_DECL:
1669     case TYPEOF_TYPE:
1670     case DECLTYPE_TYPE:
1671     case TEMPLATE_ID_EXPR:
1672       pp_cxx_type_specifier_seq (pp, t);
1673       break;
1674
1675     case TYPE_PACK_EXPANSION:
1676       pp_cxx_type_id (pp, PACK_EXPANSION_PATTERN (t));
1677       pp_cxx_ws_string (pp, "...");
1678       break;
1679
1680     default:
1681       pp_c_type_id (pp_c_base (pp), t);
1682       break;
1683     }
1684
1685   pp_c_base (pp)->flags = saved_flags;
1686 }
1687
1688 /* template-argument-list:
1689       template-argument ...(opt)
1690       template-argument-list, template-argument ...(opt)
1691
1692    template-argument:
1693       assignment-expression
1694       type-id
1695       template-name  */
1696
1697 static void
1698 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1699 {
1700   int i;
1701   bool need_comma = false;
1702
1703   if (t == NULL)
1704     return;
1705   for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1706     {
1707       tree arg = TREE_VEC_ELT (t, i);
1708       tree argpack = NULL_TREE;
1709       int idx, len = 1;
1710
1711       if (ARGUMENT_PACK_P (arg))
1712         {
1713           argpack = ARGUMENT_PACK_ARGS (arg);
1714           len = TREE_VEC_LENGTH (argpack);
1715         }
1716
1717       for (idx = 0; idx < len; idx++)
1718         {
1719           if (argpack)
1720             arg = TREE_VEC_ELT (argpack, idx);
1721           
1722           if (need_comma)
1723             pp_cxx_separate_with (pp, ',');
1724           else
1725             need_comma = true;
1726
1727           if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1728                                && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1729             pp_cxx_type_id (pp, arg);
1730           else
1731             pp_cxx_expression (pp, arg);
1732         }
1733     }
1734 }
1735
1736
1737 static void
1738 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1739 {
1740   t = DECL_EXPR_DECL (t);
1741   pp_cxx_type_specifier_seq (pp, t);
1742   if (TYPE_P (t))
1743     pp_cxx_abstract_declarator (pp, t);
1744   else
1745     pp_cxx_declarator (pp, t);
1746 }
1747
1748 /* Statements.  */
1749
1750 static void
1751 pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1752 {
1753   switch (TREE_CODE (t))
1754     {
1755     case CTOR_INITIALIZER:
1756       pp_cxx_ctor_initializer (pp, t);
1757       break;
1758
1759     case USING_STMT:
1760       pp_cxx_ws_string (pp, "using");
1761       pp_cxx_ws_string (pp, "namespace");
1762       if (DECL_CONTEXT (t))
1763         pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1764       pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1765       break;
1766
1767     case USING_DECL:
1768       pp_cxx_ws_string (pp, "using");
1769       pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
1770       pp_cxx_unqualified_id (pp, DECL_NAME (t));
1771       break;
1772
1773     case EH_SPEC_BLOCK:
1774       break;
1775
1776       /* try-block:
1777             try compound-statement handler-seq  */
1778     case TRY_BLOCK:
1779       pp_maybe_newline_and_indent (pp, 0);
1780       pp_cxx_ws_string (pp, "try");
1781       pp_newline_and_indent (pp, 3);
1782       pp_cxx_statement (pp, TRY_STMTS (t));
1783       pp_newline_and_indent (pp, -3);
1784       if (CLEANUP_P (t))
1785         ;
1786       else
1787         pp_cxx_statement (pp, TRY_HANDLERS (t));
1788       break;
1789
1790       /*
1791          handler-seq:
1792             handler handler-seq(opt)
1793
1794          handler:
1795          catch ( exception-declaration ) compound-statement
1796
1797          exception-declaration:
1798             type-specifier-seq declarator
1799             type-specifier-seq abstract-declarator
1800             ...   */
1801     case HANDLER:
1802       pp_cxx_ws_string (pp, "catch");
1803       pp_cxx_left_paren (pp);
1804       pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1805       pp_cxx_right_paren (pp);
1806       pp_indentation (pp) += 3;
1807       pp_needs_newline (pp) = true;
1808       pp_cxx_statement (pp, HANDLER_BODY (t));
1809       pp_indentation (pp) -= 3;
1810       pp_needs_newline (pp) = true;
1811       break;
1812
1813       /* selection-statement:
1814             if ( expression ) statement
1815             if ( expression ) statement else statement  */
1816     case IF_STMT:
1817       pp_cxx_ws_string (pp, "if");
1818       pp_cxx_whitespace (pp);
1819       pp_cxx_left_paren (pp);
1820       pp_cxx_expression (pp, IF_COND (t));
1821       pp_cxx_right_paren (pp);
1822       pp_newline_and_indent (pp, 2);
1823       pp_cxx_statement (pp, THEN_CLAUSE (t));
1824       pp_newline_and_indent (pp, -2);
1825       if (ELSE_CLAUSE (t))
1826         {
1827           tree else_clause = ELSE_CLAUSE (t);
1828           pp_cxx_ws_string (pp, "else");
1829           if (TREE_CODE (else_clause) == IF_STMT)
1830             pp_cxx_whitespace (pp);
1831           else
1832             pp_newline_and_indent (pp, 2);
1833           pp_cxx_statement (pp, else_clause);
1834           if (TREE_CODE (else_clause) != IF_STMT)
1835             pp_newline_and_indent (pp, -2);
1836         }
1837       break;
1838
1839     case SWITCH_STMT:
1840       pp_cxx_ws_string (pp, "switch");
1841       pp_space (pp);
1842       pp_cxx_left_paren (pp);
1843       pp_cxx_expression (pp, SWITCH_STMT_COND (t));
1844       pp_cxx_right_paren (pp);
1845       pp_indentation (pp) += 3;
1846       pp_needs_newline (pp) = true;
1847       pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
1848       pp_newline_and_indent (pp, -3);
1849       break;
1850
1851       /* iteration-statement:
1852             while ( expression ) statement
1853             do statement while ( expression ) ;
1854             for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1855             for ( declaration expression(opt) ; expression(opt) ) statement  */
1856     case WHILE_STMT:
1857       pp_cxx_ws_string (pp, "while");
1858       pp_space (pp);
1859       pp_cxx_left_paren (pp);
1860       pp_cxx_expression (pp, WHILE_COND (t));
1861       pp_cxx_right_paren (pp);
1862       pp_newline_and_indent (pp, 3);
1863       pp_cxx_statement (pp, WHILE_BODY (t));
1864       pp_indentation (pp) -= 3;
1865       pp_needs_newline (pp) = true;
1866       break;
1867
1868     case DO_STMT:
1869       pp_cxx_ws_string (pp, "do");
1870       pp_newline_and_indent (pp, 3);
1871       pp_cxx_statement (pp, DO_BODY (t));
1872       pp_newline_and_indent (pp, -3);
1873       pp_cxx_ws_string (pp, "while");
1874       pp_space (pp);
1875       pp_cxx_left_paren (pp);
1876       pp_cxx_expression (pp, DO_COND (t));
1877       pp_cxx_right_paren (pp);
1878       pp_cxx_semicolon (pp);
1879       pp_needs_newline (pp) = true;
1880       break;
1881
1882     case FOR_STMT:
1883       pp_cxx_ws_string (pp, "for");
1884       pp_space (pp);
1885       pp_cxx_left_paren (pp);
1886       if (FOR_INIT_STMT (t))
1887         pp_cxx_statement (pp, FOR_INIT_STMT (t));
1888       else
1889         pp_cxx_semicolon (pp);
1890       pp_needs_newline (pp) = false;
1891       pp_cxx_whitespace (pp);
1892       if (FOR_COND (t))
1893         pp_cxx_expression (pp, FOR_COND (t));
1894       pp_cxx_semicolon (pp);
1895       pp_needs_newline (pp) = false;
1896       pp_cxx_whitespace (pp);
1897       if (FOR_EXPR (t))
1898         pp_cxx_expression (pp, FOR_EXPR (t));
1899       pp_cxx_right_paren (pp);
1900       pp_newline_and_indent (pp, 3);
1901       pp_cxx_statement (pp, FOR_BODY (t));
1902       pp_indentation (pp) -= 3;
1903       pp_needs_newline (pp) = true;
1904       break;
1905
1906       /* jump-statement:
1907             goto identifier;
1908             continue ;
1909             return expression(opt) ;  */
1910     case BREAK_STMT:
1911     case CONTINUE_STMT:
1912       pp_string (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1913       pp_cxx_semicolon (pp);
1914       pp_needs_newline (pp) = true;
1915       break;
1916
1917       /* expression-statement:
1918             expression(opt) ;  */
1919     case EXPR_STMT:
1920       pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
1921       pp_cxx_semicolon (pp);
1922       pp_needs_newline (pp) = true;
1923       break;
1924
1925     case CLEANUP_STMT:
1926       pp_cxx_ws_string (pp, "try");
1927       pp_newline_and_indent (pp, 2);
1928       pp_cxx_statement (pp, CLEANUP_BODY (t));
1929       pp_newline_and_indent (pp, -2);
1930       pp_cxx_ws_string (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1931       pp_newline_and_indent (pp, 2);
1932       pp_cxx_statement (pp, CLEANUP_EXPR (t));
1933       pp_newline_and_indent (pp, -2);
1934       break;
1935
1936     case STATIC_ASSERT:
1937       pp_cxx_declaration (pp, t);
1938       break;
1939
1940     default:
1941       pp_c_statement (pp_c_base (pp), t);
1942       break;
1943     }
1944 }
1945
1946 /* original-namespace-definition:
1947       namespace identifier { namespace-body }
1948
1949   As an edge case, we also handle unnamed namespace definition here.  */
1950
1951 static void
1952 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1953 {
1954   pp_cxx_ws_string (pp, "namespace");
1955   if (DECL_CONTEXT (t))
1956     pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1957   if (DECL_NAME (t))
1958     pp_cxx_unqualified_id (pp, t);
1959   pp_cxx_whitespace (pp);
1960   pp_cxx_left_brace (pp);
1961   /* We do not print the namespace-body.  */
1962   pp_cxx_whitespace (pp);
1963   pp_cxx_right_brace (pp);
1964 }
1965
1966 /* namespace-alias:
1967       identifier
1968
1969    namespace-alias-definition:
1970       namespace identifier = qualified-namespace-specifier ;
1971
1972    qualified-namespace-specifier:
1973       ::(opt) nested-name-specifier(opt) namespace-name   */
1974
1975 static void
1976 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1977 {
1978   pp_cxx_ws_string (pp, "namespace");
1979   if (DECL_CONTEXT (t))
1980     pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1981   pp_cxx_unqualified_id (pp, t);
1982   pp_cxx_whitespace (pp);
1983   pp_equal (pp);
1984   pp_cxx_whitespace (pp);
1985   if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
1986     pp_cxx_nested_name_specifier (pp,
1987                                   DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
1988   pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1989   pp_cxx_semicolon (pp);
1990 }
1991
1992 /* simple-declaration:
1993       decl-specifier-seq(opt) init-declarator-list(opt)  */
1994
1995 static void
1996 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1997 {
1998   pp_cxx_decl_specifier_seq (pp, t);
1999   pp_cxx_init_declarator (pp, t);
2000   pp_cxx_semicolon (pp);
2001   pp_needs_newline (pp) = true;
2002 }
2003
2004 /*
2005   template-parameter-list:
2006      template-parameter
2007      template-parameter-list , template-parameter  */
2008
2009 static inline void
2010 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2011 {
2012   const int n = TREE_VEC_LENGTH (t);
2013   int i;
2014   for (i = 0; i < n; ++i)
2015     {
2016       if (i)
2017         pp_cxx_separate_with (pp, ',');
2018       pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2019     }
2020 }
2021
2022 /* template-parameter:
2023       type-parameter
2024       parameter-declaration
2025
2026    type-parameter:
2027      class ...(opt) identifier(opt)
2028      class identifier(opt) = type-id
2029      typename identifier(opt)
2030      typename ...(opt) identifier(opt) = type-id
2031      template < template-parameter-list > class ...(opt) identifier(opt)
2032      template < template-parameter-list > class identifier(opt) = template-name  */
2033
2034 static void
2035 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2036 {
2037   tree parameter =  TREE_VALUE (t);
2038   switch (TREE_CODE (parameter))
2039     {
2040     case TYPE_DECL:
2041       pp_cxx_ws_string (pp, "class");
2042       if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2043         pp_cxx_ws_string (pp, "...");
2044       if (DECL_NAME (parameter))
2045         pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2046       /* FIXME: Check if we should print also default argument.  */
2047       break;
2048
2049     case PARM_DECL:
2050       pp_cxx_parameter_declaration (pp, parameter);
2051       break;
2052
2053     case TEMPLATE_DECL:
2054       break;
2055
2056     default:
2057       pp_unsupported_tree (pp, t);
2058       break;
2059     }
2060 }
2061
2062 /* Pretty-print a template parameter in the canonical form
2063    "template-parameter-<level>-<position in parameter list>".  */
2064
2065 void
2066 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2067 {
2068   const enum tree_code code = TREE_CODE (parm);
2069
2070   /* Brings type template parameters to the canonical forms.  */
2071   if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2072       || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2073     parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2074
2075   pp_cxx_begin_template_argument_list (pp);
2076   pp_cxx_ws_string (pp, M_("template-parameter-"));
2077   pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2078   pp_minus (pp);
2079   pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2080   pp_cxx_end_template_argument_list (pp);
2081 }
2082
2083 /*
2084   template-declaration:
2085      export(opt) template < template-parameter-list > declaration   */
2086
2087 static void
2088 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2089 {
2090   tree tmpl = most_general_template (t);
2091   tree level;
2092   int i = 0;
2093
2094   pp_maybe_newline_and_indent (pp, 0);
2095   for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2096     {
2097       pp_cxx_ws_string (pp, "template");
2098       pp_cxx_begin_template_argument_list (pp);
2099       pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2100       pp_cxx_end_template_argument_list (pp);
2101       pp_newline_and_indent (pp, 3);
2102       i += 3;
2103     }
2104   if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2105     pp_cxx_function_definition (pp, t);
2106   else
2107     pp_cxx_simple_declaration (pp, t);
2108 }
2109
2110 static void
2111 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2112 {
2113   pp_unsupported_tree (pp, t);
2114 }
2115
2116 static void
2117 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2118 {
2119   pp_unsupported_tree (pp, t);
2120 }
2121
2122 /*
2123     declaration:
2124        block-declaration
2125        function-definition
2126        template-declaration
2127        explicit-instantiation
2128        explicit-specialization
2129        linkage-specification
2130        namespace-definition
2131
2132     block-declaration:
2133        simple-declaration
2134        asm-definition
2135        namespace-alias-definition
2136        using-declaration
2137        using-directive
2138        static_assert-declaration */
2139 void
2140 pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
2141 {
2142   if (TREE_CODE (t) == STATIC_ASSERT)
2143     {
2144       pp_cxx_ws_string (pp, "static_assert");
2145       pp_cxx_left_paren (pp);
2146       pp_cxx_expression (pp, STATIC_ASSERT_CONDITION (t));
2147       pp_cxx_separate_with (pp, ',');
2148       pp_cxx_expression (pp, STATIC_ASSERT_MESSAGE (t));
2149       pp_cxx_right_paren (pp);
2150     }
2151   else if (!DECL_LANG_SPECIFIC (t))
2152     pp_cxx_simple_declaration (pp, t);
2153   else if (DECL_USE_TEMPLATE (t))
2154     switch (DECL_USE_TEMPLATE (t))
2155       {
2156       case 1:
2157         pp_cxx_template_declaration (pp, t);
2158         break;
2159
2160       case 2:
2161         pp_cxx_explicit_specialization (pp, t);
2162         break;
2163
2164       case 3:
2165         pp_cxx_explicit_instantiation (pp, t);
2166         break;
2167
2168       default:
2169         break;
2170       }
2171   else switch (TREE_CODE (t))
2172     {
2173     case VAR_DECL:
2174     case TYPE_DECL:
2175       pp_cxx_simple_declaration (pp, t);
2176       break;
2177
2178     case FUNCTION_DECL:
2179       if (DECL_SAVED_TREE (t))
2180         pp_cxx_function_definition (pp, t);
2181       else
2182         pp_cxx_simple_declaration (pp, t);
2183       break;
2184
2185     case NAMESPACE_DECL:
2186       if (DECL_NAMESPACE_ALIAS (t))
2187         pp_cxx_namespace_alias_definition (pp, t);
2188       else
2189         pp_cxx_original_namespace_definition (pp, t);
2190       break;
2191
2192     default:
2193       pp_unsupported_tree (pp, t);
2194       break;
2195     }
2196 }
2197
2198 static void
2199 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2200 {
2201   t = TREE_OPERAND (t, 0);
2202   pp_cxx_ws_string (pp, "typeid");
2203   pp_cxx_left_paren (pp);
2204   if (TYPE_P (t))
2205     pp_cxx_type_id (pp, t);
2206   else
2207     pp_cxx_expression (pp, t);
2208   pp_cxx_right_paren (pp);
2209 }
2210
2211 void
2212 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2213 {
2214   pp_cxx_ws_string (pp, "va_arg");
2215   pp_cxx_left_paren (pp);
2216   pp_cxx_assignment_expression (pp, TREE_OPERAND (t, 0));
2217   pp_cxx_separate_with (pp, ',');
2218   pp_cxx_type_id (pp, TREE_TYPE (t));
2219   pp_cxx_right_paren (pp);
2220 }
2221
2222 static bool
2223 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2224 {
2225   switch (TREE_CODE (t))
2226     {
2227     case ARROW_EXPR:
2228       if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2229           && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2230         {
2231           pp_cxx_type_id (pp, TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2232           pp_cxx_separate_with (pp, ',');
2233           return true;
2234         }
2235       return false;
2236     case COMPONENT_REF:
2237       if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2238         return false;
2239       if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2240         pp_cxx_dot (pp);
2241       pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2242       return true;
2243     case ARRAY_REF:
2244       if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2245         return false;
2246       pp_left_bracket (pp);
2247       pp_cxx_expression (pp, TREE_OPERAND (t, 1));
2248       pp_right_bracket (pp);
2249       return true;
2250     default:
2251       return false;
2252     }
2253 }
2254
2255 void
2256 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2257 {
2258   pp_cxx_ws_string (pp, "offsetof");
2259   pp_cxx_left_paren (pp);
2260   if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2261     pp_cxx_expression (pp, TREE_OPERAND (t, 0));
2262   pp_cxx_right_paren (pp);
2263 }
2264
2265 void
2266 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2267 {
2268   cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2269
2270   switch (kind)
2271     {
2272     case CPTK_HAS_NOTHROW_ASSIGN:
2273       pp_cxx_ws_string (pp, "__has_nothrow_assign");
2274       break;
2275     case CPTK_HAS_TRIVIAL_ASSIGN:
2276       pp_cxx_ws_string (pp, "__has_trivial_assign");
2277       break;
2278     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2279       pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2280       break;
2281     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2282       pp_cxx_ws_string (pp, "__has_trivial_constructor");
2283       break;
2284     case CPTK_HAS_NOTHROW_COPY:
2285       pp_cxx_ws_string (pp, "__has_nothrow_copy");
2286       break;
2287     case CPTK_HAS_TRIVIAL_COPY:
2288       pp_cxx_ws_string (pp, "__has_trivial_copy");
2289       break;
2290     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2291       pp_cxx_ws_string (pp, "__has_trivial_destructor");
2292       break;
2293     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2294       pp_cxx_ws_string (pp, "__has_virtual_destructor");
2295       break;
2296     case CPTK_IS_ABSTRACT:
2297       pp_cxx_ws_string (pp, "__is_abstract");
2298       break;
2299     case CPTK_IS_BASE_OF:
2300       pp_cxx_ws_string (pp, "__is_base_of");
2301       break;
2302     case CPTK_IS_CLASS:
2303       pp_cxx_ws_string (pp, "__is_class");
2304       break;
2305     case CPTK_IS_CONVERTIBLE_TO:
2306       pp_cxx_ws_string (pp, "__is_convertible_to");
2307       break;
2308     case CPTK_IS_EMPTY:
2309       pp_cxx_ws_string (pp, "__is_empty");
2310       break;
2311     case CPTK_IS_ENUM:
2312       pp_cxx_ws_string (pp, "__is_enum");
2313       break;
2314     case CPTK_IS_POD:
2315       pp_cxx_ws_string (pp, "__is_pod");
2316       break;
2317     case CPTK_IS_POLYMORPHIC:
2318       pp_cxx_ws_string (pp, "__is_polymorphic");
2319       break;
2320     case CPTK_IS_STD_LAYOUT:
2321       pp_cxx_ws_string (pp, "__is_std_layout");
2322       break;
2323     case CPTK_IS_TRIVIAL:
2324       pp_cxx_ws_string (pp, "__is_trivial");
2325       break;
2326     case CPTK_IS_UNION:
2327       pp_cxx_ws_string (pp, "__is_union");
2328       break;
2329
2330     default:
2331       gcc_unreachable ();
2332     }
2333
2334   pp_cxx_left_paren (pp);
2335   pp_cxx_type_id (pp, TRAIT_EXPR_TYPE1 (t));
2336
2337   if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
2338     {
2339       pp_cxx_separate_with (pp, ',');
2340       pp_cxx_type_id (pp, TRAIT_EXPR_TYPE2 (t));
2341     }
2342
2343   pp_cxx_right_paren (pp);
2344 }
2345 \f
2346 typedef c_pretty_print_fn pp_fun;
2347
2348 /* Initialization of a C++ pretty-printer object.  */
2349
2350 void
2351 pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
2352 {
2353   pp_c_pretty_printer_init (pp_c_base (pp));
2354   pp_set_line_maximum_length (pp, 0);
2355
2356   pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
2357   pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
2358   pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
2359   pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2360   pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
2361   pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
2362   pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2363   pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
2364   pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
2365   pp->c_base.direct_abstract_declarator =
2366     (pp_fun) pp_cxx_direct_abstract_declarator;
2367   pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
2368
2369   /* pp->c_base.statement = (pp_fun) pp_cxx_statement;  */
2370
2371   pp->c_base.constant = (pp_fun) pp_cxx_constant;
2372   pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
2373   pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
2374   pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
2375   pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
2376   pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
2377   pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
2378   pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
2379   pp->c_base.expression = (pp_fun) pp_cxx_expression;
2380   pp->enclosing_scope = global_namespace;
2381 }