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