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