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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
28void
29cxx_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
123void
124cxx_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
239void
240cxx_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
250void
251cxx_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
276void
277cxx_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
398DEBUG_FUNCTION void
399debug_tree (cp_expr node)
400{
401  debug_tree (node.get_value());
402}
403
404DEBUG_FUNCTION void
405debug_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