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