Branch data Line data Source code
1 : : /* Prints out trees in human readable form.
2 : : Copyright (C) 1992-2024 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 : && PRIMARY_TEMPLATE_P (TI_TEMPLATE (node)))
359 : 0 : print_node (file, "partial", TI_PARTIAL_INFO (node), indent+4);
360 : 0 : if (TI_PENDING_TEMPLATE_FLAG (node))
361 : : {
362 : 0 : indent_to (file, indent + 3);
363 : 0 : fprintf (file, "pending_template");
364 : : }
365 : : break;
366 : 0 : case CONSTRAINT_INFO:
367 : 0 : {
368 : 0 : tree_constraint_info *cinfo = (tree_constraint_info *)node;
369 : 0 : if (cinfo->template_reqs)
370 : 0 : print_node (file, "template_reqs", cinfo->template_reqs, indent+4);
371 : 0 : if (cinfo->declarator_reqs)
372 : 0 : print_node (file, "declarator_reqs", cinfo->declarator_reqs,
373 : : indent+4);
374 : 0 : print_node (file, "associated_constr",
375 : : cinfo->associated_constr, indent+4);
376 : 0 : break;
377 : : }
378 : 0 : case ARGUMENT_PACK_SELECT:
379 : 0 : print_node (file, "pack", ARGUMENT_PACK_SELECT_FROM_PACK (node),
380 : : indent+4);
381 : 0 : indent_to (file, indent + 3);
382 : 0 : fprintf (file, "index %d", ARGUMENT_PACK_SELECT_INDEX (node));
383 : 0 : break;
384 : 0 : case DEFERRED_NOEXCEPT:
385 : 0 : print_node (file, "pattern", DEFERRED_NOEXCEPT_PATTERN (node), indent+4);
386 : 0 : print_node (file, "args", DEFERRED_NOEXCEPT_ARGS (node), indent+4);
387 : 0 : break;
388 : 0 : case TRAIT_EXPR:
389 : 0 : indent_to (file, indent+4);
390 : 0 : fprintf (file, "kind %d", TRAIT_EXPR_KIND (node));
391 : 0 : print_node (file, "type 1", TRAIT_EXPR_TYPE1 (node), indent+4);
392 : 0 : if (TRAIT_EXPR_TYPE2 (node))
393 : 0 : print_node (file, "type 2", TRAIT_EXPR_TYPE2 (node), indent+4);
394 : : break;
395 : 0 : case LAMBDA_EXPR:
396 : 0 : cxx_print_lambda_node (file, node, indent);
397 : 0 : break;
398 : 0 : case STATIC_ASSERT:
399 : 0 : if (location_t loc = STATIC_ASSERT_SOURCE_LOCATION (node))
400 : : {
401 : 0 : expanded_location xloc = expand_location (loc);
402 : 0 : indent_to (file, indent+4);
403 : 0 : fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
404 : : }
405 : 0 : print_node (file, "condition", STATIC_ASSERT_CONDITION (node), indent+4);
406 : 0 : if (tree message = STATIC_ASSERT_MESSAGE (node))
407 : 0 : print_node (file, "message", message, indent+4);
408 : : break;
409 : 0 : case PTRMEM_CST:
410 : 0 : print_node (file, "member", PTRMEM_CST_MEMBER (node), indent+4);
411 : 0 : break;
412 : : default:
413 : : break;
414 : : }
415 : 0 : }
416 : :
417 : : /* Print the node NODE on standard error, for debugging. */
418 : :
419 : : DEBUG_FUNCTION void
420 : 0 : debug_tree (cp_expr node)
421 : : {
422 : 0 : debug_tree (node.get_value());
423 : 0 : }
424 : :
425 : : DEBUG_FUNCTION void
426 : 0 : debug_overload (tree node)
427 : : {
428 : 0 : FILE *file = stdout;
429 : :
430 : 0 : for (lkp_iterator iter (node); iter; ++iter)
431 : : {
432 : 0 : tree decl = *iter;
433 : 0 : auto xloc = expand_location (DECL_SOURCE_LOCATION (decl));
434 : 0 : auto fullname = decl_as_string (decl, 0);
435 : 0 : bool using_p = iter.using_p ();
436 : 0 : bool hidden_p = iter.hidden_p ();
437 : :
438 : 0 : fprintf (file, "%p:%c%c %s:%d:%d \"%s\"\n", (void *)decl,
439 : : hidden_p ? 'H' : '-',
440 : : using_p ? 'U' : '-',
441 : : xloc.file, xloc.line, xloc.column, fullname);
442 : : }
443 : 0 : }
|