02176b5f0f62a1afbcb6b6ff4d2802904cfa1f04
[libfirm] / ir / tr / entity.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/tr/entity.c
4  * Purpose:     Representation of all program known entities.
5  * Author:      Martin Trapp, Christian Schaefer
6  * Modified by: Goetz Lindenmaier, Michael Beck
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2006 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #ifdef HAVE_STRING_H
17 # include <string.h>
18 #endif
19 #ifdef HAVE_STDLIB_H
20 # include <stdlib.h>
21 #endif
22 #ifdef HAVE_STDDEF_H
23 # include <stddef.h>
24 #endif
25
26 #include "firm_common_t.h"
27
28 #include "xmalloc.h"
29 #include "entity_t.h"
30 #include "mangle.h"
31 #include "typegmod.h"
32 #include "array.h"
33 #include "irtools.h"
34 #include "irhooks.h"
35 #include "irprintf.h"
36
37 /* All this is needed to build the constant node for methods: */
38 #include "irprog_t.h"
39 #include "ircons.h"
40 #include "tv_t.h"
41 #include "irdump.h"  /* for output if errors occur. */
42
43 #include "callgraph.h"  /* for dumping debug output */
44
45 /*******************************************************************/
46 /** general                                                       **/
47 /*******************************************************************/
48
49 entity *unknown_entity = NULL;
50
51 entity *get_unknown_entity(void) { return unknown_entity; }
52
53 #define UNKNOWN_ENTITY_NAME "unknown_entity"
54
55 /*-----------------------------------------------------------------*/
56 /* ENTITY                                                          */
57 /*-----------------------------------------------------------------*/
58
59 static INLINE void insert_entity_in_owner (entity *ent) {
60   ir_type *owner = ent->owner;
61   switch (get_type_tpop_code(owner)) {
62   case tpo_class: {
63     add_class_member (owner, ent);
64   } break;
65   case tpo_struct: {
66     add_struct_member (owner, ent);
67   } break;
68   case tpo_union: {
69     add_union_member (owner, ent);
70   } break;
71   case tpo_array: {
72     set_array_element_entity(owner, ent);
73   } break;
74   default: assert(0);
75   }
76 }
77
78 /**
79  * Creates a new entity. This entity is NOT inserted in the owner type.
80  *
81  * @param db     debug info for this entity
82  * @param owner  the owner type of the new entity
83  * @param name   the name of the new entity
84  * @param type   the type of the new entity
85  *
86  * @return the new created entity
87  */
88 static INLINE entity *
89 new_rd_entity (dbg_info *db, ir_type *owner, ident *name, ir_type *type)
90 {
91   entity *res;
92   ir_graph *rem;
93
94   assert(!id_contains_char(name, ' ') && "entity name should not contain spaces");
95
96   res = xmalloc(sizeof(*res));
97   memset(res, 0, sizeof(*res));
98
99   res->kind    = k_entity;
100   res->name    = name;
101   res->ld_name = NULL;
102   res->owner   = owner;
103   res->type    = type;
104
105   if (get_type_tpop(type) == type_method)
106     res->allocation = allocation_static;
107   else
108     res->allocation = allocation_automatic;
109
110   res->visibility  = visibility_local;
111   res->volatility  = volatility_non_volatile;
112   res->stickyness  = stickyness_unsticky;
113   res->offset      = -1;
114   res->peculiarity = peculiarity_existent;
115   res->link        = NULL;
116
117
118   if (is_Method_type(type)) {
119     symconst_symbol sym;
120     sym.entity_p            = res;
121     rem                     = current_ir_graph;
122     current_ir_graph        = get_const_code_irg();
123     res->value              = new_SymConst(sym, symconst_addr_ent);
124     current_ir_graph        = rem;
125     res->variability        = variability_constant;
126     res->attr.mtd_attr.irg_add_properties = mtp_property_inherited;
127     res->attr.mtd_attr.vtable_number      = VTABLE_NUM_NOT_SET;
128     res->attr.mtd_attr.param_access       = NULL;
129     res->attr.mtd_attr.param_weight       = NULL;
130     res->attr.mtd_attr.irg                = NULL;
131   }
132   else if (is_compound_type(type)) {
133     res->variability = variability_uninitialized;
134     res->value       = NULL;
135     res->attr.cmpd_attr.values    = NULL;
136     res->attr.cmpd_attr.val_paths = NULL;
137   }
138   else {
139     res->variability = variability_uninitialized;
140     res->value       = NULL;
141   }
142
143   if (is_Class_type(owner)) {
144     res->overwrites    = NEW_ARR_F(entity *, 0);
145     res->overwrittenby = NEW_ARR_F(entity *, 0);
146   } else {
147     res->overwrites    = NULL;
148     res->overwrittenby = NULL;
149   }
150
151 #ifdef DEBUG_libfirm
152   res->nr = get_irp_new_node_nr();
153 #endif /* DEBUG_libfirm */
154
155   res->visit = 0;
156   set_entity_dbg_info(res, db);
157
158   return res;
159 }
160
161 entity *
162 new_d_entity (ir_type *owner, ident *name, ir_type *type, dbg_info *db) {
163   entity *res;
164
165   assert_legal_owner_of_ent(owner);
166   res = new_rd_entity(db, owner, name, type);
167   /* Remember entity in it's owner. */
168   insert_entity_in_owner (res);
169
170   hook_new_entity(res);
171   return res;
172 }
173
174 entity *
175 new_entity (ir_type *owner, ident *name, ir_type *type) {
176   return new_d_entity(owner, name, type, NULL);
177 }
178
179 /**
180  * Free entity attributes.
181  *
182  * @param ent  the entity
183  */
184 static void free_entity_attrs(entity *ent) {
185   int i;
186   if (get_type_tpop(get_entity_owner(ent)) == type_class) {
187     DEL_ARR_F(ent->overwrites);    ent->overwrites = NULL;
188     DEL_ARR_F(ent->overwrittenby); ent->overwrittenby = NULL;
189   } else {
190     assert(ent->overwrites == NULL);
191     assert(ent->overwrittenby == NULL);
192   }
193   if (is_compound_entity(ent)) {
194     if (ent->attr.cmpd_attr.val_paths) {
195       for (i = 0; i < get_compound_ent_n_values(ent); i++)
196         if (ent->attr.cmpd_attr.val_paths[i]) {
197           /* free_compound_graph_path(ent->attr.cmpd_attr.val_paths[i]) ;  * @@@ warum nich? */
198           /* Geht nich: wird mehrfach verwendet!!! ==> mehrfach frei gegeben. */
199           /* DEL_ARR_F(ent->attr.cmpd_attr.val_paths); */
200         }
201       ent->attr.cmpd_attr.val_paths = NULL;
202     }
203     /* if (ent->attr.cmpd_attr.values) DEL_ARR_F(ent->attr.cmpd_attr.values); *//* @@@ warum nich? */
204     ent->attr.cmpd_attr.values = NULL;
205   }
206   else if (is_method_entity(ent)) {
207     if (ent->attr.mtd_attr.param_access) {
208       DEL_ARR_F(ent->attr.mtd_attr.param_access);
209       ent->attr.mtd_attr.param_access = NULL;
210     }
211     if (ent->attr.mtd_attr.param_weight) {
212       DEL_ARR_F(ent->attr.mtd_attr.param_weight);
213       ent->attr.mtd_attr.param_weight = NULL;
214     }
215   }
216 }
217
218 entity *
219 copy_entity_own (entity *old, ir_type *new_owner) {
220   entity *newe;
221   assert(old && old->kind == k_entity);
222   assert_legal_owner_of_ent(new_owner);
223
224   if (old->owner == new_owner) return old;
225   newe = xmalloc(sizeof(*newe));
226   memcpy (newe, old, sizeof(*newe));
227   newe->owner = new_owner;
228   if (is_Class_type(new_owner)) {
229     newe->overwrites    = NEW_ARR_F(entity *, 0);
230     newe->overwrittenby = NEW_ARR_F(entity *, 0);
231   }
232 #ifdef DEBUG_libfirm
233   newe->nr = get_irp_new_node_nr();
234 #endif
235
236   insert_entity_in_owner (newe);
237
238   return newe;
239 }
240
241 entity *
242 copy_entity_name (entity *old, ident *new_name) {
243   entity *newe;
244   assert(old && old->kind == k_entity);
245
246   if (old->name == new_name) return old;
247   newe = xmalloc(sizeof(*newe));
248   memcpy(newe, old, sizeof(*newe));
249   newe->name = new_name;
250   newe->ld_name = NULL;
251   if (is_Class_type(newe->owner)) {
252     newe->overwrites    = DUP_ARR_F(entity *, old->overwrites);
253     newe->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
254   }
255 #ifdef DEBUG_libfirm
256   newe->nr = get_irp_new_node_nr();
257 #endif
258
259   insert_entity_in_owner (newe);
260
261   return newe;
262 }
263
264
265 void
266 free_entity (entity *ent) {
267   assert(ent && ent->kind == k_entity);
268   free_entity_attrs(ent);
269   ent->kind = k_BAD;
270   free(ent);
271 }
272
273 /* Outputs a unique number for this node */
274 long
275 get_entity_nr(entity *ent) {
276   assert(ent && ent->kind == k_entity);
277 #ifdef DEBUG_libfirm
278   return ent->nr;
279 #else
280   return (long)PTR_TO_INT(ent);
281 #endif
282 }
283
284 const char *
285 (get_entity_name)(const entity *ent) {
286   return _get_entity_name(ent);
287 }
288
289 ident *
290 (get_entity_ident)(const entity *ent) {
291   return _get_entity_ident(ent);
292 }
293
294 void
295 (set_entity_ident)(entity *ent, ident *id) {
296   _set_entity_ident(ent, id);
297 }
298
299 ir_type *
300 (get_entity_owner)(entity *ent) {
301   return _get_entity_owner(ent);
302 }
303
304 void
305 set_entity_owner (entity *ent, ir_type *owner) {
306   assert(ent && ent->kind == k_entity);
307   assert_legal_owner_of_ent(owner);
308   ent->owner = owner;
309 }
310
311 void   /* should this go into type.c? */
312 assert_legal_owner_of_ent(ir_type *owner) {
313   assert(get_type_tpop_code(owner) == tpo_class ||
314           get_type_tpop_code(owner) == tpo_union ||
315           get_type_tpop_code(owner) == tpo_struct ||
316       get_type_tpop_code(owner) == tpo_array);   /* Yes, array has an entity
317                             -- to select fields! */
318 }
319
320 ident *
321 (get_entity_ld_ident)(entity *ent) {
322   return _get_entity_ld_ident(ent);
323 }
324
325 void
326 (set_entity_ld_ident)(entity *ent, ident *ld_ident) {
327    _set_entity_ld_ident(ent, ld_ident);
328 }
329
330 const char *
331 (get_entity_ld_name)(entity *ent) {
332   return _get_entity_ld_name(ent);
333 }
334
335 ir_type *
336 (get_entity_type)(entity *ent) {
337   return _get_entity_type(ent);
338 }
339
340 void
341 (set_entity_type)(entity *ent, ir_type *type) {
342   _set_entity_type(ent, type);
343 }
344
345 ent_allocation
346 (get_entity_allocation)(const entity *ent) {
347   return _get_entity_allocation(ent);
348 }
349
350 void
351 (set_entity_allocation)(entity *ent, ent_allocation al) {
352   _set_entity_allocation(ent, al);
353 }
354
355 /* return the name of the visibility */
356 const char *get_allocation_name(ent_allocation all)
357 {
358 #define X(a)    case a: return #a
359   switch (all) {
360     X(allocation_automatic);
361     X(allocation_parameter);
362     X(allocation_dynamic);
363     X(allocation_static);
364     default: return "BAD VALUE";
365   }
366 #undef X
367 }
368
369
370 visibility
371 (get_entity_visibility)(const entity *ent) {
372   return _get_entity_visibility(ent);
373 }
374
375 void
376 set_entity_visibility (entity *ent, visibility vis) {
377   assert(ent && ent->kind == k_entity);
378   if (vis != visibility_local)
379     assert((ent->allocation == allocation_static) ||
380        (ent->allocation == allocation_automatic));
381   /* @@@ Test that the owner type is not local, but how??
382          && get_class_visibility(get_entity_owner(ent)) != local));*/
383   ent->visibility = vis;
384 }
385
386 /* return the name of the visibility */
387 const char *get_visibility_name(visibility vis)
388 {
389 #define X(a)    case a: return #a
390   switch (vis) {
391     X(visibility_local);
392     X(visibility_external_visible);
393     X(visibility_external_allocated);
394     default: return "BAD VALUE";
395   }
396 #undef X
397 }
398
399 ent_variability
400 (get_entity_variability)(const entity *ent) {
401   return _get_entity_variability(ent);
402 }
403
404 void
405 set_entity_variability (entity *ent, ent_variability var)
406 {
407   assert(ent && ent->kind == k_entity);
408   if (var == variability_part_constant)
409     assert(is_Class_type(ent->type) || is_Struct_type(ent->type));
410
411   if ((is_compound_type(ent->type)) &&
412       (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
413     /* Allocate data structures for constant values */
414     ent->attr.cmpd_attr.values    = NEW_ARR_F(ir_node *, 0);
415     ent->attr.cmpd_attr.val_paths = NEW_ARR_F(compound_graph_path *, 0);
416   }
417   if ((is_atomic_type(ent->type)) &&
418       (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
419     /* Set default constant value. */
420     ent->value = new_rd_Unknown(get_const_code_irg(), get_type_mode(ent->type));
421   }
422
423   if ((is_compound_type(ent->type)) &&
424       (var == variability_uninitialized) && (ent->variability != variability_uninitialized)) {
425     /* Free data structures for constant values */
426     DEL_ARR_F(ent->attr.cmpd_attr.values);    ent->attr.cmpd_attr.values    = NULL;
427     DEL_ARR_F(ent->attr.cmpd_attr.val_paths); ent->attr.cmpd_attr.val_paths = NULL;
428   }
429   ent->variability = var;
430 }
431
432 /* return the name of the variability */
433 const char *get_variability_name(ent_variability var)
434 {
435 #define X(a)    case a: return #a
436   switch (var) {
437     X(variability_uninitialized);
438     X(variability_initialized);
439     X(variability_part_constant);
440     X(variability_constant);
441     default: return "BAD VALUE";
442   }
443 #undef X
444 }
445
446 ent_volatility
447 (get_entity_volatility)(const entity *ent) {
448   return _get_entity_volatility(ent);
449 }
450
451 void
452 (set_entity_volatility)(entity *ent, ent_volatility vol) {
453   _set_entity_volatility(ent, vol);
454 }
455
456 /* return the name of the volatility */
457 const char *get_volatility_name(ent_volatility var)
458 {
459 #define X(a)    case a: return #a
460   switch (var) {
461     X(volatility_non_volatile);
462     X(volatility_is_volatile);
463     default: return "BAD VALUE";
464   }
465 #undef X
466 }
467
468 peculiarity
469 (get_entity_peculiarity)(const entity *ent) {
470   return _get_entity_peculiarity(ent);
471 }
472
473 void
474 (set_entity_peculiarity)(entity *ent, peculiarity pec) {
475   _set_entity_peculiarity(ent, pec);
476 }
477
478 /* Get the entity's stickyness */
479 ent_stickyness
480 (get_entity_stickyness)(const entity *ent) {
481   return _get_entity_stickyness(ent);
482 }
483
484 /* Set the entity's stickyness */
485 void
486 (set_entity_stickyness)(entity *ent, ent_stickyness stickyness) {
487   _set_entity_stickyness(ent, stickyness);
488 }
489
490 /* Set has no effect for existent entities of type method. */
491 ir_node *
492 get_atomic_ent_value(entity *ent)
493 {
494   assert(ent && is_atomic_entity(ent));
495   assert(ent->variability != variability_uninitialized);
496   return skip_Id (ent->value);
497 }
498
499 void
500 set_atomic_ent_value(entity *ent, ir_node *val) {
501   assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized));
502   if (is_Method_type(ent->type) && (ent->peculiarity == peculiarity_existent))
503     return;
504   ent->value = val;
505 }
506
507 /* Returns true if the the node is representable as code on
508  *  const_code_irg. */
509 int is_irn_const_expression(ir_node *n) {
510   ir_mode *m;
511
512   /* we are in danger iff an exception will arise. TODO: be more precisely,
513    * for instance Div. will NOT rise if divisor != 0
514    */
515   if (is_binop(n) && !is_fragile_op(n))
516     return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));
517
518   m = get_irn_mode(n);
519   switch(get_irn_opcode(n)) {
520   case iro_Const:
521   case iro_SymConst:
522   case iro_Unknown:
523     return 1;
524   case iro_Conv:
525   case iro_Cast:
526     return is_irn_const_expression(get_irn_n(n, 0));
527   default:
528     break;
529   }
530   return 0;
531 }
532
533 /*
534  * Copies a firm subgraph that complies to the restrictions for
535  * constant expressions to current_block in current_ir_graph.
536  */
537 ir_node *copy_const_value(dbg_info *dbg, ir_node *n) {
538   ir_node *nn;
539   ir_mode *m;
540
541   /* @@@ GL I think  we should implement this using the routines from irgopt for
542      dead node elimination/inlineing. */
543
544   m = get_irn_mode(n);
545   switch (get_irn_opcode(n)) {
546   case iro_Const:
547     nn = new_d_Const_type(dbg, m, get_Const_tarval(n), get_Const_type(n));
548     break;
549   case iro_SymConst:
550     nn = new_d_SymConst_type(dbg, get_SymConst_symbol(n), get_SymConst_kind(n),
551                              get_SymConst_value_type(n));
552     break;
553   case iro_Add:
554     nn = new_d_Add(dbg, copy_const_value(dbg, get_Add_left(n)),
555                  copy_const_value(dbg, get_Add_right(n)), m); break;
556   case iro_Sub:
557     nn = new_d_Sub(dbg, copy_const_value(dbg, get_Sub_left(n)),
558                  copy_const_value(dbg, get_Sub_right(n)), m); break;
559   case iro_Mul:
560     nn = new_d_Mul(dbg, copy_const_value(dbg, get_Mul_left(n)),
561                  copy_const_value(dbg, get_Mul_right(n)), m); break;
562   case iro_And:
563     nn = new_d_And(dbg, copy_const_value(dbg, get_And_left(n)),
564                  copy_const_value(dbg, get_And_right(n)), m); break;
565   case iro_Or:
566     nn = new_d_Or(dbg, copy_const_value(dbg, get_Or_left(n)),
567                 copy_const_value(dbg, get_Or_right(n)), m); break;
568   case iro_Eor:
569     nn = new_d_Eor(dbg, copy_const_value(dbg, get_Eor_left(n)),
570                  copy_const_value(dbg, get_Eor_right(n)), m); break;
571   case iro_Cast:
572     nn = new_d_Cast(dbg, copy_const_value(dbg, get_Cast_op(n)), get_Cast_type(n)); break;
573   case iro_Conv:
574     nn = new_d_Conv(dbg, copy_const_value(dbg, get_Conv_op(n)), m); break;
575   case iro_Unknown:
576     nn = new_d_Unknown(m); break;
577   default:
578     DDMN(n);
579     assert(0 && "opcode invalid or not implemented");
580     nn = NULL;
581     break;
582   }
583   return nn;
584 }
585
586 /* Creates a new compound graph path. */
587 compound_graph_path *
588 new_compound_graph_path(ir_type *tp, int length) {
589   compound_graph_path *res;
590
591   assert(is_type(tp) && is_compound_type(tp));
592   assert(length > 0);
593
594   res = xmalloc(sizeof(*res) + (length-1) * sizeof(res->list[0]));
595   memset(res, 0, sizeof(*res) + (length-1) * sizeof(res->list[0]));
596   res->kind         = k_ir_compound_graph_path;
597   res->tp           = tp;
598   res->len          = length;
599
600   return res;
601 }
602
603 /* Frees an graph path object */
604 void free_compound_graph_path (compound_graph_path *gr) {
605   assert(gr && is_compound_graph_path(gr));
606   gr->kind = k_BAD;
607   free(gr);
608 }
609
610 /* Returns non-zero if an object is a compound graph path */
611 int is_compound_graph_path(void *thing) {
612   return (get_kind(thing) == k_ir_compound_graph_path);
613 }
614
615 /* Checks whether the path up to pos is correct. If the path contains a NULL,
616  *  assumes the path is not complete and returns 'true'. */
617 int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
618   int i;
619   entity *node;
620   ir_type *owner = gr->tp;
621
622   for (i = 0; i <= pos; i++) {
623     node = get_compound_graph_path_node(gr, i);
624     if (node == NULL)
625       /* Path not yet complete. */
626       return 1;
627     if (get_entity_owner(node) != owner)
628       return 0;
629     owner = get_entity_type(node);
630   }
631   if (pos == get_compound_graph_path_length(gr))
632     if (!is_atomic_type(owner))
633       return 0;
634   return 1;
635 }
636
637 /* Returns the length of a graph path */
638 int get_compound_graph_path_length(compound_graph_path *gr) {
639   assert(gr && is_compound_graph_path(gr));
640   return gr->len;
641 }
642
643 entity *
644 get_compound_graph_path_node(compound_graph_path *gr, int pos) {
645   assert(gr && is_compound_graph_path(gr));
646   assert(pos >= 0 && pos < gr->len);
647   return gr->list[pos].node;
648 }
649
650 void
651 set_compound_graph_path_node(compound_graph_path *gr, int pos, entity *node) {
652   assert(gr && is_compound_graph_path(gr));
653   assert(pos >= 0 && pos < gr->len);
654   assert(is_entity(node));
655   gr->list[pos].node = node;
656   assert(is_proper_compound_graph_path(gr, pos));
657 }
658
659 int
660 get_compound_graph_path_array_index(compound_graph_path *gr, int pos) {
661   assert(gr && is_compound_graph_path(gr));
662   assert(pos >= 0 && pos < gr->len);
663   return gr->list[pos].index;
664 }
665
666 void
667 set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index) {
668   assert(gr && is_compound_graph_path(gr));
669   assert(pos >= 0 && pos < gr->len);
670   gr->list[pos].index = index;
671 }
672
673 /* A value of a compound entity is a pair of value and the corresponding path to a member of
674    the compound. */
675 void
676 add_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path) {
677   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
678   assert(is_compound_graph_path(path));
679   ARR_APP1(ir_node *, ent->attr.cmpd_attr.values, val);
680   ARR_APP1(compound_graph_path *, ent->attr.cmpd_attr.val_paths, path);
681 }
682
683 void
684 set_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path, int pos) {
685   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
686   assert(is_compound_graph_path(path));
687   assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.values));
688   ent->attr.cmpd_attr.values[pos]    = val;
689   ent->attr.cmpd_attr.val_paths[pos] = path;
690 }
691
692 int
693 get_compound_ent_n_values(entity *ent) {
694   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
695   return ARR_LEN(ent->attr.cmpd_attr.values);
696 }
697
698 ir_node *
699 get_compound_ent_value(entity *ent, int pos) {
700   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
701   assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.values));
702   return ent->attr.cmpd_attr.values[pos];
703 }
704
705 compound_graph_path *
706 get_compound_ent_value_path(entity *ent, int pos) {
707   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
708   assert(0 <= pos && pos < ARR_LEN(ent->attr.cmpd_attr.val_paths));
709   return ent->attr.cmpd_attr.val_paths[pos];
710 }
711
712 /**
713  * Returns non-zero, if two compound_graph_pathes are equal
714  */
715 static int equal_paths(compound_graph_path *path1, int *visited_indicees, compound_graph_path *path2) {
716   int i;
717   int len1 = get_compound_graph_path_length(path1);
718   int len2 = get_compound_graph_path_length(path2);
719
720   if (len2 > len1) return 0;
721
722   for (i = 0; i < len1; i++) {
723     ir_type *tp;
724     entity *node1 = get_compound_graph_path_node(path1, i);
725     entity *node2 = get_compound_graph_path_node(path2, i);
726
727     if (node1 != node2) return 0;
728
729     tp = get_entity_owner(node1);
730     if (is_Array_type(tp)) {
731       long low;
732
733       /* Compute the index of this node. */
734       assert(get_array_n_dimensions(tp) == 1 && "multidim not implemented");
735
736       low = get_array_lower_bound_int(tp, 0);
737       if (low + visited_indicees[i] < get_compound_graph_path_array_index(path2, i)) {
738         visited_indicees[i]++;
739         return 0;
740       }
741       else
742         assert(low + visited_indicees[i] == get_compound_graph_path_array_index(path2, i));
743     }
744   }
745   return 1;
746 }
747
748 /* Returns the position of a value with the given path.
749  *  The path must contain array indicees for all array element entities. */
750 int get_compound_ent_pos_by_path(entity *ent, compound_graph_path *path) {
751   int i, n_paths = get_compound_ent_n_values(ent);
752   int *visited_indicees = (int *)xcalloc(get_compound_graph_path_length(path), sizeof(int));
753   for (i = 0; i < n_paths; i ++) {
754     if (equal_paths(get_compound_ent_value_path(ent, i), visited_indicees, path))
755       return i;
756   }
757
758 #if 0
759   {
760     int j;
761     printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
762       printf("Entity %s : ", get_entity_name(ent));
763       for (j = 0; j < get_compound_graph_path_length(path); ++j) {
764         entity *node = get_compound_graph_path_node(path, j);
765         printf("%s", get_entity_name(node));
766         if (is_Array_type(get_entity_owner(node)))
767           printf("[%d]", get_compound_graph_path_array_index(path, j));
768       }
769     printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
770   }
771 #endif
772
773   assert(0 && "path not found");
774   return -1;
775 }
776
777 /* Returns a constant value given the access path.
778  *  The path must contain array indicees for all array element entities. */
779 ir_node *get_compound_ent_value_by_path(entity *ent, compound_graph_path *path) {
780   return get_compound_ent_value(ent, get_compound_ent_pos_by_path(ent, path));
781 }
782
783
784 void
785 remove_compound_ent_value(entity *ent, entity *value_ent) {
786   int i;
787   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
788   for (i = 0; i < (ARR_LEN(ent->attr.cmpd_attr.val_paths)); ++i) {
789     compound_graph_path *path = ent->attr.cmpd_attr.val_paths[i];
790     if (path->list[path->len-1].node == value_ent) {
791       for (; i < (ARR_LEN(ent->attr.cmpd_attr.val_paths))-1; ++i) {
792         ent->attr.cmpd_attr.val_paths[i] = ent->attr.cmpd_attr.val_paths[i+1];
793         ent->attr.cmpd_attr.values[i]    = ent->attr.cmpd_attr.values[i+1];
794       }
795       ARR_SETLEN(entity*,  ent->attr.cmpd_attr.val_paths, ARR_LEN(ent->attr.cmpd_attr.val_paths) - 1);
796       ARR_SETLEN(ir_node*, ent->attr.cmpd_attr.values,    ARR_LEN(ent->attr.cmpd_attr.values)    - 1);
797       break;
798     }
799   }
800 }
801
802 void
803 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
804   compound_graph_path *path;
805   ir_type *owner_tp = get_entity_owner(member);
806   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
807   path = new_compound_graph_path(get_entity_type(ent), 1);
808   path->list[0].node = member;
809   if (is_Array_type(owner_tp)) {
810     int max;
811     int i;
812
813     assert(get_array_n_dimensions(owner_tp) == 1 && has_array_lower_bound(owner_tp, 0));
814     max = get_array_lower_bound_int(owner_tp, 0) -1;
815     for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
816       int index = get_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0);
817       if (index > max) {
818         max = index;
819       }
820     }
821     path->list[0].index = max + 1;
822   }
823   add_compound_ent_value_w_path(ent, val, path);
824 }
825
826 /* Copies the firm subgraph referenced by val to const_code_irg and adds
827    the node as constant initialization to ent.
828    The subgraph may not contain control flow operations.
829 void
830 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
831   ir_graph *rem = current_ir_graph;
832
833   assert(get_entity_variability(ent) != variability_uninitialized);
834   current_ir_graph = get_const_code_irg();
835
836   val = copy_const_value(val);
837   add_compound_ent_value(ent, val, member);
838   current_ir_graph = rem;
839   }*/
840
841 /* Copies the value i of the entity to current_block in current_ir_graph.
842 ir_node *
843 copy_compound_ent_value(entity *ent, int pos) {
844   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
845   return copy_const_value(ent->values[pos+1]);
846   }*/
847
848 entity   *
849 get_compound_ent_value_member(entity *ent, int pos) {
850   compound_graph_path *path;
851   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
852   path = get_compound_ent_value_path(ent, pos);
853
854   return get_compound_graph_path_node(path, get_compound_graph_path_length(path)-1);
855 }
856
857 void
858 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
859   compound_graph_path *path;
860   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
861   path = get_compound_ent_value_path(ent, pos);
862   set_compound_graph_path_node(path, 0, member);
863   set_compound_ent_value_w_path(ent, val, path, pos);
864 }
865
866 void
867 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
868   int i;
869   ir_graph *rem = current_ir_graph;
870   ir_type *arrtp = get_entity_type(ent);
871   ir_node *val;
872   ir_type *elttp = get_array_element_type(arrtp);
873
874   assert(is_Array_type(arrtp));
875   assert(get_array_n_dimensions(arrtp) == 1);
876   /* One bound is sufficient, the number of constant fields makes the
877      size. */
878   assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
879   assert(get_entity_variability(ent) != variability_uninitialized);
880   current_ir_graph = get_const_code_irg();
881
882   for (i = 0; i < num_vals; i++) {
883     val = new_Const_type(values[i], elttp);
884     add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
885     set_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0, i);
886   }
887   current_ir_graph = rem;
888 }
889
890 int  get_compound_ent_value_offset_bits(entity *ent, int pos) {
891   compound_graph_path *path;
892   int i, path_len;
893   int offset = 0;
894
895   assert(get_type_state(get_entity_type(ent)) == layout_fixed);
896
897   path = get_compound_ent_value_path(ent, pos);
898   path_len = get_compound_graph_path_length(path);
899
900   for (i = 0; i < path_len; ++i) {
901     entity *node = get_compound_graph_path_node(path, i);
902     ir_type *node_tp = get_entity_type(node);
903     ir_type *owner_tp = get_entity_owner(node);
904     if (is_Array_type(owner_tp)) {
905       int size  = get_type_size_bits(node_tp);
906       int align = get_type_alignment_bits(node_tp);
907       if (size < align)
908         size = align;
909       else {
910         assert(size % align == 0);
911         /* ansonsten aufrunden */
912       }
913       offset += size * get_compound_graph_path_array_index(path, i);
914     } else {
915       offset += get_entity_offset_bits(node);
916     }
917   }
918   return offset;
919 }
920
921 int  get_compound_ent_value_offset_bytes(entity *ent, int pos) {
922   int offset = get_compound_ent_value_offset_bits(ent, pos);
923   assert(offset % 8 == 0);
924   return offset >> 3;
925 }
926
927
928 static void init_index(ir_type *arr) {
929   int init;
930   int dim = 0;
931
932   assert(get_array_n_dimensions(arr) == 1);
933
934   if (has_array_lower_bound(arr, dim))
935     init = get_array_lower_bound_int(arr, 0) -1;
936   else
937     init = get_array_upper_bound_int(arr, 0) +1;
938
939   set_entity_link(get_array_element_entity(arr), INT_TO_PTR(init));
940 }
941
942
943 static int get_next_index(entity *elem_ent) {
944   ir_type *arr = get_entity_owner(elem_ent);
945   int next;
946   int dim = 0;
947
948   assert(get_array_n_dimensions(arr) == 1);
949
950   if (has_array_lower_bound(arr, dim)) {
951     next = PTR_TO_INT(get_entity_link(elem_ent)) + 1;
952     if (has_array_upper_bound(arr, dim)) {
953       int upper = get_array_upper_bound_int(arr, dim);
954       if (next == upper) next = get_array_lower_bound_int(arr, dim);
955     }
956   } else {
957     next = PTR_TO_INT(get_entity_link(elem_ent)) - 1;
958     if (has_array_lower_bound(arr, dim)) {
959       int upper = get_array_upper_bound_int(arr, dim);
960       if (next == upper) next = get_array_upper_bound_int(arr, dim);
961     }
962   }
963
964   set_entity_link(elem_ent, INT_TO_PTR(next));
965   return next;
966 }
967
968 /* Compute the array indices in compound graph paths of initialized entities.
969  *
970  *  All arrays must have fixed lower and upper bounds.  One array can
971  *  have an open bound.  If there are several open bounds, we do
972  *  nothing.  There must be initializer elements for all array
973  *  elements.  Uses the link field in the array element entities.  The
974  *  array bounds must be representable as ints.
975  *
976  *  (If the bounds are not representable as ints we have to represent
977  *  the indices as firm nodes.  But still we must be able to
978  *  evaluate the index against the upper bound.)
979  */
980 void compute_compound_ent_array_indicees(entity *ent) {
981   ir_type *tp = get_entity_type(ent);
982   int i, n_vals;
983   entity *unknown_bound_entity = NULL;
984
985   if (!is_compound_type(tp) ||
986       (ent->variability == variability_uninitialized)) return ;
987
988   n_vals = get_compound_ent_n_values(ent);
989   if (n_vals == 0) return;
990
991   /* We can not compute the indexes if there is more than one array
992      with an unknown bound.  For this remember the first entity that
993      represents such an array. It could be ent. */
994   if (is_Array_type(tp)) {
995     int dim = 0;
996
997     assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
998     if (!has_array_lower_bound(tp, dim) || !has_array_upper_bound(tp, dim))
999      unknown_bound_entity = ent;
1000   }
1001
1002   /* Initialize the entity links to lower bound -1 and test all path elements
1003      for known bounds. */
1004   for (i = 0; i < n_vals; ++i) {
1005     compound_graph_path *path = get_compound_ent_value_path(ent, i);
1006     int j, path_len =  get_compound_graph_path_length(path);
1007     for (j = 0; j < path_len; ++j) {
1008       entity *node = get_compound_graph_path_node(path, j);
1009       ir_type *elem_tp = get_entity_type(node);
1010
1011       if (is_Array_type(elem_tp)) {
1012         int dim = 0;
1013         assert(get_array_n_dimensions(elem_tp) == 1 && "other not implemented");
1014         if (!has_array_lower_bound(elem_tp, dim) || !has_array_upper_bound(elem_tp, dim)) {
1015           if (!unknown_bound_entity) unknown_bound_entity = node;
1016           if (node != unknown_bound_entity) return;
1017         }
1018
1019         init_index(elem_tp);
1020       }
1021     }
1022   }
1023
1024   /* Finally compute the indexes ... */
1025   for (i = 0; i < n_vals; ++i) {
1026     compound_graph_path *path = get_compound_ent_value_path(ent, i);
1027     int j, path_len =  get_compound_graph_path_length(path);
1028     for (j = 0; j < path_len; ++j) {
1029       entity *node = get_compound_graph_path_node(path, j);
1030       ir_type *owner_tp = get_entity_owner(node);
1031       if (is_Array_type(owner_tp))
1032         set_compound_graph_path_array_index (path, j, get_next_index(node));
1033     }
1034   }
1035 }
1036
1037 /** resize: double the allocated buffer */
1038 static int *resize (int *buf, int *size) {
1039   int new_size =  *size * 2;
1040   int *new_buf = xcalloc(new_size, sizeof(new_buf[0]));
1041   memcpy(new_buf, buf, *size);
1042   free(buf);
1043   *size = new_size;
1044   return new_buf;
1045 }
1046
1047 /* We sort the elements by placing them at their bit offset in an
1048    array where each entry represents one bit called permutation.  In
1049    fact, we do not place the values themselves, as we would have to
1050    copy two things, the value and the path.  We only remember the
1051    position in the old order. Each value should have a distinct
1052    position in the permutation.
1053
1054    A second iteration now permutes the actual elements into two
1055    new arrays. */
1056 void sort_compound_ent_values(entity *ent) {
1057   ir_type *tp;
1058   int i, n_vals;
1059   int tp_size;
1060   int size;
1061   int *permutation;
1062
1063   int next;
1064   ir_node **my_values;
1065   compound_graph_path **my_paths;
1066
1067   assert(get_type_state(get_entity_type(ent)) == layout_fixed);
1068
1069   tp      = get_entity_type(ent);
1070   n_vals  = get_compound_ent_n_values(ent);
1071   tp_size = get_type_size_bits(tp);
1072
1073   if (!is_compound_type(tp)                           ||
1074       (ent->variability == variability_uninitialized) ||
1075       (get_type_state(tp) != layout_fixed)            ||
1076       (n_vals == 0)                                     ) return;
1077
1078   /* estimated upper bound for size. Better: use flexible array ... */
1079   size = ((tp_size > (n_vals * 32)) ? tp_size : (n_vals * 32)) * 4;
1080   permutation = xcalloc(size, sizeof(permutation[0]));
1081
1082   for (i = 0; i < n_vals; ++i) {
1083     int pos = get_compound_ent_value_offset_bits(ent, i);
1084     while (pos >= size) {
1085       permutation = resize(permutation, &size);
1086     }
1087     assert(pos < size);
1088     assert(permutation[pos] == 0 && "two values with the same offset");
1089     permutation[pos] = i + 1;         /* We initialized with 0, so we can not distinguish entry 0.
1090                      So inc all entries by one. */
1091     //fprintf(stderr, "i: %d, pos: %d \n", i, pos);
1092   }
1093
1094   next = 0;
1095   my_values = NEW_ARR_F(ir_node *, n_vals);
1096   my_paths  = NEW_ARR_F(compound_graph_path *, n_vals);
1097   for (i = 0; i < size; ++i) {
1098     int pos = permutation[i];
1099     if (pos) {
1100       //fprintf(stderr, "pos: %d i: %d  next %d \n", i, pos, next);
1101       assert(next < n_vals);
1102       pos--;   /* We increased the pos by one */
1103       my_values[next] = get_compound_ent_value     (ent, pos);
1104       my_paths [next] = get_compound_ent_value_path(ent, pos);
1105       next++;
1106     }
1107   }
1108   free(permutation);
1109
1110   DEL_ARR_F(ent->attr.cmpd_attr.values);
1111   ent->attr.cmpd_attr.values = my_values;
1112   DEL_ARR_F(ent->attr.cmpd_attr.val_paths);
1113   ent->attr.cmpd_attr.val_paths = my_paths;
1114 }
1115
1116 int
1117 (get_entity_offset_bytes)(const entity *ent) {
1118   return _get_entity_offset_bytes(ent);
1119 }
1120
1121 int
1122 (get_entity_offset_bits)(const entity *ent) {
1123   return _get_entity_offset_bits(ent);
1124 }
1125
1126 void
1127 (set_entity_offset_bytes)(entity *ent, int offset) {
1128   _set_entity_offset_bytes(ent, offset);
1129 }
1130
1131 void
1132 (set_entity_offset_bits)(entity *ent, int offset) {
1133   _set_entity_offset_bits(ent, offset);
1134 }
1135
1136 void
1137 add_entity_overwrites(entity *ent, entity *overwritten) {
1138   assert(ent && is_Class_type(get_entity_owner(ent)));
1139   ARR_APP1(entity *, ent->overwrites, overwritten);
1140   ARR_APP1(entity *, overwritten->overwrittenby, ent);
1141 }
1142
1143 int
1144 get_entity_n_overwrites(entity *ent) {
1145   assert(ent && is_Class_type(get_entity_owner(ent)));
1146   return (ARR_LEN(ent->overwrites));
1147 }
1148
1149 int
1150 get_entity_overwrites_index(entity *ent, entity *overwritten) {
1151   int i;
1152   assert(ent && is_Class_type(get_entity_owner(ent)));
1153   for (i = 0; i < get_entity_n_overwrites(ent); i++)
1154     if (get_entity_overwrites(ent, i) == overwritten)
1155       return i;
1156   return -1;
1157 }
1158
1159 entity *
1160 get_entity_overwrites   (entity *ent, int pos) {
1161   assert(ent && is_Class_type(get_entity_owner(ent)));
1162   assert(pos < get_entity_n_overwrites(ent));
1163   return ent->overwrites[pos];
1164 }
1165
1166 void
1167 set_entity_overwrites   (entity *ent, int pos, entity *overwritten) {
1168   assert(ent && is_Class_type(get_entity_owner(ent)));
1169   assert(pos < get_entity_n_overwrites(ent));
1170   ent->overwrites[pos] = overwritten;
1171 }
1172
1173 void
1174 remove_entity_overwrites(entity *ent, entity *overwritten) {
1175   int i;
1176   assert(ent && is_Class_type(get_entity_owner(ent)));
1177   for (i = 0; i < (ARR_LEN (ent->overwrites)); i++)
1178     if (ent->overwrites[i] == overwritten) {
1179       for(; i < (ARR_LEN (ent->overwrites))-1; i++)
1180     ent->overwrites[i] = ent->overwrites[i+1];
1181       ARR_SETLEN(entity*, ent->overwrites, ARR_LEN(ent->overwrites) - 1);
1182       break;
1183     }
1184 }
1185
1186 void
1187 add_entity_overwrittenby   (entity *ent, entity *overwrites) {
1188   assert(ent && is_Class_type(get_entity_owner(ent)));
1189   add_entity_overwrites(overwrites, ent);
1190 }
1191
1192 int
1193 get_entity_n_overwrittenby (entity *ent) {
1194   assert(ent && is_Class_type(get_entity_owner(ent)));
1195   return (ARR_LEN (ent->overwrittenby));
1196 }
1197
1198 int
1199 get_entity_overwrittenby_index(entity *ent, entity *overwrites) {
1200   int i;
1201   assert(ent && is_Class_type(get_entity_owner(ent)));
1202   for (i = 0; i < get_entity_n_overwrittenby(ent); i++)
1203     if (get_entity_overwrittenby(ent, i) == overwrites)
1204       return i;
1205   return -1;
1206 }
1207
1208 entity *
1209 get_entity_overwrittenby   (entity *ent, int pos) {
1210   assert(ent && is_Class_type(get_entity_owner(ent)));
1211   assert(pos < get_entity_n_overwrittenby(ent));
1212   return ent->overwrittenby[pos];
1213 }
1214
1215 void
1216 set_entity_overwrittenby   (entity *ent, int pos, entity *overwrites) {
1217   assert(ent && is_Class_type(get_entity_owner(ent)));
1218   assert(pos < get_entity_n_overwrittenby(ent));
1219   ent->overwrittenby[pos] = overwrites;
1220 }
1221
1222 void    remove_entity_overwrittenby(entity *ent, entity *overwrites) {
1223   int i;
1224   assert(ent  && is_Class_type(get_entity_owner(ent)));
1225   for (i = 0; i < (ARR_LEN (ent->overwrittenby)); i++)
1226     if (ent->overwrittenby[i] == overwrites) {
1227       for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
1228     ent->overwrittenby[i] = ent->overwrittenby[i+1];
1229       ARR_SETLEN(entity*, ent->overwrittenby, ARR_LEN(ent->overwrittenby) - 1);
1230       break;
1231     }
1232 }
1233
1234 /* A link to store intermediate information */
1235 void *
1236 (get_entity_link)(const entity *ent) {
1237   return _get_entity_link(ent);
1238 }
1239
1240 void
1241 (set_entity_link)(entity *ent, void *l) {
1242   _set_entity_link(ent, l);
1243 }
1244
1245 ir_graph *
1246 (get_entity_irg)(const entity *ent) {
1247   return _get_entity_irg(ent);
1248 }
1249
1250 void
1251 set_entity_irg(entity *ent, ir_graph *irg) {
1252   assert(ent && is_method_entity(ent));
1253   /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
1254    * Methode selbst nicht mehr aufgerufen werden kann, die Entität
1255    * aber erhalten bleiben soll?  Wandle die Entitaet in description oder
1256    * inherited um! */
1257   /* assert(irg); */
1258   assert((irg  && ent->peculiarity == peculiarity_existent) ||
1259          (!irg && (ent->peculiarity == peculiarity_existent)
1260           && (ent -> visibility == visibility_external_allocated)) ||
1261          (!irg && ent->peculiarity == peculiarity_description) ||
1262          (!irg && ent->peculiarity == peculiarity_inherited));
1263   ent->attr.mtd_attr.irg = irg;
1264 }
1265
1266 unsigned get_entity_vtable_number(entity *ent) {
1267   assert(ent && is_method_entity(ent));
1268   return ent->attr.mtd_attr.vtable_number;
1269 }
1270
1271 void set_entity_vtable_number(entity *ent, unsigned vtable_number) {
1272   assert(ent && is_method_entity(ent));
1273   ent->attr.mtd_attr.vtable_number = vtable_number;
1274 }
1275
1276 int
1277 (is_entity)(const void *thing) {
1278   return _is_entity(thing);
1279 }
1280
1281 int is_atomic_entity(entity *ent) {
1282   ir_type *t = get_entity_type(ent);
1283   assert(ent && ent->kind == k_entity);
1284   return (is_Primitive_type(t) || is_Pointer_type(t) ||
1285       is_Enumeration_type(t) || is_Method_type(t));
1286 }
1287
1288 int is_compound_entity(entity *ent) {
1289   ir_type *t = get_entity_type(ent);
1290   assert(ent && ent->kind == k_entity);
1291   return (is_Class_type(t) || is_Struct_type(t) ||
1292       is_Array_type(t) || is_Union_type(t));
1293 }
1294
1295 int is_method_entity(entity *ent) {
1296   ir_type *t = get_entity_type(ent);
1297   assert(ent && ent->kind == k_entity);
1298   return (is_Method_type(t));
1299 }
1300
1301 /**
1302  * @todo not implemented!!! */
1303 int equal_entity(entity *ent1, entity *ent2) {
1304   fprintf(stderr, " calling unimplemented equal entity!!! \n");
1305   return 1;
1306 }
1307
1308
1309 unsigned long (get_entity_visited)(entity *ent) {
1310   return _get_entity_visited(ent);
1311 }
1312
1313 void (set_entity_visited)(entity *ent, unsigned long num) {
1314   _set_entity_visited(ent, num);
1315 }
1316
1317 /* Sets visited field in entity to entity_visited. */
1318 void (mark_entity_visited)(entity *ent) {
1319   _mark_entity_visited(ent);
1320 }
1321
1322 int (entity_visited)(entity *ent) {
1323   return _entity_visited(ent);
1324 }
1325
1326 int (entity_not_visited)(entity *ent) {
1327   return _entity_not_visited(ent);
1328 }
1329
1330 /* Returns the mask of the additional entity properties. */
1331 unsigned get_entity_additional_properties(entity *ent) {
1332   ir_graph *irg;
1333
1334   assert(is_method_entity(ent));
1335
1336   /* first check, if the graph has additional properties */
1337   irg = get_entity_irg(ent);
1338
1339   if (irg)
1340     return get_irg_additional_properties(irg);
1341
1342   if (ent->attr.mtd_attr.irg_add_properties & mtp_property_inherited)
1343     return get_method_additional_properties(get_entity_type(ent));
1344
1345   return ent->attr.mtd_attr.irg_add_properties;
1346 }
1347
1348 /* Sets the mask of the additional graph properties. */
1349 void set_entity_additional_properties(entity *ent, unsigned property_mask)
1350 {
1351   ir_graph *irg;
1352
1353   assert(is_method_entity(ent));
1354
1355   /* first check, if the graph exists */
1356   irg = get_entity_irg(ent);
1357   if (irg)
1358     set_irg_additional_properties(irg, property_mask);
1359   else {
1360     /* do not allow to set the mtp_property_inherited flag or
1361      * the automatic inheritance of flags will not work */
1362     ent->attr.mtd_attr.irg_add_properties = property_mask & ~mtp_property_inherited;
1363   }
1364 }
1365
1366 /* Sets one additional graph property. */
1367 void set_entity_additional_property(entity *ent, mtp_additional_property flag)
1368 {
1369   ir_graph *irg;
1370
1371   assert(is_method_entity(ent));
1372
1373   /* first check, if the graph exists */
1374   irg = get_entity_irg(ent);
1375   if (irg)
1376     set_irg_additional_property(irg, flag);
1377   else {
1378     unsigned mask = ent->attr.mtd_attr.irg_add_properties;
1379
1380     if (mask & mtp_property_inherited)
1381       mask = get_method_additional_properties(get_entity_type(ent));
1382
1383     /* do not allow to set the mtp_property_inherited flag or
1384      * the automatic inheritance of flags will not work */
1385     ent->attr.mtd_attr.irg_add_properties = mask | (flag & ~mtp_property_inherited);
1386   }
1387 }
1388
1389 /* Initialize entity module. */
1390 void firm_init_entity(void)
1391 {
1392   symconst_symbol sym;
1393
1394   assert(firm_unknown_type && "Call init_type() before firm_init_entity()!");
1395   assert(!unknown_entity && "Call firm_init_entity() only once!");
1396
1397   unknown_entity = new_rd_entity(NULL, firm_unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), firm_unknown_type);
1398   set_entity_visibility(unknown_entity, visibility_external_allocated);
1399   set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity));
1400
1401   current_ir_graph      = get_const_code_irg();
1402   sym.entity_p          = unknown_entity;
1403   unknown_entity->value = new_SymConst(sym, symconst_addr_ent);
1404 }