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