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