Added initialization of fields
[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 <string.h>
17
18 # include "entity_t.h"
19 # include "mangle.h"
20 # include "typegmod_t.h"
21 # include "array.h"
22 /* All this is needed to build the constant node for methods: */
23 # include "irprog_t.h"
24 # include "ircons.h"
25
26 /*******************************************************************/
27 /** general                                                       **/
28 /*******************************************************************/
29
30 void
31 init_entity (void)
32 {
33 }
34
35 /*******************************************************************/
36 /** ENTITY                                                        **/
37 /*******************************************************************/
38
39 /* redeclared to declare INLINE. */
40 INLINE entity *get_entity_overwrites   (entity *ent, int pos);
41 INLINE entity *get_entity_overwrittenby   (entity *ent, int pos);
42 INLINE type   *get_entity_owner (entity *ent);
43
44 INLINE void insert_entity_in_owner (entity *ent) {
45   type *owner = ent->owner;
46   switch (get_type_tpop_code(owner)) {
47   case tpo_class: {
48     add_class_member (owner, ent);
49   } break;
50   case tpo_struct: {
51     add_struct_member (owner, ent);
52   } break;
53   case tpo_union: {
54     add_union_member (owner, ent);
55   } break;
56   case tpo_array: {
57     set_array_element_entity(owner, ent);
58   } break;
59   default: assert(0);
60   }
61 }
62
63 entity *
64 new_entity (type *owner, ident *name, type *type)
65 {
66   entity *res;
67   ir_graph *rem;
68
69   assert(!id_contains_char(name, ' ') && "entity name should not contain spaces");
70
71   res = (entity *) malloc (sizeof (entity));
72   res->kind = k_entity;
73   assert_legal_owner_of_ent(owner);
74   res->owner = owner;
75   res->name = name;
76   res->type = type;
77   if (get_type_tpop(type) == type_method)
78     res->allocation = static_allocated;
79   else
80     res->allocation = automatic_allocated;
81   res->visibility = local;
82   res->offset = -1;
83   if (is_method_type(type)) {
84     res->variability = constant;
85     rem = current_ir_graph;
86     current_ir_graph = get_const_code_irg();
87     res->value = new_Const(mode_P, tarval_P_from_entity(res));
88     current_ir_graph = rem;
89   } else {
90     res->variability = uninitialized;
91     res->value = NULL;
92     res->values = NULL;
93   }
94   res->peculiarity = existent;
95   res->volatility = non_volatile;
96   res->ld_name = NULL;
97   res->overwrites = NEW_ARR_F(entity *, 1);
98   res->overwrittenby = NEW_ARR_F(entity *, 1);
99
100   res->irg = NULL;
101
102 #ifdef DEBUG_libfirm
103   res->nr = get_irp_new_node_nr();
104 #endif
105
106   res->visit = 0;
107
108   /* Remember entity in it's owner. */
109   insert_entity_in_owner (res);
110   return res;
111 }
112 entity *
113 new_d_entity (type *owner, ident *name, type *type, dbg_info *db) {
114   entity *res = new_entity(owner, name, type);
115   set_entity_dbg_info(res, db);
116   return res;
117 }
118 INLINE void free_entity_attrs(entity *ent) {
119   assert(ent);
120   if (get_type_tpop(get_entity_owner(ent)) == type_class) {
121     DEL_ARR_F(ent->overwrites);
122     DEL_ARR_F(ent->overwrittenby);
123   }
124 }
125
126 entity *
127 copy_entity_own (entity *old, type *new_owner) {
128   entity *new;
129
130   assert_legal_owner_of_ent(new_owner);
131   if (old->owner == new_owner) return old;
132   new = (entity *) malloc (sizeof (entity));
133   memcpy (new, old, sizeof (entity));
134   new->owner = new_owner;
135   /*
136   if ((get_type_tpop(get_entity_owner(old)) == type_class) &&
137       (get_type_tpop(new_owner) == type_class)) {
138     new->overwrites = DUP_ARR_F(entity *, old->overwrites);
139     new->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
140   } else if ((get_type_tpop(get_entity_owner(old)) != type_class) &&
141              (get_type_tpop(new_owner) == type_class)) {
142     new->overwrites = NEW_ARR_F(entity *, 1);
143     new->overwrittenby = NEW_ARR_F(entity *, 1);
144   }
145   */
146   if (is_class_type(new_owner)) {
147     new->overwrites = NEW_ARR_F(entity *, 1);
148     new->overwrittenby = NEW_ARR_F(entity *, 1);
149   }
150 #ifdef DEBUG_libfirm
151   new->nr = get_irp_new_node_nr();
152 #endif
153
154   insert_entity_in_owner (new);
155
156   return new;
157 }
158
159 entity *
160 copy_entity_name (entity *old, ident *new_name) {
161   entity *new;
162
163   if (old->name == new_name) return old;
164   new = (entity *) malloc (sizeof (entity));
165   memcpy (new, old, sizeof (entity));
166   new->name = new_name;
167   new->ld_name = NULL;
168   if (is_class_type(new->owner)) {
169     new->overwrites = DUP_ARR_F(entity *, old->overwrites);
170     new->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
171   }
172 #ifdef DEBUG_libfirm
173   new->nr = get_irp_new_node_nr();
174 #endif
175
176   insert_entity_in_owner (new);
177
178   return new;
179 }
180
181
182 void
183 free_entity (entity *ent) {
184   free_tv_entity(ent);
185   free_entity_attrs(ent);
186   free(ent);
187 }
188
189 /* Outputs a unique number for this node */
190 INLINE long
191 get_entity_nr(entity *ent) {
192   assert(ent);
193 #ifdef DEBUG_libfirm
194   return ent->nr;
195 #else
196   return 0;
197 #endif
198 }
199
200 INLINE const char *
201 get_entity_name (entity *ent) {
202   assert (ent);
203   return id_to_str(get_entity_ident(ent));
204 }
205
206 ident *
207 get_entity_ident    (entity *ent) {
208   assert(ent);
209   return ent->name;
210 }
211
212 /*
213 void   set_entitye_ld_name  (entity *, char *ld_name);
214 void   set_entity_ld_ident (entity *, ident *ld_ident);
215 */
216
217 INLINE type *
218 get_entity_owner (entity *ent) {
219   return ent->owner = skip_tid(ent->owner);
220 }
221
222 INLINE void
223 set_entity_owner (entity *ent, type *owner) {
224   assert_legal_owner_of_ent(owner);
225   ent->owner = owner;
226 }
227
228 INLINE void   /* should this go into type.c? */
229 assert_legal_owner_of_ent(type *owner) {
230   assert (get_type_tpop_code(owner) == tpo_class ||
231           get_type_tpop_code(owner) == tpo_union ||
232           get_type_tpop_code(owner) == tpo_struct ||
233           get_type_tpop_code(owner) == tpo_array);   /* Yes, array has an entity
234                                                         -- to select fields! */
235 }
236
237 INLINE ident *
238 get_entity_ld_ident (entity *ent)
239 {
240   if (ent->ld_name == NULL)
241     ent->ld_name = mangle_entity (ent);
242   return ent->ld_name;
243 }
244
245 INLINE void
246 set_entity_ld_ident (entity *ent, ident *ld_ident) {
247   ent->ld_name = ld_ident;
248 }
249
250 INLINE const char *
251 get_entity_ld_name (entity *ent) {
252   return id_to_str(get_entity_ld_ident(ent));
253 }
254
255 /*
256 char  *get_entity_ld_name  (entity *);
257 void   set_entity_ld_name  (entity *, char *ld_name);
258 */
259
260 INLINE type *
261 get_entity_type (entity *ent) {
262   return ent->type = skip_tid(ent->type);
263 }
264
265 INLINE void
266 set_entity_type (entity *ent, type *type) {
267   ent->type = type;
268 }
269
270
271 INLINE ent_allocation
272 get_entity_allocation (entity *ent) {
273   return ent->allocation;
274 }
275
276 INLINE void
277 set_entity_allocation (entity *ent, ent_allocation al) {
278   ent->allocation = al;
279 }
280
281
282 INLINE ent_visibility
283 get_entity_visibility (entity *ent) {
284   return ent->visibility;
285 }
286
287 INLINE void
288 set_entity_visibility (entity *ent, ent_visibility vis) {
289   if (vis != local)
290     assert((ent->allocation == static_allocated) ||
291            (ent->allocation == automatic_allocated));
292   // @@@ Test that the owner type is not local, but how??
293   //       && get_class_visibility(get_entity_owner(ent)) != local));
294   ent->visibility = vis;
295 }
296
297 INLINE ent_variability
298 get_entity_variability (entity *ent) {
299   return ent->variability;
300 }
301
302 INLINE void
303 set_entity_variability (entity *ent, ent_variability var){
304   if (var == part_constant)
305     assert(is_class_type(ent->type) || is_struct_type(ent->type));
306   if ((is_compound_type(ent->type)) &&
307       (ent->variability == uninitialized) && (var != uninitialized)) {
308     /* Allocate datastructures for constant values */
309     ent->values = NEW_ARR_F(ir_node *, 1);
310     ent->val_ents = NEW_ARR_F(entity *, 1);
311   }
312   if ((is_compound_type(ent->type)) &&
313       (var == uninitialized) && (ent->variability != uninitialized)) {
314     /* Free datastructures for constant values */
315     DEL_ARR_F(ent->values);
316     DEL_ARR_F(ent->val_ents);
317   }
318   ent->variability = var;
319 }
320
321
322 INLINE ent_volatility
323 get_entity_volatility (entity *ent) {
324   assert (ent);
325   return ent->volatility;
326 }
327
328 INLINE void
329 set_entity_volatility (entity *ent, ent_volatility vol) {
330   assert (ent);
331   ent->volatility = vol;
332 }
333
334 INLINE peculiarity
335 get_entity_peculiarity (entity *ent) {
336   assert (ent);
337   return ent->peculiarity;
338 }
339
340 INLINE void
341 set_entity_peculiarity (entity *ent, peculiarity pec) {
342   assert (ent);
343   /* @@@ why peculiarity only for methods? */
344   assert (is_method_type(ent->type));
345   ent->peculiarity = pec;
346 }
347
348 /* Set has no effect for entities of type method. */
349 INLINE ir_node *
350 get_atomic_ent_value(entity *ent) {
351   assert(ent); assert(is_atomic_entity(ent));
352   assert((ent->variability != uninitialized));
353   return ent->value;
354 }
355
356 INLINE void
357 set_atomic_ent_value(entity *ent, ir_node *val) {
358   assert(ent && is_atomic_entity(ent) && (ent->variability != uninitialized));
359   if (is_method_type(ent->type)) return;
360   ent->value = val;
361 }
362
363
364 ir_node *copy_const_value(ir_node *n) {
365   ir_node *nn;
366   ir_mode *m;
367
368   m = get_irn_mode(n);
369   switch(get_irn_opcode(n)) {
370   case iro_Const:
371     nn = new_Const(m, get_Const_tarval(n)); break;
372   case iro_SymConst:
373     nn = new_SymConst(get_SymConst_type_or_id(n), get_SymConst_kind(n)); break;
374   case iro_Add:
375     nn = new_Add(copy_const_value(get_Add_left(n)), copy_const_value(get_Add_right(n)), m); break;
376   default:
377     assert(0 && "opdope invalid or not implemented"); break;
378   }
379   return nn;
380 }
381
382 /* A value of a compound entity is a pair of value and the corresponding member of
383    the compound. */
384 INLINE void
385 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
386   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
387   ARR_APP1 (ir_node *, ent->values, val);
388   ARR_APP1 (entity *, ent->val_ents, member);
389 }
390
391 /* Copies the firm subgraph referenced by val to const_code_irg and adds
392    the node as constant initialization to ent.
393    The subgraph may not contain control flow operations.
394 INLINE void
395 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
396   ir_graph *rem = current_ir_graph;
397
398   assert(get_entity_variability(ent) != uninitialized);
399   current_ir_graph = get_const_code_irg();
400
401   val = copy_const_value(val);
402   add_compound_ent_value(ent, val, member);
403   current_ir_graph = rem;
404   }*/
405
406 INLINE int
407 get_compound_ent_n_values(entity *ent) {
408   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
409   return (ARR_LEN (ent->values))-1;
410 }
411
412 INLINE ir_node  *
413 get_compound_ent_value(entity *ent, int pos) {
414   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
415   return ent->values[pos+1];
416 }
417
418 /* Copies the value i of the entity to current_block in current_ir_graph.
419 ir_node *
420 copy_compound_ent_value(entity *ent, int pos) {
421   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
422   return copy_const_value(ent->values[pos+1]);
423   }*/
424
425 INLINE entity   *
426 get_compound_ent_value_member(entity *ent, int pos) {
427   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
428   return ent->val_ents[pos+1];
429 }
430
431 INLINE void
432 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
433   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
434   ent->values[pos+1] = val;
435   ent->val_ents[pos+1] = member;
436 }
437
438 void
439 remove_compound_ent_value(entity *ent, entity *value_ent) {
440   int i;
441   assert(ent && is_compound_entity(ent) && (ent->variability != uninitialized));
442   for (i = 1; i < (ARR_LEN (ent->val_ents)); i++) {
443     if (ent->val_ents[i] == value_ent) {
444       for(; i < (ARR_LEN (ent->val_ents))-1; i++) {
445         ent->val_ents[i] = ent->val_ents[i+1];
446         ent->values[i]   = ent->values[i+1];
447       }
448       ARR_SETLEN(entity*,  ent->val_ents, ARR_LEN(ent->val_ents) - 1);
449       ARR_SETLEN(ir_node*, ent->values,   ARR_LEN(ent->values) - 1);
450       break;
451     }
452   }
453 }
454
455 void
456 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
457   int i;
458   ir_graph *rem = current_ir_graph;
459   type *arrtp = get_entity_type(ent);
460   ir_node *val;
461
462   assert(is_array_type(arrtp));
463   assert(get_array_n_dimensions(arrtp) == 1);
464   /* One bound is sufficient, the nunmber of constant fields makes the
465      size. */
466   assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
467   assert(get_entity_variability(ent) != uninitialized);
468   current_ir_graph = get_const_code_irg();
469
470   for (i = 0; i < num_vals; i++) {
471     val = new_Const(get_tv_mode (values[i]), values[i]);
472     add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
473   }
474   current_ir_graph = rem;
475 }
476
477 INLINE int
478 get_entity_offset (entity *ent) {
479   return ent->offset;
480 }
481
482 INLINE void
483 set_entity_offset (entity *ent, int offset) {
484   ent->offset = offset;
485 }
486
487 INLINE void
488 add_entity_overwrites   (entity *ent, entity *overwritten) {
489   assert(ent);
490   assert(is_class_type(get_entity_owner(ent)));
491   ARR_APP1 (entity *, ent->overwrites, overwritten);
492   ARR_APP1 (entity *, overwritten->overwrittenby, ent);
493 }
494
495 INLINE int
496 get_entity_n_overwrites (entity *ent) {
497   assert(ent);
498   assert(is_class_type(get_entity_owner(ent)));
499   return (ARR_LEN (ent->overwrites))-1;
500 }
501
502 int
503 get_entity_overwrites_index(entity *ent, entity *overwritten) {
504   int i;
505   assert(ent && is_class_type(get_entity_owner(ent)));
506   for (i = 0; i < get_entity_n_overwrites(ent); i++)
507     if (get_entity_overwrites(ent, i) == overwritten)
508       return i;
509   return -1;
510 }
511
512 INLINE entity *
513 get_entity_overwrites   (entity *ent, int pos) {
514   assert(ent);
515   assert(is_class_type(get_entity_owner(ent)));
516   assert(pos < get_entity_n_overwrites(ent));
517   return ent->overwrites[pos+1];
518 }
519
520 INLINE void
521 set_entity_overwrites   (entity *ent, int pos, entity *overwritten) {
522   assert(ent);
523   assert(is_class_type(get_entity_owner(ent)));
524   assert(pos < get_entity_n_overwrites(ent));
525   ent->overwrites[pos+1] = overwritten;
526 }
527
528 void
529 remove_entity_overwrites(entity *ent, entity *overwritten) {
530   int i;
531   assert(ent && is_class_type(get_entity_owner(ent)));
532   for (i = 1; i < (ARR_LEN (ent->overwrites)); i++)
533     if (ent->overwrites[i] == overwritten) {
534       for(; i < (ARR_LEN (ent->overwrites))-1; i++)
535         ent->overwrites[i] = ent->overwrites[i+1];
536       ARR_SETLEN(entity*, ent->overwrites, ARR_LEN(ent->overwrites) - 1);
537       break;
538     }
539 }
540
541 INLINE void
542 add_entity_overwrittenby   (entity *ent, entity *overwrites) {
543   assert(ent);
544   assert(is_class_type(get_entity_owner(ent)));
545   add_entity_overwrites(overwrites, ent);
546 }
547
548 INLINE int
549 get_entity_n_overwrittenby (entity *ent) {
550   assert(ent);
551   assert(is_class_type(get_entity_owner(ent)));
552   return (ARR_LEN (ent->overwrittenby))-1;
553 }
554
555 int
556 get_entity_overwrittenby_index(entity *ent, entity *overwrites) {
557   int i;
558   assert(ent && is_class_type(get_entity_owner(ent)));
559   for (i = 0; i < get_entity_n_overwrittenby(ent); i++)
560     if (get_entity_overwrittenby(ent, i) == overwrites)
561       return i;
562   return -1;
563 }
564
565 INLINE entity *
566 get_entity_overwrittenby   (entity *ent, int pos) {
567   assert(ent);
568   assert(is_class_type(get_entity_owner(ent)));
569   assert(pos < get_entity_n_overwrittenby(ent));
570   return ent->overwrittenby[pos+1];
571 }
572
573 INLINE void
574 set_entity_overwrittenby   (entity *ent, int pos, entity *overwrites) {
575   assert(ent);
576   assert(is_class_type(get_entity_owner(ent)));
577   assert(pos < get_entity_n_overwrittenby(ent));
578   ent->overwrittenby[pos+1] = overwrites;
579 }
580
581 void    remove_entity_overwrittenby(entity *ent, entity *overwrites) {
582   int i;
583   assert(ent && is_class_type(get_entity_owner(ent)));
584   for (i = 1; i < (ARR_LEN (ent->overwrittenby)); i++)
585     if (ent->overwrittenby[i] == overwrites) {
586       for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
587         ent->overwrittenby[i] = ent->overwrittenby[i+1];
588       ARR_SETLEN(entity*, ent->overwrittenby, ARR_LEN(ent->overwrittenby) - 1);
589       break;
590     }
591 }
592
593 /* A link to store intermediate information */
594 void *
595 get_entity_link(entity *ent) {
596   assert(ent);
597   return ent->link;
598 }
599
600 void
601 set_entity_link(entity *ent, void *l) {
602   assert(ent);
603   ent->link = l;
604 }
605
606 INLINE ir_graph *
607 get_entity_irg(entity *ent) {
608   assert (ent);
609   assert (is_method_type(ent->type));
610   return ent->irg;
611 }
612
613 INLINE void
614 set_entity_irg(entity *ent, ir_graph *irg) {
615   assert (ent && ent->type);
616   /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
617    * Methode selbst nicht mehr aufgerufen werden kann, die Entität
618    * aber erhalten bleiben soll. */
619   /* assert (irg); */
620   assert (is_method_type(ent->type));
621   assert (ent->peculiarity == existent);
622   ent->irg = irg;
623 }
624
625 int is_entity (void *thing) {
626   assert(thing);
627   if (get_kind(thing) == k_entity)
628     return 1;
629   else
630     return 0;
631 }
632
633 int is_atomic_entity(entity *ent) {
634   type* t = get_entity_type(ent);
635   return (is_primitive_type(t) || is_pointer_type(t) ||
636           is_enumeration_type(t) || is_method_type(t));
637 }
638
639 int is_compound_entity(entity *ent) {
640   type* t = get_entity_type(ent);
641   return (is_class_type(t) || is_struct_type(t) ||
642           is_array_type(t) || is_union_type(t));
643 }
644
645 /* @@@ not implemnted!!! */
646 bool equal_entity(entity *ent1, entity *ent2) {
647   printf(" calling unimplemented equal entity!!! \n");
648   return true;
649 }
650
651
652 unsigned long get_entity_visited(entity *ent) {
653   assert (ent);
654   return ent->visit;
655 }
656 void        set_entity_visited(entity *ent, unsigned long num) {
657   assert (ent);
658   ent->visit = num;
659 }
660 /* Sets visited field in entity to entity_visited. */
661 void        mark_entity_visited(entity *ent) {
662   assert (ent);
663   ent->visit = type_visited;
664 }
665
666
667 INLINE bool entity_visited(entity *ent) {
668   return get_entity_visited(ent) >= type_visited;
669 }
670 INLINE bool entity_not_visited(entity *ent) {
671   return get_entity_visited(ent) < type_visited;
672 }