c++: "'decltype_type' not supported" in diagnostic [PR85278]
[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 decltype-specifier
1329 char
1330 wchar_t
1331 bool
1332 short
1333 int
1334 long
1335 signed
1336 unsigned
1337 float
1338 double
1339 void */
1340
1341 void
1342 cxx_pretty_printer::simple_type_specifier (tree t)
1343 {
1344 switch (TREE_CODE (t))
1345 {
1346 case RECORD_TYPE:
1347 case UNION_TYPE:
1348 case ENUMERAL_TYPE:
1349 pp_cxx_qualified_id (this, t);
1350 break;
1351
1352 case TEMPLATE_TYPE_PARM:
1353 case TEMPLATE_TEMPLATE_PARM:
1354 case TEMPLATE_PARM_INDEX:
1355 case BOUND_TEMPLATE_TEMPLATE_PARM:
1356 pp_cxx_unqualified_id (this, t);
1357 if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
1358 pp_cxx_constrained_type_spec (this, c);
1359 break;
1360
1361 case TYPENAME_TYPE:
1362 pp_cxx_ws_string (this, "typename");
1363 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1364 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
1365 break;
1366
1367 case DECLTYPE_TYPE:
1368 pp_cxx_ws_string (this, "decltype");
1369 pp_cxx_left_paren (this);
1370 this->expression (DECLTYPE_TYPE_EXPR (t));
1371 pp_cxx_right_paren (this);
1372 break;
1373
1374 default:
1375 c_pretty_printer::simple_type_specifier (t);
1376 break;
1377 }
1378 }
1379
1380 /* type-specifier-seq:
1381 type-specifier type-specifier-seq(opt)
1382
1383 type-specifier:
1384 simple-type-specifier
1385 class-specifier
1386 enum-specifier
1387 elaborated-type-specifier
1388 cv-qualifier */
1389
1390 static void
1391 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1392 {
1393 switch (TREE_CODE (t))
1394 {
1395 case TEMPLATE_DECL:
1396 case TEMPLATE_TYPE_PARM:
1397 case TEMPLATE_TEMPLATE_PARM:
1398 case TYPE_DECL:
1399 case BOUND_TEMPLATE_TEMPLATE_PARM:
1400 case DECLTYPE_TYPE:
1401 pp_cxx_cv_qualifier_seq (pp, t);
1402 pp->simple_type_specifier (t);
1403 break;
1404
1405 case METHOD_TYPE:
1406 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1407 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1408 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1409 break;
1410
1411 case RECORD_TYPE:
1412 if (TYPE_PTRMEMFUNC_P (t))
1413 {
1414 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1415 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1416 pp_cxx_whitespace (pp);
1417 pp_cxx_ptr_operator (pp, t);
1418 break;
1419 }
1420 /* fall through */
1421
1422 default:
1423 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1424 pp_c_specifier_qualifier_list (pp, t);
1425 }
1426 }
1427
1428 /* ptr-operator:
1429 * cv-qualifier-seq(opt)
1430 &
1431 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1432
1433 static void
1434 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1435 {
1436 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1437 t = TREE_TYPE (t);
1438 switch (TREE_CODE (t))
1439 {
1440 case REFERENCE_TYPE:
1441 case POINTER_TYPE:
1442 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1443 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1444 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1445 if (TYPE_PTR_P (t))
1446 {
1447 pp_star (pp);
1448 pp_cxx_cv_qualifier_seq (pp, t);
1449 }
1450 else
1451 pp_ampersand (pp);
1452 break;
1453
1454 case RECORD_TYPE:
1455 if (TYPE_PTRMEMFUNC_P (t))
1456 {
1457 pp_cxx_left_paren (pp);
1458 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1459 pp_star (pp);
1460 break;
1461 }
1462 /* FALLTHRU */
1463 case OFFSET_TYPE:
1464 if (TYPE_PTRMEM_P (t))
1465 {
1466 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1467 pp_cxx_left_paren (pp);
1468 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1469 pp_star (pp);
1470 pp_cxx_cv_qualifier_seq (pp, t);
1471 break;
1472 }
1473 /* fall through. */
1474
1475 default:
1476 pp_unsupported_tree (pp, t);
1477 break;
1478 }
1479 }
1480
1481 static inline tree
1482 pp_cxx_implicit_parameter_type (tree mf)
1483 {
1484 return class_of_this_parm (TREE_TYPE (mf));
1485 }
1486
1487 /*
1488 parameter-declaration:
1489 decl-specifier-seq declarator
1490 decl-specifier-seq declarator = assignment-expression
1491 decl-specifier-seq abstract-declarator(opt)
1492 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1493
1494 static inline void
1495 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1496 {
1497 pp->declaration_specifiers (t);
1498 if (TYPE_P (t))
1499 pp->abstract_declarator (t);
1500 else
1501 pp->declarator (t);
1502 }
1503
1504 /* parameter-declaration-clause:
1505 parameter-declaration-list(opt) ...(opt)
1506 parameter-declaration-list , ...
1507
1508 parameter-declaration-list:
1509 parameter-declaration
1510 parameter-declaration-list , parameter-declaration */
1511
1512 static void
1513 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1514 {
1515 tree args;
1516 tree types;
1517 bool abstract;
1518
1519 // For a requires clause or the explicit printing of a parameter list
1520 // we expect T to be a chain of PARM_DECLs. Otherwise, the list of
1521 // args and types are taken from the function decl T.
1522 if (TREE_CODE (t) == PARM_DECL)
1523 {
1524 args = t;
1525 types = t;
1526 abstract = false;
1527 }
1528 else
1529 {
1530 bool type_p = TYPE_P (t);
1531 args = type_p ? NULL : FUNCTION_FIRST_USER_PARM (t);
1532 types = type_p ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
1533 abstract = args == NULL || pp->flags & pp_c_flag_abstract;
1534 }
1535 bool first = true;
1536
1537 /* Skip artificial parameter for nonstatic member functions. */
1538 if (TREE_CODE (t) == METHOD_TYPE)
1539 types = TREE_CHAIN (types);
1540
1541 pp_cxx_left_paren (pp);
1542 for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
1543 {
1544 if (!first)
1545 pp_cxx_separate_with (pp, ',');
1546 first = false;
1547 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1548 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1549 {
1550 pp_cxx_whitespace (pp);
1551 pp_equal (pp);
1552 pp_cxx_whitespace (pp);
1553 pp->assignment_expression (TREE_PURPOSE (types));
1554 }
1555 }
1556 pp_cxx_right_paren (pp);
1557 }
1558
1559 /* exception-specification:
1560 throw ( type-id-list(opt) )
1561
1562 type-id-list
1563 type-id
1564 type-id-list , type-id */
1565
1566 static void
1567 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1568 {
1569 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1570 bool need_comma = false;
1571
1572 if (ex_spec == NULL)
1573 return;
1574 if (TREE_PURPOSE (ex_spec))
1575 {
1576 pp_cxx_ws_string (pp, "noexcept");
1577 pp_cxx_whitespace (pp);
1578 pp_cxx_left_paren (pp);
1579 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1580 pp_cxx_ws_string (pp, "<uninstantiated>");
1581 else
1582 pp->expression (TREE_PURPOSE (ex_spec));
1583 pp_cxx_right_paren (pp);
1584 return;
1585 }
1586 pp_cxx_ws_string (pp, "throw");
1587 pp_cxx_left_paren (pp);
1588 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1589 {
1590 tree type = TREE_VALUE (ex_spec);
1591 tree argpack = NULL_TREE;
1592 int i, len = 1;
1593
1594 if (ARGUMENT_PACK_P (type))
1595 {
1596 argpack = ARGUMENT_PACK_ARGS (type);
1597 len = TREE_VEC_LENGTH (argpack);
1598 }
1599
1600 for (i = 0; i < len; ++i)
1601 {
1602 if (argpack)
1603 type = TREE_VEC_ELT (argpack, i);
1604
1605 if (need_comma)
1606 pp_cxx_separate_with (pp, ',');
1607 else
1608 need_comma = true;
1609
1610 pp->type_id (type);
1611 }
1612 }
1613 pp_cxx_right_paren (pp);
1614 }
1615
1616 /* direct-declarator:
1617 declarator-id
1618 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1619 exception-specification(opt)
1620 direct-declaration [ constant-expression(opt) ]
1621 ( declarator ) */
1622
1623 void
1624 cxx_pretty_printer::direct_declarator (tree t)
1625 {
1626 switch (TREE_CODE (t))
1627 {
1628 case VAR_DECL:
1629 case PARM_DECL:
1630 case CONST_DECL:
1631 case FIELD_DECL:
1632 if (DECL_NAME (t))
1633 {
1634 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1635
1636 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1637 || template_parameter_pack_p (t))
1638 /* A function parameter pack or non-type template
1639 parameter pack. */
1640 pp_cxx_ws_string (this, "...");
1641
1642 id_expression (DECL_NAME (t));
1643 }
1644 abstract_declarator (TREE_TYPE (t));
1645 break;
1646
1647 case FUNCTION_DECL:
1648 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1649 expression (t);
1650 pp_cxx_parameter_declaration_clause (this, t);
1651
1652 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1653 {
1654 padding = pp_before;
1655 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1656 }
1657
1658 pp_cxx_exception_specification (this, TREE_TYPE (t));
1659 break;
1660
1661 case TYPENAME_TYPE:
1662 case TEMPLATE_DECL:
1663 case TEMPLATE_TYPE_PARM:
1664 case TEMPLATE_PARM_INDEX:
1665 case TEMPLATE_TEMPLATE_PARM:
1666 break;
1667
1668 default:
1669 c_pretty_printer::direct_declarator (t);
1670 break;
1671 }
1672 }
1673
1674 /* declarator:
1675 direct-declarator
1676 ptr-operator declarator */
1677
1678 void
1679 cxx_pretty_printer::declarator (tree t)
1680 {
1681 direct_declarator (t);
1682
1683 // Print a requires clause.
1684 if (flag_concepts)
1685 if (tree ci = get_constraints (t))
1686 if (tree reqs = CI_DECLARATOR_REQS (ci))
1687 pp_cxx_requires_clause (this, reqs);
1688 }
1689
1690 /* ctor-initializer:
1691 : mem-initializer-list
1692
1693 mem-initializer-list:
1694 mem-initializer
1695 mem-initializer , mem-initializer-list
1696
1697 mem-initializer:
1698 mem-initializer-id ( expression-list(opt) )
1699
1700 mem-initializer-id:
1701 ::(opt) nested-name-specifier(opt) class-name
1702 identifier */
1703
1704 static void
1705 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1706 {
1707 t = TREE_OPERAND (t, 0);
1708 pp_cxx_whitespace (pp);
1709 pp_colon (pp);
1710 pp_cxx_whitespace (pp);
1711 for (; t; t = TREE_CHAIN (t))
1712 {
1713 tree purpose = TREE_PURPOSE (t);
1714 bool is_pack = PACK_EXPANSION_P (purpose);
1715
1716 if (is_pack)
1717 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1718 else
1719 pp->primary_expression (purpose);
1720 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1721 if (is_pack)
1722 pp_cxx_ws_string (pp, "...");
1723 if (TREE_CHAIN (t))
1724 pp_cxx_separate_with (pp, ',');
1725 }
1726 }
1727
1728 /* function-definition:
1729 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1730 decl-specifier-seq(opt) declarator function-try-block */
1731
1732 static void
1733 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1734 {
1735 tree saved_scope = pp->enclosing_scope;
1736 pp->declaration_specifiers (t);
1737 pp->declarator (t);
1738 pp_needs_newline (pp) = true;
1739 pp->enclosing_scope = DECL_CONTEXT (t);
1740 if (DECL_SAVED_TREE (t))
1741 pp->statement (DECL_SAVED_TREE (t));
1742 else
1743 pp_cxx_semicolon (pp);
1744 pp_newline_and_flush (pp);
1745 pp->enclosing_scope = saved_scope;
1746 }
1747
1748 /* abstract-declarator:
1749 ptr-operator abstract-declarator(opt)
1750 direct-abstract-declarator */
1751
1752 void
1753 cxx_pretty_printer::abstract_declarator (tree t)
1754 {
1755 if (TYPE_PTRMEM_P (t))
1756 pp_cxx_right_paren (this);
1757 else if (INDIRECT_TYPE_P (t))
1758 {
1759 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1760 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1761 pp_cxx_right_paren (this);
1762 t = TREE_TYPE (t);
1763 }
1764 direct_abstract_declarator (t);
1765 }
1766
1767 /* direct-abstract-declarator:
1768 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1769 cv-qualifier-seq(opt) exception-specification(opt)
1770 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1771 ( abstract-declarator ) */
1772
1773 void
1774 cxx_pretty_printer::direct_abstract_declarator (tree t)
1775 {
1776 switch (TREE_CODE (t))
1777 {
1778 case REFERENCE_TYPE:
1779 abstract_declarator (t);
1780 break;
1781
1782 case RECORD_TYPE:
1783 if (TYPE_PTRMEMFUNC_P (t))
1784 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1785 break;
1786
1787 case METHOD_TYPE:
1788 case FUNCTION_TYPE:
1789 pp_cxx_parameter_declaration_clause (this, t);
1790 direct_abstract_declarator (TREE_TYPE (t));
1791 if (TREE_CODE (t) == METHOD_TYPE)
1792 {
1793 padding = pp_before;
1794 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1795 }
1796 pp_cxx_exception_specification (this, t);
1797 break;
1798
1799 case TYPENAME_TYPE:
1800 case TEMPLATE_TYPE_PARM:
1801 case TEMPLATE_TEMPLATE_PARM:
1802 case BOUND_TEMPLATE_TEMPLATE_PARM:
1803 case UNBOUND_CLASS_TEMPLATE:
1804 case DECLTYPE_TYPE:
1805 break;
1806
1807 default:
1808 c_pretty_printer::direct_abstract_declarator (t);
1809 break;
1810 }
1811 }
1812
1813 /* type-id:
1814 type-specifier-seq abstract-declarator(opt) */
1815
1816 void
1817 cxx_pretty_printer::type_id (tree t)
1818 {
1819 pp_flags saved_flags = flags;
1820 flags |= pp_c_flag_abstract;
1821
1822 switch (TREE_CODE (t))
1823 {
1824 case TYPE_DECL:
1825 case UNION_TYPE:
1826 case RECORD_TYPE:
1827 case ENUMERAL_TYPE:
1828 case TYPENAME_TYPE:
1829 case BOUND_TEMPLATE_TEMPLATE_PARM:
1830 case UNBOUND_CLASS_TEMPLATE:
1831 case TEMPLATE_TEMPLATE_PARM:
1832 case TEMPLATE_TYPE_PARM:
1833 case TEMPLATE_PARM_INDEX:
1834 case TEMPLATE_DECL:
1835 case TYPEOF_TYPE:
1836 case UNDERLYING_TYPE:
1837 case DECLTYPE_TYPE:
1838 case TEMPLATE_ID_EXPR:
1839 pp_cxx_type_specifier_seq (this, t);
1840 break;
1841
1842 case TYPE_PACK_EXPANSION:
1843 type_id (PACK_EXPANSION_PATTERN (t));
1844 pp_cxx_ws_string (this, "...");
1845 break;
1846
1847 case TYPE_ARGUMENT_PACK:
1848 {
1849 tree args = ARGUMENT_PACK_ARGS (t);
1850 int len = TREE_VEC_LENGTH (args);
1851 pp_cxx_left_brace (this);
1852 for (int i = 0; i < len; ++i)
1853 {
1854 if (i > 0)
1855 pp_cxx_separate_with (this, ',');
1856 type_id (TREE_VEC_ELT (args, i));
1857 }
1858 pp_cxx_right_brace (this);
1859 }
1860 break;
1861
1862 default:
1863 c_pretty_printer::type_id (t);
1864 break;
1865 }
1866
1867 flags = saved_flags;
1868 }
1869
1870 /* template-argument-list:
1871 template-argument ...(opt)
1872 template-argument-list, template-argument ...(opt)
1873
1874 template-argument:
1875 assignment-expression
1876 type-id
1877 template-name */
1878
1879 static void
1880 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1881 {
1882 int i;
1883 bool need_comma = false;
1884
1885 if (t == NULL)
1886 return;
1887 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1888 {
1889 tree arg = TREE_VEC_ELT (t, i);
1890 tree argpack = NULL_TREE;
1891 int idx, len = 1;
1892
1893 if (ARGUMENT_PACK_P (arg))
1894 {
1895 argpack = ARGUMENT_PACK_ARGS (arg);
1896 len = TREE_VEC_LENGTH (argpack);
1897 }
1898
1899 for (idx = 0; idx < len; idx++)
1900 {
1901 if (argpack)
1902 arg = TREE_VEC_ELT (argpack, idx);
1903
1904 if (need_comma)
1905 pp_cxx_separate_with (pp, ',');
1906 else
1907 need_comma = true;
1908
1909 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1910 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1911 pp->type_id (arg);
1912 else
1913 pp->expression (arg);
1914 }
1915 }
1916 }
1917
1918
1919 static void
1920 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1921 {
1922 t = DECL_EXPR_DECL (t);
1923 pp_cxx_type_specifier_seq (pp, t);
1924 if (TYPE_P (t))
1925 pp->abstract_declarator (t);
1926 else
1927 pp->declarator (t);
1928 }
1929
1930 /* Statements. */
1931
1932 void
1933 cxx_pretty_printer::statement (tree t)
1934 {
1935 switch (TREE_CODE (t))
1936 {
1937 case CTOR_INITIALIZER:
1938 pp_cxx_ctor_initializer (this, t);
1939 break;
1940
1941 case USING_STMT:
1942 pp_cxx_ws_string (this, "using");
1943 pp_cxx_ws_string (this, "namespace");
1944 if (DECL_CONTEXT (t))
1945 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1946 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1947 break;
1948
1949 case USING_DECL:
1950 pp_cxx_ws_string (this, "using");
1951 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
1952 pp_cxx_unqualified_id (this, DECL_NAME (t));
1953 break;
1954
1955 case EH_SPEC_BLOCK:
1956 break;
1957
1958 /* try-block:
1959 try compound-statement handler-seq */
1960 case TRY_BLOCK:
1961 pp_maybe_newline_and_indent (this, 0);
1962 pp_cxx_ws_string (this, "try");
1963 pp_newline_and_indent (this, 3);
1964 statement (TRY_STMTS (t));
1965 pp_newline_and_indent (this, -3);
1966 if (CLEANUP_P (t))
1967 ;
1968 else
1969 statement (TRY_HANDLERS (t));
1970 break;
1971
1972 /*
1973 handler-seq:
1974 handler handler-seq(opt)
1975
1976 handler:
1977 catch ( exception-declaration ) compound-statement
1978
1979 exception-declaration:
1980 type-specifier-seq declarator
1981 type-specifier-seq abstract-declarator
1982 ... */
1983 case HANDLER:
1984 pp_cxx_ws_string (this, "catch");
1985 pp_cxx_left_paren (this);
1986 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
1987 pp_cxx_right_paren (this);
1988 pp_indentation (this) += 3;
1989 pp_needs_newline (this) = true;
1990 statement (HANDLER_BODY (t));
1991 pp_indentation (this) -= 3;
1992 pp_needs_newline (this) = true;
1993 break;
1994
1995 /* selection-statement:
1996 if ( expression ) statement
1997 if ( expression ) statement else statement */
1998 case IF_STMT:
1999 pp_cxx_ws_string (this, "if");
2000 pp_cxx_whitespace (this);
2001 pp_cxx_left_paren (this);
2002 expression (IF_COND (t));
2003 pp_cxx_right_paren (this);
2004 pp_newline_and_indent (this, 2);
2005 statement (THEN_CLAUSE (t));
2006 pp_newline_and_indent (this, -2);
2007 if (ELSE_CLAUSE (t))
2008 {
2009 tree else_clause = ELSE_CLAUSE (t);
2010 pp_cxx_ws_string (this, "else");
2011 if (TREE_CODE (else_clause) == IF_STMT)
2012 pp_cxx_whitespace (this);
2013 else
2014 pp_newline_and_indent (this, 2);
2015 statement (else_clause);
2016 if (TREE_CODE (else_clause) != IF_STMT)
2017 pp_newline_and_indent (this, -2);
2018 }
2019 break;
2020
2021 case SWITCH_STMT:
2022 pp_cxx_ws_string (this, "switch");
2023 pp_space (this);
2024 pp_cxx_left_paren (this);
2025 expression (SWITCH_STMT_COND (t));
2026 pp_cxx_right_paren (this);
2027 pp_indentation (this) += 3;
2028 pp_needs_newline (this) = true;
2029 statement (SWITCH_STMT_BODY (t));
2030 pp_newline_and_indent (this, -3);
2031 break;
2032
2033 /* iteration-statement:
2034 while ( expression ) statement
2035 do statement while ( expression ) ;
2036 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
2037 for ( declaration expression(opt) ; expression(opt) ) statement */
2038 case WHILE_STMT:
2039 pp_cxx_ws_string (this, "while");
2040 pp_space (this);
2041 pp_cxx_left_paren (this);
2042 expression (WHILE_COND (t));
2043 pp_cxx_right_paren (this);
2044 pp_newline_and_indent (this, 3);
2045 statement (WHILE_BODY (t));
2046 pp_indentation (this) -= 3;
2047 pp_needs_newline (this) = true;
2048 break;
2049
2050 case DO_STMT:
2051 pp_cxx_ws_string (this, "do");
2052 pp_newline_and_indent (this, 3);
2053 statement (DO_BODY (t));
2054 pp_newline_and_indent (this, -3);
2055 pp_cxx_ws_string (this, "while");
2056 pp_space (this);
2057 pp_cxx_left_paren (this);
2058 expression (DO_COND (t));
2059 pp_cxx_right_paren (this);
2060 pp_cxx_semicolon (this);
2061 pp_needs_newline (this) = true;
2062 break;
2063
2064 case FOR_STMT:
2065 pp_cxx_ws_string (this, "for");
2066 pp_space (this);
2067 pp_cxx_left_paren (this);
2068 if (FOR_INIT_STMT (t))
2069 statement (FOR_INIT_STMT (t));
2070 else
2071 pp_cxx_semicolon (this);
2072 pp_needs_newline (this) = false;
2073 pp_cxx_whitespace (this);
2074 if (FOR_COND (t))
2075 expression (FOR_COND (t));
2076 pp_cxx_semicolon (this);
2077 pp_needs_newline (this) = false;
2078 pp_cxx_whitespace (this);
2079 if (FOR_EXPR (t))
2080 expression (FOR_EXPR (t));
2081 pp_cxx_right_paren (this);
2082 pp_newline_and_indent (this, 3);
2083 statement (FOR_BODY (t));
2084 pp_indentation (this) -= 3;
2085 pp_needs_newline (this) = true;
2086 break;
2087
2088 case RANGE_FOR_STMT:
2089 pp_cxx_ws_string (this, "for");
2090 pp_space (this);
2091 pp_cxx_left_paren (this);
2092 if (RANGE_FOR_INIT_STMT (t))
2093 {
2094 statement (RANGE_FOR_INIT_STMT (t));
2095 pp_needs_newline (this) = false;
2096 pp_cxx_whitespace (this);
2097 }
2098 statement (RANGE_FOR_DECL (t));
2099 pp_space (this);
2100 pp_needs_newline (this) = false;
2101 pp_colon (this);
2102 pp_space (this);
2103 statement (RANGE_FOR_EXPR (t));
2104 pp_cxx_right_paren (this);
2105 pp_newline_and_indent (this, 3);
2106 statement (FOR_BODY (t));
2107 pp_indentation (this) -= 3;
2108 pp_needs_newline (this) = true;
2109 break;
2110
2111 /* jump-statement:
2112 goto identifier;
2113 continue ;
2114 return expression(opt) ; */
2115 case BREAK_STMT:
2116 case CONTINUE_STMT:
2117 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2118 pp_cxx_semicolon (this);
2119 pp_needs_newline (this) = true;
2120 break;
2121
2122 /* expression-statement:
2123 expression(opt) ; */
2124 case EXPR_STMT:
2125 expression (EXPR_STMT_EXPR (t));
2126 pp_cxx_semicolon (this);
2127 pp_needs_newline (this) = true;
2128 break;
2129
2130 case CLEANUP_STMT:
2131 pp_cxx_ws_string (this, "try");
2132 pp_newline_and_indent (this, 2);
2133 statement (CLEANUP_BODY (t));
2134 pp_newline_and_indent (this, -2);
2135 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2136 pp_newline_and_indent (this, 2);
2137 statement (CLEANUP_EXPR (t));
2138 pp_newline_and_indent (this, -2);
2139 break;
2140
2141 case STATIC_ASSERT:
2142 declaration (t);
2143 break;
2144
2145 case OMP_DEPOBJ:
2146 pp_cxx_ws_string (this, "#pragma omp depobj");
2147 pp_space (this);
2148 pp_cxx_left_paren (this);
2149 expression (OMP_DEPOBJ_DEPOBJ (t));
2150 pp_cxx_right_paren (this);
2151 if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
2152 {
2153 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
2154 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t),
2155 pp_indentation (this), TDF_NONE);
2156 else
2157 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2158 {
2159 case OMP_CLAUSE_DEPEND_IN:
2160 pp_cxx_ws_string (this, " update(in)");
2161 break;
2162 case OMP_CLAUSE_DEPEND_INOUT:
2163 pp_cxx_ws_string (this, " update(inout)");
2164 break;
2165 case OMP_CLAUSE_DEPEND_OUT:
2166 pp_cxx_ws_string (this, " update(out)");
2167 break;
2168 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2169 pp_cxx_ws_string (this, " update(mutexinoutset)");
2170 break;
2171 case OMP_CLAUSE_DEPEND_LAST:
2172 pp_cxx_ws_string (this, " destroy");
2173 break;
2174 default:
2175 break;
2176 }
2177 }
2178 pp_needs_newline (this) = true;
2179 break;
2180
2181 default:
2182 c_pretty_printer::statement (t);
2183 break;
2184 }
2185 }
2186
2187 /* original-namespace-definition:
2188 namespace identifier { namespace-body }
2189
2190 As an edge case, we also handle unnamed namespace definition here. */
2191
2192 static void
2193 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2194 {
2195 pp_cxx_ws_string (pp, "namespace");
2196 if (DECL_CONTEXT (t))
2197 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2198 if (DECL_NAME (t))
2199 pp_cxx_unqualified_id (pp, t);
2200 pp_cxx_whitespace (pp);
2201 pp_cxx_left_brace (pp);
2202 /* We do not print the namespace-body. */
2203 pp_cxx_whitespace (pp);
2204 pp_cxx_right_brace (pp);
2205 }
2206
2207 /* namespace-alias:
2208 identifier
2209
2210 namespace-alias-definition:
2211 namespace identifier = qualified-namespace-specifier ;
2212
2213 qualified-namespace-specifier:
2214 ::(opt) nested-name-specifier(opt) namespace-name */
2215
2216 static void
2217 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2218 {
2219 pp_cxx_ws_string (pp, "namespace");
2220 if (DECL_CONTEXT (t))
2221 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2222 pp_cxx_unqualified_id (pp, t);
2223 pp_cxx_whitespace (pp);
2224 pp_equal (pp);
2225 pp_cxx_whitespace (pp);
2226 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2227 pp_cxx_nested_name_specifier (pp,
2228 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2229 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2230 pp_cxx_semicolon (pp);
2231 }
2232
2233 /* simple-declaration:
2234 decl-specifier-seq(opt) init-declarator-list(opt) */
2235
2236 static void
2237 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2238 {
2239 pp->declaration_specifiers (t);
2240 pp_cxx_init_declarator (pp, t);
2241 pp_cxx_semicolon (pp);
2242 pp_needs_newline (pp) = true;
2243 }
2244
2245 /*
2246 template-parameter-list:
2247 template-parameter
2248 template-parameter-list , template-parameter */
2249
2250 static inline void
2251 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2252 {
2253 const int n = TREE_VEC_LENGTH (t);
2254 int i;
2255 for (i = 0; i < n; ++i)
2256 {
2257 if (i)
2258 pp_cxx_separate_with (pp, ',');
2259 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2260 }
2261 }
2262
2263 /* template-parameter:
2264 type-parameter
2265 parameter-declaration
2266
2267 type-parameter:
2268 class ...(opt) identifier(opt)
2269 class identifier(opt) = type-id
2270 typename identifier(opt)
2271 typename ...(opt) identifier(opt) = type-id
2272 template < template-parameter-list > class ...(opt) identifier(opt)
2273 template < template-parameter-list > class identifier(opt) = template-name */
2274
2275 static void
2276 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2277 {
2278 tree parameter = TREE_VALUE (t);
2279 switch (TREE_CODE (parameter))
2280 {
2281 case TYPE_DECL:
2282 pp_cxx_ws_string (pp, "class");
2283 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2284 pp_cxx_ws_string (pp, "...");
2285 if (DECL_NAME (parameter))
2286 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2287 /* FIXME: Check if we should print also default argument. */
2288 break;
2289
2290 case PARM_DECL:
2291 pp_cxx_parameter_declaration (pp, parameter);
2292 break;
2293
2294 case TEMPLATE_DECL:
2295 break;
2296
2297 default:
2298 pp_unsupported_tree (pp, t);
2299 break;
2300 }
2301 }
2302
2303 /* Pretty-print a template parameter in the canonical form
2304 "template-parameter-<level>-<position in parameter list>". */
2305
2306 void
2307 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2308 {
2309 const enum tree_code code = TREE_CODE (parm);
2310
2311 /* Brings type template parameters to the canonical forms. */
2312 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2313 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2314 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2315
2316 pp_cxx_begin_template_argument_list (pp);
2317 pp->translate_string ("template-parameter-");
2318 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2319 pp_minus (pp);
2320 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2321 pp_cxx_end_template_argument_list (pp);
2322 }
2323
2324 /* Print a constrained-type-specifier. */
2325
2326 void
2327 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2328 {
2329 pp_cxx_whitespace (pp);
2330 pp_cxx_left_bracket (pp);
2331 pp->translate_string ("requires");
2332 pp_cxx_whitespace (pp);
2333 if (c == error_mark_node)
2334 {
2335 pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
2336 return;
2337 }
2338 tree t, a;
2339 placeholder_extract_concept_and_args (c, t, a);
2340 pp->id_expression (t);
2341 pp_cxx_begin_template_argument_list (pp);
2342 pp_cxx_ws_string (pp, "<placeholder>");
2343 pp_cxx_separate_with (pp, ',');
2344 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2345 for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i)
2346 TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1);
2347 pp_cxx_template_argument_list (pp, args);
2348 ggc_free (args);
2349 pp_cxx_end_template_argument_list (pp);
2350 pp_cxx_right_bracket (pp);
2351 }
2352
2353 /*
2354 template-declaration:
2355 export(opt) template < template-parameter-list > declaration
2356
2357 Concept extensions:
2358
2359 template-declaration:
2360 export(opt) template < template-parameter-list >
2361 requires-clause(opt) declaration */
2362
2363 static void
2364 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2365 {
2366 tree tmpl = most_general_template (t);
2367 tree level;
2368
2369 pp_maybe_newline_and_indent (pp, 0);
2370 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2371 {
2372 pp_cxx_ws_string (pp, "template");
2373 pp_cxx_begin_template_argument_list (pp);
2374 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2375 pp_cxx_end_template_argument_list (pp);
2376 pp_newline_and_indent (pp, 3);
2377 }
2378
2379 if (flag_concepts)
2380 if (tree ci = get_constraints (t))
2381 if (tree reqs = CI_TEMPLATE_REQS (ci))
2382 {
2383 pp_cxx_requires_clause (pp, reqs);
2384 pp_newline_and_indent (pp, 6);
2385 }
2386
2387 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2388 pp_cxx_function_definition (pp, t);
2389 else if (TREE_CODE (t) == CONCEPT_DECL)
2390 pp_cxx_concept_definition (pp, t);
2391 else
2392 pp_cxx_simple_declaration (pp, t);
2393 }
2394
2395 static void
2396 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2397 {
2398 pp_unsupported_tree (pp, t);
2399 }
2400
2401 static void
2402 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2403 {
2404 pp_unsupported_tree (pp, t);
2405 }
2406
2407 static void
2408 pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t)
2409 {
2410 pp_cxx_unqualified_id (pp, DECL_NAME (t));
2411 pp_cxx_whitespace (pp);
2412 pp_cxx_ws_string (pp, "=");
2413 pp_cxx_whitespace (pp);
2414 pp->expression (DECL_INITIAL (t));
2415 pp_cxx_semicolon (pp);
2416 }
2417
2418 /*
2419 declaration:
2420 block-declaration
2421 function-definition
2422 template-declaration
2423 explicit-instantiation
2424 explicit-specialization
2425 linkage-specification
2426 namespace-definition
2427
2428 block-declaration:
2429 simple-declaration
2430 asm-definition
2431 namespace-alias-definition
2432 using-declaration
2433 using-directive
2434 static_assert-declaration */
2435 void
2436 cxx_pretty_printer::declaration (tree t)
2437 {
2438 if (TREE_CODE (t) == STATIC_ASSERT)
2439 {
2440 pp_cxx_ws_string (this, "static_assert");
2441 pp_cxx_left_paren (this);
2442 expression (STATIC_ASSERT_CONDITION (t));
2443 pp_cxx_separate_with (this, ',');
2444 expression (STATIC_ASSERT_MESSAGE (t));
2445 pp_cxx_right_paren (this);
2446 }
2447 else if (!DECL_LANG_SPECIFIC (t))
2448 pp_cxx_simple_declaration (this, t);
2449 else if (DECL_USE_TEMPLATE (t))
2450 switch (DECL_USE_TEMPLATE (t))
2451 {
2452 case 1:
2453 pp_cxx_template_declaration (this, t);
2454 break;
2455
2456 case 2:
2457 pp_cxx_explicit_specialization (this, t);
2458 break;
2459
2460 case 3:
2461 pp_cxx_explicit_instantiation (this, t);
2462 break;
2463
2464 default:
2465 break;
2466 }
2467 else switch (TREE_CODE (t))
2468 {
2469 case VAR_DECL:
2470 case TYPE_DECL:
2471 pp_cxx_simple_declaration (this, t);
2472 break;
2473
2474 case FUNCTION_DECL:
2475 if (DECL_SAVED_TREE (t))
2476 pp_cxx_function_definition (this, t);
2477 else
2478 pp_cxx_simple_declaration (this, t);
2479 break;
2480
2481 case NAMESPACE_DECL:
2482 if (DECL_NAMESPACE_ALIAS (t))
2483 pp_cxx_namespace_alias_definition (this, t);
2484 else
2485 pp_cxx_original_namespace_definition (this, t);
2486 break;
2487
2488 default:
2489 pp_unsupported_tree (this, t);
2490 break;
2491 }
2492 }
2493
2494 static void
2495 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2496 {
2497 t = TREE_OPERAND (t, 0);
2498 pp_cxx_ws_string (pp, "typeid");
2499 pp_cxx_left_paren (pp);
2500 if (TYPE_P (t))
2501 pp->type_id (t);
2502 else
2503 pp->expression (t);
2504 pp_cxx_right_paren (pp);
2505 }
2506
2507 void
2508 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2509 {
2510 pp_cxx_ws_string (pp, "va_arg");
2511 pp_cxx_left_paren (pp);
2512 pp->assignment_expression (TREE_OPERAND (t, 0));
2513 pp_cxx_separate_with (pp, ',');
2514 pp->type_id (TREE_TYPE (t));
2515 pp_cxx_right_paren (pp);
2516 }
2517
2518 static bool
2519 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2520 {
2521 switch (TREE_CODE (t))
2522 {
2523 case ARROW_EXPR:
2524 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2525 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2526 {
2527 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2528 pp_cxx_separate_with (pp, ',');
2529 return true;
2530 }
2531 return false;
2532 case COMPONENT_REF:
2533 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2534 return false;
2535 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2536 pp_cxx_dot (pp);
2537 pp->expression (TREE_OPERAND (t, 1));
2538 return true;
2539 case ARRAY_REF:
2540 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2541 return false;
2542 pp_left_bracket (pp);
2543 pp->expression (TREE_OPERAND (t, 1));
2544 pp_right_bracket (pp);
2545 return true;
2546 default:
2547 return false;
2548 }
2549 }
2550
2551 void
2552 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2553 {
2554 pp_cxx_ws_string (pp, "offsetof");
2555 pp_cxx_left_paren (pp);
2556 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2557 pp->expression (TREE_OPERAND (t, 0));
2558 pp_cxx_right_paren (pp);
2559 }
2560
2561 void
2562 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2563 {
2564 pp_cxx_ws_string (pp, "__builtin_addressof");
2565 pp_cxx_left_paren (pp);
2566 pp->expression (TREE_OPERAND (t, 0));
2567 pp_cxx_right_paren (pp);
2568 }
2569
2570 static char const*
2571 get_fold_operator (tree t)
2572 {
2573 int op = int_cst_value (FOLD_EXPR_OP (t));
2574 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t), op);
2575 return info->name;
2576 }
2577
2578 void
2579 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2580 {
2581 char const* op = get_fold_operator (t);
2582 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2583 pp_cxx_left_paren (pp);
2584 pp_cxx_ws_string (pp, "...");
2585 pp_cxx_ws_string (pp, op);
2586 pp->expression (expr);
2587 pp_cxx_right_paren (pp);
2588 }
2589
2590 void
2591 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2592 {
2593 char const* op = get_fold_operator (t);
2594 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2595 pp_cxx_left_paren (pp);
2596 pp->expression (expr);
2597 pp_space (pp);
2598 pp_cxx_ws_string (pp, op);
2599 pp_cxx_ws_string (pp, "...");
2600 pp_cxx_right_paren (pp);
2601 }
2602
2603 void
2604 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2605 {
2606 char const* op = get_fold_operator (t);
2607 tree t1 = TREE_OPERAND (t, 1);
2608 tree t2 = TREE_OPERAND (t, 2);
2609 if (t1 == FOLD_EXPR_PACK (t))
2610 t1 = PACK_EXPANSION_PATTERN (t1);
2611 else
2612 t2 = PACK_EXPANSION_PATTERN (t2);
2613 pp_cxx_left_paren (pp);
2614 pp->expression (t1);
2615 pp_cxx_ws_string (pp, op);
2616 pp_cxx_ws_string (pp, "...");
2617 pp_cxx_ws_string (pp, op);
2618 pp->expression (t2);
2619 pp_cxx_right_paren (pp);
2620 }
2621
2622 void
2623 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2624 {
2625 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2626
2627 switch (kind)
2628 {
2629 case CPTK_HAS_NOTHROW_ASSIGN:
2630 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2631 break;
2632 case CPTK_HAS_TRIVIAL_ASSIGN:
2633 pp_cxx_ws_string (pp, "__has_trivial_assign");
2634 break;
2635 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2636 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2637 break;
2638 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2639 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2640 break;
2641 case CPTK_HAS_NOTHROW_COPY:
2642 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2643 break;
2644 case CPTK_HAS_TRIVIAL_COPY:
2645 pp_cxx_ws_string (pp, "__has_trivial_copy");
2646 break;
2647 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2648 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2649 break;
2650 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
2651 pp_cxx_ws_string (pp, "__has_unique_object_representations");
2652 break;
2653 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2654 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2655 break;
2656 case CPTK_IS_ABSTRACT:
2657 pp_cxx_ws_string (pp, "__is_abstract");
2658 break;
2659 case CPTK_IS_AGGREGATE:
2660 pp_cxx_ws_string (pp, "__is_aggregate");
2661 break;
2662 case CPTK_IS_BASE_OF:
2663 pp_cxx_ws_string (pp, "__is_base_of");
2664 break;
2665 case CPTK_IS_CLASS:
2666 pp_cxx_ws_string (pp, "__is_class");
2667 break;
2668 case CPTK_IS_EMPTY:
2669 pp_cxx_ws_string (pp, "__is_empty");
2670 break;
2671 case CPTK_IS_ENUM:
2672 pp_cxx_ws_string (pp, "__is_enum");
2673 break;
2674 case CPTK_IS_FINAL:
2675 pp_cxx_ws_string (pp, "__is_final");
2676 break;
2677 case CPTK_IS_POD:
2678 pp_cxx_ws_string (pp, "__is_pod");
2679 break;
2680 case CPTK_IS_POLYMORPHIC:
2681 pp_cxx_ws_string (pp, "__is_polymorphic");
2682 break;
2683 case CPTK_IS_SAME_AS:
2684 pp_cxx_ws_string (pp, "__is_same");
2685 break;
2686 case CPTK_IS_STD_LAYOUT:
2687 pp_cxx_ws_string (pp, "__is_std_layout");
2688 break;
2689 case CPTK_IS_TRIVIAL:
2690 pp_cxx_ws_string (pp, "__is_trivial");
2691 break;
2692 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2693 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2694 break;
2695 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2696 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2697 break;
2698 case CPTK_IS_TRIVIALLY_COPYABLE:
2699 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2700 break;
2701 case CPTK_IS_UNION:
2702 pp_cxx_ws_string (pp, "__is_union");
2703 break;
2704 case CPTK_IS_LITERAL_TYPE:
2705 pp_cxx_ws_string (pp, "__is_literal_type");
2706 break;
2707 case CPTK_IS_ASSIGNABLE:
2708 pp_cxx_ws_string (pp, "__is_assignable");
2709 break;
2710 case CPTK_IS_CONSTRUCTIBLE:
2711 pp_cxx_ws_string (pp, "__is_constructible");
2712 break;
2713
2714 default:
2715 gcc_unreachable ();
2716 }
2717
2718 pp_cxx_left_paren (pp);
2719 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2720
2721 if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2722 {
2723 pp_cxx_separate_with (pp, ',');
2724 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2725 }
2726
2727 pp_cxx_right_paren (pp);
2728 }
2729
2730 // requires-clause:
2731 // 'requires' logical-or-expression
2732 void
2733 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2734 {
2735 if (!t)
2736 return;
2737 pp->padding = pp_before;
2738 pp_cxx_ws_string (pp, "requires");
2739 pp_space (pp);
2740 pp->expression (t);
2741 }
2742
2743 /* requirement:
2744 simple-requirement
2745 compound-requirement
2746 type-requirement
2747 nested-requirement */
2748 static void
2749 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2750 {
2751 switch (TREE_CODE (t))
2752 {
2753 case SIMPLE_REQ:
2754 pp_cxx_simple_requirement (pp, t);
2755 break;
2756
2757 case TYPE_REQ:
2758 pp_cxx_type_requirement (pp, t);
2759 break;
2760
2761 case COMPOUND_REQ:
2762 pp_cxx_compound_requirement (pp, t);
2763 break;
2764
2765 case NESTED_REQ:
2766 pp_cxx_nested_requirement (pp, t);
2767 break;
2768
2769 default:
2770 gcc_unreachable ();
2771 }
2772 }
2773
2774 // requirement-list:
2775 // requirement
2776 // requirement-list ';' requirement[opt]
2777 //
2778 static void
2779 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2780 {
2781 for (; t; t = TREE_CHAIN (t))
2782 pp_cxx_requirement (pp, TREE_VALUE (t));
2783 }
2784
2785 // requirement-body:
2786 // '{' requirement-list '}'
2787 static void
2788 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2789 {
2790 pp_cxx_left_brace (pp);
2791 pp_cxx_requirement_list (pp, t);
2792 pp_cxx_right_brace (pp);
2793 }
2794
2795 // requires-expression:
2796 // 'requires' requirement-parameter-list requirement-body
2797 void
2798 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2799 {
2800 pp_string (pp, "requires");
2801 if (tree parms = TREE_OPERAND (t, 0))
2802 {
2803 pp_cxx_parameter_declaration_clause (pp, parms);
2804 pp_cxx_whitespace (pp);
2805 }
2806 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2807 }
2808
2809 /* simple-requirement:
2810 expression ';' */
2811 void
2812 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2813 {
2814 pp->expression (TREE_OPERAND (t, 0));
2815 pp_cxx_semicolon (pp);
2816 }
2817
2818 /* type-requirement:
2819 typename type-name ';' */
2820 void
2821 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2822 {
2823 pp->type_id (TREE_OPERAND (t, 0));
2824 pp_cxx_semicolon (pp);
2825 }
2826
2827 /* compound-requirement:
2828 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2829 void
2830 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2831 {
2832 pp_cxx_left_brace (pp);
2833 pp->expression (TREE_OPERAND (t, 0));
2834 pp_cxx_right_brace (pp);
2835
2836 if (COMPOUND_REQ_NOEXCEPT_P (t))
2837 pp_cxx_ws_string (pp, "noexcept");
2838
2839 if (tree type = TREE_OPERAND (t, 1))
2840 {
2841 pp_cxx_whitespace (pp);
2842 pp_cxx_ws_string (pp, "->");
2843 pp->type_id (type);
2844 }
2845 pp_cxx_semicolon (pp);
2846 }
2847
2848 /* nested requirement:
2849 'requires' constraint-expression */
2850 void
2851 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2852 {
2853 pp_cxx_ws_string (pp, "requires");
2854 pp->expression (TREE_OPERAND (t, 0));
2855 pp_cxx_semicolon (pp);
2856 }
2857
2858 void
2859 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2860 {
2861 tree decl = CHECK_CONSTR_CONCEPT (t);
2862 tree tmpl = DECL_TI_TEMPLATE (decl);
2863 tree args = CHECK_CONSTR_ARGS (t);
2864 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2865
2866 if (TREE_CODE (decl) == CONCEPT_DECL)
2867 pp->expression (id);
2868 else if (VAR_P (decl))
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 ();
2879 }
2880
2881 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2882 constraint. */
2883
2884 void
2885 pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map)
2886 {
2887 pp_cxx_whitespace (pp);
2888 pp_cxx_left_bracket (pp);
2889 pp->translate_string ("with");
2890 pp_cxx_whitespace (pp);
2891
2892 for (tree p = map; p; p = TREE_CHAIN (p))
2893 {
2894 tree parm = TREE_VALUE (p);
2895 tree arg = TREE_PURPOSE (p);
2896
2897 if (TYPE_P (parm))
2898 pp->type_id (parm);
2899 else
2900 pp_cxx_tree_identifier (pp, DECL_NAME (TEMPLATE_PARM_DECL (parm)));
2901
2902 pp_cxx_whitespace (pp);
2903 pp_equal (pp);
2904 pp_cxx_whitespace (pp);
2905
2906 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2907 pp->type_id (arg);
2908 else
2909 pp->expression (arg);
2910
2911 if (TREE_CHAIN (p) != NULL_TREE)
2912 pp_cxx_separate_with (pp, ';');
2913 }
2914
2915 pp_cxx_right_bracket (pp);
2916 }
2917
2918 void
2919 pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t)
2920 {
2921 /* Emit the expression. */
2922 pp->expression (ATOMIC_CONSTR_EXPR (t));
2923
2924 /* Emit the parameter mapping. */
2925 tree map = ATOMIC_CONSTR_MAP (t);
2926 if (map && map != error_mark_node)
2927 pp_cxx_parameter_mapping (pp, map);
2928 }
2929
2930 void
2931 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2932 {
2933 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2934 pp_string (pp, " /\\ ");
2935 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2936 }
2937
2938 void
2939 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2940 {
2941 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2942 pp_string (pp, " \\/ ");
2943 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2944 }
2945
2946 void
2947 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2948 {
2949 if (t == error_mark_node)
2950 return pp->expression (t);
2951
2952 switch (TREE_CODE (t))
2953 {
2954 case ATOMIC_CONSTR:
2955 pp_cxx_atomic_constraint (pp, t);
2956 break;
2957
2958 case CHECK_CONSTR:
2959 pp_cxx_check_constraint (pp, t);
2960 break;
2961
2962 case CONJ_CONSTR:
2963 pp_cxx_conjunction (pp, t);
2964 break;
2965
2966 case DISJ_CONSTR:
2967 pp_cxx_disjunction (pp, t);
2968 break;
2969
2970 case EXPR_PACK_EXPANSION:
2971 pp->expression (TREE_OPERAND (t, 0));
2972 break;
2973
2974 default:
2975 gcc_unreachable ();
2976 }
2977 }
2978
2979 \f
2980 typedef c_pretty_print_fn pp_fun;
2981
2982 /* Initialization of a C++ pretty-printer object. */
2983
2984 cxx_pretty_printer::cxx_pretty_printer ()
2985 : c_pretty_printer (),
2986 enclosing_scope (global_namespace)
2987 {
2988 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2989 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2990 }
2991
2992 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2993
2994 pretty_printer *
2995 cxx_pretty_printer::clone () const
2996 {
2997 return new cxx_pretty_printer (*this);
2998 }