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