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