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