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