1/* Implementation of subroutines for the GNU C++ pretty-printer.
2   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3   Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301, USA.  */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "real.h"
27#include "cxx-pretty-print.h"
28#include "cp-tree.h"
29#include "toplev.h"
30
31static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
32static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
33static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
34static void pp_cxx_assignment_expression (cxx_pretty_printer *, tree);
35static void pp_cxx_expression (cxx_pretty_printer *, tree);
36static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
37static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
38static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
39static void pp_cxx_type_id (cxx_pretty_printer *, tree);
40static void pp_cxx_direct_abstract_declarator (cxx_pretty_printer *, tree);
41static void pp_cxx_declarator (cxx_pretty_printer *, tree);
42static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
43static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
44static void pp_cxx_statement (cxx_pretty_printer *, tree);
45static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
46static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
47
48
49static inline void
50pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
51{
52  const char *p = pp_last_position_in_text (pp);
53
54  if (p != NULL && *p == c)
55    pp_cxx_whitespace (pp);
56  pp_character (pp, c);
57  pp_base (pp)->padding = pp_none;
58}
59
60#define pp_cxx_storage_class_specifier(PP, T) \
61   pp_c_storage_class_specifier (pp_c_base (PP), T)
62#define pp_cxx_expression_list(PP, T)    \
63   pp_c_expression_list (pp_c_base (PP), T)
64#define pp_cxx_space_for_pointer_operator(PP, T)  \
65   pp_c_space_for_pointer_operator (pp_c_base (PP), T)
66#define pp_cxx_init_declarator(PP, T)    \
67   pp_c_init_declarator (pp_c_base (PP), T)
68#define pp_cxx_call_argument_list(PP, T) \
69   pp_c_call_argument_list (pp_c_base (PP), T)
70
71void
72pp_cxx_colon_colon (cxx_pretty_printer *pp)
73{
74  pp_colon_colon (pp);
75  pp_base (pp)->padding = pp_none;
76}
77
78void
79pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
80{
81  pp_cxx_nonconsecutive_character (pp, '<');
82}
83
84void
85pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
86{
87  pp_cxx_nonconsecutive_character (pp, '>');
88}
89
90void
91pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
92{
93  pp_separate_with (pp, c);
94  pp_base (pp)->padding = pp_none;
95}
96
97/* Expressions.  */
98
99static inline bool
100is_destructor_name (tree name)
101{
102  return name == complete_dtor_identifier
103    || name == base_dtor_identifier
104    || name == deleting_dtor_identifier;
105}
106
107/* conversion-function-id:
108      operator conversion-type-id
109
110   conversion-type-id:
111      type-specifier-seq conversion-declarator(opt)
112
113   conversion-declarator:
114      ptr-operator conversion-declarator(opt)  */
115
116static inline void
117pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
118{
119  pp_cxx_identifier (pp, "operator");
120  pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
121}
122
123static inline void
124pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
125{
126  pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
127  pp_cxx_begin_template_argument_list (pp);
128  pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
129  pp_cxx_end_template_argument_list (pp);
130}
131
132/* unqualified-id:
133     identifier
134     operator-function-id
135     conversion-function-id
136     ~ class-name
137     template-id  */
138
139static void
140pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
141{
142  enum tree_code code = TREE_CODE (t);
143  switch (code)
144    {
145    case RESULT_DECL:
146      pp_cxx_identifier (pp, "<return-value>");
147      break;
148
149    case OVERLOAD:
150      t = OVL_CURRENT (t);
151    case VAR_DECL:
152    case PARM_DECL:
153    case CONST_DECL:
154    case TYPE_DECL:
155    case FUNCTION_DECL:
156    case NAMESPACE_DECL:
157    case FIELD_DECL:
158    case LABEL_DECL:
159    case USING_DECL:
160    case TEMPLATE_DECL:
161      t = DECL_NAME (t);
162
163    case IDENTIFIER_NODE:
164      if (t == NULL)
165	pp_cxx_identifier (pp, "<unnamed>");
166      else if (IDENTIFIER_TYPENAME_P (t))
167	pp_cxx_conversion_function_id (pp, t);
168      else
169	{
170	  if (is_destructor_name (t))
171	    {
172	      pp_complement (pp);
173	      /* FIXME: Why is this necessary? */
174	      if (TREE_TYPE (t))
175		t = constructor_name (TREE_TYPE (t));
176	    }
177	  pp_cxx_tree_identifier (pp, t);
178	}
179      break;
180
181    case TEMPLATE_ID_EXPR:
182      pp_cxx_template_id (pp, t);
183      break;
184
185    case BASELINK:
186      pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
187      break;
188
189    case RECORD_TYPE:
190    case UNION_TYPE:
191    case ENUMERAL_TYPE:
192      pp_cxx_unqualified_id (pp, TYPE_NAME (t));
193      break;
194
195    case TEMPLATE_TYPE_PARM:
196    case TEMPLATE_TEMPLATE_PARM:
197      if (TYPE_IDENTIFIER (t))
198	pp_cxx_unqualified_id (pp, TYPE_IDENTIFIER (t));
199      else
200	pp_cxx_canonical_template_parameter (pp, t);
201      break;
202
203    case TEMPLATE_PARM_INDEX:
204      pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
205      break;
206
207    case UNBOUND_CLASS_TEMPLATE:
208      pp_cxx_unqualified_id (pp, TYPE_NAME (t));
209      break;
210
211    default:
212      pp_unsupported_tree (pp, t);
213      break;
214    }
215}
216
217/* Pretty-print out the token sequence ":: template" in template codes
218   where it is needed to "inline declare" the (following) member as
219   a template.  This situation arises when SCOPE of T is dependent
220   on template parameters.  */
221
222static inline void
223pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
224{
225  if (TREE_CODE (t) == TEMPLATE_ID_EXPR
226      && TYPE_P (scope) && dependent_type_p (scope))
227    pp_cxx_identifier (pp, "template");
228}
229
230/* nested-name-specifier:
231      class-or-namespace-name :: nested-name-specifier(opt)
232      class-or-namespace-name :: template nested-name-specifier   */
233
234static void
235pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
236{
237  if (t != NULL && t != pp->enclosing_scope)
238    {
239      tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
240      pp_cxx_nested_name_specifier (pp, scope);
241      pp_cxx_template_keyword_if_needed (pp, scope, t);
242      pp_cxx_unqualified_id (pp, t);
243      pp_cxx_colon_colon (pp);
244    }
245}
246
247/* qualified-id:
248      nested-name-specifier template(opt) unqualified-id  */
249
250static void
251pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
252{
253  switch (TREE_CODE (t))
254    {
255      /* A pointer-to-member is always qualified.  */
256    case PTRMEM_CST:
257      pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
258      pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
259      break;
260
261      /* In Standard C++, functions cannot possibly be used as
262	 nested-name-specifiers.  However, there are situations where
263	 is "makes sense" to output the surrounding function name for the
264	 purpose of emphasizing on the scope kind.  Just printing the
265	 function name might not be sufficient as it may be overloaded; so,
266	 we decorate the function with its signature too.
267	 FIXME:  This is probably the wrong pretty-printing for conversion
268	 functions and some function templates.  */
269    case OVERLOAD:
270      t = OVL_CURRENT (t);
271    case FUNCTION_DECL:
272      if (DECL_FUNCTION_MEMBER_P (t))
273	pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
274      pp_cxx_unqualified_id
275	(pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
276      pp_cxx_parameter_declaration_clause (pp, TREE_TYPE (t));
277      break;
278
279    case OFFSET_REF:
280    case SCOPE_REF:
281      pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
282      pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
283      break;
284
285    default:
286      {
287	tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
288	if (scope != pp->enclosing_scope)
289	  {
290	    pp_cxx_nested_name_specifier (pp, scope);
291	    pp_cxx_template_keyword_if_needed (pp, scope, t);
292	  }
293	pp_cxx_unqualified_id (pp, t);
294      }
295      break;
296    }
297}
298
299
300static void
301pp_cxx_constant (cxx_pretty_printer *pp, tree t)
302{
303  switch (TREE_CODE (t))
304    {
305    case STRING_CST:
306      {
307	const bool in_parens = PAREN_STRING_LITERAL_P (t);
308	if (in_parens)
309	  pp_cxx_left_paren (pp);
310	pp_c_constant (pp_c_base (pp), t);
311	if (in_parens)
312	  pp_cxx_right_paren (pp);
313      }
314      break;
315
316    default:
317      pp_c_constant (pp_c_base (pp), t);
318      break;
319    }
320}
321
322/* id-expression:
323      unqualified-id
324      qualified-id   */
325
326static inline void
327pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
328{
329  if (TREE_CODE (t) == OVERLOAD)
330    t = OVL_CURRENT (t);
331  if (DECL_P (t) && DECL_CONTEXT (t))
332    pp_cxx_qualified_id (pp, t);
333  else
334    pp_cxx_unqualified_id (pp, t);
335}
336
337/* primary-expression:
338     literal
339     this
340     :: identifier
341     :: operator-function-id
342     :: qualifier-id
343     ( expression )
344     id-expression   */
345
346static void
347pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
348{
349  switch (TREE_CODE (t))
350    {
351    case INTEGER_CST:
352    case REAL_CST:
353    case STRING_CST:
354      pp_cxx_constant (pp, t);
355      break;
356
357    case BASELINK:
358      t = BASELINK_FUNCTIONS (t);
359    case VAR_DECL:
360    case PARM_DECL:
361    case FIELD_DECL:
362    case FUNCTION_DECL:
363    case OVERLOAD:
364    case CONST_DECL:
365    case TEMPLATE_DECL:
366      pp_cxx_id_expression (pp, t);
367      break;
368
369    case RESULT_DECL:
370    case TEMPLATE_TYPE_PARM:
371    case TEMPLATE_TEMPLATE_PARM:
372    case TEMPLATE_PARM_INDEX:
373      pp_cxx_unqualified_id (pp, t);
374      break;
375
376    case STMT_EXPR:
377      pp_cxx_left_paren (pp);
378      pp_cxx_statement (pp, STMT_EXPR_STMT (t));
379      pp_cxx_right_paren (pp);
380      break;
381
382    default:
383      pp_c_primary_expression (pp_c_base (pp), t);
384      break;
385    }
386}
387
388/* postfix-expression:
389     primary-expression
390     postfix-expression [ expression ]
391     postfix-expression ( expression-list(opt) )
392     simple-type-specifier ( expression-list(opt) )
393     typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
394     typename ::(opt) nested-name-specifier template(opt)
395				       template-id ( expression-list(opt) )
396     postfix-expression . template(opt) ::(opt) id-expression
397     postfix-expression -> template(opt) ::(opt) id-expression
398     postfix-expression . pseudo-destructor-name
399     postfix-expression -> pseudo-destructor-name
400     postfix-expression ++
401     postfix-expression --
402     dynamic_cast < type-id > ( expression )
403     static_cast < type-id > ( expression )
404     reinterpret_cast < type-id > ( expression )
405     const_cast < type-id > ( expression )
406     typeid ( expression )
407     typeif ( type-id )  */
408
409static void
410pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
411{
412  enum tree_code code = TREE_CODE (t);
413
414  switch (code)
415    {
416    case AGGR_INIT_EXPR:
417    case CALL_EXPR:
418      {
419	tree fun = TREE_OPERAND (t, 0);
420	tree args = TREE_OPERAND (t, 1);
421	tree saved_scope = pp->enclosing_scope;
422
423	if (TREE_CODE (fun) == ADDR_EXPR)
424	  fun = TREE_OPERAND (fun, 0);
425
426	/* In templates, where there is no way to tell whether a given
427	   call uses an actual member function.  So the parser builds
428	   FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
429	   instantiation time.  */
430	if (TREE_CODE (fun) != FUNCTION_DECL)
431	  ;
432	else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
433	  {
434	    tree object = code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
435	      ? TREE_OPERAND (t, 2)
436	      : TREE_VALUE (args);
437
438	    while (TREE_CODE (object) == NOP_EXPR)
439	      object = TREE_OPERAND (object, 0);
440
441	    if (TREE_CODE (object) == ADDR_EXPR)
442	      object = TREE_OPERAND (object, 0);
443
444	    if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
445	      {
446		pp_cxx_postfix_expression (pp, object);
447		pp_cxx_dot (pp);
448	      }
449	    else
450	      {
451		pp_cxx_postfix_expression (pp, object);
452		pp_cxx_arrow (pp);
453	      }
454	    args = TREE_CHAIN (args);
455	    pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
456	  }
457
458	pp_cxx_postfix_expression (pp, fun);
459	pp->enclosing_scope = saved_scope;
460	pp_cxx_call_argument_list (pp, args);
461      }
462      if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
463	{
464	  pp_cxx_separate_with (pp, ',');
465	  pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 2));
466	}
467      break;
468
469    case BASELINK:
470    case VAR_DECL:
471    case PARM_DECL:
472    case FIELD_DECL:
473    case FUNCTION_DECL:
474    case OVERLOAD:
475    case CONST_DECL:
476    case TEMPLATE_DECL:
477    case RESULT_DECL:
478      pp_cxx_primary_expression (pp, t);
479      break;
480
481    case DYNAMIC_CAST_EXPR:
482    case STATIC_CAST_EXPR:
483    case REINTERPRET_CAST_EXPR:
484    case CONST_CAST_EXPR:
485      if (code == DYNAMIC_CAST_EXPR)
486	pp_cxx_identifier (pp, "dynamic_cast");
487      else if (code == STATIC_CAST_EXPR)
488	pp_cxx_identifier (pp, "static_cast");
489      else if (code == REINTERPRET_CAST_EXPR)
490	pp_cxx_identifier (pp, "reinterpret_cast");
491      else
492	pp_cxx_identifier (pp, "const_cast");
493      pp_cxx_begin_template_argument_list (pp);
494      pp_cxx_type_id (pp, TREE_TYPE (t));
495      pp_cxx_end_template_argument_list (pp);
496      pp_left_paren (pp);
497      pp_cxx_expression (pp, TREE_OPERAND (t, 0));
498      pp_right_paren (pp);
499      break;
500
501    case EMPTY_CLASS_EXPR:
502      pp_cxx_type_id (pp, TREE_TYPE (t));
503      pp_left_paren (pp);
504      pp_right_paren (pp);
505      break;
506
507    case TYPEID_EXPR:
508      t = TREE_OPERAND (t, 0);
509      pp_cxx_identifier (pp, "typeid");
510      pp_left_paren (pp);
511      if (TYPE_P (t))
512	pp_cxx_type_id (pp, t);
513      else
514	pp_cxx_expression (pp, t);
515      pp_right_paren (pp);
516      break;
517
518    case PSEUDO_DTOR_EXPR:
519      pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
520      pp_cxx_dot (pp);
521      pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
522      pp_cxx_colon_colon (pp);
523      pp_complement (pp);
524      pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
525      break;
526
527    case ARROW_EXPR:
528      pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
529      pp_cxx_arrow (pp);
530      break;
531
532    default:
533      pp_c_postfix_expression (pp_c_base (pp), t);
534      break;
535    }
536}
537
538/* new-expression:
539      ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
540      ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
541
542   new-placement:
543      ( expression-list )
544
545   new-type-id:
546      type-specifier-seq new-declarator(opt)
547
548   new-declarator:
549      ptr-operator new-declarator(opt)
550      direct-new-declarator
551
552   direct-new-declarator
553      [ expression ]
554      direct-new-declarator [ constant-expression ]
555
556   new-initializer:
557      ( expression-list(opt) )  */
558
559static void
560pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
561{
562  enum tree_code code = TREE_CODE (t);
563  switch (code)
564    {
565    case NEW_EXPR:
566    case VEC_NEW_EXPR:
567      if (NEW_EXPR_USE_GLOBAL (t))
568	pp_cxx_colon_colon (pp);
569      pp_cxx_identifier (pp, "new");
570      if (TREE_OPERAND (t, 0))
571	{
572	  pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
573	  pp_space (pp);
574	}
575      /* FIXME: array-types are built with one more element.  */
576      pp_cxx_type_id (pp, TREE_OPERAND (t, 1));
577      if (TREE_OPERAND (t, 2))
578	{
579	  pp_left_paren (pp);
580	  t = TREE_OPERAND (t, 2);
581	  if (TREE_CODE (t) == TREE_LIST)
582	    pp_c_expression_list (pp_c_base (pp), t);
583	  else if (t == void_zero_node)
584	    ;			/* OK, empty initializer list.  */
585	  else
586	    pp_cxx_expression (pp, t);
587	  pp_right_paren (pp);
588	}
589      break;
590
591    default:
592      pp_unsupported_tree (pp, t);
593    }
594}
595
596/* delete-expression:
597      ::(opt) delete cast-expression
598      ::(opt) delete [ ] cast-expression   */
599
600static void
601pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
602{
603  enum tree_code code = TREE_CODE (t);
604  switch (code)
605    {
606    case DELETE_EXPR:
607    case VEC_DELETE_EXPR:
608      if (DELETE_EXPR_USE_GLOBAL (t))
609	pp_cxx_colon_colon (pp);
610      pp_cxx_identifier (pp, "delete");
611      if (code == VEC_DELETE_EXPR)
612	{
613	  pp_left_bracket (pp);
614	  pp_right_bracket (pp);
615	}
616      pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
617      break;
618
619    default:
620      pp_unsupported_tree (pp, t);
621    }
622}
623
624/* unary-expression:
625      postfix-expression
626      ++ cast-expression
627      -- cast-expression
628      unary-operator cast-expression
629      sizeof unary-expression
630      sizeof ( type-id )
631      new-expression
632      delete-expression
633
634   unary-operator: one of
635      *   &   +   -  !
636
637   GNU extensions:
638      __alignof__ unary-expression
639      __alignof__ ( type-id )  */
640
641static void
642pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
643{
644  enum tree_code code = TREE_CODE (t);
645  switch (code)
646    {
647    case NEW_EXPR:
648    case VEC_NEW_EXPR:
649      pp_cxx_new_expression (pp, t);
650      break;
651
652    case DELETE_EXPR:
653    case VEC_DELETE_EXPR:
654      pp_cxx_delete_expression (pp, t);
655      break;
656
657    case SIZEOF_EXPR:
658    case ALIGNOF_EXPR:
659      pp_cxx_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
660      pp_cxx_whitespace (pp);
661      if (TYPE_P (TREE_OPERAND (t, 0)))
662	{
663	  pp_cxx_left_paren (pp);
664	  pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
665	  pp_cxx_right_paren (pp);
666	}
667      else
668	pp_unary_expression (pp, TREE_OPERAND (t, 0));
669      break;
670
671    case UNARY_PLUS_EXPR:
672      pp_plus (pp);
673      pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
674      break;
675
676    default:
677      pp_c_unary_expression (pp_c_base (pp), t);
678      break;
679    }
680}
681
682/* cast-expression:
683      unary-expression
684      ( type-id ) cast-expression  */
685
686static void
687pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
688{
689  switch (TREE_CODE (t))
690    {
691    case CAST_EXPR:
692      pp_cxx_type_id (pp, TREE_TYPE (t));
693      pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
694      break;
695
696    default:
697      pp_c_cast_expression (pp_c_base (pp), t);
698      break;
699    }
700}
701
702/* pm-expression:
703      cast-expression
704      pm-expression .* cast-expression
705      pm-expression ->* cast-expression  */
706
707static void
708pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
709{
710  switch (TREE_CODE (t))
711    {
712      /* Handle unfortunate OFFESET_REF overloading here.  */
713    case OFFSET_REF:
714      if (TYPE_P (TREE_OPERAND (t, 0)))
715	{
716	  pp_cxx_qualified_id (pp, t);
717	  break;
718	}
719      /* Else fall through.  */
720    case MEMBER_REF:
721    case DOTSTAR_EXPR:
722      pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
723      pp_cxx_dot (pp);
724      pp_star(pp);
725      pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
726      break;
727
728
729    default:
730      pp_cxx_cast_expression (pp, t);
731      break;
732    }
733}
734
735/* multiplicative-expression:
736      pm-expression
737      multiplicative-expression * pm-expression
738      multiplicative-expression / pm-expression
739      multiplicative-expression % pm-expression  */
740
741static void
742pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
743{
744  enum tree_code code = TREE_CODE (e);
745  switch (code)
746    {
747    case MULT_EXPR:
748    case TRUNC_DIV_EXPR:
749    case TRUNC_MOD_EXPR:
750      pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
751      pp_space (pp);
752      if (code == MULT_EXPR)
753	pp_star (pp);
754      else if (code == TRUNC_DIV_EXPR)
755	pp_slash (pp);
756      else
757	pp_modulo (pp);
758      pp_space (pp);
759      pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
760      break;
761
762    default:
763      pp_cxx_pm_expression (pp, e);
764      break;
765    }
766}
767
768/* conditional-expression:
769      logical-or-expression
770      logical-or-expression ?  expression  : assignment-expression  */
771
772static void
773pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
774{
775  if (TREE_CODE (e) == COND_EXPR)
776    {
777      pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
778      pp_space (pp);
779      pp_question (pp);
780      pp_space (pp);
781      pp_cxx_expression (pp, TREE_OPERAND (e, 1));
782      pp_space (pp);
783      pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
784    }
785  else
786    pp_c_logical_or_expression (pp_c_base (pp), e);
787}
788
789/* Pretty-print a compound assignment operator token as indicated by T.  */
790
791static void
792pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
793{
794  const char *op;
795
796  switch (TREE_CODE (t))
797    {
798    case NOP_EXPR:
799      op = "=";
800      break;
801
802    case PLUS_EXPR:
803      op = "+=";
804      break;
805
806    case MINUS_EXPR:
807      op = "-=";
808      break;
809
810    case TRUNC_DIV_EXPR:
811      op = "/=";
812      break;
813
814    case TRUNC_MOD_EXPR:
815      op = "%=";
816      break;
817
818    default:
819      op = tree_code_name[TREE_CODE (t)];
820      break;
821    }
822
823  pp_cxx_identifier (pp, op);
824}
825
826
827/* assignment-expression:
828      conditional-expression
829      logical-or-expression assignment-operator assignment-expression
830      throw-expression
831
832   throw-expression:
833       throw assignment-expression(opt)
834
835   assignment-operator: one of
836      =    *=    /=    %=    +=    -=    >>=    <<=    &=    ^=    |=  */
837
838static void
839pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
840{
841  switch (TREE_CODE (e))
842    {
843    case MODIFY_EXPR:
844    case INIT_EXPR:
845      pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
846      pp_space (pp);
847      pp_equal (pp);
848      pp_space (pp);
849      pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
850      break;
851
852    case THROW_EXPR:
853      pp_cxx_identifier (pp, "throw");
854      if (TREE_OPERAND (e, 0))
855	pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
856      break;
857
858    case MODOP_EXPR:
859      pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
860      pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
861      pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
862      break;
863
864    default:
865      pp_cxx_conditional_expression (pp, e);
866      break;
867    }
868}
869
870static void
871pp_cxx_expression (cxx_pretty_printer *pp, tree t)
872{
873  switch (TREE_CODE (t))
874    {
875    case STRING_CST:
876    case INTEGER_CST:
877    case REAL_CST:
878      pp_cxx_constant (pp, t);
879      break;
880
881    case RESULT_DECL:
882      pp_cxx_unqualified_id (pp, t);
883      break;
884
885#if 0
886    case OFFSET_REF:
887#endif
888    case SCOPE_REF:
889    case PTRMEM_CST:
890      pp_cxx_qualified_id (pp, t);
891      break;
892
893    case OVERLOAD:
894      t = OVL_CURRENT (t);
895    case VAR_DECL:
896    case PARM_DECL:
897    case FIELD_DECL:
898    case CONST_DECL:
899    case FUNCTION_DECL:
900    case BASELINK:
901    case TEMPLATE_DECL:
902    case TEMPLATE_TYPE_PARM:
903    case TEMPLATE_PARM_INDEX:
904    case TEMPLATE_TEMPLATE_PARM:
905    case STMT_EXPR:
906      pp_cxx_primary_expression (pp, t);
907      break;
908
909    case CALL_EXPR:
910    case DYNAMIC_CAST_EXPR:
911    case STATIC_CAST_EXPR:
912    case REINTERPRET_CAST_EXPR:
913    case CONST_CAST_EXPR:
914#if 0
915    case MEMBER_REF:
916#endif
917    case EMPTY_CLASS_EXPR:
918    case TYPEID_EXPR:
919    case PSEUDO_DTOR_EXPR:
920    case AGGR_INIT_EXPR:
921    case ARROW_EXPR:
922      pp_cxx_postfix_expression (pp, t);
923      break;
924
925    case NEW_EXPR:
926    case VEC_NEW_EXPR:
927      pp_cxx_new_expression (pp, t);
928      break;
929
930    case DELETE_EXPR:
931    case VEC_DELETE_EXPR:
932      pp_cxx_delete_expression (pp, t);
933      break;
934
935    case SIZEOF_EXPR:
936    case ALIGNOF_EXPR:
937      pp_cxx_unary_expression (pp, t);
938      break;
939
940    case CAST_EXPR:
941      pp_cxx_cast_expression (pp, t);
942      break;
943
944    case OFFSET_REF:
945    case MEMBER_REF:
946    case DOTSTAR_EXPR:
947      pp_cxx_pm_expression (pp, t);
948      break;
949
950    case MULT_EXPR:
951    case TRUNC_DIV_EXPR:
952    case TRUNC_MOD_EXPR:
953      pp_cxx_multiplicative_expression (pp, t);
954      break;
955
956    case COND_EXPR:
957      pp_cxx_conditional_expression (pp, t);
958      break;
959
960    case MODIFY_EXPR:
961    case INIT_EXPR:
962    case THROW_EXPR:
963    case MODOP_EXPR:
964      pp_cxx_assignment_expression (pp, t);
965      break;
966
967    case NON_DEPENDENT_EXPR:
968    case MUST_NOT_THROW_EXPR:
969      pp_cxx_expression (pp, t);
970      break;
971
972    default:
973      pp_c_expression (pp_c_base (pp), t);
974      break;
975    }
976}
977
978
979/* Declarations.  */
980
981/* function-specifier:
982      inline
983      virtual
984      explicit   */
985
986static void
987pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
988{
989  switch (TREE_CODE (t))
990    {
991    case FUNCTION_DECL:
992      if (DECL_VIRTUAL_P (t))
993	pp_cxx_identifier (pp, "virtual");
994      else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
995	pp_cxx_identifier (pp, "explicit");
996      else
997	pp_c_function_specifier (pp_c_base (pp), t);
998
999    default:
1000      break;
1001    }
1002}
1003
1004/* decl-specifier-seq:
1005      decl-specifier-seq(opt) decl-specifier
1006
1007   decl-specifier:
1008      storage-class-specifier
1009      type-specifier
1010      function-specifier
1011      friend
1012      typedef  */
1013
1014static void
1015pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
1016{
1017  switch (TREE_CODE (t))
1018    {
1019    case VAR_DECL:
1020    case PARM_DECL:
1021    case CONST_DECL:
1022    case FIELD_DECL:
1023      pp_cxx_storage_class_specifier (pp, t);
1024      pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1025      break;
1026
1027    case TYPE_DECL:
1028      pp_cxx_identifier (pp, "typedef");
1029      pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
1030      break;
1031
1032    case RECORD_TYPE:
1033      if (TYPE_PTRMEMFUNC_P (t))
1034	{
1035	  tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1036	  pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
1037	  pp_cxx_whitespace (pp);
1038	  pp_cxx_ptr_operator (pp, t);
1039	}
1040      break;
1041
1042    case FUNCTION_DECL:
1043      /* Constructors don't have return types.  And conversion functions
1044	 do not have a type-specifier in their return types.  */
1045      if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1046	pp_cxx_function_specifier (pp, t);
1047      else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1048	pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
1049      else
1050	default:
1051      pp_c_declaration_specifiers (pp_c_base (pp), t);
1052      break;
1053    }
1054}
1055
1056/* simple-type-specifier:
1057      ::(opt) nested-name-specifier(opt) type-name
1058      ::(opt) nested-name-specifier(opt) template(opt) template-id
1059      char
1060      wchar_t
1061      bool
1062      short
1063      int
1064      long
1065      signed
1066      unsigned
1067      float
1068      double
1069      void  */
1070
1071static void
1072pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
1073{
1074  switch (TREE_CODE (t))
1075    {
1076    case RECORD_TYPE:
1077    case UNION_TYPE:
1078    case ENUMERAL_TYPE:
1079      pp_cxx_qualified_id (pp, t);
1080      break;
1081
1082    case TEMPLATE_TYPE_PARM:
1083    case TEMPLATE_TEMPLATE_PARM:
1084    case TEMPLATE_PARM_INDEX:
1085      pp_cxx_unqualified_id (pp, t);
1086      break;
1087
1088    case TYPENAME_TYPE:
1089      pp_cxx_identifier (pp, "typename");
1090      pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
1091      pp_cxx_unqualified_id (pp, TYPE_NAME (t));
1092      break;
1093
1094    default:
1095      pp_c_type_specifier (pp_c_base (pp), t);
1096      break;
1097    }
1098}
1099
1100/* type-specifier-seq:
1101      type-specifier type-specifier-seq(opt)
1102
1103   type-specifier:
1104      simple-type-specifier
1105      class-specifier
1106      enum-specifier
1107      elaborated-type-specifier
1108      cv-qualifier   */
1109
1110static void
1111pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1112{
1113  switch (TREE_CODE (t))
1114    {
1115    case TEMPLATE_DECL:
1116    case TEMPLATE_TYPE_PARM:
1117    case TEMPLATE_TEMPLATE_PARM:
1118    case TYPE_DECL:
1119    case BOUND_TEMPLATE_TEMPLATE_PARM:
1120      pp_cxx_cv_qualifier_seq (pp, t);
1121      pp_cxx_simple_type_specifier (pp, t);
1122      break;
1123
1124    case METHOD_TYPE:
1125      pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1126      pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1127      pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1128      break;
1129
1130    default:
1131      if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1132	pp_c_specifier_qualifier_list (pp_c_base (pp), t);
1133    }
1134}
1135
1136/* ptr-operator:
1137      * cv-qualifier-seq(opt)
1138      &
1139      ::(opt) nested-name-specifier * cv-qualifier-seq(opt)  */
1140
1141static void
1142pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1143{
1144  if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1145    t = TREE_TYPE (t);
1146  switch (TREE_CODE (t))
1147    {
1148    case REFERENCE_TYPE:
1149    case POINTER_TYPE:
1150      if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
1151	  || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
1152	pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1153      if (TREE_CODE (t) == POINTER_TYPE)
1154	{
1155	  pp_star (pp);
1156	  pp_cxx_cv_qualifier_seq (pp, t);
1157	}
1158      else
1159	pp_ampersand (pp);
1160      break;
1161
1162    case RECORD_TYPE:
1163      if (TYPE_PTRMEMFUNC_P (t))
1164	{
1165	  pp_cxx_left_paren (pp);
1166	  pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1167	  pp_star (pp);
1168	  break;
1169	}
1170    case OFFSET_TYPE:
1171      if (TYPE_PTR_TO_MEMBER_P (t))
1172	{
1173	  if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1174	    pp_cxx_left_paren (pp);
1175	  pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1176	  pp_star (pp);
1177	  pp_cxx_cv_qualifier_seq (pp, t);
1178	  break;
1179	}
1180      /* else fall through.  */
1181
1182    default:
1183      pp_unsupported_tree (pp, t);
1184      break;
1185    }
1186}
1187
1188static inline tree
1189pp_cxx_implicit_parameter_type (tree mf)
1190{
1191  return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
1192}
1193
1194/*
1195   parameter-declaration:
1196      decl-specifier-seq declarator
1197      decl-specifier-seq declarator = assignment-expression
1198      decl-specifier-seq abstract-declarator(opt)
1199      decl-specifier-seq abstract-declarator(opt) assignment-expression  */
1200
1201static inline void
1202pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1203{
1204  pp_cxx_decl_specifier_seq (pp, t);
1205  if (TYPE_P (t))
1206    pp_cxx_abstract_declarator (pp, t);
1207  else
1208    pp_cxx_declarator (pp, t);
1209}
1210
1211/* parameter-declaration-clause:
1212      parameter-declaration-list(opt) ...(opt)
1213      parameter-declaration-list , ...
1214
1215   parameter-declaration-list:
1216      parameter-declaration
1217      parameter-declaration-list , parameter-declaration  */
1218
1219static void
1220pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1221{
1222  tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
1223  tree types =
1224    TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1225  const bool abstract = args == NULL
1226    || pp_c_base (pp)->flags & pp_c_flag_abstract;
1227  bool first = true;
1228
1229  /* Skip artificial parameter for nonstatic member functions.  */
1230  if (TREE_CODE (t) == METHOD_TYPE)
1231    types = TREE_CHAIN (types);
1232
1233  pp_cxx_left_paren (pp);
1234  for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1235    {
1236      if (!first)
1237	pp_cxx_separate_with (pp, ',');
1238      first = false;
1239      pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1240      if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
1241	{
1242	  pp_cxx_whitespace (pp);
1243	  pp_equal (pp);
1244	  pp_cxx_whitespace (pp);
1245	  pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
1246	}
1247    }
1248  pp_cxx_right_paren (pp);
1249}
1250
1251/* exception-specification:
1252      throw ( type-id-list(opt) )
1253
1254   type-id-list
1255      type-id
1256      type-id-list , type-id   */
1257
1258static void
1259pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1260{
1261  tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1262
1263  if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
1264    return;
1265  pp_cxx_identifier (pp, "throw");
1266  pp_cxx_left_paren (pp);
1267  for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1268    {
1269      pp_cxx_type_id (pp, TREE_VALUE (ex_spec));
1270      if (TREE_CHAIN (ex_spec))
1271	pp_cxx_separate_with (pp, ',');
1272    }
1273  pp_cxx_right_paren (pp);
1274}
1275
1276/* direct-declarator:
1277      declarator-id
1278      direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1279					    exception-specification(opt)
1280      direct-declaration [ constant-expression(opt) ]
1281      ( declarator )  */
1282
1283static void
1284pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
1285{
1286  switch (TREE_CODE (t))
1287    {
1288    case VAR_DECL:
1289    case PARM_DECL:
1290    case CONST_DECL:
1291    case FIELD_DECL:
1292      if (DECL_NAME (t))
1293	{
1294	  pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1295	  pp_cxx_id_expression (pp, DECL_NAME (t));
1296	}
1297      pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
1298      break;
1299
1300    case FUNCTION_DECL:
1301      pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
1302      pp_cxx_id_expression (pp, t);
1303      pp_cxx_parameter_declaration_clause (pp, t);
1304
1305      if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1306	{
1307	  pp_base (pp)->padding = pp_before;
1308	  pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
1309	}
1310
1311      pp_cxx_exception_specification (pp, TREE_TYPE (t));
1312      break;
1313
1314    case TYPENAME_TYPE:
1315    case TEMPLATE_DECL:
1316    case TEMPLATE_TYPE_PARM:
1317    case TEMPLATE_PARM_INDEX:
1318    case TEMPLATE_TEMPLATE_PARM:
1319      break;
1320
1321    default:
1322      pp_c_direct_declarator (pp_c_base (pp), t);
1323      break;
1324    }
1325}
1326
1327/* declarator:
1328   direct-declarator
1329   ptr-operator declarator  */
1330
1331static void
1332pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
1333{
1334  pp_cxx_direct_declarator (pp, t);
1335}
1336
1337/* ctor-initializer:
1338      : mem-initializer-list
1339
1340   mem-initializer-list:
1341      mem-initializer
1342      mem-initializer , mem-initializer-list
1343
1344   mem-initializer:
1345      mem-initializer-id ( expression-list(opt) )
1346
1347   mem-initializer-id:
1348      ::(opt) nested-name-specifier(opt) class-name
1349      identifier   */
1350
1351static void
1352pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1353{
1354  t = TREE_OPERAND (t, 0);
1355  pp_cxx_whitespace (pp);
1356  pp_colon (pp);
1357  pp_cxx_whitespace (pp);
1358  for (; t; t = TREE_CHAIN (t))
1359    {
1360      pp_cxx_primary_expression (pp, TREE_PURPOSE (t));
1361      pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1362      if (TREE_CHAIN (t))
1363	pp_cxx_separate_with (pp, ',');
1364    }
1365}
1366
1367/* function-definition:
1368      decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1369      decl-specifier-seq(opt) declarator function-try-block  */
1370
1371static void
1372pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1373{
1374  tree saved_scope = pp->enclosing_scope;
1375  pp_cxx_decl_specifier_seq (pp, t);
1376  pp_cxx_declarator (pp, t);
1377  pp_needs_newline (pp) = true;
1378  pp->enclosing_scope = DECL_CONTEXT (t);
1379  if (DECL_SAVED_TREE (t))
1380    pp_cxx_statement (pp, DECL_SAVED_TREE (t));
1381  else
1382    {
1383      pp_cxx_semicolon (pp);
1384      pp_needs_newline (pp) = true;
1385    }
1386  pp_flush (pp);
1387  pp->enclosing_scope = saved_scope;
1388}
1389
1390/* abstract-declarator:
1391      ptr-operator abstract-declarator(opt)
1392      direct-abstract-declarator  */
1393
1394static void
1395pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
1396{
1397  if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
1398    pp_cxx_right_paren (pp);
1399  else if (POINTER_TYPE_P (t))
1400    {
1401      if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1402	  || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1403	pp_cxx_right_paren (pp);
1404      t = TREE_TYPE (t);
1405    }
1406  pp_cxx_direct_abstract_declarator (pp, t);
1407}
1408
1409/* direct-abstract-declarator:
1410      direct-abstract-declarator(opt) ( parameter-declaration-clause )
1411			   cv-qualifier-seq(opt) exception-specification(opt)
1412      direct-abstract-declarator(opt) [ constant-expression(opt) ]
1413      ( abstract-declarator )  */
1414
1415static void
1416pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
1417{
1418  switch (TREE_CODE (t))
1419    {
1420    case REFERENCE_TYPE:
1421      pp_cxx_abstract_declarator (pp, t);
1422      break;
1423
1424    case RECORD_TYPE:
1425      if (TYPE_PTRMEMFUNC_P (t))
1426	pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
1427      break;
1428
1429    case METHOD_TYPE:
1430    case FUNCTION_TYPE:
1431      pp_cxx_parameter_declaration_clause (pp, t);
1432      pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
1433      if (TREE_CODE (t) == METHOD_TYPE)
1434	{
1435	  pp_base (pp)->padding = pp_before;
1436	  pp_cxx_cv_qualifier_seq
1437	    (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
1438	}
1439      pp_cxx_exception_specification (pp, t);
1440      break;
1441
1442    case TYPENAME_TYPE:
1443    case TEMPLATE_TYPE_PARM:
1444    case TEMPLATE_TEMPLATE_PARM:
1445    case BOUND_TEMPLATE_TEMPLATE_PARM:
1446    case UNBOUND_CLASS_TEMPLATE:
1447      break;
1448
1449    default:
1450      pp_c_direct_abstract_declarator (pp_c_base (pp), t);
1451      break;
1452    }
1453}
1454
1455/* type-id:
1456     type-specifier-seq abstract-declarator(opt) */
1457
1458static void
1459pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
1460{
1461  pp_flags saved_flags = pp_c_base (pp)->flags;
1462  pp_c_base (pp)->flags |= pp_c_flag_abstract;
1463
1464  switch (TREE_CODE (t))
1465    {
1466    case TYPE_DECL:
1467    case UNION_TYPE:
1468    case RECORD_TYPE:
1469    case ENUMERAL_TYPE:
1470    case TYPENAME_TYPE:
1471    case BOUND_TEMPLATE_TEMPLATE_PARM:
1472    case UNBOUND_CLASS_TEMPLATE:
1473    case TEMPLATE_TEMPLATE_PARM:
1474    case TEMPLATE_TYPE_PARM:
1475    case TEMPLATE_PARM_INDEX:
1476    case TEMPLATE_DECL:
1477    case TYPEOF_TYPE:
1478    case TEMPLATE_ID_EXPR:
1479      pp_cxx_type_specifier_seq (pp, t);
1480      break;
1481
1482    default:
1483      pp_c_type_id (pp_c_base (pp), t);
1484      break;
1485    }
1486
1487  pp_c_base (pp)->flags = saved_flags;
1488}
1489
1490/* template-argument-list:
1491      template-argument
1492      template-argument-list, template-argument
1493
1494   template-argument:
1495      assignment-expression
1496      type-id
1497      template-name   */
1498
1499static void
1500pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1501{
1502  int i;
1503  if (t == NULL)
1504    return;
1505  for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1506    {
1507      tree arg = TREE_VEC_ELT (t, i);
1508      if (i != 0)
1509	pp_cxx_separate_with (pp, ',');
1510      if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1511			   && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1512	pp_cxx_type_id (pp, arg);
1513      else
1514	pp_cxx_expression (pp, arg);
1515    }
1516}
1517
1518
1519static void
1520pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1521{
1522  t = DECL_EXPR_DECL (t);
1523  pp_cxx_type_specifier_seq (pp, t);
1524  if (TYPE_P (t))
1525    pp_cxx_abstract_declarator (pp, t);
1526  else
1527    pp_cxx_declarator (pp, t);
1528}
1529
1530/* Statements.  */
1531
1532static void
1533pp_cxx_statement (cxx_pretty_printer *pp, tree t)
1534{
1535  switch (TREE_CODE (t))
1536    {
1537    case CTOR_INITIALIZER:
1538      pp_cxx_ctor_initializer (pp, t);
1539      break;
1540
1541    case USING_STMT:
1542      pp_cxx_identifier (pp, "using");
1543      pp_cxx_identifier (pp, "namespace");
1544      if (DECL_CONTEXT (t))
1545	pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1546      pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
1547      break;
1548
1549    case USING_DECL:
1550      pp_cxx_identifier (pp, "using");
1551      pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
1552      pp_cxx_unqualified_id (pp, DECL_NAME (t));
1553      break;
1554
1555    case EH_SPEC_BLOCK:
1556      break;
1557
1558      /* try-block:
1559	    try compound-statement handler-seq  */
1560    case TRY_BLOCK:
1561      pp_maybe_newline_and_indent (pp, 0);
1562      pp_cxx_identifier (pp, "try");
1563      pp_newline_and_indent (pp, 3);
1564      pp_cxx_statement (pp, TRY_STMTS (t));
1565      pp_newline_and_indent (pp, -3);
1566      if (CLEANUP_P (t))
1567	;
1568      else
1569	pp_cxx_statement (pp, TRY_HANDLERS (t));
1570      break;
1571
1572      /*
1573	 handler-seq:
1574	    handler handler-seq(opt)
1575
1576	 handler:
1577	 catch ( exception-declaration ) compound-statement
1578
1579	 exception-declaration:
1580	    type-specifier-seq declarator
1581	    type-specifier-seq abstract-declarator
1582	    ...   */
1583    case HANDLER:
1584      pp_cxx_identifier (pp, "catch");
1585      pp_cxx_left_paren (pp);
1586      pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
1587      pp_cxx_right_paren (pp);
1588      pp_indentation (pp) += 3;
1589      pp_needs_newline (pp) = true;
1590      pp_cxx_statement (pp, HANDLER_BODY (t));
1591      pp_indentation (pp) -= 3;
1592      pp_needs_newline (pp) = true;
1593      break;
1594
1595      /* selection-statement:
1596	    if ( expression ) statement
1597	    if ( expression ) statement else statement  */
1598    case IF_STMT:
1599      pp_cxx_identifier (pp, "if");
1600      pp_cxx_whitespace (pp);
1601      pp_cxx_left_paren (pp);
1602      pp_cxx_expression (pp, IF_COND (t));
1603      pp_cxx_right_paren (pp);
1604      pp_newline_and_indent (pp, 2);
1605      pp_cxx_statement (pp, THEN_CLAUSE (t));
1606      pp_newline_and_indent (pp, -2);
1607      if (ELSE_CLAUSE (t))
1608	{
1609	  tree else_clause = ELSE_CLAUSE (t);
1610	  pp_cxx_identifier (pp, "else");
1611	  if (TREE_CODE (else_clause) == IF_STMT)
1612	    pp_cxx_whitespace (pp);
1613	  else
1614	    pp_newline_and_indent (pp, 2);
1615	  pp_cxx_statement (pp, else_clause);
1616	  if (TREE_CODE (else_clause) != IF_STMT)
1617	    pp_newline_and_indent (pp, -2);
1618	}
1619      break;
1620
1621    case SWITCH_STMT:
1622      pp_cxx_identifier (pp, "switch");
1623      pp_space (pp);
1624      pp_cxx_left_paren (pp);
1625      pp_cxx_expression (pp, SWITCH_STMT_COND (t));
1626      pp_cxx_right_paren (pp);
1627      pp_indentation (pp) += 3;
1628      pp_needs_newline (pp) = true;
1629      pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
1630      pp_newline_and_indent (pp, -3);
1631      break;
1632
1633      /* iteration-statement:
1634	    while ( expression ) statement
1635	    do statement while ( expression ) ;
1636	    for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
1637	    for ( declaration expression(opt) ; expression(opt) ) statement  */
1638    case WHILE_STMT:
1639      pp_cxx_identifier (pp, "while");
1640      pp_space (pp);
1641      pp_cxx_left_paren (pp);
1642      pp_cxx_expression (pp, WHILE_COND (t));
1643      pp_cxx_right_paren (pp);
1644      pp_newline_and_indent (pp, 3);
1645      pp_cxx_statement (pp, WHILE_BODY (t));
1646      pp_indentation (pp) -= 3;
1647      pp_needs_newline (pp) = true;
1648      break;
1649
1650    case DO_STMT:
1651      pp_cxx_identifier (pp, "do");
1652      pp_newline_and_indent (pp, 3);
1653      pp_cxx_statement (pp, DO_BODY (t));
1654      pp_newline_and_indent (pp, -3);
1655      pp_cxx_identifier (pp, "while");
1656      pp_space (pp);
1657      pp_cxx_left_paren (pp);
1658      pp_cxx_expression (pp, DO_COND (t));
1659      pp_cxx_right_paren (pp);
1660      pp_cxx_semicolon (pp);
1661      pp_needs_newline (pp) = true;
1662      break;
1663
1664    case FOR_STMT:
1665      pp_cxx_identifier (pp, "for");
1666      pp_space (pp);
1667      pp_cxx_left_paren (pp);
1668      if (FOR_INIT_STMT (t))
1669	pp_cxx_statement (pp, FOR_INIT_STMT (t));
1670      else
1671	pp_cxx_semicolon (pp);
1672      pp_needs_newline (pp) = false;
1673      pp_cxx_whitespace (pp);
1674      if (FOR_COND (t))
1675	pp_cxx_expression (pp, FOR_COND (t));
1676      pp_cxx_semicolon (pp);
1677      pp_needs_newline (pp) = false;
1678      pp_cxx_whitespace (pp);
1679      if (FOR_EXPR (t))
1680	pp_cxx_expression (pp, FOR_EXPR (t));
1681      pp_cxx_right_paren (pp);
1682      pp_newline_and_indent (pp, 3);
1683      pp_cxx_statement (pp, FOR_BODY (t));
1684      pp_indentation (pp) -= 3;
1685      pp_needs_newline (pp) = true;
1686      break;
1687
1688      /* jump-statement:
1689	    goto identifier;
1690	    continue ;
1691	    return expression(opt) ;  */
1692    case BREAK_STMT:
1693    case CONTINUE_STMT:
1694      pp_identifier (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
1695      pp_cxx_semicolon (pp);
1696      pp_needs_newline (pp) = true;
1697      break;
1698
1699      /* expression-statement:
1700	    expression(opt) ;  */
1701    case EXPR_STMT:
1702      pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
1703      pp_cxx_semicolon (pp);
1704      pp_needs_newline (pp) = true;
1705      break;
1706
1707    case CLEANUP_STMT:
1708      pp_cxx_identifier (pp, "try");
1709      pp_newline_and_indent (pp, 2);
1710      pp_cxx_statement (pp, CLEANUP_BODY (t));
1711      pp_newline_and_indent (pp, -2);
1712      pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
1713      pp_newline_and_indent (pp, 2);
1714      pp_cxx_statement (pp, CLEANUP_EXPR (t));
1715      pp_newline_and_indent (pp, -2);
1716      break;
1717
1718    default:
1719      pp_c_statement (pp_c_base (pp), t);
1720      break;
1721    }
1722}
1723
1724/* original-namespace-definition:
1725      namespace identifier { namespace-body }
1726
1727  As an edge case, we also handle unnamed namespace definition here.  */
1728
1729static void
1730pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
1731{
1732  pp_cxx_identifier (pp, "namespace");
1733  if (DECL_CONTEXT (t))
1734    pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1735  if (DECL_NAME (t))
1736    pp_cxx_unqualified_id (pp, t);
1737  pp_cxx_whitespace (pp);
1738  pp_cxx_left_brace (pp);
1739  /* We do not print the namespace-body.  */
1740  pp_cxx_whitespace (pp);
1741  pp_cxx_right_brace (pp);
1742}
1743
1744/* namespace-alias:
1745      identifier
1746
1747   namespace-alias-definition:
1748      namespace identifier = qualified-namespace-specifier ;
1749
1750   qualified-namespace-specifier:
1751      ::(opt) nested-name-specifier(opt) namespace-name   */
1752
1753static void
1754pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
1755{
1756  pp_cxx_identifier (pp, "namespace");
1757  if (DECL_CONTEXT (t))
1758    pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
1759  pp_cxx_unqualified_id (pp, t);
1760  pp_cxx_whitespace (pp);
1761  pp_equal (pp);
1762  pp_cxx_whitespace (pp);
1763  if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
1764    pp_cxx_nested_name_specifier (pp,
1765				  DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
1766  pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
1767  pp_cxx_semicolon (pp);
1768}
1769
1770/* simple-declaration:
1771      decl-specifier-seq(opt) init-declarator-list(opt)  */
1772
1773static void
1774pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
1775{
1776  pp_cxx_decl_specifier_seq (pp, t);
1777  pp_cxx_init_declarator (pp, t);
1778  pp_cxx_semicolon (pp);
1779  pp_needs_newline (pp) = true;
1780}
1781
1782/*
1783  template-parameter-list:
1784     template-parameter
1785     template-parameter-list , template-parameter  */
1786
1787static inline void
1788pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
1789{
1790  const int n = TREE_VEC_LENGTH (t);
1791  int i;
1792  for (i = 0; i < n; ++i)
1793    {
1794      if (i)
1795	pp_cxx_separate_with (pp, ',');
1796      pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
1797    }
1798}
1799
1800/* template-parameter:
1801      type-parameter
1802      parameter-declaration
1803
1804   type-parameter:
1805     class identifier(opt)
1806     class identifier(op) = type-id
1807     typename identifier(opt)
1808     typename identifier(opt) = type-id
1809     template < template-parameter-list > class identifier(opt)
1810     template < template-parameter-list > class identifier(opt) = template-name  */
1811
1812static void
1813pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
1814{
1815  tree parameter =  TREE_VALUE (t);
1816  switch (TREE_CODE (parameter))
1817    {
1818    case TYPE_DECL:
1819      pp_cxx_identifier (pp, "class");
1820      if (DECL_NAME (parameter))
1821	pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
1822      /* FIXME: Chech if we should print also default argument.  */
1823      break;
1824
1825    case PARM_DECL:
1826      pp_cxx_parameter_declaration (pp, parameter);
1827      break;
1828
1829    case TEMPLATE_DECL:
1830      break;
1831
1832    default:
1833      pp_unsupported_tree (pp, t);
1834      break;
1835    }
1836}
1837
1838/* Pretty-print a template parameter in the canonical form
1839   "template-parameter-<level>-<position in parameter list>".  */
1840
1841void
1842pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
1843{
1844  const enum tree_code code = TREE_CODE (parm);
1845
1846  /* Brings type template parameters to the canonical forms.  */
1847  if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
1848      || code == BOUND_TEMPLATE_TEMPLATE_PARM)
1849    parm = TEMPLATE_TYPE_PARM_INDEX (parm);
1850
1851  pp_cxx_begin_template_argument_list (pp);
1852  pp_cxx_identifier (pp, "template-parameter-");
1853  pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
1854  pp_minus (pp);
1855  pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
1856  pp_cxx_end_template_argument_list (pp);
1857}
1858
1859/*
1860  template-declaration:
1861     export(opt) template < template-parameter-list > declaration   */
1862
1863static void
1864pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
1865{
1866  tree tmpl = most_general_template (t);
1867  tree level;
1868  int i = 0;
1869
1870  pp_maybe_newline_and_indent (pp, 0);
1871  for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
1872    {
1873      pp_cxx_identifier (pp, "template");
1874      pp_cxx_begin_template_argument_list (pp);
1875      pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
1876      pp_cxx_end_template_argument_list (pp);
1877      pp_newline_and_indent (pp, 3);
1878      i += 3;
1879    }
1880  if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
1881    pp_cxx_function_definition (pp, t);
1882  else
1883    pp_cxx_simple_declaration (pp, t);
1884}
1885
1886static void
1887pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
1888{
1889  pp_unsupported_tree (pp, t);
1890}
1891
1892static void
1893pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
1894{
1895  pp_unsupported_tree (pp, t);
1896}
1897
1898/*
1899    declaration:
1900       block-declaration
1901       function-definition
1902       template-declaration
1903       explicit-instantiation
1904       explicit-specialization
1905       linkage-specification
1906       namespace-definition
1907
1908    block-declaration:
1909       simple-declaration
1910       asm-definition
1911       namespace-alias-definition
1912       using-declaration
1913       using-directive  */
1914void
1915pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
1916{
1917  if (!DECL_LANG_SPECIFIC (t))
1918    pp_cxx_simple_declaration (pp, t);
1919  else if (DECL_USE_TEMPLATE (t))
1920    switch (DECL_USE_TEMPLATE (t))
1921      {
1922      case 1:
1923	pp_cxx_template_declaration (pp, t);
1924	break;
1925
1926      case 2:
1927	pp_cxx_explicit_specialization (pp, t);
1928	break;
1929
1930      case 3:
1931	pp_cxx_explicit_instantiation (pp, t);
1932	break;
1933
1934      default:
1935	break;
1936      }
1937  else switch (TREE_CODE (t))
1938    {
1939    case VAR_DECL:
1940    case TYPE_DECL:
1941      pp_cxx_simple_declaration (pp, t);
1942      break;
1943
1944    case FUNCTION_DECL:
1945      if (DECL_SAVED_TREE (t))
1946	pp_cxx_function_definition (pp, t);
1947      else
1948	pp_cxx_simple_declaration (pp, t);
1949      break;
1950
1951    case NAMESPACE_DECL:
1952      if (DECL_NAMESPACE_ALIAS (t))
1953	pp_cxx_namespace_alias_definition (pp, t);
1954      else
1955	pp_cxx_original_namespace_definition (pp, t);
1956      break;
1957
1958    default:
1959      pp_unsupported_tree (pp, t);
1960      break;
1961    }
1962}
1963
1964
1965typedef c_pretty_print_fn pp_fun;
1966
1967/* Initialization of a C++ pretty-printer object.  */
1968
1969void
1970pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
1971{
1972  pp_c_pretty_printer_init (pp_c_base (pp));
1973  pp_set_line_maximum_length (pp, 0);
1974
1975  pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
1976  pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
1977  pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
1978  pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
1979  pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
1980  pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
1981  pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
1982  pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
1983  pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
1984  pp->c_base.direct_abstract_declarator =
1985    (pp_fun) pp_cxx_direct_abstract_declarator;
1986  pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
1987
1988  /* pp->c_base.statement = (pp_fun) pp_cxx_statement;  */
1989
1990  pp->c_base.constant = (pp_fun) pp_cxx_constant;
1991  pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
1992  pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
1993  pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
1994  pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
1995  pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
1996  pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
1997  pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
1998  pp->c_base.expression = (pp_fun) pp_cxx_expression;
1999  pp->enclosing_scope = global_namespace;
2000}
2001