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