6d9076f596284f8f5a3d61b356a83e73375d8f8f
[libfirm] / ir / tr / trvrfy.c
1
2 #include "trvrfy.h"
3 #include "irgraph_t.h"  /* for checking whether constant code is allocated
4                            on proper obstack */
5
6 /**
7  * Check a class
8  */
9 static int check_class(type *tp) {
10   int i, j, k;
11   int found;
12
13   /*printf("\n"); DDMT(tp);*/
14
15   for (i = 0; i < get_class_n_members(tp); i++) {
16
17     entity *mem = get_class_member(tp, i);
18     assert(mem && "NULL members not allowed");
19     /*printf(" %d, %d", get_entity_n_overwrites(mem), get_class_n_supertypes(tp)); DDME(mem);*/
20     if (!mem) return error_null_mem;
21
22     if (get_entity_n_overwrites(mem) > get_class_n_supertypes(tp)) {
23       DDMT(tp); DDME(mem);
24       assert(get_entity_n_overwrites(mem) <= get_class_n_supertypes(tp));
25     }
26     for (j = 0; j < get_entity_n_overwrites(mem); j++) {
27       entity *ovw = get_entity_overwrites(mem, j);
28       /*printf(" overwrites: "); DDME(ovw);*/
29       /* Check whether ovw is member of one of tp's supertypes. If so,
30          the representation is correct. */
31       found = false;
32       for (k = 0; k < get_class_n_supertypes(tp); k++) {
33         if (get_class_member_index(get_class_supertype(tp, k), ovw) >= 0) {
34           found = true;
35           break;
36         }
37       }
38       if (!found) {
39         DDMT(tp); DDME(mem);
40         assert(found && "overwrites an entity not contained in direct supertype");
41         return error_ent_not_cont;
42       }
43     }
44
45   }
46   return 0;
47 }
48
49 /**
50  * Checks a type.
51  *
52  * Currently checks class types only.
53  */
54 static int check_type(type *tp) {
55   switch (get_type_tpop_code(tp)) {
56   case tpo_class:
57     return check_class(tp);
58   default: break;
59   }
60   return 0;
61 }
62
63 /**
64  * helper environment struct for constant_on_wrong_obstack()
65  */
66 struct myenv {
67   int res;
68   ir_graph *irg;
69 };
70
71 /**
72  * called by the walker
73  */
74 static void on_irg_storage(ir_node *n, void *env) {
75   struct myenv * myenv = env;
76
77   myenv->res = node_is_in_irgs_storage(myenv->irg, n);
78
79   /* We also test whether the setting of the visited flag is legal. */
80   assert(get_irn_visited(n) <= get_irg_visited(myenv->irg) &&
81          "Visited flag of node is larger than that of corresponding irg.");
82 }
83
84 /**
85  * checks wheater a given constant IR node is NOT on the
86  * constant IR graph.
87  */
88 static int constant_on_wrong_irg(ir_node *n) {
89   struct myenv env;
90
91   env.res = 1;  /* on right obstack */
92   env.irg = get_const_code_irg();
93
94   irg_walk(n, on_irg_storage, NULL, (void *)&env);
95   return ! env.res;
96 }
97
98 /*
99  * Check if constants node are NOT on the constant IR graph.
100  */
101 static int constants_on_wrong_irg(entity *ent) {
102   if (get_entity_variability(ent) == uninitialized) return 0;
103
104   if (is_compound_entity(ent)) {
105     int i;
106     for (i = 0; i < get_compound_ent_n_values(ent); i++) {
107       if (constant_on_wrong_irg(get_compound_ent_value(ent, i)))
108         return 1;
109     }
110   } else {
111     /* Might not be set if entity belongs to a description. */
112     if (get_atomic_ent_value(ent))
113       return constant_on_wrong_irg(get_atomic_ent_value(ent));
114     else
115       assert((is_class_type(get_entity_owner(ent)) &&
116               get_class_peculiarity(get_entity_owner(ent)) == description) &&
117              "Value in constant atomic entity not set.");
118   }
119   return 0;
120 }
121
122 /*
123  * Check an entity. Currently, we check only if initialized constants
124  * are build on the const irg graph.
125  *
126  * @return
127  *      0       if no error encountered
128  *      != 0    else
129  */
130 static int check_entity(entity *ent) {
131   current_ir_graph =  get_const_code_irg();
132   if (constants_on_wrong_irg(ent)) {
133     assert(0 && "Contants placed on wrong IRG");
134     return error_const_on_wrong_irg;
135   }
136   return 0;
137 }
138
139 /*
140  * check types and entities
141  */
142 static void check_tore(type_or_ent *tore, void *env) {
143   int *res = env;
144   assert(tore);
145   if (is_type(tore)) {
146     *res = check_type((type *)tore);
147   } else {
148     assert(is_entity(tore));
149     *res = check_entity((entity *)tore);
150   }
151 }
152
153 /*
154  * Verify types and entities.
155  */
156 int tr_vrfy(void) {
157   int res;
158
159   type_walk(check_tore, NULL, &res);
160   return res;
161 }