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