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