1 | /* Prints out tree in human readable form - GCC |
2 | Copyright (C) 1990-2023 Free Software Foundation, Inc. |
3 | |
4 | This file is part of GCC. |
5 | |
6 | GCC is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free |
8 | Software Foundation; either version 3, or (at your option) any later |
9 | version. |
10 | |
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along 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 | |
44 | static hash_set<tree> *table = NULL; |
45 | |
46 | /* Print PREFIX and ADDR to FILE. */ |
47 | void |
48 | dump_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 | |
59 | static void |
60 | print_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 | |
123 | void |
124 | print_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 | |
207 | void |
208 | indent_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 | |
222 | void |
223 | print_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 | |
1059 | void |
1060 | print_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 | |
1141 | DEBUG_FUNCTION void |
1142 | debug_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 | |
1151 | DEBUG_FUNCTION void |
1152 | debug_raw (const tree_node &ref) |
1153 | { |
1154 | debug_tree (node: const_cast <tree> (&ref)); |
1155 | } |
1156 | |
1157 | DEBUG_FUNCTION void |
1158 | debug_raw (const tree_node *ptr) |
1159 | { |
1160 | if (ptr) |
1161 | debug_raw (ref: *ptr); |
1162 | else |
1163 | fprintf (stderr, format: "<nil>\n" ); |
1164 | } |
1165 | |
1166 | static void |
1167 | dump_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 | |
1180 | DEBUG_FUNCTION void |
1181 | debug (const tree_node &ref) |
1182 | { |
1183 | dump_tree_via_hooks (ptr: &ref, options: TDF_NONE); |
1184 | } |
1185 | |
1186 | DEBUG_FUNCTION void |
1187 | debug (const tree_node *ptr) |
1188 | { |
1189 | if (ptr) |
1190 | debug (ref: *ptr); |
1191 | else |
1192 | fprintf (stderr, format: "<nil>\n" ); |
1193 | } |
1194 | |
1195 | DEBUG_FUNCTION void |
1196 | debug_head (const tree_node &ref) |
1197 | { |
1198 | debug (ref); |
1199 | } |
1200 | |
1201 | DEBUG_FUNCTION void |
1202 | debug_head (const tree_node *ptr) |
1203 | { |
1204 | if (ptr) |
1205 | debug_head (ref: *ptr); |
1206 | else |
1207 | fprintf (stderr, format: "<nil>\n" ); |
1208 | } |
1209 | |
1210 | DEBUG_FUNCTION void |
1211 | debug_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 | |
1219 | DEBUG_FUNCTION void |
1220 | debug_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 | |
1232 | DEBUG_FUNCTION void |
1233 | debug_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 | |
1249 | DEBUG_FUNCTION void |
1250 | debug_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 | |
1258 | static void |
1259 | debug_slim (tree t) |
1260 | { |
1261 | print_node_brief (stderr, prefix: "" , node: t, indent: 0); |
1262 | } |
1263 | |
1264 | DEFINE_DEBUG_VEC (tree) |
1265 | DEFINE_DEBUG_HASH_SET (tree) |
1266 | |