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