1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
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
22 #include "type_or_entity.h"
24 /* Make types visible to allow most efficient access */
25 # include "entity_t.h"
27 typedef struct type_walk_env {
34 void type_walk_2(type_or_ent *tore,
35 void (pre)(type_or_ent*, void*),
36 void (post)(type_or_ent*, void*),
42 switch (get_kind(tore)) {
44 if (((entity *)tore)->visit >= type_visited) visited = 1; break;
46 if (((type_class *)tore)->visit >= type_visited) visited = 1; break;
48 if (((type_strct *)tore)->visit >= type_visited) visited = 1; break;
50 if (((type_method *)tore)->visit >= type_visited) visited = 1; break;
52 if (((type_union *)tore)->visit >= type_visited) visited = 1; break;
54 if (((type_array *)tore)->visit >= type_visited) visited = 1; break;
55 case k_type_enumeration:
56 if (((type_enumeration *)tore)->visit >= type_visited) visited = 1; break;
58 if (((type_pointer *)tore)->visit >= type_visited) visited = 1; break;
59 case k_type_primitive:
60 if (((type_primitive *)tore)->visit >= type_visited) visited = 1; break;
65 if (!visited) { /* not marked. */
67 /* execute pre method */
72 switch (get_kind(tore)) {
75 entity *ent = (entity *)tore;
76 ent->visit = type_visited;
77 type_walk_2((type_or_ent *)get_entity_owner(ent), pre, post, env);
78 type_walk_2((type_or_ent *)get_entity_type(ent), pre, post, env);
84 ((type_class *)tore)->visit = type_visited;
86 for (i=0; i<get_class_n_member((type_class *)tore); i++)
88 type_walk_2((type_or_ent *)get_class_member((type_class *)tore, i),
91 for (i=0; i<get_class_n_subtype((type_class *)tore); i++)
93 type_walk_2((type_or_ent *)get_class_subtype((type_class *)tore, i),
96 for (i=0; i<get_class_n_supertype((type_class *)tore); i++)
98 type_walk_2((type_or_ent *)get_class_supertype((type_class *)tore, i),
107 ((type_strct *)tore)->visit = type_visited;
109 for (i=0; i<get_strct_n_member((type_strct *)tore); i++)
111 type_walk_2((type_or_ent *)get_strct_member((type_strct *)tore, i),
118 type_method *meth = (type_method *)tore;
119 meth->visit = type_visited;
120 for (i = 0; i < get_method_arity(meth); i++)
121 type_walk_2((type_or_ent *)get_method_param_type(meth, i), pre, post, env);
122 for (i = 0; i < get_method_n_res(meth); i++)
123 type_walk_2((type_or_ent *)get_method_res_type(meth, i), pre, post, env);
127 ((type_union *)tore)->visit = type_visited;
131 ((type_array *)tore)->visit = type_visited;
132 type_walk_2((type_or_ent *)get_array_element_type((type_array *)tore),
135 case k_type_enumeration:
136 ((type_enumeration *)tore)->visit = type_visited;
140 ((type_pointer *)tore)->visit = type_visited;
141 type_walk_2((type_or_ent *)get_pointer_points_to_type((type_pointer *)tore),
144 case k_type_primitive:
145 ((type_primitive *)tore)->visit = type_visited;
152 /* execute post method */
160 void start_type_walk(ir_node *node, void *env) {
161 void *pre = ((type_walk_env *)env)->pre;
162 void *post = ((type_walk_env *)env)->post;
163 void *envi = ((type_walk_env *)env)->env;
167 switch (get_irn_opcode(node)) { /* node label */
169 if ( (get_SymConst_kind(node) == type_tag)
170 || (get_SymConst_kind(node) == size))
171 type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi);
174 type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi);
177 type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi);
180 type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi);
183 printf("here in typewalk\n");
184 type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi);
192 void type_walk(void (pre)(type_or_ent*, void*),
193 void (post)(type_or_ent*, void*),
197 type_walk_2((type_or_ent *)get_glob_type(), pre, post, env);
198 for (i = 0; i < get_irp_n_types(); i++) {
199 type_walk_2((type_or_ent *)get_irp_type(i), pre, post, env);
203 void type_walk_irg (ir_graph *irg,
204 void (pre)(type_or_ent*, void*),
205 void (post)(type_or_ent*, void*),
208 /* this is needed to pass the parameters to the walker that actually
209 walks the type information */
210 type_walk_env* type_env;
211 type_env = (type_walk_env *) malloc (sizeof(type_walk_env));
213 type_env->post = post;
217 irg_walk(get_irg_end(irg), start_type_walk, NULL, type_env);
219 type_walk_2((type_or_ent *)get_irg_ent(irg), pre, post, env);
221 /* @@@ free type_walk_env!! */