aet_entity_ident() added
[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
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 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 # include <stddef.h>
23
24 #include "firm_common_t.h"
25
26 # include "xmalloc.h"
27 # include "entity_t.h"
28 # include "mangle.h"
29 # include "typegmod.h"
30 # include "array.h"
31 # include "irtools.h"
32 # include "irhooks.h"
33
34 /* All this is needed to build the constant node for methods: */
35 # include "irprog_t.h"
36 # include "ircons.h"
37 # include "tv_t.h"
38
39 #if DEBUG_libfirm
40 # include "irdump.h"  /* for output if errors occur. */
41 #endif
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   ARR_APP1 (ir_node *, ent->attr.cmpd_attr.values, val);
679   ARR_APP1 (compound_graph_path *, ent->attr.cmpd_attr.val_paths, path);
680 }
681
682 void
683 set_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path, int pos) {
684   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
685   ent->attr.cmpd_attr.values[pos] = val;
686   ent->attr.cmpd_attr.val_paths[pos] = path;
687 }
688
689 int
690 get_compound_ent_n_values(entity *ent) {
691   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
692   return (ARR_LEN (ent->attr.cmpd_attr.values));
693 }
694
695 ir_node  *
696 get_compound_ent_value(entity *ent, int pos) {
697   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
698   return ent->attr.cmpd_attr.values[pos];
699 }
700
701 compound_graph_path *
702 get_compound_ent_value_path(entity *ent, int pos) {
703   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
704   return ent->attr.cmpd_attr.val_paths[pos];
705 }
706
707 /**
708  * Returns non-zero, if two compound_graph_pathes are equal
709  */
710 static int equal_paths(compound_graph_path *path1, int *visited_indicees, compound_graph_path *path2) {
711   int i;
712   int len1 = get_compound_graph_path_length(path1);
713   int len2 = get_compound_graph_path_length(path2);
714
715   if (len2 > len1) return 0;
716
717   for (i = 0; i < len1; i++) {
718     ir_type *tp;
719     entity *node1 = get_compound_graph_path_node(path1, i);
720     entity *node2 = get_compound_graph_path_node(path2, i);
721
722     if (node1 != node2) return 0;
723
724     tp = get_entity_owner(node1);
725     if (is_Array_type(tp)) {
726       long low;
727
728       /* Compute the index of this node. */
729       assert(get_array_n_dimensions(tp) == 1 && "multidim not implemented");
730
731       low = get_array_lower_bound_int(tp, 0);
732       if (low + visited_indicees[i] < get_compound_graph_path_array_index(path2, i)) {
733         visited_indicees[i]++;
734         return 0;
735       }
736       else
737         assert(low + visited_indicees[i] == get_compound_graph_path_array_index(path2, i));
738     }
739   }
740   return 1;
741 }
742
743 /* Returns the position of a value with the given path.
744  *  The path must contain array indicees for all array element entities. */
745 int get_compound_ent_pos_by_path(entity *ent, compound_graph_path *path) {
746   int i, n_paths = get_compound_ent_n_values(ent);
747   int *visited_indicees = (int *)xcalloc(get_compound_graph_path_length(path), sizeof(int));
748   for (i = 0; i < n_paths; i ++) {
749     if (equal_paths(get_compound_ent_value_path(ent, i), visited_indicees, path))
750       return i;
751   }
752
753 #if 0
754   {
755     int j;
756     printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
757       printf("Entity %s : ", get_entity_name(ent));
758       for (j = 0; j < get_compound_graph_path_length(path); ++j) {
759         entity *node = get_compound_graph_path_node(path, j);
760         printf("%s", get_entity_name(node));
761         if (is_Array_type(get_entity_owner(node)))
762           printf("[%d]", get_compound_graph_path_array_index(path, j));
763       }
764     printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
765   }
766 #endif
767
768   assert(0 && "path not found");
769   return -1;
770 }
771
772 /* Returns a constant value given the access path.
773  *  The path must contain array indicees for all array element entities. */
774 ir_node *get_compound_ent_value_by_path(entity *ent, compound_graph_path *path) {
775   return get_compound_ent_value(ent, get_compound_ent_pos_by_path(ent, path));
776 }
777
778
779 void
780 remove_compound_ent_value(entity *ent, entity *value_ent) {
781   int i;
782   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
783   for (i = 0; i < (ARR_LEN (ent->attr.cmpd_attr.val_paths)); i++) {
784     compound_graph_path *path = ent->attr.cmpd_attr.val_paths[i];
785     if (path->list[path->len-1].node == value_ent) {
786       for(; i < (ARR_LEN (ent->attr.cmpd_attr.val_paths))-1; i++) {
787         ent->attr.cmpd_attr.val_paths[i] = ent->attr.cmpd_attr.val_paths[i+1];
788         ent->attr.cmpd_attr.values[i]    = ent->attr.cmpd_attr.values[i+1];
789       }
790       ARR_SETLEN(entity*,  ent->attr.cmpd_attr.val_paths, ARR_LEN(ent->attr.cmpd_attr.val_paths) - 1);
791       ARR_SETLEN(ir_node*, ent->attr.cmpd_attr.values,    ARR_LEN(ent->attr.cmpd_attr.values)    - 1);
792       break;
793     }
794   }
795 }
796
797 void
798 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
799   compound_graph_path *path;
800   ir_type *owner_tp = get_entity_owner(member);
801   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
802   path = new_compound_graph_path(get_entity_type(ent), 1);
803   path->list[0].node = member;
804   if (is_Array_type(owner_tp)) {
805     int max;
806     int i;
807
808     assert(get_array_n_dimensions(owner_tp) == 1 && has_array_lower_bound(owner_tp, 0));
809     max = get_array_lower_bound_int(owner_tp, 0) -1;
810     for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
811       int index = get_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0);
812       if (index > max) {
813         max = index;
814       }
815     }
816     path->list[0].index = max + 1;
817   }
818   add_compound_ent_value_w_path(ent, val, path);
819 }
820
821 /* Copies the firm subgraph referenced by val to const_code_irg and adds
822    the node as constant initialization to ent.
823    The subgraph may not contain control flow operations.
824 void
825 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
826   ir_graph *rem = current_ir_graph;
827
828   assert(get_entity_variability(ent) != variability_uninitialized);
829   current_ir_graph = get_const_code_irg();
830
831   val = copy_const_value(val);
832   add_compound_ent_value(ent, val, member);
833   current_ir_graph = rem;
834   }*/
835
836 /* Copies the value i of the entity to current_block in current_ir_graph.
837 ir_node *
838 copy_compound_ent_value(entity *ent, int pos) {
839   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
840   return copy_const_value(ent->values[pos+1]);
841   }*/
842
843 entity   *
844 get_compound_ent_value_member(entity *ent, int pos) {
845   compound_graph_path *path;
846   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
847   path = get_compound_ent_value_path(ent, pos);
848
849   return get_compound_graph_path_node(path, get_compound_graph_path_length(path)-1);
850 }
851
852 void
853 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
854   compound_graph_path *path;
855   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
856   path = get_compound_ent_value_path(ent, pos);
857   set_compound_graph_path_node(path, 0, member);
858   set_compound_ent_value_w_path(ent, val, path, pos);
859 }
860
861 void
862 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
863   int i;
864   ir_graph *rem = current_ir_graph;
865   ir_type *arrtp = get_entity_type(ent);
866   ir_node *val;
867   ir_type *elttp = get_array_element_type(arrtp);
868
869   assert(is_Array_type(arrtp));
870   assert(get_array_n_dimensions(arrtp) == 1);
871   /* One bound is sufficient, the number of constant fields makes the
872      size. */
873   assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
874   assert(get_entity_variability(ent) != variability_uninitialized);
875   current_ir_graph = get_const_code_irg();
876
877   for (i = 0; i < num_vals; i++) {
878     val = new_Const_type(values[i], elttp);
879     add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
880     set_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0, i);
881   }
882   current_ir_graph = rem;
883 }
884
885 int  get_compound_ent_value_offset_bits(entity *ent, int pos) {
886   compound_graph_path *path;
887   int i, path_len;
888   int offset = 0;
889
890   assert(get_type_state(get_entity_type(ent)) == layout_fixed);
891
892   path = get_compound_ent_value_path(ent, pos);
893   path_len = get_compound_graph_path_length(path);
894
895   for (i = 0; i < path_len; ++i) {
896     entity *node = get_compound_graph_path_node(path, i);
897     ir_type *node_tp = get_entity_type(node);
898     ir_type *owner_tp = get_entity_owner(node);
899     if (is_Array_type(owner_tp)) {
900       int size  = get_type_size_bits(node_tp);
901       int align = get_type_alignment_bits(node_tp);
902       if (size < align)
903         size = align;
904       else {
905         assert(size % align == 0);
906         /* ansonsten aufrunden */
907       }
908       offset += size * get_compound_graph_path_array_index(path, i);
909     } else {
910       offset += get_entity_offset_bits(node);
911     }
912   }
913   return offset;
914 }
915
916 int  get_compound_ent_value_offset_bytes(entity *ent, int pos) {
917   int offset = get_compound_ent_value_offset_bits(ent, pos);
918   assert(offset % 8 == 0);
919   return offset >> 3;
920 }
921
922
923 static void init_index(ir_type *arr) {
924   int init;
925   int dim = 0;
926
927   assert(get_array_n_dimensions(arr) == 1);
928
929   if (has_array_lower_bound(arr, dim))
930     init = get_array_lower_bound_int(arr, 0) -1;
931   else
932     init = get_array_upper_bound_int(arr, 0) +1;
933
934   set_entity_link(get_array_element_entity(arr), INT_TO_PTR(init));
935 }
936
937
938 static int get_next_index(entity *elem_ent) {
939   ir_type *arr = get_entity_owner(elem_ent);
940   int next;
941   int dim = 0;
942
943   assert(get_array_n_dimensions(arr) == 1);
944
945   if (has_array_lower_bound(arr, dim)) {
946     next = PTR_TO_INT(get_entity_link(elem_ent)) + 1;
947     if (has_array_upper_bound(arr, dim)) {
948       int upper = get_array_upper_bound_int(arr, dim);
949       if (next == upper) next = get_array_lower_bound_int(arr, dim);
950     }
951   } else {
952     next = PTR_TO_INT(get_entity_link(elem_ent)) - 1;
953     if (has_array_lower_bound(arr, dim)) {
954       int upper = get_array_upper_bound_int(arr, dim);
955       if (next == upper) next = get_array_upper_bound_int(arr, dim);
956     }
957   }
958
959   set_entity_link(elem_ent, INT_TO_PTR(next));
960   return next;
961 }
962
963 /* Compute the array indices in compound graph paths of initialized entities.
964  *
965  *  All arrays must have fixed lower and upper bounds.  One array can
966  *  have an open bound.  If there are several open bounds, we do
967  *  nothing.  There must be initializer elements for all array
968  *  elements.  Uses the link field in the array element entities.  The
969  *  array bounds must be representable as ints.
970  *
971  *  (If the bounds are not representable as ints we have to represent
972  *  the indices as firm nodes.  But still we must be able to
973  *  evaluate the index against the upper bound.)
974  */
975 void compute_compound_ent_array_indicees(entity *ent) {
976   ir_type *tp = get_entity_type(ent);
977   int i, n_vals;
978   entity *unknown_bound_entity = NULL;
979
980   if (!is_compound_type(tp) ||
981       (ent->variability == variability_uninitialized)) return ;
982
983   n_vals = get_compound_ent_n_values(ent);
984   if (n_vals == 0) return;
985
986   /* We can not compute the indexes if there is more than one array
987      with an unknown bound.  For this remember the first entity that
988      represents such an array. It could be ent. */
989   if (is_Array_type(tp)) {
990     int dim = 0;
991
992     assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
993     if (!has_array_lower_bound(tp, dim) || !has_array_upper_bound(tp, dim))
994      unknown_bound_entity = ent;
995   }
996
997   /* Initialize the entity links to lower bound -1 and test all path elements
998      for known bounds. */
999   for (i = 0; i < n_vals; ++i) {
1000     compound_graph_path *path = get_compound_ent_value_path(ent, i);
1001     int j, path_len =  get_compound_graph_path_length(path);
1002     for (j = 0; j < path_len; ++j) {
1003       entity *node = get_compound_graph_path_node(path, j);
1004       ir_type *elem_tp = get_entity_type(node);
1005
1006       if (is_Array_type(elem_tp)) {
1007         int dim = 0;
1008         assert(get_array_n_dimensions(elem_tp) == 1 && "other not implemented");
1009         if (!has_array_lower_bound(elem_tp, dim) || !has_array_upper_bound(elem_tp, dim)) {
1010           if (!unknown_bound_entity) unknown_bound_entity = node;
1011           if (node != unknown_bound_entity) return;
1012         }
1013
1014         init_index(elem_tp);
1015       }
1016     }
1017   }
1018
1019   /* Finally compute the indexes ... */
1020   for (i = 0; i < n_vals; ++i) {
1021     compound_graph_path *path = get_compound_ent_value_path(ent, i);
1022     int j, path_len =  get_compound_graph_path_length(path);
1023     for (j = 0; j < path_len; ++j) {
1024       entity *node = get_compound_graph_path_node(path, j);
1025       ir_type *owner_tp = get_entity_owner(node);
1026       if (is_Array_type(owner_tp))
1027         set_compound_graph_path_array_index (path, j, get_next_index(node));
1028     }
1029   }
1030 }
1031
1032 /** resize: double the allocated buffer */
1033 static int *resize (int *buf, int *size) {
1034   int new_size =  *size * 2;
1035   int *new_buf = xcalloc(new_size, sizeof(new_buf[0]));
1036   memcpy(new_buf, buf, *size);
1037   free(buf);
1038   *size = new_size;
1039   return new_buf;
1040 }
1041
1042 /* We sort the elements by placing them at their bit offset in an
1043    array where each entry represents one bit called permutation.  In
1044    fact, we do not place the values themselves, as we would have to
1045    copy two things, the value and the path.  We only remember the
1046    position in the old order. Each value should have a distinct
1047    position in the permutation.
1048
1049    A second iteration now permutes the actual elements into two
1050    new arrays. */
1051 void sort_compound_ent_values(entity *ent) {
1052   ir_type *tp;
1053   int i, n_vals;
1054   int tp_size;
1055   int size;
1056   int *permutation;
1057
1058   int next;
1059   ir_node **my_values;
1060   compound_graph_path **my_paths;
1061
1062   assert(get_type_state(get_entity_type(ent)) == layout_fixed);
1063
1064   tp      = get_entity_type(ent);
1065   n_vals  = get_compound_ent_n_values(ent);
1066   tp_size = get_type_size_bits(tp);
1067
1068   if (!is_compound_type(tp)                           ||
1069       (ent->variability == variability_uninitialized) ||
1070       (get_type_state(tp) != layout_fixed)            ||
1071       (n_vals == 0)                                     ) return;
1072
1073   /* estimated upper bound for size. Better: use flexible array ... */
1074   size = ((tp_size > (n_vals * 32)) ? tp_size : (n_vals * 32)) * 4;
1075   permutation = xcalloc(size, sizeof(permutation[0]));
1076
1077   for (i = 0; i < n_vals; ++i) {
1078     int pos = get_compound_ent_value_offset_bits(ent, i);
1079     while (pos >= size) {
1080       permutation = resize(permutation, &size);
1081     }
1082     assert(pos < size);
1083     assert(permutation[pos] == 0 && "two values with the same offset");
1084     permutation[pos] = i + 1;         /* We initialized with 0, so we can not distinguish entry 0.
1085                      So inc all entries by one. */
1086     //fprintf(stderr, "i: %d, pos: %d \n", i, pos);
1087   }
1088
1089   next = 0;
1090   my_values = NEW_ARR_F(ir_node *, n_vals);
1091   my_paths  = NEW_ARR_F(compound_graph_path *, n_vals);
1092   for (i = 0; i < size; ++i) {
1093     int pos = permutation[i];
1094     if (pos) {
1095       //fprintf(stderr, "pos: %d i: %d  next %d \n", i, pos, next);
1096       assert(next < n_vals);
1097       pos--;   /* We increased the pos by one */
1098       my_values[next] = get_compound_ent_value     (ent, pos);
1099       my_paths [next] = get_compound_ent_value_path(ent, pos);
1100       next++;
1101     }
1102   }
1103   free(permutation);
1104
1105   DEL_ARR_F(ent->attr.cmpd_attr.values);
1106   ent->attr.cmpd_attr.values = my_values;
1107   DEL_ARR_F(ent->attr.cmpd_attr.val_paths);
1108   ent->attr.cmpd_attr.val_paths = my_paths;
1109 }
1110
1111 int
1112 (get_entity_offset_bytes)(const entity *ent) {
1113   return _get_entity_offset_bytes(ent);
1114 }
1115
1116 int
1117 (get_entity_offset_bits)(const entity *ent) {
1118   return _get_entity_offset_bits(ent);
1119 }
1120
1121 void
1122 (set_entity_offset_bytes)(entity *ent, int offset) {
1123   _set_entity_offset_bytes(ent, offset);
1124 }
1125
1126 void
1127 (set_entity_offset_bits)(entity *ent, int offset) {
1128   _set_entity_offset_bits(ent, offset);
1129 }
1130
1131 void
1132 add_entity_overwrites(entity *ent, entity *overwritten) {
1133   assert(ent && is_Class_type(get_entity_owner(ent)));
1134   ARR_APP1(entity *, ent->overwrites, overwritten);
1135   ARR_APP1(entity *, overwritten->overwrittenby, ent);
1136 }
1137
1138 int
1139 get_entity_n_overwrites(entity *ent) {
1140   assert(ent && is_Class_type(get_entity_owner(ent)));
1141   return (ARR_LEN(ent->overwrites));
1142 }
1143
1144 int
1145 get_entity_overwrites_index(entity *ent, entity *overwritten) {
1146   int i;
1147   assert(ent && is_Class_type(get_entity_owner(ent)));
1148   for (i = 0; i < get_entity_n_overwrites(ent); i++)
1149     if (get_entity_overwrites(ent, i) == overwritten)
1150       return i;
1151   return -1;
1152 }
1153
1154 entity *
1155 get_entity_overwrites   (entity *ent, int pos) {
1156   assert(ent && is_Class_type(get_entity_owner(ent)));
1157   assert(pos < get_entity_n_overwrites(ent));
1158   return ent->overwrites[pos];
1159 }
1160
1161 void
1162 set_entity_overwrites   (entity *ent, int pos, entity *overwritten) {
1163   assert(ent && is_Class_type(get_entity_owner(ent)));
1164   assert(pos < get_entity_n_overwrites(ent));
1165   ent->overwrites[pos] = overwritten;
1166 }
1167
1168 void
1169 remove_entity_overwrites(entity *ent, entity *overwritten) {
1170   int i;
1171   assert(ent && is_Class_type(get_entity_owner(ent)));
1172   for (i = 0; i < (ARR_LEN (ent->overwrites)); i++)
1173     if (ent->overwrites[i] == overwritten) {
1174       for(; i < (ARR_LEN (ent->overwrites))-1; i++)
1175     ent->overwrites[i] = ent->overwrites[i+1];
1176       ARR_SETLEN(entity*, ent->overwrites, ARR_LEN(ent->overwrites) - 1);
1177       break;
1178     }
1179 }
1180
1181 void
1182 add_entity_overwrittenby   (entity *ent, entity *overwrites) {
1183   assert(ent && is_Class_type(get_entity_owner(ent)));
1184   add_entity_overwrites(overwrites, ent);
1185 }
1186
1187 int
1188 get_entity_n_overwrittenby (entity *ent) {
1189   assert(ent && is_Class_type(get_entity_owner(ent)));
1190   return (ARR_LEN (ent->overwrittenby));
1191 }
1192
1193 int
1194 get_entity_overwrittenby_index(entity *ent, entity *overwrites) {
1195   int i;
1196   assert(ent && is_Class_type(get_entity_owner(ent)));
1197   for (i = 0; i < get_entity_n_overwrittenby(ent); i++)
1198     if (get_entity_overwrittenby(ent, i) == overwrites)
1199       return i;
1200   return -1;
1201 }
1202
1203 entity *
1204 get_entity_overwrittenby   (entity *ent, int pos) {
1205   assert(ent && is_Class_type(get_entity_owner(ent)));
1206   assert(pos < get_entity_n_overwrittenby(ent));
1207   return ent->overwrittenby[pos];
1208 }
1209
1210 void
1211 set_entity_overwrittenby   (entity *ent, int pos, entity *overwrites) {
1212   assert(ent && is_Class_type(get_entity_owner(ent)));
1213   assert(pos < get_entity_n_overwrittenby(ent));
1214   ent->overwrittenby[pos] = overwrites;
1215 }
1216
1217 void    remove_entity_overwrittenby(entity *ent, entity *overwrites) {
1218   int i;
1219   assert(ent  && is_Class_type(get_entity_owner(ent)));
1220   for (i = 0; i < (ARR_LEN (ent->overwrittenby)); i++)
1221     if (ent->overwrittenby[i] == overwrites) {
1222       for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
1223     ent->overwrittenby[i] = ent->overwrittenby[i+1];
1224       ARR_SETLEN(entity*, ent->overwrittenby, ARR_LEN(ent->overwrittenby) - 1);
1225       break;
1226     }
1227 }
1228
1229 /* A link to store intermediate information */
1230 void *
1231 (get_entity_link)(const entity *ent) {
1232   return _get_entity_link(ent);
1233 }
1234
1235 void
1236 (set_entity_link)(entity *ent, void *l) {
1237   _set_entity_link(ent, l);
1238 }
1239
1240 ir_graph *
1241 (get_entity_irg)(const entity *ent) {
1242   return _get_entity_irg(ent);
1243 }
1244
1245 void
1246 set_entity_irg(entity *ent, ir_graph *irg) {
1247   assert(ent && is_method_entity(ent));
1248   /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
1249    * Methode selbst nicht mehr aufgerufen werden kann, die Entität
1250    * aber erhalten bleiben soll?  Wandle die Entitaet in description oder
1251    * inherited um! */
1252   /* assert(irg); */
1253   assert((irg  && ent->peculiarity == peculiarity_existent) ||
1254          (!irg && (ent->peculiarity == peculiarity_existent)
1255           && (ent -> visibility == visibility_external_allocated)) ||
1256          (!irg && ent->peculiarity == peculiarity_description) ||
1257          (!irg && ent->peculiarity == peculiarity_inherited));
1258   ent->attr.mtd_attr.irg = irg;
1259 }
1260
1261 unsigned get_entity_vtable_number(entity *ent) {
1262   assert(ent && is_method_entity(ent));
1263   return ent->attr.mtd_attr.vtable_number;
1264 }
1265
1266 void set_entity_vtable_number(entity *ent, unsigned vtable_number) {
1267   assert(ent && is_method_entity(ent));
1268   ent->attr.mtd_attr.vtable_number = vtable_number;
1269 }
1270
1271 int
1272 (is_entity)(const void *thing) {
1273   return _is_entity(thing);
1274 }
1275
1276 int is_atomic_entity(entity *ent) {
1277   ir_type *t = get_entity_type(ent);
1278   assert(ent && ent->kind == k_entity);
1279   return (is_Primitive_type(t) || is_Pointer_type(t) ||
1280       is_Enumeration_type(t) || is_Method_type(t));
1281 }
1282
1283 int is_compound_entity(entity *ent) {
1284   ir_type *t = get_entity_type(ent);
1285   assert(ent && ent->kind == k_entity);
1286   return (is_Class_type(t) || is_Struct_type(t) ||
1287       is_Array_type(t) || is_Union_type(t));
1288 }
1289
1290 int is_method_entity(entity *ent) {
1291   ir_type *t = get_entity_type(ent);
1292   assert(ent && ent->kind == k_entity);
1293   return (is_Method_type(t));
1294 }
1295
1296 /**
1297  * @todo not implemented!!! */
1298 int equal_entity(entity *ent1, entity *ent2) {
1299   fprintf(stderr, " calling unimplemented equal entity!!! \n");
1300   return 1;
1301 }
1302
1303
1304 unsigned long (get_entity_visited)(entity *ent) {
1305   return _get_entity_visited(ent);
1306 }
1307
1308 void (set_entity_visited)(entity *ent, unsigned long num) {
1309   _set_entity_visited(ent, num);
1310 }
1311
1312 /* Sets visited field in entity to entity_visited. */
1313 void (mark_entity_visited)(entity *ent) {
1314   _mark_entity_visited(ent);
1315 }
1316
1317 int (entity_visited)(entity *ent) {
1318   return _entity_visited(ent);
1319 }
1320
1321 int (entity_not_visited)(entity *ent) {
1322   return _entity_not_visited(ent);
1323 }
1324
1325 /* Returns the mask of the additional entity properties. */
1326 unsigned get_entity_additional_properties(entity *ent) {
1327   ir_graph *irg;
1328
1329   assert(is_method_entity(ent));
1330
1331   /* first check, if the graph has additional properties */
1332   irg = get_entity_irg(ent);
1333
1334   if (irg)
1335     return get_irg_additional_properties(irg);
1336
1337   if (ent->attr.mtd_attr.irg_add_properties & mtp_property_inherited)
1338     return get_method_additional_properties(get_entity_type(ent));
1339
1340   return ent->attr.mtd_attr.irg_add_properties;
1341 }
1342
1343 /* Sets the mask of the additional graph properties. */
1344 void set_entity_additional_properties(entity *ent, unsigned property_mask)
1345 {
1346   ir_graph *irg;
1347
1348   assert(is_method_entity(ent));
1349
1350   /* first check, if the graph exists */
1351   irg = get_entity_irg(ent);
1352   if (irg)
1353     set_irg_additional_properties(irg, property_mask);
1354   else {
1355     /* do not allow to set the mtp_property_inherited flag or
1356      * the automatic inheritance of flags will not work */
1357     ent->attr.mtd_attr.irg_add_properties = property_mask & ~mtp_property_inherited;
1358   }
1359 }
1360
1361 /* Sets one additional graph property. */
1362 void set_entity_additional_property(entity *ent, mtp_additional_property flag)
1363 {
1364   ir_graph *irg;
1365
1366   assert(is_method_entity(ent));
1367
1368   /* first check, if the graph exists */
1369   irg = get_entity_irg(ent);
1370   if (irg)
1371     set_irg_additional_property(irg, flag);
1372   else {
1373     unsigned mask = ent->attr.mtd_attr.irg_add_properties;
1374
1375     if (mask & mtp_property_inherited)
1376       mask = get_method_additional_properties(get_entity_type(ent));
1377
1378     /* do not allow to set the mtp_property_inherited flag or
1379      * the automatic inheritance of flags will not work */
1380     ent->attr.mtd_attr.irg_add_properties = mask | (flag & ~mtp_property_inherited);
1381   }
1382 }
1383
1384 /* Initialize entity module. */
1385 void firm_init_entity(void)
1386 {
1387   symconst_symbol sym;
1388
1389   assert(firm_unknown_type && "Call init_type() before firm_init_entity()!");
1390   assert(!unknown_entity && "Call firm_init_entity() only once!");
1391
1392   unknown_entity = new_rd_entity(NULL, firm_unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), firm_unknown_type);
1393   set_entity_visibility(unknown_entity, visibility_external_allocated);
1394   set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity));
1395
1396   current_ir_graph      = get_const_code_irg();
1397   sym.entity_p          = unknown_entity;
1398   unknown_entity->value = new_SymConst(sym, symconst_addr_ent);
1399 }