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
9 * Copyright: (c) 1998-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
13 #include "firm_common_t.h"
19 # include "entity_t.h"
21 # include "typegmod.h"
24 /* All this is needed to build the constant node for methods: */
25 # include "irprog_t.h"
30 # include "irdump.h" /* for output if errors occur. */
33 # include "callgraph.h" /* for dumping debug output */
35 /*******************************************************************/
37 /*******************************************************************/
44 /*-----------------------------------------------------------------*/
46 /*-----------------------------------------------------------------*/
48 static void insert_entity_in_owner (entity *ent) {
49 type *owner = ent->owner;
50 switch (get_type_tpop_code(owner)) {
52 add_class_member (owner, ent);
55 add_struct_member (owner, ent);
58 add_union_member (owner, ent);
61 set_array_element_entity(owner, ent);
68 new_entity (type *owner, ident *name, type *type)
73 assert(!id_contains_char(name, ' ') && "entity name should not contain spaces");
75 res = (entity *) xmalloc (sizeof (entity));
77 assert_legal_owner_of_ent(owner);
82 if (get_type_tpop(type) == type_method)
83 res->allocation = allocation_static;
85 res->allocation = allocation_automatic;
87 res->visibility = visibility_local;
89 if (is_method_type(type)) {
92 res->variability = variability_constant;
93 rem = current_ir_graph;
94 current_ir_graph = get_const_code_irg();
95 res->value = new_SymConst(sym, symconst_addr_ent);
96 current_ir_graph = rem;
98 res->variability = variability_uninitialized;
101 res->val_paths = NULL;
103 res->peculiarity = peculiarity_existent;
104 res->volatility = volatility_non_volatile;
105 res->stickyness = stickyness_unsticky;
107 if (is_class_type(owner)) {
108 res->overwrites = NEW_ARR_F(entity *, 0);
109 res->overwrittenby = NEW_ARR_F(entity *, 0);
111 res->overwrites = NULL;
112 res->overwrittenby = NULL;
116 res->accesses = NULL;
119 res->nr = get_irp_new_node_nr();
120 res->c_name = (char*) get_id_str (name);
121 #endif /* DEBUG_libfirm */
125 /* Remember entity in it's owner. */
126 insert_entity_in_owner (res);
130 new_d_entity (type *owner, ident *name, type *type, dbg_info *db) {
131 entity *res = new_entity(owner, name, type);
132 set_entity_dbg_info(res, db);
136 static void free_entity_attrs(entity *ent) {
138 if (get_type_tpop(get_entity_owner(ent)) == type_class) {
139 DEL_ARR_F(ent->overwrites); ent->overwrites = NULL;
140 DEL_ARR_F(ent->overwrittenby); ent->overwrittenby = NULL;
142 assert(ent->overwrites == NULL);
143 assert(ent->overwrittenby == NULL);
145 /* if (ent->values) DEL_ARR_F(ent->values); *//* @@@ warum nich? */
146 if (ent->val_paths) {
147 if (is_compound_entity(ent))
148 for (i = 0; i < get_compound_ent_n_values(ent); i++)
149 if (ent->val_paths[i]) ;
150 /* free_compound_graph_path(ent->val_paths[i]) ; * @@@ warum nich? */
151 /* Geht nich: wird mehrfach verwendet!!! ==> mehrfach frei gegeben. */
152 /* DEL_ARR_F(ent->val_paths); */
154 ent->val_paths = NULL;
159 copy_entity_own (entity *old, type *new_owner) {
161 assert(old && old->kind == k_entity);
162 assert_legal_owner_of_ent(new_owner);
164 if (old->owner == new_owner) return old;
165 new = (entity *) xmalloc (sizeof (entity));
166 memcpy (new, old, sizeof (entity));
167 new->owner = new_owner;
168 if (is_class_type(new_owner)) {
169 new->overwrites = NEW_ARR_F(entity *, 0);
170 new->overwrittenby = NEW_ARR_F(entity *, 0);
173 new->nr = get_irp_new_node_nr();
176 insert_entity_in_owner (new);
182 copy_entity_name (entity *old, ident *new_name) {
184 assert(old && old->kind == k_entity);
186 if (old->name == new_name) return old;
187 new = (entity *) xmalloc (sizeof (entity));
188 memcpy (new, old, sizeof (entity));
189 new->name = new_name;
191 if (is_class_type(new->owner)) {
192 new->overwrites = DUP_ARR_F(entity *, old->overwrites);
193 new->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
196 new->nr = get_irp_new_node_nr();
197 new->c_name = get_id_str (new->name);
200 insert_entity_in_owner (new);
207 free_entity (entity *ent) {
208 assert(ent && ent->kind == k_entity);
209 free_entity_attrs(ent);
214 /* Outputs a unique number for this node */
216 get_entity_nr(entity *ent) {
217 assert(ent && ent->kind == k_entity);
226 (get_entity_name)(const entity *ent) {
227 return __get_entity_name(ent);
231 (get_entity_ident)(const entity *ent) {
232 return get_entity_ident(ent);
236 void set_entitye_ld_name (entity *, char *ld_name);
237 void set_entity_ld_ident (entity *, ident *ld_ident);
241 (get_entity_owner)(entity *ent) {
242 return __get_entity_owner(ent);
246 set_entity_owner (entity *ent, type *owner) {
247 assert(ent && ent->kind == k_entity);
248 assert_legal_owner_of_ent(owner);
252 void /* should this go into type.c? */
253 assert_legal_owner_of_ent(type *owner) {
254 assert(get_type_tpop_code(owner) == tpo_class ||
255 get_type_tpop_code(owner) == tpo_union ||
256 get_type_tpop_code(owner) == tpo_struct ||
257 get_type_tpop_code(owner) == tpo_array); /* Yes, array has an entity
258 -- to select fields! */
262 (get_entity_ld_ident)(entity *ent) {
263 return __get_entity_ld_ident(ent);
267 (set_entity_ld_ident)(entity *ent, ident *ld_ident) {
268 __set_entity_ld_ident(ent, ld_ident);
272 (get_entity_ld_name)(entity *ent) {
273 return __get_entity_ld_name(ent);
277 (get_entity_type)(entity *ent) {
278 return __get_entity_type(ent);
282 (set_entity_type)(entity *ent, type *type) {
283 __set_entity_type(ent, type);
287 (get_entity_allocation)(const entity *ent) {
288 return __get_entity_allocation(ent);
292 (set_entity_allocation)(entity *ent, ent_allocation al) {
293 __set_entity_allocation(ent, al);
296 /* return the name of the visibility */
297 const char *get_allocation_name(ent_allocation all)
299 #define X(a) case a: return #a
301 X(allocation_automatic);
302 X(allocation_parameter);
303 X(allocation_dynamic);
304 X(allocation_static);
305 default: return "BAD VALUE";
312 (get_entity_visibility)(const entity *ent) {
313 return __get_entity_visibility(ent);
317 set_entity_visibility (entity *ent, ent_visibility vis) {
318 assert(ent && ent->kind == k_entity);
319 if (vis != visibility_local)
320 assert((ent->allocation == allocation_static) ||
321 (ent->allocation == allocation_automatic));
322 /* @@@ Test that the owner type is not local, but how??
323 && get_class_visibility(get_entity_owner(ent)) != local));*/
324 ent->visibility = vis;
327 /* return the name of the visibility */
328 const char *get_visibility_name(ent_visibility vis)
330 #define X(a) case a: return #a
333 X(visibility_external_visible);
334 X(visibility_external_allocated);
335 default: return "BAD VALUE";
341 (get_entity_variability)(const entity *ent) {
342 return __get_entity_variability(ent);
346 set_entity_variability (entity *ent, ent_variability var)
348 assert(ent && ent->kind == k_entity);
349 if (var == variability_part_constant)
350 assert(is_class_type(ent->type) || is_struct_type(ent->type));
352 if ((is_compound_type(ent->type)) &&
353 (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
354 /* Allocate datastructures for constant values */
355 ent->values = NEW_ARR_F(ir_node *, 0);
356 ent->val_paths = NEW_ARR_F(compound_graph_path *, 0);
358 if ((is_atomic_type(ent->type)) &&
359 (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
360 /* Set default constant value. */
361 ent->value = new_rd_Unknown(get_const_code_irg(), get_type_mode(ent->type));
364 if ((is_compound_type(ent->type)) &&
365 (var == variability_uninitialized) && (ent->variability != variability_uninitialized)) {
366 /* Free datastructures for constant values */
367 DEL_ARR_F(ent->values); ent->values = NULL;
368 DEL_ARR_F(ent->val_paths); ent->val_paths = NULL;
370 ent->variability = var;
373 /* return the name of the variablity */
374 const char *get_variability_name(ent_variability var)
376 #define X(a) case a: return #a
378 X(variability_uninitialized);
379 X(variability_initialized);
380 X(variability_part_constant);
381 X(variability_constant);
382 default: return "BAD VALUE";
388 (get_entity_volatility)(const entity *ent) {
389 return __get_entity_volatility(ent);
393 (set_entity_volatility)(entity *ent, ent_volatility vol) {
394 __set_entity_volatility(ent, vol);
397 /* return the name of the volatility */
398 const char *get_volatility_name(ent_volatility var)
400 #define X(a) case a: return #a
402 X(volatility_non_volatile);
403 X(volatility_is_volatile);
404 default: return "BAD VALUE";
410 (get_entity_peculiarity)(const entity *ent) {
411 return __get_entity_peculiarity(ent);
415 (set_entity_peculiarity)(entity *ent, peculiarity pec) {
416 __set_entity_peculiarity(ent, pec);
419 /* return the name of the peculiarity */
420 const char *get_peculiarity_name(peculiarity var)
422 #define X(a) case a: return #a
424 X(peculiarity_description);
425 X(peculiarity_inherited);
426 X(peculiarity_existent);
427 default: return "BAD VALUE";
432 /* Get the entity's stickyness */
434 (get_entity_stickyness)(const entity *ent) {
435 return __get_entity_stickyness(ent);
438 /* Set the entity's stickyness */
440 (set_entity_stickyness)(entity *ent, ent_stickyness stickyness) {
441 __set_entity_stickyness(ent, stickyness);
444 /* Set has no effect for existent entities of type method. */
446 get_atomic_ent_value(entity *ent)
448 assert(ent && is_atomic_entity(ent));
449 assert(ent->variability != variability_uninitialized);
450 return skip_Id (ent->value);
454 set_atomic_ent_value(entity *ent, ir_node *val) {
455 assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized));
456 if (is_method_type(ent->type) && (ent->peculiarity == peculiarity_existent))
461 /* Returns true if the the node is representable as code on
463 int is_irn_const_expression(ir_node *n) {
466 /* we are in dange iff an exception will arise. TODO: be more precisely,
467 * for instance Div. will NOT rise if divisor != 0
469 if (is_binop(n) && !is_fragile_op(n))
470 return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));
473 switch(get_irn_opcode(n)) {
480 return is_irn_const_expression(get_irn_n(n, 0));
489 ir_node *copy_const_value(ir_node *n) {
493 /* @@@ GL I think we should implement this using the routines from irgopt for
494 dead node elimination/inlineing. */
497 switch(get_irn_opcode(n)) {
499 nn = new_Const(m, get_Const_tarval(n)); set_Const_type(nn, get_Const_type(n));
500 //nn = new_rd_Const_type(get_irn_dbg_info(n), current_ir_graph, get_cur_block(),
501 // m, get_Const_tarval(n), get_Const_type(n));
504 nn = new_d_SymConst_type(NULL, get_SymConst_symbol(n), get_SymConst_kind(n),
505 get_SymConst_value_type(n));
508 nn = new_Add(copy_const_value(get_Add_left(n)),
509 copy_const_value(get_Add_right(n)), m); break;
511 nn = new_Sub(copy_const_value(get_Sub_left(n)),
512 copy_const_value(get_Sub_right(n)), m); break;
514 nn = new_Mul(copy_const_value(get_Mul_left(n)),
515 copy_const_value(get_Mul_right(n)), m); break;
517 nn = new_And(copy_const_value(get_And_left(n)),
518 copy_const_value(get_And_right(n)), m); break;
520 nn = new_Or(copy_const_value(get_Or_left(n)),
521 copy_const_value(get_Or_right(n)), m); break;
523 nn = new_Eor(copy_const_value(get_Eor_left(n)),
524 copy_const_value(get_Eor_right(n)), m); break;
526 nn = new_Cast(copy_const_value(get_Cast_op(n)), get_Cast_type(n)); break;
528 nn = new_Conv(copy_const_value(get_Conv_op(n)), m); break;
530 nn = new_Unknown(m); break;
533 assert(0 && "opcode invalid or not implemented");
540 compound_graph_path *
541 new_compound_graph_path(type *tp, int length) {
542 compound_graph_path *res;
543 assert(is_type(tp) && is_compound_type(tp));
546 res = (compound_graph_path *) calloc (1, sizeof(compound_graph_path) + (length-1) * sizeof(entity *));
547 res->kind = k_ir_compound_graph_path;
550 res ->arr_indicees = (int *) calloc(length, sizeof(int));
555 free_compound_graph_path (compound_graph_path *gr) {
556 assert(gr && is_compound_graph_path(gr));
558 free(gr ->arr_indicees);
563 is_compound_graph_path(void *thing) {
564 return (get_kind(thing) == k_ir_compound_graph_path);
567 /* checks whether nodes 0..pos are correct (all lie on a path.) */
568 /* @@@ not implemented */
569 int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
572 type *owner = gr->tp;
573 for (i = 0; i <= pos; i++) {
574 node = get_compound_graph_path_node(gr, i);
575 if (get_entity_owner(node) != owner) return false;
576 owner = get_entity_type(node);
578 if (pos == get_compound_graph_path_length(gr))
579 if (!is_atomic_type(owner)) return false;
584 get_compound_graph_path_length(compound_graph_path *gr) {
585 assert(gr && is_compound_graph_path(gr));
590 get_compound_graph_path_node(compound_graph_path *gr, int pos) {
591 assert(gr && is_compound_graph_path(gr));
592 assert(pos >= 0 && pos < gr->len);
593 return gr->nodes[pos];
597 set_compound_graph_path_node(compound_graph_path *gr, int pos, entity *node) {
598 assert(gr && is_compound_graph_path(gr));
599 assert(pos >= 0 && pos < gr->len);
600 assert(is_entity(node));
601 gr->nodes[pos] = node;
602 assert(is_proper_compound_graph_path(gr, pos));
606 get_compound_graph_path_array_index(compound_graph_path *gr, int pos) {
607 assert(gr && is_compound_graph_path(gr));
608 assert(pos >= 0 && pos < gr->len);
609 return gr->arr_indicees[pos];
613 set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index) {
614 assert(gr && is_compound_graph_path(gr));
615 assert(pos >= 0 && pos < gr->len);
616 gr->arr_indicees[pos] = index;
619 /* A value of a compound entity is a pair of value and the corresponding path to a member of
622 add_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path) {
623 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
624 ARR_APP1 (ir_node *, ent->values, val);
625 ARR_APP1 (compound_graph_path *, ent->val_paths, path);
629 set_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path, int pos) {
630 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
631 ent->values[pos] = val;
632 ent->val_paths[pos] = path;
636 get_compound_ent_n_values(entity *ent) {
637 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
638 return (ARR_LEN (ent->values));
642 get_compound_ent_value(entity *ent, int pos) {
643 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
644 return ent->values[pos];
647 compound_graph_path *
648 get_compound_ent_value_path(entity *ent, int pos) {
649 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
650 return ent->val_paths[pos];
654 remove_compound_ent_value(entity *ent, entity *value_ent) {
656 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
657 for (i = 0; i < (ARR_LEN (ent->val_paths)); i++) {
658 compound_graph_path *path = ent->val_paths[i];
659 if (path->nodes[path->len-1] == value_ent) {
660 for(; i < (ARR_LEN (ent->val_paths))-1; i++) {
661 ent->val_paths[i] = ent->val_paths[i+1];
662 ent->values[i] = ent->values[i+1];
664 ARR_SETLEN(entity*, ent->val_paths, ARR_LEN(ent->val_paths) - 1);
665 ARR_SETLEN(ir_node*, ent->values, ARR_LEN(ent->values) - 1);
672 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
673 compound_graph_path *path;
674 type *owner_tp = get_entity_owner(ent);
675 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
676 path = new_compound_graph_path(owner_tp, 1);
677 path->nodes[0] = member;
678 if (is_array_type(owner_tp)) {
682 assert(get_array_n_dimensions(owner_tp) == 1 && has_array_lower_bound(owner_tp, 0));
683 max = get_array_lower_bound_int(owner_tp, 0) -1;
684 for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
685 int index = get_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0);
690 path->arr_indicees[0] = max + 1;
692 add_compound_ent_value_w_path(ent, val, path);
695 /* Copies the firm subgraph referenced by val to const_code_irg and adds
696 the node as constant initialization to ent.
697 The subgraph may not contain control flow operations.
699 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
700 ir_graph *rem = current_ir_graph;
702 assert(get_entity_variability(ent) != variability_uninitialized);
703 current_ir_graph = get_const_code_irg();
705 val = copy_const_value(val);
706 add_compound_ent_value(ent, val, member);
707 current_ir_graph = rem;
710 /* Copies the value i of the entity to current_block in current_ir_graph.
712 copy_compound_ent_value(entity *ent, int pos) {
713 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
714 return copy_const_value(ent->values[pos+1]);
718 get_compound_ent_value_member(entity *ent, int pos) {
719 compound_graph_path *path;
720 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
721 path = get_compound_ent_value_path(ent, pos);
723 return get_compound_graph_path_node(path, get_compound_graph_path_length(path)-1);
727 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
728 compound_graph_path *path;
729 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
730 path = get_compound_ent_value_path(ent, pos);
731 set_compound_graph_path_node(path, 0, member);
732 set_compound_ent_value_w_path(ent, val, path, pos);
736 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
738 ir_graph *rem = current_ir_graph;
739 type *arrtp = get_entity_type(ent);
741 type *elttp = get_array_element_type(arrtp);
743 assert(is_array_type(arrtp));
744 assert(get_array_n_dimensions(arrtp) == 1);
745 /* One bound is sufficient, the nunmber of constant fields makes the
747 assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
748 assert(get_entity_variability(ent) != variability_uninitialized);
749 current_ir_graph = get_const_code_irg();
751 for (i = 0; i < num_vals; i++) {
752 val = new_Const_type(values[i], elttp);
753 add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
754 set_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0, i);
756 current_ir_graph = rem;
759 int get_compound_ent_value_offset_bits(entity *ent, int pos) {
760 assert(get_type_state(get_entity_type(ent)) == layout_fixed);
762 compound_graph_path *path = get_compound_ent_value_path(ent, pos);
763 int i, path_len = get_compound_graph_path_length(path);
766 for (i = 0; i < path_len; ++i) {
767 entity *node = get_compound_graph_path_node(path, i);
768 type *node_tp = get_entity_type(node);
769 type *owner_tp = get_entity_owner(node);
770 if (is_array_type(owner_tp)) {
771 int size = get_type_size_bits(node_tp);
772 int align = get_type_alignment_bits(node_tp);
776 assert(size % align == 0);
777 /* ansonsten aufrunden */
779 offset += size * get_compound_graph_path_array_index(path, i);
781 offset += get_entity_offset_bits(node);
787 int get_compound_ent_value_offset_bytes(entity *ent, int pos) {
788 int offset = get_compound_ent_value_offset_bits(ent, pos);
789 assert(offset % 8 == 0);
794 static void init_index(type *arr) {
798 assert(get_array_n_dimensions(arr) == 1);
800 if (has_array_lower_bound(arr, dim))
801 init = get_array_lower_bound_int(arr, 0) -1;
803 init = get_array_upper_bound_int(arr, 0) +1;
805 set_entity_link(get_array_element_entity(arr), (void *)init);
809 static int get_next_index(entity *elem_ent) {
810 type *arr = get_entity_owner(elem_ent);
814 assert(get_array_n_dimensions(arr) == 1);
816 if (has_array_lower_bound(arr, dim)) {
817 next = (int)get_entity_link(elem_ent) +1;
818 if (has_array_upper_bound(arr, dim)) {
819 int upper = get_array_upper_bound_int(arr, dim);
820 if (next == upper) next = get_array_lower_bound_int(arr, dim);
823 next = (int)get_entity_link(elem_ent) -1;
824 if (has_array_lower_bound(arr, dim)) {
825 int upper = get_array_upper_bound_int(arr, dim);
826 if (next == upper) next = get_array_upper_bound_int(arr, dim);
830 set_entity_link(elem_ent, (void *)next);
834 /* Compute the array indicees in compound graph paths of initialized entities.
836 * All arrays must have fixed lower and upper bounds. One array can
837 * have an open bound. If there are several open bounds, we do
838 * nothing. There must be initializer elements for all array
839 * elements. Uses the link field in the array element entities. The
840 * array bounds must be representable as ints.
842 * (If the bounds are not representable as ints we have to represent
843 * the indicees as firm nodes. But the still we must be able to
844 * evaluate the index against the upper bound.)
846 void compute_compound_ent_array_indicees(entity *ent) {
847 type *tp = get_entity_type(ent);
849 entity *unknown_bound_entity = NULL;
851 if (!is_compound_type(tp) ||
852 (ent->variability == variability_uninitialized)) return ;
854 n_vals = get_compound_ent_n_values(ent);
855 if (n_vals == 0) return;
857 /* We can not compute the indicees if there is more than one array
858 with an unknown bound. For this remember the first entity that
859 represents such an array. It could be ent. */
860 if (is_array_type(tp)) {
861 assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
863 if (!has_array_lower_bound(tp, dim) || !has_array_upper_bound(tp, dim))
864 unknown_bound_entity = ent;
867 /* Initialize the entity links to lower bound -1 and test all path elements
869 for (i = 0; i < n_vals; ++i) {
870 compound_graph_path *path = get_compound_ent_value_path(ent, i);
871 int j, path_len = get_compound_graph_path_length(path);
872 for (j = 0; j < path_len; ++j) {
873 entity *node = get_compound_graph_path_node(path, j);
874 type *elem_tp = get_entity_type(node);
876 if (is_array_type(elem_tp)) {
877 assert(get_array_n_dimensions(elem_tp) == 1 && "other not implemented");
879 if (!has_array_lower_bound(elem_tp, dim) || !has_array_upper_bound(elem_tp, dim)) {
880 if (!unknown_bound_entity) unknown_bound_entity = node;
881 if (node != unknown_bound_entity) return;
889 /* Finally compute the indicees ... */
890 for (i = 0; i < n_vals; ++i) {
891 compound_graph_path *path = get_compound_ent_value_path(ent, i);
892 int j, path_len = get_compound_graph_path_length(path);
893 for (j = 0; j < path_len; ++j) {
894 entity *node = get_compound_graph_path_node(path, j);
895 type *owner_tp = get_entity_owner(node);
896 if (is_array_type(owner_tp))
897 set_compound_graph_path_array_index (path, j, get_next_index(node));
904 static int *resize (int *buf, int new_size) {
905 int *new_buf = (int *)calloc(new_size, 4);
906 memcpy(new_buf, buf, new_size>1);
911 /* We sort the elements by placing them at their bit offset in an
912 array where each entry represents one bit called permutation. In
913 fact, we do not place the values themselves, as we would have to
914 copy two things, the value and the path. We only remember the
915 position in the old order. Each value should have a distinct
916 position in the permutation.
918 A second iteration now permutes the actual elements into two
920 void sort_compound_ent_values(entity *ent) {
921 assert(get_type_state(get_entity_type(ent)) == layout_fixed);
923 type *tp = get_entity_type(ent);
924 int i, n_vals = get_compound_ent_n_values(ent);
925 int tp_size = get_type_size_bits(tp);
929 if (!is_compound_type(tp) ||
930 (ent->variability == variability_uninitialized) ||
931 (get_type_state(tp) != layout_fixed) ||
932 (n_vals == 0) ) return;
934 /* estimated upper bound for size. Better: use flexible array ... */
935 size = ((tp_size > (n_vals * 32)) ? tp_size : (n_vals * 32)) * 4;
936 permutation = (int *)calloc(size, 4);
937 for (i = 0; i < n_vals; ++i) {
938 int pos = get_compound_ent_value_offset_bits(ent, i);
939 while (pos >= size) {
941 permutation = resize(permutation, size);
944 assert(permutation[pos] == 0 && "two values with the same offset");
945 permutation[pos] = i + 1; /* We initialized with 0, so we can not distinguish entry 0.
946 So inc all entries by one. */
947 //fprintf(stderr, "i: %d, pos: %d \n", i, pos);
951 ir_node **my_values = NEW_ARR_F(ir_node *, n_vals);
952 compound_graph_path **my_paths = NEW_ARR_F(compound_graph_path *, n_vals);
953 for (i = 0; i < size; ++i) {
954 int pos = permutation[i];
956 //fprintf(stderr, "pos: %d i: %d next %d \n", i, pos, next);
957 assert(next < n_vals);
958 pos--; /* We increased the pos by one */
959 my_values[next] = get_compound_ent_value (ent, pos);
960 my_paths [next] = get_compound_ent_value_path(ent, pos);
966 DEL_ARR_F(ent->values);
967 ent->values = my_values;
968 DEL_ARR_F(ent->val_paths);
969 ent->val_paths = my_paths;
973 (get_entity_offset_bytes)(const entity *ent) {
974 return __get_entity_offset_bytes(ent);
978 (get_entity_offset_bits)(const entity *ent) {
979 return __get_entity_offset_bits(ent);
983 (set_entity_offset_bytes)(entity *ent, int offset) {
984 __set_entity_offset_bytes(ent, offset);
988 (set_entity_offset_bits)(entity *ent, int offset) {
989 __set_entity_offset_bits(ent, offset);
993 add_entity_overwrites(entity *ent, entity *overwritten) {
994 assert(ent && is_class_type(get_entity_owner(ent)));
995 ARR_APP1(entity *, ent->overwrites, overwritten);
996 ARR_APP1(entity *, overwritten->overwrittenby, ent);
1000 get_entity_n_overwrites(entity *ent) {
1001 assert(ent && is_class_type(get_entity_owner(ent)));
1002 return (ARR_LEN(ent->overwrites));
1006 get_entity_overwrites_index(entity *ent, entity *overwritten) {
1008 assert(ent && is_class_type(get_entity_owner(ent)));
1009 for (i = 0; i < get_entity_n_overwrites(ent); i++)
1010 if (get_entity_overwrites(ent, i) == overwritten)
1016 get_entity_overwrites (entity *ent, int pos) {
1017 assert(ent && is_class_type(get_entity_owner(ent)));
1018 assert(pos < get_entity_n_overwrites(ent));
1019 return ent->overwrites[pos];
1023 set_entity_overwrites (entity *ent, int pos, entity *overwritten) {
1024 assert(ent && is_class_type(get_entity_owner(ent)));
1025 assert(pos < get_entity_n_overwrites(ent));
1026 ent->overwrites[pos] = overwritten;
1030 remove_entity_overwrites(entity *ent, entity *overwritten) {
1032 assert(ent && is_class_type(get_entity_owner(ent)));
1033 for (i = 0; i < (ARR_LEN (ent->overwrites)); i++)
1034 if (ent->overwrites[i] == overwritten) {
1035 for(; i < (ARR_LEN (ent->overwrites))-1; i++)
1036 ent->overwrites[i] = ent->overwrites[i+1];
1037 ARR_SETLEN(entity*, ent->overwrites, ARR_LEN(ent->overwrites) - 1);
1043 add_entity_overwrittenby (entity *ent, entity *overwrites) {
1044 assert(ent && is_class_type(get_entity_owner(ent)));
1045 add_entity_overwrites(overwrites, ent);
1049 get_entity_n_overwrittenby (entity *ent) {
1050 assert(ent && is_class_type(get_entity_owner(ent)));
1051 return (ARR_LEN (ent->overwrittenby));
1055 get_entity_overwrittenby_index(entity *ent, entity *overwrites) {
1057 assert(ent && is_class_type(get_entity_owner(ent)));
1058 for (i = 0; i < get_entity_n_overwrittenby(ent); i++)
1059 if (get_entity_overwrittenby(ent, i) == overwrites)
1065 get_entity_overwrittenby (entity *ent, int pos) {
1066 assert(ent && is_class_type(get_entity_owner(ent)));
1067 assert(pos < get_entity_n_overwrittenby(ent));
1068 return ent->overwrittenby[pos];
1072 set_entity_overwrittenby (entity *ent, int pos, entity *overwrites) {
1073 assert(ent && is_class_type(get_entity_owner(ent)));
1074 assert(pos < get_entity_n_overwrittenby(ent));
1075 ent->overwrittenby[pos] = overwrites;
1078 void remove_entity_overwrittenby(entity *ent, entity *overwrites) {
1080 assert(ent && is_class_type(get_entity_owner(ent)));
1081 for (i = 0; i < (ARR_LEN (ent->overwrittenby)); i++)
1082 if (ent->overwrittenby[i] == overwrites) {
1083 for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
1084 ent->overwrittenby[i] = ent->overwrittenby[i+1];
1085 ARR_SETLEN(entity*, ent->overwrittenby, ARR_LEN(ent->overwrittenby) - 1);
1090 /* A link to store intermediate information */
1092 (get_entity_link)(const entity *ent) {
1093 return __get_entity_link(ent);
1097 (set_entity_link)(entity *ent, void *l) {
1098 __set_entity_link(ent, l);
1102 (get_entity_irg)(const entity *ent) {
1103 return __get_entity_irg(ent);
1107 set_entity_irg(entity *ent, ir_graph *irg) {
1108 assert(ent && is_method_type(get_entity_type(ent)));
1109 /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
1110 * Methode selbst nicht mehr aufgerufen werden kann, die Entität
1111 * aber erhalten bleiben soll. */
1113 assert((irg && ent->peculiarity == peculiarity_existent) ||
1114 (!irg && ent->peculiarity == peculiarity_description) ||
1115 (!irg && ent->peculiarity == peculiarity_inherited));
1120 (is_entity)(const void *thing) {
1121 return __is_entity(thing);
1124 int is_atomic_entity(entity *ent) {
1125 type* t = get_entity_type(ent);
1126 assert(ent && ent->kind == k_entity);
1127 return (is_primitive_type(t) || is_pointer_type(t) ||
1128 is_enumeration_type(t) || is_method_type(t));
1131 int is_compound_entity(entity *ent) {
1132 type* t = get_entity_type(ent);
1133 assert(ent && ent->kind == k_entity);
1134 return (is_class_type(t) || is_struct_type(t) ||
1135 is_array_type(t) || is_union_type(t));
1139 * @todo not implemnted!!! */
1140 bool equal_entity(entity *ent1, entity *ent2) {
1141 fprintf(stderr, " calling unimplemented equal entity!!! \n");
1146 unsigned long get_entity_visited(entity *ent) {
1147 assert(ent && ent->kind == k_entity);
1150 void set_entity_visited(entity *ent, unsigned long num) {
1151 assert(ent && ent->kind == k_entity);
1154 /* Sets visited field in entity to entity_visited. */
1155 void mark_entity_visited(entity *ent) {
1156 assert(ent && ent->kind == k_entity);
1157 ent->visit = type_visited;
1161 bool entity_visited(entity *ent) {
1162 assert(ent && ent->kind == k_entity);
1163 return get_entity_visited(ent) >= type_visited;
1166 bool entity_not_visited(entity *ent) {
1167 assert(ent && ent->kind == k_entity);
1168 return get_entity_visited(ent) < type_visited;
1171 /* Need two routines because I want to assert the result. */
1172 static entity *resolve_ent_polymorphy2 (type *dynamic_class, entity* static_ent) {
1173 int i, n_overwrittenby;
1176 if (get_entity_owner(static_ent) == dynamic_class) return static_ent;
1178 n_overwrittenby = get_entity_n_overwrittenby(static_ent);
1179 for (i = 0; i < n_overwrittenby; ++i) {
1180 res = resolve_ent_polymorphy2(dynamic_class, get_entity_overwrittenby(static_ent, i));
1187 /** Resolve polymorphy in the inheritance relation.
1189 * Returns the dynamically referenced entity if the static entity and the
1190 * dynamic type are given.
1191 * Search downwards in overwritten tree. */
1192 entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent) {
1194 assert(static_ent && static_ent->kind == k_entity);
1196 res = resolve_ent_polymorphy2(dynamic_class, static_ent);
1199 printf(" Could not find entity "); DDME(static_ent);
1200 printf(" in "); DDMT(dynamic_class);
1202 dump_entity(static_ent);
1203 dump_type(get_entity_owner(static_ent));
1204 dump_type(dynamic_class);