1/* Prints out tree in human readable form - GCC
2 Copyright (C) 1990-2023 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "tree.h"
26#include "cgraph.h"
27#include "diagnostic.h"
28#include "varasm.h"
29#include "print-rtl.h"
30#include "stor-layout.h"
31#include "langhooks.h"
32#include "tree-iterator.h"
33#include "gimple-pretty-print.h" /* FIXME */
34#include "tree-cfg.h"
35#include "dumpfile.h"
36#include "print-tree.h"
37#include "file-prefix-map.h"
38
39/* Define the hash table of nodes already seen.
40 Such nodes are not repeated; brief cross-references are used. */
41
42#define HASH_SIZE 37
43
44static hash_set<tree> *table = NULL;
45
46/* Print PREFIX and ADDR to FILE. */
47void
48dump_addr (FILE *file, const char *prefix, const void *addr)
49{
50 if (flag_dump_noaddr || flag_dump_unnumbered)
51 fprintf (stream: file, format: "%s#", prefix);
52 else
53 fprintf (stream: file, format: "%s" HOST_PTR_PRINTF, prefix, addr);
54}
55
56/* Print to FILE a NODE representing a REAL_CST constant, including
57 Infinity and NaN. Be verbose when BFRIEF is false. */
58
59static void
60print_real_cst (FILE *file, const_tree node, bool brief)
61{
62 if (TREE_OVERFLOW (node))
63 fprintf (stream: file, format: " overflow");
64
65 REAL_VALUE_TYPE d = TREE_REAL_CST (node);
66 if (REAL_VALUE_ISINF (d))
67 fprintf (stream: file, REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
68 else if (REAL_VALUE_ISNAN (d))
69 {
70 /* Print a NaN in the format [-][Q]NaN[(significand[exponent])]
71 where significand is a hexadecimal string that starts with
72 the 0x prefix followed by 0 if the number is not canonical
73 and a non-zero digit if it is, and exponent is decimal. */
74 unsigned start = 0;
75 const char *psig = (const char *) d.sig;
76 for (unsigned i = 0; i != sizeof d.sig; ++i)
77 if (psig[i])
78 {
79 start = i;
80 break;
81 }
82
83 fprintf (stream: file, format: " %s%sNaN", d.sign ? "-" : "",
84 d.signalling ? "S" : "Q");
85
86 if (brief)
87 return;
88
89 if (start)
90 fprintf (stream: file, format: "(0x%s", d.canonical ? "" : "0");
91 else if (d.uexp)
92 fprintf (stream: file, format: "(%s", d.canonical ? "" : "0");
93 else if (!d.canonical)
94 {
95 fprintf (stream: file, format: "(0)");
96 return;
97 }
98
99 if (psig[start])
100 {
101 for (unsigned i = start; i != sizeof d.sig; ++i)
102 if (i == start)
103 fprintf (stream: file, format: "%x", psig[i]);
104 else
105 fprintf (stream: file, format: "%02x", psig[i]);
106 }
107
108 if (d.uexp)
109 fprintf (stream: file, format: "%se%u)", psig[start] ? "," : "", d.uexp);
110 else if (psig[start])
111 fputc (c: ')', stream: file);
112 }
113 else
114 {
115 char string[64];
116 real_to_decimal (string, &d, sizeof (string), 0, 1);
117 fprintf (stream: file, format: " %s", string);
118 }
119}
120
121/* Print a node in brief fashion, with just the code, address and name. */
122
123void
124print_node_brief (FILE *file, const char *prefix, const_tree node, int indent)
125{
126 enum tree_code_class tclass;
127
128 if (node == 0)
129 return;
130
131 tclass = TREE_CODE_CLASS (TREE_CODE (node));
132
133 /* Always print the slot this node is in, and its code, address and
134 name if any. */
135 if (indent > 0)
136 fprintf (stream: file, format: " ");
137 fprintf (stream: file, format: "%s <%s", prefix, get_tree_code_name (TREE_CODE (node)));
138 dump_addr (file, prefix: " ", addr: node);
139
140 if (tclass == tcc_declaration)
141 {
142 if (DECL_NAME (node))
143 fprintf (stream: file, format: " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
144 else if (TREE_CODE (node) == LABEL_DECL
145 && LABEL_DECL_UID (node) != -1)
146 {
147 if (dump_flags & TDF_NOUID)
148 fprintf (stream: file, format: " L.xxxx");
149 else
150 fprintf (stream: file, format: " L.%d", (int) LABEL_DECL_UID (node));
151 }
152 else
153 {
154 if (dump_flags & TDF_NOUID)
155 fprintf (stream: file, format: " %c.xxxx",
156 TREE_CODE (node) == CONST_DECL ? 'C' : 'D');
157 else
158 fprintf (stream: file, format: " %c.%u",
159 TREE_CODE (node) == CONST_DECL ? 'C' : 'D',
160 DECL_UID (node));
161 }
162 }
163 else if (tclass == tcc_type)
164 {
165 if (TYPE_NAME (node))
166 {
167 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
168 fprintf (stream: file, format: " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
169 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
170 && DECL_NAME (TYPE_NAME (node)))
171 fprintf (stream: file, format: " %s",
172 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
173 }
174 if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
175 fprintf (stream: file, format: " address-space-%d", TYPE_ADDR_SPACE (node));
176 }
177 if (TREE_CODE (node) == IDENTIFIER_NODE)
178 fprintf (stream: file, format: " %s", IDENTIFIER_POINTER (node));
179
180 /* We might as well always print the value of an integer or real. */
181 if (TREE_CODE (node) == INTEGER_CST)
182 {
183 if (TREE_OVERFLOW (node))
184 fprintf (stream: file, format: " overflow");
185
186 fprintf (stream: file, format: " ");
187 print_dec (wi: wi::to_wide (t: node), file, TYPE_SIGN (TREE_TYPE (node)));
188 }
189 if (TREE_CODE (node) == REAL_CST)
190 print_real_cst (file, node, brief: true);
191 if (TREE_CODE (node) == FIXED_CST)
192 {
193 FIXED_VALUE_TYPE f;
194 char string[60];
195
196 if (TREE_OVERFLOW (node))
197 fprintf (stream: file, format: " overflow");
198
199 f = TREE_FIXED_CST (node);
200 fixed_to_decimal (str: string, &f, sizeof (string));
201 fprintf (stream: file, format: " %s", string);
202 }
203
204 fprintf (stream: file, format: ">");
205}
206
207void
208indent_to (FILE *file, int column)
209{
210 int i;
211
212 /* Since this is the long way, indent to desired column. */
213 if (column > 0)
214 fprintf (stream: file, format: "\n");
215 for (i = 0; i < column; i++)
216 fprintf (stream: file, format: " ");
217}
218
219/* Print the node NODE in full on file FILE, preceded by PREFIX,
220 starting in column INDENT. */
221
222void
223print_node (FILE *file, const char *prefix, tree node, int indent,
224 bool brief_for_visited)
225{
226 machine_mode mode;
227 enum tree_code_class tclass;
228 int len;
229 int i;
230 expanded_location xloc;
231 enum tree_code code;
232
233 if (node == 0)
234 return;
235
236 code = TREE_CODE (node);
237
238 /* It is unsafe to look at any other fields of a node with ERROR_MARK or
239 invalid code. */
240 if (code == ERROR_MARK || code >= MAX_TREE_CODES)
241 {
242 print_node_brief (file, prefix, node, indent);
243 return;
244 }
245
246 tclass = TREE_CODE_CLASS (code);
247
248 /* Don't get too deep in nesting. If the user wants to see deeper,
249 it is easy to use the address of a lowest-level node
250 as an argument in another call to debug_tree. */
251
252 if (indent > 24)
253 {
254 print_node_brief (file, prefix, node, indent);
255 return;
256 }
257
258 if (indent > 8 && (tclass == tcc_type || tclass == tcc_declaration))
259 {
260 print_node_brief (file, prefix, node, indent);
261 return;
262 }
263
264 /* Allow this function to be called if the table is not there. */
265 if (table)
266 {
267 /* If node is in the table, just mention its address. */
268 if (table->contains (k: node) && brief_for_visited)
269 {
270 print_node_brief (file, prefix, node, indent);
271 return;
272 }
273
274 table->add (k: node);
275 }
276
277 /* Indent to the specified column, since this is the long form. */
278 indent_to (file, column: indent);
279
280 /* Print the slot this node is in, and its code, and address. */
281 fprintf (stream: file, format: "%s <%s", prefix, get_tree_code_name (code));
282 dump_addr (file, prefix: " ", addr: node);
283
284 /* Print the name, if any. */
285 if (tclass == tcc_declaration)
286 {
287 if (DECL_NAME (node))
288 fprintf (stream: file, format: " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
289 else if (code == LABEL_DECL
290 && LABEL_DECL_UID (node) != -1)
291 {
292 if (dump_flags & TDF_NOUID)
293 fprintf (stream: file, format: " L.xxxx");
294 else
295 fprintf (stream: file, format: " L.%d", (int) LABEL_DECL_UID (node));
296 }
297 else
298 {
299 if (dump_flags & TDF_NOUID)
300 fprintf (stream: file, format: " %c.xxxx", code == CONST_DECL ? 'C' : 'D');
301 else
302 fprintf (stream: file, format: " %c.%u", code == CONST_DECL ? 'C' : 'D',
303 DECL_UID (node));
304 }
305 }
306 else if (tclass == tcc_type)
307 {
308 if (TYPE_NAME (node))
309 {
310 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
311 fprintf (stream: file, format: " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
312 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
313 && DECL_NAME (TYPE_NAME (node)))
314 fprintf (stream: file, format: " %s",
315 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
316 }
317 }
318 if (code == IDENTIFIER_NODE)
319 fprintf (stream: file, format: " %s", IDENTIFIER_POINTER (node));
320
321 if (code == INTEGER_CST)
322 {
323 if (indent <= 4)
324 print_node_brief (file, prefix: "type", TREE_TYPE (node), indent: indent + 4);
325 }
326 else if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
327 {
328 print_node (file, prefix: "type", TREE_TYPE (node), indent: indent + 4);
329 if (TREE_TYPE (node))
330 indent_to (file, column: indent + 3);
331 }
332
333 if (!TYPE_P (node) && TREE_SIDE_EFFECTS (node))
334 fputs (s: " side-effects", stream: file);
335
336 if (TYPE_P (node) ? TYPE_READONLY (node) : TREE_READONLY (node))
337 fputs (s: " readonly", stream: file);
338 if (TYPE_P (node) && TYPE_ATOMIC (node))
339 fputs (s: " atomic", stream: file);
340 if (!TYPE_P (node) && TREE_CONSTANT (node))
341 fputs (s: " constant", stream: file);
342 else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node))
343 fputs (s: " sizes-gimplified", stream: file);
344
345 if (TYPE_P (node) && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
346 fprintf (stream: file, format: " address-space-%d", TYPE_ADDR_SPACE (node));
347
348 if (TREE_ADDRESSABLE (node))
349 fputs (s: " addressable", stream: file);
350 if (TREE_THIS_VOLATILE (node))
351 fputs (s: " volatile", stream: file);
352 if (TREE_ASM_WRITTEN (node))
353 fputs (s: " asm_written", stream: file);
354 if (TREE_USED (node))
355 fputs (s: " used", stream: file);
356 if (TREE_NOTHROW (node))
357 fputs (s: " nothrow", stream: file);
358 if (TREE_PUBLIC (node))
359 fputs (s: " public", stream: file);
360 if (TREE_PRIVATE (node))
361 fputs (s: " private", stream: file);
362 if (TREE_PROTECTED (node))
363 fputs (s: " protected", stream: file);
364 if (TREE_STATIC (node))
365 fputs (s: code == CALL_EXPR ? " must-tail-call" : " static", stream: file);
366 if (TREE_DEPRECATED (node))
367 fputs (s: " deprecated", stream: file);
368 if (TREE_VISITED (node))
369 fputs (s: " visited", stream: file);
370
371 if (code != TREE_VEC && code != INTEGER_CST && code != SSA_NAME)
372 {
373 if (TREE_UNAVAILABLE (node))
374 fputs (s: " unavailable", stream: file);
375 if (TREE_LANG_FLAG_0 (node))
376 fputs (s: " tree_0", stream: file);
377 if (TREE_LANG_FLAG_1 (node))
378 fputs (s: " tree_1", stream: file);
379 if (TREE_LANG_FLAG_2 (node))
380 fputs (s: " tree_2", stream: file);
381 if (TREE_LANG_FLAG_3 (node))
382 fputs (s: " tree_3", stream: file);
383 if (TREE_LANG_FLAG_4 (node))
384 fputs (s: " tree_4", stream: file);
385 if (TREE_LANG_FLAG_5 (node))
386 fputs (s: " tree_5", stream: file);
387 if (TREE_LANG_FLAG_6 (node))
388 fputs (s: " tree_6", stream: file);
389 }
390
391 /* DECL_ nodes have additional attributes. */
392
393 switch (TREE_CODE_CLASS (code))
394 {
395 case tcc_declaration:
396 if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
397 {
398 if (DECL_UNSIGNED (node))
399 fputs (s: " unsigned", stream: file);
400 if (DECL_IGNORED_P (node))
401 fputs (s: " ignored", stream: file);
402 if (DECL_ABSTRACT_P (node))
403 fputs (s: " abstract", stream: file);
404 if (DECL_EXTERNAL (node))
405 fputs (s: " external", stream: file);
406 if (DECL_NONLOCAL (node))
407 fputs (s: " nonlocal", stream: file);
408 }
409 if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
410 {
411 if (DECL_WEAK (node))
412 fputs (s: " weak", stream: file);
413 if (DECL_IN_SYSTEM_HEADER (node))
414 fputs (s: " in_system_header", stream: file);
415 }
416 if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)
417 && code != LABEL_DECL
418 && code != FUNCTION_DECL
419 && DECL_REGISTER (node))
420 fputs (s: " regdecl", stream: file);
421
422 if (code == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
423 fputs (s: " suppress-debug", stream: file);
424
425 if (code == FUNCTION_DECL
426 && DECL_FUNCTION_SPECIFIC_TARGET (node))
427 fputs (s: " function-specific-target", stream: file);
428 if (code == FUNCTION_DECL
429 && DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node))
430 fputs (s: " function-specific-opt", stream: file);
431 if (code == FUNCTION_DECL && DECL_DECLARED_INLINE_P (node))
432 fputs (s: " autoinline", stream: file);
433 if (code == FUNCTION_DECL && DECL_UNINLINABLE (node))
434 fputs (s: " uninlinable", stream: file);
435 if (code == FUNCTION_DECL && fndecl_built_in_p (node))
436 fputs (s: " built-in", stream: file);
437 if (code == FUNCTION_DECL && DECL_STATIC_CHAIN (node))
438 fputs (s: " static-chain", stream: file);
439 if (TREE_CODE (node) == FUNCTION_DECL && decl_is_tm_clone (fndecl: node))
440 fputs (s: " tm-clone", stream: file);
441
442 if (code == FIELD_DECL && DECL_PACKED (node))
443 fputs (s: " packed", stream: file);
444 if (code == FIELD_DECL && DECL_BIT_FIELD (node))
445 fputs (s: " bit-field", stream: file);
446 if (code == FIELD_DECL && DECL_NONADDRESSABLE_P (node))
447 fputs (s: " nonaddressable", stream: file);
448
449 if (code == LABEL_DECL && EH_LANDING_PAD_NR (node))
450 fprintf (stream: file, format: " landing-pad:%d", EH_LANDING_PAD_NR (node));
451
452 if (code == VAR_DECL && DECL_IN_TEXT_SECTION (node))
453 fputs (s: " in-text-section", stream: file);
454 if (code == VAR_DECL && DECL_IN_CONSTANT_POOL (node))
455 fputs (s: " in-constant-pool", stream: file);
456 if (code == VAR_DECL && DECL_COMMON (node))
457 fputs (s: " common", stream: file);
458 if ((code == VAR_DECL || code == PARM_DECL) && DECL_READ_P (node))
459 fputs (s: " read", stream: file);
460 if (code == VAR_DECL && DECL_THREAD_LOCAL_P (node))
461 {
462 fputs (s: " ", stream: file);
463 fputs (s: tls_model_names[DECL_TLS_MODEL (node)], stream: file);
464 }
465
466 if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
467 {
468 if (DECL_VIRTUAL_P (node))
469 fputs (s: " virtual", stream: file);
470 if (DECL_PRESERVE_P (node))
471 fputs (s: " preserve", stream: file);
472 if (DECL_LANG_FLAG_0 (node))
473 fputs (s: " decl_0", stream: file);
474 if (DECL_LANG_FLAG_1 (node))
475 fputs (s: " decl_1", stream: file);
476 if (DECL_LANG_FLAG_2 (node))
477 fputs (s: " decl_2", stream: file);
478 if (DECL_LANG_FLAG_3 (node))
479 fputs (s: " decl_3", stream: file);
480 if (DECL_LANG_FLAG_4 (node))
481 fputs (s: " decl_4", stream: file);
482 if (DECL_LANG_FLAG_5 (node))
483 fputs (s: " decl_5", stream: file);
484 if (DECL_LANG_FLAG_6 (node))
485 fputs (s: " decl_6", stream: file);
486 if (DECL_LANG_FLAG_7 (node))
487 fputs (s: " decl_7", stream: file);
488 if (DECL_LANG_FLAG_8 (node))
489 fputs (s: " decl_8", stream: file);
490
491 mode = DECL_MODE (node);
492 fprintf (stream: file, format: " %s", GET_MODE_NAME (mode));
493 }
494
495 if ((code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
496 && DECL_BY_REFERENCE (node))
497 fputs (s: " passed-by-reference", stream: file);
498
499 if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS) && DECL_DEFER_OUTPUT (node))
500 fputs (s: " defer-output", stream: file);
501
502
503 xloc = expand_location (DECL_SOURCE_LOCATION (node));
504 fprintf (stream: file, format: " %s:%d:%d", xloc.file, xloc.line,
505 xloc.column);
506
507 if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
508 {
509 print_node (file, prefix: "size", DECL_SIZE (node), indent: indent + 4);
510 print_node (file, prefix: "unit-size", DECL_SIZE_UNIT (node), indent: indent + 4);
511
512 if (code != FUNCTION_DECL || fndecl_built_in_p (node))
513 indent_to (file, column: indent + 3);
514
515 if (DECL_USER_ALIGN (node))
516 fprintf (stream: file, format: " user");
517
518 fprintf (stream: file, format: " align:%d warn_if_not_align:%d",
519 DECL_ALIGN (node), DECL_WARN_IF_NOT_ALIGN (node));
520 if (code == FIELD_DECL)
521 {
522 fprintf (stream: file, format: " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
523 DECL_OFFSET_ALIGN (node));
524 fprintf (stream: file, format: " decl_not_flexarray: %d",
525 DECL_NOT_FLEXARRAY (node));
526 }
527
528 if (code == FUNCTION_DECL && fndecl_built_in_p (node))
529 {
530 if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
531 fprintf (stream: file, format: " built-in: BUILT_IN_MD:%d",
532 DECL_MD_FUNCTION_CODE (decl: node));
533 else if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_FRONTEND)
534 fprintf (stream: file, format: " built-in: BUILT_IN_FRONTEND:%d",
535 DECL_FE_FUNCTION_CODE (decl: node));
536 else
537 fprintf (stream: file, format: " built-in: %s:%s",
538 built_in_class_names[(int) DECL_BUILT_IN_CLASS (node)],
539 built_in_names[(int) DECL_FUNCTION_CODE (decl: node)]);
540 }
541 }
542 if (code == FIELD_DECL)
543 {
544 print_node (file, prefix: "offset", DECL_FIELD_OFFSET (node), indent: indent + 4);
545 print_node (file, prefix: "bit-offset", DECL_FIELD_BIT_OFFSET (node),
546 indent: indent + 4);
547 if (DECL_BIT_FIELD_TYPE (node))
548 print_node (file, prefix: "bit_field_type", DECL_BIT_FIELD_TYPE (node),
549 indent: indent + 4);
550 }
551
552 print_node_brief (file, prefix: "context", DECL_CONTEXT (node), indent: indent + 4);
553
554 if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
555 {
556 print_node (file, prefix: "attributes",
557 DECL_ATTRIBUTES (node), indent: indent + 4);
558 if (code != PARM_DECL)
559 print_node_brief (file, prefix: "initial", DECL_INITIAL (node),
560 indent: indent + 4);
561 }
562 if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
563 {
564 print_node_brief (file, prefix: "abstract_origin",
565 DECL_ABSTRACT_ORIGIN (node), indent: indent + 4);
566 }
567 if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
568 {
569 print_node (file, prefix: "result", DECL_RESULT_FLD (node), indent: indent + 4);
570 }
571
572 lang_hooks.print_decl (file, node, indent);
573
574 if (DECL_RTL_SET_P (node))
575 {
576 indent_to (file, column: indent + 4);
577 print_rtl (file, DECL_RTL (node));
578 }
579
580 if (code == PARM_DECL)
581 {
582 print_node (file, prefix: "arg-type", DECL_ARG_TYPE (node), indent: indent + 4);
583
584 if (DECL_INCOMING_RTL (node) != 0)
585 {
586 indent_to (file, column: indent + 4);
587 fprintf (stream: file, format: "incoming-rtl ");
588 print_rtl (file, DECL_INCOMING_RTL (node));
589 }
590 }
591 else if (code == FUNCTION_DECL
592 && DECL_STRUCT_FUNCTION (node) != 0)
593 {
594 print_node (file, prefix: "arguments", DECL_ARGUMENTS (node), indent: indent + 4);
595 indent_to (file, column: indent + 4);
596 dump_addr (file, prefix: "struct-function ", DECL_STRUCT_FUNCTION (node));
597 }
598
599 if ((code == VAR_DECL || code == PARM_DECL)
600 && DECL_HAS_VALUE_EXPR_P (node))
601 print_node (file, prefix: "value-expr", DECL_VALUE_EXPR (node), indent: indent + 4);
602
603 /* Print the decl chain only if decl is at second level. */
604 if (indent == 4)
605 print_node (file, prefix: "chain", TREE_CHAIN (node), indent: indent + 4);
606 else
607 print_node_brief (file, prefix: "chain", TREE_CHAIN (node), indent: indent + 4);
608 break;
609
610 case tcc_type:
611 if (TYPE_UNSIGNED (node))
612 fputs (s: " unsigned", stream: file);
613
614 if (TYPE_NO_FORCE_BLK (node))
615 fputs (s: " no-force-blk", stream: file);
616
617 if (code == ARRAY_TYPE && TYPE_STRING_FLAG (node))
618 fputs (s: " string-flag", stream: file);
619
620 if (TYPE_NEEDS_CONSTRUCTING (node))
621 fputs (s: " needs-constructing", stream: file);
622
623 if ((code == RECORD_TYPE
624 || code == UNION_TYPE
625 || code == QUAL_UNION_TYPE
626 || code == ARRAY_TYPE)
627 && TYPE_REVERSE_STORAGE_ORDER (node))
628 fputs (s: " reverse-storage-order", stream: file);
629
630 if ((code == RECORD_TYPE
631 || code == UNION_TYPE)
632 && TYPE_CXX_ODR_P (node))
633 fputs (s: " cxx-odr-p", stream: file);
634
635 if ((code == RECORD_TYPE
636 || code == UNION_TYPE)
637 && TYPE_INCLUDES_FLEXARRAY (node))
638 fputs (s: " includes-flexarray", stream: file);
639
640 /* The transparent-union flag is used for different things in
641 different nodes. */
642 if ((code == UNION_TYPE || code == RECORD_TYPE)
643 && TYPE_TRANSPARENT_AGGR (node))
644 fputs (s: " transparent-aggr", stream: file);
645 else if (code == ARRAY_TYPE
646 && TYPE_NONALIASED_COMPONENT (node))
647 fputs (s: " nonaliased-component", stream: file);
648
649 if (TYPE_PACKED (node))
650 fputs (s: " packed", stream: file);
651
652 if (TYPE_RESTRICT (node))
653 fputs (s: " restrict", stream: file);
654
655 if (TYPE_LANG_FLAG_0 (node))
656 fputs (s: " type_0", stream: file);
657 if (TYPE_LANG_FLAG_1 (node))
658 fputs (s: " type_1", stream: file);
659 if (TYPE_LANG_FLAG_2 (node))
660 fputs (s: " type_2", stream: file);
661 if (TYPE_LANG_FLAG_3 (node))
662 fputs (s: " type_3", stream: file);
663 if (TYPE_LANG_FLAG_4 (node))
664 fputs (s: " type_4", stream: file);
665 if (TYPE_LANG_FLAG_5 (node))
666 fputs (s: " type_5", stream: file);
667 if (TYPE_LANG_FLAG_6 (node))
668 fputs (s: " type_6", stream: file);
669 if (TYPE_LANG_FLAG_7 (node))
670 fputs (s: " type_7", stream: file);
671
672 mode = TYPE_MODE (node);
673 fprintf (stream: file, format: " %s", GET_MODE_NAME (mode));
674
675 print_node (file, prefix: "size", TYPE_SIZE (node), indent: indent + 4);
676 print_node (file, prefix: "unit-size", TYPE_SIZE_UNIT (node), indent: indent + 4);
677 indent_to (file, column: indent + 3);
678
679 if (TYPE_USER_ALIGN (node))
680 fprintf (stream: file, format: " user");
681
682 fprintf (stream: file, format: " align:%d warn_if_not_align:%d symtab:%d alias-set "
683 HOST_WIDE_INT_PRINT_DEC,
684 TYPE_ALIGN (node), TYPE_WARN_IF_NOT_ALIGN (node),
685 TYPE_SYMTAB_ADDRESS (node),
686 (HOST_WIDE_INT) TYPE_ALIAS_SET (node));
687
688 if (TYPE_STRUCTURAL_EQUALITY_P (node))
689 fprintf (stream: file, format: " structural-equality");
690 else
691 dump_addr (file, prefix: " canonical-type ", TYPE_CANONICAL (node));
692
693 print_node (file, prefix: "attributes", TYPE_ATTRIBUTES (node), indent: indent + 4);
694
695 if (INTEGRAL_TYPE_P (node) || code == REAL_TYPE
696 || code == FIXED_POINT_TYPE)
697 {
698 fprintf (stream: file, format: " precision:%d", TYPE_PRECISION (node));
699 print_node_brief (file, prefix: "min", TYPE_MIN_VALUE (node), indent: indent + 4);
700 print_node_brief (file, prefix: "max", TYPE_MAX_VALUE (node), indent: indent + 4);
701 }
702
703 if (code == ENUMERAL_TYPE)
704 print_node (file, prefix: "values", TYPE_VALUES (node), indent: indent + 4);
705 else if (code == ARRAY_TYPE)
706 print_node (file, prefix: "domain", TYPE_DOMAIN (node), indent: indent + 4);
707 else if (code == VECTOR_TYPE)
708 {
709 fprintf (stream: file, format: " nunits:");
710 print_dec (value: TYPE_VECTOR_SUBPARTS (node), file);
711 }
712 else if (code == RECORD_TYPE
713 || code == UNION_TYPE
714 || code == QUAL_UNION_TYPE)
715 print_node (file, prefix: "fields", TYPE_FIELDS (node), indent: indent + 4);
716 else if (code == FUNCTION_TYPE
717 || code == METHOD_TYPE)
718 {
719 if (TYPE_METHOD_BASETYPE (node))
720 print_node_brief (file, prefix: "method basetype",
721 TYPE_METHOD_BASETYPE (node), indent: indent + 4);
722 print_node (file, prefix: "arg-types", TYPE_ARG_TYPES (node), indent: indent + 4);
723 }
724 else if (code == OFFSET_TYPE)
725 print_node_brief (file, prefix: "basetype", TYPE_OFFSET_BASETYPE (node),
726 indent: indent + 4);
727
728 if (TYPE_CONTEXT (node))
729 print_node_brief (file, prefix: "context", TYPE_CONTEXT (node), indent: indent + 4);
730
731 lang_hooks.print_type (file, node, indent);
732
733 if (TYPE_POINTER_TO (node) || TREE_CHAIN (node))
734 indent_to (file, column: indent + 3);
735
736 print_node_brief (file, prefix: "pointer_to_this", TYPE_POINTER_TO (node),
737 indent: indent + 4);
738 print_node_brief (file, prefix: "reference_to_this", TYPE_REFERENCE_TO (node),
739 indent: indent + 4);
740 print_node_brief (file, prefix: "chain", TREE_CHAIN (node), indent: indent + 4);
741 break;
742
743 case tcc_expression:
744 case tcc_comparison:
745 case tcc_unary:
746 case tcc_binary:
747 case tcc_reference:
748 case tcc_statement:
749 case tcc_vl_exp:
750 if (code == BIND_EXPR)
751 {
752 print_node (file, prefix: "vars", TREE_OPERAND (node, 0), indent: indent + 4);
753 print_node (file, prefix: "body", TREE_OPERAND (node, 1), indent: indent + 4);
754 print_node (file, prefix: "block", TREE_OPERAND (node, 2), indent: indent + 4);
755 break;
756 }
757 if (code == CALL_EXPR)
758 {
759 print_node (file, prefix: "fn", CALL_EXPR_FN (node), indent: indent + 4);
760 print_node (file, prefix: "static_chain", CALL_EXPR_STATIC_CHAIN (node),
761 indent: indent + 4);
762
763 call_expr_arg_iterator iter;
764 init_call_expr_arg_iterator (exp: node, iter: &iter);
765 while (more_call_expr_args_p (iter: &iter))
766 {
767 /* Buffer big enough to format a 32-bit UINT_MAX into, plus
768 the text. */
769 char temp[15];
770 sprintf (s: temp, format: "arg:%u", iter.i);
771 tree arg = next_call_expr_arg (iter: &iter);
772 if (arg)
773 print_node (file, prefix: temp, node: arg, indent: indent + 4);
774 else
775 {
776 indent_to (file, column: indent + 4);
777 fprintf (stream: file, format: "%s NULL", temp);
778 }
779 }
780 }
781 else
782 {
783 len = TREE_OPERAND_LENGTH (node);
784
785 for (i = 0; i < len; i++)
786 {
787 /* Buffer big enough to format a 32-bit UINT_MAX into, plus
788 the text. */
789 char temp[16];
790
791 sprintf (s: temp, format: "arg:%d", i);
792 print_node (file, prefix: temp, TREE_OPERAND (node, i), indent: indent + 4);
793 }
794 }
795 if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
796 print_node (file, prefix: "chain", TREE_CHAIN (node), indent: indent + 4);
797 break;
798
799 case tcc_constant:
800 case tcc_exceptional:
801 switch (code)
802 {
803 case INTEGER_CST:
804 if (TREE_OVERFLOW (node))
805 fprintf (stream: file, format: " overflow");
806
807 fprintf (stream: file, format: " ");
808 print_dec (wi: wi::to_wide (t: node), file, TYPE_SIGN (TREE_TYPE (node)));
809 break;
810
811 case REAL_CST:
812 print_real_cst (file, node, brief: false);
813 break;
814
815 case FIXED_CST:
816 {
817 FIXED_VALUE_TYPE f;
818 char string[64];
819
820 if (TREE_OVERFLOW (node))
821 fprintf (stream: file, format: " overflow");
822
823 f = TREE_FIXED_CST (node);
824 fixed_to_decimal (str: string, &f, sizeof (string));
825 fprintf (stream: file, format: " %s", string);
826 }
827 break;
828
829 case VECTOR_CST:
830 {
831 /* Big enough for UINT_MAX plus the string below. */
832 char buf[32];
833
834 fprintf (stream: file, format: " npatterns:%u nelts-per-pattern:%u",
835 VECTOR_CST_NPATTERNS (node),
836 VECTOR_CST_NELTS_PER_PATTERN (node));
837 unsigned int count = vector_cst_encoded_nelts (t: node);
838 for (unsigned int i = 0; i < count; ++i)
839 {
840 sprintf (s: buf, format: "elt:%u: ", i);
841 print_node (file, prefix: buf, VECTOR_CST_ENCODED_ELT (node, i),
842 indent: indent + 4);
843 }
844 }
845 break;
846
847 case COMPLEX_CST:
848 print_node (file, prefix: "real", TREE_REALPART (node), indent: indent + 4);
849 print_node (file, prefix: "imag", TREE_IMAGPART (node), indent: indent + 4);
850 break;
851
852 case STRING_CST:
853 {
854 const char *p = TREE_STRING_POINTER (node);
855 int i = TREE_STRING_LENGTH (node);
856 fputs (s: " \"", stream: file);
857 while (--i >= 0)
858 {
859 char ch = *p++;
860 if (ch >= ' ' && ch < 127)
861 putc (c: ch, stream: file);
862 else
863 fprintf (stream: file, format: "\\%03o", ch & 0xFF);
864 }
865 fputc (c: '\"', stream: file);
866 }
867 break;
868
869 case POLY_INT_CST:
870 {
871 char buf[10];
872 for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
873 {
874 snprintf (s: buf, maxlen: sizeof (buf), format: "elt%u:", i);
875 print_node (file, prefix: buf, POLY_INT_CST_COEFF (node, i),
876 indent: indent + 4);
877 }
878 }
879 break;
880
881 case IDENTIFIER_NODE:
882 lang_hooks.print_identifier (file, node, indent);
883 break;
884
885 case TREE_LIST:
886 print_node (file, prefix: "purpose", TREE_PURPOSE (node), indent: indent + 4);
887 print_node (file, prefix: "value", TREE_VALUE (node), indent: indent + 4);
888 print_node (file, prefix: "chain", TREE_CHAIN (node), indent: indent + 4);
889 break;
890
891 case TREE_VEC:
892 len = TREE_VEC_LENGTH (node);
893 fprintf (stream: file, format: " length:%d", len);
894 for (i = 0; i < len; i++)
895 if (TREE_VEC_ELT (node, i))
896 {
897 /* Buffer big enough to format a 32-bit UINT_MAX into, plus
898 the text. */
899 char temp[16];
900 sprintf (s: temp, format: "elt:%d", i);
901 print_node (file, prefix: temp, TREE_VEC_ELT (node, i), indent: indent + 4);
902 }
903 break;
904
905 case CONSTRUCTOR:
906 {
907 unsigned HOST_WIDE_INT cnt;
908 tree index, value;
909 len = CONSTRUCTOR_NELTS (node);
910 fprintf (stream: file, format: " length:%d", len);
911 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node),
912 cnt, index, value)
913 {
914 print_node (file, prefix: "idx", node: index, indent: indent + 4, brief_for_visited: false);
915 print_node (file, prefix: "val", node: value, indent: indent + 4, brief_for_visited: false);
916 }
917 }
918 break;
919
920 case STATEMENT_LIST:
921 dump_addr (file, prefix: " head ", addr: node->stmt_list.head);
922 dump_addr (file, prefix: " tail ", addr: node->stmt_list.tail);
923 fprintf (stream: file, format: " stmts");
924 {
925 tree_stmt_iterator i;
926 for (i = tsi_start (t: node); !tsi_end_p (i); tsi_next (i: &i))
927 {
928 /* Not printing the addresses of the (not-a-tree)
929 'struct tree_stmt_list_node's. */
930 dump_addr (file, prefix: " ", addr: tsi_stmt (i));
931 }
932 fprintf (stream: file, format: "\n");
933 for (i = tsi_start (t: node); !tsi_end_p (i); tsi_next (i: &i))
934 {
935 /* Not printing the addresses of the (not-a-tree)
936 'struct tree_stmt_list_node's. */
937 print_node (file, prefix: "stmt", node: tsi_stmt (i), indent: indent + 4);
938 }
939 }
940 break;
941
942 case BLOCK:
943 print_node (file, prefix: "vars", BLOCK_VARS (node), indent: indent + 4);
944 print_node (file, prefix: "supercontext", BLOCK_SUPERCONTEXT (node),
945 indent: indent + 4);
946 print_node (file, prefix: "subblocks", BLOCK_SUBBLOCKS (node), indent: indent + 4);
947 print_node (file, prefix: "chain", BLOCK_CHAIN (node), indent: indent + 4);
948 print_node (file, prefix: "abstract_origin",
949 BLOCK_ABSTRACT_ORIGIN (node), indent: indent + 4);
950 break;
951
952 case SSA_NAME:
953 print_node_brief (file, prefix: "var", SSA_NAME_VAR (node), indent: indent + 4);
954 indent_to (file, column: indent + 4);
955 fprintf (stream: file, format: "def_stmt ");
956 {
957 pretty_printer buffer;
958 buffer.buffer->stream = file;
959 pp_gimple_stmt_1 (&buffer, SSA_NAME_DEF_STMT (node), indent + 4,
960 TDF_NONE);
961 pp_flush (&buffer);
962 }
963
964 indent_to (file, column: indent + 4);
965 fprintf (stream: file, format: "version:%u", SSA_NAME_VERSION (node));
966 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
967 fprintf (stream: file, format: " in-abnormal-phi");
968 if (SSA_NAME_IN_FREE_LIST (node))
969 fprintf (stream: file, format: " in-free-list");
970
971 if (SSA_NAME_PTR_INFO (node))
972 {
973 indent_to (file, column: indent + 3);
974 if (SSA_NAME_PTR_INFO (node))
975 dump_addr (file, prefix: " ptr-info ", SSA_NAME_PTR_INFO (node));
976 }
977 break;
978
979 case OMP_CLAUSE:
980 {
981 int i;
982 fprintf (stream: file, format: " %s",
983 omp_clause_code_name[OMP_CLAUSE_CODE (node)]);
984 for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (node)]; i++)
985 {
986 indent_to (file, column: indent + 4);
987 fprintf (stream: file, format: "op-%d:", i);
988 print_node_brief (file, prefix: "", OMP_CLAUSE_OPERAND (node, i), indent: 0);
989 }
990 }
991 break;
992
993 case OPTIMIZATION_NODE:
994 cl_optimization_print (file, indent + 4, TREE_OPTIMIZATION (node));
995 break;
996
997 case TARGET_OPTION_NODE:
998 cl_target_option_print (file, indent + 4, TREE_TARGET_OPTION (node));
999 break;
1000 case IMPORTED_DECL:
1001 fprintf (stream: file, format: " imported-declaration");
1002 print_node_brief (file, prefix: "associated-declaration",
1003 IMPORTED_DECL_ASSOCIATED_DECL (node),
1004 indent: indent + 4);
1005 break;
1006
1007 case TREE_BINFO:
1008 fprintf (stream: file, format: " bases:%d",
1009 vec_safe_length (BINFO_BASE_BINFOS (node)));
1010 print_node_brief (file, prefix: "offset", BINFO_OFFSET (node), indent: indent + 4);
1011 print_node_brief (file, prefix: "virtuals", BINFO_VIRTUALS (node),
1012 indent: indent + 4);
1013 print_node_brief (file, prefix: "inheritance-chain",
1014 BINFO_INHERITANCE_CHAIN (node),
1015 indent: indent + 4);
1016 break;
1017
1018 default:
1019 lang_hooks.print_xnode (file, node, indent);
1020 break;
1021 }
1022
1023 break;
1024 }
1025
1026 if (EXPR_HAS_LOCATION (node))
1027 {
1028 expanded_location xloc = expand_location (EXPR_LOCATION (node));
1029 indent_to (file, column: indent+4);
1030 fprintf (stream: file, format: "%s:%d:%d", xloc.file, xloc.line, xloc.column);
1031
1032 /* Print the range, if any */
1033 source_range r = EXPR_LOCATION_RANGE (node);
1034 if (r.m_start)
1035 {
1036 xloc = expand_location (r.m_start);
1037 fprintf (stream: file, format: " start: %s:%d:%d", xloc.file, xloc.line, xloc.column);
1038 }
1039 else
1040 {
1041 fprintf (stream: file, format: " start: unknown");
1042 }
1043 if (r.m_finish)
1044 {
1045 xloc = expand_location (r.m_finish);
1046 fprintf (stream: file, format: " finish: %s:%d:%d", xloc.file, xloc.line, xloc.column);
1047 }
1048 else
1049 {
1050 fprintf (stream: file, format: " finish: unknown");
1051 }
1052 }
1053
1054 fprintf (stream: file, format: ">");
1055}
1056
1057/* Print the identifier for DECL according to FLAGS. */
1058
1059void
1060print_decl_identifier (FILE *file, tree decl, int flags)
1061{
1062 bool needs_colon = false;
1063 const char *name;
1064 char c;
1065
1066 if (flags & PRINT_DECL_ORIGIN)
1067 {
1068 if (DECL_IS_UNDECLARED_BUILTIN (decl))
1069 fputs (s: "<built-in>", stream: file);
1070 else
1071 {
1072 expanded_location loc
1073 = expand_location (DECL_SOURCE_LOCATION (decl));
1074 const char *f = flags & PRINT_DECL_REMAP_DEBUG
1075 ? remap_debug_filename (loc.file)
1076 : loc.file;
1077 fprintf (stream: file, format: "%s:%d:%d", f, loc.line, loc.column);
1078 }
1079 needs_colon = true;
1080 }
1081
1082 if (flags & PRINT_DECL_UNIQUE_NAME)
1083 {
1084 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1085 if (!TREE_PUBLIC (decl)
1086 || (DECL_WEAK (decl) && !DECL_EXTERNAL (decl)))
1087 /* The symbol has internal or weak linkage so its assembler name
1088 is not necessarily unique among the compilation units of the
1089 program. We therefore have to further mangle it. But we can't
1090 simply use DECL_SOURCE_FILE because it contains the name of the
1091 file the symbol originates from so, e.g. for function templates
1092 in C++ where the templates are defined in a header file, we can
1093 have symbols with the same assembler name and DECL_SOURCE_FILE.
1094 That's why we use the name of the top-level source file of the
1095 compilation unit. ??? Unnecessary for Ada. */
1096 name = ACONCAT ((main_input_filename, ":", name, NULL));
1097 }
1098 else if (flags & PRINT_DECL_NAME)
1099 {
1100 /* We don't want to print the full qualified name because it can be long,
1101 so we strip the scope prefix, but we may need to deal with the suffix
1102 created by the compiler. */
1103 const char *suffix = strchr (IDENTIFIER_POINTER (DECL_NAME (decl)), c: '.');
1104 name = lang_hooks.decl_printable_name (decl, 2);
1105 if (suffix)
1106 {
1107 const char *dot = strchr (s: name, c: '.');
1108 while (dot && strcasecmp (s1: dot, s2: suffix) != 0)
1109 {
1110 name = dot + 1;
1111 dot = strchr (s: name, c: '.');
1112 }
1113 }
1114 else
1115 {
1116 const char *dot = strrchr (s: name, c: '.');
1117 if (dot)
1118 name = dot + 1;
1119 }
1120 }
1121 else
1122 return;
1123
1124 if (needs_colon)
1125 fputc (c: ':', stream: file);
1126
1127 while ((c = *name++) != '\0')
1128 {
1129 /* Strip double-quotes because of VCG. */
1130 if (c == '"')
1131 continue;
1132 fputc (c: c, stream: file);
1133 }
1134}
1135
1136
1137/* Print the node NODE on standard error, for debugging.
1138 Most nodes referred to by this one are printed recursively
1139 down to a depth of six. */
1140
1141DEBUG_FUNCTION void
1142debug_tree (tree node)
1143{
1144 table = new hash_set<tree> (HASH_SIZE);
1145 print_node (stderr, prefix: "", node, indent: 0);
1146 delete table;
1147 table = NULL;
1148 putc (c: '\n', stderr);
1149}
1150
1151DEBUG_FUNCTION void
1152debug_raw (const tree_node &ref)
1153{
1154 debug_tree (node: const_cast <tree> (&ref));
1155}
1156
1157DEBUG_FUNCTION void
1158debug_raw (const tree_node *ptr)
1159{
1160 if (ptr)
1161 debug_raw (ref: *ptr);
1162 else
1163 fprintf (stderr, format: "<nil>\n");
1164}
1165
1166static void
1167dump_tree_via_hooks (const tree_node *ptr, dump_flags_t options)
1168{
1169 if (DECL_P (ptr))
1170 lang_hooks.print_decl (stderr, const_cast <tree_node*> (ptr), 0);
1171 else if (TYPE_P (ptr))
1172 lang_hooks.print_type (stderr, const_cast <tree_node*> (ptr), 0);
1173 else if (TREE_CODE (ptr) == IDENTIFIER_NODE)
1174 lang_hooks.print_identifier (stderr, const_cast <tree_node*> (ptr), 0);
1175 else
1176 print_generic_expr (stderr, const_cast <tree_node*> (ptr), options);
1177 fprintf (stderr, format: "\n");
1178}
1179
1180DEBUG_FUNCTION void
1181debug (const tree_node &ref)
1182{
1183 dump_tree_via_hooks (ptr: &ref, options: TDF_NONE);
1184}
1185
1186DEBUG_FUNCTION void
1187debug (const tree_node *ptr)
1188{
1189 if (ptr)
1190 debug (ref: *ptr);
1191 else
1192 fprintf (stderr, format: "<nil>\n");
1193}
1194
1195DEBUG_FUNCTION void
1196debug_head (const tree_node &ref)
1197{
1198 debug (ref);
1199}
1200
1201DEBUG_FUNCTION void
1202debug_head (const tree_node *ptr)
1203{
1204 if (ptr)
1205 debug_head (ref: *ptr);
1206 else
1207 fprintf (stderr, format: "<nil>\n");
1208}
1209
1210DEBUG_FUNCTION void
1211debug_body (const tree_node &ref)
1212{
1213 if (TREE_CODE (&ref) == FUNCTION_DECL)
1214 dump_function_to_file (const_cast <tree_node*> (&ref), stderr, TDF_NONE);
1215 else
1216 debug (ref);
1217}
1218
1219DEBUG_FUNCTION void
1220debug_body (const tree_node *ptr)
1221{
1222 if (ptr)
1223 debug_body (ref: *ptr);
1224 else
1225 fprintf (stderr, format: "<nil>\n");
1226}
1227
1228/* Print the vector of trees VEC on standard error, for debugging.
1229 Most nodes referred to by this one are printed recursively
1230 down to a depth of six. */
1231
1232DEBUG_FUNCTION void
1233debug_raw (vec<tree, va_gc> &ref)
1234{
1235 tree elt;
1236 unsigned ix;
1237
1238 /* Print the slot this node is in, and its code, and address. */
1239 fprintf (stderr, format: "<VEC");
1240 dump_addr (stderr, prefix: " ", addr: ref.address ());
1241
1242 FOR_EACH_VEC_ELT (ref, ix, elt)
1243 {
1244 fprintf (stderr, format: "elt:%d ", ix);
1245 debug_raw (ptr: elt);
1246 }
1247}
1248
1249DEBUG_FUNCTION void
1250debug_raw (vec<tree, va_gc> *ptr)
1251{
1252 if (ptr)
1253 debug_raw (ref&: *ptr);
1254 else
1255 fprintf (stderr, format: "<nil>\n");
1256}
1257
1258static void
1259debug_slim (tree t)
1260{
1261 print_node_brief (stderr, prefix: "", node: t, indent: 0);
1262}
1263
1264DEFINE_DEBUG_VEC (tree)
1265DEFINE_DEBUG_HASH_SET (tree)
1266

source code of gcc/print-tree.cc