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