1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
4 * Author: Goetz Lindenmaier
6 * traverse the type information. The walker walks the whole ir graph
7 * to find the distinct type trees in the type graph forest.
8 * - execute the pre function before recursion
9 * - execute the post function after recursion
21 #include "irgraph_t.h"
24 #include "type_or_entity.h"
27 /* Make types visible to allow most efficient access */
31 typedef struct type_walk_env {
38 static void type_walk_2(type_or_ent *tore,
39 void (*pre)(type_or_ent*, void*),
40 void (*post)(type_or_ent*, void*),
46 switch (get_kind(tore)) {
48 if (((entity *)tore)->visit >= type_visited) return;
51 if(type_id == get_type_tpop((type*)tore)) {
52 type_walk_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
55 if (((type *)tore)->visit >= type_visited) return;
61 /* execute pre method */
66 switch (get_kind(tore)) {
70 entity *ent = (entity *)tore;
71 ent->visit = type_visited;
72 type_walk_2((type_or_ent *)get_entity_owner(ent), pre, post, env);
73 type_walk_2((type_or_ent *)get_entity_type(ent), pre, post, env);
78 type *tp = (type *)tore;
79 mark_type_visited(tp);
80 switch (get_type_tpop_code(tp)) {
83 for (i=0; i<get_class_n_supertypes(tp); i++)
84 type_walk_2((type_or_ent *)get_class_supertype(tp, i), pre, post, env);
85 for (i=0; i<get_class_n_members(tp); i++)
86 type_walk_2((type_or_ent *)get_class_member(tp, i), pre, post, env);
87 for (i=0; i<get_class_n_subtypes(tp); i++)
88 type_walk_2((type_or_ent *)get_class_subtype(tp, i), pre, post, env);
93 for (i=0; i<get_struct_n_members(tp); i++)
94 type_walk_2((type_or_ent *)get_struct_member(tp, i), pre, post, env);
99 for (i = 0; i < get_method_n_params(tp); i++)
100 type_walk_2((type_or_ent *)get_method_param_type(tp, i), pre, post, env);
101 for (i = 0; i < get_method_n_ress(tp); i++)
102 type_walk_2((type_or_ent *)get_method_res_type(tp, i), pre, post, env);
107 for (i = 0; i < get_union_n_members(tp); i++)
108 type_walk_2((type_or_ent *)get_union_member(tp, i), pre, post, env);
112 type_walk_2((type_or_ent *)get_array_element_type(tp),
114 type_walk_2((type_or_ent *)get_array_element_entity(tp),
117 case tpo_enumeration:
121 type_walk_2((type_or_ent *)get_pointer_points_to_type(tp),
129 printf(" *** Faulty type! \n");
132 } break; /* end case k_type */
134 printf(" *** Faulty type or entity! \n");
138 /* execute post method */
145 static void start_type_walk(ir_node *node, void *env) {
146 void *pre = ((type_walk_env *)env)->pre;
147 void *post = ((type_walk_env *)env)->post;
148 void *envi = ((type_walk_env *)env)->env;
152 switch (get_irn_opcode(node)) { /* node label */
154 if ( (get_SymConst_kind(node) == type_tag)
155 || (get_SymConst_kind(node) == size))
156 type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi);
159 type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi);
162 type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi);
165 type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi);
168 type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi);
175 void type_walk(void (pre)(type_or_ent*, void*),
176 void (post)(type_or_ent*, void*),
180 /*type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
181 global type is on the list visited below, too. */
182 for (i = 0; i < get_irp_n_types(); i++) {
183 type_walk_2((type_or_ent *)get_irp_type(i), pre, post, env);
185 type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
188 void type_walk_irg (ir_graph *irg,
189 void (pre)(type_or_ent*, void*),
190 void (post)(type_or_ent*, void*),
193 /* this is needed to pass the parameters to the walker that actually
194 walks the type information */
195 type_walk_env* type_env;
196 type_env = (type_walk_env *) malloc (sizeof(type_walk_env));
198 type_env->post = post;
202 irg_walk(get_irg_end(irg), start_type_walk, NULL, type_env);
204 type_walk_2((type_or_ent *)get_irg_ent(irg), pre, post, env);
210 static void type_walk_s2s_2(type_or_ent *tore,
211 void (*pre)(type_or_ent*, void*),
212 void (*post)(type_or_ent*, void*),
218 switch (get_kind(tore)) {
220 if (((entity *)tore)->visit >= type_visited) return;
223 if(type_id == get_type_tpop((type*)tore)) {
224 type_walk_s2s_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
227 if (((type *)tore)->visit >= type_visited) return;
234 switch (get_kind(tore)) {
237 type *tp = (type *)tore;
238 mark_type_visited(tp);
239 switch (get_type_tpop_code(tp)) {
242 for (i = 0; i < get_class_n_supertypes(tp); i++) {
243 type_walk_s2s_2((type_or_ent *)get_class_supertype(tp, i), pre,
246 /* execute pre method */
249 tp = skip_tid((type*)tore);
251 for (i = 0; i < get_class_n_subtypes(tp); i++) {
252 type_walk_s2s_2((type_or_ent *)get_class_subtype(tp, i), pre,
256 /* execute post method */
265 case tpo_enumeration:
272 printf(" *** Faulty type! \n");
275 } break; /* end case k_type */
280 printf(" *** Faulty type or entity! \n");
286 void type_walk_super2sub(
287 void (*pre)(type_or_ent*, void*),
288 void (*post)(type_or_ent*, void*),
294 type_walk_s2s_2((type_or_ent *)get_glob_type(), pre, post, env);
295 for (i = 0; i < get_irp_n_types(); i++) {
296 tp = get_irp_type(i);
297 type_walk_s2s_2((type_or_ent *)tp, pre, post, env);
301 /*****************************************************************************/
304 type_walk_super_2(type_or_ent *tore,
305 void (*pre)(type_or_ent*, void*),
306 void (*post)(type_or_ent*, void*),
312 switch (get_kind(tore)) {
314 if (((entity *)tore)->visit >= type_visited) return;
317 if(type_id == get_type_tpop((type*)tore)) {
318 type_walk_super_2((type_or_ent *)skip_tid((type *)tore), pre, post, env);
321 if (((type *)tore)->visit >= type_visited) return;
328 switch (get_kind(tore)) {
331 type *tp = (type *)tore;
332 mark_type_visited(tp);
333 switch (get_type_tpop_code(tp)) {
336 /* execute pre method */
339 tp = skip_tid((type*)tore);
341 for (i = 0; i < get_class_n_supertypes(tp); i++) {
342 type_walk_super_2((type_or_ent *)get_class_supertype(tp, i), pre,
346 /* execute post method */
355 case tpo_enumeration:
362 printf(" *** Faulty type! \n");
365 } break; /* end case k_type */
370 printf(" *** Faulty type or entity! \n");
376 void type_walk_super(
377 void (*pre)(type_or_ent*, void*),
378 void (*post)(type_or_ent*, void*),
383 type_walk_super_2((type_or_ent *)get_glob_type(), pre, post, env);
384 for (i = 0; i < get_irp_n_types(); i++) {
385 tp = get_irp_type(i);
386 type_walk_super_2((type_or_ent *)tp, pre, post, env);
390 /*****************************************************************************/
394 class_walk_s2s_2(type *tp,
395 void (*pre)(type*, void*),
396 void (*post)(type*, void*),
402 if (tp->visit >= type_visited) return;
404 assert(is_class_type(tp));
405 /* Assure all supertypes are visited before */
406 for (i=0; i < get_class_n_supertypes(tp); i++) {
407 if (get_type_visited(get_class_supertype(tp, i)) < type_visited)
411 mark_type_visited(tp);
413 /* execute pre method */
417 tp = skip_tid((type*)tp);
418 for (i=0; i<get_class_n_subtypes(tp); i++) {
419 class_walk_s2s_2(get_class_subtype(tp, i), pre, post, env);
421 /* execute post method */
429 void class_walk_super2sub(
430 void (*pre)(type*, void*),
431 void (*post)(type*, void*),
438 for (i = 0; i < get_irp_n_types(); i++) {
439 tp = get_irp_type(i);
440 if (is_class_type(tp) &&
441 (get_class_n_supertypes(tp) == 0) &&
442 (tp->visit < type_visited) &&
443 (!is_frame_type(tp)) &&
444 (tp != get_glob_type())) {
445 class_walk_s2s_2(tp, pre, post, env);
450 void class_walk_super2sub(
451 void (*pre)(type*, void*),
452 void (post)(type*, void*),
459 for (i = 0; i < get_irp_n_types(); i++) {
460 tp = get_irp_type(i);
461 if (is_class_type(tp) &&
462 (get_class_n_supertypes(tp) == 0) &&
463 (tp->visit < type_visited)) {
464 assert(!is_frame_type(tp));
465 assert(tp != get_glob_type());
466 class_walk_s2s_2(tp, pre, post, env);
472 /* Walks over all entities in the type */
473 void walk_types_entities(
475 void (*doit)(entity*, void*),
479 switch(get_type_tpop_code(tp)) {
481 for (i=0; i<get_class_n_members(tp); i++)
482 doit(get_class_member(tp, i), env);
485 for (i=0; i<get_struct_n_members(tp); i++)
486 doit(get_struct_member(tp, i), env);
489 for (i = 0; i < get_union_n_members(tp); i++)
490 doit(get_union_member(tp, i), env);
493 doit(get_array_element_entity(tp), env);
496 case tpo_enumeration: