1/* Tree-dumping functionality for intermediate representation.
2   Copyright (C) 1999-2022 Free Software Foundation, Inc.
3   Written by Mark Mitchell <mark@codesourcery.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#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "cp-tree.h"
25#include "tree-dump.h"
26
27/* Dump a representation of the accessibility information associated
28   with T.  */
29
30static void
31dump_access (dump_info_p di, tree t)
32{
33  if (TREE_PROTECTED(t))
34    dump_string_field (di, "accs", "prot");
35  else if (TREE_PRIVATE(t))
36    dump_string_field (di, "accs", "priv");
37  else
38    dump_string_field (di, "accs", "pub");
39}
40
41/* Dump information common to statements from STMT.  */
42
43static void
44dump_stmt (dump_info_p di, const_tree t)
45{
46  if (EXPR_HAS_LOCATION (t))
47    dump_int (di, "line", EXPR_LINENO (t));
48}
49
50bool
51cp_dump_tree (void* dump_info, tree t)
52{
53  enum tree_code code;
54  dump_info_p di = (dump_info_p) dump_info;
55
56  /* Figure out what kind of node this is.  */
57  code = TREE_CODE (t);
58
59  if (DECL_P (t))
60    {
61      if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus)
62	dump_string_field (di, "lang", language_to_string (DECL_LANGUAGE (t)));
63    }
64
65  switch (code)
66    {
67    case IDENTIFIER_NODE:
68      if (IDENTIFIER_ANY_OP_P (t))
69	{
70	  dump_string_field (di, "note", "operator");
71	  return true;
72	}
73      else if (IDENTIFIER_CONV_OP_P (t))
74	{
75	  dump_child ("tynm", TREE_TYPE (t));
76	  return true;
77	}
78      break;
79
80    case OFFSET_TYPE:
81      dump_string_field (di, "note", "ptrmem");
82      dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
83      dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
84      return true;
85
86    case RECORD_TYPE:
87      if (TYPE_PTRMEMFUNC_P (t))
88	{
89	  dump_string_field (di, "note", "ptrmem");
90	  dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
91	  dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
92	  return true;
93	}
94      /* Fall through.  */
95
96    case UNION_TYPE:
97      /* Is it a type used as a base? */
98      if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t)
99	  && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
100	{
101	  dump_child ("bfld", TYPE_CONTEXT (t));
102	  return true;
103	}
104
105      if (! MAYBE_CLASS_TYPE_P (t))
106	break;
107
108      dump_child ("vfld", TYPE_VFIELD (t));
109      if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t))
110	dump_string(di, "spec");
111
112      if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t))
113	{
114	  int i;
115	  tree binfo;
116	  tree base_binfo;
117
118	  for (binfo = TYPE_BINFO (t), i = 0;
119	       BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
120	    {
121	      dump_child ("base", BINFO_TYPE (base_binfo));
122	      if (BINFO_VIRTUAL_P (base_binfo))
123		dump_string_field (di, "spec", "virt");
124	      dump_access (di, base_binfo);
125	    }
126	}
127      break;
128
129    case FIELD_DECL:
130      dump_access (di, t);
131      if (DECL_MUTABLE_P (t))
132	dump_string_field (di, "spec", "mutable");
133      break;
134
135    case VAR_DECL:
136      if (TREE_CODE (CP_DECL_CONTEXT (t)) == RECORD_TYPE)
137	dump_access (di, t);
138      if (TREE_STATIC (t) && !TREE_PUBLIC (t))
139	dump_string_field (di, "link", "static");
140      break;
141
142    case FUNCTION_DECL:
143      if (!DECL_THUNK_P (t))
144	{
145	  if (DECL_OVERLOADED_OPERATOR_P (t))
146	    dump_string_field (di, "note", "operator");
147	  if (DECL_FUNCTION_MEMBER_P (t))
148	    {
149	      dump_string_field (di, "note", "member");
150	      dump_access (di, t);
151	    }
152	  if (DECL_PURE_VIRTUAL_P (t))
153	    dump_string_field (di, "spec", "pure");
154	  if (DECL_VIRTUAL_P (t))
155	    dump_string_field (di, "spec", "virt");
156	  if (DECL_CONSTRUCTOR_P (t))
157	    dump_string_field (di, "note", "constructor");
158	  if (DECL_DESTRUCTOR_P (t))
159	    dump_string_field (di, "note", "destructor");
160	  if (DECL_CONV_FN_P (t))
161	    dump_string_field (di, "note", "conversion");
162	  if (DECL_GLOBAL_CTOR_P (t))
163	    dump_string_field (di, "note", "global init");
164	  if (DECL_GLOBAL_DTOR_P (t))
165	    dump_string_field (di, "note", "global fini");
166	  if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t))
167	    dump_string_field (di, "note", "pseudo tmpl");
168	}
169      else
170	{
171	  tree virt = THUNK_VIRTUAL_OFFSET (t);
172
173	  dump_string_field (di, "note", "thunk");
174	  if (DECL_THIS_THUNK_P (t))
175	    dump_string_field (di, "note", "this adjusting");
176	  else
177	    {
178	      dump_string_field (di, "note", "result adjusting");
179	      if (virt)
180		virt = BINFO_VPTR_FIELD (virt);
181	    }
182	  dump_int (di, "fixd", THUNK_FIXED_OFFSET (t));
183	  if (virt)
184	    dump_int (di, "virt", tree_to_shwi (virt));
185	  dump_child ("fn", DECL_INITIAL (t));
186	}
187      break;
188
189    case NAMESPACE_DECL:
190      if (DECL_NAMESPACE_ALIAS (t))
191	dump_child ("alis", DECL_NAMESPACE_ALIAS (t));
192      else if (!dump_flag (di, TDF_SLIM, t))
193	dump_child ("dcls", cp_namespace_decls (t));
194      break;
195
196    case TEMPLATE_DECL:
197      dump_child ("rslt", DECL_TEMPLATE_RESULT (t));
198      dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t));
199      dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
200      dump_child ("prms", DECL_TEMPLATE_PARMS (t));
201      break;
202
203    case OVERLOAD:
204      dump_child ("name", OVL_NAME (t));
205      if (!dump_flag (di, TDF_SLIM, t))
206	for (lkp_iterator iter (t); iter; ++iter)
207	  dump_child ("chld", *iter);
208      break;
209
210    case TRY_BLOCK:
211      dump_stmt (di, t);
212      if (CLEANUP_P (t))
213	dump_string_field (di, "note", "cleanup");
214      dump_child ("body", TRY_STMTS (t));
215      dump_child ("hdlr", TRY_HANDLERS (t));
216      break;
217
218    case EH_SPEC_BLOCK:
219      dump_stmt (di, t);
220      dump_child ("body", EH_SPEC_STMTS (t));
221      dump_child ("raises", EH_SPEC_RAISES (t));
222      break;
223
224    case PTRMEM_CST:
225      dump_child ("clas", PTRMEM_CST_CLASS (t));
226      dump_child ("mbr", PTRMEM_CST_MEMBER (t));
227      break;
228
229    case THROW_EXPR:
230      /* These nodes are unary, but do not have code class `1'.  */
231      dump_child ("op 0", TREE_OPERAND (t, 0));
232      break;
233
234    case AGGR_INIT_EXPR:
235      {
236	int i = 0;
237	tree arg;
238	aggr_init_expr_arg_iterator iter;
239	dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
240	dump_child ("fn", AGGR_INIT_EXPR_FN (t));
241	FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
242	  {
243	    char buffer[32];
244	    sprintf (buffer, "%u", i);
245	    dump_child (buffer, arg);
246	    i++;
247	  }
248	dump_child ("decl", AGGR_INIT_EXPR_SLOT (t));
249      }
250      break;
251
252    case HANDLER:
253      dump_stmt (di, t);
254      dump_child ("parm", HANDLER_PARMS (t));
255      dump_child ("body", HANDLER_BODY (t));
256      break;
257
258    case MUST_NOT_THROW_EXPR:
259      dump_stmt (di, t);
260      dump_child ("body", TREE_OPERAND (t, 0));
261      dump_child ("cond", MUST_NOT_THROW_COND (t));
262      break;
263
264    case USING_STMT:
265      dump_stmt (di, t);
266      dump_child ("nmsp", USING_STMT_NAMESPACE (t));
267      break;
268
269    case CLEANUP_STMT:
270      dump_stmt (di, t);
271      dump_child ("decl", CLEANUP_DECL (t));
272      dump_child ("expr", CLEANUP_EXPR (t));
273      dump_child ("body", CLEANUP_BODY (t));
274      break;
275
276    case IF_STMT:
277      dump_stmt (di, t);
278      dump_child ("cond", IF_COND (t));
279      dump_child ("then", THEN_CLAUSE (t));
280      dump_child ("else", ELSE_CLAUSE (t));
281      break;
282
283    case RANGE_FOR_STMT:
284      dump_stmt (di, t);
285      dump_child ("init", RANGE_FOR_INIT_STMT (t));
286      dump_child ("decl", RANGE_FOR_DECL (t));
287      dump_child ("expr", RANGE_FOR_EXPR (t));
288      dump_child ("body", RANGE_FOR_BODY (t));
289      break;
290
291    case STMT_EXPR:
292      dump_child ("stmt", STMT_EXPR_STMT (t));
293      break;
294
295    case EXPR_STMT:
296      dump_stmt (di, t);
297      dump_child ("expr", EXPR_STMT_EXPR (t));
298      break;
299
300    case OMP_DEPOBJ:
301      dump_stmt (di, t);
302      dump_child ("depobj", OMP_DEPOBJ_DEPOBJ (t));
303      dump_child ("clauses", OMP_DEPOBJ_CLAUSES (t));
304      break;
305
306    default:
307      break;
308    }
309
310  return c_dump_tree (di, t);
311}
312