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