01cee4adb3d1f9cc06d546651e09fdf4c5e53585
[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->volatility = non_volatile;
84   res->ld_name = NULL;
85   res->overwrites = NEW_ARR_F(entity *, 1);
86
87   res->irg = NULL;
88
89   res->visit = 0;
90
91   /* Remember entity in it's owner. */
92   insert_entity_in_owner (res);
93   return res;
94 }
95 inline void free_entity_attrs(entity *ent) {
96   assert(ent);
97   DEL_ARR_F(ent->overwrites);
98 }
99
100 entity *
101 copy_entity_own (entity *old, type *new_owner) {
102   entity *new;
103
104   assert_legal_owner_of_ent(new_owner);
105   if (old->owner == new_owner) return old;
106   new = (entity *) malloc (sizeof (entity));
107   memcpy (new, old, sizeof (entity));
108   new->owner = new_owner;
109   new->overwrites = DUP_ARR_F(entity *, old->overwrites);
110
111   insert_entity_in_owner (new);
112
113   return new;
114 }
115
116 entity *
117 copy_entity_name (entity *old, ident *new_name) {
118   entity *new;
119
120   if (old->name == new_name) return old;
121   new = (entity *) malloc (sizeof (entity));
122   memcpy (new, old, sizeof (entity));
123   new->name = new_name;
124   new->ld_name = NULL;
125   new->overwrites = DUP_ARR_F(entity *, old->overwrites);
126
127   insert_entity_in_owner (new);
128
129   return new;
130 }
131
132 inline const char *
133 get_entity_name (entity *ent) {
134   assert (ent);
135   return id_to_str(get_entity_ident(ent));
136 }
137
138 ident *
139 get_entity_ident    (entity *ent) {
140   assert(ent);
141   return ent->name;
142 }
143
144 /*
145 void   set_entity_ld_name  (entity *, char *ld_name);
146 void   set_entity_ld_ident (entity *, ident *ld_ident);
147 */
148
149 inline type *
150 get_entity_owner (entity *ent) {
151   return ent->owner = skip_tid(ent->owner);
152 }
153
154 inline void
155 set_entity_owner (entity *ent, type *owner) {
156   assert_legal_owner_of_ent(owner);
157   ent->owner = owner;
158 }
159
160 inline void   /* should this go into type.c? */
161 assert_legal_owner_of_ent(type *owner) {
162   assert (get_type_tpop_code(owner) == tpo_class ||
163           get_type_tpop_code(owner) == tpo_union ||
164           get_type_tpop_code(owner) == tpo_struct ||
165           get_type_tpop_code(owner) == tpo_array);   /* Yes, array has an entity
166                                                         -- to select fields! */
167 }
168
169 inline ident *
170 get_entity_ld_ident (entity *ent)
171 {
172   if (ent->ld_name == NULL)
173     ent->ld_name = mangle_entity (ent);
174   return ent->ld_name;
175 }
176
177 inline void
178 set_entity_ld_ident (entity *ent, ident *ld_ident) {
179   ent->ld_name = ld_ident;
180 }
181
182 inline const char *
183 get_entity_ld_name (entity *ent) {
184   return id_to_str(get_entity_ld_ident(ent));
185 }
186
187 /*
188 char  *get_entity_ld_name  (entity *);
189 void   set_entity_ld_name  (entity *, char *ld_name);
190 */
191
192 inline type *
193 get_entity_type (entity *ent) {
194   return ent->type = skip_tid(ent->type);
195 }
196
197 inline void
198 set_entity_type (entity *ent, type *type) {
199   ent->type = type;
200 }
201
202
203 inline ent_allocation
204 get_entity_allocation (entity *ent) {
205   return ent->allocation;
206 }
207
208 inline void
209 set_entity_allocation (entity *ent, ent_allocation al) {
210   ent->allocation = al;
211 }
212
213
214 inline ent_visibility
215 get_entity_visibility (entity *ent) {
216   return ent->visibility;
217 }
218
219 inline void
220 set_entity_visibility (entity *ent, ent_visibility vis) {
221   if (vis != local) assert(ent->allocation == static_allocated);
222   ent->visibility = vis;
223 }
224
225 inline ent_variability
226 get_entity_variability (entity *ent) {
227   return ent->variability;
228 }
229
230 inline void
231 set_entity_variability (entity *ent, ent_variability var){
232   if (var == part_constant)
233     assert(is_class_type(ent->type) || is_struct_type(ent->type));
234   if ((is_compound_type(ent->type)) &&
235       (ent->variability == uninitialized) && (var != uninitialized)) {
236     /* Allocate datastructures for constant values */
237     ent->values = NEW_ARR_F(ir_node *, 1);
238     ent->val_ents = NEW_ARR_F(entity *, 1);
239   }
240   if ((is_compound_type(ent->type)) &&
241       (var == uninitialized) && (ent->variability != uninitialized)) {
242     /* Free datastructures for constant values */
243     DEL_ARR_F(ent->values);
244     DEL_ARR_F(ent->val_ents);
245   }
246   ent->variability = var;
247 }
248
249
250 inline ent_volatility
251 get_entity_volatility (entity *ent) {
252   return ent->volatility;
253 }
254
255 inline void
256 set_entity_volatility (entity *ent, ent_volatility vol) {
257   ent->volatility = vol;
258 }
259
260 inline peculiarity
261 get_entity_peculiarity (entity *ent) {
262   assert (ent);
263   assert (is_method_type(ent->type));
264   return ent->peculiarity;
265 }
266
267 inline void
268 set_entity_peculiarity (entity *ent, peculiarity pec) {
269   assert (ent);
270   assert (is_method_type(ent->type));
271   ent->peculiarity = pec;
272 }
273
274 /* Set has no effect for entities of type method. */
275 inline ir_node *
276 get_atomic_ent_value(entity *ent) {
277   assert(ent); assert(is_atomic_entity(ent)); assert((ent->variability != uninitialized));
278   return ent->value;
279 }
280
281 inline void
282 set_atomic_ent_value(entity *ent, ir_node *val) {
283   assert(ent && is_atomic_entity(ent) && (ent->variability != uninitialized));
284   if (is_method_type(ent->type)) return;
285   ent->value = val;
286 }
287
288 ir_node *copy_value(ir_node *n) {
289   ir_node *nn;
290   ir_mode *m;
291
292   m = get_irn_mode(n);
293   switch(get_irn_opcode(n)) {
294   case iro_Const:
295     nn = new_Const(m, get_Const_tarval(n)); break;
296   case iro_SymConst:
297     nn = new_SymConst(get_SymConst_type_or_id(n), get_SymConst_kind(n)); break;
298   case iro_Add:
299     nn = new_Add(copy_value(get_Add_left(n)), copy_value(get_Add_right(n)), m); break;
300   default:
301     assert(0 && "opdope invalid or not implemented"); break;
302   }
303   return nn;
304 }
305
306 /* Copies the value represented by the entity to current_block
307    in current_ir_graph. */
308 ir_node *copy_atomic_ent_value(entity *ent) {
309   assert(ent && is_atomic_entity(ent) && (ent->variability != uninitialized));
310   return copy_value(ent->value);
311 }
312
313 /* A value of a compound entity is a pair of value and the corresponding member of
314    the compound. */
315 inline void
316 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
317   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
318   ARR_APP1 (ir_node *, ent->values, val);
319   ARR_APP1 (entity *, ent->val_ents, member);
320 }
321
322 inline int
323 get_compound_ent_n_values(entity *ent) {
324   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
325   return (ARR_LEN (ent->values))-1;
326 }
327
328 inline ir_node  *
329 get_compound_ent_value(entity *ent, int pos) {
330   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
331   return ent->values[pos+1];
332 }
333
334 /* Copies the value i of the entity to current_block in current_ir_graph. */
335 ir_node *copy_compound_ent_value(entity *ent, int pos) {
336   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
337   return copy_value(ent->values[pos+1]);
338 }
339
340 inline entity   *
341 get_compound_ent_value_member(entity *ent, int pos) {
342   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
343   return ent->val_ents[pos+1];
344 }
345
346 inline void
347 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
348   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
349   ent->values[pos+1] = val;
350   ent->val_ents[pos+1] = member;
351 }
352
353 inline int
354 get_entity_offset (entity *ent) {
355   return ent->offset;
356 }
357
358 inline void
359 set_entity_offset (entity *ent, int offset) {
360   ent->offset = offset;
361 }
362
363 inline void
364 add_entity_overwrites   (entity *ent, entity *overwritten) {
365   assert(ent);
366   ARR_APP1 (entity *, ent->overwrites, overwritten);
367 }
368
369 inline int
370 get_entity_n_overwrites (entity *ent){
371   assert(ent);
372   return (ARR_LEN (ent->overwrites))-1;
373 }
374
375 inline entity *
376 get_entity_overwrites   (entity *ent, int pos){
377   assert(ent);
378   return ent->overwrites[pos+1];
379 }
380
381 inline void
382 set_entity_overwrites   (entity *ent, int pos, entity *overwritten) {
383   assert(ent);
384   ent->overwrites[pos+1] = overwritten;
385 }
386
387 /* A link to store intermediate information */
388 void *
389 get_entity_link(entity *ent) {
390   assert(ent);
391   return ent->link;
392 }
393
394 void
395 set_entity_link(entity *ent, void *l) {
396   assert(ent);
397   ent->link = l;
398 }
399
400 inline ir_graph *
401 get_entity_irg(entity *ent) {
402   assert (ent);
403   assert (is_method_type(ent->type));
404   return ent->irg;
405 }
406
407 inline void
408 set_entity_irg(entity *ent, ir_graph *irg) {
409   assert (ent && ent->type);
410   assert (irg);
411   assert (is_method_type(ent->type));
412   ent->irg = irg;
413 }
414
415 int is_atomic_entity(entity *ent) {
416   type* t = get_entity_type(ent);
417   return (is_primitive_type(t) || is_pointer_type(t) ||
418           is_enumeration_type(t) || is_method_type(t));
419 }
420
421 int is_compound_entity(entity *ent) {
422   type* t = get_entity_type(ent);
423   return (is_class_type(t) || is_struct_type(t) ||
424           is_array_type(t) || is_union_type(t));
425 }