]> gcc.gnu.org Git - gcc.git/blame - gcc/tree-dump.c
backport: ChangeLog.tuples: ChangeLog from gimple-tuples-branch.
[gcc.git] / gcc / tree-dump.c
CommitLineData
9c5a221c 1/* Tree-dumping functionality for intermediate representation.
a8bafc43 2 Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008
6a6305e4 3 Free Software Foundation, Inc.
9c5a221c
BM
4 Written by Mark Mitchell <mark@codesourcery.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
9c5a221c
BM
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
9c5a221c
BM
21
22#include "config.h"
23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
9c5a221c 26#include "tree.h"
9c5a221c
BM
27#include "splay-tree.h"
28#include "diagnostic.h"
29#include "toplev.h"
89d684bb 30#include "tree-dump.h"
9f8628ba 31#include "tree-pass.h"
9c5a221c 32#include "langhooks.h"
11ed191c 33#include "tree-iterator.h"
da54e73b 34#include "real.h"
325217ed 35#include "fixed-value.h"
9c5a221c 36
58f9752a 37static unsigned int queue (dump_info_p, const_tree, int);
79a490a9
AJ
38static void dump_index (dump_info_p, unsigned int);
39static void dequeue_and_dump (dump_info_p);
40static void dump_new_line (dump_info_p);
41static void dump_maybe_newline (dump_info_p);
9c5a221c
BM
42
43/* Add T to the end of the queue of nodes to dump. Returns the index
44 assigned to T. */
45
46static unsigned int
58f9752a 47queue (dump_info_p di, const_tree t, int flags)
9c5a221c
BM
48{
49 dump_queue_p dq;
50 dump_node_info_p dni;
51 unsigned int index;
52
53 /* Assign the next available index to T. */
54 index = ++di->index;
55
56 /* Obtain a new queue node. */
57 if (di->free_list)
58 {
59 dq = di->free_list;
60 di->free_list = dq->next;
61 }
62 else
5ed6ace5 63 dq = XNEW (struct dump_queue);
9c5a221c
BM
64
65 /* Create a new entry in the splay-tree. */
5ed6ace5 66 dni = XNEW (struct dump_node_info);
9c5a221c
BM
67 dni->index = index;
68 dni->binfo_p = ((flags & DUMP_BINFO) != 0);
d92b4486 69 dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
9c5a221c
BM
70 (splay_tree_value) dni);
71
72 /* Add it to the end of the queue. */
73 dq->next = 0;
74 if (!di->queue_end)
75 di->queue = dq;
76 else
77 di->queue_end->next = dq;
78 di->queue_end = dq;
79
80 /* Return the index. */
81 return index;
82}
83
84static void
79a490a9 85dump_index (dump_info_p di, unsigned int index)
9c5a221c
BM
86{
87 fprintf (di->stream, "@%-6u ", index);
88 di->column += 8;
89}
90
91/* If T has not already been output, queue it for subsequent output.
92 FIELD is a string to print before printing the index. Then, the
93 index of T is printed. */
94
95void
58f9752a 96queue_and_dump_index (dump_info_p di, const char *field, const_tree t, int flags)
9c5a221c
BM
97{
98 unsigned int index;
99 splay_tree_node n;
100
101 /* If there's no node, just return. This makes for fewer checks in
102 our callers. */
103 if (!t)
104 return;
105
106 /* See if we've already queued or dumped this node. */
107 n = splay_tree_lookup (di->nodes, (splay_tree_key) t);
108 if (n)
109 index = ((dump_node_info_p) n->value)->index;
110 else
111 /* If we haven't, add it to the queue. */
112 index = queue (di, t, flags);
113
114 /* Print the index of the node. */
115 dump_maybe_newline (di);
116 fprintf (di->stream, "%-4s: ", field);
117 di->column += 6;
118 dump_index (di, index);
119}
120
121/* Dump the type of T. */
122
123void
58f9752a 124queue_and_dump_type (dump_info_p di, const_tree t)
9c5a221c
BM
125{
126 queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
127}
128
129/* Dump column control */
130#define SOL_COLUMN 25 /* Start of line column. */
131#define EOL_COLUMN 55 /* End of line column. */
132#define COLUMN_ALIGNMENT 15 /* Alignment. */
133
134/* Insert a new line in the dump output, and indent to an appropriate
135 place to start printing more fields. */
136
137static void
79a490a9 138dump_new_line (dump_info_p di)
9c5a221c
BM
139{
140 fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
141 di->column = SOL_COLUMN;
142}
143
144/* If necessary, insert a new line. */
145
146static void
79a490a9 147dump_maybe_newline (dump_info_p di)
9c5a221c
BM
148{
149 int extra;
d92b4486 150
9c5a221c
BM
151 /* See if we need a new line. */
152 if (di->column > EOL_COLUMN)
153 dump_new_line (di);
154 /* See if we need any padding. */
155 else if ((extra = (di->column - SOL_COLUMN) % COLUMN_ALIGNMENT) != 0)
156 {
157 fprintf (di->stream, "%*s", COLUMN_ALIGNMENT - extra, "");
158 di->column += COLUMN_ALIGNMENT - extra;
159 }
160}
161
162/* Dump pointer PTR using FIELD to identify it. */
163
164void
79a490a9 165dump_pointer (dump_info_p di, const char *field, void *ptr)
9c5a221c
BM
166{
167 dump_maybe_newline (di);
8d5b1b67 168 fprintf (di->stream, "%-4s: %-8lx ", field, (unsigned long) ptr);
9c5a221c
BM
169 di->column += 15;
170}
171
172/* Dump integer I using FIELD to identify it. */
173
174void
79a490a9 175dump_int (dump_info_p di, const char *field, int i)
9c5a221c
BM
176{
177 dump_maybe_newline (di);
178 fprintf (di->stream, "%-4s: %-7d ", field, i);
179 di->column += 14;
180}
181
da54e73b
RS
182/* Dump the floating point value R, using FIELD to identify it. */
183
184static void
185dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
186{
187 char buf[32];
188 real_to_decimal (buf, r, sizeof (buf), 0, true);
189 dump_maybe_newline (di);
190 fprintf (di->stream, "%-4s: %s ", field, buf);
191 di->column += strlen (buf) + 7;
192}
193
325217ed
CF
194/* Dump the fixed-point value F, using FIELD to identify it. */
195
196static void
197dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
198{
199 char buf[32];
200 fixed_to_decimal (buf, f, sizeof (buf));
201 dump_maybe_newline (di);
202 fprintf (di->stream, "%-4s: %s ", field, buf);
203 di->column += strlen (buf) + 7;
204}
205
da54e73b 206
9c5a221c
BM
207/* Dump the string S. */
208
209void
79a490a9 210dump_string (dump_info_p di, const char *string)
9c5a221c
BM
211{
212 dump_maybe_newline (di);
213 fprintf (di->stream, "%-13s ", string);
214 if (strlen (string) > 13)
215 di->column += strlen (string) + 1;
216 else
217 di->column += 14;
218}
219
220/* Dump the string field S. */
221
1966af04 222void
79a490a9 223dump_string_field (dump_info_p di, const char *field, const char *string)
9c5a221c
BM
224{
225 dump_maybe_newline (di);
226 fprintf (di->stream, "%-4s: %-7s ", field, string);
227 if (strlen (string) > 7)
228 di->column += 6 + strlen (string) + 1;
229 else
230 di->column += 14;
231}
232
9c5a221c
BM
233/* Dump the next node in the queue. */
234
d92b4486 235static void
79a490a9 236dequeue_and_dump (dump_info_p di)
9c5a221c
BM
237{
238 dump_queue_p dq;
239 splay_tree_node stn;
240 dump_node_info_p dni;
241 tree t;
242 unsigned int index;
243 enum tree_code code;
6615c446 244 enum tree_code_class code_class;
9c5a221c
BM
245 const char* code_name;
246
247 /* Get the next node from the queue. */
248 dq = di->queue;
249 stn = dq->node;
250 t = (tree) stn->key;
251 dni = (dump_node_info_p) stn->value;
252 index = dni->index;
253
254 /* Remove the node from the queue, and put it on the free list. */
255 di->queue = dq->next;
256 if (!di->queue)
257 di->queue_end = 0;
258 dq->next = di->free_list;
259 di->free_list = dq;
260
261 /* Print the node index. */
262 dump_index (di, index);
263 /* And the type of node this is. */
264 if (dni->binfo_p)
265 code_name = "binfo";
266 else
267 code_name = tree_code_name[(int) TREE_CODE (t)];
268 fprintf (di->stream, "%-16s ", code_name);
269 di->column = 25;
270
271 /* Figure out what kind of node this is. */
272 code = TREE_CODE (t);
273 code_class = TREE_CODE_CLASS (code);
274
275 /* Although BINFOs are TREE_VECs, we dump them specially so as to be
276 more informative. */
277 if (dni->binfo_p)
278 {
dbbf88d1 279 unsigned ix;
fa743e8c 280 tree base;
d4e6fecb 281 VEC(tree,gc) *accesses = BINFO_BASE_ACCESSES (t);
79a490a9 282
dbbf88d1
NS
283 dump_child ("type", BINFO_TYPE (t));
284
809e3e7f 285 if (BINFO_VIRTUAL_P (t))
1966af04 286 dump_string_field (di, "spec", "virt");
d92b4486 287
fa743e8c
NS
288 dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
289 for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
dbbf88d1 290 {
63d1c7b3 291 tree access = (accesses ? VEC_index (tree, accesses, ix)
dbbf88d1
NS
292 : access_public_node);
293 const char *string = NULL;
294
295 if (access == access_public_node)
296 string = "pub";
297 else if (access == access_protected_node)
298 string = "prot";
299 else if (access == access_private_node)
300 string = "priv";
301 else
1e128c5f 302 gcc_unreachable ();
79a490a9 303
1966af04 304 dump_string_field (di, "accs", string);
dbbf88d1
NS
305 queue_and_dump_index (di, "binf", base, DUMP_BINFO);
306 }
79a490a9 307
9c5a221c
BM
308 goto done;
309 }
310
311 /* We can knock off a bunch of expression nodes in exactly the same
312 way. */
313 if (IS_EXPR_CODE_CLASS (code_class))
314 {
315 /* If we're dumping children, dump them now. */
316 queue_and_dump_type (di, t);
317
318 switch (code_class)
319 {
6615c446 320 case tcc_unary:
9c5a221c
BM
321 dump_child ("op 0", TREE_OPERAND (t, 0));
322 break;
d92b4486 323
6615c446
JO
324 case tcc_binary:
325 case tcc_comparison:
9c5a221c
BM
326 dump_child ("op 0", TREE_OPERAND (t, 0));
327 dump_child ("op 1", TREE_OPERAND (t, 1));
328 break;
d92b4486 329
6615c446
JO
330 case tcc_expression:
331 case tcc_reference:
332 case tcc_statement:
3328fbb7 333 case tcc_vl_exp:
9c5a221c
BM
334 /* These nodes are handled explicitly below. */
335 break;
d92b4486 336
9c5a221c 337 default:
1e128c5f 338 gcc_unreachable ();
9c5a221c
BM
339 }
340 }
341 else if (DECL_P (t))
342 {
a281759f 343 expanded_location xloc;
9c5a221c
BM
344 /* All declarations have names. */
345 if (DECL_NAME (t))
346 dump_child ("name", DECL_NAME (t));
d92b4486 347 if (DECL_ASSEMBLER_NAME_SET_P (t)
9c5a221c
BM
348 && DECL_ASSEMBLER_NAME (t) != DECL_NAME (t))
349 dump_child ("mngl", DECL_ASSEMBLER_NAME (t));
7f3b2bda
GDR
350 if (DECL_ABSTRACT_ORIGIN (t))
351 dump_child ("orig", DECL_ABSTRACT_ORIGIN (t));
9c5a221c
BM
352 /* And types. */
353 queue_and_dump_type (di, t);
354 dump_child ("scpe", DECL_CONTEXT (t));
355 /* And a source position. */
a281759f
PB
356 xloc = expand_location (DECL_SOURCE_LOCATION (t));
357 if (xloc.file)
9c5a221c 358 {
a281759f 359 const char *filename = strrchr (xloc.file, '/');
9c5a221c 360 if (!filename)
a281759f 361 filename = xloc.file;
9c5a221c
BM
362 else
363 /* Skip the slash. */
364 ++filename;
365
366 dump_maybe_newline (di);
d92b4486 367 fprintf (di->stream, "srcp: %s:%-6d ", filename,
a281759f 368 xloc.line);
9c5a221c
BM
369 di->column += 6 + strlen (filename) + 8;
370 }
371 /* And any declaration can be compiler-generated. */
326eda4b
DB
372 if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_COMMON)
373 && DECL_ARTIFICIAL (t))
1966af04 374 dump_string_field (di, "note", "artificial");
9c5a221c
BM
375 if (TREE_CHAIN (t) && !dump_flag (di, TDF_SLIM, NULL))
376 dump_child ("chan", TREE_CHAIN (t));
377 }
6615c446 378 else if (code_class == tcc_type)
9c5a221c
BM
379 {
380 /* All types have qualifiers. */
ae2bcd98 381 int quals = lang_hooks.tree_dump.type_quals (t);
d92b4486 382
9c5a221c
BM
383 if (quals != TYPE_UNQUALIFIED)
384 {
385 fprintf (di->stream, "qual: %c%c%c ",
386 (quals & TYPE_QUAL_CONST) ? 'c' : ' ',
387 (quals & TYPE_QUAL_VOLATILE) ? 'v' : ' ',
388 (quals & TYPE_QUAL_RESTRICT) ? 'r' : ' ');
389 di->column += 14;
390 }
391
392 /* All types have associated declarations. */
393 dump_child ("name", TYPE_NAME (t));
394
395 /* All types have a main variant. */
396 if (TYPE_MAIN_VARIANT (t) != t)
397 dump_child ("unql", TYPE_MAIN_VARIANT (t));
d92b4486 398
9c5a221c
BM
399 /* And sizes. */
400 dump_child ("size", TYPE_SIZE (t));
401
402 /* All types have alignments. */
403 dump_int (di, "algn", TYPE_ALIGN (t));
404 }
6615c446 405 else if (code_class == tcc_constant)
9c5a221c
BM
406 /* All constants can have types. */
407 queue_and_dump_type (di, t);
408
409 /* Give the language-specific code a chance to print something. If
410 it's completely taken care of things, don't bother printing
411 anything more ourselves. */
ae2bcd98 412 if (lang_hooks.tree_dump.dump_tree (di, t))
9c5a221c
BM
413 goto done;
414
415 /* Now handle the various kinds of nodes. */
416 switch (code)
417 {
418 int i;
419
420 case IDENTIFIER_NODE:
421 dump_string_field (di, "strg", IDENTIFIER_POINTER (t));
422 dump_int (di, "lngt", IDENTIFIER_LENGTH (t));
423 break;
424
425 case TREE_LIST:
426 dump_child ("purp", TREE_PURPOSE (t));
427 dump_child ("valu", TREE_VALUE (t));
428 dump_child ("chan", TREE_CHAIN (t));
429 break;
430
11ed191c
RH
431 case STATEMENT_LIST:
432 {
433 tree_stmt_iterator it;
434 for (i = 0, it = tsi_start (t); !tsi_end_p (it); tsi_next (&it), i++)
435 {
436 char buffer[32];
437 sprintf (buffer, "%u", i);
438 dump_child (buffer, tsi_stmt (it));
439 }
440 }
441 break;
442
9c5a221c
BM
443 case TREE_VEC:
444 dump_int (di, "lngt", TREE_VEC_LENGTH (t));
445 for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
446 {
447 char buffer[32];
448 sprintf (buffer, "%u", i);
449 dump_child (buffer, TREE_VEC_ELT (t, i));
450 }
451 break;
452
453 case INTEGER_TYPE:
454 case ENUMERAL_TYPE:
455 dump_int (di, "prec", TYPE_PRECISION (t));
1966af04 456 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
9c5a221c
BM
457 dump_child ("min", TYPE_MIN_VALUE (t));
458 dump_child ("max", TYPE_MAX_VALUE (t));
459
460 if (code == ENUMERAL_TYPE)
461 dump_child ("csts", TYPE_VALUES (t));
462 break;
463
464 case REAL_TYPE:
465 dump_int (di, "prec", TYPE_PRECISION (t));
466 break;
467
325217ed
CF
468 case FIXED_POINT_TYPE:
469 dump_int (di, "prec", TYPE_PRECISION (t));
470 dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
471 dump_string_field (di, "saturating",
472 TYPE_SATURATING (t) ? "saturating": "non-saturating");
473 break;
474
9c5a221c
BM
475 case POINTER_TYPE:
476 dump_child ("ptd", TREE_TYPE (t));
477 break;
478
479 case REFERENCE_TYPE:
480 dump_child ("refd", TREE_TYPE (t));
481 break;
482
483 case METHOD_TYPE:
484 dump_child ("clas", TYPE_METHOD_BASETYPE (t));
485 /* Fall through. */
486
487 case FUNCTION_TYPE:
488 dump_child ("retn", TREE_TYPE (t));
489 dump_child ("prms", TYPE_ARG_TYPES (t));
490 break;
491
492 case ARRAY_TYPE:
493 dump_child ("elts", TREE_TYPE (t));
494 dump_child ("domn", TYPE_DOMAIN (t));
495 break;
496
497 case RECORD_TYPE:
498 case UNION_TYPE:
499 if (TREE_CODE (t) == RECORD_TYPE)
1966af04 500 dump_string_field (di, "tag", "struct");
9c5a221c 501 else
1966af04 502 dump_string_field (di, "tag", "union");
d92b4486 503
9c5a221c
BM
504 dump_child ("flds", TYPE_FIELDS (t));
505 dump_child ("fncs", TYPE_METHODS (t));
d92b4486 506 queue_and_dump_index (di, "binf", TYPE_BINFO (t),
9c5a221c
BM
507 DUMP_BINFO);
508 break;
509
510 case CONST_DECL:
511 dump_child ("cnst", DECL_INITIAL (t));
512 break;
326eda4b 513
18cd8a03 514 case SYMBOL_MEMORY_TAG:
326eda4b 515 case NAME_MEMORY_TAG:
326eda4b 516 break;
9c5a221c
BM
517
518 case VAR_DECL:
519 case PARM_DECL:
520 case FIELD_DECL:
521 case RESULT_DECL:
522 if (TREE_CODE (t) == PARM_DECL)
523 dump_child ("argt", DECL_ARG_TYPE (t));
524 else
525 dump_child ("init", DECL_INITIAL (t));
526 dump_child ("size", DECL_SIZE (t));
527 dump_int (di, "algn", DECL_ALIGN (t));
528
529 if (TREE_CODE (t) == FIELD_DECL)
530 {
9c5a221c
BM
531 if (DECL_FIELD_OFFSET (t))
532 dump_child ("bpos", bit_position (t));
533 }
d92b4486 534 else if (TREE_CODE (t) == VAR_DECL
9c5a221c
BM
535 || TREE_CODE (t) == PARM_DECL)
536 {
537 dump_int (di, "used", TREE_USED (t));
538 if (DECL_REGISTER (t))
1966af04 539 dump_string_field (di, "spec", "register");
9c5a221c
BM
540 }
541 break;
542
543 case FUNCTION_DECL:
544 dump_child ("args", DECL_ARGUMENTS (t));
545 if (DECL_EXTERNAL (t))
1966af04 546 dump_string_field (di, "body", "undefined");
9c5a221c 547 if (TREE_PUBLIC (t))
1966af04 548 dump_string_field (di, "link", "extern");
9c5a221c 549 else
1966af04 550 dump_string_field (di, "link", "static");
a8bafc43 551 if (DECL_SAVED_TREE (t) && !dump_flag (di, TDF_SLIM, t))
9c5a221c
BM
552 dump_child ("body", DECL_SAVED_TREE (t));
553 break;
554
9c5a221c
BM
555 case INTEGER_CST:
556 if (TREE_INT_CST_HIGH (t))
557 dump_int (di, "high", TREE_INT_CST_HIGH (t));
558 dump_int (di, "low", TREE_INT_CST_LOW (t));
559 break;
560
561 case STRING_CST:
562 fprintf (di->stream, "strg: %-7s ", TREE_STRING_POINTER (t));
563 dump_int (di, "lngt", TREE_STRING_LENGTH (t));
564 break;
565
da54e73b
RS
566 case REAL_CST:
567 dump_real (di, "valu", TREE_REAL_CST_PTR (t));
568 break;
569
325217ed
CF
570 case FIXED_CST:
571 dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
572 break;
573
9c5a221c
BM
574 case TRUTH_NOT_EXPR:
575 case ADDR_EXPR:
576 case INDIRECT_REF:
7ccf35ed
DN
577 case ALIGN_INDIRECT_REF:
578 case MISALIGNED_INDIRECT_REF:
9c5a221c
BM
579 case CLEANUP_POINT_EXPR:
580 case SAVE_EXPR:
497be978
RH
581 case REALPART_EXPR:
582 case IMAGPART_EXPR:
9c5a221c
BM
583 /* These nodes are unary, but do not have code class `1'. */
584 dump_child ("op 0", TREE_OPERAND (t, 0));
585 break;
586
587 case TRUTH_ANDIF_EXPR:
588 case TRUTH_ORIF_EXPR:
589 case INIT_EXPR:
590 case MODIFY_EXPR:
9c5a221c 591 case COMPOUND_EXPR:
9c5a221c
BM
592 case PREDECREMENT_EXPR:
593 case PREINCREMENT_EXPR:
594 case POSTDECREMENT_EXPR:
595 case POSTINCREMENT_EXPR:
596 /* These nodes are binary, but do not have code class `2'. */
597 dump_child ("op 0", TREE_OPERAND (t, 0));
598 dump_child ("op 1", TREE_OPERAND (t, 1));
599 break;
600
44de5aeb
RK
601 case COMPONENT_REF:
602 dump_child ("op 0", TREE_OPERAND (t, 0));
603 dump_child ("op 1", TREE_OPERAND (t, 1));
604 dump_child ("op 2", TREE_OPERAND (t, 2));
605 break;
606
607 case ARRAY_REF:
608 case ARRAY_RANGE_REF:
609 dump_child ("op 0", TREE_OPERAND (t, 0));
610 dump_child ("op 1", TREE_OPERAND (t, 1));
611 dump_child ("op 2", TREE_OPERAND (t, 2));
612 dump_child ("op 3", TREE_OPERAND (t, 3));
613 break;
614
9c5a221c
BM
615 case COND_EXPR:
616 dump_child ("op 0", TREE_OPERAND (t, 0));
617 dump_child ("op 1", TREE_OPERAND (t, 1));
618 dump_child ("op 2", TREE_OPERAND (t, 2));
619 break;
620
7f3b2bda
GDR
621 case TRY_FINALLY_EXPR:
622 dump_child ("op 0", TREE_OPERAND (t, 0));
623 dump_child ("op 1", TREE_OPERAND (t, 1));
624 break;
625
9c5a221c 626 case CALL_EXPR:
5039610b
SL
627 {
628 int i = 0;
629 tree arg;
630 call_expr_arg_iterator iter;
631 dump_child ("fn", CALL_EXPR_FN (t));
632 FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
633 {
634 char buffer[32];
635 sprintf (buffer, "%u", i);
636 dump_child (buffer, arg);
637 i++;
638 }
639 }
9c5a221c
BM
640 break;
641
642 case CONSTRUCTOR:
4038c495
GB
643 {
644 unsigned HOST_WIDE_INT cnt;
645 tree index, value;
646 dump_int (di, "lngt", VEC_length (constructor_elt,
647 CONSTRUCTOR_ELTS (t)));
648 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), cnt, index, value)
649 {
650 dump_child ("idx", index);
651 dump_child ("val", value);
652 }
653 }
9c5a221c
BM
654 break;
655
9c5a221c
BM
656 case BIND_EXPR:
657 dump_child ("vars", TREE_OPERAND (t, 0));
658 dump_child ("body", TREE_OPERAND (t, 1));
659 break;
660
661 case LOOP_EXPR:
662 dump_child ("body", TREE_OPERAND (t, 0));
663 break;
664
665 case EXIT_EXPR:
666 dump_child ("cond", TREE_OPERAND (t, 0));
667 break;
668
7f3b2bda
GDR
669 case RETURN_EXPR:
670 dump_child ("expr", TREE_OPERAND (t, 0));
671 break;
672
9c5a221c
BM
673 case TARGET_EXPR:
674 dump_child ("decl", TREE_OPERAND (t, 0));
675 dump_child ("init", TREE_OPERAND (t, 1));
676 dump_child ("clnp", TREE_OPERAND (t, 2));
677 /* There really are two possible places the initializer can be.
678 After RTL expansion, the second operand is moved to the
679 position of the fourth operand, and the second operand
680 becomes NULL. */
681 dump_child ("init", TREE_OPERAND (t, 3));
682 break;
d92b4486 683
7f3b2bda
GDR
684 case CASE_LABEL_EXPR:
685 dump_child ("name", CASE_LABEL (t));
428aba16
RS
686 if (CASE_LOW (t))
687 {
688 dump_child ("low ", CASE_LOW (t));
689 if (CASE_HIGH (t))
690 dump_child ("high", CASE_HIGH (t));
7f3b2bda 691 }
7f3b2bda
GDR
692 break;
693 case LABEL_EXPR:
694 dump_child ("name", TREE_OPERAND (t,0));
695 break;
696 case GOTO_EXPR:
697 dump_child ("labl", TREE_OPERAND (t, 0));
698 break;
699 case SWITCH_EXPR:
700 dump_child ("cond", TREE_OPERAND (t, 0));
701 dump_child ("body", TREE_OPERAND (t, 1));
702 if (TREE_OPERAND (t, 2))
703 {
704 dump_child ("labl", TREE_OPERAND (t,2));
705 }
706 break;
aaf46ef9
DN
707 case OMP_CLAUSE:
708 {
709 int i;
710 fprintf (di->stream, "%s\n", omp_clause_code_name[OMP_CLAUSE_CODE (t)]);
711 for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; i++)
712 dump_child ("op: ", OMP_CLAUSE_OPERAND (t, i));
713 }
714 break;
9c5a221c
BM
715 default:
716 /* There are no additional fields to print. */
717 break;
718 }
719
720 done:
721 if (dump_flag (di, TDF_ADDRESS, NULL))
722 dump_pointer (di, "addr", (void *)t);
d92b4486 723
9c5a221c
BM
724 /* Terminate the line. */
725 fprintf (di->stream, "\n");
726}
727
0e9e1e0a 728/* Return nonzero if FLAG has been specified for the dump, and NODE
9c5a221c
BM
729 is not the root node of the dump. */
730
58f9752a 731int dump_flag (dump_info_p di, int flag, const_tree node)
9c5a221c
BM
732{
733 return (di->flags & flag) && (node != di->node);
734}
735
736/* Dump T, and all its children, on STREAM. */
737
738void
58f9752a 739dump_node (const_tree t, int flags, FILE *stream)
9c5a221c
BM
740{
741 struct dump_info di;
742 dump_queue_p dq;
743 dump_queue_p next_dq;
744
745 /* Initialize the dump-information structure. */
746 di.stream = stream;
747 di.index = 0;
748 di.column = 0;
749 di.queue = 0;
750 di.queue_end = 0;
751 di.free_list = 0;
752 di.flags = flags;
753 di.node = t;
d92b4486 754 di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
9c5a221c
BM
755 (splay_tree_delete_value_fn) &free);
756
757 /* Queue up the first node. */
758 queue (&di, t, DUMP_NONE);
759
760 /* Until the queue is empty, keep dumping nodes. */
761 while (di.queue)
762 dequeue_and_dump (&di);
763
764 /* Now, clean up. */
765 for (dq = di.free_list; dq; dq = next_dq)
766 {
767 next_dq = dq->next;
768 free (dq);
769 }
770 splay_tree_delete (di.nodes);
771}
9f8628ba 772\f
9c5a221c
BM
773
774/* Table of tree dump switches. This must be consistent with the
ed3d212b 775 tree_dump_index enumeration in tree-pass.h. */
9c5a221c
BM
776static struct dump_file_info dump_files[TDI_end] =
777{
9e016eba
JH
778 {NULL, NULL, NULL, 0, 0, 0},
779 {".cgraph", "ipa-cgraph", NULL, TDF_IPA, 0, 0},
780 {".tu", "translation-unit", NULL, TDF_TREE, 0, 1},
781 {".class", "class-hierarchy", NULL, TDF_TREE, 0, 2},
782 {".original", "tree-original", NULL, TDF_TREE, 0, 3},
783 {".gimple", "tree-gimple", NULL, TDF_TREE, 0, 4},
784 {".nested", "tree-nested", NULL, TDF_TREE, 0, 5},
785 {".vcg", "tree-vcg", NULL, TDF_TREE, 0, 6},
fed39e22 786#define FIRST_AUTO_NUMBERED_DUMP 7
bbbe4e7b 787
9e016eba
JH
788 {NULL, "tree-all", NULL, TDF_TREE, 0, 0},
789 {NULL, "rtl-all", NULL, TDF_RTL, 0, 0},
790 {NULL, "ipa-all", NULL, TDF_IPA, 0, 0},
9c5a221c
BM
791};
792
6de9cd9a
DN
793/* Dynamically registered tree dump files and switches. */
794static struct dump_file_info *extra_dump_files;
795static size_t extra_dump_files_in_use;
796static size_t extra_dump_files_alloced;
797
9c5a221c
BM
798/* Define a name->number mapping for a dump flag value. */
799struct dump_option_value_info
800{
801 const char *const name; /* the name of the value */
802 const int value; /* the value of the name */
803};
804
805/* Table of dump options. This must be consistent with the TDF_* flags
806 in tree.h */
807static const struct dump_option_value_info dump_options[] =
808{
809 {"address", TDF_ADDRESS},
810 {"slim", TDF_SLIM},
6de9cd9a 811 {"raw", TDF_RAW},
fc93bcb6 812 {"graph", TDF_GRAPH},
6de9cd9a
DN
813 {"details", TDF_DETAILS},
814 {"stats", TDF_STATS},
815 {"blocks", TDF_BLOCKS},
816 {"vops", TDF_VOPS},
817 {"lineno", TDF_LINENO},
818 {"uid", TDF_UID},
f430bae8 819 {"stmtaddr", TDF_STMTADDR},
38635499 820 {"memsyms", TDF_MEMSYMS},
3e894af1 821 {"verbose", TDF_VERBOSE},
f430bae8 822 {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
726a989a
RB
823 | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
824 | TDF_RHS_ONLY)},
9c5a221c
BM
825 {NULL, 0}
826};
827
6de9cd9a 828unsigned int
f46fe224 829dump_register (const char *suffix, const char *swtch, const char *glob,
8ddbbcae 830 int flags)
6de9cd9a 831{
bbbe4e7b
PB
832 static int next_dump = FIRST_AUTO_NUMBERED_DUMP;
833 int num = next_dump++;
834
6de9cd9a
DN
835 size_t this = extra_dump_files_in_use++;
836
837 if (this >= extra_dump_files_alloced)
838 {
839 if (extra_dump_files_alloced == 0)
840 extra_dump_files_alloced = 32;
841 else
842 extra_dump_files_alloced *= 2;
3d9a9f94
KG
843 extra_dump_files = XRESIZEVEC (struct dump_file_info,
844 extra_dump_files,
845 extra_dump_files_alloced);
6de9cd9a
DN
846 }
847
848 memset (&extra_dump_files[this], 0, sizeof (struct dump_file_info));
849 extra_dump_files[this].suffix = suffix;
850 extra_dump_files[this].swtch = swtch;
f46fe224 851 extra_dump_files[this].glob = glob;
9f8628ba
PB
852 extra_dump_files[this].flags = flags;
853 extra_dump_files[this].num = num;
6de9cd9a
DN
854
855 return this + TDI_end;
856}
857
9f8628ba 858
6de9cd9a
DN
859/* Return the dump_file_info for the given phase. */
860
9f8628ba 861struct dump_file_info *
6de9cd9a
DN
862get_dump_file_info (enum tree_dump_index phase)
863{
864 if (phase < TDI_end)
865 return &dump_files[phase];
866 else if (phase - TDI_end >= extra_dump_files_in_use)
9f8628ba 867 return NULL;
6de9cd9a
DN
868 else
869 return extra_dump_files + (phase - TDI_end);
870}
871
872
9f8628ba
PB
873/* Return the name of the dump file for the given phase.
874 If the dump is not enabled, returns NULL. */
875
876char *
877get_dump_file_name (enum tree_dump_index phase)
878{
bbbe4e7b 879 char dump_id[10];
9f8628ba
PB
880 struct dump_file_info *dfi;
881
882 if (phase == TDI_none)
883 return NULL;
884
885 dfi = get_dump_file_info (phase);
886 if (dfi->state == 0)
887 return NULL;
888
9b3e897d 889 if (dfi->num < 0)
9f8628ba 890 dump_id[0] = '\0';
9b3e897d
PB
891 else
892 {
bbbe4e7b 893 char suffix;
9b3e897d 894 if (dfi->flags & TDF_TREE)
bbbe4e7b 895 suffix = 't';
9b3e897d 896 else if (dfi->flags & TDF_IPA)
bbbe4e7b 897 suffix = 'i';
9b3e897d 898 else
bbbe4e7b 899 suffix = 'r';
9b3e897d 900
bbbe4e7b 901 if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
9b3e897d
PB
902 dump_id[0] = '\0';
903 }
9f8628ba
PB
904
905 return concat (dump_base_name, dump_id, dfi->suffix, NULL);
906}
907
9c5a221c
BM
908/* Begin a tree dump for PHASE. Stores any user supplied flag in
909 *FLAG_PTR and returns a stream to write to. If the dump is not
910 enabled, returns NULL.
911 Multiple calls will reopen and append to the dump file. */
912
913FILE *
79a490a9 914dump_begin (enum tree_dump_index phase, int *flag_ptr)
9c5a221c 915{
9c5a221c 916 char *name;
6de9cd9a 917 struct dump_file_info *dfi;
9f8628ba 918 FILE *stream;
d92b4486 919
9f8628ba 920 if (phase == TDI_none || !dump_enabled_p (phase))
9c5a221c 921 return NULL;
d92b4486 922
9f8628ba 923 name = get_dump_file_name (phase);
6de9cd9a 924 dfi = get_dump_file_info (phase);
6de9cd9a 925 stream = fopen (name, dfi->state < 0 ? "w" : "a");
9c5a221c 926 if (!stream)
971801ff 927 error ("could not open dump file %qs: %s", name, strerror (errno));
9c5a221c 928 else
6de9cd9a 929 dfi->state = 1;
9c5a221c 930 free (name);
6de9cd9a 931
9c5a221c 932 if (flag_ptr)
6de9cd9a 933 *flag_ptr = dfi->flags;
d92b4486 934
9c5a221c
BM
935 return stream;
936}
937
7f3b2bda
GDR
938/* Returns nonzero if tree dump PHASE is enabled. If PHASE is
939 TDI_tree_all, return nonzero if any dump is enabled. */
9c5a221c
BM
940
941int
79a490a9 942dump_enabled_p (enum tree_dump_index phase)
9c5a221c 943{
7f3b2bda
GDR
944 if (phase == TDI_tree_all)
945 {
946 size_t i;
947 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
948 if (dump_files[i].state)
949 return 1;
950 for (i = 0; i < extra_dump_files_in_use; i++)
951 if (extra_dump_files[i].state)
952 return 1;
953 return 0;
954 }
955 else
956 {
957 struct dump_file_info *dfi = get_dump_file_info (phase);
958 return dfi->state;
959 }
9c5a221c
BM
960}
961
9f8628ba
PB
962/* Returns nonzero if tree dump PHASE has been initialized. */
963
964int
965dump_initialized_p (enum tree_dump_index phase)
966{
967 struct dump_file_info *dfi = get_dump_file_info (phase);
968 return dfi->state > 0;
969}
970
9c5a221c
BM
971/* Returns the switch name of PHASE. */
972
973const char *
79a490a9 974dump_flag_name (enum tree_dump_index phase)
9c5a221c 975{
6de9cd9a
DN
976 struct dump_file_info *dfi = get_dump_file_info (phase);
977 return dfi->swtch;
9c5a221c
BM
978}
979
980/* Finish a tree dump for PHASE. STREAM is the stream created by
981 dump_begin. */
982
983void
79a490a9 984dump_end (enum tree_dump_index phase ATTRIBUTE_UNUSED, FILE *stream)
9c5a221c
BM
985{
986 fclose (stream);
987}
988
9f8628ba 989/* Enable all tree dumps. Return number of enabled tree dumps. */
6de9cd9a 990
9f8628ba 991static int
9e016eba 992dump_enable_all (int flags)
6de9cd9a 993{
52bca999 994 int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
9f8628ba 995 int n = 0;
6de9cd9a
DN
996 size_t i;
997
998 for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
9e016eba 999 if ((dump_files[i].flags & ir_dump_type))
9f8628ba
PB
1000 {
1001 dump_files[i].state = -1;
a68e7e6c 1002 dump_files[i].flags |= flags;
9f8628ba
PB
1003 n++;
1004 }
6de9cd9a
DN
1005
1006 for (i = 0; i < extra_dump_files_in_use; i++)
9e016eba 1007 if ((extra_dump_files[i].flags & ir_dump_type))
9f8628ba
PB
1008 {
1009 extra_dump_files[i].state = -1;
a68e7e6c 1010 extra_dump_files[i].flags |= flags;
9f8628ba
PB
1011 n++;
1012 }
6de9cd9a 1013
9f8628ba 1014 return n;
6de9cd9a
DN
1015}
1016
0e9e1e0a 1017/* Parse ARG as a dump switch. Return nonzero if it is, and store the
9c5a221c
BM
1018 relevant details in the dump_files array. */
1019
6de9cd9a 1020static int
f46fe224 1021dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
9c5a221c 1022{
9c5a221c 1023 const char *option_value;
6de9cd9a
DN
1024 const char *ptr;
1025 int flags;
f46fe224
DB
1026
1027 if (doglob && !dfi->glob)
1028 return 0;
d92b4486 1029
f46fe224 1030 option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
6de9cd9a
DN
1031 if (!option_value)
1032 return 0;
d92b4486 1033
702f9d78
ZD
1034 if (*option_value && *option_value != '-')
1035 return 0;
1036
6de9cd9a
DN
1037 ptr = option_value;
1038 flags = 0;
1039
1040 while (*ptr)
1041 {
1042 const struct dump_option_value_info *option_ptr;
1043 const char *end_ptr;
1044 unsigned length;
1045
1046 while (*ptr == '-')
1047 ptr++;
1048 end_ptr = strchr (ptr, '-');
1049 if (!end_ptr)
1050 end_ptr = ptr + strlen (ptr);
1051 length = end_ptr - ptr;
1052
1053 for (option_ptr = dump_options; option_ptr->name; option_ptr++)
1054 if (strlen (option_ptr->name) == length
1055 && !memcmp (option_ptr->name, ptr, length))
9c5a221c 1056 {
6de9cd9a
DN
1057 flags |= option_ptr->value;
1058 goto found;
9c5a221c 1059 }
d4ee4d25 1060 warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
6de9cd9a
DN
1061 length, ptr, dfi->swtch);
1062 found:;
1063 ptr = end_ptr;
1064 }
1065
1066 dfi->state = -1;
9f8628ba 1067 dfi->flags |= flags;
6de9cd9a 1068
9f8628ba
PB
1069 /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
1070 known dumps. */
6de9cd9a 1071 if (dfi->suffix == NULL)
9e016eba 1072 dump_enable_all (dfi->flags);
6de9cd9a
DN
1073
1074 return 1;
1075}
d92b4486 1076
6de9cd9a
DN
1077int
1078dump_switch_p (const char *arg)
1079{
1080 size_t i;
1081 int any = 0;
1082
1083 for (i = TDI_none + 1; i != TDI_end; i++)
f46fe224
DB
1084 any |= dump_switch_p_1 (arg, &dump_files[i], false);
1085
1086 /* Don't glob if we got a hit already */
1087 if (!any)
1088 for (i = TDI_none + 1; i != TDI_end; i++)
1089 any |= dump_switch_p_1 (arg, &dump_files[i], true);
6de9cd9a
DN
1090
1091 for (i = 0; i < extra_dump_files_in_use; i++)
f46fe224
DB
1092 any |= dump_switch_p_1 (arg, &extra_dump_files[i], false);
1093
1094 if (!any)
1095 for (i = 0; i < extra_dump_files_in_use; i++)
1096 any |= dump_switch_p_1 (arg, &extra_dump_files[i], true);
1097
6de9cd9a
DN
1098
1099 return any;
1100}
d92b4486 1101
6de9cd9a
DN
1102/* Dump FUNCTION_DECL FN as tree dump PHASE. */
1103
1104void
1105dump_function (enum tree_dump_index phase, tree fn)
1106{
1107 FILE *stream;
1108 int flags;
1109
1110 stream = dump_begin (phase, &flags);
1111 if (stream)
1112 {
1113 dump_function_to_file (fn, stream, flags);
1114 dump_end (phase, stream);
1115 }
9c5a221c 1116}
9f8628ba
PB
1117
1118bool
9e016eba 1119enable_rtl_dump_file (void)
9f8628ba 1120{
9e016eba 1121 return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS) > 0;
9f8628ba
PB
1122}
1123
1124
This page took 2.971817 seconds and 5 git commands to generate.