1 /* Implementation of subroutines for the GNU C++ pretty-printer.
2 Copyright (C) 2003-2022 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "cp-tree.h"
25 #include "cxx-pretty-print.h"
26 #include "tree-pretty-print.h"
27
28 static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
29 static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
30 static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
31 static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
32 static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
33 static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
34 static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
35 static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
36 static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
37 static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
38 static void pp_cxx_unary_left_fold_expression (cxx_pretty_printer *, tree);
39 static void pp_cxx_unary_right_fold_expression (cxx_pretty_printer *, tree);
40 static void pp_cxx_binary_fold_expression (cxx_pretty_printer *, tree);
41 static void pp_cxx_concept_definition (cxx_pretty_printer *, tree);
42
43
44 static inline void
pp_cxx_nonconsecutive_character(cxx_pretty_printer * pp,int c)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
pp_cxx_colon_colon(cxx_pretty_printer * pp)65 pp_cxx_colon_colon (cxx_pretty_printer *pp)
66 {
67 pp_colon_colon (pp);
68 pp->padding = pp_none;
69 }
70
71 void
pp_cxx_begin_template_argument_list(cxx_pretty_printer * pp)72 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
73 {
74 pp_cxx_nonconsecutive_character (pp, '<');
75 }
76
77 void
pp_cxx_end_template_argument_list(cxx_pretty_printer * pp)78 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
79 {
80 pp_cxx_nonconsecutive_character (pp, '>');
81 }
82
83 void
pp_cxx_separate_with(cxx_pretty_printer * pp,int c)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
pp_cxx_conversion_function_id(cxx_pretty_printer * pp,tree t)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
pp_cxx_template_id(cxx_pretty_printer * pp,tree t)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
pp_cxx_unqualified_id(cxx_pretty_printer * pp,tree t)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
pp_cxx_template_keyword_if_needed(cxx_pretty_printer * pp,tree scope,tree t)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
pp_cxx_nested_name_specifier(cxx_pretty_printer * pp,tree t)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
pp_cxx_qualified_id(cxx_pretty_printer * pp,tree t)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
pp_cxx_enumeration_constant(cxx_pretty_printer * pp,tree e)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
constant(tree t)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
id_expression(tree t)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
pp_cxx_userdef_literal(cxx_pretty_printer * pp,tree t)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
primary_expression(tree t)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
postfix_expression(tree t)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 BIT_CAST_EXPR:
659 pp_cxx_ws_string (this, "__builtin_bit_cast");
660 pp_left_paren (this);
661 type_id (TREE_TYPE (t));
662 pp_comma (this);
663 expression (TREE_OPERAND (t, 0));
664 pp_right_paren (this);
665 break;
666
667 case EMPTY_CLASS_EXPR:
668 type_id (TREE_TYPE (t));
669 pp_left_paren (this);
670 pp_right_paren (this);
671 break;
672
673 case TYPEID_EXPR:
674 pp_cxx_typeid_expression (this, t);
675 break;
676
677 case PSEUDO_DTOR_EXPR:
678 postfix_expression (TREE_OPERAND (t, 0));
679 pp_cxx_dot (this);
680 if (TREE_OPERAND (t, 1))
681 {
682 pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
683 pp_cxx_colon_colon (this);
684 }
685 pp_complement (this);
686 pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
687 break;
688
689 case ARROW_EXPR:
690 postfix_expression (TREE_OPERAND (t, 0));
691 pp_cxx_arrow (this);
692 break;
693
694 default:
695 c_pretty_printer::postfix_expression (t);
696 break;
697 }
698 }
699
700 /* new-expression:
701 ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
702 ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
703
704 new-placement:
705 ( expression-list )
706
707 new-type-id:
708 type-specifier-seq new-declarator(opt)
709
710 new-declarator:
711 ptr-operator new-declarator(opt)
712 direct-new-declarator
713
714 direct-new-declarator
715 [ expression ]
716 direct-new-declarator [ constant-expression ]
717
718 new-initializer:
719 ( expression-list(opt) ) */
720
721 static void
pp_cxx_new_expression(cxx_pretty_printer * pp,tree t)722 pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
723 {
724 enum tree_code code = TREE_CODE (t);
725 tree type = TREE_OPERAND (t, 1);
726 tree init = TREE_OPERAND (t, 2);
727 switch (code)
728 {
729 case NEW_EXPR:
730 case VEC_NEW_EXPR:
731 if (NEW_EXPR_USE_GLOBAL (t))
732 pp_cxx_colon_colon (pp);
733 pp_cxx_ws_string (pp, "new");
734 if (TREE_OPERAND (t, 0))
735 {
736 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
737 pp_space (pp);
738 }
739 if (TREE_CODE (type) == ARRAY_REF)
740 type = build_cplus_array_type
741 (TREE_OPERAND (type, 0),
742 build_index_type (fold_build2_loc (input_location,
743 MINUS_EXPR, integer_type_node,
744 TREE_OPERAND (type, 1),
745 integer_one_node)));
746 pp->type_id (type);
747 if (init)
748 {
749 pp_left_paren (pp);
750 if (TREE_CODE (init) == TREE_LIST)
751 pp_c_expression_list (pp, init);
752 else if (init == void_node)
753 ; /* OK, empty initializer list. */
754 else
755 pp->expression (init);
756 pp_right_paren (pp);
757 }
758 break;
759
760 default:
761 pp_unsupported_tree (pp, t);
762 }
763 }
764
765 /* delete-expression:
766 ::(opt) delete cast-expression
767 ::(opt) delete [ ] cast-expression */
768
769 static void
pp_cxx_delete_expression(cxx_pretty_printer * pp,tree t)770 pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
771 {
772 enum tree_code code = TREE_CODE (t);
773 switch (code)
774 {
775 case DELETE_EXPR:
776 case VEC_DELETE_EXPR:
777 if (DELETE_EXPR_USE_GLOBAL (t))
778 pp_cxx_colon_colon (pp);
779 pp_cxx_ws_string (pp, "delete");
780 pp_space (pp);
781 if (code == VEC_DELETE_EXPR
782 || DELETE_EXPR_USE_VEC (t))
783 {
784 pp_left_bracket (pp);
785 pp_right_bracket (pp);
786 pp_space (pp);
787 }
788 pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
789 break;
790
791 default:
792 pp_unsupported_tree (pp, t);
793 }
794 }
795
796 /* unary-expression:
797 postfix-expression
798 ++ cast-expression
799 -- cast-expression
800 unary-operator cast-expression
801 sizeof unary-expression
802 sizeof ( type-id )
803 sizeof ... ( identifier )
804 new-expression
805 delete-expression
806
807 unary-operator: one of
808 * & + - !
809
810 GNU extensions:
811 __alignof__ unary-expression
812 __alignof__ ( type-id ) */
813
814 void
unary_expression(tree t)815 cxx_pretty_printer::unary_expression (tree t)
816 {
817 enum tree_code code = TREE_CODE (t);
818 switch (code)
819 {
820 case NEW_EXPR:
821 case VEC_NEW_EXPR:
822 pp_cxx_new_expression (this, t);
823 break;
824
825 case DELETE_EXPR:
826 case VEC_DELETE_EXPR:
827 pp_cxx_delete_expression (this, t);
828 break;
829
830 case SIZEOF_EXPR:
831 if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
832 {
833 pp_cxx_ws_string (this, "sizeof");
834 pp_cxx_ws_string (this, "...");
835 pp_cxx_whitespace (this);
836 pp_cxx_left_paren (this);
837 if (TYPE_P (TREE_OPERAND (t, 0)))
838 type_id (TREE_OPERAND (t, 0));
839 else
840 unary_expression (TREE_OPERAND (t, 0));
841 pp_cxx_right_paren (this);
842 break;
843 }
844 /* Fall through */
845
846 case ALIGNOF_EXPR:
847 pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
848 pp_cxx_whitespace (this);
849 if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
850 {
851 pp_cxx_left_paren (this);
852 type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
853 pp_cxx_right_paren (this);
854 }
855 else if (TYPE_P (TREE_OPERAND (t, 0)))
856 {
857 pp_cxx_left_paren (this);
858 type_id (TREE_OPERAND (t, 0));
859 pp_cxx_right_paren (this);
860 }
861 else
862 unary_expression (TREE_OPERAND (t, 0));
863 break;
864
865 case AT_ENCODE_EXPR:
866 pp_cxx_ws_string (this, "@encode");
867 pp_cxx_whitespace (this);
868 pp_cxx_left_paren (this);
869 type_id (TREE_OPERAND (t, 0));
870 pp_cxx_right_paren (this);
871 break;
872
873 case NOEXCEPT_EXPR:
874 pp_cxx_ws_string (this, "noexcept");
875 pp_cxx_whitespace (this);
876 pp_cxx_left_paren (this);
877 expression (TREE_OPERAND (t, 0));
878 pp_cxx_right_paren (this);
879 break;
880
881 case UNARY_PLUS_EXPR:
882 pp_plus (this);
883 pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
884 break;
885
886 default:
887 c_pretty_printer::unary_expression (t);
888 break;
889 }
890 }
891
892 /* cast-expression:
893 unary-expression
894 ( type-id ) cast-expression */
895
896 static void
pp_cxx_cast_expression(cxx_pretty_printer * pp,tree t)897 pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
898 {
899 switch (TREE_CODE (t))
900 {
901 case CAST_EXPR:
902 case IMPLICIT_CONV_EXPR:
903 pp->type_id (TREE_TYPE (t));
904 pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
905 break;
906
907 default:
908 pp_c_cast_expression (pp, t);
909 break;
910 }
911 }
912
913 /* pm-expression:
914 cast-expression
915 pm-expression .* cast-expression
916 pm-expression ->* cast-expression */
917
918 static void
pp_cxx_pm_expression(cxx_pretty_printer * pp,tree t)919 pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
920 {
921 switch (TREE_CODE (t))
922 {
923 /* Handle unfortunate OFFSET_REF overloading here. */
924 case OFFSET_REF:
925 if (TYPE_P (TREE_OPERAND (t, 0)))
926 {
927 pp_cxx_qualified_id (pp, t);
928 break;
929 }
930 /* Fall through. */
931 case MEMBER_REF:
932 case DOTSTAR_EXPR:
933 pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
934 if (TREE_CODE (t) == MEMBER_REF)
935 pp_cxx_arrow (pp);
936 else
937 pp_cxx_dot (pp);
938 pp_star(pp);
939 pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
940 break;
941
942
943 default:
944 pp_cxx_cast_expression (pp, t);
945 break;
946 }
947 }
948
949 /* multiplicative-expression:
950 pm-expression
951 multiplicative-expression * pm-expression
952 multiplicative-expression / pm-expression
953 multiplicative-expression % pm-expression */
954
955 void
multiplicative_expression(tree e)956 cxx_pretty_printer::multiplicative_expression (tree e)
957 {
958 enum tree_code code = TREE_CODE (e);
959 switch (code)
960 {
961 case MULT_EXPR:
962 case TRUNC_DIV_EXPR:
963 case TRUNC_MOD_EXPR:
964 case EXACT_DIV_EXPR:
965 case RDIV_EXPR:
966 multiplicative_expression (TREE_OPERAND (e, 0));
967 pp_space (this);
968 if (code == MULT_EXPR)
969 pp_star (this);
970 else if (code != TRUNC_MOD_EXPR)
971 pp_slash (this);
972 else
973 pp_modulo (this);
974 pp_space (this);
975 pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
976 break;
977
978 default:
979 pp_cxx_pm_expression (this, e);
980 break;
981 }
982 }
983
984 /* conditional-expression:
985 logical-or-expression
986 logical-or-expression ? expression : assignment-expression */
987
988 void
conditional_expression(tree e)989 cxx_pretty_printer::conditional_expression (tree e)
990 {
991 if (TREE_CODE (e) == COND_EXPR)
992 {
993 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
994 pp_space (this);
995 pp_question (this);
996 pp_space (this);
997 expression (TREE_OPERAND (e, 1));
998 pp_space (this);
999 assignment_expression (TREE_OPERAND (e, 2));
1000 }
1001 else
1002 pp_c_logical_or_expression (this, e);
1003 }
1004
1005 /* Pretty-print a compound assignment operator token as indicated by T. */
1006
1007 static void
pp_cxx_assignment_operator(cxx_pretty_printer * pp,tree t)1008 pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
1009 {
1010 const char *op;
1011
1012 switch (TREE_CODE (t))
1013 {
1014 case NOP_EXPR:
1015 op = "=";
1016 break;
1017
1018 case PLUS_EXPR:
1019 op = "+=";
1020 break;
1021
1022 case MINUS_EXPR:
1023 op = "-=";
1024 break;
1025
1026 case TRUNC_DIV_EXPR:
1027 op = "/=";
1028 break;
1029
1030 case TRUNC_MOD_EXPR:
1031 op = "%=";
1032 break;
1033
1034 default:
1035 op = get_tree_code_name (TREE_CODE (t));
1036 break;
1037 }
1038
1039 pp_cxx_ws_string (pp, op);
1040 }
1041
1042
1043 /* assignment-expression:
1044 conditional-expression
1045 logical-or-expression assignment-operator assignment-expression
1046 throw-expression
1047
1048 throw-expression:
1049 throw assignment-expression(opt)
1050
1051 assignment-operator: one of
1052 = *= /= %= += -= >>= <<= &= ^= |= */
1053
1054 void
assignment_expression(tree e)1055 cxx_pretty_printer::assignment_expression (tree e)
1056 {
1057 switch (TREE_CODE (e))
1058 {
1059 case MODIFY_EXPR:
1060 case INIT_EXPR:
1061 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1062 pp_space (this);
1063 pp_equal (this);
1064 pp_space (this);
1065 assignment_expression (TREE_OPERAND (e, 1));
1066 break;
1067
1068 case THROW_EXPR:
1069 pp_cxx_ws_string (this, "throw");
1070 if (TREE_OPERAND (e, 0))
1071 assignment_expression (TREE_OPERAND (e, 0));
1072 break;
1073
1074 case MODOP_EXPR:
1075 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
1076 pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
1077 assignment_expression (TREE_OPERAND (e, 2));
1078 break;
1079
1080 default:
1081 conditional_expression (e);
1082 break;
1083 }
1084 }
1085
1086 void
expression(tree t)1087 cxx_pretty_printer::expression (tree t)
1088 {
1089 switch (TREE_CODE (t))
1090 {
1091 case STRING_CST:
1092 case VOID_CST:
1093 case INTEGER_CST:
1094 case REAL_CST:
1095 case COMPLEX_CST:
1096 constant (t);
1097 break;
1098
1099 case USERDEF_LITERAL:
1100 pp_cxx_userdef_literal (this, t);
1101 break;
1102
1103 case RESULT_DECL:
1104 pp_cxx_unqualified_id (this, t);
1105 break;
1106
1107 #if 0
1108 case OFFSET_REF:
1109 #endif
1110 case SCOPE_REF:
1111 case PTRMEM_CST:
1112 pp_cxx_qualified_id (this, t);
1113 break;
1114
1115 case OVERLOAD:
1116 t = OVL_FIRST (t);
1117 /* FALLTHRU */
1118 case VAR_DECL:
1119 case PARM_DECL:
1120 case FIELD_DECL:
1121 case CONST_DECL:
1122 case FUNCTION_DECL:
1123 case BASELINK:
1124 case TEMPLATE_DECL:
1125 case TEMPLATE_TYPE_PARM:
1126 case TEMPLATE_PARM_INDEX:
1127 case TEMPLATE_TEMPLATE_PARM:
1128 case STMT_EXPR:
1129 case REQUIRES_EXPR:
1130 primary_expression (t);
1131 break;
1132
1133 case CALL_EXPR:
1134 case DYNAMIC_CAST_EXPR:
1135 case STATIC_CAST_EXPR:
1136 case REINTERPRET_CAST_EXPR:
1137 case CONST_CAST_EXPR:
1138 #if 0
1139 case MEMBER_REF:
1140 #endif
1141 case EMPTY_CLASS_EXPR:
1142 case TYPEID_EXPR:
1143 case PSEUDO_DTOR_EXPR:
1144 case AGGR_INIT_EXPR:
1145 case ARROW_EXPR:
1146 postfix_expression (t);
1147 break;
1148
1149 case NEW_EXPR:
1150 case VEC_NEW_EXPR:
1151 pp_cxx_new_expression (this, t);
1152 break;
1153
1154 case DELETE_EXPR:
1155 case VEC_DELETE_EXPR:
1156 pp_cxx_delete_expression (this, t);
1157 break;
1158
1159 case SIZEOF_EXPR:
1160 case ALIGNOF_EXPR:
1161 case NOEXCEPT_EXPR:
1162 case UNARY_PLUS_EXPR:
1163 unary_expression (t);
1164 break;
1165
1166 case CAST_EXPR:
1167 case IMPLICIT_CONV_EXPR:
1168 pp_cxx_cast_expression (this, t);
1169 break;
1170
1171 case OFFSET_REF:
1172 case MEMBER_REF:
1173 case DOTSTAR_EXPR:
1174 pp_cxx_pm_expression (this, t);
1175 break;
1176
1177 case MULT_EXPR:
1178 case TRUNC_DIV_EXPR:
1179 case TRUNC_MOD_EXPR:
1180 case EXACT_DIV_EXPR:
1181 case RDIV_EXPR:
1182 multiplicative_expression (t);
1183 break;
1184
1185 case COND_EXPR:
1186 conditional_expression (t);
1187 break;
1188
1189 case MODIFY_EXPR:
1190 case INIT_EXPR:
1191 case THROW_EXPR:
1192 case MODOP_EXPR:
1193 assignment_expression (t);
1194 break;
1195
1196 case NON_DEPENDENT_EXPR:
1197 case MUST_NOT_THROW_EXPR:
1198 expression (TREE_OPERAND (t, 0));
1199 break;
1200
1201 case EXPR_PACK_EXPANSION:
1202 expression (PACK_EXPANSION_PATTERN (t));
1203 pp_cxx_ws_string (this, "...");
1204 break;
1205
1206 case UNARY_LEFT_FOLD_EXPR:
1207 pp_cxx_unary_left_fold_expression (this, t);
1208 break;
1209
1210 case UNARY_RIGHT_FOLD_EXPR:
1211 pp_cxx_unary_right_fold_expression (this, t);
1212 break;
1213
1214 case BINARY_LEFT_FOLD_EXPR:
1215 case BINARY_RIGHT_FOLD_EXPR:
1216 pp_cxx_binary_fold_expression (this, t);
1217 break;
1218
1219 case TEMPLATE_ID_EXPR:
1220 pp_cxx_template_id (this, t);
1221 break;
1222
1223 case NONTYPE_ARGUMENT_PACK:
1224 {
1225 tree args = ARGUMENT_PACK_ARGS (t);
1226 int i, len = TREE_VEC_LENGTH (args);
1227 pp_cxx_left_brace (this);
1228 for (i = 0; i < len; ++i)
1229 {
1230 if (i > 0)
1231 pp_cxx_separate_with (this, ',');
1232 expression (TREE_VEC_ELT (args, i));
1233 }
1234 pp_cxx_right_brace (this);
1235 }
1236 break;
1237
1238 case LAMBDA_EXPR:
1239 pp_cxx_ws_string (this, "<lambda>");
1240 break;
1241
1242 case TRAIT_EXPR:
1243 pp_cxx_trait_expression (this, t);
1244 break;
1245
1246 case ATOMIC_CONSTR:
1247 case CHECK_CONSTR:
1248 case CONJ_CONSTR:
1249 case DISJ_CONSTR:
1250 pp_cxx_constraint (this, t);
1251 break;
1252
1253 case PAREN_EXPR:
1254 pp_cxx_left_paren (this);
1255 expression (TREE_OPERAND (t, 0));
1256 pp_cxx_right_paren (this);
1257 break;
1258
1259 default:
1260 c_pretty_printer::expression (t);
1261 break;
1262 }
1263 }
1264
1265
1266 /* Declarations. */
1267
1268 /* function-specifier:
1269 inline
1270 virtual
1271 explicit */
1272
1273 void
function_specifier(tree t)1274 cxx_pretty_printer::function_specifier (tree t)
1275 {
1276 switch (TREE_CODE (t))
1277 {
1278 case FUNCTION_DECL:
1279 if (DECL_VIRTUAL_P (t))
1280 pp_cxx_ws_string (this, "virtual");
1281 else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
1282 pp_cxx_ws_string (this, "explicit");
1283 else
1284 c_pretty_printer::function_specifier (t);
1285
1286 default:
1287 break;
1288 }
1289 }
1290
1291 /* decl-specifier-seq:
1292 decl-specifier-seq(opt) decl-specifier
1293
1294 decl-specifier:
1295 storage-class-specifier
1296 type-specifier
1297 function-specifier
1298 friend
1299 typedef */
1300
1301 void
declaration_specifiers(tree t)1302 cxx_pretty_printer::declaration_specifiers (tree t)
1303 {
1304 switch (TREE_CODE (t))
1305 {
1306 case VAR_DECL:
1307 case PARM_DECL:
1308 case CONST_DECL:
1309 case FIELD_DECL:
1310 storage_class_specifier (t);
1311 declaration_specifiers (TREE_TYPE (t));
1312 break;
1313
1314 case TYPE_DECL:
1315 pp_cxx_ws_string (this, "typedef");
1316 declaration_specifiers (TREE_TYPE (t));
1317 break;
1318
1319 case FUNCTION_DECL:
1320 /* Constructors don't have return types. And conversion functions
1321 do not have a type-specifier in their return types. */
1322 if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
1323 function_specifier (t);
1324 else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1325 declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
1326 else
1327 c_pretty_printer::declaration_specifiers (t);
1328 break;
1329 default:
1330 c_pretty_printer::declaration_specifiers (t);
1331 break;
1332 }
1333 }
1334
1335 /* simple-type-specifier:
1336 ::(opt) nested-name-specifier(opt) type-name
1337 ::(opt) nested-name-specifier(opt) template(opt) template-id
1338 decltype-specifier
1339 char
1340 wchar_t
1341 bool
1342 short
1343 int
1344 long
1345 signed
1346 unsigned
1347 float
1348 double
1349 void */
1350
1351 void
simple_type_specifier(tree t)1352 cxx_pretty_printer::simple_type_specifier (tree t)
1353 {
1354 switch (TREE_CODE (t))
1355 {
1356 case RECORD_TYPE:
1357 case UNION_TYPE:
1358 case ENUMERAL_TYPE:
1359 pp_cxx_qualified_id (this, t);
1360 break;
1361
1362 case TEMPLATE_TYPE_PARM:
1363 case TEMPLATE_TEMPLATE_PARM:
1364 case TEMPLATE_PARM_INDEX:
1365 case BOUND_TEMPLATE_TEMPLATE_PARM:
1366 pp_cxx_unqualified_id (this, t);
1367 if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
1368 pp_cxx_constrained_type_spec (this, c);
1369 break;
1370
1371 case TYPENAME_TYPE:
1372 pp_cxx_ws_string (this, "typename");
1373 pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
1374 pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
1375 break;
1376
1377 case DECLTYPE_TYPE:
1378 pp_cxx_ws_string (this, "decltype");
1379 pp_cxx_left_paren (this);
1380 this->expression (DECLTYPE_TYPE_EXPR (t));
1381 pp_cxx_right_paren (this);
1382 break;
1383
1384 case NULLPTR_TYPE:
1385 pp_cxx_ws_string (this, "std::nullptr_t");
1386 break;
1387
1388 default:
1389 c_pretty_printer::simple_type_specifier (t);
1390 break;
1391 }
1392 }
1393
1394 /* type-specifier-seq:
1395 type-specifier type-specifier-seq(opt)
1396
1397 type-specifier:
1398 simple-type-specifier
1399 class-specifier
1400 enum-specifier
1401 elaborated-type-specifier
1402 cv-qualifier */
1403
1404 static void
pp_cxx_type_specifier_seq(cxx_pretty_printer * pp,tree t)1405 pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
1406 {
1407 switch (TREE_CODE (t))
1408 {
1409 case TEMPLATE_DECL:
1410 case TEMPLATE_TYPE_PARM:
1411 case TEMPLATE_TEMPLATE_PARM:
1412 case TYPE_DECL:
1413 case BOUND_TEMPLATE_TEMPLATE_PARM:
1414 case DECLTYPE_TYPE:
1415 case NULLPTR_TYPE:
1416 pp_cxx_cv_qualifier_seq (pp, t);
1417 pp->simple_type_specifier (t);
1418 break;
1419
1420 case METHOD_TYPE:
1421 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1422 pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
1423 pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
1424 break;
1425
1426 case RECORD_TYPE:
1427 if (TYPE_PTRMEMFUNC_P (t))
1428 {
1429 tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
1430 pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
1431 pp_cxx_whitespace (pp);
1432 pp_cxx_ptr_operator (pp, t);
1433 break;
1434 }
1435 /* fall through */
1436
1437 case OFFSET_TYPE:
1438 if (TYPE_PTRDATAMEM_P (t))
1439 {
1440 pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
1441 pp_cxx_whitespace (pp);
1442 pp_cxx_ptr_operator (pp, t);
1443 break;
1444 }
1445 /* fall through */
1446
1447 default:
1448 if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
1449 pp_c_specifier_qualifier_list (pp, t);
1450 }
1451 }
1452
1453 /* ptr-operator:
1454 * cv-qualifier-seq(opt)
1455 &
1456 ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
1457
1458 static void
pp_cxx_ptr_operator(cxx_pretty_printer * pp,tree t)1459 pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
1460 {
1461 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
1462 t = TREE_TYPE (t);
1463 switch (TREE_CODE (t))
1464 {
1465 case REFERENCE_TYPE:
1466 case POINTER_TYPE:
1467 if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
1468 pp_cxx_ptr_operator (pp, TREE_TYPE (t));
1469 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
1470 if (TYPE_PTR_P (t))
1471 {
1472 pp_star (pp);
1473 pp_cxx_cv_qualifier_seq (pp, t);
1474 }
1475 else
1476 pp_ampersand (pp);
1477 break;
1478
1479 case RECORD_TYPE:
1480 if (TYPE_PTRMEMFUNC_P (t))
1481 {
1482 pp_cxx_left_paren (pp);
1483 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
1484 pp_star (pp);
1485 break;
1486 }
1487 /* FALLTHRU */
1488 case OFFSET_TYPE:
1489 if (TYPE_PTRMEM_P (t))
1490 {
1491 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
1492 pp_cxx_left_paren (pp);
1493 pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
1494 pp_star (pp);
1495 pp_cxx_cv_qualifier_seq (pp, t);
1496 break;
1497 }
1498 /* fall through. */
1499
1500 default:
1501 pp_unsupported_tree (pp, t);
1502 break;
1503 }
1504 }
1505
1506 static inline tree
pp_cxx_implicit_parameter_type(tree mf)1507 pp_cxx_implicit_parameter_type (tree mf)
1508 {
1509 return class_of_this_parm (TREE_TYPE (mf));
1510 }
1511
1512 /*
1513 parameter-declaration:
1514 decl-specifier-seq declarator
1515 decl-specifier-seq declarator = assignment-expression
1516 decl-specifier-seq abstract-declarator(opt)
1517 decl-specifier-seq abstract-declarator(opt) assignment-expression */
1518
1519 static inline void
pp_cxx_parameter_declaration(cxx_pretty_printer * pp,tree t)1520 pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
1521 {
1522 pp->declaration_specifiers (t);
1523 if (TYPE_P (t))
1524 pp->abstract_declarator (t);
1525 else
1526 pp->declarator (t);
1527 }
1528
1529 /* parameter-declaration-clause:
1530 parameter-declaration-list(opt) ...(opt)
1531 parameter-declaration-list , ...
1532
1533 parameter-declaration-list:
1534 parameter-declaration
1535 parameter-declaration-list , parameter-declaration */
1536
1537 static void
pp_cxx_parameter_declaration_clause(cxx_pretty_printer * pp,tree t)1538 pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
1539 {
1540 gcc_assert (FUNC_OR_METHOD_TYPE_P (t) || TREE_CODE (t) == FUNCTION_DECL);
1541 tree types, args;
1542 if (TYPE_P (t))
1543 {
1544 types = TYPE_ARG_TYPES (t);
1545 args = NULL_TREE;
1546 }
1547 else
1548 {
1549 types = FUNCTION_FIRST_USER_PARMTYPE (t);
1550 args = FUNCTION_FIRST_USER_PARM (t);
1551 }
1552 bool abstract = !args || (pp->flags & pp_c_flag_abstract);
1553
1554 /* Skip artificial parameter for non-static member functions. */
1555 if (TREE_CODE (t) == METHOD_TYPE)
1556 types = TREE_CHAIN (types);
1557
1558 bool first = true;
1559 pp_cxx_left_paren (pp);
1560 for (; types != void_list_node; types = TREE_CHAIN (types))
1561 {
1562 if (!first)
1563 pp_cxx_separate_with (pp, ',');
1564 first = false;
1565 if (!types)
1566 {
1567 pp_cxx_ws_string (pp, "...");
1568 break;
1569 }
1570 pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
1571 if (!abstract && pp->flags & pp_cxx_flag_default_argument)
1572 {
1573 pp_cxx_whitespace (pp);
1574 pp_equal (pp);
1575 pp_cxx_whitespace (pp);
1576 pp->assignment_expression (TREE_PURPOSE (types));
1577 }
1578 if (!abstract)
1579 args = TREE_CHAIN (args);
1580 }
1581 pp_cxx_right_paren (pp);
1582 }
1583
1584 /* exception-specification:
1585 throw ( type-id-list(opt) )
1586
1587 type-id-list
1588 type-id
1589 type-id-list , type-id */
1590
1591 static void
pp_cxx_exception_specification(cxx_pretty_printer * pp,tree t)1592 pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
1593 {
1594 tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
1595 bool need_comma = false;
1596
1597 if (ex_spec == NULL)
1598 return;
1599 if (TREE_PURPOSE (ex_spec))
1600 {
1601 pp_cxx_ws_string (pp, "noexcept");
1602 pp_cxx_whitespace (pp);
1603 pp_cxx_left_paren (pp);
1604 if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
1605 pp_cxx_ws_string (pp, "<uninstantiated>");
1606 else
1607 pp->expression (TREE_PURPOSE (ex_spec));
1608 pp_cxx_right_paren (pp);
1609 return;
1610 }
1611 pp_cxx_ws_string (pp, "throw");
1612 pp_cxx_left_paren (pp);
1613 for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
1614 {
1615 tree type = TREE_VALUE (ex_spec);
1616 tree argpack = NULL_TREE;
1617 int i, len = 1;
1618
1619 if (ARGUMENT_PACK_P (type))
1620 {
1621 argpack = ARGUMENT_PACK_ARGS (type);
1622 len = TREE_VEC_LENGTH (argpack);
1623 }
1624
1625 for (i = 0; i < len; ++i)
1626 {
1627 if (argpack)
1628 type = TREE_VEC_ELT (argpack, i);
1629
1630 if (need_comma)
1631 pp_cxx_separate_with (pp, ',');
1632 else
1633 need_comma = true;
1634
1635 pp->type_id (type);
1636 }
1637 }
1638 pp_cxx_right_paren (pp);
1639 }
1640
1641 /* direct-declarator:
1642 declarator-id
1643 direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
1644 exception-specification(opt)
1645 direct-declaration [ constant-expression(opt) ]
1646 ( declarator ) */
1647
1648 void
direct_declarator(tree t)1649 cxx_pretty_printer::direct_declarator (tree t)
1650 {
1651 switch (TREE_CODE (t))
1652 {
1653 case VAR_DECL:
1654 case PARM_DECL:
1655 case CONST_DECL:
1656 case FIELD_DECL:
1657 if (DECL_NAME (t))
1658 {
1659 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
1660
1661 if ((TREE_CODE (t) == PARM_DECL && DECL_PACK_P (t))
1662 || template_parameter_pack_p (t))
1663 /* A function parameter pack or non-type template
1664 parameter pack. */
1665 pp_cxx_ws_string (this, "...");
1666
1667 id_expression (DECL_NAME (t));
1668 }
1669 abstract_declarator (TREE_TYPE (t));
1670 break;
1671
1672 case FUNCTION_DECL:
1673 pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
1674 expression (t);
1675 pp_cxx_parameter_declaration_clause (this, t);
1676
1677 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
1678 {
1679 padding = pp_before;
1680 pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
1681 }
1682
1683 pp_cxx_exception_specification (this, TREE_TYPE (t));
1684 break;
1685
1686 case TYPENAME_TYPE:
1687 case TEMPLATE_DECL:
1688 case TEMPLATE_TYPE_PARM:
1689 case TEMPLATE_PARM_INDEX:
1690 case TEMPLATE_TEMPLATE_PARM:
1691 break;
1692
1693 default:
1694 c_pretty_printer::direct_declarator (t);
1695 break;
1696 }
1697 }
1698
1699 /* declarator:
1700 direct-declarator
1701 ptr-operator declarator */
1702
1703 void
declarator(tree t)1704 cxx_pretty_printer::declarator (tree t)
1705 {
1706 direct_declarator (t);
1707
1708 // Print a requires clause.
1709 if (flag_concepts)
1710 if (tree ci = get_constraints (t))
1711 if (tree reqs = CI_DECLARATOR_REQS (ci))
1712 pp_cxx_requires_clause (this, reqs);
1713 }
1714
1715 /* ctor-initializer:
1716 : mem-initializer-list
1717
1718 mem-initializer-list:
1719 mem-initializer
1720 mem-initializer , mem-initializer-list
1721
1722 mem-initializer:
1723 mem-initializer-id ( expression-list(opt) )
1724
1725 mem-initializer-id:
1726 ::(opt) nested-name-specifier(opt) class-name
1727 identifier */
1728
1729 static void
pp_cxx_ctor_initializer(cxx_pretty_printer * pp,tree t)1730 pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
1731 {
1732 t = TREE_OPERAND (t, 0);
1733 pp_cxx_whitespace (pp);
1734 pp_colon (pp);
1735 pp_cxx_whitespace (pp);
1736 for (; t; t = TREE_CHAIN (t))
1737 {
1738 tree purpose = TREE_PURPOSE (t);
1739 bool is_pack = PACK_EXPANSION_P (purpose);
1740
1741 if (is_pack)
1742 pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
1743 else
1744 pp->primary_expression (purpose);
1745 pp_cxx_call_argument_list (pp, TREE_VALUE (t));
1746 if (is_pack)
1747 pp_cxx_ws_string (pp, "...");
1748 if (TREE_CHAIN (t))
1749 pp_cxx_separate_with (pp, ',');
1750 }
1751 }
1752
1753 /* function-definition:
1754 decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
1755 decl-specifier-seq(opt) declarator function-try-block */
1756
1757 static void
pp_cxx_function_definition(cxx_pretty_printer * pp,tree t)1758 pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
1759 {
1760 tree saved_scope = pp->enclosing_scope;
1761 pp->declaration_specifiers (t);
1762 pp->declarator (t);
1763 pp_needs_newline (pp) = true;
1764 pp->enclosing_scope = DECL_CONTEXT (t);
1765 if (DECL_SAVED_TREE (t))
1766 pp->statement (DECL_SAVED_TREE (t));
1767 else
1768 pp_cxx_semicolon (pp);
1769 pp_newline_and_flush (pp);
1770 pp->enclosing_scope = saved_scope;
1771 }
1772
1773 /* abstract-declarator:
1774 ptr-operator abstract-declarator(opt)
1775 direct-abstract-declarator */
1776
1777 void
abstract_declarator(tree t)1778 cxx_pretty_printer::abstract_declarator (tree t)
1779 {
1780 /* pp_cxx_ptr_operator prints '(' for a pointer-to-member function,
1781 or a pointer-to-data-member of array type:
1782
1783 void (X::*)()
1784 int (X::*)[5]
1785
1786 but not for a pointer-to-data-member of non-array type:
1787
1788 int X::*
1789
1790 so be mindful of that. */
1791 if (TYPE_PTRMEMFUNC_P (t)
1792 || (TYPE_PTRDATAMEM_P (t)
1793 && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE))
1794 pp_cxx_right_paren (this);
1795 else if (INDIRECT_TYPE_P (t))
1796 {
1797 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
1798 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1799 pp_cxx_right_paren (this);
1800 t = TREE_TYPE (t);
1801 }
1802 direct_abstract_declarator (t);
1803 }
1804
1805 /* direct-abstract-declarator:
1806 direct-abstract-declarator(opt) ( parameter-declaration-clause )
1807 cv-qualifier-seq(opt) exception-specification(opt)
1808 direct-abstract-declarator(opt) [ constant-expression(opt) ]
1809 ( abstract-declarator ) */
1810
1811 void
direct_abstract_declarator(tree t)1812 cxx_pretty_printer::direct_abstract_declarator (tree t)
1813 {
1814 switch (TREE_CODE (t))
1815 {
1816 case REFERENCE_TYPE:
1817 abstract_declarator (t);
1818 break;
1819
1820 case RECORD_TYPE:
1821 if (TYPE_PTRMEMFUNC_P (t))
1822 direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
1823 break;
1824
1825 case OFFSET_TYPE:
1826 if (TYPE_PTRDATAMEM_P (t))
1827 direct_abstract_declarator (TREE_TYPE (t));
1828 break;
1829
1830 case METHOD_TYPE:
1831 case FUNCTION_TYPE:
1832 pp_cxx_parameter_declaration_clause (this, t);
1833 direct_abstract_declarator (TREE_TYPE (t));
1834 if (TREE_CODE (t) == METHOD_TYPE)
1835 {
1836 padding = pp_before;
1837 pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
1838 }
1839 pp_cxx_exception_specification (this, t);
1840 break;
1841
1842 case TYPENAME_TYPE:
1843 case TEMPLATE_TYPE_PARM:
1844 case TEMPLATE_TEMPLATE_PARM:
1845 case BOUND_TEMPLATE_TEMPLATE_PARM:
1846 case UNBOUND_CLASS_TEMPLATE:
1847 case DECLTYPE_TYPE:
1848 break;
1849
1850 default:
1851 c_pretty_printer::direct_abstract_declarator (t);
1852 break;
1853 }
1854 }
1855
1856 /* type-id:
1857 type-specifier-seq abstract-declarator(opt) */
1858
1859 void
type_id(tree t)1860 cxx_pretty_printer::type_id (tree t)
1861 {
1862 pp_flags saved_flags = flags;
1863 flags |= pp_c_flag_abstract;
1864
1865 switch (TREE_CODE (t))
1866 {
1867 case TYPE_DECL:
1868 case UNION_TYPE:
1869 case RECORD_TYPE:
1870 case ENUMERAL_TYPE:
1871 case TYPENAME_TYPE:
1872 case BOUND_TEMPLATE_TEMPLATE_PARM:
1873 case UNBOUND_CLASS_TEMPLATE:
1874 case TEMPLATE_TEMPLATE_PARM:
1875 case TEMPLATE_TYPE_PARM:
1876 case TEMPLATE_PARM_INDEX:
1877 case TEMPLATE_DECL:
1878 case TYPEOF_TYPE:
1879 case UNDERLYING_TYPE:
1880 case DECLTYPE_TYPE:
1881 case NULLPTR_TYPE:
1882 case TEMPLATE_ID_EXPR:
1883 case OFFSET_TYPE:
1884 pp_cxx_type_specifier_seq (this, t);
1885 if (TYPE_PTRMEM_P (t))
1886 abstract_declarator (t);
1887 break;
1888
1889 case TYPE_PACK_EXPANSION:
1890 type_id (PACK_EXPANSION_PATTERN (t));
1891 pp_cxx_ws_string (this, "...");
1892 break;
1893
1894 case TYPE_ARGUMENT_PACK:
1895 {
1896 tree args = ARGUMENT_PACK_ARGS (t);
1897 int len = TREE_VEC_LENGTH (args);
1898 pp_cxx_left_brace (this);
1899 for (int i = 0; i < len; ++i)
1900 {
1901 if (i > 0)
1902 pp_cxx_separate_with (this, ',');
1903 type_id (TREE_VEC_ELT (args, i));
1904 }
1905 pp_cxx_right_brace (this);
1906 }
1907 break;
1908
1909 default:
1910 c_pretty_printer::type_id (t);
1911 break;
1912 }
1913
1914 flags = saved_flags;
1915 }
1916
1917 /* template-argument-list:
1918 template-argument ...(opt)
1919 template-argument-list, template-argument ...(opt)
1920
1921 template-argument:
1922 assignment-expression
1923 type-id
1924 template-name */
1925
1926 static void
pp_cxx_template_argument_list(cxx_pretty_printer * pp,tree t)1927 pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
1928 {
1929 int i;
1930 bool need_comma = false;
1931
1932 if (t == NULL)
1933 return;
1934 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
1935 {
1936 tree arg = TREE_VEC_ELT (t, i);
1937 tree argpack = NULL_TREE;
1938 int idx, len = 1;
1939
1940 if (ARGUMENT_PACK_P (arg))
1941 {
1942 argpack = ARGUMENT_PACK_ARGS (arg);
1943 len = TREE_VEC_LENGTH (argpack);
1944 }
1945
1946 for (idx = 0; idx < len; idx++)
1947 {
1948 if (argpack)
1949 arg = TREE_VEC_ELT (argpack, idx);
1950
1951 if (need_comma)
1952 pp_cxx_separate_with (pp, ',');
1953 else
1954 need_comma = true;
1955
1956 if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
1957 && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
1958 pp->type_id (arg);
1959 else if (template_parm_object_p (arg))
1960 pp->expression (DECL_INITIAL (arg));
1961 else
1962 pp->expression (arg);
1963 }
1964 }
1965 }
1966
1967
1968 static void
pp_cxx_exception_declaration(cxx_pretty_printer * pp,tree t)1969 pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
1970 {
1971 t = DECL_EXPR_DECL (t);
1972 pp_cxx_type_specifier_seq (pp, t);
1973 if (TYPE_P (t))
1974 pp->abstract_declarator (t);
1975 else
1976 pp->declarator (t);
1977 }
1978
1979 /* Statements. */
1980
1981 void
statement(tree t)1982 cxx_pretty_printer::statement (tree t)
1983 {
1984 switch (TREE_CODE (t))
1985 {
1986 case CTOR_INITIALIZER:
1987 pp_cxx_ctor_initializer (this, t);
1988 break;
1989
1990 case USING_STMT:
1991 pp_cxx_ws_string (this, "using");
1992 pp_cxx_ws_string (this, "namespace");
1993 if (DECL_CONTEXT (t))
1994 pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
1995 pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
1996 break;
1997
1998 case USING_DECL:
1999 pp_cxx_ws_string (this, "using");
2000 pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
2001 pp_cxx_unqualified_id (this, DECL_NAME (t));
2002 break;
2003
2004 case EH_SPEC_BLOCK:
2005 break;
2006
2007 /* try-block:
2008 try compound-statement handler-seq */
2009 case TRY_BLOCK:
2010 pp_maybe_newline_and_indent (this, 0);
2011 pp_cxx_ws_string (this, "try");
2012 pp_newline_and_indent (this, 3);
2013 statement (TRY_STMTS (t));
2014 pp_newline_and_indent (this, -3);
2015 if (CLEANUP_P (t))
2016 ;
2017 else
2018 statement (TRY_HANDLERS (t));
2019 break;
2020
2021 /*
2022 handler-seq:
2023 handler handler-seq(opt)
2024
2025 handler:
2026 catch ( exception-declaration ) compound-statement
2027
2028 exception-declaration:
2029 type-specifier-seq declarator
2030 type-specifier-seq abstract-declarator
2031 ... */
2032 case HANDLER:
2033 pp_cxx_ws_string (this, "catch");
2034 pp_cxx_left_paren (this);
2035 pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
2036 pp_cxx_right_paren (this);
2037 pp_indentation (this) += 3;
2038 pp_needs_newline (this) = true;
2039 statement (HANDLER_BODY (t));
2040 pp_indentation (this) -= 3;
2041 pp_needs_newline (this) = true;
2042 break;
2043
2044 /* selection-statement:
2045 if ( expression ) statement
2046 if ( expression ) statement else statement */
2047 case IF_STMT:
2048 pp_cxx_ws_string (this, "if");
2049 pp_cxx_whitespace (this);
2050 pp_cxx_left_paren (this);
2051 expression (IF_COND (t));
2052 pp_cxx_right_paren (this);
2053 pp_newline_and_indent (this, 2);
2054 statement (THEN_CLAUSE (t));
2055 pp_newline_and_indent (this, -2);
2056 if (ELSE_CLAUSE (t))
2057 {
2058 tree else_clause = ELSE_CLAUSE (t);
2059 pp_cxx_ws_string (this, "else");
2060 if (TREE_CODE (else_clause) == IF_STMT)
2061 pp_cxx_whitespace (this);
2062 else
2063 pp_newline_and_indent (this, 2);
2064 statement (else_clause);
2065 if (TREE_CODE (else_clause) != IF_STMT)
2066 pp_newline_and_indent (this, -2);
2067 }
2068 break;
2069
2070 case RANGE_FOR_STMT:
2071 pp_cxx_ws_string (this, "for");
2072 pp_space (this);
2073 pp_cxx_left_paren (this);
2074 if (RANGE_FOR_INIT_STMT (t))
2075 {
2076 statement (RANGE_FOR_INIT_STMT (t));
2077 pp_needs_newline (this) = false;
2078 pp_cxx_whitespace (this);
2079 }
2080 statement (RANGE_FOR_DECL (t));
2081 pp_space (this);
2082 pp_needs_newline (this) = false;
2083 pp_colon (this);
2084 pp_space (this);
2085 statement (RANGE_FOR_EXPR (t));
2086 pp_cxx_right_paren (this);
2087 pp_newline_and_indent (this, 3);
2088 statement (FOR_BODY (t));
2089 pp_indentation (this) -= 3;
2090 pp_needs_newline (this) = true;
2091 break;
2092
2093 /* expression-statement:
2094 expression(opt) ; */
2095 case EXPR_STMT:
2096 expression (EXPR_STMT_EXPR (t));
2097 pp_cxx_semicolon (this);
2098 pp_needs_newline (this) = true;
2099 break;
2100
2101 case CLEANUP_STMT:
2102 pp_cxx_ws_string (this, "try");
2103 pp_newline_and_indent (this, 2);
2104 statement (CLEANUP_BODY (t));
2105 pp_newline_and_indent (this, -2);
2106 pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
2107 pp_newline_and_indent (this, 2);
2108 statement (CLEANUP_EXPR (t));
2109 pp_newline_and_indent (this, -2);
2110 break;
2111
2112 case STATIC_ASSERT:
2113 declaration (t);
2114 break;
2115
2116 case OMP_DEPOBJ:
2117 pp_cxx_ws_string (this, "#pragma omp depobj");
2118 pp_space (this);
2119 pp_cxx_left_paren (this);
2120 expression (OMP_DEPOBJ_DEPOBJ (t));
2121 pp_cxx_right_paren (this);
2122 if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
2123 {
2124 if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
2125 dump_omp_clauses (this, OMP_DEPOBJ_CLAUSES (t),
2126 pp_indentation (this), TDF_NONE);
2127 else
2128 switch (tree_to_uhwi (OMP_DEPOBJ_CLAUSES (t)))
2129 {
2130 case OMP_CLAUSE_DEPEND_IN:
2131 pp_cxx_ws_string (this, " update(in)");
2132 break;
2133 case OMP_CLAUSE_DEPEND_INOUT:
2134 pp_cxx_ws_string (this, " update(inout)");
2135 break;
2136 case OMP_CLAUSE_DEPEND_OUT:
2137 pp_cxx_ws_string (this, " update(out)");
2138 break;
2139 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
2140 pp_cxx_ws_string (this, " update(mutexinoutset)");
2141 break;
2142 case OMP_CLAUSE_DEPEND_LAST:
2143 pp_cxx_ws_string (this, " destroy");
2144 break;
2145 default:
2146 break;
2147 }
2148 }
2149 pp_needs_newline (this) = true;
2150 break;
2151
2152 default:
2153 c_pretty_printer::statement (t);
2154 break;
2155 }
2156 }
2157
2158 /* original-namespace-definition:
2159 namespace identifier { namespace-body }
2160
2161 As an edge case, we also handle unnamed namespace definition here. */
2162
2163 static void
pp_cxx_original_namespace_definition(cxx_pretty_printer * pp,tree t)2164 pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
2165 {
2166 pp_cxx_ws_string (pp, "namespace");
2167 if (DECL_CONTEXT (t))
2168 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2169 if (DECL_NAME (t))
2170 pp_cxx_unqualified_id (pp, t);
2171 pp_cxx_whitespace (pp);
2172 pp_cxx_left_brace (pp);
2173 /* We do not print the namespace-body. */
2174 pp_cxx_whitespace (pp);
2175 pp_cxx_right_brace (pp);
2176 }
2177
2178 /* namespace-alias:
2179 identifier
2180
2181 namespace-alias-definition:
2182 namespace identifier = qualified-namespace-specifier ;
2183
2184 qualified-namespace-specifier:
2185 ::(opt) nested-name-specifier(opt) namespace-name */
2186
2187 static void
pp_cxx_namespace_alias_definition(cxx_pretty_printer * pp,tree t)2188 pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
2189 {
2190 pp_cxx_ws_string (pp, "namespace");
2191 if (DECL_CONTEXT (t))
2192 pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
2193 pp_cxx_unqualified_id (pp, t);
2194 pp_cxx_whitespace (pp);
2195 pp_equal (pp);
2196 pp_cxx_whitespace (pp);
2197 if (DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)))
2198 pp_cxx_nested_name_specifier (pp,
2199 DECL_CONTEXT (DECL_NAMESPACE_ALIAS (t)));
2200 pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
2201 pp_cxx_semicolon (pp);
2202 }
2203
2204 /* simple-declaration:
2205 decl-specifier-seq(opt) init-declarator-list(opt) */
2206
2207 static void
pp_cxx_simple_declaration(cxx_pretty_printer * pp,tree t)2208 pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
2209 {
2210 pp->declaration_specifiers (t);
2211 pp_cxx_init_declarator (pp, t);
2212 pp_cxx_semicolon (pp);
2213 pp_needs_newline (pp) = true;
2214 }
2215
2216 /*
2217 template-parameter-list:
2218 template-parameter
2219 template-parameter-list , template-parameter */
2220
2221 static inline void
pp_cxx_template_parameter_list(cxx_pretty_printer * pp,tree t)2222 pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
2223 {
2224 const int n = TREE_VEC_LENGTH (t);
2225 int i;
2226 for (i = 0; i < n; ++i)
2227 {
2228 if (i)
2229 pp_cxx_separate_with (pp, ',');
2230 pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
2231 }
2232 }
2233
2234 /* template-parameter:
2235 type-parameter
2236 parameter-declaration
2237
2238 type-parameter:
2239 class ...(opt) identifier(opt)
2240 class identifier(opt) = type-id
2241 typename identifier(opt)
2242 typename ...(opt) identifier(opt) = type-id
2243 template < template-parameter-list > class ...(opt) identifier(opt)
2244 template < template-parameter-list > class identifier(opt) = template-name */
2245
2246 static void
pp_cxx_template_parameter(cxx_pretty_printer * pp,tree t)2247 pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
2248 {
2249 tree parameter = TREE_VALUE (t);
2250 switch (TREE_CODE (parameter))
2251 {
2252 case TYPE_DECL:
2253 pp_cxx_ws_string (pp, "class");
2254 if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
2255 pp_cxx_ws_string (pp, "...");
2256 if (DECL_NAME (parameter))
2257 pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
2258 /* FIXME: Check if we should print also default argument. */
2259 break;
2260
2261 case PARM_DECL:
2262 pp_cxx_parameter_declaration (pp, parameter);
2263 break;
2264
2265 case TEMPLATE_DECL:
2266 break;
2267
2268 default:
2269 pp_unsupported_tree (pp, t);
2270 break;
2271 }
2272 }
2273
2274 /* Pretty-print a template parameter in the canonical form
2275 "template-parameter-<level>-<position in parameter list>". */
2276
2277 void
pp_cxx_canonical_template_parameter(cxx_pretty_printer * pp,tree parm)2278 pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
2279 {
2280 const enum tree_code code = TREE_CODE (parm);
2281
2282 /* Brings type template parameters to the canonical forms. */
2283 if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
2284 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
2285 parm = TEMPLATE_TYPE_PARM_INDEX (parm);
2286
2287 pp_cxx_begin_template_argument_list (pp);
2288 pp->translate_string ("template-parameter-");
2289 pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
2290 pp_minus (pp);
2291 pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
2292 pp_cxx_end_template_argument_list (pp);
2293 }
2294
2295 /* Print a constrained-type-specifier. */
2296
2297 void
pp_cxx_constrained_type_spec(cxx_pretty_printer * pp,tree c)2298 pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, tree c)
2299 {
2300 pp_cxx_whitespace (pp);
2301 pp_cxx_left_bracket (pp);
2302 pp->translate_string ("requires");
2303 pp_cxx_whitespace (pp);
2304 if (c == error_mark_node)
2305 {
2306 pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
2307 return;
2308 }
2309 tree t, a;
2310 placeholder_extract_concept_and_args (c, t, a);
2311 pp->id_expression (t);
2312 pp_cxx_begin_template_argument_list (pp);
2313 pp_cxx_ws_string (pp, "<placeholder>");
2314 pp_cxx_separate_with (pp, ',');
2315 tree args = make_tree_vec (TREE_VEC_LENGTH (a) - 1);
2316 for (int i = 0; i < TREE_VEC_LENGTH (a) - 1; ++i)
2317 TREE_VEC_ELT (args, i) = TREE_VEC_ELT (a, i + 1);
2318 pp_cxx_template_argument_list (pp, args);
2319 ggc_free (args);
2320 pp_cxx_end_template_argument_list (pp);
2321 pp_cxx_right_bracket (pp);
2322 }
2323
2324 /*
2325 template-declaration:
2326 export(opt) template < template-parameter-list > declaration
2327
2328 Concept extensions:
2329
2330 template-declaration:
2331 export(opt) template < template-parameter-list >
2332 requires-clause(opt) declaration */
2333
2334 static void
pp_cxx_template_declaration(cxx_pretty_printer * pp,tree t)2335 pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
2336 {
2337 tree tmpl = most_general_template (t);
2338 tree level;
2339
2340 pp_maybe_newline_and_indent (pp, 0);
2341 for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
2342 {
2343 pp_cxx_ws_string (pp, "template");
2344 pp_cxx_begin_template_argument_list (pp);
2345 pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
2346 pp_cxx_end_template_argument_list (pp);
2347 pp_newline_and_indent (pp, 3);
2348 }
2349
2350 if (flag_concepts)
2351 if (tree ci = get_constraints (t))
2352 if (tree reqs = CI_TEMPLATE_REQS (ci))
2353 {
2354 pp_cxx_requires_clause (pp, reqs);
2355 pp_newline_and_indent (pp, 6);
2356 }
2357
2358 if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
2359 pp_cxx_function_definition (pp, t);
2360 else if (TREE_CODE (t) == CONCEPT_DECL)
2361 pp_cxx_concept_definition (pp, t);
2362 else
2363 pp_cxx_simple_declaration (pp, t);
2364 }
2365
2366 static void
pp_cxx_explicit_specialization(cxx_pretty_printer * pp,tree t)2367 pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
2368 {
2369 pp_unsupported_tree (pp, t);
2370 }
2371
2372 static void
pp_cxx_explicit_instantiation(cxx_pretty_printer * pp,tree t)2373 pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
2374 {
2375 pp_unsupported_tree (pp, t);
2376 }
2377
2378 static void
pp_cxx_concept_definition(cxx_pretty_printer * pp,tree t)2379 pp_cxx_concept_definition (cxx_pretty_printer *pp, tree t)
2380 {
2381 pp_cxx_unqualified_id (pp, DECL_NAME (t));
2382 pp_cxx_whitespace (pp);
2383 pp_cxx_ws_string (pp, "=");
2384 pp_cxx_whitespace (pp);
2385 pp->expression (DECL_INITIAL (t));
2386 pp_cxx_semicolon (pp);
2387 }
2388
2389 /*
2390 declaration:
2391 block-declaration
2392 function-definition
2393 template-declaration
2394 explicit-instantiation
2395 explicit-specialization
2396 linkage-specification
2397 namespace-definition
2398
2399 block-declaration:
2400 simple-declaration
2401 asm-definition
2402 namespace-alias-definition
2403 using-declaration
2404 using-directive
2405 static_assert-declaration */
2406 void
declaration(tree t)2407 cxx_pretty_printer::declaration (tree t)
2408 {
2409 if (TREE_CODE (t) == STATIC_ASSERT)
2410 {
2411 pp_cxx_ws_string (this, "static_assert");
2412 pp_cxx_left_paren (this);
2413 expression (STATIC_ASSERT_CONDITION (t));
2414 pp_cxx_separate_with (this, ',');
2415 expression (STATIC_ASSERT_MESSAGE (t));
2416 pp_cxx_right_paren (this);
2417 }
2418 else if (!DECL_LANG_SPECIFIC (t))
2419 pp_cxx_simple_declaration (this, t);
2420 else if (DECL_USE_TEMPLATE (t))
2421 switch (DECL_USE_TEMPLATE (t))
2422 {
2423 case 1:
2424 pp_cxx_template_declaration (this, t);
2425 break;
2426
2427 case 2:
2428 pp_cxx_explicit_specialization (this, t);
2429 break;
2430
2431 case 3:
2432 pp_cxx_explicit_instantiation (this, t);
2433 break;
2434
2435 default:
2436 break;
2437 }
2438 else switch (TREE_CODE (t))
2439 {
2440 case VAR_DECL:
2441 case TYPE_DECL:
2442 pp_cxx_simple_declaration (this, t);
2443 break;
2444
2445 case FUNCTION_DECL:
2446 if (DECL_SAVED_TREE (t))
2447 pp_cxx_function_definition (this, t);
2448 else
2449 pp_cxx_simple_declaration (this, t);
2450 break;
2451
2452 case NAMESPACE_DECL:
2453 if (DECL_NAMESPACE_ALIAS (t))
2454 pp_cxx_namespace_alias_definition (this, t);
2455 else
2456 pp_cxx_original_namespace_definition (this, t);
2457 break;
2458
2459 default:
2460 pp_unsupported_tree (this, t);
2461 break;
2462 }
2463 }
2464
2465 static void
pp_cxx_typeid_expression(cxx_pretty_printer * pp,tree t)2466 pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
2467 {
2468 t = TREE_OPERAND (t, 0);
2469 pp_cxx_ws_string (pp, "typeid");
2470 pp_cxx_left_paren (pp);
2471 if (TYPE_P (t))
2472 pp->type_id (t);
2473 else
2474 pp->expression (t);
2475 pp_cxx_right_paren (pp);
2476 }
2477
2478 void
pp_cxx_va_arg_expression(cxx_pretty_printer * pp,tree t)2479 pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
2480 {
2481 pp_cxx_ws_string (pp, "va_arg");
2482 pp_cxx_left_paren (pp);
2483 pp->assignment_expression (TREE_OPERAND (t, 0));
2484 pp_cxx_separate_with (pp, ',');
2485 pp->type_id (TREE_TYPE (t));
2486 pp_cxx_right_paren (pp);
2487 }
2488
2489 static bool
pp_cxx_offsetof_expression_1(cxx_pretty_printer * pp,tree t)2490 pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
2491 {
2492 switch (TREE_CODE (t))
2493 {
2494 case ARROW_EXPR:
2495 if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
2496 && INDIRECT_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
2497 {
2498 pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
2499 pp_cxx_separate_with (pp, ',');
2500 return true;
2501 }
2502 return false;
2503 case COMPONENT_REF:
2504 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2505 return false;
2506 if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
2507 pp_cxx_dot (pp);
2508 pp->expression (TREE_OPERAND (t, 1));
2509 return true;
2510 case ARRAY_REF:
2511 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2512 return false;
2513 pp_left_bracket (pp);
2514 pp->expression (TREE_OPERAND (t, 1));
2515 pp_right_bracket (pp);
2516 return true;
2517 default:
2518 return false;
2519 }
2520 }
2521
2522 void
pp_cxx_offsetof_expression(cxx_pretty_printer * pp,tree t)2523 pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
2524 {
2525 pp_cxx_ws_string (pp, "offsetof");
2526 pp_cxx_left_paren (pp);
2527 if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
2528 pp->expression (TREE_OPERAND (t, 0));
2529 pp_cxx_right_paren (pp);
2530 }
2531
2532 void
pp_cxx_addressof_expression(cxx_pretty_printer * pp,tree t)2533 pp_cxx_addressof_expression (cxx_pretty_printer *pp, tree t)
2534 {
2535 pp_cxx_ws_string (pp, "__builtin_addressof");
2536 pp_cxx_left_paren (pp);
2537 pp->expression (TREE_OPERAND (t, 0));
2538 pp_cxx_right_paren (pp);
2539 }
2540
2541 static char const*
get_fold_operator(tree t)2542 get_fold_operator (tree t)
2543 {
2544 ovl_op_info_t *info = OVL_OP_INFO (FOLD_EXPR_MODIFY_P (t),
2545 FOLD_EXPR_OP (t));
2546 return info->name;
2547 }
2548
2549 void
pp_cxx_unary_left_fold_expression(cxx_pretty_printer * pp,tree t)2550 pp_cxx_unary_left_fold_expression (cxx_pretty_printer *pp, tree t)
2551 {
2552 char const* op = get_fold_operator (t);
2553 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2554 pp_cxx_left_paren (pp);
2555 pp_cxx_ws_string (pp, "...");
2556 pp_cxx_ws_string (pp, op);
2557 pp->expression (expr);
2558 pp_cxx_right_paren (pp);
2559 }
2560
2561 void
pp_cxx_unary_right_fold_expression(cxx_pretty_printer * pp,tree t)2562 pp_cxx_unary_right_fold_expression (cxx_pretty_printer *pp, tree t)
2563 {
2564 char const* op = get_fold_operator (t);
2565 tree expr = PACK_EXPANSION_PATTERN (FOLD_EXPR_PACK (t));
2566 pp_cxx_left_paren (pp);
2567 pp->expression (expr);
2568 pp_space (pp);
2569 pp_cxx_ws_string (pp, op);
2570 pp_cxx_ws_string (pp, "...");
2571 pp_cxx_right_paren (pp);
2572 }
2573
2574 void
pp_cxx_binary_fold_expression(cxx_pretty_printer * pp,tree t)2575 pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t)
2576 {
2577 char const* op = get_fold_operator (t);
2578 tree t1 = TREE_OPERAND (t, 1);
2579 tree t2 = TREE_OPERAND (t, 2);
2580 if (t1 == FOLD_EXPR_PACK (t))
2581 t1 = PACK_EXPANSION_PATTERN (t1);
2582 else
2583 t2 = PACK_EXPANSION_PATTERN (t2);
2584 pp_cxx_left_paren (pp);
2585 pp->expression (t1);
2586 pp_cxx_ws_string (pp, op);
2587 pp_cxx_ws_string (pp, "...");
2588 pp_cxx_ws_string (pp, op);
2589 pp->expression (t2);
2590 pp_cxx_right_paren (pp);
2591 }
2592
2593 void
pp_cxx_trait_expression(cxx_pretty_printer * pp,tree t)2594 pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
2595 {
2596 cp_trait_kind kind = TRAIT_EXPR_KIND (t);
2597
2598 switch (kind)
2599 {
2600 case CPTK_HAS_NOTHROW_ASSIGN:
2601 pp_cxx_ws_string (pp, "__has_nothrow_assign");
2602 break;
2603 case CPTK_HAS_TRIVIAL_ASSIGN:
2604 pp_cxx_ws_string (pp, "__has_trivial_assign");
2605 break;
2606 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
2607 pp_cxx_ws_string (pp, "__has_nothrow_constructor");
2608 break;
2609 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
2610 pp_cxx_ws_string (pp, "__has_trivial_constructor");
2611 break;
2612 case CPTK_HAS_NOTHROW_COPY:
2613 pp_cxx_ws_string (pp, "__has_nothrow_copy");
2614 break;
2615 case CPTK_HAS_TRIVIAL_COPY:
2616 pp_cxx_ws_string (pp, "__has_trivial_copy");
2617 break;
2618 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
2619 pp_cxx_ws_string (pp, "__has_trivial_destructor");
2620 break;
2621 case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
2622 pp_cxx_ws_string (pp, "__has_unique_object_representations");
2623 break;
2624 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
2625 pp_cxx_ws_string (pp, "__has_virtual_destructor");
2626 break;
2627 case CPTK_IS_ABSTRACT:
2628 pp_cxx_ws_string (pp, "__is_abstract");
2629 break;
2630 case CPTK_IS_AGGREGATE:
2631 pp_cxx_ws_string (pp, "__is_aggregate");
2632 break;
2633 case CPTK_IS_BASE_OF:
2634 pp_cxx_ws_string (pp, "__is_base_of");
2635 break;
2636 case CPTK_IS_CLASS:
2637 pp_cxx_ws_string (pp, "__is_class");
2638 break;
2639 case CPTK_IS_EMPTY:
2640 pp_cxx_ws_string (pp, "__is_empty");
2641 break;
2642 case CPTK_IS_ENUM:
2643 pp_cxx_ws_string (pp, "__is_enum");
2644 break;
2645 case CPTK_IS_FINAL:
2646 pp_cxx_ws_string (pp, "__is_final");
2647 break;
2648 case CPTK_IS_LAYOUT_COMPATIBLE:
2649 pp_cxx_ws_string (pp, "__is_layout_compatible");
2650 break;
2651 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
2652 pp_cxx_ws_string (pp, "__is_pointer_interconvertible_base_of");
2653 break;
2654 case CPTK_IS_POD:
2655 pp_cxx_ws_string (pp, "__is_pod");
2656 break;
2657 case CPTK_IS_POLYMORPHIC:
2658 pp_cxx_ws_string (pp, "__is_polymorphic");
2659 break;
2660 case CPTK_IS_SAME_AS:
2661 pp_cxx_ws_string (pp, "__is_same");
2662 break;
2663 case CPTK_IS_STD_LAYOUT:
2664 pp_cxx_ws_string (pp, "__is_std_layout");
2665 break;
2666 case CPTK_IS_TRIVIAL:
2667 pp_cxx_ws_string (pp, "__is_trivial");
2668 break;
2669 case CPTK_IS_TRIVIALLY_ASSIGNABLE:
2670 pp_cxx_ws_string (pp, "__is_trivially_assignable");
2671 break;
2672 case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
2673 pp_cxx_ws_string (pp, "__is_trivially_constructible");
2674 break;
2675 case CPTK_IS_TRIVIALLY_COPYABLE:
2676 pp_cxx_ws_string (pp, "__is_trivially_copyable");
2677 break;
2678 case CPTK_IS_UNION:
2679 pp_cxx_ws_string (pp, "__is_union");
2680 break;
2681 case CPTK_IS_LITERAL_TYPE:
2682 pp_cxx_ws_string (pp, "__is_literal_type");
2683 break;
2684 case CPTK_IS_ASSIGNABLE:
2685 pp_cxx_ws_string (pp, "__is_assignable");
2686 break;
2687 case CPTK_IS_CONSTRUCTIBLE:
2688 pp_cxx_ws_string (pp, "__is_constructible");
2689 break;
2690 case CPTK_IS_NOTHROW_ASSIGNABLE:
2691 pp_cxx_ws_string (pp, "__is_nothrow_assignable");
2692 break;
2693 case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
2694 pp_cxx_ws_string (pp, "__is_nothrow_constructible");
2695 break;
2696
2697 default:
2698 gcc_unreachable ();
2699 }
2700
2701 pp_cxx_left_paren (pp);
2702 pp->type_id (TRAIT_EXPR_TYPE1 (t));
2703
2704 if (kind == CPTK_IS_BASE_OF
2705 || kind == CPTK_IS_SAME_AS
2706 || kind == CPTK_IS_LAYOUT_COMPATIBLE
2707 || kind == CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF)
2708 {
2709 pp_cxx_separate_with (pp, ',');
2710 pp->type_id (TRAIT_EXPR_TYPE2 (t));
2711 }
2712
2713 pp_cxx_right_paren (pp);
2714 }
2715
2716 // requires-clause:
2717 // 'requires' logical-or-expression
2718 void
pp_cxx_requires_clause(cxx_pretty_printer * pp,tree t)2719 pp_cxx_requires_clause (cxx_pretty_printer *pp, tree t)
2720 {
2721 if (!t)
2722 return;
2723 pp->padding = pp_before;
2724 pp_cxx_ws_string (pp, "requires");
2725 pp_space (pp);
2726 pp->expression (t);
2727 }
2728
2729 /* requirement:
2730 simple-requirement
2731 compound-requirement
2732 type-requirement
2733 nested-requirement */
2734 static void
pp_cxx_requirement(cxx_pretty_printer * pp,tree t)2735 pp_cxx_requirement (cxx_pretty_printer *pp, tree t)
2736 {
2737 switch (TREE_CODE (t))
2738 {
2739 case SIMPLE_REQ:
2740 pp_cxx_simple_requirement (pp, t);
2741 break;
2742
2743 case TYPE_REQ:
2744 pp_cxx_type_requirement (pp, t);
2745 break;
2746
2747 case COMPOUND_REQ:
2748 pp_cxx_compound_requirement (pp, t);
2749 break;
2750
2751 case NESTED_REQ:
2752 pp_cxx_nested_requirement (pp, t);
2753 break;
2754
2755 default:
2756 gcc_unreachable ();
2757 }
2758 }
2759
2760 // requirement-list:
2761 // requirement
2762 // requirement-list ';' requirement[opt]
2763 //
2764 static void
pp_cxx_requirement_list(cxx_pretty_printer * pp,tree t)2765 pp_cxx_requirement_list (cxx_pretty_printer *pp, tree t)
2766 {
2767 for (; t; t = TREE_CHAIN (t))
2768 pp_cxx_requirement (pp, TREE_VALUE (t));
2769 }
2770
2771 // requirement-body:
2772 // '{' requirement-list '}'
2773 static void
pp_cxx_requirement_body(cxx_pretty_printer * pp,tree t)2774 pp_cxx_requirement_body (cxx_pretty_printer *pp, tree t)
2775 {
2776 pp_cxx_left_brace (pp);
2777 pp_cxx_requirement_list (pp, t);
2778 pp_cxx_right_brace (pp);
2779 }
2780
2781 // requires-expression:
2782 // 'requires' requirement-parameter-list requirement-body
2783 void
pp_cxx_requires_expr(cxx_pretty_printer * pp,tree t)2784 pp_cxx_requires_expr (cxx_pretty_printer *pp, tree t)
2785 {
2786 pp_string (pp, "requires");
2787 if (tree parms = REQUIRES_EXPR_PARMS (t))
2788 {
2789 bool first = true;
2790 pp_cxx_left_paren (pp);
2791 for (; parms; parms = TREE_CHAIN (parms))
2792 {
2793 if (!first)
2794 pp_cxx_separate_with (pp, ',' );
2795 first = false;
2796 pp_cxx_parameter_declaration (pp, parms);
2797 }
2798 pp_cxx_right_paren (pp);
2799 pp_cxx_whitespace (pp);
2800 }
2801 pp_cxx_requirement_body (pp, TREE_OPERAND (t, 1));
2802 }
2803
2804 /* simple-requirement:
2805 expression ';' */
2806 void
pp_cxx_simple_requirement(cxx_pretty_printer * pp,tree t)2807 pp_cxx_simple_requirement (cxx_pretty_printer *pp, tree t)
2808 {
2809 pp->expression (TREE_OPERAND (t, 0));
2810 pp_cxx_semicolon (pp);
2811 }
2812
2813 /* type-requirement:
2814 typename type-name ';' */
2815 void
pp_cxx_type_requirement(cxx_pretty_printer * pp,tree t)2816 pp_cxx_type_requirement (cxx_pretty_printer *pp, tree t)
2817 {
2818 pp->type_id (TREE_OPERAND (t, 0));
2819 pp_cxx_semicolon (pp);
2820 }
2821
2822 /* compound-requirement:
2823 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] */
2824 void
pp_cxx_compound_requirement(cxx_pretty_printer * pp,tree t)2825 pp_cxx_compound_requirement (cxx_pretty_printer *pp, tree t)
2826 {
2827 pp_cxx_left_brace (pp);
2828 pp->expression (TREE_OPERAND (t, 0));
2829 pp_cxx_right_brace (pp);
2830
2831 if (COMPOUND_REQ_NOEXCEPT_P (t))
2832 pp_cxx_ws_string (pp, "noexcept");
2833
2834 if (tree type = TREE_OPERAND (t, 1))
2835 {
2836 pp_cxx_whitespace (pp);
2837 pp_cxx_ws_string (pp, "->");
2838 pp->type_id (type);
2839 }
2840 pp_cxx_semicolon (pp);
2841 }
2842
2843 /* nested requirement:
2844 'requires' constraint-expression */
2845 void
pp_cxx_nested_requirement(cxx_pretty_printer * pp,tree t)2846 pp_cxx_nested_requirement (cxx_pretty_printer *pp, tree t)
2847 {
2848 pp_cxx_ws_string (pp, "requires");
2849 pp->expression (TREE_OPERAND (t, 0));
2850 pp_cxx_semicolon (pp);
2851 }
2852
2853 void
pp_cxx_check_constraint(cxx_pretty_printer * pp,tree t)2854 pp_cxx_check_constraint (cxx_pretty_printer *pp, tree t)
2855 {
2856 tree decl = CHECK_CONSTR_CONCEPT (t);
2857 tree tmpl = DECL_TI_TEMPLATE (decl);
2858 tree args = CHECK_CONSTR_ARGS (t);
2859 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
2860
2861 if (TREE_CODE (decl) == CONCEPT_DECL)
2862 pp->expression (id);
2863 else if (VAR_P (decl))
2864 pp->expression (id);
2865 else if (TREE_CODE (decl) == FUNCTION_DECL)
2866 {
2867 tree call = build_vl_exp (CALL_EXPR, 2);
2868 TREE_OPERAND (call, 0) = integer_two_node;
2869 TREE_OPERAND (call, 1) = id;
2870 pp->expression (call);
2871 }
2872 else
2873 gcc_unreachable ();
2874 }
2875
2876 /* Output the "[with ...]" clause for a parameter mapping of an atomic
2877 constraint. */
2878
2879 void
pp_cxx_parameter_mapping(cxx_pretty_printer * pp,tree map)2880 pp_cxx_parameter_mapping (cxx_pretty_printer *pp, tree map)
2881 {
2882 pp_cxx_whitespace (pp);
2883 pp_cxx_left_bracket (pp);
2884 pp->translate_string ("with");
2885 pp_cxx_whitespace (pp);
2886
2887 for (tree p = map; p; p = TREE_CHAIN (p))
2888 {
2889 tree parm = TREE_VALUE (p);
2890 tree arg = TREE_PURPOSE (p);
2891
2892 if (TYPE_P (parm))
2893 pp->type_id (parm);
2894 else if (tree name = DECL_NAME (TEMPLATE_PARM_DECL (parm)))
2895 pp_cxx_tree_identifier (pp, name);
2896 else
2897 pp->translate_string ("<unnamed>");
2898
2899 pp_cxx_whitespace (pp);
2900 pp_equal (pp);
2901 pp_cxx_whitespace (pp);
2902
2903 if (TYPE_P (arg) || DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
2904 pp->type_id (arg);
2905 else
2906 pp->expression (arg);
2907
2908 if (TREE_CHAIN (p) != NULL_TREE)
2909 pp_cxx_separate_with (pp, ';');
2910 }
2911
2912 pp_cxx_right_bracket (pp);
2913 }
2914
2915 void
pp_cxx_atomic_constraint(cxx_pretty_printer * pp,tree t)2916 pp_cxx_atomic_constraint (cxx_pretty_printer *pp, tree t)
2917 {
2918 /* Emit the expression. */
2919 pp->expression (ATOMIC_CONSTR_EXPR (t));
2920
2921 /* Emit the parameter mapping. */
2922 tree map = ATOMIC_CONSTR_MAP (t);
2923 if (map && map != error_mark_node)
2924 pp_cxx_parameter_mapping (pp, map);
2925 }
2926
2927 void
pp_cxx_conjunction(cxx_pretty_printer * pp,tree t)2928 pp_cxx_conjunction (cxx_pretty_printer *pp, tree t)
2929 {
2930 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2931 pp_string (pp, " /\\ ");
2932 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2933 }
2934
2935 void
pp_cxx_disjunction(cxx_pretty_printer * pp,tree t)2936 pp_cxx_disjunction (cxx_pretty_printer *pp, tree t)
2937 {
2938 pp_cxx_constraint (pp, TREE_OPERAND (t, 0));
2939 pp_string (pp, " \\/ ");
2940 pp_cxx_constraint (pp, TREE_OPERAND (t, 1));
2941 }
2942
2943 void
pp_cxx_constraint(cxx_pretty_printer * pp,tree t)2944 pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
2945 {
2946 if (t == error_mark_node)
2947 return pp->expression (t);
2948
2949 switch (TREE_CODE (t))
2950 {
2951 case ATOMIC_CONSTR:
2952 pp_cxx_atomic_constraint (pp, t);
2953 break;
2954
2955 case CHECK_CONSTR:
2956 pp_cxx_check_constraint (pp, t);
2957 break;
2958
2959 case CONJ_CONSTR:
2960 pp_cxx_conjunction (pp, t);
2961 break;
2962
2963 case DISJ_CONSTR:
2964 pp_cxx_disjunction (pp, t);
2965 break;
2966
2967 case EXPR_PACK_EXPANSION:
2968 pp->expression (TREE_OPERAND (t, 0));
2969 break;
2970
2971 default:
2972 gcc_unreachable ();
2973 }
2974 }
2975
2976
2977 typedef c_pretty_print_fn pp_fun;
2978
2979 /* Initialization of a C++ pretty-printer object. */
2980
cxx_pretty_printer()2981 cxx_pretty_printer::cxx_pretty_printer ()
2982 : c_pretty_printer (),
2983 enclosing_scope (global_namespace)
2984 {
2985 type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
2986 parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
2987 }
2988
2989 /* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */
2990
2991 pretty_printer *
clone() const2992 cxx_pretty_printer::clone () const
2993 {
2994 return new cxx_pretty_printer (*this);
2995 }
2996