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