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