Branch data Line data Source code
1 : : /* Tree-dumping functionality for intermediate representation.
2 : : Copyright (C) 1999-2025 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 : 42110 : queue (dump_info_p di, const_tree t, int flags)
41 : : {
42 : 42110 : dump_queue_p dq;
43 : 42110 : dump_node_info_p dni;
44 : 42110 : unsigned int index;
45 : :
46 : : /* Assign the next available index to T. */
47 : 42110 : index = ++di->index;
48 : :
49 : : /* Obtain a new queue node. */
50 : 42110 : if (di->free_list)
51 : : {
52 : 41943 : dq = di->free_list;
53 : 41943 : di->free_list = dq->next;
54 : : }
55 : : else
56 : 167 : dq = XNEW (struct dump_queue);
57 : :
58 : : /* Create a new entry in the splay-tree. */
59 : 42110 : dni = XNEW (struct dump_node_info);
60 : 42110 : dni->index = index;
61 : 42110 : dni->binfo_p = ((flags & DUMP_BINFO) != 0);
62 : 42110 : 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 : 42110 : dq->next = 0;
67 : 42110 : if (!di->queue_end)
68 : 5852 : di->queue = dq;
69 : : else
70 : 36258 : di->queue_end->next = dq;
71 : 42110 : di->queue_end = dq;
72 : :
73 : : /* Return the index. */
74 : 42110 : return index;
75 : : }
76 : :
77 : : static void
78 : 130099 : dump_index (dump_info_p di, unsigned int index)
79 : : {
80 : 130099 : fprintf (di->stream, "@%-6u ", index);
81 : 130099 : di->column += 8;
82 : 130099 : }
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 : 111982 : queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
90 : : {
91 : 111982 : unsigned int index;
92 : 111982 : splay_tree_node n;
93 : :
94 : : /* If there's no node, just return. This makes for fewer checks in
95 : : our callers. */
96 : 111982 : if (!t)
97 : : return;
98 : :
99 : : /* See if we've already queued or dumped this node. */
100 : 87989 : n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
101 : 87989 : if (n)
102 : 45886 : index = ((dump_node_info_p) n->value)->index;
103 : : else
104 : : /* If we haven't, add it to the queue. */
105 : 42103 : index = queue (di, t, flags);
106 : :
107 : : /* Print the index of the node. */
108 : 87989 : dump_maybe_newline (di);
109 : 87989 : fprintf (di->stream, "%-4s: ", field);
110 : 87989 : di->column += 6;
111 : 87989 : dump_index (di, index);
112 : : }
113 : :
114 : : /* Dump the type of T. */
115 : :
116 : : void
117 : 15217 : queue_and_dump_type (dump_info_p di, const_tree t)
118 : : {
119 : 15217 : queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
120 : 15217 : }
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 : 54140 : dump_new_line (dump_info_p di)
132 : : {
133 : 54140 : fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
134 : 54140 : di->column = SOL_COLUMN;
135 : 54140 : }
136 : :
137 : : /* If necessary, insert a new line. */
138 : :
139 : : static void
140 : 198431 : dump_maybe_newline (dump_info_p di)
141 : : {
142 : 198431 : int extra;
143 : :
144 : : /* See if we need a new line. */
145 : 198431 : if (di->column > EOL_COLUMN)
146 : 54140 : dump_new_line (di);
147 : : /* See if we need any padding. */
148 : 144291 : else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
149 : : {
150 : 100047 : fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
151 : 100047 : di->column += COLUMN_ALIGNMENT - extra;
152 : : }
153 : 198431 : }
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 : 21844 : dump_int (dump_info_p di, const char *field, int i)
170 : : {
171 : 21844 : dump_maybe_newline (di);
172 : 21844 : fprintf (di->stream, "%-4s: %-7d ", field, i);
173 : 21844 : di->column += 14;
174 : 21844 : }
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 : 74118 : dump_string_field (dump_info_p di, const char *field, const char *string)
218 : : {
219 : 74118 : dump_maybe_newline (di);
220 : 74118 : fprintf (di->stream, "%-4s: %-7s ", field, string);
221 : 74118 : if (strlen (string) > 7)
222 : 42576 : di->column += 6 + strlen (string) + 1;
223 : : else
224 : 31542 : di->column += 14;
225 : 74118 : }
226 : :
227 : : /* Dump the next node in the queue. */
228 : :
229 : : static void
230 : 42110 : dequeue_and_dump (dump_info_p di)
231 : : {
232 : 42110 : dump_queue_p dq;
233 : 42110 : splay_tree_node stn;
234 : 42110 : dump_node_info_p dni;
235 : 42110 : tree t;
236 : 42110 : unsigned int index;
237 : 42110 : enum tree_code code;
238 : 42110 : enum tree_code_class code_class;
239 : 42110 : const char* code_name;
240 : :
241 : : /* Get the next node from the queue. */
242 : 42110 : dq = di->queue;
243 : 42110 : stn = dq->node;
244 : 42110 : t = (tree) stn->key;
245 : 42110 : dni = (dump_node_info_p) stn->value;
246 : 42110 : index = dni->index;
247 : :
248 : : /* Remove the node from the queue, and put it on the free list. */
249 : 42110 : di->queue = dq->next;
250 : 42110 : if (!di->queue)
251 : 5852 : di->queue_end = 0;
252 : 42110 : dq->next = di->free_list;
253 : 42110 : di->free_list = dq;
254 : :
255 : : /* Print the node index. */
256 : 42110 : dump_index (di, index);
257 : : /* And the type of node this is. */
258 : 42110 : if (dni->binfo_p)
259 : : code_name = "binfo";
260 : : else
261 : 42083 : code_name = get_tree_code_name (TREE_CODE (t));
262 : 42110 : fprintf (di->stream, "%-16s ", code_name);
263 : 42110 : di->column = 25;
264 : :
265 : : /* Figure out what kind of node this is. */
266 : 42110 : code = TREE_CODE (t);
267 : 42110 : 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 : 42110 : 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 : 42083 : 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 : 41808 : else if (DECL_P (t))
335 : : {
336 : 14632 : expanded_location xloc;
337 : : /* All declarations have names. */
338 : 14632 : if (DECL_NAME (t))
339 : 14538 : dump_child ("name", DECL_NAME (t));
340 : 14632 : if (HAS_DECL_ASSEMBLER_NAME_P (t)
341 : 14484 : && DECL_ASSEMBLER_NAME_SET_P (t)
342 : 20487 : && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
343 : 5648 : dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
344 : 14632 : if (DECL_ABSTRACT_ORIGIN (t))
345 : 53 : dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
346 : : /* And types. */
347 : 14632 : queue_and_dump_type (di, t);
348 : 14632 : dump_child ("scpe", DECL_CONTEXT (t));
349 : : /* And a source position. */
350 : 14632 : xloc = expand_location (DECL_SOURCE_LOCATION (t));
351 : 14632 : if (xloc.file)
352 : : {
353 : 14480 : const char *filename = lbasename (xloc.file);
354 : :
355 : 14480 : dump_maybe_newline (di);
356 : 14480 : fprintf (di->stream, "srcp: %s:%-6d ", filename,
357 : : xloc.line);
358 : 14480 : di->column += 6 + strlen (filename) + 8;
359 : : }
360 : : /* And any declaration can be compiler-generated. */
361 : 14632 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
362 : 14632 : && DECL_ARTIFICIAL (t))
363 : 14359 : dump_string_field (di, "note", "artificial");
364 : 14632 : if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
365 : 14301 : dump_child ("chain", DECL_CHAIN (t));
366 : : }
367 : 27176 : else if (code_class == tcc_type)
368 : : {
369 : : /* All types have qualifiers. */
370 : 4138 : int quals = lang_hooks.tree_dump.type_quals (t);
371 : :
372 : 4138 : 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 : 4138 : dump_child ("name", TYPE_NAME (t));
383 : :
384 : : /* All types have a main variant. */
385 : 4138 : if (TYPE_MAIN_VARIANT (t) != t)
386 : 200 : dump_child ("unql", TYPE_MAIN_VARIANT (t));
387 : :
388 : : /* And sizes. */
389 : 4138 : dump_child ("size", TYPE_SIZE (t));
390 : :
391 : : /* All types have alignments. */
392 : 4138 : dump_int (di, "algn", TYPE_ALIGN (t));
393 : : }
394 : 23038 : else if (code_class == tcc_constant)
395 : : /* All constants can have types. */
396 : 310 : 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 : 42083 : if (lang_hooks.tree_dump.dump_tree (di, t))
402 : 27 : goto done;
403 : :
404 : : /* Now handle the various kinds of nodes. */
405 : 42056 : switch (code)
406 : : {
407 : 17113 : int i;
408 : :
409 : 17113 : case IDENTIFIER_NODE:
410 : 17113 : dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
411 : 17113 : dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
412 : 17113 : break;
413 : :
414 : 5552 : case TREE_LIST:
415 : 5552 : dump_child ("purp", TREE_PURPOSE (t));
416 : 5552 : dump_child ("valu", TREE_VALUE (t));
417 : 5552 : dump_child ("chan", TREE_CHAIN (t));
418 : 5552 : 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 : 3253 : case FUNCTION_TYPE:
480 : 3253 : dump_child ("retn", TREE_TYPE (t));
481 : 3253 : dump_child ("prms", TYPE_ARG_TYPES (t));
482 : 3253 : 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 : 14079 : case FUNCTION_DECL:
534 : 14079 : dump_child ("args", DECL_ARGUMENTS (t));
535 : 14079 : if (DECL_EXTERNAL (t))
536 : 14045 : dump_string_field (di, "body", "undefined");
537 : 14079 : if (TREE_PUBLIC (t))
538 : 14079 : dump_string_field (di, "link", "extern");
539 : : else
540 : 0 : dump_string_field (di, "link", "static");
541 : 14079 : if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
542 : 33 : dump_child ("body", DECL_SAVED_TREE (t));
543 : : break;
544 : :
545 : 298 : case INTEGER_CST:
546 : 298 : fprintf (di->stream, "int: ");
547 : 298 : print_decs (wi::to_wide (t), di->stream);
548 : 298 : 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 : 42110 : done:
713 : 42110 : if (dump_flag (di, TDF_ADDRESS, NULL))
714 : 0 : dump_pointer (di, "addr", (void *)t);
715 : :
716 : : /* Terminate the line. */
717 : 42110 : fprintf (di->stream, "\n");
718 : 42110 : }
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 : 56520 : int dump_flag (dump_info_p di, dump_flags_t flag, const_tree node)
724 : : {
725 : 56520 : 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 : 42124 : while (di.queue)
754 : 42110 : dequeue_and_dump (&di);
755 : :
756 : : /* Now, clean up. */
757 : 174 : for (dq = di.free_list; dq; dq = next_dq)
758 : : {
759 : 167 : next_dq = dq->next;
760 : 167 : free (dq);
761 : : }
762 : 7 : splay_tree_delete (di.nodes);
763 : 7 : }
|