Branch data Line data Source code
1 : : /* Tree-dumping functionality for intermediate representation.
2 : : Copyright (C) 1999-2024 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 : 27543 : queue (dump_info_p di, const_tree t, int flags)
41 : : {
42 : 27543 : dump_queue_p dq;
43 : 27543 : dump_node_info_p dni;
44 : 27543 : unsigned int index;
45 : :
46 : : /* Assign the next available index to T. */
47 : 27543 : index = ++di->index;
48 : :
49 : : /* Obtain a new queue node. */
50 : 27543 : if (di->free_list)
51 : : {
52 : 27433 : dq = di->free_list;
53 : 27433 : di->free_list = dq->next;
54 : : }
55 : : else
56 : 110 : dq = XNEW (struct dump_queue);
57 : :
58 : : /* Create a new entry in the splay-tree. */
59 : 27543 : dni = XNEW (struct dump_node_info);
60 : 27543 : dni->index = index;
61 : 27543 : dni->binfo_p = ((flags & DUMP_BINFO) != 0);
62 : 27543 : 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 : 27543 : dq->next = 0;
67 : 27543 : if (!di->queue_end)
68 : 4049 : di->queue = dq;
69 : : else
70 : 23494 : di->queue_end->next = dq;
71 : 27543 : di->queue_end = dq;
72 : :
73 : : /* Return the index. */
74 : 27543 : return index;
75 : : }
76 : :
77 : : static void
78 : 85430 : dump_index (dump_info_p di, unsigned int index)
79 : : {
80 : 85430 : fprintf (di->stream, "@%-6u ", index);
81 : 85430 : di->column += 8;
82 : 85430 : }
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 : 73638 : queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
90 : : {
91 : 73638 : unsigned int index;
92 : 73638 : splay_tree_node n;
93 : :
94 : : /* If there's no node, just return. This makes for fewer checks in
95 : : our callers. */
96 : 73638 : if (!t)
97 : : return;
98 : :
99 : : /* See if we've already queued or dumped this node. */
100 : 57887 : n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
101 : 57887 : if (n)
102 : 30349 : index = ((dump_node_info_p) n->value)->index;
103 : : else
104 : : /* If we haven't, add it to the queue. */
105 : 27538 : index = queue (di, t, flags);
106 : :
107 : : /* Print the index of the node. */
108 : 57887 : dump_maybe_newline (di);
109 : 57887 : fprintf (di->stream, "%-4s: ", field);
110 : 57887 : di->column += 6;
111 : 57887 : dump_index (di, index);
112 : : }
113 : :
114 : : /* Dump the type of T. */
115 : :
116 : : void
117 : 10045 : queue_and_dump_type (dump_info_p di, const_tree t)
118 : : {
119 : 10045 : queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
120 : 10045 : }
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 : 35688 : dump_new_line (dump_info_p di)
132 : : {
133 : 35688 : fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
134 : 35688 : di->column = SOL_COLUMN;
135 : 35688 : }
136 : :
137 : : /* If necessary, insert a new line. */
138 : :
139 : : static void
140 : 130640 : dump_maybe_newline (dump_info_p di)
141 : : {
142 : 130640 : int extra;
143 : :
144 : : /* See if we need a new line. */
145 : 130640 : if (di->column > EOL_COLUMN)
146 : 35688 : dump_new_line (di);
147 : : /* See if we need any padding. */
148 : 94952 : else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
149 : : {
150 : 66008 : fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
151 : 66008 : di->column += COLUMN_ALIGNMENT - extra;
152 : : }
153 : 130640 : }
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 : 14251 : dump_int (dump_info_p di, const char *field, int i)
170 : : {
171 : 14251 : dump_maybe_newline (di);
172 : 14251 : fprintf (di->stream, "%-4s: %-7d ", field, i);
173 : 14251 : di->column += 14;
174 : 14251 : }
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 : 48910 : dump_string_field (dump_info_p di, const char *field, const char *string)
218 : : {
219 : 48910 : dump_maybe_newline (di);
220 : 48910 : fprintf (di->stream, "%-4s: %-7s ", field, string);
221 : 48910 : if (strlen (string) > 7)
222 : 27999 : di->column += 6 + strlen (string) + 1;
223 : : else
224 : 20911 : di->column += 14;
225 : 48910 : }
226 : :
227 : : /* Dump the next node in the queue. */
228 : :
229 : : static void
230 : 27543 : dequeue_and_dump (dump_info_p di)
231 : : {
232 : 27543 : dump_queue_p dq;
233 : 27543 : splay_tree_node stn;
234 : 27543 : dump_node_info_p dni;
235 : 27543 : tree t;
236 : 27543 : unsigned int index;
237 : 27543 : enum tree_code code;
238 : 27543 : enum tree_code_class code_class;
239 : 27543 : const char* code_name;
240 : :
241 : : /* Get the next node from the queue. */
242 : 27543 : dq = di->queue;
243 : 27543 : stn = dq->node;
244 : 27543 : t = (tree) stn->key;
245 : 27543 : dni = (dump_node_info_p) stn->value;
246 : 27543 : index = dni->index;
247 : :
248 : : /* Remove the node from the queue, and put it on the free list. */
249 : 27543 : di->queue = dq->next;
250 : 27543 : if (!di->queue)
251 : 4049 : di->queue_end = 0;
252 : 27543 : dq->next = di->free_list;
253 : 27543 : di->free_list = dq;
254 : :
255 : : /* Print the node index. */
256 : 27543 : dump_index (di, index);
257 : : /* And the type of node this is. */
258 : 27543 : if (dni->binfo_p)
259 : : code_name = "binfo";
260 : : else
261 : 27519 : code_name = get_tree_code_name (TREE_CODE (t));
262 : 27543 : fprintf (di->stream, "%-16s ", code_name);
263 : 27543 : di->column = 25;
264 : :
265 : : /* Figure out what kind of node this is. */
266 : 27543 : code = TREE_CODE (t);
267 : 27543 : 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 : 27543 : if (dni->binfo_p)
272 : : {
273 : 24 : unsigned ix;
274 : 24 : tree base;
275 : 24 : vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (t);
276 : :
277 : 24 : dump_child ("type", BINFO_TYPE (t));
278 : :
279 : 24 : if (BINFO_VIRTUAL_P (t))
280 : 0 : dump_string_field (di, "spec", "virt");
281 : :
282 : 24 : dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
283 : 28 : for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
284 : : {
285 : 4 : tree access = (accesses ? (*accesses)[ix] : access_public_node);
286 : 4 : const char *string = NULL;
287 : :
288 : 4 : 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 : 4 : dump_string_field (di, "accs", string);
298 : 4 : queue_and_dump_index (di, "binf", base, DUMP_BINFO);
299 : : }
300 : :
301 : 24 : goto done;
302 : : }
303 : :
304 : : /* We can knock off a bunch of expression nodes in exactly the same
305 : : way. */
306 : 27519 : if (IS_EXPR_CODE_CLASS (code_class))
307 : : {
308 : : /* If we're dumping children, dump them now. */
309 : 148 : queue_and_dump_type (di, t);
310 : :
311 : 148 : switch (code_class)
312 : : {
313 : 40 : case tcc_unary:
314 : 40 : dump_child ("op 0", TREE_OPERAND (t, 0));
315 : 40 : break;
316 : :
317 : 12 : case tcc_binary:
318 : 12 : case tcc_comparison:
319 : 12 : dump_child ("op 0", TREE_OPERAND (t, 0));
320 : 12 : dump_child ("op 1", TREE_OPERAND (t, 1));
321 : 12 : 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 : 27371 : else if (DECL_P (t))
335 : : {
336 : 9694 : expanded_location xloc;
337 : : /* All declarations have names. */
338 : 9694 : if (DECL_NAME (t))
339 : 9633 : dump_child ("name", DECL_NAME (t));
340 : 9694 : if (HAS_DECL_ASSEMBLER_NAME_P (t)
341 : 9593 : && DECL_ASSEMBLER_NAME_SET_P (t)
342 : 13570 : && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
343 : 3736 : dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
344 : 9694 : if (DECL_ABSTRACT_ORIGIN (t))
345 : 36 : dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
346 : : /* And types. */
347 : 9694 : queue_and_dump_type (di, t);
348 : 9694 : dump_child ("scpe", DECL_CONTEXT (t));
349 : : /* And a source position. */
350 : 9694 : xloc = expand_location (DECL_SOURCE_LOCATION (t));
351 : 9694 : if (xloc.file)
352 : : {
353 : 9592 : const char *filename = lbasename (xloc.file);
354 : :
355 : 9592 : dump_maybe_newline (di);
356 : 9592 : fprintf (di->stream, "srcp: %s:%-6d ", filename,
357 : : xloc.line);
358 : 9592 : di->column += 6 + strlen (filename) + 8;
359 : : }
360 : : /* And any declaration can be compiler-generated. */
361 : 9694 : if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
362 : 9694 : && DECL_ARTIFICIAL (t))
363 : 9511 : dump_string_field (di, "note", "artificial");
364 : 9694 : if (DECL_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
365 : 9470 : dump_child ("chain", DECL_CHAIN (t));
366 : : }
367 : 17677 : else if (code_class == tcc_type)
368 : : {
369 : : /* All types have qualifiers. */
370 : 2709 : int quals = lang_hooks.tree_dump.type_quals (t);
371 : :
372 : 2709 : if (quals != TYPE_UNQUALIFIED)
373 : : {
374 : 65 : fprintf (di->stream, "qual: %c%c%c ",
375 : 65 : (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
376 : 65 : (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
377 : 65 : (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
378 : 65 : di->column += 14;
379 : : }
380 : :
381 : : /* All types have associated declarations. */
382 : 2709 : dump_child ("name", TYPE_NAME (t));
383 : :
384 : : /* All types have a main variant. */
385 : 2709 : if (TYPE_MAIN_VARIANT (t) != t)
386 : 137 : dump_child ("unql", TYPE_MAIN_VARIANT (t));
387 : :
388 : : /* And sizes. */
389 : 2709 : dump_child ("size", TYPE_SIZE (t));
390 : :
391 : : /* All types have alignments. */
392 : 2709 : dump_int (di, "algn", TYPE_ALIGN (t));
393 : : }
394 : 14968 : else if (code_class == tcc_constant)
395 : : /* All constants can have types. */
396 : 203 : 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 : 27519 : if (lang_hooks.tree_dump.dump_tree (di, t))
402 : 20 : goto done;
403 : :
404 : : /* Now handle the various kinds of nodes. */
405 : 27499 : switch (code)
406 : : {
407 : 11161 : int i;
408 : :
409 : 11161 : case IDENTIFIER_NODE:
410 : 11161 : dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
411 : 11161 : dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
412 : 11161 : break;
413 : :
414 : 3563 : case TREE_LIST:
415 : 3563 : dump_child ("purp", TREE_PURPOSE (t));
416 : 3563 : dump_child ("valu", TREE_VALUE (t));
417 : 3563 : dump_child ("chan", TREE_CHAIN (t));
418 : 3563 : break;
419 : :
420 : 9 : case STATEMENT_LIST:
421 : 9 : {
422 : 9 : tree_stmt_iterator it;
423 : 19 : for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
424 : : {
425 : 10 : char buffer[32];
426 : 10 : sprintf (buffer, "%u", i);
427 : 10 : dump_child (buffer, tsi_stmt (it));
428 : : }
429 : : }
430 : 9 : 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 : 85 : case INTEGER_TYPE:
443 : 85 : case ENUMERAL_TYPE:
444 : 85 : dump_int (di, "prec", TYPE_PRECISION (t));
445 : 134 : dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
446 : 85 : dump_child ("min", TYPE_MIN_VALUE (t));
447 : 85 : dump_child ("max", TYPE_MAX_VALUE (t));
448 : :
449 : 85 : if (code == ENUMERAL_TYPE)
450 : 2 : dump_child ("csts", TYPE_VALUES (t));
451 : : break;
452 : :
453 : 64 : case REAL_TYPE:
454 : 64 : dump_int (di, "prec", TYPE_PRECISION (t));
455 : 64 : break;
456 : :
457 : 0 : case FIXED_POINT_TYPE:
458 : 0 : dump_int (di, "prec", TYPE_PRECISION (t));
459 : 0 : dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
460 : 0 : dump_string_field (di, "saturating",
461 : 0 : TYPE_SATURATING (t) ? "saturating": "non-saturating");
462 : 0 : break;
463 : :
464 : 203 : case POINTER_TYPE:
465 : 203 : dump_child ("ptd", TREE_TYPE (t));
466 : 203 : break;
467 : :
468 : 8 : case REFERENCE_TYPE:
469 : 8 : dump_child ("refd", TREE_TYPE (t));
470 : 8 : break;
471 : :
472 : 31 : case METHOD_TYPE:
473 : 31 : dump_child ("clas", TYPE_METHOD_BASETYPE (t));
474 : : /* Fall through. */
475 : :
476 : 2112 : case FUNCTION_TYPE:
477 : 2112 : dump_child ("retn", TREE_TYPE (t));
478 : 2112 : dump_child ("prms", TYPE_ARG_TYPES (t));
479 : 2112 : break;
480 : :
481 : 32 : case ARRAY_TYPE:
482 : 32 : dump_child ("elts", TREE_TYPE (t));
483 : 32 : dump_child ("domn", TYPE_DOMAIN (t));
484 : 32 : break;
485 : :
486 : 48 : case RECORD_TYPE:
487 : 48 : case UNION_TYPE:
488 : 48 : if (TREE_CODE (t) == RECORD_TYPE)
489 : 48 : dump_string_field (di, "tag", "struct");
490 : : else
491 : 0 : dump_string_field (di, "tag", "union");
492 : :
493 : 48 : dump_child ("flds", TYPE_FIELDS (t));
494 : 48 : queue_and_dump_index (di, "binf", TYPE_BINFO (t),
495 : : DUMP_BINFO);
496 : 48 : break;
497 : :
498 : 0 : case CONST_DECL:
499 : 0 : dump_child ("cnst", DECL_INITIAL (t));
500 : 0 : break;
501 : :
502 : 0 : case DEBUG_EXPR_DECL:
503 : 0 : dump_int (di, "-uid", DEBUG_TEMP_UID (t));
504 : : /* Fall through. */
505 : :
506 : 117 : case VAR_DECL:
507 : 117 : case PARM_DECL:
508 : 117 : case FIELD_DECL:
509 : 117 : case RESULT_DECL:
510 : 117 : if (TREE_CODE (t) == PARM_DECL)
511 : 44 : dump_child ("argt", DECL_ARG_TYPE (t));
512 : : else
513 : 73 : dump_child ("init", DECL_INITIAL (t));
514 : 117 : dump_child ("size", DECL_SIZE (t));
515 : 117 : dump_int (di, "algn", DECL_ALIGN (t));
516 : :
517 : 117 : if (TREE_CODE (t) == FIELD_DECL)
518 : : {
519 : 48 : if (DECL_FIELD_OFFSET (t))
520 : 48 : dump_child ("bpos", bit_position (t));
521 : : }
522 : 69 : else if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
523 : : {
524 : 64 : dump_int (di, "used", TREE_USED (t));
525 : 64 : if (DECL_REGISTER (t))
526 : 0 : dump_string_field (di, "spec", "register");
527 : : }
528 : : break;
529 : :
530 : 9317 : case FUNCTION_DECL:
531 : 9317 : dump_child ("args", DECL_ARGUMENTS (t));
532 : 9317 : if (DECL_EXTERNAL (t))
533 : 9296 : dump_string_field (di, "body", "undefined");
534 : 9317 : if (TREE_PUBLIC (t))
535 : 9317 : dump_string_field (di, "link", "extern");
536 : : else
537 : 0 : dump_string_field (di, "link", "static");
538 : 9317 : if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
539 : 12 : dump_child ("body", DECL_SAVED_TREE (t));
540 : : break;
541 : :
542 : 199 : case INTEGER_CST:
543 : 199 : fprintf (di->stream, "int: ");
544 : 199 : print_decs (wi::to_wide (t), di->stream);
545 : 199 : break;
546 : :
547 : 4 : case STRING_CST:
548 : 4 : fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
549 : 4 : dump_int (di, "lngt", TREE_STRING_LENGTH (t));
550 : 4 : break;
551 : :
552 : 0 : case REAL_CST:
553 : 0 : dump_real (di, "valu", TREE_REAL_CST_PTR (t));
554 : 0 : break;
555 : :
556 : 0 : case FIXED_CST:
557 : 0 : dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
558 : 0 : break;
559 : :
560 : 44 : case TRUTH_NOT_EXPR:
561 : 44 : case ADDR_EXPR:
562 : 44 : case INDIRECT_REF:
563 : 44 : case CLEANUP_POINT_EXPR:
564 : 44 : case VIEW_CONVERT_EXPR:
565 : 44 : case SAVE_EXPR:
566 : 44 : case REALPART_EXPR:
567 : 44 : case IMAGPART_EXPR:
568 : : /* These nodes are unary, but do not have code class `1'. */
569 : 44 : dump_child ("op 0", TREE_OPERAND (t, 0));
570 : 44 : break;
571 : :
572 : 14 : case TRUTH_ANDIF_EXPR:
573 : 14 : case TRUTH_ORIF_EXPR:
574 : 14 : case INIT_EXPR:
575 : 14 : case MODIFY_EXPR:
576 : 14 : case COMPOUND_EXPR:
577 : 14 : case PREDECREMENT_EXPR:
578 : 14 : case PREINCREMENT_EXPR:
579 : 14 : case POSTDECREMENT_EXPR:
580 : 14 : case POSTINCREMENT_EXPR:
581 : : /* These nodes are binary, but do not have code class `2'. */
582 : 14 : dump_child ("op 0", TREE_OPERAND (t, 0));
583 : 14 : dump_child ("op 1", TREE_OPERAND (t, 1));
584 : 14 : break;
585 : :
586 : 4 : case COMPONENT_REF:
587 : 4 : case BIT_FIELD_REF:
588 : 4 : dump_child ("op 0", TREE_OPERAND (t, 0));
589 : 4 : dump_child ("op 1", TREE_OPERAND (t, 1));
590 : 4 : dump_child ("op 2", TREE_OPERAND (t, 2));
591 : 4 : break;
592 : :
593 : 0 : case ARRAY_REF:
594 : 0 : case ARRAY_RANGE_REF:
595 : 0 : dump_child ("op 0", TREE_OPERAND (t, 0));
596 : 0 : dump_child ("op 1", TREE_OPERAND (t, 1));
597 : 0 : dump_child ("op 2", TREE_OPERAND (t, 2));
598 : 0 : dump_child ("op 3", TREE_OPERAND (t, 3));
599 : 0 : break;
600 : :
601 : 0 : case COND_EXPR:
602 : 0 : dump_child ("op 0", TREE_OPERAND (t, 0));
603 : 0 : dump_child ("op 1", TREE_OPERAND (t, 1));
604 : 0 : dump_child ("op 2", TREE_OPERAND (t, 2));
605 : 0 : break;
606 : :
607 : 8 : case TRY_FINALLY_EXPR:
608 : 8 : case EH_ELSE_EXPR:
609 : 8 : dump_child ("op 0", TREE_OPERAND (t, 0));
610 : 8 : dump_child ("op 1", TREE_OPERAND (t, 1));
611 : 8 : break;
612 : :
613 : 8 : case CALL_EXPR:
614 : 8 : {
615 : 8 : int i = 0;
616 : 8 : tree arg;
617 : 8 : call_expr_arg_iterator iter;
618 : 8 : dump_child ("fn", CALL_EXPR_FN (t));
619 : 19 : FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
620 : : {
621 : 11 : char buffer[32];
622 : 11 : sprintf (buffer, "%u", i);
623 : 11 : dump_child (buffer, arg);
624 : 11 : i++;
625 : : }
626 : : }
627 : 8 : break;
628 : :
629 : 16 : case CONSTRUCTOR:
630 : 16 : {
631 : 16 : unsigned HOST_WIDE_INT cnt;
632 : 16 : tree index, value;
633 : 16 : dump_int (di, "lngt", CONSTRUCTOR_NELTS (t));
634 : 60 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
635 : : {
636 : 28 : dump_child ("idx", index);
637 : 28 : dump_child ("val", value);
638 : : }
639 : : }
640 : : break;
641 : :
642 : 5 : case BIND_EXPR:
643 : 5 : dump_child ("vars", TREE_OPERAND (t, 0));
644 : 5 : dump_child ("body", TREE_OPERAND (t, 1));
645 : 5 : break;
646 : :
647 : 0 : case LOOP_EXPR:
648 : 0 : dump_child ("body", TREE_OPERAND (t, 0));
649 : 0 : break;
650 : :
651 : 0 : case EXIT_EXPR:
652 : 0 : dump_child ("cond", TREE_OPERAND (t, 0));
653 : 0 : break;
654 : :
655 : 6 : case RETURN_EXPR:
656 : 6 : dump_child ("expr", TREE_OPERAND (t, 0));
657 : 6 : break;
658 : :
659 : 0 : case TARGET_EXPR:
660 : 0 : dump_child ("decl", TREE_OPERAND (t, 0));
661 : 0 : dump_child ("init", TREE_OPERAND (t, 1));
662 : 0 : dump_child ("clnp", TREE_OPERAND (t, 2));
663 : : /* There really are two possible places the initializer can be.
664 : : After RTL expansion, the second operand is moved to the
665 : : position of the fourth operand, and the second operand
666 : : becomes NULL. */
667 : 0 : dump_child ("init", TREE_OPERAND (t, 3));
668 : 0 : break;
669 : :
670 : 0 : case CASE_LABEL_EXPR:
671 : 0 : dump_child ("name", CASE_LABEL (t));
672 : 0 : if (CASE_LOW (t))
673 : : {
674 : 0 : dump_child ("low ", CASE_LOW (t));
675 : 0 : if (CASE_HIGH (t))
676 : 0 : dump_child ("high", CASE_HIGH (t));
677 : : }
678 : : break;
679 : 0 : case LABEL_EXPR:
680 : 0 : dump_child ("name", TREE_OPERAND (t,0));
681 : 0 : break;
682 : 0 : case GOTO_EXPR:
683 : 0 : dump_child ("labl", TREE_OPERAND (t, 0));
684 : 0 : break;
685 : 0 : case SWITCH_EXPR:
686 : 0 : dump_child ("cond", TREE_OPERAND (t, 0));
687 : 0 : dump_child ("body", TREE_OPERAND (t, 1));
688 : 0 : break;
689 : 0 : case OMP_CLAUSE:
690 : 0 : {
691 : 0 : int i;
692 : 0 : fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
693 : 0 : for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
694 : 0 : dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
695 : : }
696 : : break;
697 : : default:
698 : : /* There are no additional fields to print. */
699 : : break;
700 : : }
701 : :
702 : 27543 : done:
703 : 27543 : if (dump_flag (di, TDF_ADDRESS, NULL))
704 : 0 : dump_pointer (di, "addr", (void *)t);
705 : :
706 : : /* Terminate the line. */
707 : 27543 : fprintf (di->stream, "\n");
708 : 27543 : }
709 : :
710 : : /* Return nonzero if FLAG has been specified for the dump, and NODE
711 : : is not the root node of the dump. */
712 : :
713 : 37082 : int dump_flag (dump_info_p di, dump_flags_t flag, const_tree node)
714 : : {
715 : 37082 : return (di->flags & flag) && (node != di->node);
716 : : }
717 : :
718 : : /* Dump T, and all its children, on STREAM. */
719 : :
720 : : void
721 : 5 : dump_node (const_tree t, dump_flags_t flags, FILE *stream)
722 : : {
723 : 5 : struct dump_info di;
724 : 5 : dump_queue_p dq;
725 : 5 : dump_queue_p next_dq;
726 : :
727 : : /* Initialize the dump-information structure. */
728 : 5 : di.stream = stream;
729 : 5 : di.index = 0;
730 : 5 : di.column = 0;
731 : 5 : di.queue = 0;
732 : 5 : di.queue_end = 0;
733 : 5 : di.free_list = 0;
734 : 5 : di.flags = flags;
735 : 5 : di.node = t;
736 : 5 : di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
737 : : splay_tree_delete_pointers);
738 : :
739 : : /* Queue up the first node. */
740 : 5 : queue (&di, t, DUMP_NONE);
741 : :
742 : : /* Until the queue is empty, keep dumping nodes. */
743 : 27553 : while (di.queue)
744 : 27543 : dequeue_and_dump (&di);
745 : :
746 : : /* Now, clean up. */
747 : 115 : for (dq = di.free_list; dq; dq = next_dq)
748 : : {
749 : 110 : next_dq = dq->next;
750 : 110 : free (dq);
751 : : }
752 : 5 : splay_tree_delete (di.nodes);
753 : 5 : }
|