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
15 #include "type_or_entity.h"
17 typedef struct type_walk_env {
24 void type_walk_2(type_or_ent *tore,
25 void (pre)(type_or_ent*, void*), void (post)(type_or_ent*, void*),
31 switch (get_kind(tore)) {
33 if (((entity *)tore)->visit >= type_visited) visited = 1; break;
35 if (((type_class *)tore)->visit >= type_visited) visited = 1; break;
37 if (((type_strct *)tore)->visit >= type_visited) visited = 1; break;
39 if (((type_method *)tore)->visit >= type_visited) visited = 1; break;
41 if (((type_union *)tore)->visit >= type_visited) visited = 1; break;
43 if (((type_array *)tore)->visit >= type_visited) visited = 1; break;
44 case k_type_enumeration:
45 if (((type_enumeration *)tore)->visit >= type_visited) visited = 1; break;
47 if (((type_pointer *)tore)->visit >= type_visited) visited = 1; break;
48 case k_type_primitive:
49 if (((type_primitive *)tore)->visit >= type_visited) visited = 1; break;
54 if (!visited) { /* not marked. */
56 /* execute pre method */
61 switch (get_kind(tore)) {
64 entity *ent = (entity *)tore;
65 ent->visit = type_visited;
66 type_walk_2((type_or_ent *)get_entity_owner(ent), pre, post, env);
67 type_walk_2((type_or_ent *)get_entity_type(ent), pre, post, env);
71 ((type_class *)tore)->visit = type_visited;
75 ((type_strct *)tore)->visit = type_visited;
80 type_method *meth = (type_method *)tore;
81 meth->visit = type_visited;
82 for (i = 0; i < get_method_arity(meth); i++)
83 type_walk_2((type_or_ent *)get_method_param_type(meth, i), pre, post, env);
84 for (i = 0; i < get_method_n_res(meth); i++)
85 type_walk_2((type_or_ent *)get_method_res_type(meth, i), pre, post, env);
89 ((type_union *)tore)->visit = type_visited;
92 ((type_array *)tore)->visit = type_visited;
93 type_walk_2((type_or_ent *)get_array_element_type((type_array *)tore),
96 case k_type_enumeration:
97 ((type_enumeration *)tore)->visit = type_visited;
101 ((type_pointer *)tore)->visit = type_visited;
102 type_walk_2((type_or_ent *)get_pointer_points_to_type((type_pointer *)tore),
105 case k_type_primitive:
106 ((type_primitive *)tore)->visit = type_visited;
113 /* execute post method */
121 void start_type_walk(ir_node *node, void *env) {
122 void *pre = ((type_walk_env *)env)->pre;
123 void *post = ((type_walk_env *)env)->post;
124 void *envi = ((type_walk_env *)env)->env;
128 switch (get_irn_opcode(node)) { /* node label */
130 if ( (get_SymConst_kind(node) == type_tag)
131 || (get_SymConst_kind(node) == size))
132 type_walk_2((type_or_ent *)get_SymConst_type(node), pre, post, envi);
135 type_walk_2((type_or_ent *)get_Sel_entity(node), pre, post, envi);
138 type_walk_2((type_or_ent *)get_Call_type(node), pre, post, envi);
141 type_walk_2((type_or_ent *)get_Alloc_type(node), pre, post, envi);
143 type_walk_2((type_or_ent *)get_Free_type(node), pre, post, envi);
151 void type_walk(ir_graph *irg,
152 void (pre)(type_or_ent*, void*), void (post)(type_or_ent*, void*),
155 /* this is needed to pass the parameters to the walker that actually
156 walks the type information */
157 type_walk_env* type_env;
158 type_env = (type_walk_env *) malloc (sizeof(type_walk_env));
160 type_env->post = post;
164 irg_walk(irg->end, start_type_walk, NULL, type_env);