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