Line data Source code
1 : /* Tree-dumping functionality for intermediate representation.
2 : Copyright (C) 1999-2026 Free Software Foundation, Inc.
3 : Written by Mark Mitchell <mark@codesourcery.com>
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it under
8 : the terms of the GNU General Public License as published by the Free
9 : Software Foundation; either version 3, or (at your option) any later
10 : version.
11 :
12 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "tree.h"
25 : #include "tree-pretty-print.h"
26 : #include "tree-dump.h"
27 : #include "langhooks.h"
28 : #include "tree-iterator.h"
29 :
30 : static unsigned int queue (dump_info_p, const_tree, int);
31 : static void dump_index (dump_info_p, unsigned int);
32 : static void dequeue_and_dump (dump_info_p);
33 : static void dump_new_line (dump_info_p);
34 : static void dump_maybe_newline (dump_info_p);
35 :
36 : /* Add T to the end of the queue of nodes to dump. Returns the index
37 : assigned to T. */
38 :
39 : static unsigned int
40 43329 : queue (dump_info_p di, const_tree t, int flags)
41 : {
42 43329 : dump_queue_p dq;
43 43329 : dump_node_info_p dni;
44 43329 : unsigned int index;
45 :
46 : /* Assign the next available index to T. */
47 43329 : index = ++di->index;
48 :
49 : /* Obtain a new queue node. */
50 43329 : if (di->free_list)
51 : {
52 43166 : dq = di->free_list;
53 43166 : di->free_list = dq->next;
54 : }
55 : else
56 163 : dq = XNEW (struct dump_queue);
57 :
58 : /* Create a new entry in the splay-tree. */
59 43329 : dni = XNEW (struct dump_node_info);
60 43329 : dni->index = index;
61 43329 : dni->binfo_p = ((flags & DUMP_BINFO) != 0);
62 43329 : dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
63 : (splay_tree_value) dni);
64 :
65 : /* Add it to the end of the queue. */
66 43329 : dq->next = 0;
67 43329 : if (!di->queue_end)
68 6244 : di->queue = dq;
69 : else
70 37085 : di->queue_end->next = dq;
71 43329 : di->queue_end = dq;
72 :
73 : /* Return the index. */
74 43329 : return index;
75 : }
76 :
77 : static void
78 133365 : dump_index (dump_info_p di, unsigned int index)
79 : {
80 133365 : fprintf (di->stream, "@%-6u ", index);
81 133365 : di->column += 8;
82 133365 : }
83 :
84 : /* If T has not already been output, queue it for subsequent output.
85 : FIELD is a string to print before printing the index. Then, the
86 : index of T is printed. */
87 :
88 : void
89 114477 : queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
90 : {
91 114477 : unsigned int index;
92 114477 : splay_tree_node n;
93 :
94 : /* If there's no node, just return. This makes for fewer checks in
95 : our callers. */
96 114477 : if (!t)
97 : return;
98 :
99 : /* See if we've already queued or dumped this node. */
100 90036 : n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
101 90036 : if (n)
102 46714 : index = ((dump_node_info_p) n->value)->index;
103 : else
104 : /* If we haven't, add it to the queue. */
105 43322 : index = queue (di, t, flags);
106 :
107 : /* Print the index of the node. */
108 90036 : dump_maybe_newline (di);
109 90036 : fprintf (di->stream, "%-4s: ", field);
110 90036 : di->column += 6;
111 90036 : dump_index (di, index);
112 : }
113 :
114 : /* Dump the type of T. */
115 :
116 : void
117 15620 : queue_and_dump_type (dump_info_p di, const_tree t)
118 : {
119 15620 : queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
120 15620 : }
121 :
122 : /* Dump column control */
123 : #define SOL_COLUMN 25 /* Start of line column. */
124 : #define EOL_COLUMN 55 /* End of line column. */
125 : #define COLUMN_ALIGNMENT 15 /* Alignment. */
126 :
127 : /* Insert a new line in the dump output, and indent to an appropriate
128 : place to start printing more fields. */
129 :
130 : static void
131 55768 : dump_new_line (dump_info_p di)
132 : {
133 55768 : fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
134 55768 : di->column = SOL_COLUMN;
135 55768 : }
136 :
137 : /* If necessary, insert a new line. */
138 :
139 : static void
140 204102 : dump_maybe_newline (dump_info_p di)
141 : {
142 204102 : int extra;
143 :
144 : /* See if we need a new line. */
145 204102 : if (di->column > EOL_COLUMN)
146 55768 : dump_new_line (di);
147 : /* See if we need any padding. */
148 148334 : else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
149 : {
150 102811 : fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
151 102811 : di->column += COLUMN_ALIGNMENT - extra;
152 : }
153 204102 : }
154 :
155 : /* Dump pointer PTR using FIELD to identify it. */
156 :
157 : void
158 0 : dump_pointer (dump_info_p di, const char *field, void *ptr)
159 : {
160 0 : dump_maybe_newline (di);
161 0 : fprintf (di->stream, "%-4s: %-8" HOST_WIDE_INT_PRINT "x ", field,
162 : (unsigned HOST_WIDE_INT) (uintptr_t) ptr);
163 0 : di->column += 15;
164 0 : }
165 :
166 : /* Dump integer I using FIELD to identify it. */
167 :
168 : void
169 22646 : dump_int (dump_info_p di, const char *field, int i)
170 : {
171 22646 : dump_maybe_newline (di);
172 22646 : fprintf (di->stream, "%-4s: %-7d ", field, i);
173 22646 : di->column += 14;
174 22646 : }
175 :
176 : /* Dump the floating point value R, using FIELD to identify it. */
177 :
178 : static void
179 0 : dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
180 : {
181 0 : char buf[32];
182 0 : real_to_decimal (buf, r, sizeof (buf), 0, true);
183 0 : dump_maybe_newline (di);
184 0 : fprintf (di->stream, "%-4s: %s ", field, buf);
185 0 : di->column += strlen (buf) + 7;
186 0 : }
187 :
188 : /* Dump the fixed-point value F, using FIELD to identify it. */
189 :
190 : static void
191 0 : dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
192 : {
193 0 : char buf[32];
194 0 : fixed_to_decimal (buf, f, sizeof (buf));
195 0 : dump_maybe_newline (di);
196 0 : fprintf (di->stream, "%-4s: %s ", field, buf);
197 0 : di->column += strlen (buf) + 7;
198 0 : }
199 :
200 :
201 : /* Dump the string S. */
202 :
203 : void
204 0 : dump_string (dump_info_p di, const char *string)
205 : {
206 0 : dump_maybe_newline (di);
207 0 : fprintf (di->stream, "%-13s ", string);
208 0 : if (strlen (string) > 13)
209 0 : di->column += strlen (string) + 1;
210 : else
211 0 : di->column += 14;
212 0 : }
213 :
214 : /* Dump the string field S. */
215 :
216 : void
217 76534 : dump_string_field (dump_info_p di, const char *field, const char *string)
218 : {
219 76534 : dump_maybe_newline (di);
220 76534 : fprintf (di->stream, "%-4s: %-7s ", field, string);
221 76534 : if (strlen (string) > 7)
222 44060 : di->column += 6 + strlen (string) + 1;
223 : else
224 32474 : di->column += 14;
225 76534 : }
226 :
227 : /* Dump the next node in the queue. */
228 :
229 : static void
230 43329 : dequeue_and_dump (dump_info_p di)
231 : {
232 43329 : dump_queue_p dq;
233 43329 : splay_tree_node stn;
234 43329 : dump_node_info_p dni;
235 43329 : tree t;
236 43329 : unsigned int index;
237 43329 : enum tree_code code;
238 43329 : enum tree_code_class code_class;
239 43329 : const char* code_name;
240 :
241 : /* Get the next node from the queue. */
242 43329 : dq = di->queue;
243 43329 : stn = dq->node;
244 43329 : t = (tree) stn->key;
245 43329 : dni = (dump_node_info_p) stn->value;
246 43329 : index = dni->index;
247 :
248 : /* Remove the node from the queue, and put it on the free list. */
249 43329 : di->queue = dq->next;
250 43329 : if (!di->queue)
251 6244 : di->queue_end = 0;
252 43329 : dq->next = di->free_list;
253 43329 : di->free_list = dq;
254 :
255 : /* Print the node index. */
256 43329 : dump_index (di, index);
257 : /* And the type of node this is. */
258 43329 : if (dni->binfo_p)
259 : code_name = "binfo";
260 : else
261 43302 : code_name = get_tree_code_name (TREE_CODE (t));
262 43329 : fprintf (di->stream, "%-16s ", code_name);
263 43329 : di->column = 25;
264 :
265 : /* Figure out what kind of node this is. */
266 43329 : code = TREE_CODE (t);
267 43329 : code_class = TREE_CODE_CLASS (code);
268 :
269 : /* Although BINFOs are TREE_VECs, we dump them specially so as to be
270 : more informative. */
271 43329 : if (dni->binfo_p)
272 : {
273 27 : unsigned ix;
274 27 : tree base;
275 27 : vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
276 :
277 27 : dump_child ("type", BINFO_TYPE (t));
278 :
279 27 : if (BINFO_VIRTUAL_P (t))
280 0 : dump_string_field (di, "spec", "virt");
281 :
282 27 : dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
283 30 : for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
284 : {
285 3 : tree access = (accesses ? (*accesses)[ix] : access_public_node);
286 3 : const char *string = NULL;
287 :
288 3 : if (access == access_public_node)
289 : string = "pub";
290 0 : else if (access == access_protected_node)
291 : string = "prot";
292 0 : else if (access == access_private_node)
293 : string = "priv";
294 : else
295 0 : gcc_unreachable ();
296 :
297 3 : dump_string_field (di, "accs", string);
298 3 : queue_and_dump_index (di, "binf", base, DUMP_BINFO);
299 : }
300 :
301 27 : goto done;
302 : }
303 :
304 : /* We can knock off a bunch of expression nodes in exactly the same
305 : way. */
306 43302 : if (IS_EXPR_CODE_CLASS (code_class))
307 : {
308 : /* If we're dumping children, dump them now. */
309 275 : queue_and_dump_type (di, t);
310 :
311 275 : switch (code_class)
312 : {
313 67 : case tcc_unary:
314 67 : dump_child ("op 0", TREE_OPERAND (t, 0));
315 67 : break;
316 :
317 22 : case tcc_binary:
318 22 : case tcc_comparison:
319 22 : dump_child ("op 0", TREE_OPERAND (t, 0));
320 22 : dump_child ("op 1", TREE_OPERAND (t, 1));
321 22 : break;
322 :
323 : case tcc_expression:
324 : case tcc_reference:
325 : case tcc_statement:
326 : case tcc_vl_exp:
327 : /* These nodes are handled explicitly below. */
328 : break;
329 :
330 : default:
331 : gcc_unreachable ();
332 : }
333 : }
334 43027 : else if (DECL_P (t))
335 : {
336 15038 : expanded_location xloc;
337 : /* All declarations have names. */
338 15038 : if (DECL_NAME (t))
339 14944 : dump_child ("name", DECL_NAME (t));
340 15038 : if (HAS_DECL_ASSEMBLER_NAME_P (t)
341 14890 : && DECL_ASSEMBLER_NAME_SET_P (t)
342 21279 : && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
343 6034 : dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
344 15038 : if (DECL_ABSTRACT_ORIGIN (t))
345 53 : dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
346 : /* And types. */
347 15038 : queue_and_dump_type (di, t);
348 15038 : dump_child ("scpe", DECL_CONTEXT (t));
349 : /* And a source position. */
350 15038 : xloc = expand_location (DECL_SOURCE_LOCATION (t));
351 15038 : if (xloc.file)
352 : {
353 14886 : const char *filename = lbasename (xloc.file);
354 :
355 14886 : dump_maybe_newline (di);
356 14886 : fprintf (di->stream, "srcp: %s:%-6d ", filename,
357 : xloc.line);
358 14886 : di->column += 6 + strlen (filename) + 8;
359 : }
360 : /* And any declaration can be compiler-generated. */
361 15038 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
362 15038 : && DECL_ARTIFICIAL (t))
363 14765 : dump_string_field (di, "note", "artificial");
364 15038 : if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
365 14707 : dump_child ("chain", DECL_CHAIN (t));
366 : }
367 27989 : else if (code_class == tcc_type)
368 : {
369 : /* All types have qualifiers. */
370 4148 : int quals = lang_hooks.tree_dump.type_quals (t);
371 :
372 4148 : if (quals != TYPE_UNQUALIFIED)
373 : {
374 99 : fprintf (di->stream, "qual: %c%c%c ",
375 99 : (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
376 99 : (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
377 99 : (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
378 99 : di->column += 14;
379 : }
380 :
381 : /* All types have associated declarations. */
382 4148 : dump_child ("name", TYPE_NAME (t));
383 :
384 : /* All types have a main variant. */
385 4148 : if (TYPE_MAIN_VARIANT (t) != t)
386 200 : dump_child ("unql", TYPE_MAIN_VARIANT (t));
387 :
388 : /* And sizes. */
389 4148 : dump_child ("size", TYPE_SIZE (t));
390 :
391 : /* All types have alignments. */
392 4148 : dump_int (di, "algn", TYPE_ALIGN (t));
393 : }
394 23841 : else if (code_class == tcc_constant)
395 : /* All constants can have types. */
396 307 : queue_and_dump_type (di, t);
397 :
398 : /* Give the language-specific code a chance to print something. If
399 : it's completely taken care of things, don't bother printing
400 : anything more ourselves. */
401 43302 : if (lang_hooks.tree_dump.dump_tree (di, t))
402 27 : goto done;
403 :
404 : /* Now handle the various kinds of nodes. */
405 43275 : switch (code)
406 : {
407 17905 : int i;
408 :
409 17905 : case IDENTIFIER_NODE:
410 17905 : dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
411 17905 : dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
412 17905 : break;
413 :
414 5566 : case TREE_LIST:
415 5566 : dump_child ("purp", TREE_PURPOSE (t));
416 5566 : dump_child ("valu", TREE_VALUE (t));
417 5566 : dump_child ("chan", TREE_CHAIN (t));
418 5566 : break;
419 :
420 16 : case STATEMENT_LIST:
421 16 : {
422 16 : tree_stmt_iterator it;
423 37 : for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
424 : {
425 21 : char buffer[32];
426 21 : sprintf (buffer, "%u", i);
427 21 : dump_child (buffer, tsi_stmt (it));
428 : }
429 : }
430 16 : break;
431 :
432 0 : case TREE_VEC:
433 0 : dump_int (di, "lngt", TREE_VEC_LENGTH (t));
434 0 : for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
435 : {
436 0 : char buffer[32];
437 0 : sprintf (buffer, "%u", i);
438 0 : dump_child (buffer, TREE_VEC_ELT (t, i));
439 : }
440 : break;
441 :
442 132 : case INTEGER_TYPE:
443 132 : case ENUMERAL_TYPE:
444 132 : dump_int (di, "prec", TYPE_PRECISION (t));
445 132 : dump_string_field (di, "sign",
446 132 : TYPE_UNSIGNED (t) ? "unsigned" : "signed");
447 132 : dump_child ("min", TYPE_MIN_VALUE (t));
448 132 : dump_child ("max", TYPE_MAX_VALUE (t));
449 :
450 132 : if (code == ENUMERAL_TYPE)
451 4 : dump_child ("csts", TYPE_VALUES (t));
452 : break;
453 :
454 102 : case REAL_TYPE:
455 102 : dump_int (di, "prec", TYPE_PRECISION (t));
456 102 : break;
457 :
458 0 : case FIXED_POINT_TYPE:
459 0 : dump_int (di, "prec", TYPE_PRECISION (t));
460 0 : dump_string_field (di, "sign",
461 0 : TYPE_UNSIGNED (t) ? "unsigned" : "signed");
462 0 : dump_string_field (di, "saturating",
463 0 : TYPE_SATURATING (t)
464 : ? "saturating" : "non-saturating");
465 0 : break;
466 :
467 294 : case POINTER_TYPE:
468 294 : dump_child ("ptd", TREE_TYPE (t));
469 294 : break;
470 :
471 14 : case REFERENCE_TYPE:
472 14 : dump_child ("refd", TREE_TYPE (t));
473 14 : break;
474 :
475 30 : case METHOD_TYPE:
476 30 : dump_child ("clas", TYPE_METHOD_BASETYPE (t));
477 : /* Fall through. */
478 :
479 3263 : case FUNCTION_TYPE:
480 3263 : dump_child ("retn", TREE_TYPE (t));
481 3263 : dump_child ("prms", TYPE_ARG_TYPES (t));
482 3263 : break;
483 :
484 48 : case ARRAY_TYPE:
485 48 : dump_child ("elts", TREE_TYPE (t));
486 48 : dump_child ("domn", TYPE_DOMAIN (t));
487 48 : break;
488 :
489 63 : case RECORD_TYPE:
490 63 : case UNION_TYPE:
491 63 : if (TREE_CODE (t) == RECORD_TYPE)
492 63 : dump_string_field (di, "tag", "struct");
493 : else
494 0 : dump_string_field (di, "tag", "union");
495 :
496 63 : dump_child ("flds", TYPE_FIELDS (t));
497 63 : queue_and_dump_index (di, "binf", TYPE_BINFO (t),
498 : DUMP_BINFO);
499 63 : break;
500 :
501 0 : case CONST_DECL:
502 0 : dump_child ("cnst", DECL_INITIAL (t));
503 0 : break;
504 :
505 0 : case DEBUG_EXPR_DECL:
506 0 : dump_int (di, "-uid", DEBUG_TEMP_UID (t));
507 : /* Fall through. */
508 :
509 175 : case VAR_DECL:
510 175 : case PARM_DECL:
511 175 : case FIELD_DECL:
512 175 : case RESULT_DECL:
513 175 : if (TREE_CODE (t) == PARM_DECL)
514 78 : dump_child ("argt", DECL_ARG_TYPE (t));
515 : else
516 97 : dump_child ("init", DECL_INITIAL (t));
517 175 : dump_child ("size", DECL_SIZE (t));
518 175 : dump_int (di, "algn", DECL_ALIGN (t));
519 :
520 175 : if (TREE_CODE (t) == FIELD_DECL)
521 : {
522 60 : if (DECL_FIELD_OFFSET (t))
523 60 : dump_child ("bpos", bit_position (t));
524 : }
525 115 : else if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
526 : {
527 111 : dump_int (di, "used", TREE_USED (t));
528 111 : if (DECL_REGISTER (t))
529 0 : dump_string_field (di, "spec", "register");
530 : }
531 : break;
532 :
533 14485 : case FUNCTION_DECL:
534 14485 : dump_child ("args", DECL_ARGUMENTS (t));
535 14485 : if (DECL_EXTERNAL (t))
536 14451 : dump_string_field (di, "body", "undefined");
537 14485 : if (TREE_PUBLIC (t))
538 14485 : dump_string_field (di, "link", "extern");
539 : else
540 0 : dump_string_field (di, "link", "static");
541 14485 : if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
542 33 : dump_child ("body", DECL_SAVED_TREE (t));
543 : break;
544 :
545 295 : case INTEGER_CST:
546 295 : fprintf (di->stream, "int: ");
547 295 : print_decs (wi::to_wide (t), di->stream);
548 295 : break;
549 :
550 6 : case STRING_CST:
551 6 : fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
552 6 : dump_int (di, "lngt", TREE_STRING_LENGTH (t));
553 6 : break;
554 :
555 0 : case REAL_CST:
556 0 : dump_real (di, "valu", TREE_REAL_CST_PTR (t));
557 0 : break;
558 :
559 0 : case FIXED_CST:
560 0 : dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
561 0 : break;
562 :
563 91 : case TRUTH_NOT_EXPR:
564 91 : case ADDR_EXPR:
565 91 : case INDIRECT_REF:
566 91 : case CLEANUP_POINT_EXPR:
567 91 : case VIEW_CONVERT_EXPR:
568 91 : case SAVE_EXPR:
569 91 : case REALPART_EXPR:
570 91 : case IMAGPART_EXPR:
571 : /* These nodes are unary, but do not have code class `1'. */
572 91 : dump_child ("op 0", TREE_OPERAND (t, 0));
573 91 : break;
574 :
575 16 : case TRUTH_ANDIF_EXPR:
576 16 : case TRUTH_ORIF_EXPR:
577 16 : case INIT_EXPR:
578 16 : case MODIFY_EXPR:
579 16 : case COMPOUND_EXPR:
580 16 : case PREDECREMENT_EXPR:
581 16 : case PREINCREMENT_EXPR:
582 16 : case POSTDECREMENT_EXPR:
583 16 : case POSTINCREMENT_EXPR:
584 : /* These nodes are binary, but do not have code class `2'. */
585 16 : dump_child ("op 0", TREE_OPERAND (t, 0));
586 16 : dump_child ("op 1", TREE_OPERAND (t, 1));
587 16 : break;
588 :
589 14 : case COMPONENT_REF:
590 14 : case BIT_FIELD_REF:
591 14 : dump_child ("op 0", TREE_OPERAND (t, 0));
592 14 : dump_child ("op 1", TREE_OPERAND (t, 1));
593 14 : dump_child ("op 2", TREE_OPERAND (t, 2));
594 14 : break;
595 :
596 0 : case ARRAY_REF:
597 0 : case ARRAY_RANGE_REF:
598 0 : dump_child ("op 0", TREE_OPERAND (t, 0));
599 0 : dump_child ("op 1", TREE_OPERAND (t, 1));
600 0 : dump_child ("op 2", TREE_OPERAND (t, 2));
601 0 : dump_child ("op 3", TREE_OPERAND (t, 3));
602 0 : break;
603 :
604 0 : case COND_EXPR:
605 0 : dump_child ("op 0", TREE_OPERAND (t, 0));
606 0 : dump_child ("op 1", TREE_OPERAND (t, 1));
607 0 : dump_child ("op 2", TREE_OPERAND (t, 2));
608 0 : break;
609 :
610 6 : case TRY_FINALLY_EXPR:
611 6 : case EH_ELSE_EXPR:
612 6 : dump_child ("op 0", TREE_OPERAND (t, 0));
613 6 : dump_child ("op 1", TREE_OPERAND (t, 1));
614 6 : break;
615 :
616 13 : case CALL_EXPR:
617 13 : {
618 13 : int i = 0;
619 13 : tree arg;
620 13 : call_expr_arg_iterator iter;
621 13 : dump_child ("fn", CALL_EXPR_FN (t));
622 28 : FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
623 : {
624 15 : char buffer[32];
625 15 : sprintf (buffer, "%u", i);
626 15 : dump_child (buffer, arg);
627 15 : i++;
628 : }
629 : }
630 13 : break;
631 :
632 23 : case CONSTRUCTOR:
633 23 : {
634 23 : unsigned HOST_WIDE_INT cnt;
635 23 : tree index, value;
636 23 : dump_int (di, "lngt", CONSTRUCTOR_NELTS (t));
637 90 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
638 : {
639 44 : dump_child ("idx", index);
640 44 : dump_child ("val", value);
641 : }
642 : }
643 : break;
644 :
645 12 : case BIND_EXPR:
646 12 : dump_child ("vars", TREE_OPERAND (t, 0));
647 12 : dump_child ("body", TREE_OPERAND (t, 1));
648 12 : break;
649 :
650 0 : case LOOP_EXPR:
651 0 : dump_child ("body", TREE_OPERAND (t, 0));
652 0 : break;
653 :
654 0 : case EXIT_EXPR:
655 0 : dump_child ("cond", TREE_OPERAND (t, 0));
656 0 : break;
657 :
658 5 : case RETURN_EXPR:
659 5 : dump_child ("expr", TREE_OPERAND (t, 0));
660 5 : break;
661 :
662 0 : case TARGET_EXPR:
663 0 : dump_child ("decl", TREE_OPERAND (t, 0));
664 0 : dump_child ("init", TREE_OPERAND (t, 1));
665 0 : dump_child ("clnp", TREE_OPERAND (t, 2));
666 : /* There really are two possible places the initializer can be.
667 : After RTL expansion, the second operand is moved to the
668 : position of the fourth operand, and the second operand
669 : becomes NULL. */
670 0 : dump_child ("init", TREE_OPERAND (t, 3));
671 0 : break;
672 :
673 0 : case CASE_LABEL_EXPR:
674 0 : dump_child ("name", CASE_LABEL (t));
675 0 : if (CASE_LOW (t))
676 : {
677 0 : dump_child ("low ", CASE_LOW (t));
678 0 : if (CASE_HIGH (t))
679 0 : dump_child ("high", CASE_HIGH (t));
680 : }
681 : break;
682 0 : case LABEL_EXPR:
683 0 : dump_child ("name", TREE_OPERAND (t,0));
684 0 : break;
685 0 : case GOTO_EXPR:
686 0 : dump_child ("labl", TREE_OPERAND (t, 0));
687 0 : break;
688 0 : case SWITCH_EXPR:
689 0 : dump_child ("cond", TREE_OPERAND (t, 0));
690 0 : dump_child ("body", TREE_OPERAND (t, 1));
691 0 : break;
692 0 : case OMP_CLAUSE:
693 0 : {
694 0 : int i;
695 0 : fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
696 0 : for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
697 0 : dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
698 : }
699 : break;
700 :
701 6 : case OBJ_TYPE_REF:
702 6 : dump_child ("expr", OBJ_TYPE_REF_EXPR (t));
703 6 : dump_child ("obj", OBJ_TYPE_REF_OBJECT (t));
704 6 : dump_child ("tok", OBJ_TYPE_REF_TOKEN (t));
705 6 : break;
706 :
707 : default:
708 : /* There are no additional fields to print. */
709 : break;
710 : }
711 :
712 43329 : done:
713 43329 : if (dump_flag (di, TDF_ADDRESS, NULL))
714 0 : dump_pointer (di, "addr", (void *)t);
715 :
716 : /* Terminate the line. */
717 43329 : fprintf (di->stream, "\n");
718 43329 : }
719 :
720 : /* Return nonzero if FLAG has been specified for the dump, and NODE
721 : is not the root node of the dump. */
722 :
723 58145 : int dump_flag (dump_info_p di, dump_flags_t flag, const_tree node)
724 : {
725 58145 : return (di->flags & flag) && (node != di->node);
726 : }
727 :
728 : /* Dump T, and all its children, on STREAM. */
729 :
730 : void
731 7 : dump_node (const_tree t, dump_flags_t flags, FILE *stream)
732 : {
733 7 : struct dump_info di;
734 7 : dump_queue_p dq;
735 7 : dump_queue_p next_dq;
736 :
737 : /* Initialize the dump-information structure. */
738 7 : di.stream = stream;
739 7 : di.index = 0;
740 7 : di.column = 0;
741 7 : di.queue = 0;
742 7 : di.queue_end = 0;
743 7 : di.free_list = 0;
744 7 : di.flags = flags;
745 7 : di.node = t;
746 7 : di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
747 : splay_tree_delete_pointers);
748 :
749 : /* Queue up the first node. */
750 7 : queue (&di, t, DUMP_NONE);
751 :
752 : /* Until the queue is empty, keep dumping nodes. */
753 43343 : while (di.queue)
754 43329 : dequeue_and_dump (&di);
755 :
756 : /* Now, clean up. */
757 170 : for (dq = di.free_list; dq; dq = next_dq)
758 : {
759 163 : next_dq = dq->next;
760 163 : free (dq);
761 : }
762 7 : splay_tree_delete (di.nodes);
763 7 : }
|