Line data Source code
1 : /* Prints out trees in human readable form.
2 : Copyright (C) 1992-2026 Free Software Foundation, Inc.
3 : Hacked by Michael Tiemann (tiemann@cygnus.com)
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 :
22 : #include "config.h"
23 : #include "system.h"
24 : #include "coretypes.h"
25 : #include "cp-tree.h"
26 : #include "print-tree.h"
27 :
28 : void
29 0 : cxx_print_decl (FILE *file, tree node, int indent)
30 : {
31 0 : if (TREE_CODE (node) == FIELD_DECL)
32 : {
33 0 : if (DECL_MUTABLE_P (node))
34 : {
35 0 : indent_to (file, indent + 3);
36 0 : fprintf (file, " mutable ");
37 : }
38 0 : return;
39 : }
40 :
41 0 : if (TREE_CODE (node) == FUNCTION_DECL)
42 : {
43 0 : int flags = TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
44 : |TFF_FUNCTION_DEFAULT_ARGUMENTS|TFF_EXCEPTION_SPECIFICATION ;
45 0 : indent_to (file, indent + 3);
46 0 : fprintf (file, " full-name \"%s\"", decl_as_string (node, flags));
47 : }
48 0 : else if (TREE_CODE (node) == TEMPLATE_DECL)
49 : {
50 0 : print_node (file, "result", DECL_TEMPLATE_RESULT (node), indent + 4);
51 0 : print_node (file, "parms", DECL_TEMPLATE_PARMS (node), indent + 4);
52 0 : indent_to (file, indent + 3);
53 0 : fprintf (file, " full-name \"%s\"",
54 : decl_as_string (node, TFF_TEMPLATE_HEADER));
55 : }
56 :
57 0 : bool need_indent = true;
58 :
59 0 : tree ntnode = STRIP_TEMPLATE (node);
60 0 : if (TREE_CODE (ntnode) == FUNCTION_DECL
61 : || TREE_CODE (ntnode) == VAR_DECL
62 : || TREE_CODE (ntnode) == TYPE_DECL
63 : || TREE_CODE (ntnode) == CONCEPT_DECL
64 : || TREE_CODE (ntnode) == NAMESPACE_DECL)
65 : {
66 0 : unsigned m = 0;
67 0 : if (DECL_LANG_SPECIFIC (ntnode) && DECL_MODULE_IMPORT_P (ntnode))
68 0 : m = get_importing_module (ntnode, true);
69 :
70 0 : if (const char *name = m == ~0u ? "" : module_name (m, true))
71 : {
72 0 : if (need_indent)
73 0 : indent_to (file, indent + 3);
74 0 : fprintf (file, " module %d:%s", m, name);
75 0 : need_indent = false;
76 : }
77 :
78 0 : if (DECL_LANG_SPECIFIC (ntnode))
79 : {
80 0 : if (DECL_MODULE_PURVIEW_P (ntnode))
81 : {
82 0 : if (need_indent)
83 0 : indent_to (file, indent + 3);
84 0 : fprintf (file, " purview");
85 0 : need_indent = false;
86 : }
87 0 : if (DECL_MODULE_ATTACH_P (ntnode))
88 : {
89 0 : if (need_indent)
90 0 : indent_to (file, indent + 3);
91 0 : fprintf (file, " attached");
92 0 : need_indent = false;
93 : }
94 : }
95 : }
96 :
97 0 : if (DECL_MODULE_EXPORT_P (node))
98 : {
99 0 : if (need_indent)
100 0 : indent_to (file, indent + 3);
101 0 : fprintf (file, " exported");
102 0 : need_indent = false;
103 : }
104 :
105 0 : if (!CODE_CONTAINS_STRUCT (TREE_CODE (node), TS_DECL_COMMON)
106 0 : || !DECL_LANG_SPECIFIC (node))
107 : return;
108 :
109 0 : if (DECL_EXTERNAL (node) && DECL_NOT_REALLY_EXTERN (node))
110 : {
111 0 : if (need_indent)
112 0 : indent_to (file, indent + 3);
113 0 : fprintf (file, " not-really-extern");
114 0 : need_indent = false;
115 : }
116 :
117 0 : if (TREE_CODE (node) == FUNCTION_DECL
118 0 : && DECL_PENDING_INLINE_INFO (node))
119 : {
120 0 : if (need_indent)
121 0 : indent_to (file, indent + 3);
122 0 : fprintf (file, " pending-inline-info %p",
123 0 : (void *) DECL_PENDING_INLINE_INFO (node));
124 0 : need_indent = false;
125 : }
126 :
127 0 : if ((VAR_OR_FUNCTION_DECL_P (node)
128 : || TREE_CODE (node) == FIELD_DECL
129 : || TREE_CODE (node) == TYPE_DECL
130 : || TREE_CODE (node) == CONCEPT_DECL
131 : || TREE_CODE (node) == TEMPLATE_DECL)
132 0 : && DECL_TEMPLATE_INFO (node))
133 : {
134 0 : print_node (file, "template-info", DECL_TEMPLATE_INFO (node),
135 : indent + 4);
136 0 : indent_to (file, indent + 3);
137 0 : fprintf (file, " use_template=%d", DECL_USE_TEMPLATE (node));
138 : }
139 : }
140 :
141 : void
142 0 : cxx_print_type (FILE *file, tree node, int indent)
143 : {
144 0 : if (tree ti = TYPE_TEMPLATE_INFO (node))
145 0 : print_node (file, "template-info", ti, indent + 4);
146 :
147 0 : switch (TREE_CODE (node))
148 : {
149 0 : case BOUND_TEMPLATE_TEMPLATE_PARM:
150 0 : case TEMPLATE_TYPE_PARM:
151 0 : case TEMPLATE_TEMPLATE_PARM:
152 0 : print_node (file, "tpi", TEMPLATE_TYPE_PARM_INDEX (node), indent + 4);
153 0 : return;
154 :
155 0 : case FUNCTION_TYPE:
156 0 : case METHOD_TYPE:
157 0 : if (TYPE_RAISES_EXCEPTIONS (node))
158 0 : print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4);
159 : return;
160 :
161 0 : case RECORD_TYPE:
162 0 : case UNION_TYPE:
163 0 : break;
164 :
165 0 : case DECLTYPE_TYPE:
166 0 : print_node (file, "expr", DECLTYPE_TYPE_EXPR (node), indent + 4);
167 0 : return;
168 :
169 0 : case DEPENDENT_OPERATOR_TYPE:
170 0 : print_node (file, "saved_lookups",
171 0 : DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS (node),
172 : indent + 4);
173 0 : return;
174 :
175 0 : case TYPENAME_TYPE:
176 0 : print_node (file, "fullname", TYPENAME_TYPE_FULLNAME (node),
177 : indent + 4);
178 0 : return;
179 :
180 0 : case TYPEOF_TYPE:
181 0 : print_node (file, "expr", TYPEOF_TYPE_EXPR (node), indent + 4);
182 0 : return;
183 :
184 0 : case BASES:
185 0 : if (BASES_DIRECT (node))
186 0 : fputs (" direct", file);
187 0 : print_node (file, "type", BASES_TYPE (node), indent + 4);
188 0 : return;
189 :
190 0 : case TYPE_PACK_EXPANSION:
191 0 : print_node (file, "pattern", PACK_EXPANSION_PATTERN (node), indent + 4);
192 0 : print_node (file, "args", PACK_EXPANSION_EXTRA_ARGS (node), indent + 4);
193 0 : return;
194 :
195 0 : case PACK_INDEX_TYPE:
196 0 : print_node (file, "pack", PACK_INDEX_PACK (node), indent + 4);
197 0 : print_node (file, "index", PACK_INDEX_INDEX (node), indent + 4);
198 0 : return;
199 :
200 : default:
201 : return;
202 : }
203 :
204 0 : if (TYPE_PTRMEMFUNC_P (node))
205 0 : print_node (file, "ptrmemfunc fn type", TYPE_PTRMEMFUNC_FN_TYPE (node),
206 : indent + 4);
207 :
208 0 : if (! CLASS_TYPE_P (node))
209 : return;
210 :
211 0 : indent_to (file, indent + 4);
212 0 : fprintf (file, "full-name \"%s\"",
213 : type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
214 :
215 0 : indent_to (file, indent + 3);
216 :
217 0 : if (TYPE_NEEDS_CONSTRUCTING (node))
218 0 : fputs ( " needs-constructor", file);
219 0 : if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (node))
220 0 : fputs (" needs-destructor", file);
221 0 : if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node))
222 0 : fputs (" X()", file);
223 0 : if (TYPE_HAS_CONVERSION (node))
224 0 : fputs (" has-type-conversion", file);
225 0 : if (TYPE_HAS_COPY_CTOR (node))
226 : {
227 0 : if (TYPE_HAS_CONST_COPY_CTOR (node))
228 0 : fputs (" X(constX&)", file);
229 : else
230 0 : fputs (" X(X&)", file);
231 : }
232 0 : if (TYPE_HAS_NEW_OPERATOR (node))
233 0 : fputs (" new", file);
234 0 : if (TYPE_HAS_ARRAY_NEW_OPERATOR (node))
235 0 : fputs (" new[]", file);
236 0 : if (TYPE_GETS_DELETE (node) & 1)
237 0 : fputs (" delete", file);
238 0 : if (TYPE_GETS_DELETE (node) & 2)
239 0 : fputs (" delete[]", file);
240 0 : if (TYPE_HAS_COPY_ASSIGN (node))
241 0 : fputs (" this=(X&)", file);
242 :
243 0 : if (TREE_CODE (node) == RECORD_TYPE)
244 : {
245 0 : if (TYPE_BINFO (node))
246 0 : fprintf (file, " n_parents=%d",
247 0 : BINFO_N_BASE_BINFOS (TYPE_BINFO (node)));
248 : else
249 0 : fprintf (file, " no-binfo");
250 :
251 0 : fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node));
252 0 : if (CLASSTYPE_INTERFACE_ONLY (node))
253 0 : fprintf (file, " interface-only");
254 0 : if (CLASSTYPE_INTERFACE_UNKNOWN (node))
255 0 : fprintf (file, " interface-unknown");
256 : }
257 : }
258 :
259 : void
260 0 : cxx_print_identifier (FILE *file, tree node, int indent)
261 : {
262 0 : if (indent == 0)
263 0 : fprintf (file, " ");
264 : else
265 0 : indent_to (file, indent + 4);
266 0 : fprintf (file, "%s local bindings <%p>", get_identifier_kind_name (node),
267 0 : (void *) IDENTIFIER_BINDING (node));
268 0 : }
269 :
270 : void
271 0 : cxx_print_lambda_node (FILE *file, tree node, int indent)
272 : {
273 0 : fprintf (file, " default_capture_mode=[");
274 0 : switch (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (node))
275 : {
276 0 : case CPLD_NONE:
277 0 : fprintf (file, "NONE");
278 0 : break;
279 0 : case CPLD_COPY:
280 0 : fprintf (file, "COPY");
281 0 : break;
282 0 : case CPLD_REFERENCE:
283 0 : fprintf (file, "CPLD_REFERENCE");
284 0 : break;
285 0 : default:
286 0 : fprintf (file, "??");
287 0 : break;
288 : }
289 0 : fprintf (file, "] ");
290 0 : print_node (file, "capture_list", LAMBDA_EXPR_CAPTURE_LIST (node), indent + 4);
291 0 : print_node (file, "this_capture", LAMBDA_EXPR_THIS_CAPTURE (node), indent + 4);
292 0 : }
293 :
294 : void
295 0 : cxx_print_xnode (FILE *file, tree node, int indent)
296 : {
297 0 : switch (TREE_CODE (node))
298 : {
299 0 : case BASELINK:
300 0 : print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4);
301 0 : print_node (file, "binfo", BASELINK_BINFO (node), indent + 4);
302 0 : print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node),
303 : indent + 4);
304 0 : print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4);
305 0 : break;
306 0 : case OVERLOAD:
307 0 : print_node (file, "function", OVL_FUNCTION (node), indent + 4);
308 0 : print_node (file, "next", OVL_CHAIN (node), indent + 4);
309 0 : break;
310 0 : case BINDING_VECTOR:
311 0 : {
312 0 : unsigned len = BINDING_VECTOR_NUM_CLUSTERS (node);
313 0 : print_node (file, "name", BINDING_VECTOR_NAME (node), indent + 4);
314 0 : fprintf (file, " clusters %u, alloc %u", len,
315 0 : BINDING_VECTOR_ALLOC_CLUSTERS (node));
316 0 : for (unsigned ix = 0; ix != len; ix++)
317 : {
318 0 : binding_cluster *cluster = &BINDING_VECTOR_CLUSTER (node, ix);
319 : char pfx[32];
320 0 : for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++)
321 0 : if (cluster->indices[jx].span)
322 : {
323 0 : int len = sprintf (pfx, "module:%u",
324 0 : cluster->indices[jx].base);
325 0 : if (cluster->indices[jx].span > 1)
326 0 : len += sprintf (&pfx[len], "(+%u)",
327 : cluster->indices[jx].span);
328 0 : len += sprintf (&pfx[len], " cluster:%u/%u", ix, jx);
329 0 : binding_slot &slot = cluster->slots[jx];
330 0 : if (slot.is_lazy ())
331 : {
332 0 : indent_to (file, indent + 4);
333 0 : unsigned lazy = slot.get_lazy ();
334 0 : fprintf (file, "%s snum:%u", pfx, lazy);
335 : }
336 0 : else if (slot)
337 0 : print_node (file, pfx, slot, indent + 4);
338 : else
339 : {
340 0 : indent_to (file, indent + 4);
341 0 : fprintf (file, "%s NULL", pfx);
342 : }
343 : }
344 : }
345 : }
346 : break;
347 0 : case TEMPLATE_PARM_INDEX:
348 0 : print_node (file, "decl", TEMPLATE_PARM_DECL (node), indent+4);
349 0 : indent_to (file, indent + 3);
350 0 : fprintf (file, "index %d level %d orig_level %d",
351 0 : TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node),
352 0 : TEMPLATE_PARM_ORIG_LEVEL (node));
353 0 : break;
354 0 : case TEMPLATE_INFO:
355 0 : print_node (file, "template", TI_TEMPLATE (node), indent+4);
356 0 : print_node (file, "args", TI_ARGS (node), indent+4);
357 0 : if (TI_TEMPLATE (node)
358 0 : && TREE_CODE (TI_TEMPLATE (node)) == TEMPLATE_DECL
359 0 : && PRIMARY_TEMPLATE_P (TI_TEMPLATE (node)))
360 0 : print_node (file, "partial", TI_PARTIAL_INFO (node), indent+4);
361 0 : if (TI_PENDING_TEMPLATE_FLAG (node))
362 : {
363 0 : indent_to (file, indent + 3);
364 0 : fprintf (file, "pending_template");
365 : }
366 : break;
367 0 : case CONSTRAINT_INFO:
368 0 : {
369 0 : tree_constraint_info *cinfo = (tree_constraint_info *)node;
370 0 : if (cinfo->template_reqs)
371 0 : print_node (file, "template_reqs", cinfo->template_reqs, indent+4);
372 0 : if (cinfo->declarator_reqs)
373 0 : print_node (file, "declarator_reqs", cinfo->declarator_reqs,
374 : indent+4);
375 0 : print_node (file, "associated_constr",
376 : cinfo->associated_constr, indent+4);
377 0 : break;
378 : }
379 0 : case ARGUMENT_PACK_SELECT:
380 0 : print_node (file, "pack", ARGUMENT_PACK_SELECT_FROM_PACK (node),
381 : indent+4);
382 0 : indent_to (file, indent + 3);
383 0 : fprintf (file, "index %d", ARGUMENT_PACK_SELECT_INDEX (node));
384 0 : break;
385 0 : case DEFERRED_NOEXCEPT:
386 0 : print_node (file, "pattern", DEFERRED_NOEXCEPT_PATTERN (node), indent+4);
387 0 : print_node (file, "args", DEFERRED_NOEXCEPT_ARGS (node), indent+4);
388 0 : break;
389 0 : case TRAIT_EXPR:
390 0 : indent_to (file, indent+4);
391 0 : fprintf (file, "kind %d", TRAIT_EXPR_KIND (node));
392 0 : print_node (file, "type 1", TRAIT_EXPR_TYPE1 (node), indent+4);
393 0 : if (TRAIT_EXPR_TYPE2 (node))
394 0 : print_node (file, "type 2", TRAIT_EXPR_TYPE2 (node), indent+4);
395 : break;
396 0 : case LAMBDA_EXPR:
397 0 : cxx_print_lambda_node (file, node, indent);
398 0 : break;
399 0 : case STATIC_ASSERT:
400 0 : if (location_t loc = STATIC_ASSERT_SOURCE_LOCATION (node))
401 : {
402 0 : expanded_location xloc = expand_location (loc);
403 0 : indent_to (file, indent+4);
404 0 : fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
405 : }
406 0 : print_node (file, "condition", STATIC_ASSERT_CONDITION (node), indent+4);
407 0 : if (tree message = STATIC_ASSERT_MESSAGE (node))
408 0 : print_node (file, "message", message, indent+4);
409 : break;
410 0 : case PTRMEM_CST:
411 0 : print_node (file, "member", PTRMEM_CST_MEMBER (node), indent+4);
412 0 : break;
413 0 : case TU_LOCAL_ENTITY:
414 0 : print_node (file, "name", TU_LOCAL_ENTITY_NAME (node), indent+4);
415 0 : if (location_t loc = TU_LOCAL_ENTITY_LOCATION (node))
416 : {
417 0 : expanded_location xloc = expand_location (loc);
418 0 : indent_to (file, indent+4);
419 0 : fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
420 : }
421 : break;
422 : default:
423 : break;
424 : }
425 0 : }
426 :
427 : /* Print the node NODE on standard error, for debugging. */
428 :
429 : DEBUG_FUNCTION void
430 0 : debug_tree (cp_expr node)
431 : {
432 0 : debug_tree (node.get_value());
433 0 : }
434 :
435 : DEBUG_FUNCTION void
436 0 : debug_overload (tree node)
437 : {
438 0 : FILE *file = stdout;
439 :
440 0 : for (lkp_iterator iter (node); iter; ++iter)
441 : {
442 0 : tree decl = *iter;
443 0 : auto xloc = expand_location (DECL_SOURCE_LOCATION (decl));
444 0 : auto fullname = decl_as_string (decl, 0);
445 0 : bool using_p = iter.using_p ();
446 0 : bool hidden_p = iter.hidden_p ();
447 :
448 0 : fprintf (file, "%p:%c%c %s:%d:%d \"%s\"\n", (void *)decl,
449 : hidden_p ? 'H' : '-',
450 : using_p ? 'U' : '-',
451 : xloc.file, xloc.line, xloc.column, fullname);
452 : }
453 0 : }
|