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