1 /* Prints out trees in human readable form.
2 Copyright (C) 1992-2021 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
cxx_print_decl(FILE * file,tree node,int indent)29 cxx_print_decl (FILE *file, tree node, int indent)
30 {
31 if (TREE_CODE (node) == FIELD_DECL)
32 {
33 if (DECL_MUTABLE_P (node))
34 {
35 indent_to (file, indent + 3);
36 fprintf (file, " mutable ");
37 }
38 return;
39 }
40
41 if (!CODE_CONTAINS_STRUCT (TREE_CODE (node), TS_DECL_COMMON)
42 || !DECL_LANG_SPECIFIC (node))
43 return;
44
45 if (TREE_CODE (node) == FUNCTION_DECL)
46 {
47 int flags = TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
48 |TFF_FUNCTION_DEFAULT_ARGUMENTS|TFF_EXCEPTION_SPECIFICATION ;
49 indent_to (file, indent + 3);
50 fprintf (file, " full-name \"%s\"", decl_as_string (node, flags));
51 }
52 else if (TREE_CODE (node) == TEMPLATE_DECL)
53 {
54 print_node (file, "parms", DECL_TEMPLATE_PARMS (node), indent + 4);
55 indent_to (file, indent + 3);
56 fprintf (file, " full-name \"%s\"",
57 decl_as_string (node, TFF_TEMPLATE_HEADER));
58 }
59
60 bool need_indent = true;
61
62 tree ntnode = STRIP_TEMPLATE (node);
63 if (TREE_CODE (ntnode) == FUNCTION_DECL
64 || TREE_CODE (ntnode) == VAR_DECL
65 || TREE_CODE (ntnode) == TYPE_DECL
66 || TREE_CODE (ntnode) == CONCEPT_DECL
67 || TREE_CODE (ntnode) == NAMESPACE_DECL)
68 {
69 unsigned m = 0;
70 if (DECL_LANG_SPECIFIC (ntnode) && DECL_MODULE_IMPORT_P (ntnode))
71 m = get_importing_module (ntnode, true);
72
73 if (const char *name = m == ~0u ? "" : module_name (m, true))
74 {
75 if (need_indent)
76 indent_to (file, indent + 3);
77 fprintf (file, " module %d:%s", m, name);
78 need_indent = false;
79 }
80
81 if (DECL_LANG_SPECIFIC (ntnode) && DECL_MODULE_PURVIEW_P (ntnode))
82 {
83 if (need_indent)
84 indent_to (file, indent + 3);
85 fprintf (file, " purview");
86 need_indent = false;
87 }
88 }
89
90 if (DECL_MODULE_EXPORT_P (node))
91 {
92 if (need_indent)
93 indent_to (file, indent + 3);
94 fprintf (file, " exported");
95 need_indent = false;
96 }
97
98 if (DECL_EXTERNAL (node) && DECL_NOT_REALLY_EXTERN (node))
99 {
100 if (need_indent)
101 indent_to (file, indent + 3);
102 fprintf (file, " not-really-extern");
103 need_indent = false;
104 }
105
106 if (TREE_CODE (node) == FUNCTION_DECL
107 && DECL_PENDING_INLINE_INFO (node))
108 {
109 if (need_indent)
110 indent_to (file, indent + 3);
111 fprintf (file, " pending-inline-info %p",
112 (void *) DECL_PENDING_INLINE_INFO (node));
113 need_indent = false;
114 }
115
116 if (VAR_OR_FUNCTION_DECL_P (node)
117 && DECL_TEMPLATE_INFO (node))
118 {
119 if (need_indent)
120 indent_to (file, indent + 3);
121 fprintf (file, " template-info %p",
122 (void *) DECL_TEMPLATE_INFO (node));
123 need_indent = false;
124 }
125 }
126
127 void
cxx_print_type(FILE * file,tree node,int indent)128 cxx_print_type (FILE *file, tree node, int indent)
129 {
130 switch (TREE_CODE (node))
131 {
132 case BOUND_TEMPLATE_TEMPLATE_PARM:
133 print_node (file, "args", TYPE_TI_ARGS (node), indent + 4);
134 gcc_fallthrough ();
135
136 case TEMPLATE_TYPE_PARM:
137 case TEMPLATE_TEMPLATE_PARM:
138 indent_to (file, indent + 3);
139 fprintf (file, "index %d level %d orig_level %d",
140 TEMPLATE_TYPE_IDX (node), TEMPLATE_TYPE_LEVEL (node),
141 TEMPLATE_TYPE_ORIG_LEVEL (node));
142 return;
143
144 case FUNCTION_TYPE:
145 case METHOD_TYPE:
146 if (TYPE_RAISES_EXCEPTIONS (node))
147 print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4);
148 return;
149
150 case RECORD_TYPE:
151 case UNION_TYPE:
152 break;
153
154 case DECLTYPE_TYPE:
155 print_node (file, "expr", DECLTYPE_TYPE_EXPR (node), indent + 4);
156 return;
157
158 case TYPENAME_TYPE:
159 print_node (file, "fullname", TYPENAME_TYPE_FULLNAME (node),
160 indent + 4);
161 return;
162
163 case TYPEOF_TYPE:
164 print_node (file, "expr", TYPEOF_TYPE_EXPR (node), indent + 4);
165 return;
166
167 case BASES:
168 if (BASES_DIRECT (node))
169 fputs (" direct", file);
170 print_node (file, "type", BASES_TYPE (node), indent + 4);
171 return;
172
173 case TYPE_PACK_EXPANSION:
174 print_node (file, "args", PACK_EXPANSION_EXTRA_ARGS (node), indent + 4);
175 return;
176
177 default:
178 return;
179 }
180
181 if (TYPE_PTRMEMFUNC_P (node))
182 print_node (file, "ptrmemfunc fn type", TYPE_PTRMEMFUNC_FN_TYPE (node),
183 indent + 4);
184
185 if (! CLASS_TYPE_P (node))
186 return;
187
188 indent_to (file, indent + 4);
189 fprintf (file, "full-name \"%s\"",
190 type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
191
192 indent_to (file, indent + 3);
193
194 if (TYPE_NEEDS_CONSTRUCTING (node))
195 fputs ( " needs-constructor", file);
196 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (node))
197 fputs (" needs-destructor", file);
198 if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node))
199 fputs (" X()", file);
200 if (TYPE_HAS_CONVERSION (node))
201 fputs (" has-type-conversion", file);
202 if (TYPE_HAS_COPY_CTOR (node))
203 {
204 if (TYPE_HAS_CONST_COPY_CTOR (node))
205 fputs (" X(constX&)", file);
206 else
207 fputs (" X(X&)", file);
208 }
209 if (TYPE_HAS_NEW_OPERATOR (node))
210 fputs (" new", file);
211 if (TYPE_HAS_ARRAY_NEW_OPERATOR (node))
212 fputs (" new[]", file);
213 if (TYPE_GETS_DELETE (node) & 1)
214 fputs (" delete", file);
215 if (TYPE_GETS_DELETE (node) & 2)
216 fputs (" delete[]", file);
217 if (TYPE_HAS_COPY_ASSIGN (node))
218 fputs (" this=(X&)", file);
219
220 if (TREE_CODE (node) == RECORD_TYPE)
221 {
222 if (TYPE_BINFO (node))
223 fprintf (file, " n_parents=%d",
224 BINFO_N_BASE_BINFOS (TYPE_BINFO (node)));
225 else
226 fprintf (file, " no-binfo");
227
228 fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node));
229 if (CLASSTYPE_INTERFACE_ONLY (node))
230 fprintf (file, " interface-only");
231 if (CLASSTYPE_INTERFACE_UNKNOWN (node))
232 fprintf (file, " interface-unknown");
233 }
234 }
235
236 void
cxx_print_identifier(FILE * file,tree node,int indent)237 cxx_print_identifier (FILE *file, tree node, int indent)
238 {
239 if (indent == 0)
240 fprintf (file, " ");
241 else
242 indent_to (file, indent + 4);
243 fprintf (file, "%s local bindings <%p>", get_identifier_kind_name (node),
244 (void *) IDENTIFIER_BINDING (node));
245 }
246
247 void
cxx_print_lambda_node(FILE * file,tree node,int indent)248 cxx_print_lambda_node (FILE *file, tree node, int indent)
249 {
250 if (LAMBDA_EXPR_MUTABLE_P (node))
251 fprintf (file, " /mutable");
252 fprintf (file, " default_capture_mode=[");
253 switch (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (node))
254 {
255 case CPLD_NONE:
256 fprintf (file, "NONE");
257 break;
258 case CPLD_COPY:
259 fprintf (file, "COPY");
260 break;
261 case CPLD_REFERENCE:
262 fprintf (file, "CPLD_REFERENCE");
263 break;
264 default:
265 fprintf (file, "??");
266 break;
267 }
268 fprintf (file, "] ");
269 print_node (file, "capture_list", LAMBDA_EXPR_CAPTURE_LIST (node), indent + 4);
270 print_node (file, "this_capture", LAMBDA_EXPR_THIS_CAPTURE (node), indent + 4);
271 }
272
273 void
cxx_print_xnode(FILE * file,tree node,int indent)274 cxx_print_xnode (FILE *file, tree node, int indent)
275 {
276 switch (TREE_CODE (node))
277 {
278 case BASELINK:
279 print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4);
280 print_node (file, "binfo", BASELINK_BINFO (node), indent + 4);
281 print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node),
282 indent + 4);
283 print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4);
284 break;
285 case OVERLOAD:
286 print_node (file, "function", OVL_FUNCTION (node), indent + 4);
287 print_node (file, "next", OVL_CHAIN (node), indent + 4);
288 break;
289 case BINDING_VECTOR:
290 {
291 unsigned len = BINDING_VECTOR_NUM_CLUSTERS (node);
292 print_node (file, "name", BINDING_VECTOR_NAME (node), indent + 4);
293 fprintf (file, " clusters %u, alloc %u", len,
294 BINDING_VECTOR_ALLOC_CLUSTERS (node));
295 for (unsigned ix = 0; ix != len; ix++)
296 {
297 binding_cluster *cluster = &BINDING_VECTOR_CLUSTER (node, ix);
298 char pfx[24];
299 for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++)
300 if (cluster->indices[jx].span)
301 {
302 int len = sprintf (pfx, "module:%u",
303 cluster->indices[jx].base);
304 if (cluster->indices[jx].span > 1)
305 len += sprintf (&pfx[len], "(+%u)",
306 cluster->indices[jx].span);
307 len += sprintf (&pfx[len], " cluster:%u/%u", ix, jx);
308 binding_slot &slot = cluster->slots[jx];
309 if (slot.is_lazy ())
310 {
311 indent_to (file, indent + 4);
312 unsigned lazy = slot.get_lazy ();
313 fprintf (file, "%s snum:%u", pfx, lazy);
314 }
315 else if (slot)
316 print_node (file, pfx, slot, indent + 4);
317 else
318 {
319 indent_to (file, indent + 4);
320 fprintf (file, "%s NULL", pfx);
321 }
322 }
323 }
324 }
325 break;
326 case TEMPLATE_PARM_INDEX:
327 print_node (file, "decl", TEMPLATE_PARM_DECL (node), indent+4);
328 indent_to (file, indent + 3);
329 fprintf (file, "index %d level %d orig_level %d",
330 TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node),
331 TEMPLATE_PARM_ORIG_LEVEL (node));
332 break;
333 case TEMPLATE_INFO:
334 print_node (file, "template", TI_TEMPLATE (node), indent+4);
335 print_node (file, "args", TI_ARGS (node), indent+4);
336 if (TI_PENDING_TEMPLATE_FLAG (node))
337 {
338 indent_to (file, indent + 3);
339 fprintf (file, "pending_template");
340 }
341 break;
342 case CONSTRAINT_INFO:
343 {
344 tree_constraint_info *cinfo = (tree_constraint_info *)node;
345 if (cinfo->template_reqs)
346 print_node (file, "template_reqs", cinfo->template_reqs, indent+4);
347 if (cinfo->declarator_reqs)
348 print_node (file, "declarator_reqs", cinfo->declarator_reqs,
349 indent+4);
350 print_node (file, "associated_constr",
351 cinfo->associated_constr, indent+4);
352 break;
353 }
354 case ARGUMENT_PACK_SELECT:
355 print_node (file, "pack", ARGUMENT_PACK_SELECT_FROM_PACK (node),
356 indent+4);
357 indent_to (file, indent + 3);
358 fprintf (file, "index %d", ARGUMENT_PACK_SELECT_INDEX (node));
359 break;
360 case DEFERRED_NOEXCEPT:
361 print_node (file, "pattern", DEFERRED_NOEXCEPT_PATTERN (node), indent+4);
362 print_node (file, "args", DEFERRED_NOEXCEPT_ARGS (node), indent+4);
363 break;
364 case TRAIT_EXPR:
365 indent_to (file, indent+4);
366 fprintf (file, "kind %d", TRAIT_EXPR_KIND (node));
367 print_node (file, "type 1", TRAIT_EXPR_TYPE1 (node), indent+4);
368 if (TRAIT_EXPR_TYPE2 (node))
369 print_node (file, "type 2", TRAIT_EXPR_TYPE2 (node), indent+4);
370 break;
371 case LAMBDA_EXPR:
372 cxx_print_lambda_node (file, node, indent);
373 break;
374 case STATIC_ASSERT:
375 if (location_t loc = STATIC_ASSERT_SOURCE_LOCATION (node))
376 {
377 expanded_location xloc = expand_location (loc);
378 indent_to (file, indent+4);
379 fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
380 }
381 print_node (file, "condition", STATIC_ASSERT_CONDITION (node), indent+4);
382 if (tree message = STATIC_ASSERT_MESSAGE (node))
383 print_node (file, "message", message, indent+4);
384 break;
385 default:
386 break;
387 }
388 }
389
390 /* Print the node NODE on standard error, for debugging. */
391
392 DEBUG_FUNCTION void
debug_tree(cp_expr node)393 debug_tree (cp_expr node)
394 {
395 debug_tree (node.get_value());
396 }
397
398 DEBUG_FUNCTION void
debug_overload(tree node)399 debug_overload (tree node)
400 {
401 FILE *file = stdout;
402
403 for (lkp_iterator iter (node); iter; ++iter)
404 {
405 tree decl = *iter;
406 auto xloc = expand_location (DECL_SOURCE_LOCATION (decl));
407 auto fullname = decl_as_string (decl, 0);
408 bool using_p = iter.using_p ();
409 bool hidden_p = iter.hidden_p ();
410
411 fprintf (file, "%p:%c%c %s:%d:%d \"%s\"\n", (void *)decl,
412 hidden_p ? 'H' : '-',
413 using_p ? 'U' : '-',
414 xloc.file, xloc.line, xloc.column, fullname);
415 }
416 }
417