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