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

source code of gcc/c-family/c-pretty-print.cc