1/* Tree-dumping functionality for intermediate representation.
2   Copyright (C) 1999-2015 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 "tm.h"
25#include "hash-set.h"
26#include "machmode.h"
27#include "vec.h"
28#include "double-int.h"
29#include "input.h"
30#include "alias.h"
31#include "symtab.h"
32#include "wide-int.h"
33#include "inchash.h"
34#include "tree.h"
35#include "cp-tree.h"
36#include "tree-dump.h"
37
38static void dump_access (dump_info_p, tree);
39
40static void dump_op (dump_info_p, tree);
41
42/* Dump a representation of the accessibility information associated
43   with T.  */
44
45static void
46dump_access (dump_info_p di, tree t)
47{
48  if (TREE_PROTECTED(t))
49    dump_string_field (di, "accs", "prot");
50  else if (TREE_PRIVATE(t))
51    dump_string_field (di, "accs", "priv");
52  else
53    dump_string_field (di, "accs", "pub");
54}
55
56/* Dump a representation of the specific operator for an overloaded
57   operator associated with node t.  */
58
59static void
60dump_op (dump_info_p di, tree t)
61{
62  switch (DECL_OVERLOADED_OPERATOR_P (t)) {
63    case NEW_EXPR:
64      dump_string (di, "new");
65      break;
66    case VEC_NEW_EXPR:
67      dump_string (di, "vecnew");
68      break;
69    case DELETE_EXPR:
70      dump_string (di, "delete");
71      break;
72    case VEC_DELETE_EXPR:
73      dump_string (di, "vecdelete");
74      break;
75    case UNARY_PLUS_EXPR:
76      dump_string (di, "pos");
77      break;
78    case NEGATE_EXPR:
79      dump_string (di, "neg");
80      break;
81    case ADDR_EXPR:
82      dump_string (di, "addr");
83      break;
84    case INDIRECT_REF:
85      dump_string(di, "deref");
86      break;
87    case BIT_NOT_EXPR:
88      dump_string(di, "not");
89      break;
90    case TRUTH_NOT_EXPR:
91      dump_string(di, "lnot");
92      break;
93    case PREINCREMENT_EXPR:
94      dump_string(di, "preinc");
95      break;
96    case PREDECREMENT_EXPR:
97      dump_string(di, "predec");
98      break;
99    case PLUS_EXPR:
100      if (DECL_ASSIGNMENT_OPERATOR_P (t))
101	dump_string (di, "plusassign");
102      else
103	dump_string(di, "plus");
104      break;
105    case MINUS_EXPR:
106      if (DECL_ASSIGNMENT_OPERATOR_P (t))
107	dump_string (di, "minusassign");
108      else
109	dump_string(di, "minus");
110      break;
111    case MULT_EXPR:
112      if (DECL_ASSIGNMENT_OPERATOR_P (t))
113	dump_string (di, "multassign");
114      else
115	dump_string (di, "mult");
116      break;
117    case TRUNC_DIV_EXPR:
118      if (DECL_ASSIGNMENT_OPERATOR_P (t))
119	dump_string (di, "divassign");
120      else
121	dump_string (di, "div");
122      break;
123    case TRUNC_MOD_EXPR:
124      if (DECL_ASSIGNMENT_OPERATOR_P (t))
125	 dump_string (di, "modassign");
126      else
127	dump_string (di, "mod");
128      break;
129    case BIT_AND_EXPR:
130      if (DECL_ASSIGNMENT_OPERATOR_P (t))
131	dump_string (di, "andassign");
132      else
133	dump_string (di, "and");
134      break;
135    case BIT_IOR_EXPR:
136      if (DECL_ASSIGNMENT_OPERATOR_P (t))
137	dump_string (di, "orassign");
138      else
139	dump_string (di, "or");
140      break;
141    case BIT_XOR_EXPR:
142      if (DECL_ASSIGNMENT_OPERATOR_P (t))
143	dump_string (di, "xorassign");
144      else
145	dump_string (di, "xor");
146      break;
147    case LSHIFT_EXPR:
148      if (DECL_ASSIGNMENT_OPERATOR_P (t))
149	dump_string (di, "lshiftassign");
150      else
151	dump_string (di, "lshift");
152      break;
153    case RSHIFT_EXPR:
154      if (DECL_ASSIGNMENT_OPERATOR_P (t))
155	dump_string (di, "rshiftassign");
156      else
157	dump_string (di, "rshift");
158      break;
159    case EQ_EXPR:
160      dump_string (di, "eq");
161      break;
162    case NE_EXPR:
163      dump_string (di, "ne");
164      break;
165    case LT_EXPR:
166      dump_string (di, "lt");
167      break;
168    case GT_EXPR:
169      dump_string (di, "gt");
170      break;
171    case LE_EXPR:
172      dump_string (di, "le");
173      break;
174    case GE_EXPR:
175      dump_string (di, "ge");
176      break;
177    case TRUTH_ANDIF_EXPR:
178      dump_string (di, "land");
179      break;
180    case TRUTH_ORIF_EXPR:
181      dump_string (di, "lor");
182      break;
183    case COMPOUND_EXPR:
184      dump_string (di, "compound");
185      break;
186    case MEMBER_REF:
187      dump_string (di, "memref");
188      break;
189    case COMPONENT_REF:
190      dump_string (di, "ref");
191      break;
192    case ARRAY_REF:
193      dump_string (di, "subs");
194      break;
195    case POSTINCREMENT_EXPR:
196      dump_string (di, "postinc");
197      break;
198    case POSTDECREMENT_EXPR:
199      dump_string (di, "postdec");
200      break;
201    case CALL_EXPR:
202      dump_string (di, "call");
203      break;
204    case NOP_EXPR:
205      if (DECL_ASSIGNMENT_OPERATOR_P (t))
206	dump_string (di, "assign");
207      break;
208    default:
209      break;
210  }
211}
212
213/* Dump information common to statements from STMT.  */
214
215static void
216dump_stmt (dump_info_p di, const_tree t)
217{
218  if (EXPR_HAS_LOCATION (t))
219    dump_int (di, "line", EXPR_LINENO (t));
220}
221
222bool
223cp_dump_tree (void* dump_info, tree t)
224{
225  enum tree_code code;
226  dump_info_p di = (dump_info_p) dump_info;
227
228  /* Figure out what kind of node this is.  */
229  code = TREE_CODE (t);
230
231  if (DECL_P (t))
232    {
233      if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus)
234	dump_string_field (di, "lang", language_to_string (DECL_LANGUAGE (t)));
235    }
236
237  switch (code)
238    {
239    case IDENTIFIER_NODE:
240      if (IDENTIFIER_OPNAME_P (t))
241	{
242	  dump_string_field (di, "note", "operator");
243	  return true;
244	}
245      else if (IDENTIFIER_TYPENAME_P (t))
246	{
247	  dump_child ("tynm", TREE_TYPE (t));
248	  return true;
249	}
250      break;
251
252    case OFFSET_TYPE:
253      dump_string_field (di, "note", "ptrmem");
254      dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
255      dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
256      return true;
257
258    case RECORD_TYPE:
259      if (TYPE_PTRMEMFUNC_P (t))
260	{
261	  dump_string_field (di, "note", "ptrmem");
262	  dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
263	  dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
264	  return true;
265	}
266      /* Fall through.  */
267
268    case UNION_TYPE:
269      /* Is it a type used as a base? */
270      if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t)
271	  && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
272	{
273	  dump_child ("bfld", TYPE_CONTEXT (t));
274	  return true;
275	}
276
277      if (! MAYBE_CLASS_TYPE_P (t))
278	break;
279
280      dump_child ("vfld", TYPE_VFIELD (t));
281      if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t))
282	dump_string(di, "spec");
283
284      if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t))
285	{
286	  int i;
287	  tree binfo;
288	  tree base_binfo;
289
290	  for (binfo = TYPE_BINFO (t), i = 0;
291	       BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
292	    {
293	      dump_child ("base", BINFO_TYPE (base_binfo));
294	      if (BINFO_VIRTUAL_P (base_binfo))
295		dump_string_field (di, "spec", "virt");
296	      dump_access (di, base_binfo);
297	    }
298	}
299      break;
300
301    case FIELD_DECL:
302      dump_access (di, t);
303      if (DECL_MUTABLE_P (t))
304	dump_string_field (di, "spec", "mutable");
305      break;
306
307    case VAR_DECL:
308      if (TREE_CODE (CP_DECL_CONTEXT (t)) == RECORD_TYPE)
309	dump_access (di, t);
310      if (TREE_STATIC (t) && !TREE_PUBLIC (t))
311	dump_string_field (di, "link", "static");
312      break;
313
314    case FUNCTION_DECL:
315      if (!DECL_THUNK_P (t))
316	{
317	  if (DECL_OVERLOADED_OPERATOR_P (t)) {
318	    dump_string_field (di, "note", "operator");
319	    dump_op (di, t);
320	  }
321	  if (DECL_FUNCTION_MEMBER_P (t))
322	    {
323	      dump_string_field (di, "note", "member");
324	      dump_access (di, t);
325	    }
326	  if (DECL_PURE_VIRTUAL_P (t))
327	    dump_string_field (di, "spec", "pure");
328	  if (DECL_VIRTUAL_P (t))
329	    dump_string_field (di, "spec", "virt");
330	  if (DECL_CONSTRUCTOR_P (t))
331	    dump_string_field (di, "note", "constructor");
332	  if (DECL_DESTRUCTOR_P (t))
333	    dump_string_field (di, "note", "destructor");
334	  if (DECL_CONV_FN_P (t))
335	    dump_string_field (di, "note", "conversion");
336	  if (DECL_GLOBAL_CTOR_P (t))
337	    dump_string_field (di, "note", "global init");
338	  if (DECL_GLOBAL_DTOR_P (t))
339	    dump_string_field (di, "note", "global fini");
340	  if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t))
341	    dump_string_field (di, "note", "pseudo tmpl");
342	}
343      else
344	{
345	  tree virt = THUNK_VIRTUAL_OFFSET (t);
346
347	  dump_string_field (di, "note", "thunk");
348	  if (DECL_THIS_THUNK_P (t))
349	    dump_string_field (di, "note", "this adjusting");
350	  else
351	    {
352	      dump_string_field (di, "note", "result adjusting");
353	      if (virt)
354		virt = BINFO_VPTR_FIELD (virt);
355	    }
356	  dump_int (di, "fixd", THUNK_FIXED_OFFSET (t));
357	  if (virt)
358	    dump_int (di, "virt", tree_to_shwi (virt));
359	  dump_child ("fn", DECL_INITIAL (t));
360	}
361      break;
362
363    case NAMESPACE_DECL:
364      if (DECL_NAMESPACE_ALIAS (t))
365	dump_child ("alis", DECL_NAMESPACE_ALIAS (t));
366      else if (!dump_flag (di, TDF_SLIM, t))
367	dump_child ("dcls", cp_namespace_decls (t));
368      break;
369
370    case TEMPLATE_DECL:
371      dump_child ("rslt", DECL_TEMPLATE_RESULT (t));
372      dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t));
373      dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
374      dump_child ("prms", DECL_TEMPLATE_PARMS (t));
375      break;
376
377    case OVERLOAD:
378      dump_child ("crnt", OVL_CURRENT (t));
379      dump_child ("chan", OVL_CHAIN (t));
380      break;
381
382    case TRY_BLOCK:
383      dump_stmt (di, t);
384      if (CLEANUP_P (t))
385	dump_string_field (di, "note", "cleanup");
386      dump_child ("body", TRY_STMTS (t));
387      dump_child ("hdlr", TRY_HANDLERS (t));
388      break;
389
390    case EH_SPEC_BLOCK:
391      dump_stmt (di, t);
392      dump_child ("body", EH_SPEC_STMTS (t));
393      dump_child ("raises", EH_SPEC_RAISES (t));
394      break;
395
396    case PTRMEM_CST:
397      dump_child ("clas", PTRMEM_CST_CLASS (t));
398      dump_child ("mbr", PTRMEM_CST_MEMBER (t));
399      break;
400
401    case THROW_EXPR:
402      /* These nodes are unary, but do not have code class `1'.  */
403      dump_child ("op 0", TREE_OPERAND (t, 0));
404      break;
405
406    case AGGR_INIT_EXPR:
407      {
408	int i = 0;
409	tree arg;
410	aggr_init_expr_arg_iterator iter;
411	dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
412	dump_child ("fn", AGGR_INIT_EXPR_FN (t));
413	FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
414	  {
415	    char buffer[32];
416	    sprintf (buffer, "%u", i);
417	    dump_child (buffer, arg);
418	    i++;
419	  }
420	dump_child ("decl", AGGR_INIT_EXPR_SLOT (t));
421      }
422      break;
423
424    case HANDLER:
425      dump_stmt (di, t);
426      dump_child ("parm", HANDLER_PARMS (t));
427      dump_child ("body", HANDLER_BODY (t));
428      break;
429
430    case MUST_NOT_THROW_EXPR:
431      dump_stmt (di, t);
432      dump_child ("body", TREE_OPERAND (t, 0));
433      dump_child ("cond", MUST_NOT_THROW_COND (t));
434      break;
435
436    case USING_STMT:
437      dump_stmt (di, t);
438      dump_child ("nmsp", USING_STMT_NAMESPACE (t));
439      break;
440
441    case CLEANUP_STMT:
442      dump_stmt (di, t);
443      dump_child ("decl", CLEANUP_DECL (t));
444      dump_child ("expr", CLEANUP_EXPR (t));
445      dump_child ("body", CLEANUP_BODY (t));
446      break;
447
448    case IF_STMT:
449      dump_stmt (di, t);
450      dump_child ("cond", IF_COND (t));
451      dump_child ("then", THEN_CLAUSE (t));
452      dump_child ("else", ELSE_CLAUSE (t));
453      break;
454
455    case BREAK_STMT:
456    case CONTINUE_STMT:
457      dump_stmt (di, t);
458      break;
459
460    case DO_STMT:
461      dump_stmt (di, t);
462      dump_child ("body", DO_BODY (t));
463      dump_child ("cond", DO_COND (t));
464      break;
465
466    case FOR_STMT:
467      dump_stmt (di, t);
468      dump_child ("init", FOR_INIT_STMT (t));
469      dump_child ("cond", FOR_COND (t));
470      dump_child ("expr", FOR_EXPR (t));
471      dump_child ("body", FOR_BODY (t));
472      break;
473
474    case RANGE_FOR_STMT:
475      dump_stmt (di, t);
476      dump_child ("decl", RANGE_FOR_DECL (t));
477      dump_child ("expr", RANGE_FOR_EXPR (t));
478      dump_child ("body", RANGE_FOR_BODY (t));
479      break;
480
481    case SWITCH_STMT:
482      dump_stmt (di, t);
483      dump_child ("cond", SWITCH_STMT_COND (t));
484      dump_child ("body", SWITCH_STMT_BODY (t));
485      break;
486
487    case WHILE_STMT:
488      dump_stmt (di, t);
489      dump_child ("cond", WHILE_COND (t));
490      dump_child ("body", WHILE_BODY (t));
491      break;
492
493    case STMT_EXPR:
494      dump_child ("stmt", STMT_EXPR_STMT (t));
495      break;
496
497    case EXPR_STMT:
498      dump_stmt (di, t);
499      dump_child ("expr", EXPR_STMT_EXPR (t));
500      break;
501
502    default:
503      break;
504    }
505
506  return c_dump_tree (di, t);
507}
508