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