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