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