Branch data Line data Source code
1 : : /* Subroutines common to both C and C++ pretty-printers.
2 : : Copyright (C) 2002-2025 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 "c-pretty-print.h"
25 : : #include "gimple-pretty-print.h"
26 : : #include "diagnostic.h"
27 : : #include "stor-layout.h"
28 : : #include "stringpool.h"
29 : : #include "attribs.h"
30 : : #include "intl.h"
31 : : #include "tree-pretty-print.h"
32 : : #include "selftest.h"
33 : : #include "langhooks.h"
34 : : #include "options.h"
35 : : #include "internal-fn.h"
36 : : #include "function.h"
37 : : #include "basic-block.h"
38 : : #include "gimple.h"
39 : : #include "tm.h"
40 : :
41 : : /* The pretty-printer code is primarily designed to closely follow
42 : : (GNU) C and C++ grammars. That is to be contrasted with spaghetti
43 : : codes we used to have in the past. Following a structured
44 : : approach (preferably the official grammars) is believed to make it
45 : : much easier to add extensions and nifty pretty-printing effects that
46 : : takes expression or declaration contexts into account. */
47 : :
48 : :
49 : : /* literal */
50 : : static void pp_c_char (c_pretty_printer *, int);
51 : :
52 : : /* postfix-expression */
53 : : static void pp_c_initializer_list (c_pretty_printer *, tree);
54 : : static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree);
55 : :
56 : : static void pp_c_additive_expression (c_pretty_printer *, tree);
57 : : static void pp_c_shift_expression (c_pretty_printer *, tree);
58 : : static void pp_c_relational_expression (c_pretty_printer *, tree);
59 : : static void pp_c_equality_expression (c_pretty_printer *, tree);
60 : : static void pp_c_and_expression (c_pretty_printer *, tree);
61 : : static void pp_c_exclusive_or_expression (c_pretty_printer *, tree);
62 : : static void pp_c_inclusive_or_expression (c_pretty_printer *, tree);
63 : : static void pp_c_logical_and_expression (c_pretty_printer *, tree);
64 : :
65 : : /* declarations. */
66 : :
67 : :
68 : : /* Helper functions. */
69 : :
70 : : void
71 : 38267127 : pp_c_whitespace (c_pretty_printer *pp)
72 : : {
73 : 38267127 : pp_space (pp);
74 : 38267127 : pp->set_padding (pp_none);
75 : 38267127 : }
76 : :
77 : : void
78 : 2873597 : pp_c_left_paren (c_pretty_printer *pp)
79 : : {
80 : 2873597 : pp_left_paren (pp);
81 : 2873597 : pp->set_padding (pp_none);
82 : 2873597 : }
83 : :
84 : : void
85 : 2873597 : pp_c_right_paren (c_pretty_printer *pp)
86 : : {
87 : 2873597 : pp_right_paren (pp);
88 : 2873597 : pp->set_padding (pp_none);
89 : 2873597 : }
90 : :
91 : : void
92 : 6575 : pp_c_left_brace (c_pretty_printer *pp)
93 : : {
94 : 6575 : pp_left_brace (pp);
95 : 6575 : pp->set_padding (pp_none);
96 : 6575 : }
97 : :
98 : : void
99 : 6575 : pp_c_right_brace (c_pretty_printer *pp)
100 : : {
101 : 6575 : pp_right_brace (pp);
102 : 6575 : pp->set_padding (pp_none);
103 : 6575 : }
104 : :
105 : : void
106 : 402026 : pp_c_left_bracket (c_pretty_printer *pp)
107 : : {
108 : 402026 : pp_left_bracket (pp);
109 : 402026 : pp->set_padding (pp_none);
110 : 402026 : }
111 : :
112 : : void
113 : 402026 : pp_c_right_bracket (c_pretty_printer *pp)
114 : : {
115 : 402026 : pp_right_bracket (pp);
116 : 402026 : pp->set_padding (pp_none);
117 : 402026 : }
118 : :
119 : : void
120 : 3600 : pp_c_dot (c_pretty_printer *pp)
121 : : {
122 : 3600 : pp_dot (pp);
123 : 3600 : pp->set_padding (pp_none);
124 : 3600 : }
125 : :
126 : : void
127 : 4249 : pp_c_ampersand (c_pretty_printer *pp)
128 : : {
129 : 4249 : pp_ampersand (pp);
130 : 4249 : pp->set_padding (pp_none);
131 : 4249 : }
132 : :
133 : : void
134 : 206224 : pp_c_star (c_pretty_printer *pp)
135 : : {
136 : 206224 : pp_star (pp);
137 : 206224 : pp->set_padding (pp_none);
138 : 206224 : }
139 : :
140 : : void
141 : 1847 : pp_c_arrow (c_pretty_printer *pp)
142 : : {
143 : 1847 : pp_arrow (pp);
144 : 1847 : pp->set_padding (pp_none);
145 : 1847 : }
146 : :
147 : : void
148 : 226 : pp_c_semicolon (c_pretty_printer *pp)
149 : : {
150 : 226 : pp_semicolon (pp);
151 : 226 : pp->set_padding (pp_none);
152 : 226 : }
153 : :
154 : : void
155 : 2232598 : pp_c_complement (c_pretty_printer *pp)
156 : : {
157 : 2232598 : pp_complement (pp);
158 : 2232598 : pp->set_padding (pp_none);
159 : 2232598 : }
160 : :
161 : : void
162 : 0 : pp_c_exclamation (c_pretty_printer *pp)
163 : : {
164 : 0 : pp_exclamation (pp);
165 : 0 : pp->set_padding (pp_none);
166 : 0 : }
167 : :
168 : : /* Print out the external representation of QUALIFIERS. */
169 : :
170 : : void
171 : 186840231 : pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type)
172 : : {
173 : 186840231 : const char *p = pp_last_position_in_text (pp);
174 : :
175 : 186840231 : if (!qualifiers)
176 : : return;
177 : :
178 : : /* The C programming language does not have references, but it is much
179 : : simpler to handle those here rather than going through the same
180 : : logic in the C++ pretty-printer. */
181 : 12635803 : if (p != NULL && (*p == '*' || *p == '&'))
182 : 1220428 : pp_c_whitespace (pp);
183 : :
184 : 12635803 : if (qualifiers & TYPE_QUAL_ATOMIC)
185 : 134 : pp_c_ws_string (pp, "_Atomic");
186 : 12635803 : if (qualifiers & TYPE_QUAL_CONST)
187 : 25192712 : pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
188 : 12635803 : if (qualifiers & TYPE_QUAL_VOLATILE)
189 : 358849 : pp_c_ws_string (pp, func_type ? "__attribute__((noreturn))" : "volatile");
190 : 12635803 : if (qualifiers & TYPE_QUAL_RESTRICT)
191 : 1002 : pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
192 : : ? "restrict" : "__restrict__"));
193 : : }
194 : :
195 : : /* Pretty-print T using the type-cast notation '( type-name )'. */
196 : :
197 : : void
198 : 655055 : pp_c_type_cast (c_pretty_printer *pp, tree t)
199 : : {
200 : 655055 : pp_c_left_paren (pp);
201 : 655055 : pp->type_id (t);
202 : 655055 : pp_c_right_paren (pp);
203 : 655055 : }
204 : :
205 : : /* We're about to pretty-print a pointer type as indicated by T.
206 : : Output a whitespace, if needed, preparing for subsequent output. */
207 : :
208 : : void
209 : 142 : pp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t)
210 : : {
211 : 142 : if (POINTER_TYPE_P (t))
212 : : {
213 : 67 : tree pointee = strip_pointer_operator (TREE_TYPE (t));
214 : 67 : if (TREE_CODE (pointee) != ARRAY_TYPE
215 : 67 : && TREE_CODE (pointee) != FUNCTION_TYPE)
216 : 67 : pp_c_whitespace (pp);
217 : : }
218 : 142 : }
219 : :
220 : :
221 : : /* Declarations. */
222 : :
223 : : /* C++ cv-qualifiers are called type-qualifiers in C. Print out the
224 : : cv-qualifiers of T. If T is a declaration then it is the cv-qualifier
225 : : of its type. Take care of possible extensions.
226 : :
227 : : type-qualifier-list:
228 : : type-qualifier
229 : : type-qualifier-list type-qualifier
230 : :
231 : : type-qualifier:
232 : : const
233 : : restrict -- C99
234 : : __restrict__ -- GNU C
235 : : address-space-qualifier -- GNU C
236 : : volatile
237 : : _Atomic -- C11
238 : :
239 : : address-space-qualifier:
240 : : identifier -- GNU C */
241 : :
242 : : void
243 : 186152545 : pp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
244 : : {
245 : 186152545 : int qualifiers;
246 : :
247 : 186152545 : if (!t || t == error_mark_node)
248 : : return;
249 : :
250 : 186152530 : if (!TYPE_P (t))
251 : 0 : t = TREE_TYPE (t);
252 : :
253 : 186152530 : if (TREE_CODE (t) != ARRAY_TYPE)
254 : : {
255 : 186116216 : qualifiers = TYPE_QUALS (t);
256 : 186116216 : pp_c_cv_qualifiers (pp, qualifiers,
257 : : TREE_CODE (t) == FUNCTION_TYPE);
258 : : }
259 : :
260 : 186152530 : if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t)))
261 : : {
262 : 3 : const char *as = c_addr_space_name (TYPE_ADDR_SPACE (t));
263 : 3 : pp_c_identifier (pp, as);
264 : : }
265 : : }
266 : :
267 : : /* pointer:
268 : : * type-qualifier-list(opt)
269 : : * type-qualifier-list(opt) pointer */
270 : :
271 : : static void
272 : 12704 : pp_c_pointer (c_pretty_printer *pp, tree t)
273 : : {
274 : 12704 : if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
275 : 0 : t = TREE_TYPE (t);
276 : 12704 : switch (TREE_CODE (t))
277 : : {
278 : 12704 : case POINTER_TYPE:
279 : : /* It is easier to handle C++ reference types here. */
280 : 12704 : case REFERENCE_TYPE:
281 : 12704 : if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
282 : 363 : pp_c_pointer (pp, TREE_TYPE (t));
283 : 12704 : if (TREE_CODE (t) == POINTER_TYPE)
284 : 8554 : pp_c_star (pp);
285 : : else
286 : : {
287 : 4150 : pp_c_ampersand (pp);
288 : 4150 : if (TYPE_REF_IS_RVALUE (t))
289 : 87 : pp_c_ampersand (pp);
290 : : }
291 : 12704 : pp_c_type_qualifier_list (pp, t);
292 : 12704 : break;
293 : :
294 : : /* ??? This node is now in GENERIC and so shouldn't be here. But
295 : : we'll fix that later. */
296 : 0 : case DECL_EXPR:
297 : 0 : pp->declaration (DECL_EXPR_DECL (t));
298 : 0 : pp_needs_newline (pp) = true;
299 : 0 : break;
300 : :
301 : 0 : default:
302 : 0 : pp_unsupported_tree (pp, t);
303 : : }
304 : 12704 : }
305 : :
306 : : /* simple-type-specifier:
307 : : type-specifier
308 : :
309 : : type-specifier:
310 : : void
311 : : char
312 : : short
313 : : int
314 : : long
315 : : float
316 : : double
317 : : signed
318 : : unsigned
319 : : _Bool -- C99
320 : : _Complex -- C99
321 : : _Imaginary -- C99
322 : : nullptr_t -- C23
323 : : struct-or-union-specifier
324 : : enum-specifier
325 : : typedef-name.
326 : :
327 : : GNU extensions.
328 : : simple-type-specifier:
329 : : __complex__
330 : : __vector__ */
331 : :
332 : : void
333 : 97829891 : c_pretty_printer::simple_type_specifier (tree t)
334 : : {
335 : 97829891 : const enum tree_code code = TREE_CODE (t);
336 : 97829891 : switch (code)
337 : : {
338 : 15 : case ERROR_MARK:
339 : 15 : translate_string ("<type-error>");
340 : 15 : break;
341 : :
342 : 117 : case IDENTIFIER_NODE:
343 : 117 : pp_c_identifier (this, IDENTIFIER_POINTER (t));
344 : 117 : break;
345 : :
346 : 48913537 : case VOID_TYPE:
347 : 48913537 : case OPAQUE_TYPE:
348 : 48913537 : case BOOLEAN_TYPE:
349 : 48913537 : case INTEGER_TYPE:
350 : 48913537 : case REAL_TYPE:
351 : 48913537 : case FIXED_POINT_TYPE:
352 : 48913537 : if (TYPE_NAME (t))
353 : : {
354 : 48913246 : t = TYPE_NAME (t);
355 : 48913246 : simple_type_specifier (t);
356 : : }
357 : : else
358 : : {
359 : 291 : int prec = TYPE_PRECISION (t);
360 : 291 : tree common_t;
361 : 291 : if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (t)))
362 : 0 : common_t = c_common_type_for_mode (TYPE_MODE (t),
363 : 0 : TYPE_SATURATING (t));
364 : : else
365 : 291 : common_t = c_common_type_for_mode (TYPE_MODE (t),
366 : 291 : TYPE_UNSIGNED (t));
367 : 291 : if (common_t && TYPE_NAME (common_t))
368 : : {
369 : 264 : simple_type_specifier (common_t);
370 : 264 : if (TYPE_PRECISION (common_t) != prec)
371 : : {
372 : 151 : pp_colon (this);
373 : 151 : pp_decimal_int (this, prec);
374 : : }
375 : : }
376 : : else
377 : : {
378 : 27 : switch (code)
379 : : {
380 : 0 : case INTEGER_TYPE:
381 : 0 : translate_string (TYPE_UNSIGNED (t)
382 : : ? "<unnamed-unsigned:"
383 : : : "<unnamed-signed:");
384 : 0 : break;
385 : 27 : case REAL_TYPE:
386 : 27 : translate_string ("<unnamed-float:");
387 : 27 : break;
388 : 0 : case FIXED_POINT_TYPE:
389 : 0 : translate_string ("<unnamed-fixed:");
390 : 0 : break;
391 : 0 : default:
392 : 0 : gcc_unreachable ();
393 : : }
394 : 27 : pp_decimal_int (this, prec);
395 : 27 : pp_greater (this);
396 : : }
397 : : }
398 : : break;
399 : :
400 : 43 : case BITINT_TYPE:
401 : 43 : if (TYPE_NAME (t))
402 : : {
403 : 0 : t = TYPE_NAME (t);
404 : 0 : simple_type_specifier (t);
405 : : }
406 : : else
407 : : {
408 : 43 : int prec = TYPE_PRECISION (t);
409 : 43 : if (TYPE_UNSIGNED (t))
410 : 13 : pp_c_ws_string (this, "unsigned");
411 : 43 : pp_c_ws_string (this, "_BitInt(");;
412 : 43 : pp_decimal_int (this, prec);
413 : 43 : pp_right_paren (this);
414 : : }
415 : : break;
416 : :
417 : 48913129 : case TYPE_DECL:
418 : 48913129 : if (DECL_NAME (t))
419 : 48913129 : id_expression (t);
420 : : else
421 : 0 : translate_string ("<typedef-error>");
422 : : break;
423 : :
424 : 3043 : case UNION_TYPE:
425 : 3043 : case RECORD_TYPE:
426 : 3043 : case ENUMERAL_TYPE:
427 : 3043 : if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
428 : : /* Don't decorate the type if this is a typedef name. */;
429 : 2168 : else if (code == UNION_TYPE)
430 : 167 : pp_c_ws_string (this, "union");
431 : 2001 : else if (code == RECORD_TYPE)
432 : 1676 : pp_c_ws_string (this, "struct");
433 : 325 : else if (code == ENUMERAL_TYPE)
434 : 325 : pp_c_ws_string (this, "enum");
435 : : else
436 : : translate_string ("<tag-error>");
437 : :
438 : 3043 : if (TYPE_NAME (t))
439 : 2999 : id_expression (TYPE_NAME (t));
440 : : else
441 : 44 : translate_string ("<anonymous>");
442 : : break;
443 : 7 : case NULLPTR_TYPE:
444 : 7 : pp_c_ws_string (this, "nullptr_t");
445 : 7 : break;
446 : :
447 : 0 : default:
448 : 0 : pp_unsupported_tree (this, t);
449 : 0 : break;
450 : : }
451 : 97829891 : }
452 : :
453 : : /* specifier-qualifier-list:
454 : : type-specifier specifier-qualifier-list-opt
455 : : type-qualifier specifier-qualifier-list-opt
456 : :
457 : :
458 : : Implementation note: Because of the non-linearities in array or
459 : : function declarations, this routine prints not just the
460 : : specifier-qualifier-list of such entities or types of such entities,
461 : : but also the 'pointer' production part of their declarators. The
462 : : remaining part is done by declarator() or abstract_declarator(). */
463 : :
464 : : void
465 : 49631887 : pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
466 : : {
467 : 49631887 : const enum tree_code code = TREE_CODE (t);
468 : :
469 : 49631887 : if (!(pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
470 : 388000 : pp_c_type_qualifier_list (pp, t);
471 : 49623696 : switch (code)
472 : : {
473 : 12341 : case REFERENCE_TYPE:
474 : 12341 : case POINTER_TYPE:
475 : 12341 : {
476 : : /* Get the types-specifier of this type. */
477 : 12341 : tree pointee = strip_pointer_operator (TREE_TYPE (t));
478 : 12341 : pp_c_specifier_qualifier_list (pp, pointee);
479 : 12341 : if (TREE_CODE (pointee) == ARRAY_TYPE
480 : 11824 : || TREE_CODE (pointee) == FUNCTION_TYPE)
481 : : {
482 : 2405 : pp_c_whitespace (pp);
483 : 2405 : pp_c_left_paren (pp);
484 : : /* If we're dealing with the GNU form of attributes, print this:
485 : : void (__attribute__((noreturn)) *f) ();
486 : : If it is the standard [[]] attribute, we'll print the attribute
487 : : in c_pretty_printer::direct_abstract_declarator/FUNCTION_TYPE. */
488 : 2405 : if (!cxx11_attribute_p (TYPE_ATTRIBUTES (pointee)))
489 : 2401 : pp_c_attributes_display (pp, TYPE_ATTRIBUTES (pointee));
490 : : }
491 : 9936 : else if (!c_dialect_cxx ())
492 : 5500 : pp_c_whitespace (pp);
493 : 12341 : pp_ptr_operator (pp, t);
494 : : }
495 : 12341 : break;
496 : :
497 : 38919 : case FUNCTION_TYPE:
498 : 38919 : case ARRAY_TYPE:
499 : 38919 : pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
500 : 38919 : break;
501 : :
502 : 3466 : case VECTOR_TYPE:
503 : 3466 : case COMPLEX_TYPE:
504 : 3466 : if (code == COMPLEX_TYPE)
505 : 589 : pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
506 : : ? "_Complex" : "__complex__"));
507 : 3119 : else if (code == VECTOR_TYPE)
508 : : {
509 : : /* The syntax we print for vector types isn't real C or C++ syntax,
510 : : so it's better to print the type name if we have one. */
511 : 3119 : tree name = TYPE_NAME (t);
512 : 3119 : if (!(pp->flags & pp_c_flag_gnu_v3)
513 : 1262 : && name
514 : 23 : && TREE_CODE (name) == TYPE_DECL)
515 : : {
516 : 23 : pp->id_expression (name);
517 : 23 : break;
518 : : }
519 : 3096 : pp_c_ws_string (pp, "__vector");
520 : 3096 : pp_c_left_paren (pp);
521 : 3096 : pp_wide_integer (pp, TYPE_VECTOR_SUBPARTS (t));
522 : 3096 : pp_c_right_paren (pp);
523 : 3096 : pp_c_whitespace (pp);
524 : : }
525 : 3443 : pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
526 : 3443 : break;
527 : :
528 : 49577161 : default:
529 : 49577161 : pp->simple_type_specifier (t);
530 : 49577161 : break;
531 : : }
532 : 49631887 : if ((pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
533 : 49235696 : pp_c_type_qualifier_list (pp, t);
534 : 49631887 : }
535 : :
536 : : /* parameter-type-list:
537 : : parameter-list
538 : : parameter-list , ...
539 : :
540 : : parameter-list:
541 : : parameter-declaration
542 : : parameter-list , parameter-declaration
543 : :
544 : : parameter-declaration:
545 : : declaration-specifiers declarator
546 : : declaration-specifiers abstract-declarator(opt) */
547 : :
548 : : void
549 : 2589 : pp_c_parameter_type_list (c_pretty_printer *pp, tree t)
550 : : {
551 : 2589 : bool want_parm_decl = DECL_P (t) && !(pp->flags & pp_c_flag_abstract);
552 : 2589 : tree parms = want_parm_decl ? DECL_ARGUMENTS (t) : TYPE_ARG_TYPES (t);
553 : 2589 : pp_c_left_paren (pp);
554 : 2589 : if (parms == void_list_node)
555 : 889 : pp_c_ws_string (pp, "void");
556 : : else
557 : : {
558 : : bool first = true;
559 : 4340 : for ( ; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
560 : : {
561 : 2640 : if (!first)
562 : 1065 : pp_separate_with (pp, ',');
563 : 2640 : first = false;
564 : 2640 : pp->declaration_specifiers
565 : 5280 : (want_parm_decl ? parms : TREE_VALUE (parms));
566 : 2640 : if (want_parm_decl)
567 : 0 : pp->declarator (parms);
568 : : else
569 : 2640 : pp->abstract_declarator (TREE_VALUE (parms));
570 : : }
571 : 1700 : if (!first && !parms)
572 : : {
573 : 68 : pp_separate_with (pp, ',');
574 : 68 : pp_string (pp, "...");
575 : : }
576 : : }
577 : 2589 : pp_c_right_paren (pp);
578 : 2589 : }
579 : :
580 : : /* abstract-declarator:
581 : : pointer
582 : : pointer(opt) direct-abstract-declarator */
583 : :
584 : : void
585 : 32506 : c_pretty_printer::abstract_declarator (tree t)
586 : : {
587 : 32506 : if (TREE_CODE (t) == POINTER_TYPE)
588 : : {
589 : 8140 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
590 : 8140 : || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
591 : 2286 : pp_c_right_paren (this);
592 : 8140 : t = TREE_TYPE (t);
593 : : }
594 : :
595 : 32506 : direct_abstract_declarator (t);
596 : 32506 : }
597 : :
598 : : /* direct-abstract-declarator:
599 : : ( abstract-declarator )
600 : : direct-abstract-declarator(opt) [ assignment-expression(opt) ]
601 : : direct-abstract-declarator(opt) [ * ]
602 : : direct-abstract-declarator(opt) ( parameter-type-list(opt) ) */
603 : :
604 : : void
605 : 74358 : c_pretty_printer::direct_abstract_declarator (tree t)
606 : : {
607 : 74358 : bool add_space = false;
608 : :
609 : 74358 : switch (TREE_CODE (t))
610 : : {
611 : 1141 : case POINTER_TYPE:
612 : 1141 : abstract_declarator (t);
613 : 1141 : break;
614 : :
615 : 2589 : case FUNCTION_TYPE:
616 : 2589 : pp_c_parameter_type_list (this, t);
617 : 2589 : direct_abstract_declarator (TREE_TYPE (t));
618 : : /* If this is the standard [[]] attribute, print
619 : : void (*)() [[noreturn]]; */
620 : 2589 : if (cxx11_attribute_p (TYPE_ATTRIBUTES (t)))
621 : : {
622 : 4 : pp_space (this);
623 : 4 : pp_c_attributes_display (this, TYPE_ATTRIBUTES (t));
624 : : }
625 : : break;
626 : :
627 : 36310 : case ARRAY_TYPE:
628 : 36310 : pp_c_left_bracket (this);
629 : :
630 : 36310 : if (int quals = TYPE_QUALS (t))
631 : : {
632 : : /* Print the array qualifiers such as in "T[const restrict 3]". */
633 : 37 : pp_c_cv_qualifiers (this, quals, false);
634 : 37 : add_space = true;
635 : : }
636 : :
637 : 36310 : if (tree arr = lookup_attribute ("array", TYPE_ATTRIBUTES (t)))
638 : : {
639 : 809 : if (TREE_VALUE (arr))
640 : : {
641 : : /* Print the specifier as in "T[static 3]" that's not actually
642 : : part of the type but may be added by the front end. */
643 : 48 : pp_c_ws_string (this, "static");
644 : 48 : add_space = true;
645 : : }
646 : 761 : else if (!TYPE_DOMAIN (t))
647 : : /* For arrays of unspecified bound using the [*] notation. */
648 : 78 : pp_character (this, '*');
649 : : }
650 : :
651 : 36310 : if (tree dom = TYPE_DOMAIN (t))
652 : : {
653 : 35020 : if (tree maxval = TYPE_MAX_VALUE (dom))
654 : : {
655 : 34640 : if (add_space)
656 : 64 : pp_space (this);
657 : :
658 : 34640 : tree type = TREE_TYPE (maxval);
659 : :
660 : 34640 : if (tree_fits_shwi_p (maxval))
661 : 25333 : pp_wide_integer (this, tree_to_shwi (maxval) + 1);
662 : 9307 : else if (TREE_CODE (maxval) == INTEGER_CST)
663 : 0 : expression (fold_build2 (PLUS_EXPR, type, maxval,
664 : : build_int_cst (type, 1)));
665 : : else
666 : : {
667 : : /* Strip the expressions from around a VLA bound added
668 : : internally to make it fit the domain mold, including
669 : : any casts. */
670 : 9307 : if (TREE_CODE (maxval) == NOP_EXPR)
671 : 9191 : maxval = TREE_OPERAND (maxval, 0);
672 : 9307 : if (TREE_CODE (maxval) == PLUS_EXPR
673 : 9307 : && integer_all_onesp (TREE_OPERAND (maxval, 1)))
674 : : {
675 : 8502 : maxval = TREE_OPERAND (maxval, 0);
676 : 8502 : if (TREE_CODE (maxval) == NOP_EXPR)
677 : 8502 : maxval = TREE_OPERAND (maxval, 0);
678 : : }
679 : 9307 : if (TREE_CODE (maxval) == SAVE_EXPR)
680 : : {
681 : 8502 : maxval = TREE_OPERAND (maxval, 0);
682 : 8502 : if (TREE_CODE (maxval) == NOP_EXPR)
683 : 0 : maxval = TREE_OPERAND (maxval, 0);
684 : : }
685 : :
686 : : /* This covers unspecified bounds. */
687 : 9307 : if (TREE_CODE (maxval) == COMPOUND_EXPR)
688 : 42 : pp_string (this, "*");
689 : : else
690 : 9265 : expression (maxval);
691 : : }
692 : : }
693 : 380 : else if (TYPE_SIZE (t))
694 : : /* Print zero for zero-length arrays but not for flexible
695 : : array members whose TYPE_SIZE is null. */
696 : 244 : pp_string (this, "0");
697 : : }
698 : 36310 : pp_c_right_bracket (this);
699 : 36310 : direct_abstract_declarator (TREE_TYPE (t));
700 : 36310 : break;
701 : :
702 : : case IDENTIFIER_NODE:
703 : : case VOID_TYPE:
704 : : case OPAQUE_TYPE:
705 : : case BOOLEAN_TYPE:
706 : : case INTEGER_TYPE:
707 : : case REAL_TYPE:
708 : : case FIXED_POINT_TYPE:
709 : : case ENUMERAL_TYPE:
710 : : case BITINT_TYPE:
711 : : case RECORD_TYPE:
712 : : case UNION_TYPE:
713 : : case VECTOR_TYPE:
714 : : case COMPLEX_TYPE:
715 : : case TYPE_DECL:
716 : : case ERROR_MARK:
717 : : case NULLPTR_TYPE:
718 : : break;
719 : :
720 : 0 : default:
721 : 0 : pp_unsupported_tree (this, t);
722 : 0 : break;
723 : : }
724 : 74358 : }
725 : :
726 : : /* type-name:
727 : : specifier-qualifier-list abstract-declarator(opt) */
728 : :
729 : : void
730 : 35756 : c_pretty_printer::type_id (tree t)
731 : : {
732 : 35756 : pp_c_specifier_qualifier_list (this, t);
733 : 35756 : abstract_declarator (t);
734 : 35756 : }
735 : :
736 : : /* storage-class-specifier:
737 : : typedef
738 : : extern
739 : : static
740 : : auto
741 : : register */
742 : :
743 : : void
744 : 2957 : c_pretty_printer::storage_class_specifier (tree t)
745 : : {
746 : 2957 : if (TREE_CODE (t) == TYPE_DECL)
747 : 0 : pp_c_ws_string (this, "typedef");
748 : 2957 : else if (DECL_P (t))
749 : : {
750 : 142 : if ((TREE_CODE (t) == PARM_DECL || VAR_P (t))
751 : 142 : && DECL_REGISTER (t))
752 : 0 : pp_c_ws_string (this, "register");
753 : 142 : else if (TREE_STATIC (t) && VAR_P (t))
754 : 0 : pp_c_ws_string (this, "static");
755 : : }
756 : 2957 : }
757 : :
758 : : /* function-specifier:
759 : : inline */
760 : :
761 : : void
762 : 2640 : c_pretty_printer::function_specifier (tree t)
763 : : {
764 : 2640 : if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
765 : 0 : pp_c_ws_string (this, "inline");
766 : 2640 : }
767 : :
768 : : /* declaration-specifiers:
769 : : storage-class-specifier declaration-specifiers(opt)
770 : : type-specifier declaration-specifiers(opt)
771 : : type-qualifier declaration-specifiers(opt)
772 : : function-specifier declaration-specifiers(opt) */
773 : :
774 : : void
775 : 2815 : c_pretty_printer::declaration_specifiers (tree t)
776 : : {
777 : 2815 : storage_class_specifier (t);
778 : 2815 : function_specifier (t);
779 : 2815 : pp_c_specifier_qualifier_list (this, DECL_P (t) ? TREE_TYPE (t) : t);
780 : 2815 : }
781 : :
782 : : /* direct-declarator
783 : : identifier
784 : : ( declarator )
785 : : direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
786 : : direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)]
787 : : direct-declarator [ type-qualifier-list static assignment-expression ]
788 : : direct-declarator [ type-qualifier-list * ]
789 : : direct-declarator ( parameter-type-list )
790 : : direct-declarator ( identifier-list(opt) ) */
791 : :
792 : : void
793 : 0 : c_pretty_printer::direct_declarator (tree t)
794 : : {
795 : 0 : switch (TREE_CODE (t))
796 : : {
797 : 0 : case VAR_DECL:
798 : 0 : case PARM_DECL:
799 : 0 : case TYPE_DECL:
800 : 0 : case FIELD_DECL:
801 : 0 : case LABEL_DECL:
802 : 0 : pp_c_space_for_pointer_operator (this, TREE_TYPE (t));
803 : 0 : pp_c_tree_decl_identifier (this, t);
804 : 0 : break;
805 : :
806 : 0 : case ARRAY_TYPE:
807 : 0 : case POINTER_TYPE:
808 : 0 : abstract_declarator (TREE_TYPE (t));
809 : 0 : break;
810 : :
811 : 0 : case FUNCTION_TYPE:
812 : 0 : pp_parameter_list (this, t);
813 : 0 : abstract_declarator (TREE_TYPE (t));
814 : 0 : break;
815 : :
816 : 0 : case FUNCTION_DECL:
817 : 0 : pp_c_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
818 : 0 : pp_c_tree_decl_identifier (this, t);
819 : 0 : if (flags & pp_c_flag_abstract)
820 : 0 : abstract_declarator (TREE_TYPE (t));
821 : : else
822 : : {
823 : 0 : pp_parameter_list (this, t);
824 : 0 : abstract_declarator (TREE_TYPE (TREE_TYPE (t)));
825 : : }
826 : : break;
827 : :
828 : : case INTEGER_TYPE:
829 : : case REAL_TYPE:
830 : : case FIXED_POINT_TYPE:
831 : : case ENUMERAL_TYPE:
832 : : case BITINT_TYPE:
833 : : case UNION_TYPE:
834 : : case RECORD_TYPE:
835 : : break;
836 : :
837 : 0 : default:
838 : 0 : pp_unsupported_tree (this, t);
839 : 0 : break;
840 : : }
841 : 0 : }
842 : :
843 : :
844 : : /* declarator:
845 : : pointer(opt) direct-declarator */
846 : :
847 : : void
848 : 0 : c_pretty_printer::declarator (tree t)
849 : : {
850 : 0 : switch (TREE_CODE (t))
851 : : {
852 : : case INTEGER_TYPE:
853 : : case REAL_TYPE:
854 : : case FIXED_POINT_TYPE:
855 : : case ENUMERAL_TYPE:
856 : : case BITINT_TYPE:
857 : : case UNION_TYPE:
858 : : case RECORD_TYPE:
859 : : break;
860 : :
861 : 0 : case VAR_DECL:
862 : 0 : case PARM_DECL:
863 : 0 : case FIELD_DECL:
864 : 0 : case ARRAY_TYPE:
865 : 0 : case FUNCTION_TYPE:
866 : 0 : case FUNCTION_DECL:
867 : 0 : case TYPE_DECL:
868 : 0 : direct_declarator (t);
869 : 0 : break;
870 : :
871 : :
872 : 0 : default:
873 : 0 : pp_unsupported_tree (this, t);
874 : 0 : break;
875 : : }
876 : 0 : }
877 : :
878 : : /* declaration:
879 : : declaration-specifiers init-declarator-list(opt) ; */
880 : :
881 : : void
882 : 0 : c_pretty_printer::declaration (tree t)
883 : : {
884 : 0 : declaration_specifiers (t);
885 : 0 : pp_c_init_declarator (this, t);
886 : 0 : }
887 : :
888 : : /* Pretty-print ATTRIBUTES marked to be displayed on diagnostic. */
889 : :
890 : : void
891 : 405856 : pp_c_attributes_display (c_pretty_printer *pp, tree a)
892 : : {
893 : 405856 : bool is_first = true;
894 : :
895 : 405856 : if (a == NULL_TREE)
896 : : return;
897 : :
898 : 1013 : const bool std_p = cxx11_attribute_p (a);
899 : :
900 : 2279 : for (; a != NULL_TREE; a = TREE_CHAIN (a))
901 : : {
902 : 1266 : const struct attribute_spec *as
903 : 1266 : = lookup_attribute_spec (get_attribute_name (a));
904 : 1266 : if (!as || as->affects_type_identity == false)
905 : 489 : continue;
906 : 777 : if (c_dialect_cxx ()
907 : 508 : && !strcmp ("transaction_safe", as->name))
908 : : /* In C++ transaction_safe is printed at the end of the declarator. */
909 : 19 : continue;
910 : 758 : if (is_first)
911 : : {
912 : 758 : if (std_p)
913 : : {
914 : 6 : pp_c_left_bracket (pp);
915 : 6 : pp_c_left_bracket (pp);
916 : : }
917 : : else
918 : : {
919 : 752 : pp_c_ws_string (pp, "__attribute__");
920 : 752 : pp_c_left_paren (pp);
921 : 752 : pp_c_left_paren (pp);
922 : : }
923 : : is_first = false;
924 : : }
925 : : else
926 : 0 : pp_separate_with (pp, ',');
927 : 758 : tree ns;
928 : 758 : if (std_p && (ns = get_attribute_namespace (a)))
929 : : {
930 : 6 : pp_tree_identifier (pp, ns);
931 : 6 : pp_colon (pp);
932 : 6 : pp_colon (pp);
933 : : }
934 : 758 : pp_tree_identifier (pp, get_attribute_name (a));
935 : 758 : if (TREE_VALUE (a))
936 : 546 : pp_c_call_argument_list (pp, TREE_VALUE (a));
937 : : }
938 : :
939 : 1013 : if (!is_first)
940 : : {
941 : 758 : if (std_p)
942 : : {
943 : 6 : pp_c_right_bracket (pp);
944 : 6 : pp_c_right_bracket (pp);
945 : : }
946 : : else
947 : : {
948 : 752 : pp_c_right_paren (pp);
949 : 752 : pp_c_right_paren (pp);
950 : 752 : pp_c_whitespace (pp);
951 : : }
952 : : }
953 : : }
954 : :
955 : : /* function-definition:
956 : : declaration-specifiers declarator compound-statement */
957 : :
958 : : void
959 : 0 : pp_c_function_definition (c_pretty_printer *pp, tree t)
960 : : {
961 : 0 : pp->declaration_specifiers (t);
962 : 0 : pp->declarator (t);
963 : 0 : pp_needs_newline (pp) = true;
964 : 0 : pp->statement (DECL_SAVED_TREE (t));
965 : 0 : pp_newline_and_flush (pp);
966 : 0 : }
967 : :
968 : :
969 : : /* Expressions. */
970 : :
971 : : /* Print out a c-char. This is called solely for characters which are
972 : : in the *target* execution character set. We ought to convert them
973 : : back to the *host* execution character set before printing, but we
974 : : have no way to do this at present. A decent compromise is to print
975 : : all characters as if they were in the host execution character set,
976 : : and not attempt to recover any named escape characters, but render
977 : : all unprintables as octal escapes. If the host and target character
978 : : sets are the same, this produces relatively readable output. If they
979 : : are not the same, strings may appear as gibberish, but that's okay
980 : : (in fact, it may well be what the reader wants, e.g. if they are looking
981 : : to see if conversion to the target character set happened correctly).
982 : :
983 : : A special case: we need to prefix \, ", and ' with backslashes. It is
984 : : correct to do so for the *host*'s \, ", and ', because the rest of the
985 : : file appears in the host character set. */
986 : :
987 : : static void
988 : 468763 : pp_c_char (c_pretty_printer *pp, int c)
989 : : {
990 : 468763 : if (ISPRINT (c))
991 : : {
992 : 465378 : switch (c)
993 : : {
994 : 0 : case '\\': pp_string (pp, "\\\\"); break;
995 : 303 : case '\'': pp_string (pp, "\\\'"); break;
996 : 0 : case '\"': pp_string (pp, "\\\""); break;
997 : 465075 : default: pp_character (pp, c);
998 : : }
999 : : }
1000 : : else
1001 : 3385 : pp_scalar (pp, "\\%03o", (unsigned) c);
1002 : 468763 : }
1003 : :
1004 : : /* Print out a STRING literal. */
1005 : :
1006 : : void
1007 : 1381 : pp_c_string_literal (c_pretty_printer *pp, tree s)
1008 : : {
1009 : 1381 : const char *p = TREE_STRING_POINTER (s);
1010 : 1381 : int n = TREE_STRING_LENGTH (s) - 1;
1011 : 1381 : int i;
1012 : 1381 : pp_doublequote (pp);
1013 : 14138 : for (i = 0; i < n; ++i)
1014 : 11376 : pp_c_char (pp, p[i]);
1015 : 1381 : pp_doublequote (pp);
1016 : 1381 : }
1017 : :
1018 : : /* Pretty-print a VOID_CST (void_node). */
1019 : :
1020 : : static void
1021 : 27 : pp_c_void_constant (c_pretty_printer *pp)
1022 : : {
1023 : 27 : pp_c_type_cast (pp, void_type_node);
1024 : 27 : pp_string (pp, "0");
1025 : 27 : }
1026 : :
1027 : : /* Pretty-print an INTEGER literal. */
1028 : :
1029 : : void
1030 : 6702752 : pp_c_integer_constant (c_pretty_printer *pp, tree i)
1031 : : {
1032 : 6702752 : if (tree_fits_shwi_p (i))
1033 : 5829425 : pp_wide_integer (pp, tree_to_shwi (i));
1034 : 873327 : else if (tree_fits_uhwi_p (i))
1035 : 873300 : pp_unsigned_wide_integer (pp, tree_to_uhwi (i));
1036 : : else
1037 : : {
1038 : 27 : wide_int wi = wi::to_wide (i);
1039 : :
1040 : 27 : if (wi::lt_p (wi::to_wide (i), 0, TYPE_SIGN (TREE_TYPE (i))))
1041 : : {
1042 : 5 : pp_minus (pp);
1043 : 5 : wi = -wi;
1044 : : }
1045 : 27 : unsigned int prec = wi.get_precision ();
1046 : 27 : if ((prec + 3) / 4 > sizeof (pp_buffer (pp)->m_digit_buffer) - 3)
1047 : : {
1048 : 1 : char *buf = XALLOCAVEC (char, (prec + 3) / 4 + 3);
1049 : 1 : print_hex (wi, buf);
1050 : 1 : pp_string (pp, buf);
1051 : : }
1052 : : else
1053 : : {
1054 : 26 : print_hex (wi, pp_buffer (pp)->m_digit_buffer);
1055 : 26 : pp_string (pp, pp_buffer (pp)->m_digit_buffer);
1056 : : }
1057 : 27 : }
1058 : 6702752 : }
1059 : :
1060 : : /* Print out a CHARACTER literal. */
1061 : :
1062 : : static void
1063 : 457387 : pp_c_character_constant (c_pretty_printer *pp, tree c)
1064 : : {
1065 : 457387 : pp_quote (pp);
1066 : 457387 : pp_c_char (pp, (unsigned) TREE_INT_CST_LOW (c));
1067 : 457387 : pp_quote (pp);
1068 : 457387 : }
1069 : :
1070 : : /* Print out a BOOLEAN literal. */
1071 : :
1072 : : static void
1073 : 5770229 : pp_c_bool_constant (c_pretty_printer *pp, tree b)
1074 : : {
1075 : 5770229 : if (b == boolean_false_node)
1076 : : {
1077 : 3283843 : if (c_dialect_cxx ())
1078 : 3283843 : pp_c_ws_string (pp, "false");
1079 : 0 : else if (flag_isoc99)
1080 : 0 : pp_c_ws_string (pp, "_False");
1081 : : else
1082 : 0 : pp_unsupported_tree (pp, b);
1083 : : }
1084 : 2486386 : else if (b == boolean_true_node)
1085 : : {
1086 : 2486386 : if (c_dialect_cxx ())
1087 : 2486386 : pp_c_ws_string (pp, "true");
1088 : 0 : else if (flag_isoc99)
1089 : 0 : pp_c_ws_string (pp, "_True");
1090 : : else
1091 : 0 : pp_unsupported_tree (pp, b);
1092 : : }
1093 : 0 : else if (TREE_CODE (b) == INTEGER_CST)
1094 : 0 : pp_c_integer_constant (pp, b);
1095 : : else
1096 : 0 : pp_unsupported_tree (pp, b);
1097 : 5770229 : }
1098 : :
1099 : : /* Given a value e of ENUMERAL_TYPE:
1100 : : Print out the first ENUMERATOR id with value e, if one is found,
1101 : : else print out the value as a C-style cast (type-id)value. */
1102 : :
1103 : : static void
1104 : 0 : pp_c_enumeration_constant (c_pretty_printer *pp, tree e)
1105 : : {
1106 : 0 : tree type = TREE_TYPE (e);
1107 : 0 : tree value = NULL_TREE;
1108 : :
1109 : : /* Find the name of this constant. */
1110 : 0 : if ((pp->flags & pp_c_flag_gnu_v3) == 0)
1111 : 0 : for (value = TYPE_VALUES (type); value != NULL_TREE;
1112 : 0 : value = TREE_CHAIN (value))
1113 : 0 : if (tree_int_cst_equal (DECL_INITIAL (TREE_VALUE (value)), e))
1114 : : break;
1115 : :
1116 : 0 : if (value != NULL_TREE)
1117 : 0 : pp->id_expression (TREE_PURPOSE (value));
1118 : : else
1119 : : {
1120 : : /* Value must have been cast. */
1121 : 0 : pp_c_type_cast (pp, type);
1122 : 0 : pp_c_integer_constant (pp, e);
1123 : : }
1124 : 0 : }
1125 : :
1126 : : /* Print out a REAL value as a decimal-floating-constant. */
1127 : :
1128 : : static void
1129 : 877 : pp_c_floating_constant (c_pretty_printer *pp, tree r)
1130 : : {
1131 : 877 : const struct real_format *fmt
1132 : 877 : = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (r)));
1133 : :
1134 : 877 : REAL_VALUE_TYPE floating_cst = TREE_REAL_CST (r);
1135 : 877 : bool is_decimal = floating_cst.decimal;
1136 : :
1137 : : /* See ISO C++ WG N1822. Note: The fraction 643/2136 approximates
1138 : : log10(2) to 7 significant digits. */
1139 : 877 : int max_digits10 = 2 + (is_decimal ? fmt->p : fmt->p * 643L / 2136);
1140 : :
1141 : 877 : real_to_decimal (pp_buffer (pp)->m_digit_buffer, &TREE_REAL_CST (r),
1142 : : sizeof (pp_buffer (pp)->m_digit_buffer),
1143 : : max_digits10, 1);
1144 : :
1145 : 877 : pp_string (pp, pp_buffer(pp)->m_digit_buffer);
1146 : 877 : if (TREE_TYPE (r) == float_type_node)
1147 : 252 : pp_character (pp, 'f');
1148 : 625 : else if (TREE_TYPE (r) == long_double_type_node)
1149 : 32 : pp_character (pp, 'l');
1150 : 593 : else if (TREE_TYPE (r) == dfloat128_type_node)
1151 : 12 : pp_string (pp, "dl");
1152 : 581 : else if (TREE_TYPE (r) == dfloat64_type_node)
1153 : 12 : pp_string (pp, "dd");
1154 : 569 : else if (TREE_TYPE (r) == dfloat32_type_node)
1155 : 12 : pp_string (pp, "df");
1156 : 557 : else if (TREE_TYPE (r) == dfloat64x_type_node)
1157 : 0 : pp_string (pp, "d64x");
1158 : 557 : else if (TREE_TYPE (r) != double_type_node)
1159 : 4 : for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
1160 : 4 : if (TREE_TYPE (r) == FLOATN_NX_TYPE_NODE (i))
1161 : : {
1162 : 2 : pp_character (pp, 'f');
1163 : 2 : pp_decimal_int (pp, floatn_nx_types[i].n);
1164 : 2 : if (floatn_nx_types[i].extended)
1165 : 0 : pp_character (pp, 'x');
1166 : : break;
1167 : : }
1168 : 877 : }
1169 : :
1170 : : /* Print out a FIXED value as a decimal-floating-constant. */
1171 : :
1172 : : static void
1173 : 0 : pp_c_fixed_constant (c_pretty_printer *pp, tree r)
1174 : : {
1175 : 0 : fixed_to_decimal (pp_buffer (pp)->m_digit_buffer, &TREE_FIXED_CST (r),
1176 : : sizeof (pp_buffer (pp)->m_digit_buffer));
1177 : 0 : pp_string (pp, pp_buffer(pp)->m_digit_buffer);
1178 : 0 : }
1179 : :
1180 : : /* Pretty-print a compound literal expression. GNU extensions include
1181 : : vector constants. */
1182 : :
1183 : : static void
1184 : 66 : pp_c_compound_literal (c_pretty_printer *pp, tree e)
1185 : : {
1186 : 66 : tree type = TREE_TYPE (e);
1187 : 66 : pp_c_type_cast (pp, type);
1188 : :
1189 : 66 : switch (TREE_CODE (type))
1190 : : {
1191 : 66 : case RECORD_TYPE:
1192 : 66 : case UNION_TYPE:
1193 : 66 : case ARRAY_TYPE:
1194 : 66 : case VECTOR_TYPE:
1195 : 66 : case COMPLEX_TYPE:
1196 : 66 : pp_c_brace_enclosed_initializer_list (pp, e);
1197 : 66 : break;
1198 : :
1199 : 0 : default:
1200 : 0 : pp_unsupported_tree (pp, e);
1201 : 0 : break;
1202 : : }
1203 : 66 : }
1204 : :
1205 : : /* Pretty-print a COMPLEX_EXPR expression. */
1206 : :
1207 : : static void
1208 : 24 : pp_c_complex_expr (c_pretty_printer *pp, tree e)
1209 : : {
1210 : : /* Handle a few common special cases, otherwise fallback
1211 : : to printing it as compound literal. */
1212 : 24 : tree type = TREE_TYPE (e);
1213 : 24 : tree realexpr = TREE_OPERAND (e, 0);
1214 : 24 : tree imagexpr = TREE_OPERAND (e, 1);
1215 : :
1216 : : /* Cast of an COMPLEX_TYPE expression to a different COMPLEX_TYPE. */
1217 : 24 : if (TREE_CODE (realexpr) == NOP_EXPR
1218 : 20 : && TREE_CODE (imagexpr) == NOP_EXPR
1219 : 8 : && TREE_TYPE (realexpr) == TREE_TYPE (type)
1220 : 8 : && TREE_TYPE (imagexpr) == TREE_TYPE (type)
1221 : 8 : && TREE_CODE (TREE_OPERAND (realexpr, 0)) == REALPART_EXPR
1222 : 8 : && TREE_CODE (TREE_OPERAND (imagexpr, 0)) == IMAGPART_EXPR
1223 : 32 : && TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0)
1224 : 8 : == TREE_OPERAND (TREE_OPERAND (imagexpr, 0), 0))
1225 : : {
1226 : 8 : pp_c_type_cast (pp, type);
1227 : 8 : pp->expression (TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0));
1228 : 8 : return;
1229 : : }
1230 : :
1231 : : /* Cast of an scalar expression to COMPLEX_TYPE. */
1232 : 24 : if ((integer_zerop (imagexpr) || real_zerop (imagexpr))
1233 : 18 : && TREE_TYPE (realexpr) == TREE_TYPE (type))
1234 : : {
1235 : 10 : pp_c_type_cast (pp, type);
1236 : 10 : if (TREE_CODE (realexpr) == NOP_EXPR)
1237 : 6 : realexpr = TREE_OPERAND (realexpr, 0);
1238 : 10 : pp->expression (realexpr);
1239 : 10 : return;
1240 : : }
1241 : :
1242 : 6 : pp_c_compound_literal (pp, e);
1243 : : }
1244 : :
1245 : : /* constant:
1246 : : integer-constant
1247 : : floating-constant
1248 : : fixed-point-constant
1249 : : enumeration-constant
1250 : : character-constant */
1251 : :
1252 : : void
1253 : 12269971 : c_pretty_printer::constant (tree e)
1254 : : {
1255 : 12269971 : const enum tree_code code = TREE_CODE (e);
1256 : :
1257 : 12269971 : switch (code)
1258 : : {
1259 : 27 : case VOID_CST:
1260 : 27 : pp_c_void_constant (this);
1261 : 27 : break;
1262 : :
1263 : 12268122 : case INTEGER_CST:
1264 : 12268122 : {
1265 : 12268122 : tree type = TREE_TYPE (e);
1266 : 12268122 : if (type == boolean_type_node)
1267 : 5770229 : pp_c_bool_constant (this, e);
1268 : 6497893 : else if (type == char_type_node)
1269 : 457387 : pp_c_character_constant (this, e);
1270 : 6040506 : else if (TREE_CODE (type) == ENUMERAL_TYPE)
1271 : 0 : pp_c_enumeration_constant (this, e);
1272 : 6040506 : else if (NULLPTR_TYPE_P (type))
1273 : 0 : pp_string (this, "nullptr");
1274 : : else
1275 : 6040506 : pp_c_integer_constant (this, e);
1276 : : }
1277 : : break;
1278 : :
1279 : 706 : case REAL_CST:
1280 : 706 : pp_c_floating_constant (this, e);
1281 : 706 : break;
1282 : :
1283 : 0 : case FIXED_CST:
1284 : 0 : pp_c_fixed_constant (this, e);
1285 : 0 : break;
1286 : :
1287 : 1116 : case STRING_CST:
1288 : 1116 : pp_c_string_literal (this, e);
1289 : 1116 : break;
1290 : :
1291 : 0 : case COMPLEX_CST:
1292 : : /* Sometimes, we are confused and we think a complex literal
1293 : : is a constant. Such thing is a compound literal which
1294 : : grammatically belongs to postfix-expr production. */
1295 : 0 : pp_c_compound_literal (this, e);
1296 : 0 : break;
1297 : :
1298 : 0 : default:
1299 : 0 : pp_unsupported_tree (this, e);
1300 : 0 : break;
1301 : : }
1302 : 12269971 : }
1303 : :
1304 : : /* Pretty-print a string such as an identifier, without changing its
1305 : : encoding, preceded by whitespace is necessary. */
1306 : :
1307 : : void
1308 : 19782112 : pp_c_ws_string (c_pretty_printer *pp, const char *str)
1309 : : {
1310 : 19782112 : pp_c_maybe_whitespace (pp);
1311 : 19782112 : pp_string (pp, str);
1312 : 19782112 : pp->set_padding (pp_before);
1313 : 19782112 : }
1314 : :
1315 : : void
1316 : 36817 : c_pretty_printer::translate_string (const char *gmsgid)
1317 : : {
1318 : 36817 : if (pp_translate_identifiers (this))
1319 : 9301 : pp_c_ws_string (this, _(gmsgid));
1320 : : else
1321 : 27516 : pp_c_ws_string (this, gmsgid);
1322 : 36817 : }
1323 : :
1324 : : /* Pretty-print an IDENTIFIER_NODE, which may contain UTF-8 sequences
1325 : : that need converting to the locale encoding, preceded by whitespace
1326 : : is necessary. */
1327 : :
1328 : : void
1329 : 391060081 : pp_c_identifier (c_pretty_printer *pp, const char *id)
1330 : : {
1331 : 391060081 : pp_c_maybe_whitespace (pp);
1332 : 391060081 : pp_identifier (pp, id);
1333 : 391060081 : pp->set_padding (pp_before);
1334 : 391060081 : }
1335 : :
1336 : : /* Pretty-print a C primary-expression.
1337 : : primary-expression:
1338 : : identifier
1339 : : constant
1340 : : string-literal
1341 : : ( expression ) */
1342 : :
1343 : : void
1344 : 36622 : c_pretty_printer::primary_expression (tree e)
1345 : : {
1346 : 36622 : switch (TREE_CODE (e))
1347 : : {
1348 : 29241 : case VAR_DECL:
1349 : 29241 : case PARM_DECL:
1350 : 29241 : case FIELD_DECL:
1351 : 29241 : case CONST_DECL:
1352 : 29241 : case FUNCTION_DECL:
1353 : 29241 : case LABEL_DECL:
1354 : 29241 : pp_c_tree_decl_identifier (this, e);
1355 : 29241 : break;
1356 : :
1357 : 102 : case IDENTIFIER_NODE:
1358 : 102 : pp_c_tree_identifier (this, e);
1359 : 102 : break;
1360 : :
1361 : 22 : case ERROR_MARK:
1362 : 22 : translate_string ("<erroneous-expression>");
1363 : 22 : break;
1364 : :
1365 : 3 : case RESULT_DECL:
1366 : 3 : translate_string ("<return-value>");
1367 : 3 : break;
1368 : :
1369 : 1128 : case VOID_CST:
1370 : 1128 : case INTEGER_CST:
1371 : 1128 : case REAL_CST:
1372 : 1128 : case FIXED_CST:
1373 : 1128 : case STRING_CST:
1374 : 1128 : constant (e);
1375 : 1128 : break;
1376 : :
1377 : 2 : case TARGET_EXPR:
1378 : 2 : pp_c_ws_string (this, "__builtin_memcpy");
1379 : 2 : pp_c_left_paren (this);
1380 : 2 : pp_ampersand (this);
1381 : 2 : primary_expression (TARGET_EXPR_SLOT (e));
1382 : 2 : pp_separate_with (this, ',');
1383 : 2 : pp_ampersand (this);
1384 : 2 : initializer (TARGET_EXPR_INITIAL (e));
1385 : 2 : if (TARGET_EXPR_CLEANUP (e))
1386 : : {
1387 : 0 : pp_separate_with (this, ',');
1388 : 0 : expression (TARGET_EXPR_CLEANUP (e));
1389 : : }
1390 : 2 : pp_c_right_paren (this);
1391 : 2 : break;
1392 : :
1393 : 850 : case SSA_NAME:
1394 : 850 : if (SSA_NAME_VAR (e))
1395 : 793 : primary_expression (SSA_NAME_VAR (e));
1396 : 57 : else if (gimple_assign_single_p (SSA_NAME_DEF_STMT (e)))
1397 : : {
1398 : : /* Print only the right side of the GIMPLE assignment. */
1399 : 6 : gimple *def_stmt = SSA_NAME_DEF_STMT (e);
1400 : 6 : pp_gimple_stmt_1 (this, def_stmt, 0, TDF_RHS_ONLY);
1401 : : }
1402 : : else
1403 : 51 : expression (e);
1404 : : break;
1405 : :
1406 : 5274 : default:
1407 : : /* FIXME: Make sure we won't get into an infinite loop. */
1408 : 5274 : if (location_wrapper_p (e))
1409 : 330 : expression (e);
1410 : : else
1411 : : {
1412 : 4944 : pp_c_left_paren (this);
1413 : 4944 : expression (e);
1414 : 4944 : pp_c_right_paren (this);
1415 : : }
1416 : : break;
1417 : : }
1418 : 36622 : }
1419 : :
1420 : : /* Print out a C initializer -- also support C compound-literals.
1421 : : initializer:
1422 : : assignment-expression:
1423 : : { initializer-list }
1424 : : { initializer-list , } */
1425 : :
1426 : : void
1427 : 23 : c_pretty_printer::initializer (tree e)
1428 : : {
1429 : 23 : if (TREE_CODE (e) == CONSTRUCTOR)
1430 : 21 : pp_c_brace_enclosed_initializer_list (this, e);
1431 : : else
1432 : 2 : expression (e);
1433 : 23 : }
1434 : :
1435 : : /* init-declarator:
1436 : : declarator:
1437 : : declarator = initializer */
1438 : :
1439 : : void
1440 : 0 : pp_c_init_declarator (c_pretty_printer *pp, tree t)
1441 : : {
1442 : 0 : pp->declarator (t);
1443 : : /* We don't want to output function definitions here. There are handled
1444 : : elsewhere (and the syntactic form is bogus anyway). */
1445 : 0 : if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t))
1446 : : {
1447 : 0 : tree init = DECL_INITIAL (t);
1448 : : /* This C++ bit is handled here because it is easier to do so.
1449 : : In templates, the C++ parser builds a TREE_LIST for a
1450 : : direct-initialization; the TREE_PURPOSE is the variable to
1451 : : initialize and the TREE_VALUE is the initializer. */
1452 : 0 : if (TREE_CODE (init) == TREE_LIST)
1453 : : {
1454 : 0 : pp_c_left_paren (pp);
1455 : 0 : pp->expression (TREE_VALUE (init));
1456 : 0 : pp_right_paren (pp);
1457 : : }
1458 : : else
1459 : : {
1460 : 0 : pp_space (pp);
1461 : 0 : pp_equal (pp);
1462 : 0 : pp_space (pp);
1463 : 0 : pp->initializer (init);
1464 : : }
1465 : : }
1466 : 0 : }
1467 : :
1468 : : /* initializer-list:
1469 : : designation(opt) initializer
1470 : : initializer-list , designation(opt) initializer
1471 : :
1472 : : designation:
1473 : : designator-list =
1474 : :
1475 : : designator-list:
1476 : : designator
1477 : : designator-list designator
1478 : :
1479 : : designator:
1480 : : [ constant-expression ]
1481 : : identifier */
1482 : :
1483 : : static void
1484 : 87 : pp_c_initializer_list (c_pretty_printer *pp, tree e)
1485 : : {
1486 : 87 : tree type = TREE_TYPE (e);
1487 : 87 : const enum tree_code code = TREE_CODE (type);
1488 : :
1489 : 87 : if (TREE_CODE (e) == CONSTRUCTOR)
1490 : : {
1491 : 21 : pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
1492 : 21 : return;
1493 : : }
1494 : :
1495 : 66 : switch (code)
1496 : : {
1497 : 0 : case RECORD_TYPE:
1498 : 0 : case UNION_TYPE:
1499 : 0 : case ARRAY_TYPE:
1500 : 0 : {
1501 : 0 : tree init = TREE_OPERAND (e, 0);
1502 : 0 : for (; init != NULL_TREE; init = TREE_CHAIN (init))
1503 : : {
1504 : 0 : if (code == RECORD_TYPE || code == UNION_TYPE)
1505 : : {
1506 : 0 : pp_c_dot (pp);
1507 : 0 : pp->primary_expression (TREE_PURPOSE (init));
1508 : : }
1509 : : else
1510 : : {
1511 : 0 : pp_c_left_bracket (pp);
1512 : 0 : if (TREE_PURPOSE (init))
1513 : 0 : pp->constant (TREE_PURPOSE (init));
1514 : 0 : pp_c_right_bracket (pp);
1515 : : }
1516 : 0 : pp_c_whitespace (pp);
1517 : 0 : pp_equal (pp);
1518 : 0 : pp_c_whitespace (pp);
1519 : 0 : pp->initializer (TREE_VALUE (init));
1520 : 0 : if (TREE_CHAIN (init))
1521 : 0 : pp_separate_with (pp, ',');
1522 : : }
1523 : : }
1524 : : return;
1525 : :
1526 : 6 : case VECTOR_TYPE:
1527 : 6 : if (TREE_CODE (e) == VECTOR_CST)
1528 : : {
1529 : : /* We don't create variable-length VECTOR_CSTs. */
1530 : 6 : unsigned int nunits = VECTOR_CST_NELTS (e).to_constant ();
1531 : 30 : for (unsigned int i = 0; i < nunits; ++i)
1532 : : {
1533 : 24 : if (i > 0)
1534 : 18 : pp_separate_with (pp, ',');
1535 : 24 : pp->expression (VECTOR_CST_ELT (e, i));
1536 : : }
1537 : : }
1538 : : else
1539 : : break;
1540 : : return;
1541 : :
1542 : 60 : case COMPLEX_TYPE:
1543 : 60 : if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
1544 : : {
1545 : 60 : const bool cst = TREE_CODE (e) == COMPLEX_CST;
1546 : 60 : pp->expression (cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
1547 : 60 : pp_separate_with (pp, ',');
1548 : 114 : pp->expression (cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
1549 : : }
1550 : : else
1551 : : break;
1552 : 60 : return;
1553 : :
1554 : : default:
1555 : : break;
1556 : : }
1557 : :
1558 : 0 : pp_unsupported_tree (pp, type);
1559 : : }
1560 : :
1561 : : /* Pretty-print a brace-enclosed initializer-list. */
1562 : :
1563 : : static void
1564 : 87 : pp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l)
1565 : : {
1566 : 87 : pp_c_left_brace (pp);
1567 : 87 : pp_c_initializer_list (pp, l);
1568 : 87 : pp_c_right_brace (pp);
1569 : 87 : }
1570 : :
1571 : :
1572 : : /* This is a convenient function, used to bridge gap between C and C++
1573 : : grammars.
1574 : :
1575 : : id-expression:
1576 : : identifier */
1577 : :
1578 : : void
1579 : 31355 : c_pretty_printer::id_expression (tree t)
1580 : : {
1581 : 31355 : switch (TREE_CODE (t))
1582 : : {
1583 : 29231 : case VAR_DECL:
1584 : 29231 : case PARM_DECL:
1585 : 29231 : case CONST_DECL:
1586 : 29231 : case TYPE_DECL:
1587 : 29231 : case FUNCTION_DECL:
1588 : 29231 : case FIELD_DECL:
1589 : 29231 : case LABEL_DECL:
1590 : 29231 : pp_c_tree_decl_identifier (this, t);
1591 : 29231 : break;
1592 : :
1593 : 2124 : case IDENTIFIER_NODE:
1594 : 2124 : pp_c_tree_identifier (this, t);
1595 : 2124 : break;
1596 : :
1597 : 0 : default:
1598 : 0 : pp_unsupported_tree (this, t);
1599 : 0 : break;
1600 : : }
1601 : 31355 : }
1602 : :
1603 : : /* postfix-expression:
1604 : : primary-expression
1605 : : postfix-expression [ expression ]
1606 : : postfix-expression ( argument-expression-list(opt) )
1607 : : postfix-expression . identifier
1608 : : postfix-expression -> identifier
1609 : : postfix-expression ++
1610 : : postfix-expression --
1611 : : ( type-name ) { initializer-list }
1612 : : ( type-name ) { initializer-list , } */
1613 : :
1614 : : void
1615 : 11768 : c_pretty_printer::postfix_expression (tree e)
1616 : : {
1617 : 11768 : enum tree_code code = TREE_CODE (e);
1618 : 11768 : switch (code)
1619 : : {
1620 : 0 : case POSTINCREMENT_EXPR:
1621 : 0 : case POSTDECREMENT_EXPR:
1622 : 0 : postfix_expression (TREE_OPERAND (e, 0));
1623 : 0 : pp_string (this, code == POSTINCREMENT_EXPR ? "++" : "--");
1624 : 0 : break;
1625 : :
1626 : 547 : case ARRAY_REF:
1627 : 547 : postfix_expression (TREE_OPERAND (e, 0));
1628 : 547 : pp_c_left_bracket (this);
1629 : 547 : expression (TREE_OPERAND (e, 1));
1630 : 547 : pp_c_right_bracket (this);
1631 : 547 : break;
1632 : :
1633 : 6 : case OMP_ARRAY_SECTION:
1634 : 6 : postfix_expression (TREE_OPERAND (e, 0));
1635 : 6 : pp_c_left_bracket (this);
1636 : 6 : if (TREE_OPERAND (e, 1))
1637 : 4 : expression (TREE_OPERAND (e, 1));
1638 : 6 : pp_colon (this);
1639 : 6 : if (TREE_OPERAND (e, 2))
1640 : 6 : expression (TREE_OPERAND (e, 2));
1641 : 6 : pp_c_right_bracket (this);
1642 : 6 : break;
1643 : :
1644 : 116 : case CALL_EXPR:
1645 : 116 : {
1646 : 116 : call_expr_arg_iterator iter;
1647 : 116 : tree arg;
1648 : 116 : if (CALL_EXPR_FN (e) != NULL_TREE)
1649 : 115 : postfix_expression (CALL_EXPR_FN (e));
1650 : : else
1651 : 1 : pp_string (this, internal_fn_name (CALL_EXPR_IFN (e)));
1652 : 116 : pp_c_left_paren (this);
1653 : 323 : FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
1654 : : {
1655 : 91 : expression (arg);
1656 : 91 : if (more_call_expr_args_p (&iter))
1657 : 0 : pp_separate_with (this, ',');
1658 : : }
1659 : 116 : pp_c_right_paren (this);
1660 : 116 : break;
1661 : : }
1662 : :
1663 : 0 : case UNORDERED_EXPR:
1664 : 0 : pp_c_ws_string (this, flag_isoc99
1665 : : ? "isunordered"
1666 : : : "__builtin_isunordered");
1667 : 0 : goto two_args_fun;
1668 : :
1669 : 0 : case ORDERED_EXPR:
1670 : 0 : pp_c_ws_string (this, flag_isoc99
1671 : : ? "!isunordered"
1672 : : : "!__builtin_isunordered");
1673 : 0 : goto two_args_fun;
1674 : :
1675 : 0 : case UNLT_EXPR:
1676 : 0 : pp_c_ws_string (this, flag_isoc99
1677 : : ? "!isgreaterequal"
1678 : : : "!__builtin_isgreaterequal");
1679 : 0 : goto two_args_fun;
1680 : :
1681 : 0 : case UNLE_EXPR:
1682 : 0 : pp_c_ws_string (this, flag_isoc99
1683 : : ? "!isgreater"
1684 : : : "!__builtin_isgreater");
1685 : 0 : goto two_args_fun;
1686 : :
1687 : 0 : case UNGT_EXPR:
1688 : 0 : pp_c_ws_string (this, flag_isoc99
1689 : : ? "!islessequal"
1690 : : : "!__builtin_islessequal");
1691 : 0 : goto two_args_fun;
1692 : :
1693 : 0 : case UNGE_EXPR:
1694 : 0 : pp_c_ws_string (this, flag_isoc99
1695 : : ? "!isless"
1696 : : : "!__builtin_isless");
1697 : 0 : goto two_args_fun;
1698 : :
1699 : 0 : case UNEQ_EXPR:
1700 : 0 : pp_c_ws_string (this, flag_isoc99
1701 : : ? "!islessgreater"
1702 : : : "!__builtin_islessgreater");
1703 : 0 : goto two_args_fun;
1704 : :
1705 : 0 : case LTGT_EXPR:
1706 : 0 : pp_c_ws_string (this, flag_isoc99
1707 : : ? "islessgreater"
1708 : : : "__builtin_islessgreater");
1709 : 0 : goto two_args_fun;
1710 : :
1711 : 1 : case MAX_EXPR:
1712 : 1 : pp_c_ws_string (this, "max");
1713 : 1 : goto two_args_fun;
1714 : :
1715 : 1 : case MIN_EXPR:
1716 : 1 : pp_c_ws_string (this, "min");
1717 : 1 : goto two_args_fun;
1718 : :
1719 : 2 : two_args_fun:
1720 : 2 : pp_c_left_paren (this);
1721 : 2 : expression (TREE_OPERAND (e, 0));
1722 : 2 : pp_separate_with (this, ',');
1723 : 2 : expression (TREE_OPERAND (e, 1));
1724 : 2 : pp_c_right_paren (this);
1725 : 2 : break;
1726 : :
1727 : 0 : case ABS_EXPR:
1728 : 0 : pp_c_ws_string (this, "__builtin_abs");
1729 : 0 : pp_c_left_paren (this);
1730 : 0 : expression (TREE_OPERAND (e, 0));
1731 : 0 : pp_c_right_paren (this);
1732 : 0 : break;
1733 : :
1734 : 789 : case COMPONENT_REF:
1735 : 789 : {
1736 : 789 : tree object = TREE_OPERAND (e, 0);
1737 : 789 : if (INDIRECT_REF_P (object))
1738 : : {
1739 : 57 : postfix_expression (TREE_OPERAND (object, 0));
1740 : 57 : pp_c_arrow (this);
1741 : : }
1742 : : else
1743 : : {
1744 : 732 : postfix_expression (object);
1745 : 732 : pp_c_dot (this);
1746 : : }
1747 : 789 : expression (TREE_OPERAND (e, 1));
1748 : : }
1749 : 789 : break;
1750 : :
1751 : 12 : case BIT_FIELD_REF:
1752 : 12 : {
1753 : 12 : tree type = TREE_TYPE (e);
1754 : :
1755 : 12 : type = signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type);
1756 : 12 : if (type
1757 : 12 : && tree_int_cst_equal (TYPE_SIZE (type), TREE_OPERAND (e, 1)))
1758 : : {
1759 : 12 : HOST_WIDE_INT bitpos = tree_to_shwi (TREE_OPERAND (e, 2));
1760 : 12 : HOST_WIDE_INT size = tree_to_shwi (TYPE_SIZE (type));
1761 : 12 : if ((bitpos % size) == 0)
1762 : : {
1763 : 12 : pp_c_left_paren (this);
1764 : 12 : pp_c_left_paren (this);
1765 : 12 : type_id (type);
1766 : 12 : pp_c_star (this);
1767 : 12 : pp_c_right_paren (this);
1768 : 12 : pp_c_ampersand (this);
1769 : 12 : expression (TREE_OPERAND (e, 0));
1770 : 12 : pp_c_right_paren (this);
1771 : 12 : pp_c_left_bracket (this);
1772 : 12 : pp_wide_integer (this, bitpos / size);
1773 : 12 : pp_c_right_bracket (this);
1774 : 12 : break;
1775 : : }
1776 : : }
1777 : 0 : pp_unsupported_tree (this, e);
1778 : : }
1779 : 0 : break;
1780 : :
1781 : 125 : case MEM_REF:
1782 : 125 : case TARGET_MEM_REF:
1783 : 125 : expression (e);
1784 : 125 : break;
1785 : :
1786 : 60 : case COMPLEX_CST:
1787 : 60 : case VECTOR_CST:
1788 : 60 : pp_c_compound_literal (this, e);
1789 : 60 : break;
1790 : :
1791 : 24 : case COMPLEX_EXPR:
1792 : 24 : pp_c_complex_expr (this, e);
1793 : 24 : break;
1794 : :
1795 : 4 : case COMPOUND_LITERAL_EXPR:
1796 : 4 : e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
1797 : : /* Fall through. */
1798 : 21 : case CONSTRUCTOR:
1799 : 21 : initializer (e);
1800 : 21 : break;
1801 : :
1802 : 0 : case VA_ARG_EXPR:
1803 : 0 : pp_c_ws_string (this, "__builtin_va_arg");
1804 : 0 : pp_c_left_paren (this);
1805 : 0 : assignment_expression (TREE_OPERAND (e, 0));
1806 : 0 : pp_separate_with (this, ',');
1807 : 0 : type_id (TREE_TYPE (e));
1808 : 0 : pp_c_right_paren (this);
1809 : 0 : break;
1810 : :
1811 : 115 : case ADDR_EXPR:
1812 : 115 : if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
1813 : : {
1814 : 115 : id_expression (TREE_OPERAND (e, 0));
1815 : 115 : break;
1816 : : }
1817 : : /* fall through. */
1818 : :
1819 : 9951 : default:
1820 : 9951 : primary_expression (e);
1821 : 9951 : break;
1822 : : }
1823 : 11768 : }
1824 : :
1825 : : /* Print out an expression-list; E is expected to be a TREE_LIST. */
1826 : :
1827 : : void
1828 : 599 : pp_c_expression_list (c_pretty_printer *pp, tree e)
1829 : : {
1830 : 1198 : for (; e != NULL_TREE; e = TREE_CHAIN (e))
1831 : : {
1832 : 599 : pp->expression (TREE_VALUE (e));
1833 : 599 : if (TREE_CHAIN (e))
1834 : 0 : pp_separate_with (pp, ',');
1835 : : }
1836 : 599 : }
1837 : :
1838 : : /* Print out V, which contains the elements of a constructor. */
1839 : :
1840 : : void
1841 : 21 : pp_c_constructor_elts (c_pretty_printer *pp, vec<constructor_elt, va_gc> *v)
1842 : : {
1843 : 21 : unsigned HOST_WIDE_INT ix;
1844 : 21 : tree value;
1845 : :
1846 : 32 : FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
1847 : : {
1848 : 11 : pp->expression (value);
1849 : 11 : if (ix != vec_safe_length (v) - 1)
1850 : 1 : pp_separate_with (pp, ',');
1851 : : }
1852 : 21 : }
1853 : :
1854 : : /* Print out an expression-list in parens, as if it were the argument
1855 : : list to a function. */
1856 : :
1857 : : void
1858 : 625 : pp_c_call_argument_list (c_pretty_printer *pp, tree t)
1859 : : {
1860 : 625 : pp_c_left_paren (pp);
1861 : 625 : if (t && TREE_CODE (t) == TREE_LIST)
1862 : 599 : pp_c_expression_list (pp, t);
1863 : 625 : pp_c_right_paren (pp);
1864 : 625 : }
1865 : :
1866 : : /* Try to fold *(type *)&op into op.fld.fld2[1] if possible.
1867 : : Only used for printing expressions. Should punt if ambiguous
1868 : : (e.g. in unions). */
1869 : :
1870 : : static tree
1871 : 720 : c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
1872 : : offset_int &off)
1873 : : {
1874 : 720 : tree optype = TREE_TYPE (op);
1875 : 720 : if (off == 0)
1876 : : {
1877 : 648 : if (lang_hooks.types_compatible_p (optype, type))
1878 : : return op;
1879 : : /* *(foo *)&complexfoo => __real__ complexfoo */
1880 : 362 : else if (TREE_CODE (optype) == COMPLEX_TYPE
1881 : 362 : && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
1882 : 0 : return build1_loc (loc, REALPART_EXPR, type, op);
1883 : : }
1884 : : /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
1885 : 72 : else if (TREE_CODE (optype) == COMPLEX_TYPE
1886 : 0 : && lang_hooks.types_compatible_p (type, TREE_TYPE (optype))
1887 : 72 : && tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
1888 : : {
1889 : 0 : off = 0;
1890 : 0 : return build1_loc (loc, IMAGPART_EXPR, type, op);
1891 : : }
1892 : : /* ((foo *)&fooarray)[x] => fooarray[x] */
1893 : 434 : if (TREE_CODE (optype) == ARRAY_TYPE
1894 : 300 : && TYPE_SIZE_UNIT (TREE_TYPE (optype))
1895 : 300 : && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (optype))) == INTEGER_CST
1896 : 734 : && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
1897 : : {
1898 : 300 : tree type_domain = TYPE_DOMAIN (optype);
1899 : 300 : tree min_val = size_zero_node;
1900 : 300 : if (type_domain && TYPE_MIN_VALUE (type_domain))
1901 : 300 : min_val = TYPE_MIN_VALUE (type_domain);
1902 : 300 : offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
1903 : 300 : offset_int idx = off / el_sz;
1904 : 300 : offset_int rem = off % el_sz;
1905 : 300 : if (TREE_CODE (min_val) == INTEGER_CST)
1906 : : {
1907 : 300 : tree index
1908 : 300 : = wide_int_to_tree (sizetype, idx + wi::to_offset (min_val));
1909 : 300 : op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
1910 : : NULL_TREE, NULL_TREE);
1911 : 300 : off = rem;
1912 : 300 : if (tree ret = c_fold_indirect_ref_for_warn (loc, type, op, off))
1913 : 300 : return ret;
1914 : 22 : return op;
1915 : : }
1916 : : }
1917 : : /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
1918 : 134 : else if (TREE_CODE (optype) == RECORD_TYPE)
1919 : : {
1920 : 79 : for (tree field = TYPE_FIELDS (optype);
1921 : 413 : field; field = DECL_CHAIN (field))
1922 : 413 : if (TREE_CODE (field) == FIELD_DECL
1923 : 143 : && TREE_TYPE (field) != error_mark_node
1924 : 143 : && TYPE_SIZE_UNIT (TREE_TYPE (field))
1925 : 556 : && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (field))) == INTEGER_CST)
1926 : : {
1927 : 143 : tree pos = byte_position (field);
1928 : 143 : if (TREE_CODE (pos) != INTEGER_CST)
1929 : 0 : continue;
1930 : 143 : offset_int upos = wi::to_offset (pos);
1931 : 143 : offset_int el_sz
1932 : 143 : = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (field)));
1933 : 286 : if (upos <= off && off < upos + el_sz)
1934 : : {
1935 : : /* The C++ pretty printers print scope of the FIELD_DECLs,
1936 : : so punt if it is something that can't be printed. */
1937 : 79 : if (c_dialect_cxx ())
1938 : 49 : if (tree scope = get_containing_scope (field))
1939 : 49 : if (TYPE_P (scope) && TYPE_NAME (scope) == NULL_TREE)
1940 : : break;
1941 : 75 : tree cop = build3_loc (loc, COMPONENT_REF, TREE_TYPE (field),
1942 : : op, field, NULL_TREE);
1943 : 75 : off = off - upos;
1944 : 75 : if (tree ret = c_fold_indirect_ref_for_warn (loc, type, cop,
1945 : : off))
1946 : 75 : return ret;
1947 : 13 : return cop;
1948 : : }
1949 : : }
1950 : : }
1951 : : /* Similarly for unions, but in this case try to be very conservative,
1952 : : only match if some field has type compatible with type and it is the
1953 : : only such field. */
1954 : 55 : else if (TREE_CODE (optype) == UNION_TYPE)
1955 : : {
1956 : 8 : tree fld = NULL_TREE;
1957 : 8 : for (tree field = TYPE_FIELDS (optype);
1958 : 156 : field; field = DECL_CHAIN (field))
1959 : 148 : if (TREE_CODE (field) == FIELD_DECL
1960 : 18 : && TREE_TYPE (field) != error_mark_node
1961 : 166 : && lang_hooks.types_compatible_p (TREE_TYPE (field), type))
1962 : : {
1963 : 2 : if (fld)
1964 : : return NULL_TREE;
1965 : : else
1966 : : fld = field;
1967 : : }
1968 : 8 : if (fld)
1969 : : {
1970 : 2 : off = 0;
1971 : 2 : return build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), op, fld,
1972 : 2 : NULL_TREE);
1973 : : }
1974 : : }
1975 : :
1976 : : return NULL_TREE;
1977 : : }
1978 : :
1979 : : /* Print the MEM_REF expression REF, including its type and offset.
1980 : : Apply casts as necessary if the type of the access is different
1981 : : from the type of the accessed object. Produce compact output
1982 : : designed to include both the element index as well as any
1983 : : misalignment by preferring
1984 : : ((int*)((char*)p + 1))[2]
1985 : : over
1986 : : *(int*)((char*)p + 9)
1987 : : The former is more verbose but makes it clearer that the access
1988 : : to the third element of the array is misaligned by one byte. */
1989 : :
1990 : : static void
1991 : 988 : print_mem_ref (c_pretty_printer *pp, tree e)
1992 : : {
1993 : 988 : tree arg = TREE_OPERAND (e, 0);
1994 : :
1995 : : /* The byte offset. Initially equal to the MEM_REF offset, then
1996 : : adjusted to the remainder of the division by the byte size of
1997 : : the access. */
1998 : 988 : offset_int byte_off = wi::to_offset (TREE_OPERAND (e, 1));
1999 : : /* The result of dividing BYTE_OFF by the size of the access. */
2000 : 988 : offset_int elt_idx = 0;
2001 : : /* True to include a cast to char* (for a nonzero final BYTE_OFF). */
2002 : 988 : bool char_cast = false;
2003 : 988 : tree op = NULL_TREE;
2004 : 988 : bool array_ref_only = false;
2005 : 988 : if (TREE_CODE (arg) == ADDR_EXPR)
2006 : : {
2007 : 345 : op = c_fold_indirect_ref_for_warn (EXPR_LOCATION (e), TREE_TYPE (e),
2008 : 345 : TREE_OPERAND (arg, 0), byte_off);
2009 : : /* Try to fold it back to component, array ref or their combination,
2010 : : but print it only if the types and TBAA types are compatible. */
2011 : 345 : if (op
2012 : 323 : && byte_off == 0
2013 : 323 : && lang_hooks.types_compatible_p (TREE_TYPE (e), TREE_TYPE (op))
2014 : 633 : && (!flag_strict_aliasing
2015 : 28 : || (get_deref_alias_set (TREE_OPERAND (e, 1))
2016 : 14 : == get_alias_set (op))))
2017 : : {
2018 : 286 : pp->expression (op);
2019 : 286 : return;
2020 : : }
2021 : 59 : if (op == NULL_TREE)
2022 : 22 : op = TREE_OPERAND (arg, 0);
2023 : : /* If the types or TBAA types are incompatible, undo the
2024 : : UNION_TYPE handling from c_fold_indirect_ref_for_warn, and similarly
2025 : : undo __real__/__imag__ the code below doesn't try to handle. */
2026 : 59 : if (op != TREE_OPERAND (arg, 0)
2027 : 59 : && ((TREE_CODE (op) == COMPONENT_REF
2028 : 15 : && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == UNION_TYPE)
2029 : 35 : || TREE_CODE (op) == REALPART_EXPR
2030 : 35 : || TREE_CODE (op) == IMAGPART_EXPR))
2031 : 2 : op = TREE_OPERAND (op, 0);
2032 : 59 : if (op != TREE_OPERAND (arg, 0))
2033 : : {
2034 : 61 : array_ref_only = true;
2035 : 61 : for (tree ref = op; ref != TREE_OPERAND (arg, 0);
2036 : 24 : ref = TREE_OPERAND (ref, 0))
2037 : 41 : if (TREE_CODE (ref) != ARRAY_REF)
2038 : : {
2039 : : array_ref_only = false;
2040 : : break;
2041 : : }
2042 : : }
2043 : : }
2044 : :
2045 : 702 : tree access_type = TREE_TYPE (e);
2046 : 702 : tree arg_type = TREE_TYPE (TREE_TYPE (arg));
2047 : 702 : if (tree access_size = TYPE_SIZE_UNIT (access_type))
2048 : 1331 : if (byte_off != 0
2049 : 68 : && TREE_CODE (access_size) == INTEGER_CST
2050 : 766 : && !integer_zerop (access_size))
2051 : : {
2052 : 67 : offset_int asize = wi::to_offset (access_size);
2053 : 67 : elt_idx = byte_off / asize;
2054 : 67 : byte_off = byte_off % asize;
2055 : : }
2056 : :
2057 : : /* True to include a cast to the accessed type. */
2058 : 702 : const bool access_cast
2059 : 59 : = ((op && op != TREE_OPERAND (arg, 0))
2060 : 665 : || VOID_TYPE_P (arg_type)
2061 : 1327 : || !lang_hooks.types_compatible_p (access_type, arg_type));
2062 : 702 : const bool has_off = byte_off != 0 || (op && op != TREE_OPERAND (arg, 0));
2063 : :
2064 : 702 : if (has_off && (byte_off != 0 || !array_ref_only))
2065 : : {
2066 : : /* When printing the byte offset for a pointer to a type of
2067 : : a different size than char, include a cast to char* first,
2068 : : before printing the cast to a pointer to the accessed type. */
2069 : 48 : tree size = TYPE_SIZE (arg_type);
2070 : 48 : if (size == NULL_TREE
2071 : 48 : || TREE_CODE (size) != INTEGER_CST
2072 : 79 : || wi::to_wide (size) != BITS_PER_UNIT)
2073 : 42 : char_cast = true;
2074 : : }
2075 : :
2076 : 702 : if (elt_idx == 0)
2077 : 647 : pp_c_star (pp);
2078 : 55 : else if (access_cast || char_cast)
2079 : 33 : pp_c_left_paren (pp);
2080 : :
2081 : 680 : if (access_cast)
2082 : : {
2083 : : /* Include a cast to the accessed type if it isn't compatible
2084 : : with the type of the referenced object (or if the object
2085 : : is typeless). */
2086 : 132 : pp_c_left_paren (pp);
2087 : 132 : pp->type_id (build_pointer_type (access_type));
2088 : 132 : pp_c_right_paren (pp);
2089 : : }
2090 : :
2091 : 702 : if (has_off)
2092 : 68 : pp_c_left_paren (pp);
2093 : :
2094 : 702 : if (char_cast)
2095 : : {
2096 : : /* Include a cast to char *. */
2097 : 42 : pp_c_left_paren (pp);
2098 : 42 : pp->type_id (string_type_node);
2099 : 42 : pp_c_right_paren (pp);
2100 : : }
2101 : :
2102 : 702 : pp->unary_expression (arg);
2103 : :
2104 : 702 : if (op && op != TREE_OPERAND (arg, 0))
2105 : : {
2106 : 37 : auto_vec<tree, 16> refs;
2107 : 37 : tree ref;
2108 : 37 : unsigned i;
2109 : 37 : bool array_refs = true;
2110 : 126 : for (ref = op; ref != TREE_OPERAND (arg, 0); ref = TREE_OPERAND (ref, 0))
2111 : 89 : refs.safe_push (ref);
2112 : 163 : FOR_EACH_VEC_ELT_REVERSE (refs, i, ref)
2113 : 89 : if (array_refs && TREE_CODE (ref) == ARRAY_REF)
2114 : : {
2115 : 26 : pp_c_left_bracket (pp);
2116 : 26 : pp->expression (TREE_OPERAND (ref, 1));
2117 : 26 : pp_c_right_bracket (pp);
2118 : : }
2119 : : else
2120 : : {
2121 : 17 : if (array_refs)
2122 : : {
2123 : 17 : array_refs = false;
2124 : 17 : pp_string (pp, " + offsetof");
2125 : 17 : pp_c_left_paren (pp);
2126 : 17 : pp->type_id (TREE_TYPE (TREE_OPERAND (ref, 0)));
2127 : 17 : pp_comma (pp);
2128 : : }
2129 : 46 : else if (TREE_CODE (ref) == COMPONENT_REF)
2130 : 44 : pp_c_dot (pp);
2131 : 63 : if (TREE_CODE (ref) == COMPONENT_REF)
2132 : 61 : pp->expression (TREE_OPERAND (ref, 1));
2133 : : else
2134 : : {
2135 : 2 : pp_c_left_bracket (pp);
2136 : 2 : pp->expression (TREE_OPERAND (ref, 1));
2137 : 2 : pp_c_right_bracket (pp);
2138 : : }
2139 : : }
2140 : 37 : if (!array_refs)
2141 : 17 : pp_c_right_paren (pp);
2142 : 37 : }
2143 : :
2144 : 702 : if (byte_off != 0)
2145 : : {
2146 : 31 : pp_space (pp);
2147 : 31 : pp_plus (pp);
2148 : 31 : pp_space (pp);
2149 : 31 : tree off = wide_int_to_tree (ssizetype, byte_off);
2150 : 31 : pp->constant (off);
2151 : : }
2152 : :
2153 : 702 : if (has_off)
2154 : 68 : pp_c_right_paren (pp);
2155 : :
2156 : 702 : if (elt_idx != 0)
2157 : : {
2158 : 55 : if (access_cast || char_cast)
2159 : 33 : pp_c_right_paren (pp);
2160 : :
2161 : 55 : pp_c_left_bracket (pp);
2162 : 55 : tree idx = wide_int_to_tree (ssizetype, elt_idx);
2163 : 55 : pp->constant (idx);
2164 : 55 : pp_c_right_bracket (pp);
2165 : : }
2166 : : }
2167 : :
2168 : : /* unary-expression:
2169 : : postfix-expression
2170 : : ++ cast-expression
2171 : : -- cast-expression
2172 : : unary-operator cast-expression
2173 : : sizeof unary-expression
2174 : : sizeof ( type-id )
2175 : :
2176 : : unary-operator: one of
2177 : : * & + - ! ~
2178 : :
2179 : : GNU extensions.
2180 : : unary-expression:
2181 : : __alignof__ unary-expression
2182 : : __alignof__ ( type-id )
2183 : : __real__ unary-expression
2184 : : __imag__ unary-expression */
2185 : :
2186 : : void
2187 : 8651 : c_pretty_printer::unary_expression (tree e)
2188 : : {
2189 : 8651 : enum tree_code code = TREE_CODE (e);
2190 : 8651 : switch (code)
2191 : : {
2192 : 1 : case PREINCREMENT_EXPR:
2193 : 1 : case PREDECREMENT_EXPR:
2194 : 1 : pp_string (this, code == PREINCREMENT_EXPR ? "++" : "--");
2195 : 1 : unary_expression (TREE_OPERAND (e, 0));
2196 : 1 : break;
2197 : :
2198 : 1555 : case ADDR_EXPR:
2199 : 1555 : case INDIRECT_REF:
2200 : 1555 : case NEGATE_EXPR:
2201 : 1555 : case BIT_NOT_EXPR:
2202 : 1555 : case TRUTH_NOT_EXPR:
2203 : 1555 : case CONJ_EXPR:
2204 : : /* String literal are used by address. */
2205 : 1555 : if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
2206 : 285 : pp_ampersand (this);
2207 : 1270 : else if (code == INDIRECT_REF)
2208 : : {
2209 : 342 : tree type = TREE_TYPE (TREE_OPERAND (e, 0));
2210 : 342 : if (type && TREE_CODE (type) == REFERENCE_TYPE)
2211 : : /* Reference decay is implicit, don't print anything. */;
2212 : : else
2213 : 270 : pp_c_star (this);
2214 : : }
2215 : 928 : else if (code == NEGATE_EXPR)
2216 : 23 : pp_minus (this);
2217 : 905 : else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
2218 : 6 : pp_complement (this);
2219 : 899 : else if (code == TRUTH_NOT_EXPR)
2220 : 899 : pp_exclamation (this);
2221 : 1555 : pp_c_cast_expression (this, TREE_OPERAND (e, 0));
2222 : 1555 : break;
2223 : :
2224 : 988 : case MEM_REF:
2225 : 988 : print_mem_ref (this, e);
2226 : 988 : break;
2227 : :
2228 : 0 : case TARGET_MEM_REF:
2229 : : /* TARGET_MEM_REF can't appear directly from source, but can appear
2230 : : during late GIMPLE optimizations and through late diagnostic we might
2231 : : need to support it. Print it as dereferencing of a pointer after
2232 : : cast to the TARGET_MEM_REF type, with pointer arithmetics on some
2233 : : pointer to single byte types, so
2234 : : *(type *)((char *) ptr + step * index + index2) if all the operands
2235 : : are present and the casts are needed. */
2236 : 0 : pp_c_star (this);
2237 : 0 : if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (e)))) == NULL_TREE
2238 : 0 : || !integer_onep (TYPE_SIZE_UNIT
2239 : : (TREE_TYPE (TREE_TYPE (TMR_BASE (e))))))
2240 : : {
2241 : 0 : if (TYPE_SIZE_UNIT (TREE_TYPE (e))
2242 : 0 : && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (e))))
2243 : : {
2244 : 0 : pp_c_left_paren (this);
2245 : 0 : pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
2246 : : }
2247 : : else
2248 : : {
2249 : 0 : pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
2250 : 0 : pp_c_left_paren (this);
2251 : 0 : pp_c_type_cast (this, build_pointer_type (char_type_node));
2252 : : }
2253 : : }
2254 : 0 : else if (!lang_hooks.types_compatible_p
2255 : 0 : (TREE_TYPE (e), TREE_TYPE (TREE_TYPE (TMR_BASE (e)))))
2256 : : {
2257 : 0 : pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e)));
2258 : 0 : pp_c_left_paren (this);
2259 : : }
2260 : : else
2261 : 0 : pp_c_left_paren (this);
2262 : 0 : pp_c_cast_expression (this, TMR_BASE (e));
2263 : 0 : if (TMR_STEP (e) && TMR_INDEX (e))
2264 : : {
2265 : 0 : pp_plus (this);
2266 : 0 : pp_c_cast_expression (this, TMR_INDEX (e));
2267 : 0 : pp_c_star (this);
2268 : 0 : pp_c_cast_expression (this, TMR_STEP (e));
2269 : : }
2270 : 0 : if (TMR_INDEX2 (e))
2271 : : {
2272 : 0 : pp_plus (this);
2273 : 0 : pp_c_cast_expression (this, TMR_INDEX2 (e));
2274 : : }
2275 : 0 : if (!integer_zerop (TMR_OFFSET (e)))
2276 : : {
2277 : 0 : pp_plus (this);
2278 : 0 : pp_c_integer_constant (this,
2279 : 0 : fold_convert (ssizetype, TMR_OFFSET (e)));
2280 : : }
2281 : 0 : pp_c_right_paren (this);
2282 : 0 : break;
2283 : :
2284 : 14 : case REALPART_EXPR:
2285 : 14 : case IMAGPART_EXPR:
2286 : 21 : pp_c_ws_string (this, code == REALPART_EXPR ? "__real__" : "__imag__");
2287 : 14 : pp_c_whitespace (this);
2288 : 14 : unary_expression (TREE_OPERAND (e, 0));
2289 : 14 : break;
2290 : :
2291 : 6093 : default:
2292 : 6093 : postfix_expression (e);
2293 : 6093 : break;
2294 : : }
2295 : 8651 : }
2296 : :
2297 : : /* cast-expression:
2298 : : unary-expression
2299 : : ( type-name ) cast-expression */
2300 : :
2301 : : void
2302 : 5776 : pp_c_cast_expression (c_pretty_printer *pp, tree e)
2303 : : {
2304 : 6325 : switch (TREE_CODE (e))
2305 : : {
2306 : 549 : case FLOAT_EXPR:
2307 : 549 : case FIX_TRUNC_EXPR:
2308 : 549 : CASE_CONVERT:
2309 : 549 : case VIEW_CONVERT_EXPR:
2310 : 549 : case EXCESS_PRECISION_EXPR:
2311 : 549 : if (!location_wrapper_p (e))
2312 : 269 : pp_c_type_cast (pp, TREE_TYPE (e));
2313 : 549 : pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
2314 : 549 : break;
2315 : :
2316 : 5776 : default:
2317 : 5776 : pp->unary_expression (e);
2318 : : }
2319 : 5776 : }
2320 : :
2321 : : /* multiplicative-expression:
2322 : : cast-expression
2323 : : multiplicative-expression * cast-expression
2324 : : multiplicative-expression / cast-expression
2325 : : multiplicative-expression % cast-expression */
2326 : :
2327 : : void
2328 : 2183 : c_pretty_printer::multiplicative_expression (tree e)
2329 : : {
2330 : 2183 : enum tree_code code = TREE_CODE (e);
2331 : 2183 : switch (code)
2332 : : {
2333 : 133 : case MULT_EXPR:
2334 : 133 : case TRUNC_DIV_EXPR:
2335 : 133 : case TRUNC_MOD_EXPR:
2336 : 133 : case EXACT_DIV_EXPR:
2337 : 133 : case RDIV_EXPR:
2338 : 133 : multiplicative_expression (TREE_OPERAND (e, 0));
2339 : 133 : pp_c_whitespace (this);
2340 : 133 : if (code == MULT_EXPR)
2341 : 128 : pp_c_star (this);
2342 : 5 : else if (code != TRUNC_MOD_EXPR)
2343 : 4 : pp_slash (this);
2344 : : else
2345 : 1 : pp_modulo (this);
2346 : 133 : pp_c_whitespace (this);
2347 : 133 : pp_c_cast_expression (this, TREE_OPERAND (e, 1));
2348 : 133 : break;
2349 : :
2350 : 2050 : default:
2351 : 2050 : pp_c_cast_expression (this, e);
2352 : 2050 : break;
2353 : : }
2354 : 2183 : }
2355 : :
2356 : : /* additive-expression:
2357 : : multiplicative-expression
2358 : : additive-expression + multiplicative-expression
2359 : : additive-expression - multiplicative-expression */
2360 : :
2361 : : static void
2362 : 3709 : pp_c_additive_expression (c_pretty_printer *pp, tree e)
2363 : : {
2364 : 3709 : enum tree_code code = TREE_CODE (e);
2365 : 3709 : switch (code)
2366 : : {
2367 : 855 : case POINTER_PLUS_EXPR:
2368 : 855 : case PLUS_EXPR:
2369 : 855 : case POINTER_DIFF_EXPR:
2370 : 855 : case MINUS_EXPR:
2371 : 855 : pp_c_additive_expression (pp, TREE_OPERAND (e, 0));
2372 : 855 : pp_c_whitespace (pp);
2373 : 855 : if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
2374 : 843 : pp_plus (pp);
2375 : : else
2376 : 12 : pp_minus (pp);
2377 : 855 : pp_c_whitespace (pp);
2378 : 855 : {
2379 : 855 : tree op1 = TREE_OPERAND (e, 1);
2380 : 855 : if (code == POINTER_PLUS_EXPR
2381 : 65 : && TREE_CODE (op1) == INTEGER_CST
2382 : 876 : && tree_int_cst_sign_bit (op1))
2383 : : /* A pointer minus an integer is represented internally as plus a very
2384 : : large number, don't expose that to users. */
2385 : 7 : op1 = convert (ssizetype, op1);
2386 : 855 : pp->multiplicative_expression (op1);
2387 : : }
2388 : 855 : break;
2389 : :
2390 : 2854 : default:
2391 : 2854 : pp->multiplicative_expression (e);
2392 : 2854 : break;
2393 : : }
2394 : 3709 : }
2395 : :
2396 : : /* additive-expression:
2397 : : additive-expression
2398 : : shift-expression << additive-expression
2399 : : shift-expression >> additive-expression */
2400 : :
2401 : : static void
2402 : 2001 : pp_c_shift_expression (c_pretty_printer *pp, tree e)
2403 : : {
2404 : 2001 : enum tree_code code = TREE_CODE (e);
2405 : 2001 : switch (code)
2406 : : {
2407 : 116 : case LSHIFT_EXPR:
2408 : 116 : case RSHIFT_EXPR:
2409 : 116 : case LROTATE_EXPR:
2410 : 116 : case RROTATE_EXPR:
2411 : 116 : pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
2412 : 116 : pp_c_whitespace (pp);
2413 : 231 : pp_string (pp, code == LSHIFT_EXPR ? "<<" :
2414 : : code == RSHIFT_EXPR ? ">>" :
2415 : : code == LROTATE_EXPR ? "<<<" : ">>>");
2416 : 116 : pp_c_whitespace (pp);
2417 : 116 : pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
2418 : 116 : break;
2419 : :
2420 : 1885 : default:
2421 : 1885 : pp_c_additive_expression (pp, e);
2422 : : }
2423 : 2001 : }
2424 : :
2425 : : /* relational-expression:
2426 : : shift-expression
2427 : : relational-expression < shift-expression
2428 : : relational-expression > shift-expression
2429 : : relational-expression <= shift-expression
2430 : : relational-expression >= shift-expression */
2431 : :
2432 : : static void
2433 : 1769 : pp_c_relational_expression (c_pretty_printer *pp, tree e)
2434 : : {
2435 : 1769 : enum tree_code code = TREE_CODE (e);
2436 : 1769 : switch (code)
2437 : : {
2438 : 30 : case LT_EXPR:
2439 : 30 : case GT_EXPR:
2440 : 30 : case LE_EXPR:
2441 : 30 : case GE_EXPR:
2442 : 30 : pp_c_relational_expression (pp, TREE_OPERAND (e, 0));
2443 : 30 : pp_c_whitespace (pp);
2444 : 30 : if (code == LT_EXPR)
2445 : 0 : pp_less (pp);
2446 : 30 : else if (code == GT_EXPR)
2447 : 24 : pp_greater (pp);
2448 : 6 : else if (code == LE_EXPR)
2449 : 0 : pp_less_equal (pp);
2450 : 6 : else if (code == GE_EXPR)
2451 : 6 : pp_greater_equal (pp);
2452 : 30 : pp_c_whitespace (pp);
2453 : 30 : pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
2454 : 30 : break;
2455 : :
2456 : 1739 : default:
2457 : 1739 : pp_c_shift_expression (pp, e);
2458 : 1739 : break;
2459 : : }
2460 : 1769 : }
2461 : :
2462 : : /* equality-expression:
2463 : : relational-expression
2464 : : equality-expression == relational-expression
2465 : : equality-equality != relational-expression */
2466 : :
2467 : : static void
2468 : 1709 : pp_c_equality_expression (c_pretty_printer *pp, tree e)
2469 : : {
2470 : 1709 : enum tree_code code = TREE_CODE (e);
2471 : 1709 : switch (code)
2472 : : {
2473 : 269 : case EQ_EXPR:
2474 : 269 : case NE_EXPR:
2475 : 269 : pp_c_equality_expression (pp, TREE_OPERAND (e, 0));
2476 : 269 : pp_c_whitespace (pp);
2477 : 330 : pp_string (pp, code == EQ_EXPR ? "==" : "!=");
2478 : 269 : pp_c_whitespace (pp);
2479 : 269 : pp_c_relational_expression (pp, TREE_OPERAND (e, 1));
2480 : 269 : break;
2481 : :
2482 : 1440 : default:
2483 : 1440 : pp_c_relational_expression (pp, e);
2484 : 1440 : break;
2485 : : }
2486 : 1709 : }
2487 : :
2488 : : /* AND-expression:
2489 : : equality-expression
2490 : : AND-expression & equality-equality */
2491 : :
2492 : : static void
2493 : 1209 : pp_c_and_expression (c_pretty_printer *pp, tree e)
2494 : : {
2495 : 1209 : if (TREE_CODE (e) == BIT_AND_EXPR)
2496 : : {
2497 : 4 : pp_c_and_expression (pp, TREE_OPERAND (e, 0));
2498 : 4 : pp_c_whitespace (pp);
2499 : 4 : pp_ampersand (pp);
2500 : 4 : pp_c_whitespace (pp);
2501 : 4 : pp_c_equality_expression (pp, TREE_OPERAND (e, 1));
2502 : : }
2503 : : else
2504 : 1205 : pp_c_equality_expression (pp, e);
2505 : 1209 : }
2506 : :
2507 : : /* exclusive-OR-expression:
2508 : : AND-expression
2509 : : exclusive-OR-expression ^ AND-expression */
2510 : :
2511 : : static void
2512 : 1201 : pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e)
2513 : : {
2514 : 1201 : if (TREE_CODE (e) == BIT_XOR_EXPR
2515 : 1201 : || TREE_CODE (e) == TRUTH_XOR_EXPR)
2516 : : {
2517 : 1 : pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
2518 : 1 : if (TREE_CODE (e) == BIT_XOR_EXPR)
2519 : 0 : pp_c_maybe_whitespace (pp);
2520 : : else
2521 : 1 : pp_c_whitespace (pp);
2522 : 1 : pp_carret (pp);
2523 : 1 : pp_c_whitespace (pp);
2524 : 1 : pp_c_and_expression (pp, TREE_OPERAND (e, 1));
2525 : : }
2526 : : else
2527 : 1200 : pp_c_and_expression (pp, e);
2528 : 1201 : }
2529 : :
2530 : : /* inclusive-OR-expression:
2531 : : exclusive-OR-expression
2532 : : inclusive-OR-expression | exclusive-OR-expression */
2533 : :
2534 : : static void
2535 : 1187 : pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e)
2536 : : {
2537 : 1187 : if (TREE_CODE (e) == BIT_IOR_EXPR)
2538 : : {
2539 : 12 : pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
2540 : 12 : pp_c_whitespace (pp);
2541 : 12 : pp_bar (pp);
2542 : 12 : pp_c_whitespace (pp);
2543 : 12 : pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1));
2544 : : }
2545 : : else
2546 : 1175 : pp_c_exclusive_or_expression (pp, e);
2547 : 1187 : }
2548 : :
2549 : : /* logical-AND-expression:
2550 : : inclusive-OR-expression
2551 : : logical-AND-expression && inclusive-OR-expression */
2552 : :
2553 : : static void
2554 : 1175 : pp_c_logical_and_expression (c_pretty_printer *pp, tree e)
2555 : : {
2556 : 1175 : if (TREE_CODE (e) == TRUTH_ANDIF_EXPR
2557 : 655 : || TREE_CODE (e) == TRUTH_AND_EXPR)
2558 : : {
2559 : 521 : pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
2560 : 521 : pp_c_whitespace (pp);
2561 : 521 : pp_ampersand_ampersand (pp);
2562 : 521 : pp_c_whitespace (pp);
2563 : 521 : pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
2564 : : }
2565 : : else
2566 : 654 : pp_c_inclusive_or_expression (pp, e);
2567 : 1175 : }
2568 : :
2569 : : /* logical-OR-expression:
2570 : : logical-AND-expression
2571 : : logical-OR-expression || logical-AND-expression */
2572 : :
2573 : : void
2574 : 259 : pp_c_logical_or_expression (c_pretty_printer *pp, tree e)
2575 : : {
2576 : 259 : if (TREE_CODE (e) == TRUTH_ORIF_EXPR
2577 : 149 : || TREE_CODE (e) == TRUTH_OR_EXPR)
2578 : : {
2579 : 111 : pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
2580 : 111 : pp_c_whitespace (pp);
2581 : 111 : pp_bar_bar (pp);
2582 : 111 : pp_c_whitespace (pp);
2583 : 111 : pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
2584 : : }
2585 : : else
2586 : 148 : pp_c_logical_and_expression (pp, e);
2587 : 259 : }
2588 : :
2589 : : /* conditional-expression:
2590 : : logical-OR-expression
2591 : : logical-OR-expression ? expression : conditional-expression */
2592 : :
2593 : : void
2594 : 42 : c_pretty_printer::conditional_expression (tree e)
2595 : : {
2596 : 42 : if (TREE_CODE (e) == COND_EXPR)
2597 : : {
2598 : 21 : pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
2599 : 21 : pp_c_whitespace (this);
2600 : 21 : pp_question (this);
2601 : 21 : pp_c_whitespace (this);
2602 : 21 : expression (TREE_OPERAND (e, 1));
2603 : 21 : pp_c_whitespace (this);
2604 : 21 : pp_colon (this);
2605 : 21 : pp_c_whitespace (this);
2606 : 21 : conditional_expression (TREE_OPERAND (e, 2));
2607 : : }
2608 : : else
2609 : 21 : pp_c_logical_or_expression (this, e);
2610 : 42 : }
2611 : :
2612 : :
2613 : : /* assignment-expression:
2614 : : conditional-expression
2615 : : unary-expression assignment-operator assignment-expression
2616 : :
2617 : : assignment-expression: one of
2618 : : = *= /= %= += -= >>= <<= &= ^= |= */
2619 : :
2620 : : void
2621 : 0 : c_pretty_printer::assignment_expression (tree e)
2622 : : {
2623 : 0 : if (TREE_CODE (e) == MODIFY_EXPR
2624 : 0 : || TREE_CODE (e) == INIT_EXPR)
2625 : : {
2626 : 0 : unary_expression (TREE_OPERAND (e, 0));
2627 : 0 : pp_c_whitespace (this);
2628 : 0 : pp_equal (this);
2629 : 0 : pp_space (this);
2630 : 0 : expression (TREE_OPERAND (e, 1));
2631 : : }
2632 : : else
2633 : 0 : conditional_expression (e);
2634 : 0 : }
2635 : :
2636 : : /* expression:
2637 : : assignment-expression
2638 : : expression , assignment-expression
2639 : :
2640 : : Implementation note: instead of going through the usual recursion
2641 : : chain, I take the liberty of dispatching nodes to the appropriate
2642 : : functions. This makes some redundancy, but it worths it. That also
2643 : : prevents a possible infinite recursion between primary_expression ()
2644 : : and expression (). */
2645 : :
2646 : : void
2647 : 45260 : c_pretty_printer::expression (tree e)
2648 : : {
2649 : 45260 : switch (TREE_CODE (e))
2650 : : {
2651 : 0 : case VOID_CST:
2652 : 0 : pp_c_void_constant (this);
2653 : 0 : break;
2654 : :
2655 : 7571 : case INTEGER_CST:
2656 : 7571 : pp_c_integer_constant (this, e);
2657 : 7571 : break;
2658 : :
2659 : 171 : case REAL_CST:
2660 : 171 : pp_c_floating_constant (this, e);
2661 : 171 : break;
2662 : :
2663 : 0 : case FIXED_CST:
2664 : 0 : pp_c_fixed_constant (this, e);
2665 : 0 : break;
2666 : :
2667 : 265 : case STRING_CST:
2668 : 265 : pp_c_string_literal (this, e);
2669 : 265 : break;
2670 : :
2671 : 27144 : case IDENTIFIER_NODE:
2672 : 27144 : case FUNCTION_DECL:
2673 : 27144 : case VAR_DECL:
2674 : 27144 : case CONST_DECL:
2675 : 27144 : case PARM_DECL:
2676 : 27144 : case RESULT_DECL:
2677 : 27144 : case FIELD_DECL:
2678 : 27144 : case LABEL_DECL:
2679 : 27144 : case ERROR_MARK:
2680 : 27144 : primary_expression (e);
2681 : 27144 : break;
2682 : :
2683 : 4473 : case SSA_NAME:
2684 : 4473 : if (SSA_NAME_VAR (e)
2685 : 4387 : && !DECL_ARTIFICIAL (SSA_NAME_VAR (e)))
2686 : 4375 : expression (SSA_NAME_VAR (e));
2687 : : else
2688 : 98 : translate_string ("<unknown>");
2689 : : break;
2690 : :
2691 : 1290 : case POSTINCREMENT_EXPR:
2692 : 1290 : case POSTDECREMENT_EXPR:
2693 : 1290 : case ARRAY_REF:
2694 : 1290 : case OMP_ARRAY_SECTION:
2695 : 1290 : case CALL_EXPR:
2696 : 1290 : case COMPONENT_REF:
2697 : 1290 : case BIT_FIELD_REF:
2698 : 1290 : case COMPLEX_CST:
2699 : 1290 : case COMPLEX_EXPR:
2700 : 1290 : case VECTOR_CST:
2701 : 1290 : case ORDERED_EXPR:
2702 : 1290 : case UNORDERED_EXPR:
2703 : 1290 : case LTGT_EXPR:
2704 : 1290 : case UNEQ_EXPR:
2705 : 1290 : case UNLE_EXPR:
2706 : 1290 : case UNLT_EXPR:
2707 : 1290 : case UNGE_EXPR:
2708 : 1290 : case UNGT_EXPR:
2709 : 1290 : case MAX_EXPR:
2710 : 1290 : case MIN_EXPR:
2711 : 1290 : case ABS_EXPR:
2712 : 1290 : case CONSTRUCTOR:
2713 : 1290 : case COMPOUND_LITERAL_EXPR:
2714 : 1290 : case VA_ARG_EXPR:
2715 : 1290 : postfix_expression (e);
2716 : 1290 : break;
2717 : :
2718 : 1665 : case CONJ_EXPR:
2719 : 1665 : case ADDR_EXPR:
2720 : 1665 : case INDIRECT_REF:
2721 : 1665 : case MEM_REF:
2722 : 1665 : case TARGET_MEM_REF:
2723 : 1665 : case NEGATE_EXPR:
2724 : 1665 : case BIT_NOT_EXPR:
2725 : 1665 : case TRUTH_NOT_EXPR:
2726 : 1665 : case PREINCREMENT_EXPR:
2727 : 1665 : case PREDECREMENT_EXPR:
2728 : 1665 : case REALPART_EXPR:
2729 : 1665 : case IMAGPART_EXPR:
2730 : 1665 : unary_expression (e);
2731 : 1665 : break;
2732 : :
2733 : 250 : case FLOAT_EXPR:
2734 : 250 : case FIX_TRUNC_EXPR:
2735 : 250 : CASE_CONVERT:
2736 : 250 : case VIEW_CONVERT_EXPR:
2737 : 250 : case EXCESS_PRECISION_EXPR:
2738 : 250 : pp_c_cast_expression (this, e);
2739 : 250 : break;
2740 : :
2741 : 90 : case MULT_EXPR:
2742 : 90 : case TRUNC_MOD_EXPR:
2743 : 90 : case TRUNC_DIV_EXPR:
2744 : 90 : case EXACT_DIV_EXPR:
2745 : 90 : case RDIV_EXPR:
2746 : 90 : multiplicative_expression (e);
2747 : 90 : break;
2748 : :
2749 : 116 : case LSHIFT_EXPR:
2750 : 116 : case RSHIFT_EXPR:
2751 : 116 : case LROTATE_EXPR:
2752 : 116 : case RROTATE_EXPR:
2753 : 116 : pp_c_shift_expression (this, e);
2754 : 116 : break;
2755 : :
2756 : 30 : case LT_EXPR:
2757 : 30 : case GT_EXPR:
2758 : 30 : case LE_EXPR:
2759 : 30 : case GE_EXPR:
2760 : 30 : pp_c_relational_expression (this, e);
2761 : 30 : break;
2762 : :
2763 : 4 : case BIT_AND_EXPR:
2764 : 4 : pp_c_and_expression (this, e);
2765 : 4 : break;
2766 : :
2767 : 1 : case BIT_XOR_EXPR:
2768 : 1 : case TRUTH_XOR_EXPR:
2769 : 1 : pp_c_exclusive_or_expression (this, e);
2770 : 1 : break;
2771 : :
2772 : 12 : case BIT_IOR_EXPR:
2773 : 12 : pp_c_inclusive_or_expression (this, e);
2774 : 12 : break;
2775 : :
2776 : 395 : case TRUTH_ANDIF_EXPR:
2777 : 395 : case TRUTH_AND_EXPR:
2778 : 395 : pp_c_logical_and_expression (this, e);
2779 : 395 : break;
2780 : :
2781 : 81 : case TRUTH_ORIF_EXPR:
2782 : 81 : case TRUTH_OR_EXPR:
2783 : 81 : pp_c_logical_or_expression (this, e);
2784 : 81 : break;
2785 : :
2786 : 231 : case EQ_EXPR:
2787 : 231 : case NE_EXPR:
2788 : 231 : pp_c_equality_expression (this, e);
2789 : 231 : break;
2790 : :
2791 : 21 : case COND_EXPR:
2792 : 21 : conditional_expression (e);
2793 : 21 : break;
2794 : :
2795 : 853 : case POINTER_PLUS_EXPR:
2796 : 853 : case PLUS_EXPR:
2797 : 853 : case POINTER_DIFF_EXPR:
2798 : 853 : case MINUS_EXPR:
2799 : 853 : pp_c_additive_expression (this, e);
2800 : 853 : break;
2801 : :
2802 : 0 : case MODIFY_EXPR:
2803 : 0 : case INIT_EXPR:
2804 : 0 : assignment_expression (e);
2805 : 0 : break;
2806 : :
2807 : 0 : case COMPOUND_EXPR:
2808 : 0 : pp_c_left_paren (this);
2809 : 0 : expression (TREE_OPERAND (e, 0));
2810 : 0 : pp_separate_with (this, ',');
2811 : 0 : assignment_expression (TREE_OPERAND (e, 1));
2812 : 0 : pp_c_right_paren (this);
2813 : 0 : break;
2814 : :
2815 : 587 : case NON_LVALUE_EXPR:
2816 : 587 : case SAVE_EXPR:
2817 : 587 : expression (TREE_OPERAND (e, 0));
2818 : 587 : break;
2819 : :
2820 : 2 : case TARGET_EXPR:
2821 : 2 : postfix_expression (TARGET_EXPR_INITIAL (e));
2822 : 2 : break;
2823 : :
2824 : 2 : case BIND_EXPR:
2825 : 2 : case GOTO_EXPR:
2826 : : /* We don't yet have a way of dumping statements in a
2827 : : human-readable format. */
2828 : 2 : pp_string (this, "({...})");
2829 : 2 : break;
2830 : :
2831 : 6 : case C_MAYBE_CONST_EXPR:
2832 : 6 : expression (C_MAYBE_CONST_EXPR_EXPR (e));
2833 : 6 : break;
2834 : :
2835 : 0 : default:
2836 : 0 : pp_unsupported_tree (this, e);
2837 : 0 : break;
2838 : : }
2839 : 45260 : }
2840 : :
2841 : :
2842 : :
2843 : : /* Statements. */
2844 : :
2845 : : void
2846 : 5816 : c_pretty_printer::statement (tree t)
2847 : : {
2848 : 5816 : if (t == NULL)
2849 : : return;
2850 : :
2851 : 5816 : switch (TREE_CODE (t))
2852 : : {
2853 : :
2854 : 0 : case SWITCH_STMT:
2855 : 0 : if (dump_flags != TDF_NONE)
2856 : 0 : internal_error ("dump flags not handled here");
2857 : :
2858 : 0 : pp_c_ws_string (this, "switch");
2859 : 0 : pp_space (this);
2860 : 0 : pp_c_left_paren (this);
2861 : 0 : expression (SWITCH_STMT_COND (t));
2862 : 0 : pp_c_right_paren (this);
2863 : 0 : pp_indentation (this) += 3;
2864 : 0 : pp_needs_newline (this) = true;
2865 : 0 : statement (SWITCH_STMT_BODY (t));
2866 : 0 : pp_newline_and_indent (this, -3);
2867 : 0 : break;
2868 : :
2869 : : /* iteration-statement:
2870 : : while ( expression ) statement
2871 : : do statement while ( expression ) ;
2872 : : for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
2873 : : for ( declaration expression(opt) ; expression(opt) ) statement */
2874 : 0 : case WHILE_STMT:
2875 : 0 : if (dump_flags != TDF_NONE)
2876 : 0 : internal_error ("dump flags not handled here");
2877 : :
2878 : 0 : pp_c_ws_string (this, "while");
2879 : 0 : pp_space (this);
2880 : 0 : pp_c_left_paren (this);
2881 : 0 : expression (WHILE_COND (t));
2882 : 0 : pp_c_right_paren (this);
2883 : 0 : pp_newline_and_indent (this, 3);
2884 : 0 : statement (WHILE_BODY (t));
2885 : 0 : pp_indentation (this) -= 3;
2886 : 0 : pp_needs_newline (this) = true;
2887 : 0 : break;
2888 : :
2889 : 0 : case DO_STMT:
2890 : 0 : if (dump_flags != TDF_NONE)
2891 : 0 : internal_error ("dump flags not handled here");
2892 : :
2893 : 0 : pp_c_ws_string (this, "do");
2894 : 0 : pp_newline_and_indent (this, 3);
2895 : 0 : statement (DO_BODY (t));
2896 : 0 : pp_newline_and_indent (this, -3);
2897 : 0 : pp_c_ws_string (this, "while");
2898 : 0 : pp_space (this);
2899 : 0 : pp_c_left_paren (this);
2900 : 0 : expression (DO_COND (t));
2901 : 0 : pp_c_right_paren (this);
2902 : 0 : pp_c_semicolon (this);
2903 : 0 : pp_needs_newline (this) = true;
2904 : 0 : break;
2905 : :
2906 : 0 : case FOR_STMT:
2907 : 0 : if (dump_flags != TDF_NONE)
2908 : 0 : internal_error ("dump flags not handled here");
2909 : :
2910 : 0 : pp_c_ws_string (this, "for");
2911 : 0 : pp_space (this);
2912 : 0 : pp_c_left_paren (this);
2913 : 0 : if (FOR_INIT_STMT (t))
2914 : 0 : statement (FOR_INIT_STMT (t));
2915 : : else
2916 : 0 : pp_c_semicolon (this);
2917 : 0 : pp_needs_newline (this) = false;
2918 : 0 : pp_c_whitespace (this);
2919 : 0 : if (FOR_COND (t))
2920 : 0 : expression (FOR_COND (t));
2921 : 0 : pp_c_semicolon (this);
2922 : 0 : pp_needs_newline (this) = false;
2923 : 0 : pp_c_whitespace (this);
2924 : 0 : if (FOR_EXPR (t))
2925 : 0 : expression (FOR_EXPR (t));
2926 : 0 : pp_c_right_paren (this);
2927 : 0 : pp_newline_and_indent (this, 3);
2928 : 0 : statement (FOR_BODY (t));
2929 : 0 : pp_indentation (this) -= 3;
2930 : 0 : pp_needs_newline (this) = true;
2931 : 0 : break;
2932 : :
2933 : : /* jump-statement:
2934 : : goto identifier;
2935 : : continue ;
2936 : : return expression(opt) ; */
2937 : 0 : case BREAK_STMT:
2938 : 0 : if (dump_flags != TDF_NONE)
2939 : 0 : internal_error ("dump flags not handled here");
2940 : :
2941 : 0 : pp_string (this, "break");
2942 : 0 : if (BREAK_NAME (t))
2943 : : {
2944 : 0 : pp_space (this);
2945 : 0 : pp_c_tree_decl_identifier (this, BREAK_NAME (t));
2946 : : }
2947 : 0 : pp_c_semicolon (this);
2948 : 0 : pp_needs_newline (this) = true;
2949 : 0 : break;
2950 : :
2951 : 0 : case CONTINUE_STMT:
2952 : 0 : if (dump_flags != TDF_NONE)
2953 : 0 : internal_error ("dump flags not handled here");
2954 : :
2955 : 0 : pp_string (this, "continue");
2956 : 0 : if (CONTINUE_NAME (t))
2957 : : {
2958 : 0 : pp_space (this);
2959 : 0 : pp_c_tree_decl_identifier (this, CONTINUE_NAME (t));
2960 : : }
2961 : 0 : pp_c_semicolon (this);
2962 : 0 : pp_needs_newline (this) = true;
2963 : 0 : break;
2964 : :
2965 : 5816 : default:
2966 : 5816 : if (pp_needs_newline (this))
2967 : 5816 : pp_newline_and_indent (this, 0);
2968 : 5816 : dump_generic_node (this, t, pp_indentation (this), dump_flags, true);
2969 : : }
2970 : : }
2971 : :
2972 : :
2973 : : /* Initialize the PRETTY-PRINTER for handling C codes. */
2974 : :
2975 : 318721 : c_pretty_printer::c_pretty_printer (dump_flags_t dump_flags)
2976 : : : pretty_printer (),
2977 : 318721 : dump_flags (dump_flags),
2978 : 318721 : offset_list (),
2979 : 318721 : flags ()
2980 : : {
2981 : 318721 : type_specifier_seq = pp_c_specifier_qualifier_list;
2982 : 318721 : ptr_operator = pp_c_pointer;
2983 : 318721 : parameter_list = pp_c_parameter_type_list;
2984 : 318721 : }
2985 : :
2986 : : /* c_pretty_printer's implementation of pretty_printer::clone vfunc. */
2987 : :
2988 : : std::unique_ptr<pretty_printer>
2989 : 263326 : c_pretty_printer::clone () const
2990 : : {
2991 : 263326 : return std::make_unique<c_pretty_printer> (*this);
2992 : : }
2993 : :
2994 : : /* Print the tree T in full, on file FILE. */
2995 : :
2996 : : void
2997 : 5816 : print_c_tree (FILE *file, tree t, dump_flags_t dump_flags)
2998 : : {
2999 : 5816 : c_pretty_printer pp (dump_flags);
3000 : :
3001 : 5816 : pp_needs_newline (&pp) = true;
3002 : 5816 : pp.set_output_stream (file);
3003 : 5816 : pp.statement (t);
3004 : 5816 : pp_newline_and_flush (&pp);
3005 : 5816 : }
3006 : :
3007 : : /* Print the tree T in full, on stderr. */
3008 : :
3009 : : DEBUG_FUNCTION void
3010 : 0 : debug_c_tree (tree t)
3011 : : {
3012 : 0 : print_c_tree (stderr, t, TDF_NONE);
3013 : 0 : fputc ('\n', stderr);
3014 : 0 : }
3015 : :
3016 : : /* Output the DECL_NAME of T. If T has no DECL_NAME, output a string made
3017 : : up of T's memory address. */
3018 : :
3019 : : void
3020 : 58472 : pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
3021 : : {
3022 : 58472 : const char *name;
3023 : :
3024 : 58472 : gcc_assert (DECL_P (t));
3025 : :
3026 : 58472 : if (DECL_NAME (t))
3027 : : {
3028 : 58368 : const char *dot;
3029 : 58368 : name = IDENTIFIER_POINTER (DECL_NAME (t));
3030 : 58368 : if (DECL_ARTIFICIAL (t) && (dot = strchr (name, '.')))
3031 : : {
3032 : : /* Print the name without the . suffix (such as in VLAs and
3033 : : callee-copied parameters). */
3034 : 61 : size_t size = dot - name;
3035 : 61 : char *ident = XALLOCAVEC (char, size + 1);
3036 : 61 : memcpy (ident, name, size);
3037 : 61 : ident[size] = '\0';
3038 : 61 : name = ident;
3039 : : }
3040 : : }
3041 : : else
3042 : : {
3043 : 104 : static char xname[8];
3044 : 104 : sprintf (xname, "<U%4hx>", ((unsigned short) ((uintptr_t) (t)
3045 : : & 0xffff)));
3046 : 104 : name = xname;
3047 : : }
3048 : :
3049 : 58472 : pp_c_identifier (pp, name);
3050 : 58472 : }
3051 : :
3052 : : /* Prints "[version: VERSION]" for a versioned function decl.
3053 : : This will only print for targets with target_version semantics. */
3054 : : void
3055 : 561775 : pp_c_function_target_version (c_pretty_printer *pp, tree t)
3056 : : {
3057 : 561775 : if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
3058 : 561775 : return;
3059 : :
3060 : : string_slice version = get_target_version (t);
3061 : : if (!version.is_valid ())
3062 : : return;
3063 : :
3064 : : pp_c_whitespace (pp);
3065 : :
3066 : : pp_c_left_bracket (pp);
3067 : : pp_c_left_bracket (pp);
3068 : : pp_string (pp, "target_version");
3069 : : pp_c_left_paren (pp);
3070 : : pp_doublequote (pp);
3071 : : pp_string_n (pp, version.begin (), version.size ());
3072 : : pp_doublequote (pp);
3073 : : pp_c_right_paren (pp);
3074 : : pp_c_right_bracket (pp);
3075 : : pp_c_right_bracket (pp);
3076 : :
3077 : : pp->set_padding (pp_before);
3078 : : }
3079 : :
3080 : : /* Prints "[clones: VERSION, +]" for a versioned function decl.
3081 : : This only works for targets with target_version semantics. */
3082 : : void
3083 : 561775 : pp_c_function_target_clones (c_pretty_printer *pp, tree t)
3084 : : {
3085 : : /* Only print for target_version semantics.
3086 : : This is because for target FMV semantics a target_clone always defines
3087 : : the entire FMV set. target_version semantics can mix target_clone and
3088 : : target_version decls in the definition of a FMV set and so the
3089 : : target_clone becomes a part of the identity of the declaration. */
3090 : 561775 : if (TARGET_HAS_FMV_TARGET_ATTRIBUTE)
3091 : 561775 : return;
3092 : :
3093 : : auto_vec<string_slice> versions = get_clone_versions (t, NULL, false);
3094 : : if (versions.is_empty ())
3095 : : return;
3096 : :
3097 : : pp_c_whitespace (pp);
3098 : :
3099 : : string_slice final_version = versions.pop ();
3100 : : pp_c_left_bracket (pp);
3101 : : pp_c_left_bracket (pp);
3102 : : pp_string (pp, "target_clones");
3103 : : pp_c_left_paren (pp);
3104 : : for (string_slice version : versions)
3105 : : {
3106 : : pp_doublequote (pp);
3107 : : pp_string_n (pp, version.begin (), version.size ());
3108 : : pp_doublequote (pp);
3109 : : pp_string (pp, ",");
3110 : : pp_c_whitespace (pp);
3111 : : }
3112 : : pp_doublequote (pp);
3113 : : pp_string_n (pp, final_version.begin (), final_version.size ());
3114 : : pp_doublequote (pp);
3115 : : pp_c_right_paren (pp);
3116 : : pp_c_right_bracket (pp);
3117 : : pp_c_right_bracket (pp);
3118 : :
3119 : : pp->set_padding (pp_before);
3120 : : }
3121 : :
3122 : : #if CHECKING_P
3123 : :
3124 : : namespace selftest {
3125 : :
3126 : : /* Selftests for pretty-printing trees. */
3127 : :
3128 : : /* Verify that EXPR printed by c_pretty_printer is EXPECTED, using
3129 : : LOC as the effective location for any failures. */
3130 : :
3131 : : static void
3132 : 12 : assert_c_pretty_printer_output (const location &loc, const char *expected,
3133 : : tree expr)
3134 : : {
3135 : 12 : c_pretty_printer pp;
3136 : 12 : pp.expression (expr);
3137 : 12 : ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
3138 : 12 : }
3139 : :
3140 : : /* Helper function for calling assert_c_pretty_printer_output.
3141 : : This is to avoid having to write SELFTEST_LOCATION. */
3142 : :
3143 : : #define ASSERT_C_PRETTY_PRINTER_OUTPUT(EXPECTED, EXPR) \
3144 : : SELFTEST_BEGIN_STMT \
3145 : : assert_c_pretty_printer_output ((SELFTEST_LOCATION), \
3146 : : (EXPECTED), \
3147 : : (EXPR)); \
3148 : : SELFTEST_END_STMT
3149 : :
3150 : : /* Verify that location wrappers don't show up in pretty-printed output. */
3151 : :
3152 : : static void
3153 : 3 : test_location_wrappers ()
3154 : : {
3155 : : /* VAR_DECL. */
3156 : 3 : tree id = get_identifier ("foo");
3157 : 3 : tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
3158 : : integer_type_node);
3159 : 3 : tree wrapped_decl = maybe_wrap_with_location (decl, BUILTINS_LOCATION);
3160 : 3 : ASSERT_NE (wrapped_decl, decl);
3161 : 3 : ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", decl);
3162 : 3 : ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", wrapped_decl);
3163 : :
3164 : : /* INTEGER_CST. */
3165 : 3 : tree int_cst = build_int_cst (integer_type_node, 42);
3166 : 3 : tree wrapped_cst = maybe_wrap_with_location (int_cst, BUILTINS_LOCATION);
3167 : 3 : ASSERT_NE (wrapped_cst, int_cst);
3168 : 3 : ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", int_cst);
3169 : 3 : ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", wrapped_cst);
3170 : 3 : }
3171 : :
3172 : : /* Run all of the selftests within this file. */
3173 : :
3174 : : void
3175 : 3 : c_pretty_print_cc_tests ()
3176 : : {
3177 : 3 : test_location_wrappers ();
3178 : 3 : }
3179 : :
3180 : : } // namespace selftest
3181 : :
3182 : : #endif /* CHECKING_P */
|