]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/cxx-pretty-print.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / cxx-pretty-print.cc
CommitLineData
e1a4dd13 1/* Implementation of subroutines for the GNU C++ pretty-printer.
a945c346 2 Copyright (C) 2003-2024 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:
817e878a 486 pp_cxx_trait (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:
f9777f1b
PP
847 if (code == SIZEOF_EXPR)
848 pp_cxx_ws_string (this, "sizeof");
849 else if (ALIGNOF_EXPR_STD_P (t))
850 pp_cxx_ws_string (this, "alignof");
851 else
852 pp_cxx_ws_string (this, "__alignof__");
00d34d3a 853 pp_cxx_whitespace (this);
0d23cf7a
JJ
854 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
855 {
00d34d3a 856 pp_cxx_left_paren (this);
20059c8b 857 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
00d34d3a 858 pp_cxx_right_paren (this);
0d23cf7a
JJ
859 }
860 else if (TYPE_P (TREE_OPERAND (t, 0)))
03a08664 861 {
00d34d3a 862 pp_cxx_left_paren (this);
20059c8b 863 type_id (TREE_OPERAND (t, 0));
00d34d3a 864 pp_cxx_right_paren (this);
03a08664
ILT
865 }
866 else
00d34d3a 867 unary_expression (TREE_OPERAND (t, 0));
03a08664
ILT
868 break;
869
c154b3d8 870 case AT_ENCODE_EXPR:
00d34d3a
GDR
871 pp_cxx_ws_string (this, "@encode");
872 pp_cxx_whitespace (this);
873 pp_cxx_left_paren (this);
20059c8b 874 type_id (TREE_OPERAND (t, 0));
00d34d3a 875 pp_cxx_right_paren (this);
c154b3d8
NP
876 break;
877
c56ba354 878 case NOEXCEPT_EXPR:
00d34d3a
GDR
879 pp_cxx_ws_string (this, "noexcept");
880 pp_cxx_whitespace (this);
881 pp_cxx_left_paren (this);
882 expression (TREE_OPERAND (t, 0));
883 pp_cxx_right_paren (this);
c56ba354
JM
884 break;
885
392e3d51 886 case UNARY_PLUS_EXPR:
00d34d3a
GDR
887 pp_plus (this);
888 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
392e3d51
RS
889 break;
890
4b780675 891 default:
00d34d3a 892 c_pretty_printer::unary_expression (t);
4b780675
GDR
893 break;
894 }
e1a4dd13
GDR
895}
896
12ea3302
GDR
897/* cast-expression:
898 unary-expression
899 ( type-id ) cast-expression */
b9b44fb9 900
12ea3302
GDR
901static void
902pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
903{
904 switch (TREE_CODE (t))
905 {
906 case CAST_EXPR:
a4474a38 907 case IMPLICIT_CONV_EXPR:
20059c8b 908 pp->type_id (TREE_TYPE (t));
12ea3302
GDR
909 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
910 break;
911
912 default:
b066401f 913 pp_c_cast_expression (pp, t);
12ea3302
GDR
914 break;
915 }
916}
917
4b780675
GDR
918/* pm-expression:
919 cast-expression
920 pm-expression .* cast-expression
921 pm-expression ->* cast-expression */
b9b44fb9 922
e1a4dd13 923static void
4b780675 924pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
e1a4dd13 925{
4b780675
GDR
926 switch (TREE_CODE (t))
927 {
39a13be5 928 /* Handle unfortunate OFFSET_REF overloading here. */
4b780675
GDR
929 case OFFSET_REF:
930 if (TYPE_P (TREE_OPERAND (t, 0)))
0cbd7506
MS
931 {
932 pp_cxx_qualified_id (pp, t);
933 break;
934 }
191816a3 935 /* Fall through. */
4b780675
GDR
936 case MEMBER_REF:
937 case DOTSTAR_EXPR:
938 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
1e3eacc7
JJ
939 if (TREE_CODE (t) == MEMBER_REF)
940 pp_cxx_arrow (pp);
941 else
942 pp_cxx_dot (pp);
4b780675 943 pp_star(pp);
12ea3302 944 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
4b780675
GDR
945 break;
946
947
948 default:
12ea3302 949 pp_cxx_cast_expression (pp, t);
4b780675
GDR
950 break;
951 }
e1a4dd13
GDR
952}
953
4b780675
GDR
954/* multiplicative-expression:
955 pm-expression
956 multiplicative-expression * pm-expression
957 multiplicative-expression / pm-expression
958 multiplicative-expression % pm-expression */
b9b44fb9 959
00d34d3a
GDR
960void
961cxx_pretty_printer::multiplicative_expression (tree e)
e1a4dd13 962{
4b780675
GDR
963 enum tree_code code = TREE_CODE (e);
964 switch (code)
965 {
966 case MULT_EXPR:
967 case TRUNC_DIV_EXPR:
968 case TRUNC_MOD_EXPR:
889a3a30
MP
969 case EXACT_DIV_EXPR:
970 case RDIV_EXPR:
00d34d3a
GDR
971 multiplicative_expression (TREE_OPERAND (e, 0));
972 pp_space (this);
4b780675 973 if (code == MULT_EXPR)
00d34d3a 974 pp_star (this);
889a3a30 975 else if (code != TRUNC_MOD_EXPR)
00d34d3a 976 pp_slash (this);
4b780675 977 else
00d34d3a
GDR
978 pp_modulo (this);
979 pp_space (this);
980 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
4b780675
GDR
981 break;
982
983 default:
00d34d3a 984 pp_cxx_pm_expression (this, e);
4b780675
GDR
985 break;
986 }
e1a4dd13
GDR
987}
988
4b780675
GDR
989/* conditional-expression:
990 logical-or-expression
991 logical-or-expression ? expression : assignment-expression */
b9b44fb9 992
00d34d3a
GDR
993void
994cxx_pretty_printer::conditional_expression (tree e)
e1a4dd13 995{
4b780675
GDR
996 if (TREE_CODE (e) == COND_EXPR)
997 {
00d34d3a
GDR
998 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
999 pp_space (this);
1000 pp_question (this);
1001 pp_space (this);
1002 expression (TREE_OPERAND (e, 1));
1003 pp_space (this);
1004 assignment_expression (TREE_OPERAND (e, 2));
4b780675
GDR
1005 }
1006 else
00d34d3a 1007 pp_c_logical_or_expression (this, e);
4b780675
GDR
1008}
1009
b9b44fb9
GDR
1010/* Pretty-print a compound assignment operator token as indicated by T. */
1011
12ea3302
GDR
1012static void
1013pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
1014{
1015 const char *op;
1016
1017 switch (TREE_CODE (t))
1018 {
1019 case NOP_EXPR:
1020 op = "=";
1021 break;
1022
1023 case PLUS_EXPR:
1024 op = "+=";
1025 break;
1026
1027 case MINUS_EXPR:
1028 op = "-=";
1029 break;
1030
1031 case TRUNC_DIV_EXPR:
1032 op = "/=";
1033 break;
1034
1035 case TRUNC_MOD_EXPR:
1036 op = "%=";
1037 break;
1038
1039 default:
5806f481 1040 op = get_tree_code_name (TREE_CODE (t));
12ea3302
GDR
1041 break;
1042 }
1043
b02cec6e 1044 pp_cxx_ws_string (pp, op);
12ea3302
GDR
1045}
1046
1047
4b780675
GDR
1048/* assignment-expression:
1049 conditional-expression
1050 logical-or-expression assignment-operator assignment-expression
12ea3302
GDR
1051 throw-expression
1052
1053 throw-expression:
1054 throw assignment-expression(opt)
4b780675 1055
12ea3302 1056 assignment-operator: one of
4b780675 1057 = *= /= %= += -= >>= <<= &= ^= |= */
b9b44fb9 1058
00d34d3a
GDR
1059void
1060cxx_pretty_printer::assignment_expression (tree e)
4b780675 1061{
12ea3302 1062 switch (TREE_CODE (e))
4b780675 1063 {
12ea3302
GDR
1064 case MODIFY_EXPR:
1065 case INIT_EXPR:
00d34d3a
GDR
1066 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1067 pp_space (this);
1068 pp_equal (this);
1069 pp_space (this);
1070 assignment_expression (TREE_OPERAND (e, 1));
12ea3302 1071 break;
e1a4dd13 1072
12ea3302 1073 case THROW_EXPR:
00d34d3a 1074 pp_cxx_ws_string (this, "throw");
12ea3302 1075 if (TREE_OPERAND (e, 0))
00d34d3a 1076 assignment_expression (TREE_OPERAND (e, 0));
12ea3302 1077 break;
e1a4dd13 1078
12ea3302 1079 case MODOP_EXPR:
00d34d3a
GDR
1080 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1081 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1082 assignment_expression (TREE_OPERAND (e, 2));
12ea3302 1083 break;
e1a4dd13 1084
12ea3302 1085 default:
00d34d3a 1086 conditional_expression (e);
12ea3302
GDR
1087 break;
1088 }
1089}
1090
00d34d3a
GDR
1091void
1092cxx_pretty_printer::expression (tree t)
12ea3302
GDR
1093{
1094 switch (TREE_CODE (t))
1095 {
1096 case STRING_CST:
632f2871 1097 case VOID_CST:
12ea3302
GDR
1098 case INTEGER_CST:
1099 case REAL_CST:
7368348c 1100 case COMPLEX_CST:
00d34d3a 1101 constant (t);
12ea3302
GDR
1102 break;
1103
3ce4f9e4 1104 case USERDEF_LITERAL:
00d34d3a 1105 pp_cxx_userdef_literal (this, t);
3ce4f9e4
ESR
1106 break;
1107
12ea3302 1108 case RESULT_DECL:
00d34d3a 1109 pp_cxx_unqualified_id (this, t);
12ea3302
GDR
1110 break;
1111
c8094d83 1112#if 0
12ea3302 1113 case OFFSET_REF:
c8094d83 1114#endif
12ea3302
GDR
1115 case SCOPE_REF:
1116 case PTRMEM_CST:
00d34d3a 1117 pp_cxx_qualified_id (this, t);
12ea3302
GDR
1118 break;
1119
1120 case OVERLOAD:
a736411a 1121 t = OVL_FIRST (t);
191816a3 1122 /* FALLTHRU */
12ea3302 1123 case VAR_DECL:
75c4b0cd
PP
1124 if (DECL_NTTP_OBJECT_P (t))
1125 {
1126 /* Print the type followed by the CONSTRUCTOR value of the
1127 NTTP object. */
1128 simple_type_specifier (cv_unqualified (TREE_TYPE (t)));
1129 expression (DECL_INITIAL (t));
1130 break;
1131 }
1132 /* FALLTHRU */
12ea3302
GDR
1133 case PARM_DECL:
1134 case FIELD_DECL:
1135 case CONST_DECL:
1136 case FUNCTION_DECL:
1137 case BASELINK:
1138 case TEMPLATE_DECL:
1139 case TEMPLATE_TYPE_PARM:
1140 case TEMPLATE_PARM_INDEX:
41fd3bac 1141 case TEMPLATE_TEMPLATE_PARM:
c3e5898b 1142 case STMT_EXPR:
971e17ff 1143 case REQUIRES_EXPR:
00d34d3a 1144 primary_expression (t);
12ea3302
GDR
1145 break;
1146
1147 case CALL_EXPR:
1148 case DYNAMIC_CAST_EXPR:
1149 case STATIC_CAST_EXPR:
1150 case REINTERPRET_CAST_EXPR:
1151 case CONST_CAST_EXPR:
c8094d83 1152#if 0
12ea3302 1153 case MEMBER_REF:
c8094d83 1154#endif
12ea3302
GDR
1155 case EMPTY_CLASS_EXPR:
1156 case TYPEID_EXPR:
1157 case PSEUDO_DTOR_EXPR:
1158 case AGGR_INIT_EXPR:
03a08664 1159 case ARROW_EXPR:
00d34d3a 1160 postfix_expression (t);
12ea3302
GDR
1161 break;
1162
1163 case NEW_EXPR:
1164 case VEC_NEW_EXPR:
00d34d3a 1165 pp_cxx_new_expression (this, t);
12ea3302
GDR
1166 break;
1167
1168 case DELETE_EXPR:
1169 case VEC_DELETE_EXPR:
00d34d3a 1170 pp_cxx_delete_expression (this, t);
12ea3302
GDR
1171 break;
1172
03a08664
ILT
1173 case SIZEOF_EXPR:
1174 case ALIGNOF_EXPR:
c56ba354 1175 case NOEXCEPT_EXPR:
c0ea338b 1176 case UNARY_PLUS_EXPR:
00d34d3a 1177 unary_expression (t);
03a08664
ILT
1178 break;
1179
12ea3302 1180 case CAST_EXPR:
a4474a38 1181 case IMPLICIT_CONV_EXPR:
00d34d3a 1182 pp_cxx_cast_expression (this, t);
12ea3302
GDR
1183 break;
1184
1185 case OFFSET_REF:
1186 case MEMBER_REF:
1187 case DOTSTAR_EXPR:
00d34d3a 1188 pp_cxx_pm_expression (this, t);
12ea3302
GDR
1189 break;
1190
1191 case MULT_EXPR:
1192 case TRUNC_DIV_EXPR:
1193 case TRUNC_MOD_EXPR:
889a3a30
MP
1194 case EXACT_DIV_EXPR:
1195 case RDIV_EXPR:
00d34d3a 1196 multiplicative_expression (t);
12ea3302
GDR
1197 break;
1198
1199 case COND_EXPR:
00d34d3a 1200 conditional_expression (t);
12ea3302
GDR
1201 break;
1202
1203 case MODIFY_EXPR:
1204 case INIT_EXPR:
1205 case THROW_EXPR:
1206 case MODOP_EXPR:
00d34d3a 1207 assignment_expression (t);
12ea3302
GDR
1208 break;
1209
b9b44fb9 1210 case MUST_NOT_THROW_EXPR:
00d34d3a 1211 expression (TREE_OPERAND (t, 0));
b9b44fb9
GDR
1212 break;
1213
5d80a306 1214 case EXPR_PACK_EXPANSION:
00d34d3a
GDR
1215 expression (PACK_EXPANSION_PATTERN (t));
1216 pp_cxx_ws_string (this, "...");
5d80a306
DG
1217 break;
1218
f078dc7d
AS
1219 case UNARY_LEFT_FOLD_EXPR:
1220 pp_cxx_unary_left_fold_expression (this, t);
1221 break;
1222
1223 case UNARY_RIGHT_FOLD_EXPR:
1224 pp_cxx_unary_right_fold_expression (this, t);
1225 break;
1226
1227 case BINARY_LEFT_FOLD_EXPR:
1228 case BINARY_RIGHT_FOLD_EXPR:
1229 pp_cxx_binary_fold_expression (this, t);
1230 break;
1231
c7f06e13 1232 case TEMPLATE_ID_EXPR:
00d34d3a 1233 pp_cxx_template_id (this, t);
c7f06e13
PC
1234 break;
1235
5d80a306
DG
1236 case NONTYPE_ARGUMENT_PACK:
1237 {
1238 tree args = ARGUMENT_PACK_ARGS (t);
1239 int i, len = TREE_VEC_LENGTH (args);
44f6b7fb 1240 pp_cxx_left_brace (this);
5d80a306
DG
1241 for (i = 0; i < len; ++i)
1242 {
1243 if (i > 0)
00d34d3a
GDR
1244 pp_cxx_separate_with (this, ',');
1245 expression (TREE_VEC_ELT (args, i));
5d80a306 1246 }
44f6b7fb 1247 pp_cxx_right_brace (this);
5d80a306
DG
1248 }
1249 break;
cb57504a 1250
f030a1dc 1251 case LAMBDA_EXPR:
00d34d3a 1252 pp_cxx_ws_string (this, "<lambda>");
f030a1dc 1253 break;
5d80a306 1254
971e17ff 1255 case TRAIT_EXPR:
817e878a 1256 pp_cxx_trait (this, t);
971e17ff
AS
1257 break;
1258
cb57504a 1259 case ATOMIC_CONSTR:
f078dc7d 1260 case CHECK_CONSTR:
971e17ff
AS
1261 case CONJ_CONSTR:
1262 case DISJ_CONSTR:
1263 pp_cxx_constraint (this, t);
1264 break;
1265
10c6dc8e 1266 case PAREN_EXPR:
00d34d3a
GDR
1267 pp_cxx_left_paren (this);
1268 expression (TREE_OPERAND (t, 0));
1269 pp_cxx_right_paren (this);
10c6dc8e
JM
1270 break;
1271
75c4b0cd
PP
1272 case VIEW_CONVERT_EXPR:
1273 if (TREE_CODE (TREE_OPERAND (t, 0)) == TEMPLATE_PARM_INDEX)
1274 {
1275 /* Strip const VIEW_CONVERT_EXPR wrappers for class NTTPs. */
1276 expression (TREE_OPERAND (t, 0));
1277 break;
1278 }
1279 /* FALLTHRU */
12ea3302 1280 default:
00d34d3a 1281 c_pretty_printer::expression (t);
c8094d83 1282 break;
12ea3302
GDR
1283 }
1284}
1285
1286
1287/* Declarations. */
1288
1289/* function-specifier:
1290 inline
1291 virtual
1292 explicit */
b9b44fb9 1293
8f0e4d72
GDR
1294void
1295cxx_pretty_printer::function_specifier (tree t)
12ea3302
GDR
1296{
1297 switch (TREE_CODE (t))
1298 {
1299 case FUNCTION_DECL:
1300 if (DECL_VIRTUAL_P (t))
8f0e4d72 1301 pp_cxx_ws_string (this, "virtual");
12ea3302 1302 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
8f0e4d72 1303 pp_cxx_ws_string (this, "explicit");
12ea3302 1304 else
8f0e4d72 1305 c_pretty_printer::function_specifier (t);
12ea3302
GDR
1306
1307 default:
1308 break;
1309 }
1310}
1311
1312/* decl-specifier-seq:
1313 decl-specifier-seq(opt) decl-specifier
1314
1315 decl-specifier:
1316 storage-class-specifier
1317 type-specifier
1318 function-specifier
1319 friend
1320 typedef */
b9b44fb9 1321
8f0e4d72
GDR
1322void
1323cxx_pretty_printer::declaration_specifiers (tree t)
12ea3302
GDR
1324{
1325 switch (TREE_CODE (t))
1326 {
1327 case VAR_DECL:
1328 case PARM_DECL:
1329 case CONST_DECL:
1330 case FIELD_DECL:
20059c8b 1331 storage_class_specifier (t);
8f0e4d72 1332 declaration_specifiers (TREE_TYPE (t));
12ea3302 1333 break;
c8094d83 1334
12ea3302 1335 case TYPE_DECL:
8f0e4d72
GDR
1336 pp_cxx_ws_string (this, "typedef");
1337 declaration_specifiers (TREE_TYPE (t));
12ea3302
GDR
1338 break;
1339
12ea3302
GDR
1340 case FUNCTION_DECL:
1341 /* Constructors don't have return types. And conversion functions
0cbd7506 1342 do not have a type-specifier in their return types. */
12ea3302 1343 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
8f0e4d72 1344 function_specifier (t);
12ea3302 1345 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
8f0e4d72 1346 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
12ea3302 1347 else
191816a3
MP
1348 c_pretty_printer::declaration_specifiers (t);
1349 break;
1350 default:
8f0e4d72 1351 c_pretty_printer::declaration_specifiers (t);
12ea3302
GDR
1352 break;
1353 }
1354}
1355
1356/* simple-type-specifier:
1357 ::(opt) nested-name-specifier(opt) type-name
1358 ::(opt) nested-name-specifier(opt) template(opt) template-id
58a29af8 1359 decltype-specifier
12ea3302
GDR
1360 char
1361 wchar_t
1362 bool
1363 short
1364 int
1365 long
1366 signed
1367 unsigned
1368 float
1369 double
1370 void */
b9b44fb9 1371
7c26172c
GDR
1372void
1373cxx_pretty_printer::simple_type_specifier (tree t)
12ea3302
GDR
1374{
1375 switch (TREE_CODE (t))
1376 {
1377 case RECORD_TYPE:
1378 case UNION_TYPE:
1379 case ENUMERAL_TYPE:
7c26172c 1380 pp_cxx_qualified_id (this, t);
12ea3302
GDR
1381 break;
1382
1383 case TEMPLATE_TYPE_PARM:
41fd3bac 1384 case TEMPLATE_TEMPLATE_PARM:
12ea3302 1385 case TEMPLATE_PARM_INDEX:
d1093817 1386 case BOUND_TEMPLATE_TEMPLATE_PARM:
7c26172c 1387 pp_cxx_unqualified_id (this, t);
5dfe5d7d
PP
1388 if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
1389 if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
1390 pp_cxx_constrained_type_spec (this, c);
12ea3302
GDR
1391 break;
1392
1393 case TYPENAME_TYPE:
7c26172c
GDR
1394 pp_cxx_ws_string (this, "typename");
1395 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
ff0a6284 1396 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
12ea3302
GDR
1397 break;
1398
58a29af8
PP
1399 case DECLTYPE_TYPE:
1400 pp_cxx_ws_string (this, "decltype");
1401 pp_cxx_left_paren (this);
1402 this->expression (DECLTYPE_TYPE_EXPR (t));
1403 pp_cxx_right_paren (this);
1404 break;
1405
fe70679b
MP
1406 case NULLPTR_TYPE:
1407 pp_cxx_ws_string (this, "std::nullptr_t");
1408 break;
1409
817e878a
PP
1410 case TRAIT_TYPE:
1411 pp_cxx_trait (this, t);
1412 break;
1413
12ea3302 1414 default:
7c26172c 1415 c_pretty_printer::simple_type_specifier (t);
12ea3302
GDR
1416 break;
1417 }
1418}
1419
1420/* type-specifier-seq:
1421 type-specifier type-specifier-seq(opt)
1422
1423 type-specifier:
1424 simple-type-specifier
1425 class-specifier
1426 enum-specifier
1427 elaborated-type-specifier
cd0be382 1428 cv-qualifier */
12ea3302
GDR
1429
1430static void
1431pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1432{
12ea3302
GDR
1433 switch (TREE_CODE (t))
1434 {
1435 case TEMPLATE_DECL:
1436 case TEMPLATE_TYPE_PARM:
41fd3bac 1437 case TEMPLATE_TEMPLATE_PARM:
12ea3302
GDR
1438 case TYPE_DECL:
1439 case BOUND_TEMPLATE_TEMPLATE_PARM:
58a29af8 1440 case DECLTYPE_TYPE:
fe70679b 1441 case NULLPTR_TYPE:
41fd3bac 1442 pp_cxx_cv_qualifier_seq (pp, t);
7c26172c 1443 pp->simple_type_specifier (t);
12ea3302
GDR
1444 break;
1445
1446 case METHOD_TYPE:
1447 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1448 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1449 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1450 break;
1451
5cb6410a
JM
1452 case RECORD_TYPE:
1453 if (TYPE_PTRMEMFUNC_P (t))
1454 {
1455 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
8f0e4d72 1456 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
5cb6410a
JM
1457 pp_cxx_whitespace (pp);
1458 pp_cxx_ptr_operator (pp, t);
1459 break;
1460 }
191816a3 1461 /* fall through */
5cb6410a 1462
08e71221
MP
1463 case OFFSET_TYPE:
1464 if (TYPE_PTRDATAMEM_P (t))
1465 {
1466 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1467 pp_cxx_whitespace (pp);
1468 pp_cxx_ptr_operator (pp, t);
1469 break;
1470 }
1471 /* fall through */
1472
12ea3302
GDR
1473 default:
1474 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
b066401f 1475 pp_c_specifier_qualifier_list (pp, t);
12ea3302
GDR
1476 }
1477}
1478
1479/* ptr-operator:
1480 * cv-qualifier-seq(opt)
1481 &
1482 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1483
1484static void
1485pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1486{
1487 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1488 t = TREE_TYPE (t);
1489 switch (TREE_CODE (t))
1490 {
1491 case REFERENCE_TYPE:
1492 case POINTER_TYPE:
66b1156a 1493 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
0cbd7506 1494 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
b066401f 1495 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
50e10fa8 1496 if (TYPE_PTR_P (t))
0cbd7506
MS
1497 {
1498 pp_star (pp);
1499 pp_cxx_cv_qualifier_seq (pp, t);
1500 }
12ea3302 1501 else
0cbd7506 1502 pp_ampersand (pp);
12ea3302
GDR
1503 break;
1504
1505 case RECORD_TYPE:
1506 if (TYPE_PTRMEMFUNC_P (t))
0cbd7506
MS
1507 {
1508 pp_cxx_left_paren (pp);
1509 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1510 pp_star (pp);
1511 break;
1512 }
191816a3 1513 /* FALLTHRU */
12ea3302 1514 case OFFSET_TYPE:
66b1156a 1515 if (TYPE_PTRMEM_P (t))
0cbd7506
MS
1516 {
1517 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1518 pp_cxx_left_paren (pp);
1519 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1520 pp_star (pp);
1521 pp_cxx_cv_qualifier_seq (pp, t);
1522 break;
1523 }
191816a3 1524 /* fall through. */
12ea3302
GDR
1525
1526 default:
1527 pp_unsupported_tree (pp, t);
1528 break;
1529 }
1530}
1531
1532static inline tree
1533pp_cxx_implicit_parameter_type (tree mf)
1534{
7e1352fe 1535 return class_of_this_parm (TREE_TYPE (mf));
12ea3302
GDR
1536}
1537
1538/*
1539 parameter-declaration:
1540 decl-specifier-seq declarator
1541 decl-specifier-seq declarator = assignment-expression
1542 decl-specifier-seq abstract-declarator(opt)
1543 decl-specifier-seq abstract-declarator(opt) assignment-expression */
b9b44fb9 1544
12ea3302
GDR
1545static inline void
1546pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1547{
8f0e4d72 1548 pp->declaration_specifiers (t);
12ea3302 1549 if (TYPE_P (t))
20059c8b 1550 pp->abstract_declarator (t);
12ea3302 1551 else
20059c8b 1552 pp->declarator (t);
12ea3302
GDR
1553}
1554
1555/* parameter-declaration-clause:
1556 parameter-declaration-list(opt) ...(opt)
1557 parameter-declaration-list , ...
1558
1559 parameter-declaration-list:
1560 parameter-declaration
1561 parameter-declaration-list , parameter-declaration */
b9b44fb9 1562
12ea3302
GDR
1563static void
1564pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1565{
87fc34a4
PP
1566 gcc_assert (FUNC_OR_METHOD_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL);
1567 tree types, args;
1568 if (TYPE_P (t))
971e17ff 1569 {
87fc34a4
PP
1570 types = TYPE_ARG_TYPES (t);
1571 args = NULL_TREE;
971e17ff
AS
1572 }
1573 else
1574 {
87fc34a4
PP
1575 types = FUNCTION_FIRST_USER_PARMTYPE (t);
1576 args = FUNCTION_FIRST_USER_PARM (t);
971e17ff 1577 }
87fc34a4 1578 bool abstract = !args || (pp->flags & pp_c_flag_abstract);
12ea3302 1579
d20b7173 1580 /* Skip artificial parameter for non-static member functions. */
12ea3302
GDR
1581 if (TREE_CODE (t) == METHOD_TYPE)
1582 types = TREE_CHAIN (types);
1583
87fc34a4 1584 bool first = true;
12ea3302 1585 pp_cxx_left_paren (pp);
87fc34a4 1586 for (; types != void_list_node; types = TREE_CHAIN (types))
12ea3302
GDR
1587 {
1588 if (!first)
0cbd7506 1589 pp_cxx_separate_with (pp, ',');
12ea3302 1590 first = false;
87fc34a4
PP
1591 if (!types)
1592 {
1593 pp_cxx_ws_string (pp, "...");
1594 break;
1595 }
12ea3302 1596 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
b066401f 1597 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
0cbd7506
MS
1598 {
1599 pp_cxx_whitespace (pp);
1600 pp_equal (pp);
1601 pp_cxx_whitespace (pp);
20059c8b 1602 pp->assignment_expression (TREE_PURPOSE (types));
0cbd7506 1603 }
87fc34a4
PP
1604 if (!abstract)
1605 args = TREE_CHAIN (args);
12ea3302
GDR
1606 }
1607 pp_cxx_right_paren (pp);
1608}
1609
1610/* exception-specification:
1611 throw ( type-id-list(opt) )
1612
1613 type-id-list
1614 type-id
1615 type-id-list , type-id */
b9b44fb9 1616
12ea3302
GDR
1617static void
1618pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1619{
1620 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
5d80a306 1621 bool need_comma = false;
12ea3302 1622
3a55fb4c 1623 if (ex_spec == NULL)
12ea3302 1624 return;
3a55fb4c
JM
1625 if (TREE_PURPOSE (ex_spec))
1626 {
1627 pp_cxx_ws_string (pp, "noexcept");
1628 pp_cxx_whitespace (pp);
1629 pp_cxx_left_paren (pp);
10261728
JM
1630 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1631 pp_cxx_ws_string (pp, "<uninstantiated>");
1632 else
20059c8b 1633 pp->expression (TREE_PURPOSE (ex_spec));
3a55fb4c
JM
1634 pp_cxx_right_paren (pp);
1635 return;
1636 }
b02cec6e 1637 pp_cxx_ws_string (pp, "throw");
12ea3302
GDR
1638 pp_cxx_left_paren (pp);
1639 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1640 {
5d80a306
DG
1641 tree type = TREE_VALUE (ex_spec);
1642 tree argpack = NULL_TREE;
1643 int i, len = 1;
1644
1645 if (ARGUMENT_PACK_P (type))
1646 {
1647 argpack = ARGUMENT_PACK_ARGS (type);
1648 len = TREE_VEC_LENGTH (argpack);
1649 }
1650
1651 for (i = 0; i < len; ++i)
1652 {
1653 if (argpack)
1654 type = TREE_VEC_ELT (argpack, i);
1655
1656 if (need_comma)
1657 pp_cxx_separate_with (pp, ',');
1658 else
1659 need_comma = true;
1660
20059c8b 1661 pp->type_id (type);
5d80a306 1662 }
12ea3302
GDR
1663 }
1664 pp_cxx_right_paren (pp);
1665}
1666
1667/* direct-declarator:
1668 declarator-id
1669 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
0cbd7506 1670 exception-specification(opt)
12ea3302
GDR
1671 direct-declaration [ constant-expression(opt) ]
1672 ( declarator ) */
b9b44fb9 1673
8f0e4d72
GDR
1674void
1675cxx_pretty_printer::direct_declarator (tree t)
12ea3302
GDR
1676{
1677 switch (TREE_CODE (t))
1678 {
1679 case VAR_DECL:
1680 case PARM_DECL:
1681 case CONST_DECL:
1682 case FIELD_DECL:
1683 if (DECL_NAME (t))
0cbd7506 1684 {
8f0e4d72 1685 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
5d80a306 1686
73f4e2d2 1687 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
5d80a306
DG
1688 || template_parameter_pack_p (t))
1689 /* A function parameter pack or non-type template
1690 parameter pack. */
8f0e4d72 1691 pp_cxx_ws_string (this, "...");
5d80a306 1692
8f0e4d72 1693 id_expression (DECL_NAME (t));
0cbd7506 1694 }
8f0e4d72 1695 abstract_declarator (TREE_TYPE (t));
12ea3302 1696 break;
c8094d83 1697
12ea3302 1698 case FUNCTION_DECL:
8f0e4d72
GDR
1699 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1700 expression (t);
1701 pp_cxx_parameter_declaration_clause (this, t);
c8094d83 1702
12ea3302 1703 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
0cbd7506 1704 {
8f0e4d72
GDR
1705 padding = pp_before;
1706 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
0cbd7506 1707 }
12ea3302 1708
8f0e4d72 1709 pp_cxx_exception_specification (this, TREE_TYPE (t));
12ea3302
GDR
1710 break;
1711
1712 case TYPENAME_TYPE:
1713 case TEMPLATE_DECL:
1714 case TEMPLATE_TYPE_PARM:
1715 case TEMPLATE_PARM_INDEX:
41fd3bac 1716 case TEMPLATE_TEMPLATE_PARM:
12ea3302
GDR
1717 break;
1718
1719 default:
8f0e4d72 1720 c_pretty_printer::direct_declarator (t);
12ea3302
GDR
1721 break;
1722 }
1723}
1724
1725/* declarator:
1726 direct-declarator
1727 ptr-operator declarator */
b9b44fb9 1728
8f0e4d72
GDR
1729void
1730cxx_pretty_printer::declarator (tree t)
12ea3302 1731{
8f0e4d72 1732 direct_declarator (t);
971e17ff
AS
1733
1734 // Print a requires clause.
1735 if (flag_concepts)
1736 if (tree ci = get_constraints (t))
1737 if (tree reqs = CI_DECLARATOR_REQS (ci))
1738 pp_cxx_requires_clause (this, reqs);
12ea3302
GDR
1739}
1740
1741/* ctor-initializer:
1742 : mem-initializer-list
1743
1744 mem-initializer-list:
1745 mem-initializer
1746 mem-initializer , mem-initializer-list
1747
1748 mem-initializer:
1749 mem-initializer-id ( expression-list(opt) )
1750
1751 mem-initializer-id:
1752 ::(opt) nested-name-specifier(opt) class-name
1753 identifier */
b9b44fb9 1754
12ea3302
GDR
1755static void
1756pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1757{
1758 t = TREE_OPERAND (t, 0);
1759 pp_cxx_whitespace (pp);
1760 pp_colon (pp);
1761 pp_cxx_whitespace (pp);
1762 for (; t; t = TREE_CHAIN (t))
1763 {
5d80a306
DG
1764 tree purpose = TREE_PURPOSE (t);
1765 bool is_pack = PACK_EXPANSION_P (purpose);
1766
1767 if (is_pack)
20059c8b 1768 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
5d80a306 1769 else
20059c8b 1770 pp->primary_expression (purpose);
12ea3302 1771 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
5d80a306 1772 if (is_pack)
b02cec6e 1773 pp_cxx_ws_string (pp, "...");
12ea3302 1774 if (TREE_CHAIN (t))
0cbd7506 1775 pp_cxx_separate_with (pp, ',');
12ea3302
GDR
1776 }
1777}
1778
1779/* function-definition:
1780 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1781 decl-specifier-seq(opt) declarator function-try-block */
1782
b01150a2 1783static void
12ea3302
GDR
1784pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1785{
1786 tree saved_scope = pp->enclosing_scope;
8f0e4d72 1787 pp->declaration_specifiers (t);
20059c8b 1788 pp->declarator (t);
12ea3302
GDR
1789 pp_needs_newline (pp) = true;
1790 pp->enclosing_scope = DECL_CONTEXT (t);
1791 if (DECL_SAVED_TREE (t))
8dc70667 1792 pp->statement (DECL_SAVED_TREE (t));
12ea3302 1793 else
f8923f7e
SB
1794 pp_cxx_semicolon (pp);
1795 pp_newline_and_flush (pp);
12ea3302
GDR
1796 pp->enclosing_scope = saved_scope;
1797}
1798
1799/* abstract-declarator:
1800 ptr-operator abstract-declarator(opt)
1801 direct-abstract-declarator */
b9b44fb9 1802
8f0e4d72
GDR
1803void
1804cxx_pretty_printer::abstract_declarator (tree t)
12ea3302 1805{
08e71221
MP
1806 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1807 or a pointer-to-data-member of array type:
1808
1809 void (X::*)()
1810 int (X::*)[5]
1811
1812 but not for a pointer-to-data-member of non-array type:
1813
1814 int X::*
1815
1816 so be mindful of that. */
1817 if (TYPE_PTRMEMFUNC_P (t)
1818 || (TYPE_PTRDATAMEM_P (t)
1819 && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
8f0e4d72 1820 pp_cxx_right_paren (this);
71a93b08 1821 else if (INDIRECT_TYPE_P (t))
12ea3302
GDR
1822 {
1823 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
0cbd7506 1824 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
8f0e4d72 1825 pp_cxx_right_paren (this);
12ea3302
GDR
1826 t = TREE_TYPE (t);
1827 }
8f0e4d72 1828 direct_abstract_declarator (t);
12ea3302
GDR
1829}
1830
1831/* direct-abstract-declarator:
1832 direct-abstract-declarator(opt) ( parameter-declaration-clause )
0cbd7506 1833 cv-qualifier-seq(opt) exception-specification(opt)
12ea3302
GDR
1834 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1835 ( abstract-declarator ) */
b9b44fb9 1836
8f0e4d72
GDR
1837void
1838cxx_pretty_printer::direct_abstract_declarator (tree t)
12ea3302
GDR
1839{
1840 switch (TREE_CODE (t))
1841 {
1842 case REFERENCE_TYPE:
8f0e4d72 1843 abstract_declarator (t);
12ea3302
GDR
1844 break;
1845
1846 case RECORD_TYPE:
1847 if (TYPE_PTRMEMFUNC_P (t))
8f0e4d72 1848 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
12ea3302
GDR
1849 break;
1850
08e71221
MP
1851 case OFFSET_TYPE:
1852 if (TYPE_PTRDATAMEM_P (t))
1853 direct_abstract_declarator (TREE_TYPE (t));
1854 break;
1855
12ea3302
GDR
1856 case METHOD_TYPE:
1857 case FUNCTION_TYPE:
8f0e4d72
GDR
1858 pp_cxx_parameter_declaration_clause (this, t);
1859 direct_abstract_declarator (TREE_TYPE (t));
12ea3302 1860 if (TREE_CODE (t) == METHOD_TYPE)
0cbd7506 1861 {
8f0e4d72
GDR
1862 padding = pp_before;
1863 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
0cbd7506 1864 }
8f0e4d72 1865 pp_cxx_exception_specification (this, t);
12ea3302
GDR
1866 break;
1867
1868 case TYPENAME_TYPE:
1869 case TEMPLATE_TYPE_PARM:
1870 case TEMPLATE_TEMPLATE_PARM:
1871 case BOUND_TEMPLATE_TEMPLATE_PARM:
1872 case UNBOUND_CLASS_TEMPLATE:
58a29af8 1873 case DECLTYPE_TYPE:
12ea3302
GDR
1874 break;
1875
1876 default:
8f0e4d72 1877 c_pretty_printer::direct_abstract_declarator (t);
c8094d83 1878 break;
12ea3302
GDR
1879 }
1880}
1881
1882/* type-id:
1883 type-specifier-seq abstract-declarator(opt) */
b9b44fb9 1884
20059c8b
GDR
1885void
1886cxx_pretty_printer::type_id (tree t)
12ea3302 1887{
20059c8b
GDR
1888 pp_flags saved_flags = flags;
1889 flags |= pp_c_flag_abstract;
12ea3302
GDR
1890
1891 switch (TREE_CODE (t))
1892 {
1893 case TYPE_DECL:
1894 case UNION_TYPE:
1895 case RECORD_TYPE:
1896 case ENUMERAL_TYPE:
1897 case TYPENAME_TYPE:
1898 case BOUND_TEMPLATE_TEMPLATE_PARM:
1899 case UNBOUND_CLASS_TEMPLATE:
1900 case TEMPLATE_TEMPLATE_PARM:
1901 case TEMPLATE_TYPE_PARM:
1902 case TEMPLATE_PARM_INDEX:
1903 case TEMPLATE_DECL:
1904 case TYPEOF_TYPE:
817e878a 1905 case TRAIT_TYPE:
3ad6a8e1 1906 case DECLTYPE_TYPE:
fe70679b 1907 case NULLPTR_TYPE:
12ea3302 1908 case TEMPLATE_ID_EXPR:
08e71221 1909 case OFFSET_TYPE:
20059c8b 1910 pp_cxx_type_specifier_seq (this, t);
08e71221
MP
1911 if (TYPE_PTRMEM_P (t))
1912 abstract_declarator (t);
12ea3302
GDR
1913 break;
1914
5d80a306 1915 case TYPE_PACK_EXPANSION:
20059c8b
GDR
1916 type_id (PACK_EXPANSION_PATTERN (t));
1917 pp_cxx_ws_string (this, "...");
5d80a306 1918 break;
44f6b7fb
PP
1919
1920 case TYPE_ARGUMENT_PACK:
1921 {
1922 tree args = ARGUMENT_PACK_ARGS (t);
1923 int len = TREE_VEC_LENGTH (args);
1924 pp_cxx_left_brace (this);
1925 for (int i = 0; i < len; ++i)
1926 {
1927 if (i > 0)
1928 pp_cxx_separate_with (this, ',');
1929 type_id (TREE_VEC_ELT (args, i));
1930 }
1931 pp_cxx_right_brace (this);
1932 }
1933 break;
5d80a306 1934
12ea3302 1935 default:
20059c8b 1936 c_pretty_printer::type_id (t);
12ea3302
GDR
1937 break;
1938 }
1939
20059c8b 1940 flags = saved_flags;
12ea3302
GDR
1941}
1942
1943/* template-argument-list:
5d80a306
DG
1944 template-argument ...(opt)
1945 template-argument-list, template-argument ...(opt)
12ea3302
GDR
1946
1947 template-argument:
1948 assignment-expression
1949 type-id
5d80a306 1950 template-name */
b9b44fb9 1951
12ea3302
GDR
1952static void
1953pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1954{
1955 int i;
5d80a306
DG
1956 bool need_comma = false;
1957
12ea3302
GDR
1958 if (t == NULL)
1959 return;
1960 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1961 {
1962 tree arg = TREE_VEC_ELT (t, i);
5d80a306
DG
1963 tree argpack = NULL_TREE;
1964 int idx, len = 1;
1965
1966 if (ARGUMENT_PACK_P (arg))
1967 {
1968 argpack = ARGUMENT_PACK_ARGS (arg);
1969 len = TREE_VEC_LENGTH (argpack);
1970 }
1971
1972 for (idx = 0; idx < len; idx++)
1973 {
1974 if (argpack)
1975 arg = TREE_VEC_ELT (argpack, idx);
cb57504a 1976
5d80a306
DG
1977 if (need_comma)
1978 pp_cxx_separate_with (pp, ',');
1979 else
1980 need_comma = true;
1981
1982 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1983 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
20059c8b 1984 pp->type_id (arg);
5d80a306 1985 else
20059c8b 1986 pp->expression (arg);
5d80a306 1987 }
12ea3302
GDR
1988 }
1989}
1990
1991
1992static void
1993pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1994{
350fae66 1995 t = DECL_EXPR_DECL (t);
12ea3302
GDR
1996 pp_cxx_type_specifier_seq (pp, t);
1997 if (TYPE_P (t))
20059c8b 1998 pp->abstract_declarator (t);
12ea3302 1999 else
20059c8b 2000 pp->declarator (t);
12ea3302
GDR
2001}
2002
2003/* Statements. */
2004
8dc70667
GDR
2005void
2006cxx_pretty_printer::statement (tree t)
12ea3302
GDR
2007{
2008 switch (TREE_CODE (t))
2009 {
5882f0f3 2010 case CTOR_INITIALIZER:
8dc70667 2011 pp_cxx_ctor_initializer (this, t);
5882f0f3
RH
2012 break;
2013
12ea3302 2014 case USING_STMT:
8dc70667
GDR
2015 pp_cxx_ws_string (this, "using");
2016 pp_cxx_ws_string (this, "namespace");
91b1ca65 2017 if (DECL_CONTEXT (t))
8dc70667
GDR
2018 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
2019 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
12ea3302
GDR
2020 break;
2021
2022 case USING_DECL:
8dc70667
GDR
2023 pp_cxx_ws_string (this, "using");
2024 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
2025 pp_cxx_unqualified_id (this, DECL_NAME (t));
12ea3302
GDR
2026 break;
2027
2028 case EH_SPEC_BLOCK:
2029 break;
2030
2031 /* try-block:
0cbd7506 2032 try compound-statement handler-seq */
12ea3302 2033 case TRY_BLOCK:
8dc70667
GDR
2034 pp_maybe_newline_and_indent (this, 0);
2035 pp_cxx_ws_string (this, "try");
2036 pp_newline_and_indent (this, 3);
2037 statement (TRY_STMTS (t));
2038 pp_newline_and_indent (this, -3);
12ea3302 2039 if (CLEANUP_P (t))
0cbd7506 2040 ;
12ea3302 2041 else
8dc70667 2042 statement (TRY_HANDLERS (t));
12ea3302
GDR
2043 break;
2044
2045 /*
0cbd7506
MS
2046 handler-seq:
2047 handler handler-seq(opt)
12ea3302 2048
0cbd7506
MS
2049 handler:
2050 catch ( exception-declaration ) compound-statement
12ea3302 2051
0cbd7506
MS
2052 exception-declaration:
2053 type-specifier-seq declarator
2054 type-specifier-seq abstract-declarator
2055 ... */
12ea3302 2056 case HANDLER:
8dc70667
GDR
2057 pp_cxx_ws_string (this, "catch");
2058 pp_cxx_left_paren (this);
2059 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
2060 pp_cxx_right_paren (this);
2061 pp_indentation (this) += 3;
2062 pp_needs_newline (this) = true;
2063 statement (HANDLER_BODY (t));
2064 pp_indentation (this) -= 3;
2065 pp_needs_newline (this) = true;
12ea3302
GDR
2066 break;
2067
5a508662 2068 /* selection-statement:
0cbd7506
MS
2069 if ( expression ) statement
2070 if ( expression ) statement else statement */
5a508662 2071 case IF_STMT:
8dc70667
GDR
2072 pp_cxx_ws_string (this, "if");
2073 pp_cxx_whitespace (this);
2074 pp_cxx_left_paren (this);
20059c8b 2075 expression (IF_COND (t));
8dc70667
GDR
2076 pp_cxx_right_paren (this);
2077 pp_newline_and_indent (this, 2);
2078 statement (THEN_CLAUSE (t));
2079 pp_newline_and_indent (this, -2);
5a508662
RH
2080 if (ELSE_CLAUSE (t))
2081 {
2082 tree else_clause = ELSE_CLAUSE (t);
8dc70667 2083 pp_cxx_ws_string (this, "else");
5a508662 2084 if (TREE_CODE (else_clause) == IF_STMT)
8dc70667 2085 pp_cxx_whitespace (this);
5a508662 2086 else
8dc70667
GDR
2087 pp_newline_and_indent (this, 2);
2088 statement (else_clause);
5a508662 2089 if (TREE_CODE (else_clause) != IF_STMT)
8dc70667 2090 pp_newline_and_indent (this, -2);
5a508662
RH
2091 }
2092 break;
2093
f9132eb7 2094 case RANGE_FOR_STMT:
8dc70667
GDR
2095 pp_cxx_ws_string (this, "for");
2096 pp_space (this);
2097 pp_cxx_left_paren (this);
61856507
MP
2098 if (RANGE_FOR_INIT_STMT (t))
2099 {
2100 statement (RANGE_FOR_INIT_STMT (t));
2101 pp_needs_newline (this) = false;
2102 pp_cxx_whitespace (this);
2103 }
8dc70667
GDR
2104 statement (RANGE_FOR_DECL (t));
2105 pp_space (this);
2106 pp_needs_newline (this) = false;
2107 pp_colon (this);
2108 pp_space (this);
2109 statement (RANGE_FOR_EXPR (t));
2110 pp_cxx_right_paren (this);
2111 pp_newline_and_indent (this, 3);
2112 statement (FOR_BODY (t));
2113 pp_indentation (this) -= 3;
2114 pp_needs_newline (this) = true;
fbc315db
ILT
2115 break;
2116
934790cc 2117 /* expression-statement:
0cbd7506 2118 expression(opt) ; */
934790cc 2119 case EXPR_STMT:
20059c8b 2120 expression (EXPR_STMT_EXPR (t));
8dc70667
GDR
2121 pp_cxx_semicolon (this);
2122 pp_needs_newline (this) = true;
934790cc
ILT
2123 break;
2124
5a508662 2125 case CLEANUP_STMT:
8dc70667
GDR
2126 pp_cxx_ws_string (this, "try");
2127 pp_newline_and_indent (this, 2);
2128 statement (CLEANUP_BODY (t));
2129 pp_newline_and_indent (this, -2);
2130 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2131 pp_newline_and_indent (this, 2);
2132 statement (CLEANUP_EXPR (t));
2133 pp_newline_and_indent (this, -2);
5a508662
RH
2134 break;
2135
55a3debe 2136 case STATIC_ASSERT:
8f0e4d72 2137 declaration (t);
55a3debe
DG
2138 break;
2139
28567c40
JJ
2140 case OMP_DEPOBJ:
2141 pp_cxx_ws_string (this, "#pragma omp depobj");
2142 pp_space (this);
2143 pp_cxx_left_paren (this);
2144 expression (OMP_DEPOBJ_DEPOBJ (t));
2145 pp_cxx_right_paren (this);
2146 if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
2147 {
2148 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
2149 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t),
2150 pp_indentation (this), TDF_NONE);
2151 else
2152 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2153 {
2154 case OMP_CLAUSE_DEPEND_IN:
2155 pp_cxx_ws_string (this, " update(in)");
2156 break;
2157 case OMP_CLAUSE_DEPEND_INOUT:
2158 pp_cxx_ws_string (this, " update(inout)");
2159 break;
2160 case OMP_CLAUSE_DEPEND_OUT:
2161 pp_cxx_ws_string (this, " update(out)");
2162 break;
2163 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2164 pp_cxx_ws_string (this, " update(mutexinoutset)");
2165 break;
2c16eb31
JJ
2166 case OMP_CLAUSE_DEPEND_INOUTSET:
2167 pp_cxx_ws_string (this, " update(inoutset)");
2168 break;
28567c40
JJ
2169 case OMP_CLAUSE_DEPEND_LAST:
2170 pp_cxx_ws_string (this, " destroy");
2171 break;
2172 default:
2173 break;
2174 }
2175 }
2176 pp_needs_newline (this) = true;
2177 break;
2178
12ea3302 2179 default:
8dc70667 2180 c_pretty_printer::statement (t);
12ea3302
GDR
2181 break;
2182 }
2183}
2184
a2a9e21c
GDR
2185/* original-namespace-definition:
2186 namespace identifier { namespace-body }
2187
2188 As an edge case, we also handle unnamed namespace definition here. */
2189
2190static void
2191pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2192{
b02cec6e 2193 pp_cxx_ws_string (pp, "namespace");
91b1ca65
MM
2194 if (DECL_CONTEXT (t))
2195 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
ed36980c 2196 if (DECL_NAME (t))
a2a9e21c
GDR
2197 pp_cxx_unqualified_id (pp, t);
2198 pp_cxx_whitespace (pp);
2199 pp_cxx_left_brace (pp);
2200 /* We do not print the namespace-body. */
2201 pp_cxx_whitespace (pp);
2202 pp_cxx_right_brace (pp);
2203}
2204
2205/* namespace-alias:
2206 identifier
2207
2208 namespace-alias-definition:
2209 namespace identifier = qualified-namespace-specifier ;
2210
2211 qualified-namespace-specifier:
2212 ::(opt) nested-name-specifier(opt) namespace-name */
2213
2214static void
2215pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2216{
b02cec6e 2217 pp_cxx_ws_string (pp, "namespace");
91b1ca65
MM
2218 if (DECL_CONTEXT (t))
2219 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
a2a9e21c
GDR
2220 pp_cxx_unqualified_id (pp, t);
2221 pp_cxx_whitespace (pp);
2222 pp_equal (pp);
2223 pp_cxx_whitespace (pp);
91b1ca65 2224 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
3db45ab5 2225 pp_cxx_nested_name_specifier (pp,
91b1ca65 2226 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
a2a9e21c
GDR
2227 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2228 pp_cxx_semicolon (pp);
2229}
2230
12ea3302
GDR
2231/* simple-declaration:
2232 decl-specifier-seq(opt) init-declarator-list(opt) */
b9b44fb9 2233
12ea3302
GDR
2234static void
2235pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2236{
8f0e4d72 2237 pp->declaration_specifiers (t);
12ea3302
GDR
2238 pp_cxx_init_declarator (pp, t);
2239 pp_cxx_semicolon (pp);
2240 pp_needs_newline (pp) = true;
2241}
2242
2243/*
2244 template-parameter-list:
2245 template-parameter
2246 template-parameter-list , template-parameter */
2247
2248static inline void
2249pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2250{
2251 const int n = TREE_VEC_LENGTH (t);
2252 int i;
2253 for (i = 0; i < n; ++i)
2254 {
2255 if (i)
0cbd7506 2256 pp_cxx_separate_with (pp, ',');
12ea3302
GDR
2257 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2258 }
2259}
2260
2261/* template-parameter:
2262 type-parameter
2263 parameter-declaration
2264
2265 type-parameter:
5d80a306
DG
2266 class ...(opt) identifier(opt)
2267 class identifier(opt) = type-id
12ea3302 2268 typename identifier(opt)
5d80a306
DG
2269 typename ...(opt) identifier(opt) = type-id
2270 template < template-parameter-list > class ...(opt) identifier(opt)
3db45ab5 2271 template < template-parameter-list > class identifier(opt) = template-name */
b9b44fb9 2272
12ea3302
GDR
2273static void
2274pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2275{
2276 tree parameter = TREE_VALUE (t);
2277 switch (TREE_CODE (parameter))
2278 {
2279 case TYPE_DECL:
b02cec6e 2280 pp_cxx_ws_string (pp, "class");
5d80a306 2281 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
b02cec6e 2282 pp_cxx_ws_string (pp, "...");
12ea3302 2283 if (DECL_NAME (parameter))
0cbd7506 2284 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
39a13be5 2285 /* FIXME: Check if we should print also default argument. */
12ea3302
GDR
2286 break;
2287
2288 case PARM_DECL:
2289 pp_cxx_parameter_declaration (pp, parameter);
2290 break;
2291
2292 case TEMPLATE_DECL:
2293 break;
2294
2295 default:
2296 pp_unsupported_tree (pp, t);
2297 break;
2298 }
2299}
2300
b2517173
GDR
2301/* Pretty-print a template parameter in the canonical form
2302 "template-parameter-<level>-<position in parameter list>". */
2303
2304void
2305pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2306{
2307 const enum tree_code code = TREE_CODE (parm);
2308
04c06002 2309 /* Brings type template parameters to the canonical forms. */
b2517173
GDR
2310 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2311 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2312 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
c8094d83 2313
b2517173 2314 pp_cxx_begin_template_argument_list (pp);
0691175f 2315 pp->translate_string ("template-parameter-");
b2517173
GDR
2316 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2317 pp_minus (pp);
2318 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2319 pp_cxx_end_template_argument_list (pp);
2320}
2321
4fea442d
JM
2322/* Print a constrained-type-specifier. */
2323
2324void
2325pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2326{
cb57504a
JM
2327 pp_cxx_whitespace (pp);
2328 pp_cxx_left_bracket (pp);
2329 pp->translate_string ("requires");
2330 pp_cxx_whitespace (pp);
f078dc7d
AS
2331 if (c == error_mark_node)
2332 {
cb57504a 2333 pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
f078dc7d
AS
2334 return;
2335 }
cb57504a 2336 tree t, a;
4fea442d
JM
2337 placeholder_extract_concept_and_args (c, t, a);
2338 pp->id_expression (t);
cb57504a
JM
2339 pp_cxx_begin_template_argument_list (pp);
2340 pp_cxx_ws_string (pp, "<placeholder>");
2341 pp_cxx_separate_with (pp, ',');
2342 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2343 for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i)
2344 TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1);
2345 pp_cxx_template_argument_list (pp, args);
2346 ggc_free (args);
2347 pp_cxx_end_template_argument_list (pp);
2348 pp_cxx_right_bracket (pp);
4fea442d
JM
2349}
2350
12ea3302
GDR
2351/*
2352 template-declaration:
971e17ff
AS
2353 export(opt) template < template-parameter-list > declaration
2354
2355 Concept extensions:
2356
2357 template-declaration:
2358 export(opt) template < template-parameter-list >
2359 requires-clause(opt) declaration */
b9b44fb9 2360
12ea3302
GDR
2361static void
2362pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2363{
2364 tree tmpl = most_general_template (t);
2365 tree level;
12ea3302
GDR
2366
2367 pp_maybe_newline_and_indent (pp, 0);
2368 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2369 {
b02cec6e 2370 pp_cxx_ws_string (pp, "template");
12ea3302
GDR
2371 pp_cxx_begin_template_argument_list (pp);
2372 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2373 pp_cxx_end_template_argument_list (pp);
2374 pp_newline_and_indent (pp, 3);
12ea3302 2375 }
971e17ff
AS
2376
2377 if (flag_concepts)
2378 if (tree ci = get_constraints (t))
2379 if (tree reqs = CI_TEMPLATE_REQS (ci))
2380 {
2381 pp_cxx_requires_clause (pp, reqs);
2382 pp_newline_and_indent (pp, 6);
2383 }
2384
12ea3302
GDR
2385 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2386 pp_cxx_function_definition (pp, t);
cb57504a
JM
2387 else if (TREE_CODE (t) == CONCEPT_DECL)
2388 pp_cxx_concept_definition (pp, t);
12ea3302
GDR
2389 else
2390 pp_cxx_simple_declaration (pp, t);
2391}
2392
2393static void
2394pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2395{
2396 pp_unsupported_tree (pp, t);
2397}
2398
2399static void
2400pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2401{
2402 pp_unsupported_tree (pp, t);
2403}
2404
cb57504a
JM
2405static void
2406pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t)
2407{
2408 pp_cxx_unqualified_id (pp, DECL_NAME (t));
2409 pp_cxx_whitespace (pp);
2410 pp_cxx_ws_string (pp, "=");
2411 pp_cxx_whitespace (pp);
2412 pp->expression (DECL_INITIAL (t));
2413 pp_cxx_semicolon (pp);
2414}
2415
12ea3302
GDR
2416/*
2417 declaration:
2418 block-declaration
2419 function-definition
2420 template-declaration
2421 explicit-instantiation
2422 explicit-specialization
2423 linkage-specification
2424 namespace-definition
2425
2426 block-declaration:
2427 simple-declaration
2428 asm-definition
2429 namespace-alias-definition
2430 using-declaration
55a3debe
DG
2431 using-directive
2432 static_assert-declaration */
12ea3302 2433void
8f0e4d72 2434cxx_pretty_printer::declaration (tree t)
12ea3302 2435{
55a3debe
DG
2436 if (TREE_CODE (t) == STATIC_ASSERT)
2437 {
8f0e4d72
GDR
2438 pp_cxx_ws_string (this, "static_assert");
2439 pp_cxx_left_paren (this);
2440 expression (STATIC_ASSERT_CONDITION (t));
2441 pp_cxx_separate_with (this, ',');
2442 expression (STATIC_ASSERT_MESSAGE (t));
2443 pp_cxx_right_paren (this);
55a3debe
DG
2444 }
2445 else if (!DECL_LANG_SPECIFIC (t))
8f0e4d72 2446 pp_cxx_simple_declaration (this, t);
a2a9e21c 2447 else if (DECL_USE_TEMPLATE (t))
12ea3302
GDR
2448 switch (DECL_USE_TEMPLATE (t))
2449 {
a2a9e21c 2450 case 1:
8f0e4d72 2451 pp_cxx_template_declaration (this, t);
0cbd7506 2452 break;
c8094d83 2453
12ea3302 2454 case 2:
8f0e4d72 2455 pp_cxx_explicit_specialization (this, t);
0cbd7506 2456 break;
12ea3302
GDR
2457
2458 case 3:
8f0e4d72 2459 pp_cxx_explicit_instantiation (this, t);
0cbd7506 2460 break;
12ea3302
GDR
2461
2462 default:
0cbd7506 2463 break;
12ea3302 2464 }
12ea3302
GDR
2465 else switch (TREE_CODE (t))
2466 {
2467 case VAR_DECL:
2468 case TYPE_DECL:
8f0e4d72 2469 pp_cxx_simple_declaration (this, t);
12ea3302 2470 break;
c8094d83 2471
12ea3302
GDR
2472 case FUNCTION_DECL:
2473 if (DECL_SAVED_TREE (t))
8f0e4d72 2474 pp_cxx_function_definition (this, t);
12ea3302 2475 else
8f0e4d72 2476 pp_cxx_simple_declaration (this, t);
12ea3302
GDR
2477 break;
2478
a2a9e21c
GDR
2479 case NAMESPACE_DECL:
2480 if (DECL_NAMESPACE_ALIAS (t))
8f0e4d72 2481 pp_cxx_namespace_alias_definition (this, t);
a2a9e21c 2482 else
8f0e4d72 2483 pp_cxx_original_namespace_definition (this, t);
a2a9e21c
GDR
2484 break;
2485
12ea3302 2486 default:
8f0e4d72 2487 pp_unsupported_tree (this, t);
12ea3302
GDR
2488 break;
2489 }
2490}
2491
066f956c 2492static void
2d65b828
PC
2493pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2494{
2495 t = TREE_OPERAND (t, 0);
b02cec6e 2496 pp_cxx_ws_string (pp, "typeid");
2d65b828
PC
2497 pp_cxx_left_paren (pp);
2498 if (TYPE_P (t))
20059c8b 2499 pp->type_id (t);
2d65b828 2500 else
20059c8b 2501 pp->expression (t);
2d65b828
PC
2502 pp_cxx_right_paren (pp);
2503}
2504
fdb8f418
PC
2505void
2506pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2507{
b02cec6e 2508 pp_cxx_ws_string (pp, "va_arg");
fdb8f418 2509 pp_cxx_left_paren (pp);
20059c8b 2510 pp->assignment_expression (TREE_OPERAND (t, 0));
fdb8f418 2511 pp_cxx_separate_with (pp, ',');
20059c8b 2512 pp->type_id (TREE_TYPE (t));
fdb8f418
PC
2513 pp_cxx_right_paren (pp);
2514}
2515
094a5fe2
JJ
2516static bool
2517pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2518{
2519 switch (TREE_CODE (t))
2520 {
2521 case ARROW_EXPR:
2522 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
71a93b08 2523 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
094a5fe2 2524 {
20059c8b 2525 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
094a5fe2
JJ
2526 pp_cxx_separate_with (pp, ',');
2527 return true;
2528 }
2529 return false;
2530 case COMPONENT_REF:
2531 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2532 return false;
2533 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2534 pp_cxx_dot (pp);
20059c8b 2535 pp->expression (TREE_OPERAND (t, 1));
094a5fe2
JJ
2536 return true;
2537 case ARRAY_REF:
2538 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2539 return false;
2540 pp_left_bracket (pp);
20059c8b 2541 pp->expression (TREE_OPERAND (t, 1));
094a5fe2
JJ
2542 pp_right_bracket (pp);
2543 return true;
2544 default:
2545 return false;
2546 }
2547}
2548
2549void
2550pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2551{
b02cec6e 2552 pp_cxx_ws_string (pp, "offsetof");
094a5fe2
JJ
2553 pp_cxx_left_paren (pp);
2554 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
20059c8b 2555 pp->expression (TREE_OPERAND (t, 0));
094a5fe2
JJ
2556 pp_cxx_right_paren (pp);
2557}
2558
be845b04
JJ
2559void
2560pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2561{
2562 pp_cxx_ws_string (pp, "__builtin_addressof");
2563 pp_cxx_left_paren (pp);
2564 pp->expression (TREE_OPERAND (t, 0));
2565 pp_cxx_right_paren (pp);
2566}
2567
f078dc7d
AS
2568static char const*
2569get_fold_operator (tree t)
2570{
bb2a7f80
PP
2571 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2572 FOLD_EXPR_OP (t));
c7667624 2573 return info->name;
f078dc7d
AS
2574}
2575
2576void
2577pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2578{
2579 char const* op = get_fold_operator (t);
2580 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2581 pp_cxx_left_paren (pp);
2582 pp_cxx_ws_string (pp, "...");
2583 pp_cxx_ws_string (pp, op);
2584 pp->expression (expr);
2585 pp_cxx_right_paren (pp);
2586}
2587
2588void
2589pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2590{
2591 char const* op = get_fold_operator (t);
2592 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2593 pp_cxx_left_paren (pp);
2594 pp->expression (expr);
2595 pp_space (pp);
2596 pp_cxx_ws_string (pp, op);
2597 pp_cxx_ws_string (pp, "...");
2598 pp_cxx_right_paren (pp);
2599}
2600
2601void
2602pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2603{
2604 char const* op = get_fold_operator (t);
2605 tree t1 = TREE_OPERAND (t, 1);
2606 tree t2 = TREE_OPERAND (t, 2);
2607 if (t1 == FOLD_EXPR_PACK (t))
2608 t1 = PACK_EXPANSION_PATTERN (t1);
2609 else
2610 t2 = PACK_EXPANSION_PATTERN (t2);
2611 pp_cxx_left_paren (pp);
2612 pp->expression (t1);
2613 pp_cxx_ws_string (pp, op);
2614 pp_cxx_ws_string (pp, "...");
2615 pp_cxx_ws_string (pp, op);
2616 pp->expression (t2);
2617 pp_cxx_right_paren (pp);
2618}
2619
e74392f0 2620void
817e878a 2621pp_cxx_trait (cxx_pretty_printer *pp, tree t)
e74392f0 2622{
817e878a
PP
2623 cp_trait_kind kind;
2624 tree type1, type2;
2625 if (TREE_CODE (t) == TRAIT_EXPR)
2626 {
2627 kind = TRAIT_EXPR_KIND (t);
2628 type1 = TRAIT_EXPR_TYPE1 (t);
2629 type2 = TRAIT_EXPR_TYPE2 (t);
2630 }
2631 else
2632 {
2633 kind = TRAIT_TYPE_KIND (t);
2634 type1 = TRAIT_TYPE_TYPE1 (t);
2635 type2 = TRAIT_TYPE_TYPE2 (t);
2636 }
e74392f0
PC
2637
2638 switch (kind)
2639 {
1e2c124d
PP
2640#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
2641 case CPTK_##CODE: \
2642 pp_cxx_ws_string (pp, NAME); \
e74392f0 2643 break;
1e2c124d
PP
2644#include "cp-trait.def"
2645#undef DEFTRAIT
e74392f0
PC
2646 }
2647
58b7dbf8
PP
2648 if (kind == CPTK_TYPE_PACK_ELEMENT)
2649 {
2650 pp_cxx_begin_template_argument_list (pp);
2651 pp->expression (type1);
2652 }
148cbb15 2653 else
58b7dbf8
PP
2654 {
2655 pp_cxx_left_paren (pp);
2656 if (TYPE_P (type1))
2657 pp->type_id (type1);
2658 else
2659 pp->expression (type1);
2660 }
817e878a 2661 if (type2)
e74392f0 2662 {
76fa66ea 2663 if (TREE_CODE (type2) != TREE_VEC)
817e878a
PP
2664 {
2665 pp_cxx_separate_with (pp, ',');
2666 pp->type_id (type2);
2667 }
2668 else
76fa66ea 2669 for (tree arg : tree_vec_range (type2))
817e878a
PP
2670 {
2671 pp_cxx_separate_with (pp, ',');
76fa66ea 2672 pp->type_id (arg);
817e878a 2673 }
e74392f0 2674 }
58b7dbf8
PP
2675 if (kind == CPTK_TYPE_PACK_ELEMENT)
2676 pp_cxx_end_template_argument_list (pp);
2677 else
2678 pp_cxx_right_paren (pp);
e74392f0 2679}
971e17ff
AS
2680
2681// requires-clause:
2682// 'requires' logical-or-expression
2683void
2684pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2685{
2686 if (!t)
2687 return;
2688 pp->padding = pp_before;
2689 pp_cxx_ws_string (pp, "requires");
2690 pp_space (pp);
2691 pp->expression (t);
2692}
2693
2694/* requirement:
2695 simple-requirement
2696 compound-requirement
2697 type-requirement
2698 nested-requirement */
2699static void
2700pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2701{
2702 switch (TREE_CODE (t))
2703 {
2704 case SIMPLE_REQ:
2705 pp_cxx_simple_requirement (pp, t);
2706 break;
2707
2708 case TYPE_REQ:
2709 pp_cxx_type_requirement (pp, t);
2710 break;
2711
2712 case COMPOUND_REQ:
2713 pp_cxx_compound_requirement (pp, t);
2714 break;
2715
2716 case NESTED_REQ:
2717 pp_cxx_nested_requirement (pp, t);
2718 break;
2719
2720 default:
2721 gcc_unreachable ();
2722 }
2723}
2724
2725// requirement-list:
2726// requirement
2727// requirement-list ';' requirement[opt]
2728//
2729static void
2730pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2731{
2732 for (; t; t = TREE_CHAIN (t))
2733 pp_cxx_requirement (pp, TREE_VALUE (t));
2734}
2735
2736// requirement-body:
2737// '{' requirement-list '}'
2738static void
2739pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2740{
2741 pp_cxx_left_brace (pp);
2742 pp_cxx_requirement_list (pp, t);
2743 pp_cxx_right_brace (pp);
2744}
2745
2746// requires-expression:
2747// 'requires' requirement-parameter-list requirement-body
2748void
2749pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2750{
2751 pp_string (pp, "requires");
87fc34a4 2752 if (tree parms = REQUIRES_EXPR_PARMS (t))
971e17ff 2753 {
87fc34a4
PP
2754 bool first = true;
2755 pp_cxx_left_paren (pp);
2756 for (; parms; parms = TREE_CHAIN (parms))
2757 {
2758 if (!first)
2759 pp_cxx_separate_with (pp, ',' );
2760 first = false;
2761 pp_cxx_parameter_declaration (pp, parms);
2762 }
2763 pp_cxx_right_paren (pp);
971e17ff
AS
2764 pp_cxx_whitespace (pp);
2765 }
2766 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2767}
2768
2769/* simple-requirement:
2770 expression ';' */
2771void
2772pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2773{
2774 pp->expression (TREE_OPERAND (t, 0));
2775 pp_cxx_semicolon (pp);
2776}
2777
2778/* type-requirement:
2779 typename type-name ';' */
2780void
2781pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2782{
2783 pp->type_id (TREE_OPERAND (t, 0));
2784 pp_cxx_semicolon (pp);
2785}
2786
2787/* compound-requirement:
2788 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2789void
2790pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2791{
2792 pp_cxx_left_brace (pp);
2793 pp->expression (TREE_OPERAND (t, 0));
2794 pp_cxx_right_brace (pp);
2795
2796 if (COMPOUND_REQ_NOEXCEPT_P (t))
2797 pp_cxx_ws_string (pp, "noexcept");
2798
2799 if (tree type = TREE_OPERAND (t, 1))
2800 {
cb57504a 2801 pp_cxx_whitespace (pp);
971e17ff
AS
2802 pp_cxx_ws_string (pp, "->");
2803 pp->type_id (type);
2804 }
f078dc7d 2805 pp_cxx_semicolon (pp);
971e17ff
AS
2806}
2807
2808/* nested requirement:
2809 'requires' constraint-expression */
2810void
2811pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2812{
2813 pp_cxx_ws_string (pp, "requires");
2814 pp->expression (TREE_OPERAND (t, 0));
2815 pp_cxx_semicolon (pp);
2816}
2817
f078dc7d
AS
2818void
2819pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2820{
2821 tree decl = CHECK_CONSTR_CONCEPT (t);
2822 tree tmpl = DECL_TI_TEMPLATE (decl);
2823 tree args = CHECK_CONSTR_ARGS (t);
2824 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2825
cb57504a
JM
2826 if (TREE_CODE (decl) == CONCEPT_DECL)
2827 pp->expression (id);
2828 else if (VAR_P (decl))
f078dc7d
AS
2829 pp->expression (id);
2830 else if (TREE_CODE (decl) == FUNCTION_DECL)
2831 {
2832 tree call = build_vl_exp (CALL_EXPR, 2);
2833 TREE_OPERAND (call, 0) = integer_two_node;
2834 TREE_OPERAND (call, 1) = id;
2835 pp->expression (call);
2836 }
2837 else
2838 gcc_unreachable ();
971e17ff
AS
2839}
2840
cb57504a
JM
2841/* Output the "[with ...]" clause for a parameter mapping of an atomic
2842 constraint. */
971e17ff 2843
828878c3 2844void
cb57504a 2845pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map)
971e17ff 2846{
828878c3
PP
2847 pp_cxx_whitespace (pp);
2848 pp_cxx_left_bracket (pp);
2849 pp->translate_string ("with");
2850 pp_cxx_whitespace (pp);
2851
cb57504a
JM
2852 for (tree p = map; p; p = TREE_CHAIN (p))
2853 {
2854 tree parm = TREE_VALUE (p);
2855 tree arg = TREE_PURPOSE (p);
971e17ff 2856
cb57504a
JM
2857 if (TYPE_P (parm))
2858 pp->type_id (parm);
6f43a8a0
MP
2859 else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2860 pp_cxx_tree_identifier (pp, name);
cb57504a 2861 else
6f43a8a0 2862 pp->translate_string ("<unnamed>");
971e17ff 2863
cb57504a
JM
2864 pp_cxx_whitespace (pp);
2865 pp_equal (pp);
2866 pp_cxx_whitespace (pp);
971e17ff 2867
cb57504a
JM
2868 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2869 pp->type_id (arg);
2870 else
2871 pp->expression (arg);
2872
2873 if (TREE_CHAIN (p) != NULL_TREE)
2874 pp_cxx_separate_with (pp, ';');
2875 }
828878c3
PP
2876
2877 pp_cxx_right_bracket (pp);
971e17ff
AS
2878}
2879
2880void
cb57504a 2881pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t)
971e17ff 2882{
cb57504a
JM
2883 /* Emit the expression. */
2884 pp->expression (ATOMIC_CONSTR_EXPR (t));
2885
2886 /* Emit the parameter mapping. */
2887 tree map = ATOMIC_CONSTR_MAP (t);
2888 if (map && map != error_mark_node)
828878c3 2889 pp_cxx_parameter_mapping (pp, map);
971e17ff
AS
2890}
2891
2892void
2893pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2894{
2895 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
cb57504a 2896 pp_string (pp, " /\\ ");
971e17ff
AS
2897 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2898}
2899
2900void
2901pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2902{
2903 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
cb57504a 2904 pp_string (pp, " \\/ ");
971e17ff
AS
2905 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2906}
2907
2908void
2909pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2910{
2911 if (t == error_mark_node)
2912 return pp->expression (t);
2913
2914 switch (TREE_CODE (t))
2915 {
cb57504a
JM
2916 case ATOMIC_CONSTR:
2917 pp_cxx_atomic_constraint (pp, t);
971e17ff
AS
2918 break;
2919
f078dc7d
AS
2920 case CHECK_CONSTR:
2921 pp_cxx_check_constraint (pp, t);
2922 break;
2923
971e17ff
AS
2924 case CONJ_CONSTR:
2925 pp_cxx_conjunction (pp, t);
2926 break;
2927
2928 case DISJ_CONSTR:
2929 pp_cxx_disjunction (pp, t);
2930 break;
2931
f078dc7d
AS
2932 case EXPR_PACK_EXPANSION:
2933 pp->expression (TREE_OPERAND (t, 0));
2934 break;
2935
971e17ff
AS
2936 default:
2937 gcc_unreachable ();
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}
368877a1
DM
2953
2954/* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2955
2956pretty_printer *
2957cxx_pretty_printer::clone () const
2958{
2959 return new cxx_pretty_printer (*this);
2960}