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