Added iro_InstOf operator --flo
[libfirm] / ir / tr / entity.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Martin Trapp, Christian Schaefer
5 **
6 */
7
8 /* $Id$ */
9
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13
14 # include <stdlib.h>
15 # include <stddef.h>
16 # include "entity_t.h"
17 # include "mangle.h"
18 # include "typegmod_t.h"
19 # include "array.h"
20 /* All this is needed to build the constant node for methods: */
21 # include "irprog.h"
22 # include "ircons.h"
23
24 /*******************************************************************/
25 /** general                                                       **/
26 /*******************************************************************/
27
28 void
29 init_entity (void)
30 {
31 }
32
33 /*******************************************************************/
34 /** ENTITY                                                        **/
35 /*******************************************************************/
36
37 inline void insert_entity_in_owner (entity *ent) {
38   type *owner = ent->owner;
39   switch (get_type_tpop_code(owner)) {
40   case tpo_class: {
41     add_class_member (owner, ent);
42   } break;
43   case tpo_struct: {
44     add_struct_member (owner, ent);
45   } break;
46   case tpo_union: {
47     add_union_member (owner, ent);
48   } break;
49   case tpo_array: {
50     set_array_element_entity(owner, ent);
51   } break;
52   default: assert(0);
53   }
54 }
55
56 entity *
57 new_entity (type *owner, ident *name, type *type)
58 {
59   entity *res;
60   ir_graph *rem;
61
62   res = (entity *) malloc (sizeof (entity));
63   res->kind = k_entity;
64   assert_legal_owner_of_ent(owner);
65   res->owner = owner;
66   res->name = name;
67   res->type = type;
68   if (get_type_tpop(type) == type_method)
69     res->allocation = static_allocated;
70   else
71     res->allocation = automatic_allocated;
72   res->visibility = local;
73   res->offset = -1;
74   if (is_method_type(type)) {
75     res->variability = constant;
76     rem = current_ir_graph;
77     current_ir_graph = get_const_code_irg();
78     res->value = new_Const(mode_p, tarval_p_from_entity(res));
79     current_ir_graph = rem;
80   } else {
81     res->variability = uninitialized;
82   }
83   res->peculiarity = existent;
84   res->volatility = non_volatile;
85   res->ld_name = NULL;
86   res->overwrites = NEW_ARR_F(entity *, 1);
87   res->overwrittenby = NEW_ARR_F(entity *, 1);
88
89   res->irg = NULL;
90
91   res->visit = 0;
92
93   /* Remember entity in it's owner. */
94   insert_entity_in_owner (res);
95   return res;
96 }
97 inline void free_entity_attrs(entity *ent) {
98   assert(ent);
99   DEL_ARR_F(ent->overwrites);
100   DEL_ARR_F(ent->overwrittenby);
101 }
102
103 entity *
104 copy_entity_own (entity *old, type *new_owner) {
105   entity *new;
106
107   assert_legal_owner_of_ent(new_owner);
108   if (old->owner == new_owner) return old;
109   new = (entity *) malloc (sizeof (entity));
110   memcpy (new, old, sizeof (entity));
111   new->owner = new_owner;
112   new->overwrites = DUP_ARR_F(entity *, old->overwrites);
113   new->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
114
115   insert_entity_in_owner (new);
116
117   return new;
118 }
119
120 entity *
121 copy_entity_name (entity *old, ident *new_name) {
122   entity *new;
123
124   if (old->name == new_name) return old;
125   new = (entity *) malloc (sizeof (entity));
126   memcpy (new, old, sizeof (entity));
127   new->name = new_name;
128   new->ld_name = NULL;
129   new->overwrites = DUP_ARR_F(entity *, old->overwrites);
130   new->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
131
132   insert_entity_in_owner (new);
133
134   return new;
135 }
136
137 inline const char *
138 get_entity_name (entity *ent) {
139   assert (ent);
140   return id_to_str(get_entity_ident(ent));
141 }
142
143 ident *
144 get_entity_ident    (entity *ent) {
145   assert(ent);
146   return ent->name;
147 }
148
149 /*
150 void   set_entity_ld_name  (entity *, char *ld_name);
151 void   set_entity_ld_ident (entity *, ident *ld_ident);
152 */
153
154 inline type *
155 get_entity_owner (entity *ent) {
156   return ent->owner = skip_tid(ent->owner);
157 }
158
159 inline void
160 set_entity_owner (entity *ent, type *owner) {
161   assert_legal_owner_of_ent(owner);
162   ent->owner = owner;
163 }
164
165 inline void   /* should this go into type.c? */
166 assert_legal_owner_of_ent(type *owner) {
167   assert (get_type_tpop_code(owner) == tpo_class ||
168           get_type_tpop_code(owner) == tpo_union ||
169           get_type_tpop_code(owner) == tpo_struct ||
170           get_type_tpop_code(owner) == tpo_array);   /* Yes, array has an entity
171                                                         -- to select fields! */
172 }
173
174 inline ident *
175 get_entity_ld_ident (entity *ent)
176 {
177   if (ent->ld_name == NULL)
178     ent->ld_name = mangle_entity (ent);
179   return ent->ld_name;
180 }
181
182 inline void
183 set_entity_ld_ident (entity *ent, ident *ld_ident) {
184   ent->ld_name = ld_ident;
185 }
186
187 inline const char *
188 get_entity_ld_name (entity *ent) {
189   return id_to_str(get_entity_ld_ident(ent));
190 }
191
192 /*
193 char  *get_entity_ld_name  (entity *);
194 void   set_entity_ld_name  (entity *, char *ld_name);
195 */
196
197 inline type *
198 get_entity_type (entity *ent) {
199   return ent->type = skip_tid(ent->type);
200 }
201
202 inline void
203 set_entity_type (entity *ent, type *type) {
204   ent->type = type;
205 }
206
207
208 inline ent_allocation
209 get_entity_allocation (entity *ent) {
210   return ent->allocation;
211 }
212
213 inline void
214 set_entity_allocation (entity *ent, ent_allocation al) {
215   ent->allocation = al;
216 }
217
218
219 inline ent_visibility
220 get_entity_visibility (entity *ent) {
221   return ent->visibility;
222 }
223
224 inline void
225 set_entity_visibility (entity *ent, ent_visibility vis) {
226   if (vis != local) assert(ent->allocation == static_allocated);
227   ent->visibility = vis;
228 }
229
230 inline ent_variability
231 get_entity_variability (entity *ent) {
232   return ent->variability;
233 }
234
235 inline void
236 set_entity_variability (entity *ent, ent_variability var){
237   if (var == part_constant)
238     assert(is_class_type(ent->type) || is_struct_type(ent->type));
239   if ((is_compound_type(ent->type)) &&
240       (ent->variability == uninitialized) && (var != uninitialized)) {
241     /* Allocate datastructures for constant values */
242     ent->values = NEW_ARR_F(ir_node *, 1);
243     ent->val_ents = NEW_ARR_F(entity *, 1);
244   }
245   if ((is_compound_type(ent->type)) &&
246       (var == uninitialized) && (ent->variability != uninitialized)) {
247     /* Free datastructures for constant values */
248     DEL_ARR_F(ent->values);
249     DEL_ARR_F(ent->val_ents);
250   }
251   ent->variability = var;
252 }
253
254
255 inline ent_volatility
256 get_entity_volatility (entity *ent) {
257   return ent->volatility;
258 }
259
260 inline void
261 set_entity_volatility (entity *ent, ent_volatility vol) {
262   ent->volatility = vol;
263 }
264
265 inline peculiarity
266 get_entity_peculiarity (entity *ent) {
267   assert (ent);
268   //assert (is_method_type(ent->type));
269   return ent->peculiarity;
270 }
271
272 inline void
273 set_entity_peculiarity (entity *ent, peculiarity pec) {
274   assert (ent);
275   assert (is_method_type(ent->type));
276   ent->peculiarity = pec;
277 }
278
279 /* Set has no effect for entities of type method. */
280 inline ir_node *
281 get_atomic_ent_value(entity *ent) {
282   assert(ent); assert(is_atomic_entity(ent));
283   assert((ent->variability != uninitialized));
284   return ent->value;
285 }
286
287 inline void
288 set_atomic_ent_value(entity *ent, ir_node *val) {
289   assert(ent && is_atomic_entity(ent) && (ent->variability != uninitialized));
290   if (is_method_type(ent->type)) return;
291   ent->value = val;
292 }
293
294
295 ir_node *copy_const_value(ir_node *n) {
296   ir_node *nn;
297   ir_mode *m;
298
299   m = get_irn_mode(n);
300   switch(get_irn_opcode(n)) {
301   case iro_Const:
302     nn = new_Const(m, get_Const_tarval(n)); break;
303   case iro_SymConst:
304     nn = new_SymConst(get_SymConst_type_or_id(n), get_SymConst_kind(n)); break;
305   case iro_Add:
306     nn = new_Add(copy_const_value(get_Add_left(n)), copy_const_value(get_Add_right(n)), m); break;
307   default:
308     assert(0 && "opdope invalid or not implemented"); break;
309   }
310   return nn;
311 }
312
313 /* Copies the value represented by the entity to current_block
314    in current_ir_graph. */
315 ir_node *copy_atomic_ent_value(entity *ent) {
316   assert(ent && is_atomic_entity(ent) && (ent->variability != uninitialized));
317   return copy_const_value(ent->value);
318 }
319
320 /* A value of a compound entity is a pair of value and the corresponding member of
321    the compound. */
322 inline void
323 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
324   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
325   ARR_APP1 (ir_node *, ent->values, val);
326   ARR_APP1 (entity *, ent->val_ents, member);
327 }
328
329 /* Copies the firm subgraph referenced by val to const_code_irg and adds
330    the node as constant initialization to ent.
331    The subgraph may not contain control flow operations. */
332 inline void
333 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
334   ir_graph *rem = current_ir_graph;
335
336   assert(get_entity_variability(ent) != uninitialized);
337   current_ir_graph = get_const_code_irg();
338
339   val = copy_const_value(val);
340   add_compound_ent_value(ent, val, member);
341   current_ir_graph = rem;
342 }
343
344 inline int
345 get_compound_ent_n_values(entity *ent) {
346   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
347   return (ARR_LEN (ent->values))-1;
348 }
349
350 inline ir_node  *
351 get_compound_ent_value(entity *ent, int pos) {
352   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
353   return ent->values[pos+1];
354 }
355
356 /* Copies the value i of the entity to current_block in current_ir_graph. */
357 ir_node *
358 copy_compound_ent_value(entity *ent, int pos) {
359   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
360   return copy_const_value(ent->values[pos+1]);
361 }
362
363 inline entity   *
364 get_compound_ent_value_member(entity *ent, int pos) {
365   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
366   return ent->val_ents[pos+1];
367 }
368
369 inline void
370 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
371   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
372   ent->values[pos+1] = val;
373   ent->val_ents[pos+1] = member;
374 }
375
376 void
377 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
378   int i;
379   ir_graph *rem = current_ir_graph;
380   type *arrtp = get_entity_type(ent);
381   ir_node *val;
382
383   assert(is_array_type(arrtp));
384   assert(get_array_n_dimensions(arrtp) == 1);
385   /* One bound is sufficient, the nunmber of constant fields makes the
386      size. */
387   assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
388   assert(get_entity_variability(ent) != uninitialized);
389   current_ir_graph = get_const_code_irg();
390
391   for (i = 0; i < num_vals; i++) {
392     val = new_Const(get_tv_mode (values[i]), values[i]);
393     add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
394   }
395   current_ir_graph = rem;
396 }
397
398 inline int
399 get_entity_offset (entity *ent) {
400   return ent->offset;
401 }
402
403 inline void
404 set_entity_offset (entity *ent, int offset) {
405   ent->offset = offset;
406 }
407
408 inline void
409 add_entity_overwrites   (entity *ent, entity *overwritten) {
410   assert(ent);
411   assert(is_class_type(get_entity_owner(ent)));
412   ARR_APP1 (entity *, ent->overwrites, overwritten);
413   ARR_APP1 (entity *, overwritten->overwrittenby, ent);
414 }
415
416 inline int
417 get_entity_n_overwrites (entity *ent) {
418   assert(ent);
419   assert(is_class_type(get_entity_owner(ent)));
420   return (ARR_LEN (ent->overwrites))-1;
421 }
422
423 inline entity *
424 get_entity_overwrites   (entity *ent, int pos) {
425   assert(ent);
426   assert(is_class_type(get_entity_owner(ent)));
427   assert(pos < get_entity_n_overwrites(ent));
428   return ent->overwrites[pos+1];
429 }
430
431 inline void
432 set_entity_overwrites   (entity *ent, int pos, entity *overwritten) {
433   assert(ent);
434   assert(is_class_type(get_entity_owner(ent)));
435   assert(pos < get_entity_n_overwrites(ent));
436   ent->overwrites[pos+1] = overwritten;
437 }
438
439 inline void
440 add_entity_overwrittenby   (entity *ent, entity *overwrites) {
441   assert(ent);
442   assert(is_class_type(get_entity_owner(ent)));
443   add_entity_overwrites(overwrites, ent);
444 }
445
446 inline int
447 get_entity_n_overwrittenby (entity *ent) {
448   assert(ent);
449   assert(is_class_type(get_entity_owner(ent)));
450   return (ARR_LEN (ent->overwrittenby))-1;
451 }
452
453 inline entity *
454 get_entity_overwrittenby   (entity *ent, int pos) {
455   assert(ent);
456   assert(is_class_type(get_entity_owner(ent)));
457   assert(pos < get_entity_n_overwrittenby(ent));
458   return ent->overwrittenby[pos+1];
459 }
460
461 inline void
462 set_entity_overwrittenby   (entity *ent, int pos, entity *overwrites) {
463   assert(ent);
464   assert(is_class_type(get_entity_owner(ent)));
465   assert(pos < get_entity_n_overwrittenby(ent));
466   ent->overwrittenby[pos+1] = overwrites;
467 }
468
469 /* A link to store intermediate information */
470 void *
471 get_entity_link(entity *ent) {
472   assert(ent);
473   return ent->link;
474 }
475
476 void
477 set_entity_link(entity *ent, void *l) {
478   assert(ent);
479   ent->link = l;
480 }
481
482 inline ir_graph *
483 get_entity_irg(entity *ent) {
484   assert (ent);
485   assert (is_method_type(ent->type));
486   return ent->irg;
487 }
488
489 inline void
490 set_entity_irg(entity *ent, ir_graph *irg) {
491   assert (ent && ent->type);
492   /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
493    * Methode selbst nicht mehr aufgerufen werden kann, die Entität
494    * aber erhalten bleiben soll. */
495   /* assert (irg); */
496   assert (is_method_type(ent->type));
497   assert (ent->peculiarity == existent);
498   ent->irg = irg;
499 }
500
501 int is_atomic_entity(entity *ent) {
502   type* t = get_entity_type(ent);
503   return (is_primitive_type(t) || is_pointer_type(t) ||
504           is_enumeration_type(t) || is_method_type(t));
505 }
506
507 int is_compound_entity(entity *ent) {
508   type* t = get_entity_type(ent);
509   return (is_class_type(t) || is_struct_type(t) ||
510           is_array_type(t) || is_union_type(t));
511 }