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