Finally removed obsolete type "type", use ir_type instead
[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 /* Get the entity's stickyness */
474 ent_stickyness
475 (get_entity_stickyness)(const entity *ent) {
476   return _get_entity_stickyness(ent);
477 }
478
479 /* Set the entity's stickyness */
480 void
481 (set_entity_stickyness)(entity *ent, ent_stickyness stickyness) {
482   _set_entity_stickyness(ent, stickyness);
483 }
484
485 /* Set has no effect for existent entities of type method. */
486 ir_node *
487 get_atomic_ent_value(entity *ent)
488 {
489   assert(ent && is_atomic_entity(ent));
490   assert(ent->variability != variability_uninitialized);
491   return skip_Id (ent->value);
492 }
493
494 void
495 set_atomic_ent_value(entity *ent, ir_node *val) {
496   assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized));
497   if (is_Method_type(ent->type) && (ent->peculiarity == peculiarity_existent))
498     return;
499   ent->value = val;
500 }
501
502 /* Returns true if the the node is representable as code on
503  *  const_code_irg. */
504 int is_irn_const_expression(ir_node *n) {
505   ir_mode *m;
506
507   /* we are in danger iff an exception will arise. TODO: be more precisely,
508    * for instance Div. will NOT rise if divisor != 0
509    */
510   if (is_binop(n) && !is_fragile_op(n))
511     return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));
512
513   m = get_irn_mode(n);
514   switch(get_irn_opcode(n)) {
515   case iro_Const:
516   case iro_SymConst:
517   case iro_Unknown:
518     return 1;
519   case iro_Conv:
520   case iro_Cast:
521     return is_irn_const_expression(get_irn_n(n, 0));
522   default:
523     break;
524   }
525   return 0;
526 }
527
528 /*
529  * Copies a firm subgraph that complies to the restrictions for
530  * constant expressions to current_block in current_ir_graph.
531  */
532 ir_node *copy_const_value(dbg_info *dbg, ir_node *n) {
533   ir_node *nn;
534   ir_mode *m;
535
536   /* @@@ GL I think  we should implement this using the routines from irgopt for
537      dead node elimination/inlineing. */
538
539   m = get_irn_mode(n);
540   switch (get_irn_opcode(n)) {
541   case iro_Const:
542     nn = new_d_Const_type(dbg, m, get_Const_tarval(n), get_Const_type(n));
543     break;
544   case iro_SymConst:
545     nn = new_d_SymConst_type(dbg, get_SymConst_symbol(n), get_SymConst_kind(n),
546                              get_SymConst_value_type(n));
547     break;
548   case iro_Add:
549     nn = new_d_Add(dbg, copy_const_value(dbg, get_Add_left(n)),
550                  copy_const_value(dbg, get_Add_right(n)), m); break;
551   case iro_Sub:
552     nn = new_d_Sub(dbg, copy_const_value(dbg, get_Sub_left(n)),
553                  copy_const_value(dbg, get_Sub_right(n)), m); break;
554   case iro_Mul:
555     nn = new_d_Mul(dbg, copy_const_value(dbg, get_Mul_left(n)),
556                  copy_const_value(dbg, get_Mul_right(n)), m); break;
557   case iro_And:
558     nn = new_d_And(dbg, copy_const_value(dbg, get_And_left(n)),
559                  copy_const_value(dbg, get_And_right(n)), m); break;
560   case iro_Or:
561     nn = new_d_Or(dbg, copy_const_value(dbg, get_Or_left(n)),
562                 copy_const_value(dbg, get_Or_right(n)), m); break;
563   case iro_Eor:
564     nn = new_d_Eor(dbg, copy_const_value(dbg, get_Eor_left(n)),
565                  copy_const_value(dbg, get_Eor_right(n)), m); break;
566   case iro_Cast:
567     nn = new_d_Cast(dbg, copy_const_value(dbg, get_Cast_op(n)), get_Cast_type(n)); break;
568   case iro_Conv:
569     nn = new_d_Conv(dbg, copy_const_value(dbg, get_Conv_op(n)), m); break;
570   case iro_Unknown:
571     nn = new_d_Unknown(m); break;
572   default:
573     DDMN(n);
574     assert(0 && "opcode invalid or not implemented");
575     nn = NULL;
576     break;
577   }
578   return nn;
579 }
580
581 /* Creates a new compound graph path. */
582 compound_graph_path *
583 new_compound_graph_path(ir_type *tp, int length) {
584   compound_graph_path *res;
585
586   assert(is_type(tp) && is_compound_type(tp));
587   assert(length > 0);
588
589   res = xmalloc(sizeof(*res) + (length-1) * sizeof(res->list[0]));
590   memset(res, 0, sizeof(*res) + (length-1) * sizeof(res->list[0]));
591   res->kind         = k_ir_compound_graph_path;
592   res->tp           = tp;
593   res->len          = length;
594
595   return res;
596 }
597
598 /* Frees an graph path object */
599 void free_compound_graph_path (compound_graph_path *gr) {
600   assert(gr && is_compound_graph_path(gr));
601   gr->kind = k_BAD;
602   free(gr);
603 }
604
605 /* Returns non-zero if an object is a compound graph path */
606 int is_compound_graph_path(void *thing) {
607   return (get_kind(thing) == k_ir_compound_graph_path);
608 }
609
610 /* Checks whether the path up to pos is correct. If the path contains a NULL,
611  *  assumes the path is not complete and returns 'true'. */
612 int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
613   int i;
614   entity *node;
615   ir_type *owner = gr->tp;
616
617   for (i = 0; i <= pos; i++) {
618     node = get_compound_graph_path_node(gr, i);
619     if (node == NULL)
620       /* Path not yet complete. */
621       return 1;
622     if (get_entity_owner(node) != owner)
623       return 0;
624     owner = get_entity_type(node);
625   }
626   if (pos == get_compound_graph_path_length(gr))
627     if (!is_atomic_type(owner))
628       return 0;
629   return 1;
630 }
631
632 /* Returns the length of a graph path */
633 int get_compound_graph_path_length(compound_graph_path *gr) {
634   assert(gr && is_compound_graph_path(gr));
635   return gr->len;
636 }
637
638 entity *
639 get_compound_graph_path_node(compound_graph_path *gr, int pos) {
640   assert(gr && is_compound_graph_path(gr));
641   assert(pos >= 0 && pos < gr->len);
642   return gr->list[pos].node;
643 }
644
645 void
646 set_compound_graph_path_node(compound_graph_path *gr, int pos, entity *node) {
647   assert(gr && is_compound_graph_path(gr));
648   assert(pos >= 0 && pos < gr->len);
649   assert(is_entity(node));
650   gr->list[pos].node = node;
651   assert(is_proper_compound_graph_path(gr, pos));
652 }
653
654 int
655 get_compound_graph_path_array_index(compound_graph_path *gr, int pos) {
656   assert(gr && is_compound_graph_path(gr));
657   assert(pos >= 0 && pos < gr->len);
658   return gr->list[pos].index;
659 }
660
661 void
662 set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index) {
663   assert(gr && is_compound_graph_path(gr));
664   assert(pos >= 0 && pos < gr->len);
665   gr->list[pos].index = index;
666 }
667
668 /* A value of a compound entity is a pair of value and the corresponding path to a member of
669    the compound. */
670 void
671 add_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path) {
672   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
673   ARR_APP1 (ir_node *, ent->attr.cmpd_attr.values, val);
674   ARR_APP1 (compound_graph_path *, ent->attr.cmpd_attr.val_paths, path);
675 }
676
677 void
678 set_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path, int pos) {
679   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
680   ent->attr.cmpd_attr.values[pos] = val;
681   ent->attr.cmpd_attr.val_paths[pos] = path;
682 }
683
684 int
685 get_compound_ent_n_values(entity *ent) {
686   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
687   return (ARR_LEN (ent->attr.cmpd_attr.values));
688 }
689
690 ir_node  *
691 get_compound_ent_value(entity *ent, int pos) {
692   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
693   return ent->attr.cmpd_attr.values[pos];
694 }
695
696 compound_graph_path *
697 get_compound_ent_value_path(entity *ent, int pos) {
698   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
699   return ent->attr.cmpd_attr.val_paths[pos];
700 }
701
702 /**
703  * Returns non-zero, if two compound_graph_pathes are equal
704  */
705 static int equal_paths(compound_graph_path *path1, int *visited_indicees, compound_graph_path *path2) {
706   int i;
707   int len1 = get_compound_graph_path_length(path1);
708   int len2 = get_compound_graph_path_length(path2);
709
710   if (len2 > len1) return 0;
711
712   for (i = 0; i < len1; i++) {
713     ir_type *tp;
714     entity *node1 = get_compound_graph_path_node(path1, i);
715     entity *node2 = get_compound_graph_path_node(path2, i);
716
717     if (node1 != node2) return 0;
718
719     tp = get_entity_owner(node1);
720     if (is_Array_type(tp)) {
721       long low;
722
723       /* Compute the index of this node. */
724       assert(get_array_n_dimensions(tp) == 1 && "multidim not implemented");
725
726       low = get_array_lower_bound_int(tp, 0);
727       if (low + visited_indicees[i] < get_compound_graph_path_array_index(path2, i)) {
728         visited_indicees[i]++;
729         return 0;
730       }
731       else
732         assert(low + visited_indicees[i] == get_compound_graph_path_array_index(path2, i));
733     }
734   }
735   return 1;
736 }
737
738 /* Returns the position of a value with the given path.
739  *  The path must contain array indicees for all array element entities. */
740 int get_compound_ent_pos_by_path(entity *ent, compound_graph_path *path) {
741   int i, n_paths = get_compound_ent_n_values(ent);
742   int *visited_indicees = (int *)xcalloc(get_compound_graph_path_length(path), sizeof(int));
743   for (i = 0; i < n_paths; i ++) {
744     if (equal_paths(get_compound_ent_value_path(ent, i), visited_indicees, path))
745       return i;
746   }
747
748 #if 0
749   {
750     int j;
751     printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
752       printf("Entity %s : ", get_entity_name(ent));
753       for (j = 0; j < get_compound_graph_path_length(path); ++j) {
754         entity *node = get_compound_graph_path_node(path, j);
755         printf("%s", get_entity_name(node));
756         if (is_Array_type(get_entity_owner(node)))
757           printf("[%d]", get_compound_graph_path_array_index(path, j));
758       }
759     printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
760   }
761 #endif
762
763   assert(0 && "path not found");
764   return -1;
765 }
766
767 /* Returns a constant value given the access path.
768  *  The path must contain array indicees for all array element entities. */
769 ir_node *get_compound_ent_value_by_path(entity *ent, compound_graph_path *path) {
770   return get_compound_ent_value(ent, get_compound_ent_pos_by_path(ent, path));
771 }
772
773
774 void
775 remove_compound_ent_value(entity *ent, entity *value_ent) {
776   int i;
777   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
778   for (i = 0; i < (ARR_LEN (ent->attr.cmpd_attr.val_paths)); i++) {
779     compound_graph_path *path = ent->attr.cmpd_attr.val_paths[i];
780     if (path->list[path->len-1].node == value_ent) {
781       for(; i < (ARR_LEN (ent->attr.cmpd_attr.val_paths))-1; i++) {
782         ent->attr.cmpd_attr.val_paths[i] = ent->attr.cmpd_attr.val_paths[i+1];
783         ent->attr.cmpd_attr.values[i]    = ent->attr.cmpd_attr.values[i+1];
784       }
785       ARR_SETLEN(entity*,  ent->attr.cmpd_attr.val_paths, ARR_LEN(ent->attr.cmpd_attr.val_paths) - 1);
786       ARR_SETLEN(ir_node*, ent->attr.cmpd_attr.values,    ARR_LEN(ent->attr.cmpd_attr.values)    - 1);
787       break;
788     }
789   }
790 }
791
792 void
793 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
794   compound_graph_path *path;
795   ir_type *owner_tp = get_entity_owner(member);
796   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
797   path = new_compound_graph_path(get_entity_type(ent), 1);
798   path->list[0].node = member;
799   if (is_Array_type(owner_tp)) {
800     int max;
801     int i;
802
803     assert(get_array_n_dimensions(owner_tp) == 1 && has_array_lower_bound(owner_tp, 0));
804     max = get_array_lower_bound_int(owner_tp, 0) -1;
805     for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
806       int index = get_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0);
807       if (index > max) {
808         max = index;
809       }
810     }
811     path->list[0].index = max + 1;
812   }
813   add_compound_ent_value_w_path(ent, val, path);
814 }
815
816 /* Copies the firm subgraph referenced by val to const_code_irg and adds
817    the node as constant initialization to ent.
818    The subgraph may not contain control flow operations.
819 void
820 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
821   ir_graph *rem = current_ir_graph;
822
823   assert(get_entity_variability(ent) != variability_uninitialized);
824   current_ir_graph = get_const_code_irg();
825
826   val = copy_const_value(val);
827   add_compound_ent_value(ent, val, member);
828   current_ir_graph = rem;
829   }*/
830
831 /* Copies the value i of the entity to current_block in current_ir_graph.
832 ir_node *
833 copy_compound_ent_value(entity *ent, int pos) {
834   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
835   return copy_const_value(ent->values[pos+1]);
836   }*/
837
838 entity   *
839 get_compound_ent_value_member(entity *ent, int pos) {
840   compound_graph_path *path;
841   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
842   path = get_compound_ent_value_path(ent, pos);
843
844   return get_compound_graph_path_node(path, get_compound_graph_path_length(path)-1);
845 }
846
847 void
848 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
849   compound_graph_path *path;
850   assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
851   path = get_compound_ent_value_path(ent, pos);
852   set_compound_graph_path_node(path, 0, member);
853   set_compound_ent_value_w_path(ent, val, path, pos);
854 }
855
856 void
857 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
858   int i;
859   ir_graph *rem = current_ir_graph;
860   ir_type *arrtp = get_entity_type(ent);
861   ir_node *val;
862   ir_type *elttp = get_array_element_type(arrtp);
863
864   assert(is_Array_type(arrtp));
865   assert(get_array_n_dimensions(arrtp) == 1);
866   /* One bound is sufficient, the number of constant fields makes the
867      size. */
868   assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
869   assert(get_entity_variability(ent) != variability_uninitialized);
870   current_ir_graph = get_const_code_irg();
871
872   for (i = 0; i < num_vals; i++) {
873     val = new_Const_type(values[i], elttp);
874     add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
875     set_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0, i);
876   }
877   current_ir_graph = rem;
878 }
879
880 int  get_compound_ent_value_offset_bits(entity *ent, int pos) {
881   compound_graph_path *path;
882   int i, path_len;
883   int offset = 0;
884
885   assert(get_type_state(get_entity_type(ent)) == layout_fixed);
886
887   path = get_compound_ent_value_path(ent, pos);
888   path_len = get_compound_graph_path_length(path);
889
890   for (i = 0; i < path_len; ++i) {
891     entity *node = get_compound_graph_path_node(path, i);
892     ir_type *node_tp = get_entity_type(node);
893     ir_type *owner_tp = get_entity_owner(node);
894     if (is_Array_type(owner_tp)) {
895       int size  = get_type_size_bits(node_tp);
896       int align = get_type_alignment_bits(node_tp);
897       if (size < align)
898         size = align;
899       else {
900         assert(size % align == 0);
901         /* ansonsten aufrunden */
902       }
903       offset += size * get_compound_graph_path_array_index(path, i);
904     } else {
905       offset += get_entity_offset_bits(node);
906     }
907   }
908   return offset;
909 }
910
911 int  get_compound_ent_value_offset_bytes(entity *ent, int pos) {
912   int offset = get_compound_ent_value_offset_bits(ent, pos);
913   assert(offset % 8 == 0);
914   return offset >> 3;
915 }
916
917
918 static void init_index(ir_type *arr) {
919   int init;
920   int dim = 0;
921
922   assert(get_array_n_dimensions(arr) == 1);
923
924   if (has_array_lower_bound(arr, dim))
925     init = get_array_lower_bound_int(arr, 0) -1;
926   else
927     init = get_array_upper_bound_int(arr, 0) +1;
928
929   set_entity_link(get_array_element_entity(arr), INT_TO_PTR(init));
930 }
931
932
933 static int get_next_index(entity *elem_ent) {
934   ir_type *arr = get_entity_owner(elem_ent);
935   int next;
936   int dim = 0;
937
938   assert(get_array_n_dimensions(arr) == 1);
939
940   if (has_array_lower_bound(arr, dim)) {
941     next = PTR_TO_INT(get_entity_link(elem_ent)) + 1;
942     if (has_array_upper_bound(arr, dim)) {
943       int upper = get_array_upper_bound_int(arr, dim);
944       if (next == upper) next = get_array_lower_bound_int(arr, dim);
945     }
946   } else {
947     next = PTR_TO_INT(get_entity_link(elem_ent)) - 1;
948     if (has_array_lower_bound(arr, dim)) {
949       int upper = get_array_upper_bound_int(arr, dim);
950       if (next == upper) next = get_array_upper_bound_int(arr, dim);
951     }
952   }
953
954   set_entity_link(elem_ent, INT_TO_PTR(next));
955   return next;
956 }
957
958 /* Compute the array indices in compound graph paths of initialized entities.
959  *
960  *  All arrays must have fixed lower and upper bounds.  One array can
961  *  have an open bound.  If there are several open bounds, we do
962  *  nothing.  There must be initializer elements for all array
963  *  elements.  Uses the link field in the array element entities.  The
964  *  array bounds must be representable as ints.
965  *
966  *  (If the bounds are not representable as ints we have to represent
967  *  the indices as firm nodes.  But still we must be able to
968  *  evaluate the index against the upper bound.)
969  */
970 void compute_compound_ent_array_indicees(entity *ent) {
971   ir_type *tp = get_entity_type(ent);
972   int i, n_vals;
973   entity *unknown_bound_entity = NULL;
974
975   if (!is_compound_type(tp) ||
976       (ent->variability == variability_uninitialized)) return ;
977
978   n_vals = get_compound_ent_n_values(ent);
979   if (n_vals == 0) return;
980
981   /* We can not compute the indexes if there is more than one array
982      with an unknown bound.  For this remember the first entity that
983      represents such an array. It could be ent. */
984   if (is_Array_type(tp)) {
985     int dim = 0;
986
987     assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
988     if (!has_array_lower_bound(tp, dim) || !has_array_upper_bound(tp, dim))
989      unknown_bound_entity = ent;
990   }
991
992   /* Initialize the entity links to lower bound -1 and test all path elements
993      for known bounds. */
994   for (i = 0; i < n_vals; ++i) {
995     compound_graph_path *path = get_compound_ent_value_path(ent, i);
996     int j, path_len =  get_compound_graph_path_length(path);
997     for (j = 0; j < path_len; ++j) {
998       entity *node = get_compound_graph_path_node(path, j);
999       ir_type *elem_tp = get_entity_type(node);
1000
1001       if (is_Array_type(elem_tp)) {
1002         int dim = 0;
1003         assert(get_array_n_dimensions(elem_tp) == 1 && "other not implemented");
1004         if (!has_array_lower_bound(elem_tp, dim) || !has_array_upper_bound(elem_tp, dim)) {
1005           if (!unknown_bound_entity) unknown_bound_entity = node;
1006           if (node != unknown_bound_entity) return;
1007         }
1008
1009         init_index(elem_tp);
1010       }
1011     }
1012   }
1013
1014   /* Finally compute the indexes ... */
1015   for (i = 0; i < n_vals; ++i) {
1016     compound_graph_path *path = get_compound_ent_value_path(ent, i);
1017     int j, path_len =  get_compound_graph_path_length(path);
1018     for (j = 0; j < path_len; ++j) {
1019       entity *node = get_compound_graph_path_node(path, j);
1020       ir_type *owner_tp = get_entity_owner(node);
1021       if (is_Array_type(owner_tp))
1022         set_compound_graph_path_array_index (path, j, get_next_index(node));
1023     }
1024   }
1025 }
1026
1027 /** resize: double the allocated buffer */
1028 static int *resize (int *buf, int *size) {
1029   int new_size =  *size * 2;
1030   int *new_buf = xcalloc(new_size, sizeof(new_buf[0]));
1031   memcpy(new_buf, buf, *size);
1032   free(buf);
1033   *size = new_size;
1034   return new_buf;
1035 }
1036
1037 /* We sort the elements by placing them at their bit offset in an
1038    array where each entry represents one bit called permutation.  In
1039    fact, we do not place the values themselves, as we would have to
1040    copy two things, the value and the path.  We only remember the
1041    position in the old order. Each value should have a distinct
1042    position in the permutation.
1043
1044    A second iteration now permutes the actual elements into two
1045    new arrays. */
1046 void sort_compound_ent_values(entity *ent) {
1047   ir_type *tp;
1048   int i, n_vals;
1049   int tp_size;
1050   int size;
1051   int *permutation;
1052
1053   int next;
1054   ir_node **my_values;
1055   compound_graph_path **my_paths;
1056
1057   assert(get_type_state(get_entity_type(ent)) == layout_fixed);
1058
1059   tp      = get_entity_type(ent);
1060   n_vals  = get_compound_ent_n_values(ent);
1061   tp_size = get_type_size_bits(tp);
1062
1063   if (!is_compound_type(tp)                           ||
1064       (ent->variability == variability_uninitialized) ||
1065       (get_type_state(tp) != layout_fixed)            ||
1066       (n_vals == 0)                                     ) return;
1067
1068   /* estimated upper bound for size. Better: use flexible array ... */
1069   size = ((tp_size > (n_vals * 32)) ? tp_size : (n_vals * 32)) * 4;
1070   permutation = xcalloc(size, sizeof(permutation[0]));
1071
1072   for (i = 0; i < n_vals; ++i) {
1073     int pos = get_compound_ent_value_offset_bits(ent, i);
1074     while (pos >= size) {
1075       permutation = resize(permutation, &size);
1076     }
1077     assert(pos < size);
1078     assert(permutation[pos] == 0 && "two values with the same offset");
1079     permutation[pos] = i + 1;         /* We initialized with 0, so we can not distinguish entry 0.
1080                      So inc all entries by one. */
1081     //fprintf(stderr, "i: %d, pos: %d \n", i, pos);
1082   }
1083
1084   next = 0;
1085   my_values = NEW_ARR_F(ir_node *, n_vals);
1086   my_paths  = NEW_ARR_F(compound_graph_path *, n_vals);
1087   for (i = 0; i < size; ++i) {
1088     int pos = permutation[i];
1089     if (pos) {
1090       //fprintf(stderr, "pos: %d i: %d  next %d \n", i, pos, next);
1091       assert(next < n_vals);
1092       pos--;   /* We increased the pos by one */
1093       my_values[next] = get_compound_ent_value     (ent, pos);
1094       my_paths [next] = get_compound_ent_value_path(ent, pos);
1095       next++;
1096     }
1097   }
1098   free(permutation);
1099
1100   DEL_ARR_F(ent->attr.cmpd_attr.values);
1101   ent->attr.cmpd_attr.values = my_values;
1102   DEL_ARR_F(ent->attr.cmpd_attr.val_paths);
1103   ent->attr.cmpd_attr.val_paths = my_paths;
1104 }
1105
1106 int
1107 (get_entity_offset_bytes)(const entity *ent) {
1108   return _get_entity_offset_bytes(ent);
1109 }
1110
1111 int
1112 (get_entity_offset_bits)(const entity *ent) {
1113   return _get_entity_offset_bits(ent);
1114 }
1115
1116 void
1117 (set_entity_offset_bytes)(entity *ent, int offset) {
1118   _set_entity_offset_bytes(ent, offset);
1119 }
1120
1121 void
1122 (set_entity_offset_bits)(entity *ent, int offset) {
1123   _set_entity_offset_bits(ent, offset);
1124 }
1125
1126 void
1127 add_entity_overwrites(entity *ent, entity *overwritten) {
1128   assert(ent && is_Class_type(get_entity_owner(ent)));
1129   ARR_APP1(entity *, ent->overwrites, overwritten);
1130   ARR_APP1(entity *, overwritten->overwrittenby, ent);
1131 }
1132
1133 int
1134 get_entity_n_overwrites(entity *ent) {
1135   assert(ent && is_Class_type(get_entity_owner(ent)));
1136   return (ARR_LEN(ent->overwrites));
1137 }
1138
1139 int
1140 get_entity_overwrites_index(entity *ent, entity *overwritten) {
1141   int i;
1142   assert(ent && is_Class_type(get_entity_owner(ent)));
1143   for (i = 0; i < get_entity_n_overwrites(ent); i++)
1144     if (get_entity_overwrites(ent, i) == overwritten)
1145       return i;
1146   return -1;
1147 }
1148
1149 entity *
1150 get_entity_overwrites   (entity *ent, int pos) {
1151   assert(ent && is_Class_type(get_entity_owner(ent)));
1152   assert(pos < get_entity_n_overwrites(ent));
1153   return ent->overwrites[pos];
1154 }
1155
1156 void
1157 set_entity_overwrites   (entity *ent, int pos, entity *overwritten) {
1158   assert(ent && is_Class_type(get_entity_owner(ent)));
1159   assert(pos < get_entity_n_overwrites(ent));
1160   ent->overwrites[pos] = overwritten;
1161 }
1162
1163 void
1164 remove_entity_overwrites(entity *ent, entity *overwritten) {
1165   int i;
1166   assert(ent && is_Class_type(get_entity_owner(ent)));
1167   for (i = 0; i < (ARR_LEN (ent->overwrites)); i++)
1168     if (ent->overwrites[i] == overwritten) {
1169       for(; i < (ARR_LEN (ent->overwrites))-1; i++)
1170     ent->overwrites[i] = ent->overwrites[i+1];
1171       ARR_SETLEN(entity*, ent->overwrites, ARR_LEN(ent->overwrites) - 1);
1172       break;
1173     }
1174 }
1175
1176 void
1177 add_entity_overwrittenby   (entity *ent, entity *overwrites) {
1178   assert(ent && is_Class_type(get_entity_owner(ent)));
1179   add_entity_overwrites(overwrites, ent);
1180 }
1181
1182 int
1183 get_entity_n_overwrittenby (entity *ent) {
1184   assert(ent && is_Class_type(get_entity_owner(ent)));
1185   return (ARR_LEN (ent->overwrittenby));
1186 }
1187
1188 int
1189 get_entity_overwrittenby_index(entity *ent, entity *overwrites) {
1190   int i;
1191   assert(ent && is_Class_type(get_entity_owner(ent)));
1192   for (i = 0; i < get_entity_n_overwrittenby(ent); i++)
1193     if (get_entity_overwrittenby(ent, i) == overwrites)
1194       return i;
1195   return -1;
1196 }
1197
1198 entity *
1199 get_entity_overwrittenby   (entity *ent, int pos) {
1200   assert(ent && is_Class_type(get_entity_owner(ent)));
1201   assert(pos < get_entity_n_overwrittenby(ent));
1202   return ent->overwrittenby[pos];
1203 }
1204
1205 void
1206 set_entity_overwrittenby   (entity *ent, int pos, entity *overwrites) {
1207   assert(ent && is_Class_type(get_entity_owner(ent)));
1208   assert(pos < get_entity_n_overwrittenby(ent));
1209   ent->overwrittenby[pos] = overwrites;
1210 }
1211
1212 void    remove_entity_overwrittenby(entity *ent, entity *overwrites) {
1213   int i;
1214   assert(ent  && is_Class_type(get_entity_owner(ent)));
1215   for (i = 0; i < (ARR_LEN (ent->overwrittenby)); i++)
1216     if (ent->overwrittenby[i] == overwrites) {
1217       for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
1218     ent->overwrittenby[i] = ent->overwrittenby[i+1];
1219       ARR_SETLEN(entity*, ent->overwrittenby, ARR_LEN(ent->overwrittenby) - 1);
1220       break;
1221     }
1222 }
1223
1224 /* A link to store intermediate information */
1225 void *
1226 (get_entity_link)(const entity *ent) {
1227   return _get_entity_link(ent);
1228 }
1229
1230 void
1231 (set_entity_link)(entity *ent, void *l) {
1232   _set_entity_link(ent, l);
1233 }
1234
1235 ir_graph *
1236 (get_entity_irg)(const entity *ent) {
1237   return _get_entity_irg(ent);
1238 }
1239
1240 void
1241 set_entity_irg(entity *ent, ir_graph *irg) {
1242   assert(ent && is_method_entity(ent));
1243   /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
1244    * Methode selbst nicht mehr aufgerufen werden kann, die Entität
1245    * aber erhalten bleiben soll?  Wandle die Entitaet in description oder
1246    * inherited um! */
1247   /* assert(irg); */
1248   assert((irg  && ent->peculiarity == peculiarity_existent) ||
1249          (!irg && (ent->peculiarity == peculiarity_existent)
1250           && (ent -> visibility == visibility_external_allocated)) ||
1251          (!irg && ent->peculiarity == peculiarity_description) ||
1252          (!irg && ent->peculiarity == peculiarity_inherited));
1253   ent->attr.mtd_attr.irg = irg;
1254 }
1255
1256 unsigned get_entity_vtable_number(entity *ent) {
1257   assert(ent && is_method_entity(ent));
1258   return ent->attr.mtd_attr.vtable_number;
1259 }
1260
1261 void set_entity_vtable_number(entity *ent, unsigned vtable_number) {
1262   assert(ent && is_method_entity(ent));
1263   ent->attr.mtd_attr.vtable_number = vtable_number;
1264 }
1265
1266 int
1267 (is_entity)(const void *thing) {
1268   return _is_entity(thing);
1269 }
1270
1271 int is_atomic_entity(entity *ent) {
1272   ir_type *t = get_entity_type(ent);
1273   assert(ent && ent->kind == k_entity);
1274   return (is_Primitive_type(t) || is_Pointer_type(t) ||
1275       is_Enumeration_type(t) || is_Method_type(t));
1276 }
1277
1278 int is_compound_entity(entity *ent) {
1279   ir_type *t = get_entity_type(ent);
1280   assert(ent && ent->kind == k_entity);
1281   return (is_Class_type(t) || is_Struct_type(t) ||
1282       is_Array_type(t) || is_Union_type(t));
1283 }
1284
1285 int is_method_entity(entity *ent) {
1286   ir_type *t = get_entity_type(ent);
1287   assert(ent && ent->kind == k_entity);
1288   return (is_Method_type(t));
1289 }
1290
1291 /**
1292  * @todo not implemented!!! */
1293 int equal_entity(entity *ent1, entity *ent2) {
1294   fprintf(stderr, " calling unimplemented equal entity!!! \n");
1295   return 1;
1296 }
1297
1298
1299 unsigned long (get_entity_visited)(entity *ent) {
1300   return _get_entity_visited(ent);
1301 }
1302
1303 void (set_entity_visited)(entity *ent, unsigned long num) {
1304   _set_entity_visited(ent, num);
1305 }
1306
1307 /* Sets visited field in entity to entity_visited. */
1308 void (mark_entity_visited)(entity *ent) {
1309   _mark_entity_visited(ent);
1310 }
1311
1312 int (entity_visited)(entity *ent) {
1313   return _entity_visited(ent);
1314 }
1315
1316 int (entity_not_visited)(entity *ent) {
1317   return _entity_not_visited(ent);
1318 }
1319
1320 /* Returns the mask of the additional entity properties. */
1321 unsigned get_entity_additional_properties(entity *ent) {
1322   ir_graph *irg;
1323
1324   assert(is_method_entity(ent));
1325
1326   /* first check, if the graph has additional properties */
1327   irg = get_entity_irg(ent);
1328
1329   if (irg)
1330     return get_irg_additional_properties(irg);
1331
1332   if (ent->attr.mtd_attr.irg_add_properties & mtp_property_inherited)
1333     return get_method_additional_properties(get_entity_type(ent));
1334
1335   return ent->attr.mtd_attr.irg_add_properties;
1336 }
1337
1338 /* Sets the mask of the additional graph properties. */
1339 void set_entity_additional_properties(entity *ent, unsigned property_mask)
1340 {
1341   ir_graph *irg;
1342
1343   assert(is_method_entity(ent));
1344
1345   /* first check, if the graph exists */
1346   irg = get_entity_irg(ent);
1347   if (irg)
1348     set_irg_additional_properties(irg, property_mask);
1349   else {
1350     /* do not allow to set the mtp_property_inherited flag or
1351      * the automatic inheritance of flags will not work */
1352     ent->attr.mtd_attr.irg_add_properties = property_mask & ~mtp_property_inherited;
1353   }
1354 }
1355
1356 /* Sets one additional graph property. */
1357 void set_entity_additional_property(entity *ent, mtp_additional_property flag)
1358 {
1359   ir_graph *irg;
1360
1361   assert(is_method_entity(ent));
1362
1363   /* first check, if the graph exists */
1364   irg = get_entity_irg(ent);
1365   if (irg)
1366     set_irg_additional_property(irg, flag);
1367   else {
1368     unsigned mask = ent->attr.mtd_attr.irg_add_properties;
1369
1370     if (mask & mtp_property_inherited)
1371       mask = get_method_additional_properties(get_entity_type(ent));
1372
1373     /* do not allow to set the mtp_property_inherited flag or
1374      * the automatic inheritance of flags will not work */
1375     ent->attr.mtd_attr.irg_add_properties = mask | (flag & ~mtp_property_inherited);
1376   }
1377 }
1378
1379 /* Initialize entity module. */
1380 void firm_init_entity(void)
1381 {
1382   symconst_symbol sym;
1383
1384   assert(firm_unknown_type && "Call init_type() before firm_init_entity()!");
1385   assert(!unknown_entity && "Call firm_init_entity() only once!");
1386
1387   unknown_entity = new_rd_entity(NULL, firm_unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), firm_unknown_type);
1388   set_entity_visibility(unknown_entity, visibility_external_allocated);
1389   set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity));
1390
1391   current_ir_graph      = get_const_code_irg();
1392   sym.entity_p          = unknown_entity;
1393   unknown_entity->value = new_SymConst(sym, symconst_addr_ent);
1394 }