39be89f62c8a141991f535e531739a07f476efbf
[libfirm] / ir / ir / irdumptxt.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irdump.c
4  * Purpose:     Write vcg representation of firm to file.
5  * Author:      Martin Trapp, Christian Schaefer
6  * Modified by: Goetz Lindenmaier, Hubert Schmidt
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16
17 #include "irdump.h"
18
19 #include "firm_common_t.h"
20
21 #include "irgraph_t.h"
22 #include "irprog_t.h"
23 #include "entity_t.h"
24
25 int dump_node_opcode(FILE *F, ir_node *n); /* from irdump.c */
26
27
28
29 #define X(a)    case a: fprintf(F, #a); break
30 void    dump_entity_to_file_prefix (FILE *F, entity *ent, char *prefix, unsigned verbosity) {
31   int i, j;
32   assert(ent && ent->kind == k_entity);
33   type *owner = get_entity_owner(ent);
34   type *type  = get_entity_type(ent);
35
36   if (verbosity & dump_verbosity_onlynames) {
37     fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
38     return;
39   }
40
41   if (verbosity & dump_verbosity_entattrs) {
42     fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
43     fprintf(F, "%s  type:  %s (%ld)\n", prefix, get_type_name(type),  get_type_nr(type));
44     fprintf(F, "%s  owner: %s (%ld)\n", prefix, get_type_name(owner), get_type_nr(owner));
45
46     if (is_class_type(get_entity_owner(ent))) {
47       if (get_entity_n_overwrites(ent) > 0) {
48         fprintf(F, "%s  overwrites:\n", prefix);
49         for (i = 0; i < get_entity_n_overwrites(ent); ++i) {
50           entity *ov = get_entity_overwrites(ent, i);
51           fprintf(F, "%s    %d: %s of class %s\n", prefix, i, get_entity_name(ov),
52                   get_type_name(get_entity_owner(ov)));
53         }
54       } else {
55         fprintf(F, "%s  Does not overwrite other entities. \n", prefix);
56       }
57       if (get_entity_n_overwrittenby(ent) > 0) {
58         fprintf(F, "%s  overwritten by:\n", prefix);
59         for (i = 0; i < get_entity_n_overwrittenby(ent); ++i) {
60           entity *ov = get_entity_overwrittenby(ent, i);
61           fprintf(F, "%s    %d: %s of class %s\n", prefix, i, get_entity_name(ov),
62                   get_type_name(get_entity_owner(ov)));
63         }
64       } else {
65         fprintf(F, "%s  Is not overwriten by other entities. \n", prefix);
66       }
67     }
68
69     fprintf(F, "%s  allocation:  ", prefix);
70     switch (get_entity_allocation(ent)) {
71       X(allocation_dynamic);
72       X(allocation_automatic);
73       X(allocation_static);
74       X(allocation_parameter);
75     }
76
77     fprintf(F, "\n%s  visibility:  ", prefix);
78     switch (get_entity_visibility(ent)) {
79       X(visibility_local);
80       X(visibility_external_visible);
81       X(visibility_external_allocated);
82     }
83
84     fprintf(F, "\n%s  variability: ", prefix);
85     switch (get_entity_variability(ent)) {
86       X(variability_uninitialized);
87       X(variability_initialized);
88       X(variability_part_constant);
89       X(variability_constant);
90     }
91     fprintf(F, "\n");
92   } else {  /* no entityattrs */
93     fprintf(F, "%s(%3d) %*s: %s", prefix,
94             get_entity_offset_bits(ent), -40, get_type_name(get_entity_type(ent)), get_entity_name(ent));
95     if (is_method_type(get_entity_type(ent))) fprintf(F, "(...)");
96     fprintf(F, "\n");
97   }
98
99   if (verbosity & dump_verbosity_entconsts) {
100     if (get_entity_variability(ent) != variability_uninitialized) {
101       if (is_atomic_entity(ent)) {
102         fprintf(F, "%s  atomic value: ", prefix);
103         dump_node_opcode(F, get_atomic_ent_value(ent));
104       } else {
105         fprintf(F, "%s  compound values:", prefix);
106         for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
107           compound_graph_path *path = get_compound_ent_value_path(ent, i);
108           entity *ent0 = get_compound_graph_path_node(path, 0);
109           fprintf(F, "\n%s    %3d ", prefix, get_entity_offset_bits(ent0));
110           if (get_type_state(type) == layout_fixed)
111             fprintf(F, "(%3d) ",   get_compound_ent_value_offset_bits(ent, i));
112           fprintf(F, "%s", get_entity_name(ent0));
113           for (j = 0; j < get_compound_graph_path_length(path); ++j) {
114             entity *node = get_compound_graph_path_node(path, j);
115             fprintf(F, ".%s", get_entity_name(node));
116             if (is_array_type(get_entity_owner(node)))
117               fprintf(F, "[%d]", get_compound_graph_path_array_index(path, j));
118           }
119           fprintf(F, "\t = ");
120           dump_node_opcode(F, get_compound_ent_value(ent, i));
121         }
122       }
123       fprintf(F, "\n");
124     }
125   }
126
127
128   if (verbosity & dump_verbosity_entattrs) {
129     fprintf(F, "%s  volatility:  ", prefix);
130     switch (get_entity_volatility(ent)) {
131       X(volatility_non_volatile);
132       X(volatility_is_volatile);
133     }
134
135     fprintf(F, "\n%s  peculiarity: %s", prefix, get_peculiarity_string(get_entity_peculiarity(ent)));
136     fprintf(F, "\n%s  ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
137     fprintf(F, "\n%s  offset:  %d", prefix, get_entity_offset_bits(ent));
138     if (is_method_type(get_entity_type(ent))) {
139       if (get_entity_irg(ent))   /* can be null */ {
140         fprintf(F, "\n%s  irg = %ld", prefix, get_irg_graph_nr(get_entity_irg(ent)));
141         if (get_irp_callgraph_state() == irp_callgraph_and_calltree_consistent) {
142           fprintf(F, "\n%s    recursion depth %d", prefix, get_irg_recursion_depth(get_entity_irg(ent)));
143           fprintf(F, "\n%s    loop depth      %d", prefix, get_irg_loop_depth(get_entity_irg(ent)));
144         }
145       } else {
146         fprintf(F, "\n%s  irg = NULL", prefix);
147       }
148     }
149     fprintf(F, "\n");
150   }
151 }
152 #undef X
153
154 void    dump_entity_to_file (FILE *F, entity *ent, unsigned verbosity) {
155   dump_entity_to_file_prefix (F, ent, "", verbosity);
156   fprintf(F, "\n");
157 }
158
159 void dump_entity (entity *ent) {
160   dump_entity_to_file(stdout, ent, dump_verbosity_max);
161 }
162
163 void dump_type_to_file (FILE *F, type *tp, dump_verbosity verbosity) {
164   int i;
165
166   if ((is_class_type(tp))       && (verbosity & dump_verbosity_noClassTypes)) return;
167   if ((is_struct_type(tp))      && (verbosity & dump_verbosity_noStructTypes)) return;
168   if ((is_union_type(tp))       && (verbosity & dump_verbosity_noUnionTypes)) return;
169   if ((is_array_type(tp))       && (verbosity & dump_verbosity_noArrayTypes)) return;
170   if ((is_pointer_type(tp))     && (verbosity & dump_verbosity_noPointerTypes)) return;
171   if ((is_method_type(tp))      && (verbosity & dump_verbosity_noMethodTypes)) return;
172   if ((is_primitive_type(tp))   && (verbosity & dump_verbosity_noPrimitiveTypes)) return;
173   if ((is_enumeration_type(tp)) && (verbosity & dump_verbosity_noEnumerationTypes)) return;
174
175   fprintf(F, "%s type %s (%ld)", get_tpop_name(get_type_tpop(tp)), get_type_name(tp), get_type_nr(tp));
176   if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }
177
178   switch (get_type_tpop_code(tp)) {
179
180   case tpo_class:
181     if ((verbosity & dump_verbosity_methods) || (verbosity & dump_verbosity_fields)) {
182       fprintf(F, "\n  members: \n");
183     }
184     for (i = 0; i < get_class_n_members(tp); ++i) {
185       entity *mem = get_class_member(tp, i);
186       if (((verbosity & dump_verbosity_methods) &&  is_method_type(get_entity_type(mem))) ||
187           ((verbosity & dump_verbosity_fields)  && !is_method_type(get_entity_type(mem)))   ) {
188         dump_entity_to_file_prefix(F, mem, "    ", verbosity);
189       }
190     }
191     if (verbosity & dump_verbosity_typeattrs) {
192       fprintf(F, "  supertypes: ");
193       for (i = 0; i < get_class_n_supertypes(tp); ++i) {
194         type *stp = get_class_supertype(tp, i);
195         fprintf(F, "\n    %s", get_type_name(stp));
196       }
197       fprintf(F, "\n  subtypes: ");
198       for (i = 0; i < get_class_n_subtypes(tp); ++i) {
199         type *stp = get_class_subtype(tp, i);
200         fprintf(F, "\n    %s", get_type_name(stp));
201       }
202
203       fprintf(F, "\n  peculiarity: %s", get_peculiarity_string(get_class_peculiarity(tp)));
204     }
205     break;
206
207   case tpo_union:
208   case tpo_struct:
209     if (verbosity & dump_verbosity_fields) fprintf(F, "\n  members: ");
210     for (i = 0; i < get_compound_n_members(tp); ++i) {
211       entity *mem = get_compound_member(tp, i);
212       if (verbosity & dump_verbosity_fields) {
213         dump_entity_to_file_prefix(F, mem, "    ", verbosity);
214       }
215     }
216     break;
217
218   case tpo_pointer: {
219     if (verbosity & dump_verbosity_typeattrs) {
220       type *tt = get_pointer_points_to_type(tp);
221       fprintf(F, "\n  points to %s (%ld)", get_type_name(tt), get_type_nr(tt));
222     }
223
224   } break;
225
226   default:
227     if (verbosity & dump_verbosity_typeattrs) {
228       fprintf(F, ": details not implemented\n");
229     }
230   }
231   fprintf(F, "\n\n");
232 }
233
234 void dump_type(type *tp) {
235   dump_type_to_file (stdout, tp, dump_verbosity_max);
236 }
237
238
239
240 static FILE *text_open (const char *basename, const char * suffix1, const char *suffix2) {
241   FILE *F;
242   int len = strlen(basename), i, j;
243   char *fname;  /* filename to put the vcg information in */
244
245   if (!basename) assert(basename);
246   if (!suffix1) suffix1 = "";
247   if (!suffix2) suffix2 = "";
248
249   /* open file for vcg graph */
250   fname = malloc (strlen(basename)*2 + strlen(suffix1) + strlen(suffix2) + 5); /* *2: space for excapes. */
251
252   j = 0;
253   for (i = 0; i < len; ++i) {  /* replase '/' in the name: escape by @. */
254     if (basename[i] == '/') {
255       fname[j] = '@'; j++; fname[j] = '1'; j++;
256     } else if (basename[i] == '@') {
257       fname[j] = '@'; j++; fname[j] = '2'; j++;
258     } else {
259       fname[j] = basename[i]; j++;
260     }
261   }
262   fname[j] = '\0';
263   strcat (fname, suffix1);  /* append file suffix */
264   strcat (fname, suffix2);  /* append file suffix */
265   strcat (fname, ".txt");   /* append the .txt suffix */
266
267   F = fopen (fname, "w");   /* open file for writing */
268   if (!F) {
269     assert(0);
270   }
271   free(fname);
272
273   return F;
274 }
275
276 void dump_types_as_text(unsigned verbosity, const char *suffix) {
277   const char *basename;
278   FILE *F;
279   int i, n_types = get_irp_n_types();
280
281   if (get_irp_prog_ident() == new_id_from_str("no_name_set")) {
282     basename = "TextTypes";
283   } else {
284     basename = get_irp_prog_name();
285   }
286   F = text_open (basename, suffix, "-types");
287
288   for (i = 0; i < n_types; ++i) {
289     type *t = get_irp_type(i);
290     dump_type_to_file(F, t, verbosity);
291   }
292
293   fclose (F);
294 }