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