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