1 /* Tree-dumping functionality for intermediate representation.
2    Copyright (C) 1999-2018 Free Software Foundation, Inc.
3    Written by Mark Mitchell <mark@codesourcery.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 #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 
30 static void
dump_access(dump_info_p di,tree t)31 dump_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 
43 static void
dump_stmt(dump_info_p di,const_tree t)44 dump_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 
50 bool
cp_dump_tree(void * dump_info,tree t)51 cp_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 BREAK_STMT:
284     case CONTINUE_STMT:
285       dump_stmt (di, t);
286       break;
287 
288     case DO_STMT:
289       dump_stmt (di, t);
290       dump_child ("body", DO_BODY (t));
291       dump_child ("cond", DO_COND (t));
292       break;
293 
294     case FOR_STMT:
295       dump_stmt (di, t);
296       dump_child ("init", FOR_INIT_STMT (t));
297       dump_child ("cond", FOR_COND (t));
298       dump_child ("expr", FOR_EXPR (t));
299       dump_child ("body", FOR_BODY (t));
300       break;
301 
302     case RANGE_FOR_STMT:
303       dump_stmt (di, t);
304       dump_child ("decl", RANGE_FOR_DECL (t));
305       dump_child ("expr", RANGE_FOR_EXPR (t));
306       dump_child ("body", RANGE_FOR_BODY (t));
307       break;
308 
309     case SWITCH_STMT:
310       dump_stmt (di, t);
311       dump_child ("cond", SWITCH_STMT_COND (t));
312       dump_child ("body", SWITCH_STMT_BODY (t));
313       break;
314 
315     case WHILE_STMT:
316       dump_stmt (di, t);
317       dump_child ("cond", WHILE_COND (t));
318       dump_child ("body", WHILE_BODY (t));
319       break;
320 
321     case STMT_EXPR:
322       dump_child ("stmt", STMT_EXPR_STMT (t));
323       break;
324 
325     case EXPR_STMT:
326       dump_stmt (di, t);
327       dump_child ("expr", EXPR_STMT_EXPR (t));
328       break;
329 
330     default:
331       break;
332     }
333 
334   return c_dump_tree (di, t);
335 }
336