]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/c-family/c-pretty-print.c
2015-06-04 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / c-family / c-pretty-print.c
CommitLineData
ba21936b 1/* Subroutines common to both C and C++ pretty-printers.
d353bf18 2 Copyright (C) 2002-2015 Free Software Foundation, Inc.
ba21936b 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
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
ba21936b 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
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
ba21936b 20
21#include "config.h"
22#include "system.h"
805e22b2 23#include "coretypes.h"
24#include "tm.h"
b20a8bb4 25#include "hash-set.h"
b20a8bb4 26#include "vec.h"
b20a8bb4 27#include "input.h"
28#include "alias.h"
29#include "symtab.h"
30#include "options.h"
b20a8bb4 31#include "inchash.h"
a7a46268 32#include "tree.h"
9ed99284 33#include "stor-layout.h"
34#include "attribs.h"
1e00012f 35#include "intl.h"
ba21936b 36#include "c-pretty-print.h"
ce084dfc 37#include "tree-pretty-print.h"
2363ef00 38#include "tree-iterator.h"
4ee9c684 39#include "diagnostic.h"
e913b5cd 40#include "wide-int-print.h"
ba21936b 41
bfbc45f5 42/* The pretty-printer code is primarily designed to closely follow
43 (GNU) C and C++ grammars. That is to be contrasted with spaghetti
44 codes we used to have in the past. Following a structured
91c82c20 45 approach (preferably the official grammars) is believed to make it
46 much easier to add extensions and nifty pretty-printing effects that
47 takes expression or declaration contexts into account. */
bfbc45f5 48
bfdec0d1 49
bfdec0d1 50#define pp_c_maybe_whitespace(PP) \
51 do { \
a94db6b0 52 if ((PP)->padding == pp_before) \
bfdec0d1 53 pp_c_whitespace (PP); \
54 } while (0)
55
ba21936b 56/* literal */
c10de5e7 57static void pp_c_char (c_pretty_printer *, int);
ba21936b 58
5dadc2ef 59/* postfix-expression */
c10de5e7 60static void pp_c_initializer_list (c_pretty_printer *, tree);
d7b8e04e 61static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree);
c10de5e7 62
c10de5e7 63static void pp_c_additive_expression (c_pretty_printer *, tree);
64static void pp_c_shift_expression (c_pretty_printer *, tree);
65static void pp_c_relational_expression (c_pretty_printer *, tree);
66static void pp_c_equality_expression (c_pretty_printer *, tree);
67static void pp_c_and_expression (c_pretty_printer *, tree);
68static void pp_c_exclusive_or_expression (c_pretty_printer *, tree);
69static void pp_c_inclusive_or_expression (c_pretty_printer *, tree);
70static void pp_c_logical_and_expression (c_pretty_printer *, tree);
8e10b18f 71
72/* declarations. */
aa6db498 73
ba21936b 74\f
e9efa031 75/* Helper functions. */
c10de5e7 76
77void
78pp_c_whitespace (c_pretty_printer *pp)
79{
80 pp_space (pp);
a94db6b0 81 pp->padding = pp_none;
c10de5e7 82}
83
84void
85pp_c_left_paren (c_pretty_printer *pp)
86{
87 pp_left_paren (pp);
a94db6b0 88 pp->padding = pp_none;
c10de5e7 89}
90
91void
92pp_c_right_paren (c_pretty_printer *pp)
93{
94 pp_right_paren (pp);
a94db6b0 95 pp->padding = pp_none;
c10de5e7 96}
97
2a9d763b 98void
99pp_c_left_brace (c_pretty_printer *pp)
100{
101 pp_left_brace (pp);
a94db6b0 102 pp->padding = pp_none;
2a9d763b 103}
104
105void
106pp_c_right_brace (c_pretty_printer *pp)
107{
108 pp_right_brace (pp);
a94db6b0 109 pp->padding = pp_none;
2a9d763b 110}
111
f97c44fd 112void
113pp_c_left_bracket (c_pretty_printer *pp)
114{
115 pp_left_bracket (pp);
a94db6b0 116 pp->padding = pp_none;
f97c44fd 117}
118
119void
120pp_c_right_bracket (c_pretty_printer *pp)
121{
122 pp_right_bracket (pp);
a94db6b0 123 pp->padding = pp_none;
f97c44fd 124}
125
c10de5e7 126void
127pp_c_dot (c_pretty_printer *pp)
128{
129 pp_dot (pp);
a94db6b0 130 pp->padding = pp_none;
c10de5e7 131}
132
133void
134pp_c_ampersand (c_pretty_printer *pp)
135{
136 pp_ampersand (pp);
a94db6b0 137 pp->padding = pp_none;
c10de5e7 138}
139
f97c44fd 140void
141pp_c_star (c_pretty_printer *pp)
142{
143 pp_star (pp);
a94db6b0 144 pp->padding = pp_none;
f97c44fd 145}
146
c10de5e7 147void
148pp_c_arrow (c_pretty_printer *pp)
149{
150 pp_arrow (pp);
a94db6b0 151 pp->padding = pp_none;
c10de5e7 152}
153
154void
ad46e187 155pp_c_semicolon (c_pretty_printer *pp)
c10de5e7 156{
157 pp_semicolon (pp);
a94db6b0 158 pp->padding = pp_none;
c10de5e7 159}
ba21936b 160
f97c44fd 161void
162pp_c_complement (c_pretty_printer *pp)
163{
164 pp_complement (pp);
a94db6b0 165 pp->padding = pp_none;
f97c44fd 166}
167
168void
169pp_c_exclamation (c_pretty_printer *pp)
170{
171 pp_exclamation (pp);
a94db6b0 172 pp->padding = pp_none;
f97c44fd 173}
174
754eb2f5 175/* Print out the external representation of QUALIFIERS. */
ad46e187 176
754eb2f5 177void
178pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type)
bfdec0d1 179{
180 const char *p = pp_last_position_in_text (pp);
754eb2f5 181 bool previous = false;
182
183 if (!qualifiers)
184 return;
185
ad46e187 186 /* The C programming language does not have references, but it is much
187 simpler to handle those here rather than going through the same
188 logic in the C++ pretty-printer. */
189 if (p != NULL && (*p == '*' || *p == '&'))
bfdec0d1 190 pp_c_whitespace (pp);
754eb2f5 191
b560fabd 192 if (qualifiers & TYPE_QUAL_ATOMIC)
193 {
194 pp_c_ws_string (pp, "_Atomic");
195 previous = true;
196 }
197
754eb2f5 198 if (qualifiers & TYPE_QUAL_CONST)
199 {
b560fabd 200 if (previous)
201 pp_c_whitespace (pp);
754eb2f5 202 pp_c_ws_string (pp, func_type ? "__attribute__((const))" : "const");
203 previous = true;
204 }
205
206 if (qualifiers & TYPE_QUAL_VOLATILE)
207 {
208 if (previous)
209 pp_c_whitespace (pp);
210 pp_c_ws_string (pp, func_type ? "__attribute__((noreturn))" : "volatile");
211 previous = true;
212 }
213
214 if (qualifiers & TYPE_QUAL_RESTRICT)
215 {
216 if (previous)
217 pp_c_whitespace (pp);
dc251364 218 pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
219 ? "restrict" : "__restrict__"));
754eb2f5 220 }
bfdec0d1 221}
222
c10de5e7 223/* Pretty-print T using the type-cast notation '( type-name )'. */
d7b8e04e 224
89df180d 225static void
c10de5e7 226pp_c_type_cast (c_pretty_printer *pp, tree t)
227{
228 pp_c_left_paren (pp);
eaab24b9 229 pp->type_id (t);
c10de5e7 230 pp_c_right_paren (pp);
231}
232
ad46e187 233/* We're about to pretty-print a pointer type as indicated by T.
234 Output a whitespace, if needed, preparing for subsequent output. */
235
c10de5e7 236void
237pp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t)
238{
239 if (POINTER_TYPE_P (t))
240 {
241 tree pointee = strip_pointer_operator (TREE_TYPE (t));
242 if (TREE_CODE (pointee) != ARRAY_TYPE
a0c938f0 243 && TREE_CODE (pointee) != FUNCTION_TYPE)
244 pp_c_whitespace (pp);
c10de5e7 245 }
246}
247
248\f
249/* Declarations. */
250
bfdec0d1 251/* C++ cv-qualifiers are called type-qualifiers in C. Print out the
252 cv-qualifiers of T. If T is a declaration then it is the cv-qualifier
253 of its type. Take care of possible extensions.
c10de5e7 254
255 type-qualifier-list:
256 type-qualifier
257 type-qualifier-list type-qualifier
258
259 type-qualifier:
bfdec0d1 260 const
c10de5e7 261 restrict -- C99
262 __restrict__ -- GNU C
6d5d708e 263 address-space-qualifier -- GNU C
264 volatile
b560fabd 265 _Atomic -- C11
6d5d708e 266
267 address-space-qualifier:
268 identifier -- GNU C */
d7b8e04e 269
ba21936b 270void
c10de5e7 271pp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
ba21936b 272{
830a6615 273 int qualifiers;
274
275 if (!t || t == error_mark_node)
276 return;
b27ac6b5 277
bfdec0d1 278 if (!TYPE_P (t))
279 t = TREE_TYPE (t);
280
281 qualifiers = TYPE_QUALS (t);
754eb2f5 282 pp_c_cv_qualifiers (pp, qualifiers,
283 TREE_CODE (t) == FUNCTION_TYPE);
6d5d708e 284
285 if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (t)))
286 {
287 const char *as = c_addr_space_name (TYPE_ADDR_SPACE (t));
288 pp_c_identifier (pp, as);
289 }
bfdec0d1 290}
291
292/* pointer:
293 * type-qualifier-list(opt)
294 * type-qualifier-list(opt) pointer */
d7b8e04e 295
bfdec0d1 296static void
c10de5e7 297pp_c_pointer (c_pretty_printer *pp, tree t)
bfdec0d1 298{
299 if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
300 t = TREE_TYPE (t);
301 switch (TREE_CODE (t))
302 {
303 case POINTER_TYPE:
e9efa031 304 /* It is easier to handle C++ reference types here. */
c10de5e7 305 case REFERENCE_TYPE:
bfdec0d1 306 if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
a0c938f0 307 pp_c_pointer (pp, TREE_TYPE (t));
c10de5e7 308 if (TREE_CODE (t) == POINTER_TYPE)
a0c938f0 309 pp_c_star (pp);
c10de5e7 310 else
a0c938f0 311 pp_c_ampersand (pp);
bfdec0d1 312 pp_c_type_qualifier_list (pp, t);
313 break;
314
7dd37241 315 /* ??? This node is now in GENERIC and so shouldn't be here. But
316 we'll fix that later. */
317 case DECL_EXPR:
eaab24b9 318 pp->declaration (DECL_EXPR_DECL (t));
7dd37241 319 pp_needs_newline (pp) = true;
320 break;
321
bfdec0d1 322 default:
323 pp_unsupported_tree (pp, t);
324 }
ba21936b 325}
326
95af4c75 327/* simple-type-specifier:
328 type-specifier
329
330 type-specifier:
c10de5e7 331 void
332 char
333 short
334 int
335 long
336 float
337 double
338 signed
339 unsigned
340 _Bool -- C99
341 _Complex -- C99
342 _Imaginary -- C99
343 struct-or-union-specifier
344 enum-specifier
345 typedef-name.
bfbc45f5 346
347 GNU extensions.
348 simple-type-specifier:
349 __complex__
350 __vector__ */
d7b8e04e 351
c10de5e7 352void
95af4c75 353c_pretty_printer::simple_type_specifier (tree t)
8e10b18f 354{
c10de5e7 355 const enum tree_code code = TREE_CODE (t);
8e10b18f 356 switch (code)
357 {
358 case ERROR_MARK:
95af4c75 359 translate_string ("<type-error>");
8e10b18f 360 break;
8e10b18f 361
362 case IDENTIFIER_NODE:
95af4c75 363 pp_c_identifier (this, IDENTIFIER_POINTER (t));
8e10b18f 364 break;
2b30d46c 365
8e10b18f 366 case VOID_TYPE:
367 case BOOLEAN_TYPE:
ed22b9fe 368 case INTEGER_TYPE:
8e10b18f 369 case REAL_TYPE:
06f0b99c 370 case FIXED_POINT_TYPE:
d7b8e04e 371 if (TYPE_NAME (t))
2ac1e110 372 {
373 t = TYPE_NAME (t);
95af4c75 374 simple_type_specifier (t);
2ac1e110 375 }
d7b8e04e 376 else
2ac1e110 377 {
378 int prec = TYPE_PRECISION (t);
06f0b99c 379 if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (t)))
380 t = c_common_type_for_mode (TYPE_MODE (t), TYPE_SATURATING (t));
381 else
382 t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
1d0e6127 383 if (TYPE_NAME (t))
384 {
95af4c75 385 simple_type_specifier (t);
1d0e6127 386 if (TYPE_PRECISION (t) != prec)
387 {
95af4c75 388 pp_colon (this);
389 pp_decimal_int (this, prec);
1d0e6127 390 }
391 }
392 else
2ac1e110 393 {
1d0e6127 394 switch (code)
395 {
396 case INTEGER_TYPE:
95af4c75 397 translate_string (TYPE_UNSIGNED (t)
398 ? "<unnamed-unsigned:"
399 : "<unnamed-signed:");
1d0e6127 400 break;
401 case REAL_TYPE:
95af4c75 402 translate_string ("<unnamed-float:");
1d0e6127 403 break;
06f0b99c 404 case FIXED_POINT_TYPE:
95af4c75 405 translate_string ("<unnamed-fixed:");
06f0b99c 406 break;
1d0e6127 407 default:
408 gcc_unreachable ();
409 }
95af4c75 410 pp_decimal_int (this, prec);
411 pp_greater (this);
2ac1e110 412 }
413 }
8e10b18f 414 break;
415
416 case TYPE_DECL:
ed22b9fe 417 if (DECL_NAME (t))
95af4c75 418 id_expression (t);
ed22b9fe 419 else
95af4c75 420 translate_string ("<typedef-error>");
8e10b18f 421 break;
422
423 case UNION_TYPE:
424 case RECORD_TYPE:
425 case ENUMERAL_TYPE:
85fecbe2 426 if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
427 /* Don't decorate the type if this is a typedef name. */;
428 else if (code == UNION_TYPE)
95af4c75 429 pp_c_ws_string (this, "union");
8e10b18f 430 else if (code == RECORD_TYPE)
95af4c75 431 pp_c_ws_string (this, "struct");
8e10b18f 432 else if (code == ENUMERAL_TYPE)
95af4c75 433 pp_c_ws_string (this, "enum");
ed22b9fe 434 else
95af4c75 435 translate_string ("<tag-error>");
2b30d46c 436
8e10b18f 437 if (TYPE_NAME (t))
95af4c75 438 id_expression (TYPE_NAME (t));
8e10b18f 439 else
95af4c75 440 translate_string ("<anonymous>");
bfdec0d1 441 break;
442
8e10b18f 443 default:
95af4c75 444 pp_unsupported_tree (this, t);
bfdec0d1 445 break;
8e10b18f 446 }
447}
448
bfbc45f5 449/* specifier-qualifier-list:
450 type-specifier specifier-qualifier-list-opt
c10de5e7 451 type-qualifier specifier-qualifier-list-opt
bfdec0d1 452
453
454 Implementation note: Because of the non-linearities in array or
91c82c20 455 function declarations, this routine prints not just the
bfdec0d1 456 specifier-qualifier-list of such entities or types of such entities,
457 but also the 'pointer' production part of their declarators. The
eaab24b9 458 remaining part is done by declarator() or abstract_declarator(). */
d7b8e04e 459
bfdec0d1 460void
c10de5e7 461pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
8e10b18f 462{
c10de5e7 463 const enum tree_code code = TREE_CODE (t);
464
8a47db47 465 if (!(pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
bfdec0d1 466 pp_c_type_qualifier_list (pp, t);
c10de5e7 467 switch (code)
bfdec0d1 468 {
c10de5e7 469 case REFERENCE_TYPE:
bfdec0d1 470 case POINTER_TYPE:
471 {
a0c938f0 472 /* Get the types-specifier of this type. */
473 tree pointee = strip_pointer_operator (TREE_TYPE (t));
474 pp_c_specifier_qualifier_list (pp, pointee);
475 if (TREE_CODE (pointee) == ARRAY_TYPE
476 || TREE_CODE (pointee) == FUNCTION_TYPE)
477 {
478 pp_c_whitespace (pp);
479 pp_c_left_paren (pp);
ee212425 480 pp_c_attributes_display (pp, TYPE_ATTRIBUTES (pointee));
a0c938f0 481 }
31266980 482 else if (!c_dialect_cxx ())
483 pp_c_whitespace (pp);
a0c938f0 484 pp_ptr_operator (pp, t);
bfdec0d1 485 }
486 break;
487
488 case FUNCTION_TYPE:
489 case ARRAY_TYPE:
490 pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
491 break;
492
493 case VECTOR_TYPE:
494 case COMPLEX_TYPE:
c10de5e7 495 if (code == COMPLEX_TYPE)
dc251364 496 pp_c_ws_string (pp, (flag_isoc99 && !c_dialect_cxx ()
497 ? "_Complex" : "__complex__"));
c10de5e7 498 else if (code == VECTOR_TYPE)
a5be0e14 499 {
500 pp_c_ws_string (pp, "__vector");
2c69eb5f 501 pp_c_left_paren (pp);
a5be0e14 502 pp_wide_integer (pp, TYPE_VECTOR_SUBPARTS (t));
2c69eb5f 503 pp_c_right_paren (pp);
504 pp_c_whitespace (pp);
a5be0e14 505 }
2c69eb5f 506 pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
bfdec0d1 507 break;
508
509 default:
95af4c75 510 pp->simple_type_specifier (t);
bfdec0d1 511 break;
512 }
8a47db47 513 if ((pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
514 pp_c_type_qualifier_list (pp, t);
8e10b18f 515}
516
bfdec0d1 517/* parameter-type-list:
518 parameter-list
519 parameter-list , ...
520
521 parameter-list:
522 parameter-declaration
523 parameter-list , parameter-declaration
524
525 parameter-declaration:
526 declaration-specifiers declarator
527 declaration-specifiers abstract-declarator(opt) */
d7b8e04e 528
c10de5e7 529void
530pp_c_parameter_type_list (c_pretty_printer *pp, tree t)
8e10b18f 531{
c10de5e7 532 bool want_parm_decl = DECL_P (t) && !(pp->flags & pp_c_flag_abstract);
533 tree parms = want_parm_decl ? DECL_ARGUMENTS (t) : TYPE_ARG_TYPES (t);
bfdec0d1 534 pp_c_left_paren (pp);
c10de5e7 535 if (parms == void_list_node)
1e00012f 536 pp_c_ws_string (pp, "void");
bfdec0d1 537 else
538 {
539 bool first = true;
c10de5e7 540 for ( ; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
a0c938f0 541 {
542 if (!first)
543 pp_separate_with (pp, ',');
544 first = false;
eaab24b9 545 pp->declaration_specifiers
546 (want_parm_decl ? parms : TREE_VALUE (parms));
a0c938f0 547 if (want_parm_decl)
eaab24b9 548 pp->declarator (parms);
a0c938f0 549 else
eaab24b9 550 pp->abstract_declarator (TREE_VALUE (parms));
a0c938f0 551 }
bfdec0d1 552 }
553 pp_c_right_paren (pp);
8e10b18f 554}
555
bfdec0d1 556/* abstract-declarator:
557 pointer
558 pointer(opt) direct-abstract-declarator */
d7b8e04e 559
36a8d9b9 560void
561c_pretty_printer::abstract_declarator (tree t)
bfdec0d1 562{
563 if (TREE_CODE (t) == POINTER_TYPE)
564 {
565 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
a0c938f0 566 || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
36a8d9b9 567 pp_c_right_paren (this);
bfdec0d1 568 t = TREE_TYPE (t);
569 }
570
36a8d9b9 571 direct_abstract_declarator (t);
bfdec0d1 572}
573
574/* direct-abstract-declarator:
575 ( abstract-declarator )
576 direct-abstract-declarator(opt) [ assignment-expression(opt) ]
577 direct-abstract-declarator(opt) [ * ]
578 direct-abstract-declarator(opt) ( parameter-type-list(opt) ) */
d7b8e04e 579
c10de5e7 580void
36a8d9b9 581c_pretty_printer::direct_abstract_declarator (tree t)
bfdec0d1 582{
583 switch (TREE_CODE (t))
584 {
585 case POINTER_TYPE:
36a8d9b9 586 abstract_declarator (t);
bfdec0d1 587 break;
b27ac6b5 588
bfdec0d1 589 case FUNCTION_TYPE:
36a8d9b9 590 pp_c_parameter_type_list (this, t);
591 direct_abstract_declarator (TREE_TYPE (t));
bfdec0d1 592 break;
593
594 case ARRAY_TYPE:
36a8d9b9 595 pp_c_left_bracket (this);
31266980 596 if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
e259be19 597 {
598 tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (t));
599 tree type = TREE_TYPE (maxval);
600
e913b5cd 601 if (tree_fits_shwi_p (maxval))
d85a2013 602 pp_wide_integer (this, tree_to_shwi (maxval) + 1);
e259be19 603 else
eaab24b9 604 expression (fold_build2 (PLUS_EXPR, type, maxval,
605 build_int_cst (type, 1)));
e259be19 606 }
36a8d9b9 607 pp_c_right_bracket (this);
608 direct_abstract_declarator (TREE_TYPE (t));
bfdec0d1 609 break;
610
611 case IDENTIFIER_NODE:
612 case VOID_TYPE:
613 case BOOLEAN_TYPE:
614 case INTEGER_TYPE:
615 case REAL_TYPE:
06f0b99c 616 case FIXED_POINT_TYPE:
bfdec0d1 617 case ENUMERAL_TYPE:
618 case RECORD_TYPE:
619 case UNION_TYPE:
620 case VECTOR_TYPE:
621 case COMPLEX_TYPE:
622 case TYPE_DECL:
623 break;
b27ac6b5 624
bfdec0d1 625 default:
36a8d9b9 626 pp_unsupported_tree (this, t);
bfdec0d1 627 break;
628 }
629}
630
c10de5e7 631/* type-name:
632 specifier-qualifier-list abstract-declarator(opt) */
d7b8e04e 633
bfdec0d1 634void
eaab24b9 635c_pretty_printer::type_id (tree t)
8e10b18f 636{
eaab24b9 637 pp_c_specifier_qualifier_list (this, t);
638 abstract_declarator (t);
8e10b18f 639}
640
c10de5e7 641/* storage-class-specifier:
642 typedef
643 extern
644 static
645 auto
646 register */
d7b8e04e 647
c10de5e7 648void
eaab24b9 649c_pretty_printer::storage_class_specifier (tree t)
ed22b9fe 650{
651 if (TREE_CODE (t) == TYPE_DECL)
eaab24b9 652 pp_c_ws_string (this, "typedef");
bfdec0d1 653 else if (DECL_P (t))
654 {
655 if (DECL_REGISTER (t))
eaab24b9 656 pp_c_ws_string (this, "register");
bfdec0d1 657 else if (TREE_STATIC (t) && TREE_CODE (t) == VAR_DECL)
eaab24b9 658 pp_c_ws_string (this, "static");
bfdec0d1 659 }
ed22b9fe 660}
661
c10de5e7 662/* function-specifier:
663 inline */
d7b8e04e 664
c10de5e7 665void
36a8d9b9 666c_pretty_printer::function_specifier (tree t)
ed22b9fe 667{
668 if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
36a8d9b9 669 pp_c_ws_string (this, "inline");
ed22b9fe 670}
671
bfdec0d1 672/* declaration-specifiers:
673 storage-class-specifier declaration-specifiers(opt)
674 type-specifier declaration-specifiers(opt)
675 type-qualifier declaration-specifiers(opt)
676 function-specifier declaration-specifiers(opt) */
d7b8e04e 677
c10de5e7 678void
36a8d9b9 679c_pretty_printer::declaration_specifiers (tree t)
ed22b9fe 680{
eaab24b9 681 storage_class_specifier (t);
682 function_specifier (t);
36a8d9b9 683 pp_c_specifier_qualifier_list (this, DECL_P (t) ? TREE_TYPE (t) : t);
ed22b9fe 684}
685
bfdec0d1 686/* direct-declarator
687 identifier
688 ( declarator )
689 direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
690 direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)]
f024691d 691 direct-declarator [ type-qualifier-list static assignment-expression ]
bfdec0d1 692 direct-declarator [ type-qualifier-list * ]
3f7df443 693 direct-declarator ( parameter-type-list )
bfdec0d1 694 direct-declarator ( identifier-list(opt) ) */
d7b8e04e 695
bfdec0d1 696void
36a8d9b9 697c_pretty_printer::direct_declarator (tree t)
ed22b9fe 698{
bfdec0d1 699 switch (TREE_CODE (t))
700 {
701 case VAR_DECL:
702 case PARM_DECL:
703 case TYPE_DECL:
704 case FIELD_DECL:
705 case LABEL_DECL:
36a8d9b9 706 pp_c_space_for_pointer_operator (this, TREE_TYPE (t));
707 pp_c_tree_decl_identifier (this, t);
4ee9c684 708 break;
709
bfdec0d1 710 case ARRAY_TYPE:
711 case POINTER_TYPE:
36a8d9b9 712 abstract_declarator (TREE_TYPE (t));
bfdec0d1 713 break;
714
715 case FUNCTION_TYPE:
36a8d9b9 716 pp_parameter_list (this, t);
717 abstract_declarator (TREE_TYPE (t));
bfdec0d1 718 break;
719
720 case FUNCTION_DECL:
36a8d9b9 721 pp_c_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
722 pp_c_tree_decl_identifier (this, t);
723 if (flags & pp_c_flag_abstract)
724 abstract_declarator (TREE_TYPE (t));
bfdec0d1 725 else
a0c938f0 726 {
36a8d9b9 727 pp_parameter_list (this, t);
728 abstract_declarator (TREE_TYPE (TREE_TYPE (t)));
a0c938f0 729 }
bfdec0d1 730 break;
731
732 case INTEGER_TYPE:
733 case REAL_TYPE:
06f0b99c 734 case FIXED_POINT_TYPE:
bfdec0d1 735 case ENUMERAL_TYPE:
736 case UNION_TYPE:
737 case RECORD_TYPE:
738 break;
739
740 default:
36a8d9b9 741 pp_unsupported_tree (this, t);
bfdec0d1 742 break;
743 }
ed22b9fe 744}
745
bfdec0d1 746
747/* declarator:
748 pointer(opt) direct-declarator */
d7b8e04e 749
bfdec0d1 750void
36a8d9b9 751c_pretty_printer::declarator (tree t)
ed22b9fe 752{
bfdec0d1 753 switch (TREE_CODE (t))
754 {
755 case INTEGER_TYPE:
756 case REAL_TYPE:
06f0b99c 757 case FIXED_POINT_TYPE:
bfdec0d1 758 case ENUMERAL_TYPE:
759 case UNION_TYPE:
760 case RECORD_TYPE:
761 break;
762
763 case VAR_DECL:
764 case PARM_DECL:
765 case FIELD_DECL:
766 case ARRAY_TYPE:
767 case FUNCTION_TYPE:
768 case FUNCTION_DECL:
769 case TYPE_DECL:
eaab24b9 770 direct_declarator (t);
bfdec0d1 771 break;
772
b27ac6b5 773
bfdec0d1 774 default:
36a8d9b9 775 pp_unsupported_tree (this, t);
bfdec0d1 776 break;
777 }
ed22b9fe 778}
779
bfdec0d1 780/* declaration:
781 declaration-specifiers init-declarator-list(opt) ; */
d7b8e04e 782
ed22b9fe 783void
36a8d9b9 784c_pretty_printer::declaration (tree t)
ed22b9fe 785{
36a8d9b9 786 declaration_specifiers (t);
787 pp_c_init_declarator (this, t);
ed22b9fe 788}
789
980451fe 790/* Pretty-print ATTRIBUTES using GNU C extension syntax. */
d7b8e04e 791
2b30d46c 792void
c10de5e7 793pp_c_attributes (c_pretty_printer *pp, tree attributes)
980451fe 794{
795 if (attributes == NULL_TREE)
796 return;
2b30d46c 797
1e00012f 798 pp_c_ws_string (pp, "__attribute__");
2b30d46c 799 pp_c_left_paren (pp);
980451fe 800 pp_c_left_paren (pp);
801 for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes))
802 {
803 pp_tree_identifier (pp, TREE_PURPOSE (attributes));
804 if (TREE_VALUE (attributes))
a0c938f0 805 pp_c_call_argument_list (pp, TREE_VALUE (attributes));
2b30d46c 806
980451fe 807 if (TREE_CHAIN (attributes))
808 pp_separate_with (pp, ',');
809 }
810 pp_c_right_paren (pp);
811 pp_c_right_paren (pp);
812}
813
ee212425 814/* Pretty-print ATTRIBUTES using GNU C extension syntax for attributes
815 marked to be displayed on disgnostic. */
816
817void
818pp_c_attributes_display (c_pretty_printer *pp, tree a)
819{
820 bool is_first = true;
821
822 if (a == NULL_TREE)
823 return;
824
825 for (; a != NULL_TREE; a = TREE_CHAIN (a))
826 {
827 const struct attribute_spec *as;
828 as = lookup_attribute_spec (TREE_PURPOSE (a));
829 if (!as || as->affects_type_identity == false)
830 continue;
831 if (is_first)
832 {
833 pp_c_ws_string (pp, "__attribute__");
834 pp_c_left_paren (pp);
835 pp_c_left_paren (pp);
836 is_first = false;
837 }
838 else
839 {
840 pp_separate_with (pp, ',');
841 }
842 pp_tree_identifier (pp, TREE_PURPOSE (a));
843 if (TREE_VALUE (a))
844 pp_c_call_argument_list (pp, TREE_VALUE (a));
845 }
846
847 if (!is_first)
848 {
849 pp_c_right_paren (pp);
850 pp_c_right_paren (pp);
851 pp_c_whitespace (pp);
852 }
853}
854
bfdec0d1 855/* function-definition:
856 declaration-specifiers declarator compound-statement */
d7b8e04e 857
bfdec0d1 858void
c10de5e7 859pp_c_function_definition (c_pretty_printer *pp, tree t)
bfdec0d1 860{
eaab24b9 861 pp->declaration_specifiers (t);
862 pp->declarator (t);
bfdec0d1 863 pp_needs_newline (pp) = true;
c5d35bea 864 pp->statement (DECL_SAVED_TREE (t));
5f7f600e 865 pp_newline_and_flush (pp);
bfdec0d1 866}
867
ba21936b 868\f
869/* Expressions. */
870
624d37a6 871/* Print out a c-char. This is called solely for characters which are
872 in the *target* execution character set. We ought to convert them
873 back to the *host* execution character set before printing, but we
874 have no way to do this at present. A decent compromise is to print
875 all characters as if they were in the host execution character set,
876 and not attempt to recover any named escape characters, but render
877 all unprintables as octal escapes. If the host and target character
878 sets are the same, this produces relatively readable output. If they
879 are not the same, strings may appear as gibberish, but that's okay
880 (in fact, it may well be what the reader wants, e.g. if they are looking
881 to see if conversion to the target character set happened correctly).
882
883 A special case: we need to prefix \, ", and ' with backslashes. It is
884 correct to do so for the *host*'s \, ", and ', because the rest of the
885 file appears in the host character set. */
d7b8e04e 886
ba21936b 887static void
c10de5e7 888pp_c_char (c_pretty_printer *pp, int c)
ba21936b 889{
624d37a6 890 if (ISPRINT (c))
ba21936b 891 {
624d37a6 892 switch (c)
893 {
894 case '\\': pp_string (pp, "\\\\"); break;
895 case '\'': pp_string (pp, "\\\'"); break;
896 case '\"': pp_string (pp, "\\\""); break;
897 default: pp_character (pp, c);
898 }
ba21936b 899 }
624d37a6 900 else
901 pp_scalar (pp, "\\%03o", (unsigned) c);
ba21936b 902}
903
904/* Print out a STRING literal. */
d7b8e04e 905
0de2b732 906void
c10de5e7 907pp_c_string_literal (c_pretty_printer *pp, tree s)
ba21936b 908{
909 const char *p = TREE_STRING_POINTER (s);
910 int n = TREE_STRING_LENGTH (s) - 1;
911 int i;
c10de5e7 912 pp_doublequote (pp);
ba21936b 913 for (i = 0; i < n; ++i)
c10de5e7 914 pp_c_char (pp, p[i]);
915 pp_doublequote (pp);
ba21936b 916}
917
3ab4693e 918/* Pretty-print a VOID_CST (void_node). */
919
920static void
921pp_c_void_constant (c_pretty_printer *pp)
922{
923 pp_c_type_cast (pp, void_type_node);
924 pp_string (pp, "0");
925}
926
ad46e187 927/* Pretty-print an INTEGER literal. */
928
bfdec0d1 929static void
c10de5e7 930pp_c_integer_constant (c_pretty_printer *pp, tree i)
bfdec0d1 931{
9f75f026 932 int idx;
933
0e9a4c01 934 /* We are going to compare the type of I to other types using
935 pointer comparison so we need to use its canonical type. */
936 tree type =
937 TYPE_CANONICAL (TREE_TYPE (i))
938 ? TYPE_CANONICAL (TREE_TYPE (i))
939 : TREE_TYPE (i);
d7b8e04e 940
e913b5cd 941 if (tree_fits_shwi_p (i))
942 pp_wide_integer (pp, tree_to_shwi (i));
943 else if (tree_fits_uhwi_p (i))
944 pp_unsigned_wide_integer (pp, tree_to_uhwi (i));
bfdec0d1 945 else
946 {
e913b5cd 947 wide_int wi = i;
948
796b6678 949 if (wi::lt_p (i, 0, TYPE_SIGN (TREE_TYPE (i))))
a0c938f0 950 {
dda4f0ec 951 pp_minus (pp);
e913b5cd 952 wi = -wi;
a0c938f0 953 }
e913b5cd 954 print_hex (wi, pp_buffer (pp)->digit_buffer);
bfdec0d1 955 pp_string (pp, pp_buffer (pp)->digit_buffer);
956 }
78a8ed03 957 if (TYPE_UNSIGNED (type))
d7b8e04e 958 pp_character (pp, 'u');
959 if (type == long_integer_type_node || type == long_unsigned_type_node)
960 pp_character (pp, 'l');
961 else if (type == long_long_integer_type_node
a0c938f0 962 || type == long_long_unsigned_type_node)
d7b8e04e 963 pp_string (pp, "ll");
9f75f026 964 else for (idx = 0; idx < NUM_INT_N_ENTS; idx ++)
965 if (int_n_enabled_p[idx])
966 {
967 char buf[2+20];
968 if (type == int_n_trees[idx].signed_type
969 || type == int_n_trees[idx].unsigned_type)
970 {
971 sprintf (buf, "I%d", int_n_data[idx].bitsize);
972 pp_string (pp, buf);
973 }
974 }
bfdec0d1 975}
976
ba21936b 977/* Print out a CHARACTER literal. */
d7b8e04e 978
89df180d 979static void
c10de5e7 980pp_c_character_constant (c_pretty_printer *pp, tree c)
ba21936b 981{
bfdec0d1 982 pp_quote (pp);
f9ae6f95 983 pp_c_char (pp, (unsigned) TREE_INT_CST_LOW (c));
bfdec0d1 984 pp_quote (pp);
ba21936b 985}
986
987/* Print out a BOOLEAN literal. */
d7b8e04e 988
bfdec0d1 989static void
c10de5e7 990pp_c_bool_constant (c_pretty_printer *pp, tree b)
ba21936b 991{
bfdec0d1 992 if (b == boolean_false_node)
ba21936b 993 {
c0f19401 994 if (c_dialect_cxx ())
1e00012f 995 pp_c_ws_string (pp, "false");
c0f19401 996 else if (flag_isoc99)
1e00012f 997 pp_c_ws_string (pp, "_False");
ba21936b 998 else
bfdec0d1 999 pp_unsupported_tree (pp, b);
ba21936b 1000 }
1001 else if (b == boolean_true_node)
1002 {
c0f19401 1003 if (c_dialect_cxx ())
1e00012f 1004 pp_c_ws_string (pp, "true");
c0f19401 1005 else if (flag_isoc99)
1e00012f 1006 pp_c_ws_string (pp, "_True");
ba21936b 1007 else
bfdec0d1 1008 pp_unsupported_tree (pp, b);
ba21936b 1009 }
bfdec0d1 1010 else if (TREE_CODE (b) == INTEGER_CST)
1011 pp_c_integer_constant (pp, b);
ba21936b 1012 else
bfdec0d1 1013 pp_unsupported_tree (pp, b);
ba21936b 1014}
1015
2b30d46c 1016/* Attempt to print out an ENUMERATOR. Return true on success. Else return
ba21936b 1017 false; that means the value was obtained by a cast, in which case
1018 print out the type-id part of the cast-expression -- the casted value
1019 is then printed by pp_c_integer_literal. */
d7b8e04e 1020
ba21936b 1021static bool
c10de5e7 1022pp_c_enumeration_constant (c_pretty_printer *pp, tree e)
ba21936b 1023{
bfdec0d1 1024 bool value_is_named = true;
ba21936b 1025 tree type = TREE_TYPE (e);
1026 tree value;
1027
1028 /* Find the name of this constant. */
2b30d46c 1029 for (value = TYPE_VALUES (type);
ba21936b 1030 value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e);
1031 value = TREE_CHAIN (value))
1032 ;
2b30d46c 1033
ba21936b 1034 if (value != NULL_TREE)
eaab24b9 1035 pp->id_expression (TREE_PURPOSE (value));
ba21936b 1036 else
1037 {
1038 /* Value must have been cast. */
c10de5e7 1039 pp_c_type_cast (pp, type);
bfdec0d1 1040 value_is_named = false;
ba21936b 1041 }
2b30d46c 1042
bfdec0d1 1043 return value_is_named;
ba21936b 1044}
1045
90b80807 1046/* Print out a REAL value as a decimal-floating-constant. */
1047
89df180d 1048static void
c10de5e7 1049pp_c_floating_constant (c_pretty_printer *pp, tree r)
ba21936b 1050{
d4a627f3 1051 const struct real_format *fmt
1052 = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (r)));
1053
1054 REAL_VALUE_TYPE floating_cst = TREE_REAL_CST (r);
1055 bool is_decimal = floating_cst.decimal;
1056
1057 /* See ISO C++ WG N1822. Note: The fraction 643/2136 approximates
1058 log10(2) to 7 significant digits. */
1059 int max_digits10 = 2 + (is_decimal ? fmt->p : fmt->p * 643L / 2136);
1060
bfdec0d1 1061 real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r),
d4a627f3 1062 sizeof (pp_buffer (pp)->digit_buffer),
1063 max_digits10, 1);
1064
bfdec0d1 1065 pp_string (pp, pp_buffer(pp)->digit_buffer);
90b80807 1066 if (TREE_TYPE (r) == float_type_node)
1067 pp_character (pp, 'f');
1068 else if (TREE_TYPE (r) == long_double_type_node)
1069 pp_character (pp, 'l');
c4503c0a 1070 else if (TREE_TYPE (r) == dfloat128_type_node)
1071 pp_string (pp, "dl");
1072 else if (TREE_TYPE (r) == dfloat64_type_node)
1073 pp_string (pp, "dd");
1074 else if (TREE_TYPE (r) == dfloat32_type_node)
1075 pp_string (pp, "df");
ba21936b 1076}
1077
06f0b99c 1078/* Print out a FIXED value as a decimal-floating-constant. */
1079
1080static void
1081pp_c_fixed_constant (c_pretty_printer *pp, tree r)
1082{
1083 fixed_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_FIXED_CST (r),
1084 sizeof (pp_buffer (pp)->digit_buffer));
1085 pp_string (pp, pp_buffer(pp)->digit_buffer);
1086}
1087
d7b8e04e 1088/* Pretty-print a compound literal expression. GNU extensions include
b27ac6b5 1089 vector constants. */
d7b8e04e 1090
1091static void
1092pp_c_compound_literal (c_pretty_printer *pp, tree e)
1093{
b27ac6b5 1094 tree type = TREE_TYPE (e);
d7b8e04e 1095 pp_c_type_cast (pp, type);
1096
1097 switch (TREE_CODE (type))
1098 {
1099 case RECORD_TYPE:
1100 case UNION_TYPE:
1101 case ARRAY_TYPE:
1102 case VECTOR_TYPE:
1103 case COMPLEX_TYPE:
1104 pp_c_brace_enclosed_initializer_list (pp, e);
1105 break;
1106
1107 default:
1108 pp_unsupported_tree (pp, e);
1109 break;
1110 }
1111}
1112
7a4209c5 1113/* Pretty-print a COMPLEX_EXPR expression. */
1114
1115static void
1116pp_c_complex_expr (c_pretty_printer *pp, tree e)
1117{
1118 /* Handle a few common special cases, otherwise fallback
1119 to printing it as compound literal. */
1120 tree type = TREE_TYPE (e);
1121 tree realexpr = TREE_OPERAND (e, 0);
1122 tree imagexpr = TREE_OPERAND (e, 1);
1123
1124 /* Cast of an COMPLEX_TYPE expression to a different COMPLEX_TYPE. */
1125 if (TREE_CODE (realexpr) == NOP_EXPR
1126 && TREE_CODE (imagexpr) == NOP_EXPR
1127 && TREE_TYPE (realexpr) == TREE_TYPE (type)
1128 && TREE_TYPE (imagexpr) == TREE_TYPE (type)
1129 && TREE_CODE (TREE_OPERAND (realexpr, 0)) == REALPART_EXPR
1130 && TREE_CODE (TREE_OPERAND (imagexpr, 0)) == IMAGPART_EXPR
1131 && TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0)
1132 == TREE_OPERAND (TREE_OPERAND (imagexpr, 0), 0))
1133 {
1134 pp_c_type_cast (pp, type);
eaab24b9 1135 pp->expression (TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0));
7a4209c5 1136 return;
1137 }
1138
1139 /* Cast of an scalar expression to COMPLEX_TYPE. */
1140 if ((integer_zerop (imagexpr) || real_zerop (imagexpr))
1141 && TREE_TYPE (realexpr) == TREE_TYPE (type))
1142 {
1143 pp_c_type_cast (pp, type);
1144 if (TREE_CODE (realexpr) == NOP_EXPR)
1145 realexpr = TREE_OPERAND (realexpr, 0);
eaab24b9 1146 pp->expression (realexpr);
7a4209c5 1147 return;
1148 }
1149
1150 pp_c_compound_literal (pp, e);
1151}
1152
bfdec0d1 1153/* constant:
1154 integer-constant
1155 floating-constant
06f0b99c 1156 fixed-point-constant
bfdec0d1 1157 enumeration-constant
f024691d 1158 character-constant */
d7b8e04e 1159
ba21936b 1160void
a6cb161b 1161c_pretty_printer::constant (tree e)
ba21936b 1162{
d7b8e04e 1163 const enum tree_code code = TREE_CODE (e);
1164
1165 switch (code)
ba21936b 1166 {
3ab4693e 1167 case VOID_CST:
1168 pp_c_void_constant (this);
1169 break;
1170
ba21936b 1171 case INTEGER_CST:
bfdec0d1 1172 {
a0c938f0 1173 tree type = TREE_TYPE (e);
1174 if (type == boolean_type_node)
a6cb161b 1175 pp_c_bool_constant (this, e);
a0c938f0 1176 else if (type == char_type_node)
a6cb161b 1177 pp_c_character_constant (this, e);
a0c938f0 1178 else if (TREE_CODE (type) == ENUMERAL_TYPE
a6cb161b 1179 && pp_c_enumeration_constant (this, e))
a0c938f0 1180 ;
1181 else
a6cb161b 1182 pp_c_integer_constant (this, e);
bfdec0d1 1183 }
ba21936b 1184 break;
2b30d46c 1185
ba21936b 1186 case REAL_CST:
a6cb161b 1187 pp_c_floating_constant (this, e);
ba21936b 1188 break;
2b30d46c 1189
06f0b99c 1190 case FIXED_CST:
a6cb161b 1191 pp_c_fixed_constant (this, e);
06f0b99c 1192 break;
1193
ba21936b 1194 case STRING_CST:
a6cb161b 1195 pp_c_string_literal (this, e);
2b30d46c 1196 break;
ba21936b 1197
330b082c 1198 case COMPLEX_CST:
1199 /* Sometimes, we are confused and we think a complex literal
1200 is a constant. Such thing is a compound literal which
f0b5f617 1201 grammatically belongs to postfix-expr production. */
a6cb161b 1202 pp_c_compound_literal (this, e);
330b082c 1203 break;
1204
ba21936b 1205 default:
a6cb161b 1206 pp_unsupported_tree (this, e);
ba21936b 1207 break;
1208 }
1209}
1210
1e00012f 1211/* Pretty-print a string such as an identifier, without changing its
1212 encoding, preceded by whitespace is necessary. */
1213
1214void
1215pp_c_ws_string (c_pretty_printer *pp, const char *str)
1216{
1217 pp_c_maybe_whitespace (pp);
1218 pp_string (pp, str);
a94db6b0 1219 pp->padding = pp_before;
1e00012f 1220}
1221
08e3e481 1222void
1223c_pretty_printer::translate_string (const char *gmsgid)
1224{
1225 if (pp_translate_identifiers (this))
1226 pp_c_ws_string (this, _(gmsgid));
1227 else
1228 pp_c_ws_string (this, gmsgid);
1229}
1230
1e00012f 1231/* Pretty-print an IDENTIFIER_NODE, which may contain UTF-8 sequences
1232 that need converting to the locale encoding, preceded by whitespace
1233 is necessary. */
ad46e187 1234
bfdec0d1 1235void
c10de5e7 1236pp_c_identifier (c_pretty_printer *pp, const char *id)
bfdec0d1 1237{
b27ac6b5 1238 pp_c_maybe_whitespace (pp);
1239 pp_identifier (pp, id);
a94db6b0 1240 pp->padding = pp_before;
bfdec0d1 1241}
1242
1243/* Pretty-print a C primary-expression.
1244 primary-expression:
1245 identifier
1246 constant
1247 string-literal
1248 ( expression ) */
d7b8e04e 1249
c10de5e7 1250void
f873303a 1251c_pretty_printer::primary_expression (tree e)
ba21936b 1252{
1253 switch (TREE_CODE (e))
1254 {
1255 case VAR_DECL:
1256 case PARM_DECL:
1257 case FIELD_DECL:
1258 case CONST_DECL:
1259 case FUNCTION_DECL:
1260 case LABEL_DECL:
f873303a 1261 pp_c_tree_decl_identifier (this, e);
4ee9c684 1262 break;
1263
ba21936b 1264 case IDENTIFIER_NODE:
f873303a 1265 pp_c_tree_identifier (this, e);
ba21936b 1266 break;
1267
1268 case ERROR_MARK:
f873303a 1269 translate_string ("<erroneous-expression>");
ba21936b 1270 break;
2b30d46c 1271
ba21936b 1272 case RESULT_DECL:
f873303a 1273 translate_string ("<return-value>");
ba21936b 1274 break;
1275
3ab4693e 1276 case VOID_CST:
ba21936b 1277 case INTEGER_CST:
1278 case REAL_CST:
06f0b99c 1279 case FIXED_CST:
ba21936b 1280 case STRING_CST:
f873303a 1281 constant (e);
ba21936b 1282 break;
1283
4ee9c684 1284 case TARGET_EXPR:
f873303a 1285 pp_c_ws_string (this, "__builtin_memcpy");
1286 pp_c_left_paren (this);
1287 pp_ampersand (this);
1288 primary_expression (TREE_OPERAND (e, 0));
1289 pp_separate_with (this, ',');
1290 pp_ampersand (this);
eaab24b9 1291 initializer (TREE_OPERAND (e, 1));
4ee9c684 1292 if (TREE_OPERAND (e, 2))
1293 {
f873303a 1294 pp_separate_with (this, ',');
30635c2e 1295 expression (TREE_OPERAND (e, 2));
4ee9c684 1296 }
f873303a 1297 pp_c_right_paren (this);
4ee9c684 1298 break;
1299
ba21936b 1300 default:
f0b5f617 1301 /* FIXME: Make sure we won't get into an infinite loop. */
f873303a 1302 pp_c_left_paren (this);
eaab24b9 1303 expression (e);
f873303a 1304 pp_c_right_paren (this);
ba21936b 1305 break;
1306 }
1307}
1308
bfdec0d1 1309/* Print out a C initializer -- also support C compound-literals.
1310 initializer:
1311 assignment-expression:
1312 { initializer-list }
1313 { initializer-list , } */
1314
eaab24b9 1315void
1316c_pretty_printer::initializer (tree e)
5dadc2ef 1317{
1318 if (TREE_CODE (e) == CONSTRUCTOR)
eaab24b9 1319 pp_c_brace_enclosed_initializer_list (this, e);
5dadc2ef 1320 else
eaab24b9 1321 expression (e);
c10de5e7 1322}
1323
1324/* init-declarator:
1325 declarator:
1326 declarator = initializer */
d7b8e04e 1327
c10de5e7 1328void
1329pp_c_init_declarator (c_pretty_printer *pp, tree t)
1330{
eaab24b9 1331 pp->declarator (t);
ad46e187 1332 /* We don't want to output function definitions here. There are handled
1333 elsewhere (and the syntactic form is bogus anyway). */
1334 if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t))
c10de5e7 1335 {
1336 tree init = DECL_INITIAL (t);
1337 /* This C++ bit is handled here because it is easier to do so.
a0c938f0 1338 In templates, the C++ parser builds a TREE_LIST for a
1339 direct-initialization; the TREE_PURPOSE is the variable to
1340 initialize and the TREE_VALUE is the initializer. */
c10de5e7 1341 if (TREE_CODE (init) == TREE_LIST)
a0c938f0 1342 {
1343 pp_c_left_paren (pp);
eaab24b9 1344 pp->expression (TREE_VALUE (init));
a0c938f0 1345 pp_right_paren (pp);
1346 }
c10de5e7 1347 else
a0c938f0 1348 {
1349 pp_space (pp);
1350 pp_equal (pp);
1351 pp_space (pp);
eaab24b9 1352 pp->initializer (init);
a0c938f0 1353 }
c10de5e7 1354 }
5dadc2ef 1355}
1356
bfdec0d1 1357/* initializer-list:
1358 designation(opt) initializer
1359 initializer-list , designation(opt) initializer
1360
1361 designation:
1362 designator-list =
1363
1364 designator-list:
1365 designator
1366 designator-list designator
1367
1368 designator:
1369 [ constant-expression ]
1370 identifier */
d7b8e04e 1371
5dadc2ef 1372static void
c10de5e7 1373pp_c_initializer_list (c_pretty_printer *pp, tree e)
5dadc2ef 1374{
1375 tree type = TREE_TYPE (e);
1376 const enum tree_code code = TREE_CODE (type);
1377
87d31deb 1378 if (TREE_CODE (e) == CONSTRUCTOR)
1379 {
1380 pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
1381 return;
1382 }
1383
d7b8e04e 1384 switch (code)
5dadc2ef 1385 {
d7b8e04e 1386 case RECORD_TYPE:
1387 case UNION_TYPE:
1388 case ARRAY_TYPE:
1389 {
a0c938f0 1390 tree init = TREE_OPERAND (e, 0);
1391 for (; init != NULL_TREE; init = TREE_CHAIN (init))
1392 {
1393 if (code == RECORD_TYPE || code == UNION_TYPE)
1394 {
1395 pp_c_dot (pp);
eaab24b9 1396 pp->primary_expression (TREE_PURPOSE (init));
a0c938f0 1397 }
1398 else
1399 {
1400 pp_c_left_bracket (pp);
1401 if (TREE_PURPOSE (init))
eaab24b9 1402 pp->constant (TREE_PURPOSE (init));
a0c938f0 1403 pp_c_right_bracket (pp);
1404 }
1405 pp_c_whitespace (pp);
1406 pp_equal (pp);
1407 pp_c_whitespace (pp);
eaab24b9 1408 pp->initializer (TREE_VALUE (init));
a0c938f0 1409 if (TREE_CHAIN (init))
1410 pp_separate_with (pp, ',');
1411 }
d7b8e04e 1412 }
4ee9c684 1413 return;
d7b8e04e 1414
1415 case VECTOR_TYPE:
4ee9c684 1416 if (TREE_CODE (e) == VECTOR_CST)
fadf62f4 1417 {
1418 unsigned i;
1419 for (i = 0; i < VECTOR_CST_NELTS (e); ++i)
1420 {
1421 if (i > 0)
1422 pp_separate_with (pp, ',');
eaab24b9 1423 pp->expression (VECTOR_CST_ELT (e, i));
fadf62f4 1424 }
1425 }
4ee9c684 1426 else
a0c938f0 1427 break;
4ee9c684 1428 return;
d7b8e04e 1429
1430 case COMPLEX_TYPE:
87d31deb 1431 if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
4ee9c684 1432 {
1433 const bool cst = TREE_CODE (e) == COMPLEX_CST;
eaab24b9 1434 pp->expression (cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
4ee9c684 1435 pp_separate_with (pp, ',');
eaab24b9 1436 pp->expression (cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
4ee9c684 1437 }
1438 else
1439 break;
1440 return;
d7b8e04e 1441
1442 default:
d7b8e04e 1443 break;
5dadc2ef 1444 }
4ee9c684 1445
1446 pp_unsupported_tree (pp, type);
5dadc2ef 1447}
1448
8b332087 1449/* Pretty-print a brace-enclosed initializer-list. */
d7b8e04e 1450
1451static void
1452pp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l)
1453{
1454 pp_c_left_brace (pp);
1455 pp_c_initializer_list (pp, l);
1456 pp_c_right_brace (pp);
1457}
1458
1459
bfdec0d1 1460/* This is a convenient function, used to bridge gap between C and C++
1461 grammars.
1462
1463 id-expression:
1464 identifier */
d7b8e04e 1465
bfdec0d1 1466void
1fc4a87f 1467c_pretty_printer::id_expression (tree t)
bfdec0d1 1468{
1469 switch (TREE_CODE (t))
1470 {
1471 case VAR_DECL:
1472 case PARM_DECL:
1473 case CONST_DECL:
1474 case TYPE_DECL:
1475 case FUNCTION_DECL:
1476 case FIELD_DECL:
1477 case LABEL_DECL:
1fc4a87f 1478 pp_c_tree_decl_identifier (this, t);
4ee9c684 1479 break;
1480
bfdec0d1 1481 case IDENTIFIER_NODE:
1fc4a87f 1482 pp_c_tree_identifier (this, t);
bfdec0d1 1483 break;
1484
1485 default:
1fc4a87f 1486 pp_unsupported_tree (this, t);
bfdec0d1 1487 break;
1488 }
1489}
1490
1491/* postfix-expression:
1492 primary-expression
1493 postfix-expression [ expression ]
1494 postfix-expression ( argument-expression-list(opt) )
1495 postfix-expression . identifier
1496 postfix-expression -> identifier
1497 postfix-expression ++
1498 postfix-expression --
1499 ( type-name ) { initializer-list }
1500 ( type-name ) { initializer-list , } */
d7b8e04e 1501
ba21936b 1502void
027d08ed 1503c_pretty_printer::postfix_expression (tree e)
ba21936b 1504{
1505 enum tree_code code = TREE_CODE (e);
1506 switch (code)
1507 {
1508 case POSTINCREMENT_EXPR:
1509 case POSTDECREMENT_EXPR:
027d08ed 1510 postfix_expression (TREE_OPERAND (e, 0));
1511 pp_string (this, code == POSTINCREMENT_EXPR ? "++" : "--");
ba21936b 1512 break;
2b30d46c 1513
ba21936b 1514 case ARRAY_REF:
027d08ed 1515 postfix_expression (TREE_OPERAND (e, 0));
1516 pp_c_left_bracket (this);
eaab24b9 1517 expression (TREE_OPERAND (e, 1));
027d08ed 1518 pp_c_right_bracket (this);
ba21936b 1519 break;
1520
3c6d4197 1521 case ARRAY_NOTATION_REF:
027d08ed 1522 postfix_expression (ARRAY_NOTATION_ARRAY (e));
1523 pp_c_left_bracket (this);
eaab24b9 1524 expression (ARRAY_NOTATION_START (e));
027d08ed 1525 pp_colon (this);
eaab24b9 1526 expression (ARRAY_NOTATION_LENGTH (e));
027d08ed 1527 pp_colon (this);
eaab24b9 1528 expression (ARRAY_NOTATION_STRIDE (e));
027d08ed 1529 pp_c_right_bracket (this);
3c6d4197 1530 break;
1531
ba21936b 1532 case CALL_EXPR:
c2f47e15 1533 {
1534 call_expr_arg_iterator iter;
1535 tree arg;
027d08ed 1536 postfix_expression (CALL_EXPR_FN (e));
1537 pp_c_left_paren (this);
c2f47e15 1538 FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
1539 {
eaab24b9 1540 expression (arg);
c2f47e15 1541 if (more_call_expr_args_p (&iter))
027d08ed 1542 pp_separate_with (this, ',');
c2f47e15 1543 }
027d08ed 1544 pp_c_right_paren (this);
c2f47e15 1545 break;
1546 }
ba21936b 1547
7b85cb4b 1548 case UNORDERED_EXPR:
027d08ed 1549 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1550 ? "isunordered"
1551 : "__builtin_isunordered");
1552 goto two_args_fun;
1553
1554 case ORDERED_EXPR:
027d08ed 1555 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1556 ? "!isunordered"
1557 : "!__builtin_isunordered");
1558 goto two_args_fun;
1559
1560 case UNLT_EXPR:
027d08ed 1561 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1562 ? "!isgreaterequal"
1563 : "!__builtin_isgreaterequal");
1564 goto two_args_fun;
1565
1566 case UNLE_EXPR:
027d08ed 1567 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1568 ? "!isgreater"
1569 : "!__builtin_isgreater");
1570 goto two_args_fun;
1571
1572 case UNGT_EXPR:
027d08ed 1573 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1574 ? "!islessequal"
1575 : "!__builtin_islessequal");
1576 goto two_args_fun;
1577
1578 case UNGE_EXPR:
027d08ed 1579 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1580 ? "!isless"
1581 : "!__builtin_isless");
1582 goto two_args_fun;
1583
1584 case UNEQ_EXPR:
027d08ed 1585 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1586 ? "!islessgreater"
1587 : "!__builtin_islessgreater");
1588 goto two_args_fun;
1589
1590 case LTGT_EXPR:
027d08ed 1591 pp_c_ws_string (this, flag_isoc99
7b85cb4b 1592 ? "islessgreater"
1593 : "__builtin_islessgreater");
1594 goto two_args_fun;
1595
1596 two_args_fun:
027d08ed 1597 pp_c_left_paren (this);
eaab24b9 1598 expression (TREE_OPERAND (e, 0));
027d08ed 1599 pp_separate_with (this, ',');
eaab24b9 1600 expression (TREE_OPERAND (e, 1));
027d08ed 1601 pp_c_right_paren (this);
17e8f3e4 1602 break;
7b85cb4b 1603
5dadc2ef 1604 case ABS_EXPR:
027d08ed 1605 pp_c_ws_string (this, "__builtin_abs");
1606 pp_c_left_paren (this);
eaab24b9 1607 expression (TREE_OPERAND (e, 0));
027d08ed 1608 pp_c_right_paren (this);
5dadc2ef 1609 break;
1610
ba21936b 1611 case COMPONENT_REF:
1612 {
1613 tree object = TREE_OPERAND (e, 0);
1614 if (TREE_CODE (object) == INDIRECT_REF)
1615 {
027d08ed 1616 postfix_expression (TREE_OPERAND (object, 0));
1617 pp_c_arrow (this);
ba21936b 1618 }
1619 else
1620 {
027d08ed 1621 postfix_expression (object);
1622 pp_c_dot (this);
ba21936b 1623 }
eaab24b9 1624 expression (TREE_OPERAND (e, 1));
ba21936b 1625 }
1626 break;
1627
a3efadc7 1628 case BIT_FIELD_REF:
1629 {
1630 tree type = TREE_TYPE (e);
1631
1632 type = signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type);
1633 if (type
1634 && tree_int_cst_equal (TYPE_SIZE (type), TREE_OPERAND (e, 1)))
1635 {
e913b5cd 1636 HOST_WIDE_INT bitpos = tree_to_shwi (TREE_OPERAND (e, 2));
1637 HOST_WIDE_INT size = tree_to_shwi (TYPE_SIZE (type));
a3efadc7 1638 if ((bitpos % size) == 0)
1639 {
027d08ed 1640 pp_c_left_paren (this);
1641 pp_c_left_paren (this);
eaab24b9 1642 type_id (type);
027d08ed 1643 pp_c_star (this);
1644 pp_c_right_paren (this);
1645 pp_c_ampersand (this);
eaab24b9 1646 expression (TREE_OPERAND (e, 0));
027d08ed 1647 pp_c_right_paren (this);
1648 pp_c_left_bracket (this);
1649 pp_wide_integer (this, bitpos / size);
1650 pp_c_right_bracket (this);
a3efadc7 1651 break;
1652 }
1653 }
027d08ed 1654 pp_unsupported_tree (this, e);
a3efadc7 1655 }
1656 break;
1657
b0d55af9 1658 case MEM_REF:
30635c2e 1659 expression (e);
b0d55af9 1660 break;
1661
ba21936b 1662 case COMPLEX_CST:
1663 case VECTOR_CST:
027d08ed 1664 pp_c_compound_literal (this, e);
5dadc2ef 1665 break;
1666
7a4209c5 1667 case COMPLEX_EXPR:
027d08ed 1668 pp_c_complex_expr (this, e);
7a4209c5 1669 break;
1670
219e3838 1671 case COMPOUND_LITERAL_EXPR:
3d6aa038 1672 e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
219e3838 1673 /* Fall through. */
5dadc2ef 1674 case CONSTRUCTOR:
eaab24b9 1675 initializer (e);
ba21936b 1676 break;
2b30d46c 1677
219e3838 1678 case VA_ARG_EXPR:
027d08ed 1679 pp_c_ws_string (this, "__builtin_va_arg");
1680 pp_c_left_paren (this);
30635c2e 1681 assignment_expression (TREE_OPERAND (e, 0));
027d08ed 1682 pp_separate_with (this, ',');
eaab24b9 1683 type_id (TREE_TYPE (e));
027d08ed 1684 pp_c_right_paren (this);
219e3838 1685 break;
ba21936b 1686
bfdec0d1 1687 case ADDR_EXPR:
1688 if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
a0c938f0 1689 {
027d08ed 1690 id_expression (TREE_OPERAND (e, 0));
a0c938f0 1691 break;
1692 }
ca1fae79 1693 /* else fall through. */
bfdec0d1 1694
ba21936b 1695 default:
027d08ed 1696 primary_expression (e);
ba21936b 1697 break;
1698 }
1699}
1700
8b332087 1701/* Print out an expression-list; E is expected to be a TREE_LIST. */
d7b8e04e 1702
ba21936b 1703void
c10de5e7 1704pp_c_expression_list (c_pretty_printer *pp, tree e)
ba21936b 1705{
1706 for (; e != NULL_TREE; e = TREE_CHAIN (e))
1707 {
eaab24b9 1708 pp->expression (TREE_VALUE (e));
ba21936b 1709 if (TREE_CHAIN (e))
c10de5e7 1710 pp_separate_with (pp, ',');
ba21936b 1711 }
1712}
1713
c75b4594 1714/* Print out V, which contains the elements of a constructor. */
1715
1716void
f1f41a6c 1717pp_c_constructor_elts (c_pretty_printer *pp, vec<constructor_elt, va_gc> *v)
c75b4594 1718{
1719 unsigned HOST_WIDE_INT ix;
1720 tree value;
1721
1722 FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
1723 {
eaab24b9 1724 pp->expression (value);
f1f41a6c 1725 if (ix != vec_safe_length (v) - 1)
c75b4594 1726 pp_separate_with (pp, ',');
1727 }
1728}
1729
c2f47e15 1730/* Print out an expression-list in parens, as if it were the argument
1731 list to a function. */
d7b8e04e 1732
c10de5e7 1733void
1734pp_c_call_argument_list (c_pretty_printer *pp, tree t)
1735{
1736 pp_c_left_paren (pp);
1737 if (t && TREE_CODE (t) == TREE_LIST)
1738 pp_c_expression_list (pp, t);
1739 pp_c_right_paren (pp);
1740}
1741
bfbc45f5 1742/* unary-expression:
1743 postfix-expression
1744 ++ cast-expression
1745 -- cast-expression
1746 unary-operator cast-expression
1747 sizeof unary-expression
1748 sizeof ( type-id )
1749
1750 unary-operator: one of
1751 * & + - ! ~
b27ac6b5 1752
bfbc45f5 1753 GNU extensions.
1754 unary-expression:
1755 __alignof__ unary-expression
1756 __alignof__ ( type-id )
1757 __real__ unary-expression
1758 __imag__ unary-expression */
d7b8e04e 1759
bfdec0d1 1760void
30635c2e 1761c_pretty_printer::unary_expression (tree e)
ba21936b 1762{
1763 enum tree_code code = TREE_CODE (e);
1764 switch (code)
1765 {
1766 case PREINCREMENT_EXPR:
1767 case PREDECREMENT_EXPR:
30635c2e 1768 pp_string (this, code == PREINCREMENT_EXPR ? "++" : "--");
1769 unary_expression (TREE_OPERAND (e, 0));
ba21936b 1770 break;
2b30d46c 1771
ba21936b 1772 case ADDR_EXPR:
1773 case INDIRECT_REF:
ba21936b 1774 case NEGATE_EXPR:
1775 case BIT_NOT_EXPR:
1776 case TRUTH_NOT_EXPR:
5dadc2ef 1777 case CONJ_EXPR:
bfdec0d1 1778 /* String literal are used by address. */
1779 if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
30635c2e 1780 pp_ampersand (this);
ba21936b 1781 else if (code == INDIRECT_REF)
30635c2e 1782 pp_c_star (this);
ba21936b 1783 else if (code == NEGATE_EXPR)
30635c2e 1784 pp_minus (this);
5dadc2ef 1785 else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
30635c2e 1786 pp_complement (this);
ba21936b 1787 else if (code == TRUTH_NOT_EXPR)
30635c2e 1788 pp_exclamation (this);
1789 pp_c_cast_expression (this, TREE_OPERAND (e, 0));
ba21936b 1790 break;
1791
b0d55af9 1792 case MEM_REF:
1793 if (TREE_CODE (TREE_OPERAND (e, 0)) == ADDR_EXPR
1794 && integer_zerop (TREE_OPERAND (e, 1)))
30635c2e 1795 expression (TREE_OPERAND (TREE_OPERAND (e, 0), 0));
b0d55af9 1796 else
1797 {
30635c2e 1798 pp_c_star (this);
b0d55af9 1799 if (!integer_zerop (TREE_OPERAND (e, 1)))
1800 {
30635c2e 1801 pp_c_left_paren (this);
b0d55af9 1802 if (!integer_onep (TYPE_SIZE_UNIT
1803 (TREE_TYPE (TREE_TYPE (TREE_OPERAND (e, 0))))))
30635c2e 1804 pp_c_type_cast (this, ptr_type_node);
b0d55af9 1805 }
30635c2e 1806 pp_c_cast_expression (this, TREE_OPERAND (e, 0));
b0d55af9 1807 if (!integer_zerop (TREE_OPERAND (e, 1)))
1808 {
30635c2e 1809 pp_plus (this);
1810 pp_c_integer_constant (this,
b0d55af9 1811 fold_convert (ssizetype,
1812 TREE_OPERAND (e, 1)));
30635c2e 1813 pp_c_right_paren (this);
b0d55af9 1814 }
1815 }
1816 break;
1817
5dadc2ef 1818 case REALPART_EXPR:
1819 case IMAGPART_EXPR:
30635c2e 1820 pp_c_ws_string (this, code == REALPART_EXPR ? "__real__" : "__imag__");
1821 pp_c_whitespace (this);
1822 unary_expression (TREE_OPERAND (e, 0));
5dadc2ef 1823 break;
2b30d46c 1824
ba21936b 1825 default:
30635c2e 1826 postfix_expression (e);
ba21936b 1827 break;
1828 }
1829}
1830
c10de5e7 1831/* cast-expression:
1832 unary-expression
1833 ( type-name ) cast-expression */
d7b8e04e 1834
ba21936b 1835void
c10de5e7 1836pp_c_cast_expression (c_pretty_printer *pp, tree e)
ba21936b 1837{
bfdec0d1 1838 switch (TREE_CODE (e))
ba21936b 1839 {
bfdec0d1 1840 case FLOAT_EXPR:
1841 case FIX_TRUNC_EXPR:
72dd6141 1842 CASE_CONVERT:
6242196e 1843 case VIEW_CONVERT_EXPR:
c10de5e7 1844 pp_c_type_cast (pp, TREE_TYPE (e));
1845 pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
bfdec0d1 1846 break;
1847
1848 default:
eaab24b9 1849 pp->unary_expression (e);
ba21936b 1850 }
ba21936b 1851}
1852
c10de5e7 1853/* multiplicative-expression:
1854 cast-expression
1855 multiplicative-expression * cast-expression
1856 multiplicative-expression / cast-expression
1857 multiplicative-expression % cast-expression */
d7b8e04e 1858
30635c2e 1859void
1860c_pretty_printer::multiplicative_expression (tree e)
ba21936b 1861{
1862 enum tree_code code = TREE_CODE (e);
1863 switch (code)
1864 {
1865 case MULT_EXPR:
1866 case TRUNC_DIV_EXPR:
1867 case TRUNC_MOD_EXPR:
30635c2e 1868 multiplicative_expression (TREE_OPERAND (e, 0));
1869 pp_c_whitespace (this);
ba21936b 1870 if (code == MULT_EXPR)
30635c2e 1871 pp_c_star (this);
ba21936b 1872 else if (code == TRUNC_DIV_EXPR)
30635c2e 1873 pp_slash (this);
ba21936b 1874 else
30635c2e 1875 pp_modulo (this);
1876 pp_c_whitespace (this);
1877 pp_c_cast_expression (this, TREE_OPERAND (e, 1));
ba21936b 1878 break;
1879
1880 default:
30635c2e 1881 pp_c_cast_expression (this, e);
ba21936b 1882 break;
1883 }
1884}
1885
c10de5e7 1886/* additive-expression:
1887 multiplicative-expression
1888 additive-expression + multiplicative-expression
1889 additive-expression - multiplicative-expression */
d7b8e04e 1890
89df180d 1891static void
c10de5e7 1892pp_c_additive_expression (c_pretty_printer *pp, tree e)
ba21936b 1893{
1894 enum tree_code code = TREE_CODE (e);
1895 switch (code)
1896 {
227d73b4 1897 case POINTER_PLUS_EXPR:
ba21936b 1898 case PLUS_EXPR:
1899 case MINUS_EXPR:
c10de5e7 1900 pp_c_additive_expression (pp, TREE_OPERAND (e, 0));
1901 pp_c_whitespace (pp);
227d73b4 1902 if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
c10de5e7 1903 pp_plus (pp);
ba21936b 1904 else
c10de5e7 1905 pp_minus (pp);
1906 pp_c_whitespace (pp);
eaab24b9 1907 pp->multiplicative_expression (TREE_OPERAND (e, 1));
ba21936b 1908 break;
1909
1910 default:
eaab24b9 1911 pp->multiplicative_expression (e);
ba21936b 1912 break;
1913 }
1914}
1915
c10de5e7 1916/* additive-expression:
1917 additive-expression
1918 shift-expression << additive-expression
1919 shift-expression >> additive-expression */
d7b8e04e 1920
89df180d 1921static void
c10de5e7 1922pp_c_shift_expression (c_pretty_printer *pp, tree e)
ba21936b 1923{
1924 enum tree_code code = TREE_CODE (e);
1925 switch (code)
1926 {
1927 case LSHIFT_EXPR:
1928 case RSHIFT_EXPR:
c10de5e7 1929 pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
1930 pp_c_whitespace (pp);
1e00012f 1931 pp_string (pp, code == LSHIFT_EXPR ? "<<" : ">>");
c10de5e7 1932 pp_c_whitespace (pp);
1933 pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
ba21936b 1934 break;
1935
1936 default:
c10de5e7 1937 pp_c_additive_expression (pp, e);
ba21936b 1938 }
1939}
1940
c10de5e7 1941/* relational-expression:
1942 shift-expression
1943 relational-expression < shift-expression
1944 relational-expression > shift-expression
1945 relational-expression <= shift-expression
1946 relational-expression >= shift-expression */
d7b8e04e 1947
ba21936b 1948static void
c10de5e7 1949pp_c_relational_expression (c_pretty_printer *pp, tree e)
ba21936b 1950{
1951 enum tree_code code = TREE_CODE (e);
1952 switch (code)
1953 {
1954 case LT_EXPR:
1955 case GT_EXPR:
1956 case LE_EXPR:
1957 case GE_EXPR:
c10de5e7 1958 pp_c_relational_expression (pp, TREE_OPERAND (e, 0));
1959 pp_c_whitespace (pp);
ba21936b 1960 if (code == LT_EXPR)
c10de5e7 1961 pp_less (pp);
ba21936b 1962 else if (code == GT_EXPR)
c10de5e7 1963 pp_greater (pp);
ba21936b 1964 else if (code == LE_EXPR)
70d60d1d 1965 pp_less_equal (pp);
ba21936b 1966 else if (code == GE_EXPR)
70d60d1d 1967 pp_greater_equal (pp);
c10de5e7 1968 pp_c_whitespace (pp);
1969 pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
ba21936b 1970 break;
1971
1972 default:
c10de5e7 1973 pp_c_shift_expression (pp, e);
ba21936b 1974 break;
1975 }
1976}
1977
c10de5e7 1978/* equality-expression:
1979 relational-expression
1980 equality-expression == relational-expression
1981 equality-equality != relational-expression */
d7b8e04e 1982
89df180d 1983static void
c10de5e7 1984pp_c_equality_expression (c_pretty_printer *pp, tree e)
ba21936b 1985{
1986 enum tree_code code = TREE_CODE (e);
1987 switch (code)
1988 {
1989 case EQ_EXPR:
1990 case NE_EXPR:
c10de5e7 1991 pp_c_equality_expression (pp, TREE_OPERAND (e, 0));
1992 pp_c_whitespace (pp);
1e00012f 1993 pp_string (pp, code == EQ_EXPR ? "==" : "!=");
c10de5e7 1994 pp_c_whitespace (pp);
1995 pp_c_relational_expression (pp, TREE_OPERAND (e, 1));
2b30d46c 1996 break;
1997
ba21936b 1998 default:
c10de5e7 1999 pp_c_relational_expression (pp, e);
ba21936b 2000 break;
2001 }
2002}
2003
c10de5e7 2004/* AND-expression:
2005 equality-expression
2006 AND-expression & equality-equality */
d7b8e04e 2007
89df180d 2008static void
c10de5e7 2009pp_c_and_expression (c_pretty_printer *pp, tree e)
ba21936b 2010{
2011 if (TREE_CODE (e) == BIT_AND_EXPR)
2012 {
c10de5e7 2013 pp_c_and_expression (pp, TREE_OPERAND (e, 0));
2014 pp_c_whitespace (pp);
2015 pp_ampersand (pp);
2016 pp_c_whitespace (pp);
2017 pp_c_equality_expression (pp, TREE_OPERAND (e, 1));
ba21936b 2018 }
2019 else
c10de5e7 2020 pp_c_equality_expression (pp, e);
ba21936b 2021}
2022
c10de5e7 2023/* exclusive-OR-expression:
2024 AND-expression
2025 exclusive-OR-expression ^ AND-expression */
d7b8e04e 2026
89df180d 2027static void
c10de5e7 2028pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e)
ba21936b 2029{
37aea014 2030 if (TREE_CODE (e) == BIT_XOR_EXPR
2031 || TREE_CODE (e) == TRUTH_XOR_EXPR)
ba21936b 2032 {
c10de5e7 2033 pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
37aea014 2034 if (TREE_CODE (e) == BIT_XOR_EXPR)
2035 pp_c_maybe_whitespace (pp);
2036 else
2037 pp_c_whitespace (pp);
c10de5e7 2038 pp_carret (pp);
2039 pp_c_whitespace (pp);
2040 pp_c_and_expression (pp, TREE_OPERAND (e, 1));
ba21936b 2041 }
2042 else
c10de5e7 2043 pp_c_and_expression (pp, e);
ba21936b 2044}
2045
c10de5e7 2046/* inclusive-OR-expression:
2047 exclusive-OR-expression
2048 inclusive-OR-expression | exclusive-OR-expression */
d7b8e04e 2049
89df180d 2050static void
c10de5e7 2051pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e)
ba21936b 2052{
2053 if (TREE_CODE (e) == BIT_IOR_EXPR)
2054 {
c10de5e7 2055 pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
2056 pp_c_whitespace (pp);
2057 pp_bar (pp);
2058 pp_c_whitespace (pp);
2059 pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1));
ba21936b 2060 }
2061 else
c10de5e7 2062 pp_c_exclusive_or_expression (pp, e);
ba21936b 2063}
2064
c10de5e7 2065/* logical-AND-expression:
2066 inclusive-OR-expression
2067 logical-AND-expression && inclusive-OR-expression */
d7b8e04e 2068
89df180d 2069static void
c10de5e7 2070pp_c_logical_and_expression (c_pretty_printer *pp, tree e)
ba21936b 2071{
37aea014 2072 if (TREE_CODE (e) == TRUTH_ANDIF_EXPR
2073 || TREE_CODE (e) == TRUTH_AND_EXPR)
ba21936b 2074 {
c10de5e7 2075 pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
2076 pp_c_whitespace (pp);
70d60d1d 2077 pp_ampersand_ampersand (pp);
c10de5e7 2078 pp_c_whitespace (pp);
2079 pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
ba21936b 2080 }
2081 else
c10de5e7 2082 pp_c_inclusive_or_expression (pp, e);
ba21936b 2083}
2084
c10de5e7 2085/* logical-OR-expression:
2086 logical-AND-expression
2087 logical-OR-expression || logical-AND-expression */
d7b8e04e 2088
ba21936b 2089void
c10de5e7 2090pp_c_logical_or_expression (c_pretty_printer *pp, tree e)
ba21936b 2091{
37aea014 2092 if (TREE_CODE (e) == TRUTH_ORIF_EXPR
2093 || TREE_CODE (e) == TRUTH_OR_EXPR)
ba21936b 2094 {
c10de5e7 2095 pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
2096 pp_c_whitespace (pp);
70d60d1d 2097 pp_bar_bar (pp);
c10de5e7 2098 pp_c_whitespace (pp);
2099 pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
ba21936b 2100 }
2101 else
c10de5e7 2102 pp_c_logical_and_expression (pp, e);
ba21936b 2103}
2104
c10de5e7 2105/* conditional-expression:
2106 logical-OR-expression
2107 logical-OR-expression ? expression : conditional-expression */
d7b8e04e 2108
30635c2e 2109void
2110c_pretty_printer::conditional_expression (tree e)
ba21936b 2111{
2112 if (TREE_CODE (e) == COND_EXPR)
2113 {
30635c2e 2114 pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
2115 pp_c_whitespace (this);
2116 pp_question (this);
2117 pp_c_whitespace (this);
eaab24b9 2118 expression (TREE_OPERAND (e, 1));
30635c2e 2119 pp_c_whitespace (this);
2120 pp_colon (this);
2121 pp_c_whitespace (this);
2122 conditional_expression (TREE_OPERAND (e, 2));
ba21936b 2123 }
2124 else
30635c2e 2125 pp_c_logical_or_expression (this, e);
ba21936b 2126}
2127
2128
c10de5e7 2129/* assignment-expression:
2130 conditional-expression
b27ac6b5 2131 unary-expression assignment-operator assignment-expression
c10de5e7 2132
2133 assignment-expression: one of
2134 = *= /= %= += -= >>= <<= &= ^= |= */
d7b8e04e 2135
30635c2e 2136void
2137c_pretty_printer::assignment_expression (tree e)
ba21936b 2138{
48e1416a 2139 if (TREE_CODE (e) == MODIFY_EXPR
35cc02b5 2140 || TREE_CODE (e) == INIT_EXPR)
ba21936b 2141 {
30635c2e 2142 unary_expression (TREE_OPERAND (e, 0));
2143 pp_c_whitespace (this);
2144 pp_equal (this);
2145 pp_space (this);
eaab24b9 2146 expression (TREE_OPERAND (e, 1));
ba21936b 2147 }
2148 else
30635c2e 2149 conditional_expression (e);
ba21936b 2150}
2151
c10de5e7 2152/* expression:
2153 assignment-expression
2154 expression , assignment-expression
2155
2156 Implementation note: instead of going through the usual recursion
2157 chain, I take the liberty of dispatching nodes to the appropriate
2158 functions. This makes some redundancy, but it worths it. That also
eaab24b9 2159 prevents a possible infinite recursion between primary_expression ()
2160 and expression (). */
d7b8e04e 2161
ba21936b 2162void
30635c2e 2163c_pretty_printer::expression (tree e)
ba21936b 2164{
2165 switch (TREE_CODE (e))
2166 {
3ab4693e 2167 case VOID_CST:
2168 pp_c_void_constant (this);
2169 break;
2170
ba21936b 2171 case INTEGER_CST:
30635c2e 2172 pp_c_integer_constant (this, e);
ba21936b 2173 break;
2b30d46c 2174
ba21936b 2175 case REAL_CST:
30635c2e 2176 pp_c_floating_constant (this, e);
ba21936b 2177 break;
2178
06f0b99c 2179 case FIXED_CST:
30635c2e 2180 pp_c_fixed_constant (this, e);
06f0b99c 2181 break;
2182
ba21936b 2183 case STRING_CST:
30635c2e 2184 pp_c_string_literal (this, e);
ba21936b 2185 break;
2b30d46c 2186
c10de5e7 2187 case IDENTIFIER_NODE:
ba21936b 2188 case FUNCTION_DECL:
2189 case VAR_DECL:
2190 case CONST_DECL:
2191 case PARM_DECL:
2192 case RESULT_DECL:
2193 case FIELD_DECL:
2194 case LABEL_DECL:
2195 case ERROR_MARK:
30635c2e 2196 primary_expression (e);
ba21936b 2197 break;
2198
6aa221fa 2199 case SSA_NAME:
ec11736b 2200 if (SSA_NAME_VAR (e)
2201 && !DECL_ARTIFICIAL (SSA_NAME_VAR (e)))
30635c2e 2202 expression (SSA_NAME_VAR (e));
6aa221fa 2203 else
30635c2e 2204 translate_string ("<unknown>");
6aa221fa 2205 break;
2206
ba21936b 2207 case POSTINCREMENT_EXPR:
2208 case POSTDECREMENT_EXPR:
2209 case ARRAY_REF:
3c6d4197 2210 case ARRAY_NOTATION_REF:
ba21936b 2211 case CALL_EXPR:
2212 case COMPONENT_REF:
a3efadc7 2213 case BIT_FIELD_REF:
ba21936b 2214 case COMPLEX_CST:
d7b8e04e 2215 case COMPLEX_EXPR:
ba21936b 2216 case VECTOR_CST:
7b85cb4b 2217 case ORDERED_EXPR:
2218 case UNORDERED_EXPR:
2219 case LTGT_EXPR:
2220 case UNEQ_EXPR:
2221 case UNLE_EXPR:
2222 case UNLT_EXPR:
2223 case UNGE_EXPR:
2224 case UNGT_EXPR:
5dadc2ef 2225 case ABS_EXPR:
2226 case CONSTRUCTOR:
219e3838 2227 case COMPOUND_LITERAL_EXPR:
219e3838 2228 case VA_ARG_EXPR:
30635c2e 2229 postfix_expression (e);
ba21936b 2230 break;
2231
5dadc2ef 2232 case CONJ_EXPR:
2233 case ADDR_EXPR:
2234 case INDIRECT_REF:
b0d55af9 2235 case MEM_REF:
5dadc2ef 2236 case NEGATE_EXPR:
2237 case BIT_NOT_EXPR:
2238 case TRUTH_NOT_EXPR:
2239 case PREINCREMENT_EXPR:
2240 case PREDECREMENT_EXPR:
5dadc2ef 2241 case REALPART_EXPR:
2242 case IMAGPART_EXPR:
30635c2e 2243 unary_expression (e);
5dadc2ef 2244 break;
2245
5dadc2ef 2246 case FLOAT_EXPR:
bfdec0d1 2247 case FIX_TRUNC_EXPR:
72dd6141 2248 CASE_CONVERT:
6242196e 2249 case VIEW_CONVERT_EXPR:
30635c2e 2250 pp_c_cast_expression (this, e);
ba21936b 2251 break;
2252
2253 case MULT_EXPR:
2254 case TRUNC_MOD_EXPR:
2255 case TRUNC_DIV_EXPR:
30635c2e 2256 multiplicative_expression (e);
ba21936b 2257 break;
2258
2259 case LSHIFT_EXPR:
2260 case RSHIFT_EXPR:
30635c2e 2261 pp_c_shift_expression (this, e);
ba21936b 2262 break;
2263
2264 case LT_EXPR:
2265 case GT_EXPR:
2266 case LE_EXPR:
2267 case GE_EXPR:
30635c2e 2268 pp_c_relational_expression (this, e);
ba21936b 2269 break;
2270
2271 case BIT_AND_EXPR:
30635c2e 2272 pp_c_and_expression (this, e);
ba21936b 2273 break;
2274
2275 case BIT_XOR_EXPR:
37aea014 2276 case TRUTH_XOR_EXPR:
30635c2e 2277 pp_c_exclusive_or_expression (this, e);
ba21936b 2278 break;
2279
2280 case BIT_IOR_EXPR:
30635c2e 2281 pp_c_inclusive_or_expression (this, e);
ba21936b 2282 break;
2283
2284 case TRUTH_ANDIF_EXPR:
37aea014 2285 case TRUTH_AND_EXPR:
30635c2e 2286 pp_c_logical_and_expression (this, e);
ba21936b 2287 break;
2288
2289 case TRUTH_ORIF_EXPR:
37aea014 2290 case TRUTH_OR_EXPR:
30635c2e 2291 pp_c_logical_or_expression (this, e);
ba21936b 2292 break;
2293
bfdec0d1 2294 case EQ_EXPR:
2295 case NE_EXPR:
30635c2e 2296 pp_c_equality_expression (this, e);
bfdec0d1 2297 break;
b27ac6b5 2298
ba21936b 2299 case COND_EXPR:
30635c2e 2300 conditional_expression (e);
ba21936b 2301 break;
2302
227d73b4 2303 case POINTER_PLUS_EXPR:
bfdec0d1 2304 case PLUS_EXPR:
2305 case MINUS_EXPR:
30635c2e 2306 pp_c_additive_expression (this, e);
ba21936b 2307 break;
2308
bfdec0d1 2309 case MODIFY_EXPR:
2310 case INIT_EXPR:
30635c2e 2311 assignment_expression (e);
ba21936b 2312 break;
2313
2314 case COMPOUND_EXPR:
30635c2e 2315 pp_c_left_paren (this);
2316 expression (TREE_OPERAND (e, 0));
2317 pp_separate_with (this, ',');
2318 assignment_expression (TREE_OPERAND (e, 1));
2319 pp_c_right_paren (this);
ba21936b 2320 break;
2b30d46c 2321
bfdec0d1 2322 case NON_LVALUE_EXPR:
2323 case SAVE_EXPR:
30635c2e 2324 expression (TREE_OPERAND (e, 0));
c10de5e7 2325 break;
2326
2327 case TARGET_EXPR:
30635c2e 2328 postfix_expression (TREE_OPERAND (e, 1));
bfdec0d1 2329 break;
b27ac6b5 2330
f10af3b9 2331 case BIND_EXPR:
8f538fc3 2332 case GOTO_EXPR:
f10af3b9 2333 /* We don't yet have a way of dumping statements in a
2334 human-readable format. */
30635c2e 2335 pp_string (this, "({...})");
f10af3b9 2336 break;
2337
34416a90 2338 case C_MAYBE_CONST_EXPR:
30635c2e 2339 expression (C_MAYBE_CONST_EXPR_EXPR (e));
34416a90 2340 break;
2341
ba21936b 2342 default:
30635c2e 2343 pp_unsupported_tree (this, e);
ba21936b 2344 break;
2345 }
2346}
2347
bfdec0d1 2348
1501e78e 2349\f
2350/* Statements. */
c10de5e7 2351
1501e78e 2352void
c5d35bea 2353c_pretty_printer::statement (tree stmt)
1501e78e 2354{
bfdec0d1 2355 if (stmt == NULL)
2356 return;
dddab69e 2357
c5d35bea 2358 if (pp_needs_newline (this))
2359 pp_newline_and_indent (this, 0);
b27ac6b5 2360
c5d35bea 2361 dump_generic_node (this, stmt, pp_indentation (this), 0, true);
1501e78e 2362}
2363
ed22b9fe 2364\f
2365/* Initialize the PRETTY-PRINTER for handling C codes. */
d7b8e04e 2366
eed6bc21 2367c_pretty_printer::c_pretty_printer ()
eaab24b9 2368 : pretty_printer (),
2369 offset_list (),
2370 flags ()
ed22b9fe 2371{
eed6bc21 2372 type_specifier_seq = pp_c_specifier_qualifier_list;
eed6bc21 2373 ptr_operator = pp_c_pointer;
2374 parameter_list = pp_c_parameter_type_list;
ed22b9fe 2375}
4ee9c684 2376
2377
2378/* Print the tree T in full, on file FILE. */
2379
2380void
2381print_c_tree (FILE *file, tree t)
2382{
f874ddad 2383 c_pretty_printer pp;
eed6bc21 2384
f874ddad 2385 pp_needs_newline (&pp) = true;
2386 pp.buffer->stream = file;
c5d35bea 2387 pp.statement (t);
f874ddad 2388 pp_newline_and_flush (&pp);
4ee9c684 2389}
2390
2391/* Print the tree T in full, on stderr. */
2392
4b987fac 2393DEBUG_FUNCTION void
4ee9c684 2394debug_c_tree (tree t)
2395{
2396 print_c_tree (stderr, t);
2397 fputc ('\n', stderr);
2398}
2399
2400/* Output the DECL_NAME of T. If T has no DECL_NAME, output a string made
2401 up of T's memory address. */
2402
2403void
2404pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
2405{
2406 const char *name;
2407
231bd014 2408 gcc_assert (DECL_P (t));
4ee9c684 2409
2410 if (DECL_NAME (t))
2411 name = IDENTIFIER_POINTER (DECL_NAME (t));
2412 else
2413 {
2414 static char xname[8];
89fc44d1 2415 sprintf (xname, "<U%4x>", ((unsigned)((uintptr_t)(t) & 0xffff)));
4ee9c684 2416 name = xname;
2417 }
2418
2419 pp_c_identifier (pp, name);
2420}