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