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