1/* Subroutines common to both C and C++ pretty-printers.
2 Copyright (C) 2002-2024 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
4
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 OMP_ARRAY_SECTION:
1654 postfix_expression (TREE_OPERAND (e, 0));
1655 pp_c_left_bracket (pp: this);
1656 if (TREE_OPERAND (e, 1))
1657 expression (TREE_OPERAND (e, 1));
1658 pp_colon (this);
1659 if (TREE_OPERAND (e, 2))
1660 expression (TREE_OPERAND (e, 2));
1661 pp_c_right_bracket (pp: this);
1662 break;
1663
1664 case CALL_EXPR:
1665 {
1666 call_expr_arg_iterator iter;
1667 tree arg;
1668 if (CALL_EXPR_FN (e) != NULL_TREE)
1669 postfix_expression (CALL_EXPR_FN (e));
1670 else
1671 pp_string (this, internal_fn_name (CALL_EXPR_IFN (e)));
1672 pp_c_left_paren (pp: this);
1673 FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
1674 {
1675 expression (arg);
1676 if (more_call_expr_args_p (iter: &iter))
1677 pp_separate_with (this, ',');
1678 }
1679 pp_c_right_paren (pp: this);
1680 break;
1681 }
1682
1683 case UNORDERED_EXPR:
1684 pp_c_ws_string (pp: this, str: flag_isoc99
1685 ? "isunordered"
1686 : "__builtin_isunordered");
1687 goto two_args_fun;
1688
1689 case ORDERED_EXPR:
1690 pp_c_ws_string (pp: this, str: flag_isoc99
1691 ? "!isunordered"
1692 : "!__builtin_isunordered");
1693 goto two_args_fun;
1694
1695 case UNLT_EXPR:
1696 pp_c_ws_string (pp: this, str: flag_isoc99
1697 ? "!isgreaterequal"
1698 : "!__builtin_isgreaterequal");
1699 goto two_args_fun;
1700
1701 case UNLE_EXPR:
1702 pp_c_ws_string (pp: this, str: flag_isoc99
1703 ? "!isgreater"
1704 : "!__builtin_isgreater");
1705 goto two_args_fun;
1706
1707 case UNGT_EXPR:
1708 pp_c_ws_string (pp: this, str: flag_isoc99
1709 ? "!islessequal"
1710 : "!__builtin_islessequal");
1711 goto two_args_fun;
1712
1713 case UNGE_EXPR:
1714 pp_c_ws_string (pp: this, str: flag_isoc99
1715 ? "!isless"
1716 : "!__builtin_isless");
1717 goto two_args_fun;
1718
1719 case UNEQ_EXPR:
1720 pp_c_ws_string (pp: this, str: flag_isoc99
1721 ? "!islessgreater"
1722 : "!__builtin_islessgreater");
1723 goto two_args_fun;
1724
1725 case LTGT_EXPR:
1726 pp_c_ws_string (pp: this, str: flag_isoc99
1727 ? "islessgreater"
1728 : "__builtin_islessgreater");
1729 goto two_args_fun;
1730
1731 case MAX_EXPR:
1732 pp_c_ws_string (pp: this, str: "max");
1733 goto two_args_fun;
1734
1735 case MIN_EXPR:
1736 pp_c_ws_string (pp: this, str: "min");
1737 goto two_args_fun;
1738
1739 two_args_fun:
1740 pp_c_left_paren (pp: this);
1741 expression (TREE_OPERAND (e, 0));
1742 pp_separate_with (this, ',');
1743 expression (TREE_OPERAND (e, 1));
1744 pp_c_right_paren (pp: this);
1745 break;
1746
1747 case ABS_EXPR:
1748 pp_c_ws_string (pp: this, str: "__builtin_abs");
1749 pp_c_left_paren (pp: this);
1750 expression (TREE_OPERAND (e, 0));
1751 pp_c_right_paren (pp: this);
1752 break;
1753
1754 case COMPONENT_REF:
1755 {
1756 tree object = TREE_OPERAND (e, 0);
1757 if (INDIRECT_REF_P (object))
1758 {
1759 postfix_expression (TREE_OPERAND (object, 0));
1760 pp_c_arrow (pp: this);
1761 }
1762 else
1763 {
1764 postfix_expression (e: object);
1765 pp_c_dot (pp: this);
1766 }
1767 expression (TREE_OPERAND (e, 1));
1768 }
1769 break;
1770
1771 case BIT_FIELD_REF:
1772 {
1773 tree type = TREE_TYPE (e);
1774
1775 type = signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type);
1776 if (type
1777 && tree_int_cst_equal (TYPE_SIZE (type), TREE_OPERAND (e, 1)))
1778 {
1779 HOST_WIDE_INT bitpos = tree_to_shwi (TREE_OPERAND (e, 2));
1780 HOST_WIDE_INT size = tree_to_shwi (TYPE_SIZE (type));
1781 if ((bitpos % size) == 0)
1782 {
1783 pp_c_left_paren (pp: this);
1784 pp_c_left_paren (pp: this);
1785 type_id (t: type);
1786 pp_c_star (pp: this);
1787 pp_c_right_paren (pp: this);
1788 pp_c_ampersand (pp: this);
1789 expression (TREE_OPERAND (e, 0));
1790 pp_c_right_paren (pp: this);
1791 pp_c_left_bracket (pp: this);
1792 pp_wide_integer (pp: this, i: bitpos / size);
1793 pp_c_right_bracket (pp: this);
1794 break;
1795 }
1796 }
1797 pp_unsupported_tree (this, e);
1798 }
1799 break;
1800
1801 case MEM_REF:
1802 case TARGET_MEM_REF:
1803 expression (e);
1804 break;
1805
1806 case COMPLEX_CST:
1807 case VECTOR_CST:
1808 pp_c_compound_literal (pp: this, e);
1809 break;
1810
1811 case COMPLEX_EXPR:
1812 pp_c_complex_expr (pp: this, e);
1813 break;
1814
1815 case COMPOUND_LITERAL_EXPR:
1816 e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
1817 /* Fall through. */
1818 case CONSTRUCTOR:
1819 initializer (e);
1820 break;
1821
1822 case VA_ARG_EXPR:
1823 pp_c_ws_string (pp: this, str: "__builtin_va_arg");
1824 pp_c_left_paren (pp: this);
1825 assignment_expression (TREE_OPERAND (e, 0));
1826 pp_separate_with (this, ',');
1827 type_id (TREE_TYPE (e));
1828 pp_c_right_paren (pp: this);
1829 break;
1830
1831 case ADDR_EXPR:
1832 if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
1833 {
1834 id_expression (TREE_OPERAND (e, 0));
1835 break;
1836 }
1837 /* fall through. */
1838
1839 default:
1840 primary_expression (e);
1841 break;
1842 }
1843}
1844
1845/* Print out an expression-list; E is expected to be a TREE_LIST. */
1846
1847void
1848pp_c_expression_list (c_pretty_printer *pp, tree e)
1849{
1850 for (; e != NULL_TREE; e = TREE_CHAIN (e))
1851 {
1852 pp->expression (TREE_VALUE (e));
1853 if (TREE_CHAIN (e))
1854 pp_separate_with (pp, ',');
1855 }
1856}
1857
1858/* Print out V, which contains the elements of a constructor. */
1859
1860void
1861pp_c_constructor_elts (c_pretty_printer *pp, vec<constructor_elt, va_gc> *v)
1862{
1863 unsigned HOST_WIDE_INT ix;
1864 tree value;
1865
1866 FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
1867 {
1868 pp->expression (value);
1869 if (ix != vec_safe_length (v) - 1)
1870 pp_separate_with (pp, ',');
1871 }
1872}
1873
1874/* Print out an expression-list in parens, as if it were the argument
1875 list to a function. */
1876
1877void
1878pp_c_call_argument_list (c_pretty_printer *pp, tree t)
1879{
1880 pp_c_left_paren (pp);
1881 if (t && TREE_CODE (t) == TREE_LIST)
1882 pp_c_expression_list (pp, e: t);
1883 pp_c_right_paren (pp);
1884}
1885
1886/* Try to fold *(type *)&op into op.fld.fld2[1] if possible.
1887 Only used for printing expressions. Should punt if ambiguous
1888 (e.g. in unions). */
1889
1890static tree
1891c_fold_indirect_ref_for_warn (location_t loc, tree type, tree op,
1892 offset_int &off)
1893{
1894 tree optype = TREE_TYPE (op);
1895 if (off == 0)
1896 {
1897 if (lang_hooks.types_compatible_p (optype, type))
1898 return op;
1899 /* *(foo *)&complexfoo => __real__ complexfoo */
1900 else if (TREE_CODE (optype) == COMPLEX_TYPE
1901 && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
1902 return build1_loc (loc, code: REALPART_EXPR, type, arg1: op);
1903 }
1904 /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
1905 else if (TREE_CODE (optype) == COMPLEX_TYPE
1906 && lang_hooks.types_compatible_p (type, TREE_TYPE (optype))
1907 && tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
1908 {
1909 off = 0;
1910 return build1_loc (loc, code: IMAGPART_EXPR, type, arg1: op);
1911 }
1912 /* ((foo *)&fooarray)[x] => fooarray[x] */
1913 if (TREE_CODE (optype) == ARRAY_TYPE
1914 && TYPE_SIZE_UNIT (TREE_TYPE (optype))
1915 && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (optype))) == INTEGER_CST
1916 && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
1917 {
1918 tree type_domain = TYPE_DOMAIN (optype);
1919 tree min_val = size_zero_node;
1920 if (type_domain && TYPE_MIN_VALUE (type_domain))
1921 min_val = TYPE_MIN_VALUE (type_domain);
1922 offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
1923 offset_int idx = off / el_sz;
1924 offset_int rem = off % el_sz;
1925 if (TREE_CODE (min_val) == INTEGER_CST)
1926 {
1927 tree index
1928 = wide_int_to_tree (sizetype, cst: idx + wi::to_offset (t: min_val));
1929 op = build4_loc (loc, code: ARRAY_REF, TREE_TYPE (optype), arg0: op, arg1: index,
1930 NULL_TREE, NULL_TREE);
1931 off = rem;
1932 if (tree ret = c_fold_indirect_ref_for_warn (loc, type, op, off))
1933 return ret;
1934 return op;
1935 }
1936 }
1937 /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
1938 else if (TREE_CODE (optype) == RECORD_TYPE)
1939 {
1940 for (tree field = TYPE_FIELDS (optype);
1941 field; field = DECL_CHAIN (field))
1942 if (TREE_CODE (field) == FIELD_DECL
1943 && TREE_TYPE (field) != error_mark_node
1944 && TYPE_SIZE_UNIT (TREE_TYPE (field))
1945 && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (field))) == INTEGER_CST)
1946 {
1947 tree pos = byte_position (field);
1948 if (TREE_CODE (pos) != INTEGER_CST)
1949 continue;
1950 offset_int upos = wi::to_offset (t: pos);
1951 offset_int el_sz
1952 = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (field)));
1953 if (upos <= off && off < upos + el_sz)
1954 {
1955 /* The C++ pretty printers print scope of the FIELD_DECLs,
1956 so punt if it is something that can't be printed. */
1957 if (c_dialect_cxx ())
1958 if (tree scope = get_containing_scope (field))
1959 if (TYPE_P (scope) && TYPE_NAME (scope) == NULL_TREE)
1960 break;
1961 tree cop = build3_loc (loc, code: COMPONENT_REF, TREE_TYPE (field),
1962 arg0: op, arg1: field, NULL_TREE);
1963 off = off - upos;
1964 if (tree ret = c_fold_indirect_ref_for_warn (loc, type, op: cop,
1965 off))
1966 return ret;
1967 return cop;
1968 }
1969 }
1970 }
1971 /* Similarly for unions, but in this case try to be very conservative,
1972 only match if some field has type compatible with type and it is the
1973 only such field. */
1974 else if (TREE_CODE (optype) == UNION_TYPE)
1975 {
1976 tree fld = NULL_TREE;
1977 for (tree field = TYPE_FIELDS (optype);
1978 field; field = DECL_CHAIN (field))
1979 if (TREE_CODE (field) == FIELD_DECL
1980 && TREE_TYPE (field) != error_mark_node
1981 && lang_hooks.types_compatible_p (TREE_TYPE (field), type))
1982 {
1983 if (fld)
1984 return NULL_TREE;
1985 else
1986 fld = field;
1987 }
1988 if (fld)
1989 {
1990 off = 0;
1991 return build3_loc (loc, code: COMPONENT_REF, TREE_TYPE (fld), arg0: op, arg1: fld,
1992 NULL_TREE);
1993 }
1994 }
1995
1996 return NULL_TREE;
1997}
1998
1999/* Print the MEM_REF expression REF, including its type and offset.
2000 Apply casts as necessary if the type of the access is different
2001 from the type of the accessed object. Produce compact output
2002 designed to include both the element index as well as any
2003 misalignment by preferring
2004 ((int*)((char*)p + 1))[2]
2005 over
2006 *(int*)((char*)p + 9)
2007 The former is more verbose but makes it clearer that the access
2008 to the third element of the array is misaligned by one byte. */
2009
2010static void
2011print_mem_ref (c_pretty_printer *pp, tree e)
2012{
2013 tree arg = TREE_OPERAND (e, 0);
2014
2015 /* The byte offset. Initially equal to the MEM_REF offset, then
2016 adjusted to the remainder of the division by the byte size of
2017 the access. */
2018 offset_int byte_off = wi::to_offset (TREE_OPERAND (e, 1));
2019 /* The result of dividing BYTE_OFF by the size of the access. */
2020 offset_int elt_idx = 0;
2021 /* True to include a cast to char* (for a nonzero final BYTE_OFF). */
2022 bool char_cast = false;
2023 tree op = NULL_TREE;
2024 bool array_ref_only = false;
2025 if (TREE_CODE (arg) == ADDR_EXPR)
2026 {
2027 op = c_fold_indirect_ref_for_warn (EXPR_LOCATION (e), TREE_TYPE (e),
2028 TREE_OPERAND (arg, 0), off&: byte_off);
2029 /* Try to fold it back to component, array ref or their combination,
2030 but print it only if the types and TBAA types are compatible. */
2031 if (op
2032 && byte_off == 0
2033 && lang_hooks.types_compatible_p (TREE_TYPE (e), TREE_TYPE (op))
2034 && (!flag_strict_aliasing
2035 || (get_deref_alias_set (TREE_OPERAND (e, 1))
2036 == get_alias_set (op))))
2037 {
2038 pp->expression (op);
2039 return;
2040 }
2041 if (op == NULL_TREE)
2042 op = TREE_OPERAND (arg, 0);
2043 /* If the types or TBAA types are incompatible, undo the
2044 UNION_TYPE handling from c_fold_indirect_ref_for_warn, and similarly
2045 undo __real__/__imag__ the code below doesn't try to handle. */
2046 if (op != TREE_OPERAND (arg, 0)
2047 && ((TREE_CODE (op) == COMPONENT_REF
2048 && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == UNION_TYPE)
2049 || TREE_CODE (op) == REALPART_EXPR
2050 || TREE_CODE (op) == IMAGPART_EXPR))
2051 op = TREE_OPERAND (op, 0);
2052 if (op != TREE_OPERAND (arg, 0))
2053 {
2054 array_ref_only = true;
2055 for (tree ref = op; ref != TREE_OPERAND (arg, 0);
2056 ref = TREE_OPERAND (ref, 0))
2057 if (TREE_CODE (ref) != ARRAY_REF)
2058 {
2059 array_ref_only = false;
2060 break;
2061 }
2062 }
2063 }
2064
2065 tree access_type = TREE_TYPE (e);
2066 tree arg_type = TREE_TYPE (TREE_TYPE (arg));
2067 if (tree access_size = TYPE_SIZE_UNIT (access_type))
2068 if (byte_off != 0
2069 && TREE_CODE (access_size) == INTEGER_CST
2070 && !integer_zerop (access_size))
2071 {
2072 offset_int asize = wi::to_offset (t: access_size);
2073 elt_idx = byte_off / asize;
2074 byte_off = byte_off % asize;
2075 }
2076
2077 /* True to include a cast to the accessed type. */
2078 const bool access_cast
2079 = ((op && op != TREE_OPERAND (arg, 0))
2080 || VOID_TYPE_P (arg_type)
2081 || !lang_hooks.types_compatible_p (access_type, arg_type));
2082 const bool has_off = byte_off != 0 || (op && op != TREE_OPERAND (arg, 0));
2083
2084 if (has_off && (byte_off != 0 || !array_ref_only))
2085 {
2086 /* When printing the byte offset for a pointer to a type of
2087 a different size than char, include a cast to char* first,
2088 before printing the cast to a pointer to the accessed type. */
2089 tree size = TYPE_SIZE (arg_type);
2090 if (size == NULL_TREE
2091 || TREE_CODE (size) != INTEGER_CST
2092 || wi::to_wide (t: size) != BITS_PER_UNIT)
2093 char_cast = true;
2094 }
2095
2096 if (elt_idx == 0)
2097 pp_c_star (pp);
2098 else if (access_cast || char_cast)
2099 pp_c_left_paren (pp);
2100
2101 if (access_cast)
2102 {
2103 /* Include a cast to the accessed type if it isn't compatible
2104 with the type of the referenced object (or if the object
2105 is typeless). */
2106 pp_c_left_paren (pp);
2107 pp->type_id (t: build_pointer_type (access_type));
2108 pp_c_right_paren (pp);
2109 }
2110
2111 if (has_off)
2112 pp_c_left_paren (pp);
2113
2114 if (char_cast)
2115 {
2116 /* Include a cast to char *. */
2117 pp_c_left_paren (pp);
2118 pp->type_id (string_type_node);
2119 pp_c_right_paren (pp);
2120 }
2121
2122 pp->unary_expression (arg);
2123
2124 if (op && op != TREE_OPERAND (arg, 0))
2125 {
2126 auto_vec<tree, 16> refs;
2127 tree ref;
2128 unsigned i;
2129 bool array_refs = true;
2130 for (ref = op; ref != TREE_OPERAND (arg, 0); ref = TREE_OPERAND (ref, 0))
2131 refs.safe_push (obj: ref);
2132 FOR_EACH_VEC_ELT_REVERSE (refs, i, ref)
2133 if (array_refs && TREE_CODE (ref) == ARRAY_REF)
2134 {
2135 pp_c_left_bracket (pp);
2136 pp->expression (TREE_OPERAND (ref, 1));
2137 pp_c_right_bracket (pp);
2138 }
2139 else
2140 {
2141 if (array_refs)
2142 {
2143 array_refs = false;
2144 pp_string (pp, " + offsetof");
2145 pp_c_left_paren (pp);
2146 pp->type_id (TREE_TYPE (TREE_OPERAND (ref, 0)));
2147 pp_comma (pp);
2148 }
2149 else if (TREE_CODE (ref) == COMPONENT_REF)
2150 pp_c_dot (pp);
2151 if (TREE_CODE (ref) == COMPONENT_REF)
2152 pp->expression (TREE_OPERAND (ref, 1));
2153 else
2154 {
2155 pp_c_left_bracket (pp);
2156 pp->expression (TREE_OPERAND (ref, 1));
2157 pp_c_right_bracket (pp);
2158 }
2159 }
2160 if (!array_refs)
2161 pp_c_right_paren (pp);
2162 }
2163
2164 if (byte_off != 0)
2165 {
2166 pp_space (pp);
2167 pp_plus (pp);
2168 pp_space (pp);
2169 tree off = wide_int_to_tree (ssizetype, cst: byte_off);
2170 pp->constant (e: off);
2171 }
2172
2173 if (has_off)
2174 pp_c_right_paren (pp);
2175
2176 if (elt_idx != 0)
2177 {
2178 if (access_cast || char_cast)
2179 pp_c_right_paren (pp);
2180
2181 pp_c_left_bracket (pp);
2182 tree idx = wide_int_to_tree (ssizetype, cst: elt_idx);
2183 pp->constant (e: idx);
2184 pp_c_right_bracket (pp);
2185 }
2186}
2187
2188/* unary-expression:
2189 postfix-expression
2190 ++ cast-expression
2191 -- cast-expression
2192 unary-operator cast-expression
2193 sizeof unary-expression
2194 sizeof ( type-id )
2195
2196 unary-operator: one of
2197 * & + - ! ~
2198
2199 GNU extensions.
2200 unary-expression:
2201 __alignof__ unary-expression
2202 __alignof__ ( type-id )
2203 __real__ unary-expression
2204 __imag__ unary-expression */
2205
2206void
2207c_pretty_printer::unary_expression (tree e)
2208{
2209 enum tree_code code = TREE_CODE (e);
2210 switch (code)
2211 {
2212 case PREINCREMENT_EXPR:
2213 case PREDECREMENT_EXPR:
2214 pp_string (this, code == PREINCREMENT_EXPR ? "++" : "--");
2215 unary_expression (TREE_OPERAND (e, 0));
2216 break;
2217
2218 case ADDR_EXPR:
2219 case INDIRECT_REF:
2220 case NEGATE_EXPR:
2221 case BIT_NOT_EXPR:
2222 case TRUTH_NOT_EXPR:
2223 case CONJ_EXPR:
2224 /* String literal are used by address. */
2225 if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
2226 pp_ampersand (this);
2227 else if (code == INDIRECT_REF)
2228 {
2229 tree type = TREE_TYPE (TREE_OPERAND (e, 0));
2230 if (type && TREE_CODE (type) == REFERENCE_TYPE)
2231 /* Reference decay is implicit, don't print anything. */;
2232 else
2233 pp_c_star (pp: this);
2234 }
2235 else if (code == NEGATE_EXPR)
2236 pp_minus (this);
2237 else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
2238 pp_complement (this);
2239 else if (code == TRUTH_NOT_EXPR)
2240 pp_exclamation (this);
2241 pp_c_cast_expression (this, TREE_OPERAND (e, 0));
2242 break;
2243
2244 case MEM_REF:
2245 print_mem_ref (pp: this, e);
2246 break;
2247
2248 case TARGET_MEM_REF:
2249 /* TARGET_MEM_REF can't appear directly from source, but can appear
2250 during late GIMPLE optimizations and through late diagnostic we might
2251 need to support it. Print it as dereferencing of a pointer after
2252 cast to the TARGET_MEM_REF type, with pointer arithmetics on some
2253 pointer to single byte types, so
2254 *(type *)((char *) ptr + step * index + index2) if all the operands
2255 are present and the casts are needed. */
2256 pp_c_star (pp: this);
2257 if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (e)))) == NULL_TREE
2258 || !integer_onep (TYPE_SIZE_UNIT
2259 (TREE_TYPE (TREE_TYPE (TMR_BASE (e))))))
2260 {
2261 if (TYPE_SIZE_UNIT (TREE_TYPE (e))
2262 && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (e))))
2263 {
2264 pp_c_left_paren (pp: this);
2265 pp_c_type_cast (pp: this, t: build_pointer_type (TREE_TYPE (e)));
2266 }
2267 else
2268 {
2269 pp_c_type_cast (pp: this, t: build_pointer_type (TREE_TYPE (e)));
2270 pp_c_left_paren (pp: this);
2271 pp_c_type_cast (pp: this, t: build_pointer_type (char_type_node));
2272 }
2273 }
2274 else if (!lang_hooks.types_compatible_p
2275 (TREE_TYPE (e), TREE_TYPE (TREE_TYPE (TMR_BASE (e)))))
2276 {
2277 pp_c_type_cast (pp: this, t: build_pointer_type (TREE_TYPE (e)));
2278 pp_c_left_paren (pp: this);
2279 }
2280 else
2281 pp_c_left_paren (pp: this);
2282 pp_c_cast_expression (this, TMR_BASE (e));
2283 if (TMR_STEP (e) && TMR_INDEX (e))
2284 {
2285 pp_plus (this);
2286 pp_c_cast_expression (this, TMR_INDEX (e));
2287 pp_c_star (pp: this);
2288 pp_c_cast_expression (this, TMR_STEP (e));
2289 }
2290 if (TMR_INDEX2 (e))
2291 {
2292 pp_plus (this);
2293 pp_c_cast_expression (this, TMR_INDEX2 (e));
2294 }
2295 if (!integer_zerop (TMR_OFFSET (e)))
2296 {
2297 pp_plus (this);
2298 pp_c_integer_constant (pp: this,
2299 fold_convert (ssizetype, TMR_OFFSET (e)));
2300 }
2301 pp_c_right_paren (pp: this);
2302 break;
2303
2304 case REALPART_EXPR:
2305 case IMAGPART_EXPR:
2306 pp_c_ws_string (pp: this, str: code == REALPART_EXPR ? "__real__" : "__imag__");
2307 pp_c_whitespace (pp: this);
2308 unary_expression (TREE_OPERAND (e, 0));
2309 break;
2310
2311 default:
2312 postfix_expression (e);
2313 break;
2314 }
2315}
2316
2317/* cast-expression:
2318 unary-expression
2319 ( type-name ) cast-expression */
2320
2321void
2322pp_c_cast_expression (c_pretty_printer *pp, tree e)
2323{
2324 switch (TREE_CODE (e))
2325 {
2326 case FLOAT_EXPR:
2327 case FIX_TRUNC_EXPR:
2328 CASE_CONVERT:
2329 case VIEW_CONVERT_EXPR:
2330 case EXCESS_PRECISION_EXPR:
2331 if (!location_wrapper_p (exp: e))
2332 pp_c_type_cast (pp, TREE_TYPE (e));
2333 pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
2334 break;
2335
2336 default:
2337 pp->unary_expression (e);
2338 }
2339}
2340
2341/* multiplicative-expression:
2342 cast-expression
2343 multiplicative-expression * cast-expression
2344 multiplicative-expression / cast-expression
2345 multiplicative-expression % cast-expression */
2346
2347void
2348c_pretty_printer::multiplicative_expression (tree e)
2349{
2350 enum tree_code code = TREE_CODE (e);
2351 switch (code)
2352 {
2353 case MULT_EXPR:
2354 case TRUNC_DIV_EXPR:
2355 case TRUNC_MOD_EXPR:
2356 case EXACT_DIV_EXPR:
2357 case RDIV_EXPR:
2358 multiplicative_expression (TREE_OPERAND (e, 0));
2359 pp_c_whitespace (pp: this);
2360 if (code == MULT_EXPR)
2361 pp_c_star (pp: this);
2362 else if (code != TRUNC_MOD_EXPR)
2363 pp_slash (this);
2364 else
2365 pp_modulo (this);
2366 pp_c_whitespace (pp: this);
2367 pp_c_cast_expression (pp: this, TREE_OPERAND (e, 1));
2368 break;
2369
2370 default:
2371 pp_c_cast_expression (pp: this, e);
2372 break;
2373 }
2374}
2375
2376/* additive-expression:
2377 multiplicative-expression
2378 additive-expression + multiplicative-expression
2379 additive-expression - multiplicative-expression */
2380
2381static void
2382pp_c_additive_expression (c_pretty_printer *pp, tree e)
2383{
2384 enum tree_code code = TREE_CODE (e);
2385 switch (code)
2386 {
2387 case POINTER_PLUS_EXPR:
2388 case PLUS_EXPR:
2389 case POINTER_DIFF_EXPR:
2390 case MINUS_EXPR:
2391 pp_c_additive_expression (pp, TREE_OPERAND (e, 0));
2392 pp_c_whitespace (pp);
2393 if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
2394 pp_plus (pp);
2395 else
2396 pp_minus (pp);
2397 pp_c_whitespace (pp);
2398 {
2399 tree op1 = TREE_OPERAND (e, 1);
2400 if (code == POINTER_PLUS_EXPR
2401 && TREE_CODE (op1) == INTEGER_CST
2402 && tree_int_cst_sign_bit (op1))
2403 /* A pointer minus an integer is represented internally as plus a very
2404 large number, don't expose that to users. */
2405 op1 = convert (ssizetype, op1);
2406 pp->multiplicative_expression (e: op1);
2407 }
2408 break;
2409
2410 default:
2411 pp->multiplicative_expression (e);
2412 break;
2413 }
2414}
2415
2416/* additive-expression:
2417 additive-expression
2418 shift-expression << additive-expression
2419 shift-expression >> additive-expression */
2420
2421static void
2422pp_c_shift_expression (c_pretty_printer *pp, tree e)
2423{
2424 enum tree_code code = TREE_CODE (e);
2425 switch (code)
2426 {
2427 case LSHIFT_EXPR:
2428 case RSHIFT_EXPR:
2429 case LROTATE_EXPR:
2430 case RROTATE_EXPR:
2431 pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
2432 pp_c_whitespace (pp);
2433 pp_string (pp, code == LSHIFT_EXPR ? "<<" :
2434 code == RSHIFT_EXPR ? ">>" :
2435 code == LROTATE_EXPR ? "<<<" : ">>>");
2436 pp_c_whitespace (pp);
2437 pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
2438 break;
2439
2440 default:
2441 pp_c_additive_expression (pp, e);
2442 }
2443}
2444
2445/* relational-expression:
2446 shift-expression
2447 relational-expression < shift-expression
2448 relational-expression > shift-expression
2449 relational-expression <= shift-expression
2450 relational-expression >= shift-expression */
2451
2452static void
2453pp_c_relational_expression (c_pretty_printer *pp, tree e)
2454{
2455 enum tree_code code = TREE_CODE (e);
2456 switch (code)
2457 {
2458 case LT_EXPR:
2459 case GT_EXPR:
2460 case LE_EXPR:
2461 case GE_EXPR:
2462 pp_c_relational_expression (pp, TREE_OPERAND (e, 0));
2463 pp_c_whitespace (pp);
2464 if (code == LT_EXPR)
2465 pp_less (pp);
2466 else if (code == GT_EXPR)
2467 pp_greater (pp);
2468 else if (code == LE_EXPR)
2469 pp_less_equal (pp);
2470 else if (code == GE_EXPR)
2471 pp_greater_equal (pp);
2472 pp_c_whitespace (pp);
2473 pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
2474 break;
2475
2476 default:
2477 pp_c_shift_expression (pp, e);
2478 break;
2479 }
2480}
2481
2482/* equality-expression:
2483 relational-expression
2484 equality-expression == relational-expression
2485 equality-equality != relational-expression */
2486
2487static void
2488pp_c_equality_expression (c_pretty_printer *pp, tree e)
2489{
2490 enum tree_code code = TREE_CODE (e);
2491 switch (code)
2492 {
2493 case EQ_EXPR:
2494 case NE_EXPR:
2495 pp_c_equality_expression (pp, TREE_OPERAND (e, 0));
2496 pp_c_whitespace (pp);
2497 pp_string (pp, code == EQ_EXPR ? "==" : "!=");
2498 pp_c_whitespace (pp);
2499 pp_c_relational_expression (pp, TREE_OPERAND (e, 1));
2500 break;
2501
2502 default:
2503 pp_c_relational_expression (pp, e);
2504 break;
2505 }
2506}
2507
2508/* AND-expression:
2509 equality-expression
2510 AND-expression & equality-equality */
2511
2512static void
2513pp_c_and_expression (c_pretty_printer *pp, tree e)
2514{
2515 if (TREE_CODE (e) == BIT_AND_EXPR)
2516 {
2517 pp_c_and_expression (pp, TREE_OPERAND (e, 0));
2518 pp_c_whitespace (pp);
2519 pp_ampersand (pp);
2520 pp_c_whitespace (pp);
2521 pp_c_equality_expression (pp, TREE_OPERAND (e, 1));
2522 }
2523 else
2524 pp_c_equality_expression (pp, e);
2525}
2526
2527/* exclusive-OR-expression:
2528 AND-expression
2529 exclusive-OR-expression ^ AND-expression */
2530
2531static void
2532pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e)
2533{
2534 if (TREE_CODE (e) == BIT_XOR_EXPR
2535 || TREE_CODE (e) == TRUTH_XOR_EXPR)
2536 {
2537 pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
2538 if (TREE_CODE (e) == BIT_XOR_EXPR)
2539 pp_c_maybe_whitespace (pp);
2540 else
2541 pp_c_whitespace (pp);
2542 pp_carret (pp);
2543 pp_c_whitespace (pp);
2544 pp_c_and_expression (pp, TREE_OPERAND (e, 1));
2545 }
2546 else
2547 pp_c_and_expression (pp, e);
2548}
2549
2550/* inclusive-OR-expression:
2551 exclusive-OR-expression
2552 inclusive-OR-expression | exclusive-OR-expression */
2553
2554static void
2555pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e)
2556{
2557 if (TREE_CODE (e) == BIT_IOR_EXPR)
2558 {
2559 pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
2560 pp_c_whitespace (pp);
2561 pp_bar (pp);
2562 pp_c_whitespace (pp);
2563 pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1));
2564 }
2565 else
2566 pp_c_exclusive_or_expression (pp, e);
2567}
2568
2569/* logical-AND-expression:
2570 inclusive-OR-expression
2571 logical-AND-expression && inclusive-OR-expression */
2572
2573static void
2574pp_c_logical_and_expression (c_pretty_printer *pp, tree e)
2575{
2576 if (TREE_CODE (e) == TRUTH_ANDIF_EXPR
2577 || TREE_CODE (e) == TRUTH_AND_EXPR)
2578 {
2579 pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
2580 pp_c_whitespace (pp);
2581 pp_ampersand_ampersand (pp);
2582 pp_c_whitespace (pp);
2583 pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
2584 }
2585 else
2586 pp_c_inclusive_or_expression (pp, e);
2587}
2588
2589/* logical-OR-expression:
2590 logical-AND-expression
2591 logical-OR-expression || logical-AND-expression */
2592
2593void
2594pp_c_logical_or_expression (c_pretty_printer *pp, tree e)
2595{
2596 if (TREE_CODE (e) == TRUTH_ORIF_EXPR
2597 || TREE_CODE (e) == TRUTH_OR_EXPR)
2598 {
2599 pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
2600 pp_c_whitespace (pp);
2601 pp_bar_bar (pp);
2602 pp_c_whitespace (pp);
2603 pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
2604 }
2605 else
2606 pp_c_logical_and_expression (pp, e);
2607}
2608
2609/* conditional-expression:
2610 logical-OR-expression
2611 logical-OR-expression ? expression : conditional-expression */
2612
2613void
2614c_pretty_printer::conditional_expression (tree e)
2615{
2616 if (TREE_CODE (e) == COND_EXPR)
2617 {
2618 pp_c_logical_or_expression (pp: this, TREE_OPERAND (e, 0));
2619 pp_c_whitespace (pp: this);
2620 pp_question (this);
2621 pp_c_whitespace (pp: this);
2622 expression (TREE_OPERAND (e, 1));
2623 pp_c_whitespace (pp: this);
2624 pp_colon (this);
2625 pp_c_whitespace (pp: this);
2626 conditional_expression (TREE_OPERAND (e, 2));
2627 }
2628 else
2629 pp_c_logical_or_expression (pp: this, e);
2630}
2631
2632
2633/* assignment-expression:
2634 conditional-expression
2635 unary-expression assignment-operator assignment-expression
2636
2637 assignment-expression: one of
2638 = *= /= %= += -= >>= <<= &= ^= |= */
2639
2640void
2641c_pretty_printer::assignment_expression (tree e)
2642{
2643 if (TREE_CODE (e) == MODIFY_EXPR
2644 || TREE_CODE (e) == INIT_EXPR)
2645 {
2646 unary_expression (TREE_OPERAND (e, 0));
2647 pp_c_whitespace (pp: this);
2648 pp_equal (this);
2649 pp_space (this);
2650 expression (TREE_OPERAND (e, 1));
2651 }
2652 else
2653 conditional_expression (e);
2654}
2655
2656/* expression:
2657 assignment-expression
2658 expression , assignment-expression
2659
2660 Implementation note: instead of going through the usual recursion
2661 chain, I take the liberty of dispatching nodes to the appropriate
2662 functions. This makes some redundancy, but it worths it. That also
2663 prevents a possible infinite recursion between primary_expression ()
2664 and expression (). */
2665
2666void
2667c_pretty_printer::expression (tree e)
2668{
2669 switch (TREE_CODE (e))
2670 {
2671 case VOID_CST:
2672 pp_c_void_constant (pp: this);
2673 break;
2674
2675 case INTEGER_CST:
2676 pp_c_integer_constant (pp: this, i: e);
2677 break;
2678
2679 case REAL_CST:
2680 pp_c_floating_constant (pp: this, r: e);
2681 break;
2682
2683 case FIXED_CST:
2684 pp_c_fixed_constant (pp: this, r: e);
2685 break;
2686
2687 case STRING_CST:
2688 pp_c_string_literal (pp: this, s: e);
2689 break;
2690
2691 case IDENTIFIER_NODE:
2692 case FUNCTION_DECL:
2693 case VAR_DECL:
2694 case CONST_DECL:
2695 case PARM_DECL:
2696 case RESULT_DECL:
2697 case FIELD_DECL:
2698 case LABEL_DECL:
2699 case ERROR_MARK:
2700 primary_expression (e);
2701 break;
2702
2703 case SSA_NAME:
2704 if (SSA_NAME_VAR (e)
2705 && !DECL_ARTIFICIAL (SSA_NAME_VAR (e)))
2706 expression (SSA_NAME_VAR (e));
2707 else
2708 translate_string (gmsgid: "<unknown>");
2709 break;
2710
2711 case POSTINCREMENT_EXPR:
2712 case POSTDECREMENT_EXPR:
2713 case ARRAY_REF:
2714 case OMP_ARRAY_SECTION:
2715 case CALL_EXPR:
2716 case COMPONENT_REF:
2717 case BIT_FIELD_REF:
2718 case COMPLEX_CST:
2719 case COMPLEX_EXPR:
2720 case VECTOR_CST:
2721 case ORDERED_EXPR:
2722 case UNORDERED_EXPR:
2723 case LTGT_EXPR:
2724 case UNEQ_EXPR:
2725 case UNLE_EXPR:
2726 case UNLT_EXPR:
2727 case UNGE_EXPR:
2728 case UNGT_EXPR:
2729 case MAX_EXPR:
2730 case MIN_EXPR:
2731 case ABS_EXPR:
2732 case CONSTRUCTOR:
2733 case COMPOUND_LITERAL_EXPR:
2734 case VA_ARG_EXPR:
2735 postfix_expression (e);
2736 break;
2737
2738 case CONJ_EXPR:
2739 case ADDR_EXPR:
2740 case INDIRECT_REF:
2741 case MEM_REF:
2742 case TARGET_MEM_REF:
2743 case NEGATE_EXPR:
2744 case BIT_NOT_EXPR:
2745 case TRUTH_NOT_EXPR:
2746 case PREINCREMENT_EXPR:
2747 case PREDECREMENT_EXPR:
2748 case REALPART_EXPR:
2749 case IMAGPART_EXPR:
2750 unary_expression (e);
2751 break;
2752
2753 case FLOAT_EXPR:
2754 case FIX_TRUNC_EXPR:
2755 CASE_CONVERT:
2756 case VIEW_CONVERT_EXPR:
2757 case EXCESS_PRECISION_EXPR:
2758 pp_c_cast_expression (pp: this, e);
2759 break;
2760
2761 case MULT_EXPR:
2762 case TRUNC_MOD_EXPR:
2763 case TRUNC_DIV_EXPR:
2764 case EXACT_DIV_EXPR:
2765 case RDIV_EXPR:
2766 multiplicative_expression (e);
2767 break;
2768
2769 case LSHIFT_EXPR:
2770 case RSHIFT_EXPR:
2771 case LROTATE_EXPR:
2772 case RROTATE_EXPR:
2773 pp_c_shift_expression (pp: this, e);
2774 break;
2775
2776 case LT_EXPR:
2777 case GT_EXPR:
2778 case LE_EXPR:
2779 case GE_EXPR:
2780 pp_c_relational_expression (pp: this, e);
2781 break;
2782
2783 case BIT_AND_EXPR:
2784 pp_c_and_expression (pp: this, e);
2785 break;
2786
2787 case BIT_XOR_EXPR:
2788 case TRUTH_XOR_EXPR:
2789 pp_c_exclusive_or_expression (pp: this, e);
2790 break;
2791
2792 case BIT_IOR_EXPR:
2793 pp_c_inclusive_or_expression (pp: this, e);
2794 break;
2795
2796 case TRUTH_ANDIF_EXPR:
2797 case TRUTH_AND_EXPR:
2798 pp_c_logical_and_expression (pp: this, e);
2799 break;
2800
2801 case TRUTH_ORIF_EXPR:
2802 case TRUTH_OR_EXPR:
2803 pp_c_logical_or_expression (pp: this, e);
2804 break;
2805
2806 case EQ_EXPR:
2807 case NE_EXPR:
2808 pp_c_equality_expression (pp: this, e);
2809 break;
2810
2811 case COND_EXPR:
2812 conditional_expression (e);
2813 break;
2814
2815 case POINTER_PLUS_EXPR:
2816 case PLUS_EXPR:
2817 case POINTER_DIFF_EXPR:
2818 case MINUS_EXPR:
2819 pp_c_additive_expression (pp: this, e);
2820 break;
2821
2822 case MODIFY_EXPR:
2823 case INIT_EXPR:
2824 assignment_expression (e);
2825 break;
2826
2827 case COMPOUND_EXPR:
2828 pp_c_left_paren (pp: this);
2829 expression (TREE_OPERAND (e, 0));
2830 pp_separate_with (this, ',');
2831 assignment_expression (TREE_OPERAND (e, 1));
2832 pp_c_right_paren (pp: this);
2833 break;
2834
2835 case NON_LVALUE_EXPR:
2836 case SAVE_EXPR:
2837 expression (TREE_OPERAND (e, 0));
2838 break;
2839
2840 case TARGET_EXPR:
2841 postfix_expression (TREE_OPERAND (e, 1));
2842 break;
2843
2844 case BIND_EXPR:
2845 case GOTO_EXPR:
2846 /* We don't yet have a way of dumping statements in a
2847 human-readable format. */
2848 pp_string (this, "({...})");
2849 break;
2850
2851 case C_MAYBE_CONST_EXPR:
2852 expression (C_MAYBE_CONST_EXPR_EXPR (e));
2853 break;
2854
2855 default:
2856 pp_unsupported_tree (this, e);
2857 break;
2858 }
2859}
2860
2861
2862
2863/* Statements. */
2864
2865void
2866c_pretty_printer::statement (tree t)
2867{
2868 if (t == NULL)
2869 return;
2870
2871 switch (TREE_CODE (t))
2872 {
2873
2874 case SWITCH_STMT:
2875 pp_c_ws_string (pp: this, str: "switch");
2876 pp_space (this);
2877 pp_c_left_paren (pp: this);
2878 expression (SWITCH_STMT_COND (t));
2879 pp_c_right_paren (pp: this);
2880 pp_indentation (this) += 3;
2881 pp_needs_newline (this) = true;
2882 statement (SWITCH_STMT_BODY (t));
2883 pp_newline_and_indent (this, -3);
2884 break;
2885
2886 /* iteration-statement:
2887 while ( expression ) statement
2888 do statement while ( expression ) ;
2889 for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
2890 for ( declaration expression(opt) ; expression(opt) ) statement */
2891 case WHILE_STMT:
2892 pp_c_ws_string (pp: this, str: "while");
2893 pp_space (this);
2894 pp_c_left_paren (pp: this);
2895 expression (WHILE_COND (t));
2896 pp_c_right_paren (pp: this);
2897 pp_newline_and_indent (this, 3);
2898 statement (WHILE_BODY (t));
2899 pp_indentation (this) -= 3;
2900 pp_needs_newline (this) = true;
2901 break;
2902
2903 case DO_STMT:
2904 pp_c_ws_string (pp: this, str: "do");
2905 pp_newline_and_indent (this, 3);
2906 statement (DO_BODY (t));
2907 pp_newline_and_indent (this, -3);
2908 pp_c_ws_string (pp: this, str: "while");
2909 pp_space (this);
2910 pp_c_left_paren (pp: this);
2911 expression (DO_COND (t));
2912 pp_c_right_paren (pp: this);
2913 pp_c_semicolon (pp: this);
2914 pp_needs_newline (this) = true;
2915 break;
2916
2917 case FOR_STMT:
2918 pp_c_ws_string (pp: this, str: "for");
2919 pp_space (this);
2920 pp_c_left_paren (pp: this);
2921 if (FOR_INIT_STMT (t))
2922 statement (FOR_INIT_STMT (t));
2923 else
2924 pp_c_semicolon (pp: this);
2925 pp_needs_newline (this) = false;
2926 pp_c_whitespace (pp: this);
2927 if (FOR_COND (t))
2928 expression (FOR_COND (t));
2929 pp_c_semicolon (pp: this);
2930 pp_needs_newline (this) = false;
2931 pp_c_whitespace (pp: this);
2932 if (FOR_EXPR (t))
2933 expression (FOR_EXPR (t));
2934 pp_c_right_paren (pp: this);
2935 pp_newline_and_indent (this, 3);
2936 statement (FOR_BODY (t));
2937 pp_indentation (this) -= 3;
2938 pp_needs_newline (this) = true;
2939 break;
2940
2941 /* jump-statement:
2942 goto identifier;
2943 continue ;
2944 return expression(opt) ; */
2945 case BREAK_STMT:
2946 case CONTINUE_STMT:
2947 pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
2948 pp_c_semicolon (pp: this);
2949 pp_needs_newline (this) = true;
2950 break;
2951
2952 default:
2953 if (pp_needs_newline (this))
2954 pp_newline_and_indent (this, 0);
2955 dump_generic_node (this, t, pp_indentation (this), TDF_NONE, true);
2956 }
2957}
2958
2959
2960/* Initialize the PRETTY-PRINTER for handling C codes. */
2961
2962c_pretty_printer::c_pretty_printer ()
2963 : pretty_printer (),
2964 offset_list (),
2965 flags ()
2966{
2967 type_specifier_seq = pp_c_specifier_qualifier_list;
2968 ptr_operator = pp_c_pointer;
2969 parameter_list = pp_c_parameter_type_list;
2970}
2971
2972/* c_pretty_printer's implementation of pretty_printer::clone vfunc. */
2973
2974pretty_printer *
2975c_pretty_printer::clone () const
2976{
2977 return new c_pretty_printer (*this);
2978}
2979
2980/* Print the tree T in full, on file FILE. */
2981
2982void
2983print_c_tree (FILE *file, tree t)
2984{
2985 c_pretty_printer pp;
2986
2987 pp_needs_newline (&pp) = true;
2988 pp.buffer->stream = file;
2989 pp.statement (t);
2990 pp_newline_and_flush (&pp);
2991}
2992
2993/* Print the tree T in full, on stderr. */
2994
2995DEBUG_FUNCTION void
2996debug_c_tree (tree t)
2997{
2998 print_c_tree (stderr, t);
2999 fputc (c: '\n', stderr);
3000}
3001
3002/* Output the DECL_NAME of T. If T has no DECL_NAME, output a string made
3003 up of T's memory address. */
3004
3005void
3006pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
3007{
3008 const char *name;
3009
3010 gcc_assert (DECL_P (t));
3011
3012 if (DECL_NAME (t))
3013 name = IDENTIFIER_POINTER (DECL_NAME (t));
3014 else
3015 {
3016 static char xname[8];
3017 sprintf (s: xname, format: "<U%4hx>", ((unsigned short) ((uintptr_t) (t)
3018 & 0xffff)));
3019 name = xname;
3020 }
3021
3022 pp_c_identifier (pp, id: name);
3023}
3024
3025#if CHECKING_P
3026
3027namespace selftest {
3028
3029/* Selftests for pretty-printing trees. */
3030
3031/* Verify that EXPR printed by c_pretty_printer is EXPECTED, using
3032 LOC as the effective location for any failures. */
3033
3034static void
3035assert_c_pretty_printer_output (const location &loc, const char *expected,
3036 tree expr)
3037{
3038 c_pretty_printer pp;
3039 pp.expression (e: expr);
3040 ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
3041}
3042
3043/* Helper function for calling assert_c_pretty_printer_output.
3044 This is to avoid having to write SELFTEST_LOCATION. */
3045
3046#define ASSERT_C_PRETTY_PRINTER_OUTPUT(EXPECTED, EXPR) \
3047 SELFTEST_BEGIN_STMT \
3048 assert_c_pretty_printer_output ((SELFTEST_LOCATION), \
3049 (EXPECTED), \
3050 (EXPR)); \
3051 SELFTEST_END_STMT
3052
3053/* Verify that location wrappers don't show up in pretty-printed output. */
3054
3055static void
3056test_location_wrappers ()
3057{
3058 /* VAR_DECL. */
3059 tree id = get_identifier ("foo");
3060 tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
3061 integer_type_node);
3062 tree wrapped_decl = maybe_wrap_with_location (decl, BUILTINS_LOCATION);
3063 ASSERT_NE (wrapped_decl, decl);
3064 ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", decl);
3065 ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", wrapped_decl);
3066
3067 /* INTEGER_CST. */
3068 tree int_cst = build_int_cst (integer_type_node, 42);
3069 tree wrapped_cst = maybe_wrap_with_location (int_cst, BUILTINS_LOCATION);
3070 ASSERT_NE (wrapped_cst, int_cst);
3071 ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", int_cst);
3072 ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", wrapped_cst);
3073}
3074
3075/* Run all of the selftests within this file. */
3076
3077void
3078c_pretty_print_cc_tests ()
3079{
3080 test_location_wrappers ();
3081}
3082
3083} // namespace selftest
3084
3085#endif /* CHECKING_P */
3086

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