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