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.
24 #include "firm_common_t.h"
27 # include "entity_t.h"
29 # include "typegmod.h"
32 /* All this is needed to build the constant node for methods: */
33 # include "irprog_t.h"
38 # include "irdump.h" /* for output if errors occur. */
41 # include "callgraph.h" /* for dumping debug output */
43 /*******************************************************************/
45 /*******************************************************************/
47 entity *unknown_entity = NULL; entity *get_unknown_entity(void) { return unknown_entity; }
48 #define UNKNOWN_ENTITY_NAME "unknown_entity"
50 static INLINE entity *
51 new_rd_entity (dbg_info *db, type *owner, ident *name, type *type);
56 assert(unknown_type && "Call init_type before init_entity!");
57 assert(!unknown_entity && "Call init_entity only once!");
58 unknown_entity = new_rd_entity(NULL, unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), unknown_type);
59 set_entity_visibility(unknown_entity, visibility_external_allocated);
60 set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity));
63 sym.entity_p = unknown_entity;
64 current_ir_graph = get_const_code_irg();
65 unknown_entity->value = new_SymConst(sym, symconst_addr_ent);
69 /*-----------------------------------------------------------------*/
71 /*-----------------------------------------------------------------*/
73 static INLINE void insert_entity_in_owner (entity *ent) {
74 type *owner = ent->owner;
75 switch (get_type_tpop_code(owner)) {
77 add_class_member (owner, ent);
80 add_struct_member (owner, ent);
83 add_union_member (owner, ent);
86 set_array_element_entity(owner, ent);
92 static INLINE entity *
93 new_rd_entity (dbg_info *db, type *owner, ident *name, type *type)
98 assert(!id_contains_char(name, ' ') && "entity name should not contain spaces");
100 res = (entity *) xmalloc (sizeof (entity));
101 memset(res, 0, sizeof(res));
102 res->kind = k_entity;
107 if (get_type_tpop(type) == type_method)
108 res->allocation = allocation_static;
110 res->allocation = allocation_automatic;
112 res->visibility = visibility_local;
114 if (is_method_type(type)) {
117 res->variability = variability_constant;
118 rem = current_ir_graph;
119 current_ir_graph = get_const_code_irg();
120 res->value = new_SymConst(sym, symconst_addr_ent);
121 current_ir_graph = rem;
123 res->variability = variability_uninitialized;
126 res->val_paths = NULL;
128 res->peculiarity = peculiarity_existent;
129 res->volatility = volatility_non_volatile;
130 res->stickyness = stickyness_unsticky;
132 if (is_class_type(owner)) {
133 res->overwrites = NEW_ARR_F(entity *, 0);
134 res->overwrittenby = NEW_ARR_F(entity *, 0);
136 res->overwrites = NULL;
137 res->overwrittenby = NULL;
141 //res->accesses = NULL;
144 res->nr = get_irp_new_node_nr();
145 res->c_name = (char *)get_id_str (name);
146 #endif /* DEBUG_libfirm */
149 set_entity_dbg_info(res, db);
155 new_d_entity (type *owner, ident *name, type *type, dbg_info *db) {
156 assert_legal_owner_of_ent(owner);
157 entity *res = new_rd_entity(db, owner, name, type);
158 /* Remember entity in it's owner. */
159 insert_entity_in_owner (res);
165 new_entity (type *owner, ident *name, type *type) {
166 return new_d_entity(owner, name, type, NULL);
172 static void free_entity_attrs(entity *ent) {
174 if (get_type_tpop(get_entity_owner(ent)) == type_class) {
175 DEL_ARR_F(ent->overwrites); ent->overwrites = NULL;
176 DEL_ARR_F(ent->overwrittenby); ent->overwrittenby = NULL;
178 assert(ent->overwrites == NULL);
179 assert(ent->overwrittenby == NULL);
181 /* if (ent->values) DEL_ARR_F(ent->values); *//* @@@ warum nich? */
182 if (ent->val_paths) {
183 if (is_compound_entity(ent))
184 for (i = 0; i < get_compound_ent_n_values(ent); i++)
185 if (ent->val_paths[i]) ;
186 /* free_compound_graph_path(ent->val_paths[i]) ; * @@@ warum nich? */
187 /* Geht nich: wird mehrfach verwendet!!! ==> mehrfach frei gegeben. */
188 /* DEL_ARR_F(ent->val_paths); */
190 ent->val_paths = NULL;
195 copy_entity_own (entity *old, type *new_owner) {
197 assert(old && old->kind == k_entity);
198 assert_legal_owner_of_ent(new_owner);
200 if (old->owner == new_owner) return old;
201 new = (entity *) xmalloc (sizeof (entity));
202 memcpy (new, old, sizeof (entity));
203 new->owner = new_owner;
204 if (is_class_type(new_owner)) {
205 new->overwrites = NEW_ARR_F(entity *, 0);
206 new->overwrittenby = NEW_ARR_F(entity *, 0);
209 new->nr = get_irp_new_node_nr();
212 insert_entity_in_owner (new);
218 copy_entity_name (entity *old, ident *new_name) {
220 assert(old && old->kind == k_entity);
222 if (old->name == new_name) return old;
223 new = (entity *) xmalloc (sizeof (entity));
224 memcpy (new, old, sizeof (entity));
225 new->name = new_name;
227 if (is_class_type(new->owner)) {
228 new->overwrites = DUP_ARR_F(entity *, old->overwrites);
229 new->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
232 new->nr = get_irp_new_node_nr();
233 new->c_name = (char *)get_id_str (new->name);
236 insert_entity_in_owner (new);
243 free_entity (entity *ent) {
244 assert(ent && ent->kind == k_entity);
245 free_entity_attrs(ent);
250 /* Outputs a unique number for this node */
252 get_entity_nr(entity *ent) {
253 assert(ent && ent->kind == k_entity);
262 (get_entity_name)(const entity *ent) {
263 return __get_entity_name(ent);
267 (get_entity_ident)(const entity *ent) {
268 return get_entity_ident(ent);
272 void set_entitye_ld_name (entity *, char *ld_name);
273 void set_entity_ld_ident (entity *, ident *ld_ident);
277 (get_entity_owner)(entity *ent) {
278 return __get_entity_owner(ent);
282 set_entity_owner (entity *ent, type *owner) {
283 assert(ent && ent->kind == k_entity);
284 assert_legal_owner_of_ent(owner);
288 void /* should this go into type.c? */
289 assert_legal_owner_of_ent(type *owner) {
290 assert(get_type_tpop_code(owner) == tpo_class ||
291 get_type_tpop_code(owner) == tpo_union ||
292 get_type_tpop_code(owner) == tpo_struct ||
293 get_type_tpop_code(owner) == tpo_array); /* Yes, array has an entity
294 -- to select fields! */
298 (get_entity_ld_ident)(entity *ent) {
299 return __get_entity_ld_ident(ent);
303 (set_entity_ld_ident)(entity *ent, ident *ld_ident) {
304 __set_entity_ld_ident(ent, ld_ident);
308 (get_entity_ld_name)(entity *ent) {
309 return __get_entity_ld_name(ent);
313 (get_entity_type)(entity *ent) {
314 return __get_entity_type(ent);
318 (set_entity_type)(entity *ent, type *type) {
319 __set_entity_type(ent, type);
323 (get_entity_allocation)(const entity *ent) {
324 return __get_entity_allocation(ent);
328 (set_entity_allocation)(entity *ent, ent_allocation al) {
329 __set_entity_allocation(ent, al);
332 /* return the name of the visibility */
333 const char *get_allocation_name(ent_allocation all)
335 #define X(a) case a: return #a
337 X(allocation_automatic);
338 X(allocation_parameter);
339 X(allocation_dynamic);
340 X(allocation_static);
341 default: return "BAD VALUE";
348 (get_entity_visibility)(const entity *ent) {
349 return __get_entity_visibility(ent);
353 set_entity_visibility (entity *ent, ent_visibility vis) {
354 assert(ent && ent->kind == k_entity);
355 if (vis != visibility_local)
356 assert((ent->allocation == allocation_static) ||
357 (ent->allocation == allocation_automatic));
358 /* @@@ Test that the owner type is not local, but how??
359 && get_class_visibility(get_entity_owner(ent)) != local));*/
360 ent->visibility = vis;
363 /* return the name of the visibility */
364 const char *get_visibility_name(ent_visibility vis)
366 #define X(a) case a: return #a
369 X(visibility_external_visible);
370 X(visibility_external_allocated);
371 default: return "BAD VALUE";
377 (get_entity_variability)(const entity *ent) {
378 return __get_entity_variability(ent);
382 set_entity_variability (entity *ent, ent_variability var)
384 assert(ent && ent->kind == k_entity);
385 if (var == variability_part_constant)
386 assert(is_class_type(ent->type) || is_struct_type(ent->type));
388 if ((is_compound_type(ent->type)) &&
389 (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
390 /* Allocate datastructures for constant values */
391 ent->values = NEW_ARR_F(ir_node *, 0);
392 ent->val_paths = NEW_ARR_F(compound_graph_path *, 0);
394 if ((is_atomic_type(ent->type)) &&
395 (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
396 /* Set default constant value. */
397 ent->value = new_rd_Unknown(get_const_code_irg(), get_type_mode(ent->type));
400 if ((is_compound_type(ent->type)) &&
401 (var == variability_uninitialized) && (ent->variability != variability_uninitialized)) {
402 /* Free datastructures for constant values */
403 DEL_ARR_F(ent->values); ent->values = NULL;
404 DEL_ARR_F(ent->val_paths); ent->val_paths = NULL;
406 ent->variability = var;
409 /* return the name of the variablity */
410 const char *get_variability_name(ent_variability var)
412 #define X(a) case a: return #a
414 X(variability_uninitialized);
415 X(variability_initialized);
416 X(variability_part_constant);
417 X(variability_constant);
418 default: return "BAD VALUE";
424 (get_entity_volatility)(const entity *ent) {
425 return __get_entity_volatility(ent);
429 (set_entity_volatility)(entity *ent, ent_volatility vol) {
430 __set_entity_volatility(ent, vol);
433 /* return the name of the volatility */
434 const char *get_volatility_name(ent_volatility var)
436 #define X(a) case a: return #a
438 X(volatility_non_volatile);
439 X(volatility_is_volatile);
440 default: return "BAD VALUE";
446 (get_entity_peculiarity)(const entity *ent) {
447 return __get_entity_peculiarity(ent);
451 (set_entity_peculiarity)(entity *ent, peculiarity pec) {
452 __set_entity_peculiarity(ent, pec);
455 /* return the name of the peculiarity */
456 const char *get_peculiarity_name(peculiarity var)
458 #define X(a) case a: return #a
460 X(peculiarity_description);
461 X(peculiarity_inherited);
462 X(peculiarity_existent);
463 default: return "BAD VALUE";
468 /* Get the entity's stickyness */
470 (get_entity_stickyness)(const entity *ent) {
471 return __get_entity_stickyness(ent);
474 /* Set the entity's stickyness */
476 (set_entity_stickyness)(entity *ent, ent_stickyness stickyness) {
477 __set_entity_stickyness(ent, stickyness);
480 /* Set has no effect for existent entities of type method. */
482 get_atomic_ent_value(entity *ent)
484 assert(ent && is_atomic_entity(ent));
485 assert(ent->variability != variability_uninitialized);
486 return skip_Id (ent->value);
490 set_atomic_ent_value(entity *ent, ir_node *val) {
491 assert(is_atomic_entity(ent) && (ent->variability != variability_uninitialized));
492 if (is_method_type(ent->type) && (ent->peculiarity == peculiarity_existent))
497 /* Returns true if the the node is representable as code on
499 int is_irn_const_expression(ir_node *n) {
502 /* we are in dange iff an exception will arise. TODO: be more precisely,
503 * for instance Div. will NOT rise if divisor != 0
505 if (is_binop(n) && !is_fragile_op(n))
506 return is_irn_const_expression(get_binop_left(n)) && is_irn_const_expression(get_binop_right(n));
509 switch(get_irn_opcode(n)) {
516 return is_irn_const_expression(get_irn_n(n, 0));
525 ir_node *copy_const_value(ir_node *n) {
529 /* @@@ GL I think we should implement this using the routines from irgopt for
530 dead node elimination/inlineing. */
533 switch(get_irn_opcode(n)) {
535 nn = new_Const(m, get_Const_tarval(n)); set_Const_type(nn, get_Const_type(n));
536 //nn = new_rd_Const_type(get_irn_dbg_info(n), current_ir_graph, get_cur_block(),
537 // m, get_Const_tarval(n), get_Const_type(n));
540 nn = new_d_SymConst_type(NULL, get_SymConst_symbol(n), get_SymConst_kind(n),
541 get_SymConst_value_type(n));
544 nn = new_Add(copy_const_value(get_Add_left(n)),
545 copy_const_value(get_Add_right(n)), m); break;
547 nn = new_Sub(copy_const_value(get_Sub_left(n)),
548 copy_const_value(get_Sub_right(n)), m); break;
550 nn = new_Mul(copy_const_value(get_Mul_left(n)),
551 copy_const_value(get_Mul_right(n)), m); break;
553 nn = new_And(copy_const_value(get_And_left(n)),
554 copy_const_value(get_And_right(n)), m); break;
556 nn = new_Or(copy_const_value(get_Or_left(n)),
557 copy_const_value(get_Or_right(n)), m); break;
559 nn = new_Eor(copy_const_value(get_Eor_left(n)),
560 copy_const_value(get_Eor_right(n)), m); break;
562 nn = new_Cast(copy_const_value(get_Cast_op(n)), get_Cast_type(n)); break;
564 nn = new_Conv(copy_const_value(get_Conv_op(n)), m); break;
566 nn = new_Unknown(m); break;
569 assert(0 && "opcode invalid or not implemented");
576 compound_graph_path *
577 new_compound_graph_path(type *tp, int length) {
578 compound_graph_path *res;
579 assert(is_type(tp) && is_compound_type(tp));
582 res = (compound_graph_path *) calloc (1, sizeof(compound_graph_path) + (length-1) * sizeof(entity *));
583 res->kind = k_ir_compound_graph_path;
586 res ->arr_indicees = (int *) calloc(length, sizeof(int));
591 free_compound_graph_path (compound_graph_path *gr) {
592 assert(gr && is_compound_graph_path(gr));
594 free(gr ->arr_indicees);
599 is_compound_graph_path(void *thing) {
600 return (get_kind(thing) == k_ir_compound_graph_path);
603 /* checks whether nodes 0..pos are correct (all lie on a path.) */
604 /* @@@ not implemented */
605 int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
608 type *owner = gr->tp;
609 for (i = 0; i <= pos; i++) {
610 node = get_compound_graph_path_node(gr, i);
611 if (get_entity_owner(node) != owner) return false;
612 owner = get_entity_type(node);
614 if (pos == get_compound_graph_path_length(gr))
615 if (!is_atomic_type(owner)) return false;
620 get_compound_graph_path_length(compound_graph_path *gr) {
621 assert(gr && is_compound_graph_path(gr));
626 get_compound_graph_path_node(compound_graph_path *gr, int pos) {
627 assert(gr && is_compound_graph_path(gr));
628 assert(pos >= 0 && pos < gr->len);
629 return gr->nodes[pos];
633 set_compound_graph_path_node(compound_graph_path *gr, int pos, entity *node) {
634 assert(gr && is_compound_graph_path(gr));
635 assert(pos >= 0 && pos < gr->len);
636 assert(is_entity(node));
637 gr->nodes[pos] = node;
638 assert(is_proper_compound_graph_path(gr, pos));
642 get_compound_graph_path_array_index(compound_graph_path *gr, int pos) {
643 assert(gr && is_compound_graph_path(gr));
644 assert(pos >= 0 && pos < gr->len);
645 return gr->arr_indicees[pos];
649 set_compound_graph_path_array_index(compound_graph_path *gr, int pos, int index) {
650 assert(gr && is_compound_graph_path(gr));
651 assert(pos >= 0 && pos < gr->len);
652 gr->arr_indicees[pos] = index;
655 /* A value of a compound entity is a pair of value and the corresponding path to a member of
658 add_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path) {
659 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
660 ARR_APP1 (ir_node *, ent->values, val);
661 ARR_APP1 (compound_graph_path *, ent->val_paths, path);
665 set_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path, int pos) {
666 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
667 ent->values[pos] = val;
668 ent->val_paths[pos] = path;
672 get_compound_ent_n_values(entity *ent) {
673 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
674 return (ARR_LEN (ent->values));
678 get_compound_ent_value(entity *ent, int pos) {
679 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
680 return ent->values[pos];
683 compound_graph_path *
684 get_compound_ent_value_path(entity *ent, int pos) {
685 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
686 return ent->val_paths[pos];
690 remove_compound_ent_value(entity *ent, entity *value_ent) {
692 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
693 for (i = 0; i < (ARR_LEN (ent->val_paths)); i++) {
694 compound_graph_path *path = ent->val_paths[i];
695 if (path->nodes[path->len-1] == value_ent) {
696 for(; i < (ARR_LEN (ent->val_paths))-1; i++) {
697 ent->val_paths[i] = ent->val_paths[i+1];
698 ent->values[i] = ent->values[i+1];
700 ARR_SETLEN(entity*, ent->val_paths, ARR_LEN(ent->val_paths) - 1);
701 ARR_SETLEN(ir_node*, ent->values, ARR_LEN(ent->values) - 1);
708 add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
709 compound_graph_path *path;
710 type *owner_tp = get_entity_owner(ent);
711 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
712 path = new_compound_graph_path(owner_tp, 1);
713 path->nodes[0] = member;
714 if (is_array_type(owner_tp)) {
718 assert(get_array_n_dimensions(owner_tp) == 1 && has_array_lower_bound(owner_tp, 0));
719 max = get_array_lower_bound_int(owner_tp, 0) -1;
720 for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
721 int index = get_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0);
726 path->arr_indicees[0] = max + 1;
728 add_compound_ent_value_w_path(ent, val, path);
731 /* Copies the firm subgraph referenced by val to const_code_irg and adds
732 the node as constant initialization to ent.
733 The subgraph may not contain control flow operations.
735 copy_and_add_compound_ent_value(entity *ent, ir_node *val, entity *member) {
736 ir_graph *rem = current_ir_graph;
738 assert(get_entity_variability(ent) != variability_uninitialized);
739 current_ir_graph = get_const_code_irg();
741 val = copy_const_value(val);
742 add_compound_ent_value(ent, val, member);
743 current_ir_graph = rem;
746 /* Copies the value i of the entity to current_block in current_ir_graph.
748 copy_compound_ent_value(entity *ent, int pos) {
749 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
750 return copy_const_value(ent->values[pos+1]);
754 get_compound_ent_value_member(entity *ent, int pos) {
755 compound_graph_path *path;
756 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
757 path = get_compound_ent_value_path(ent, pos);
759 return get_compound_graph_path_node(path, get_compound_graph_path_length(path)-1);
763 set_compound_ent_value(entity *ent, ir_node *val, entity *member, int pos) {
764 compound_graph_path *path;
765 assert(is_compound_entity(ent) && (ent->variability != variability_uninitialized));
766 path = get_compound_ent_value_path(ent, pos);
767 set_compound_graph_path_node(path, 0, member);
768 set_compound_ent_value_w_path(ent, val, path, pos);
772 set_array_entity_values(entity *ent, tarval **values, int num_vals) {
774 ir_graph *rem = current_ir_graph;
775 type *arrtp = get_entity_type(ent);
777 type *elttp = get_array_element_type(arrtp);
779 assert(is_array_type(arrtp));
780 assert(get_array_n_dimensions(arrtp) == 1);
781 /* One bound is sufficient, the nunmber of constant fields makes the
783 assert(get_array_lower_bound (arrtp, 0) || get_array_upper_bound (arrtp, 0));
784 assert(get_entity_variability(ent) != variability_uninitialized);
785 current_ir_graph = get_const_code_irg();
787 for (i = 0; i < num_vals; i++) {
788 val = new_Const_type(values[i], elttp);
789 add_compound_ent_value(ent, val, get_array_element_entity(arrtp));
790 set_compound_graph_path_array_index(get_compound_ent_value_path(ent, i), 0, i);
792 current_ir_graph = rem;
795 int get_compound_ent_value_offset_bits(entity *ent, int pos) {
796 assert(get_type_state(get_entity_type(ent)) == layout_fixed);
798 compound_graph_path *path = get_compound_ent_value_path(ent, pos);
799 int i, path_len = get_compound_graph_path_length(path);
802 for (i = 0; i < path_len; ++i) {
803 entity *node = get_compound_graph_path_node(path, i);
804 type *node_tp = get_entity_type(node);
805 type *owner_tp = get_entity_owner(node);
806 if (is_array_type(owner_tp)) {
807 int size = get_type_size_bits(node_tp);
808 int align = get_type_alignment_bits(node_tp);
812 assert(size % align == 0);
813 /* ansonsten aufrunden */
815 offset += size * get_compound_graph_path_array_index(path, i);
817 offset += get_entity_offset_bits(node);
823 int get_compound_ent_value_offset_bytes(entity *ent, int pos) {
824 int offset = get_compound_ent_value_offset_bits(ent, pos);
825 assert(offset % 8 == 0);
830 static void init_index(type *arr) {
834 assert(get_array_n_dimensions(arr) == 1);
836 if (has_array_lower_bound(arr, dim))
837 init = get_array_lower_bound_int(arr, 0) -1;
839 init = get_array_upper_bound_int(arr, 0) +1;
841 set_entity_link(get_array_element_entity(arr), (void *)init);
845 static int get_next_index(entity *elem_ent) {
846 type *arr = get_entity_owner(elem_ent);
850 assert(get_array_n_dimensions(arr) == 1);
852 if (has_array_lower_bound(arr, dim)) {
853 next = (int)get_entity_link(elem_ent) +1;
854 if (has_array_upper_bound(arr, dim)) {
855 int upper = get_array_upper_bound_int(arr, dim);
856 if (next == upper) next = get_array_lower_bound_int(arr, dim);
859 next = (int)get_entity_link(elem_ent) -1;
860 if (has_array_lower_bound(arr, dim)) {
861 int upper = get_array_upper_bound_int(arr, dim);
862 if (next == upper) next = get_array_upper_bound_int(arr, dim);
866 set_entity_link(elem_ent, (void *)next);
870 /* Compute the array indicees in compound graph paths of initialized entities.
872 * All arrays must have fixed lower and upper bounds. One array can
873 * have an open bound. If there are several open bounds, we do
874 * nothing. There must be initializer elements for all array
875 * elements. Uses the link field in the array element entities. The
876 * array bounds must be representable as ints.
878 * (If the bounds are not representable as ints we have to represent
879 * the indicees as firm nodes. But the still we must be able to
880 * evaluate the index against the upper bound.)
882 void compute_compound_ent_array_indicees(entity *ent) {
883 type *tp = get_entity_type(ent);
885 entity *unknown_bound_entity = NULL;
887 if (!is_compound_type(tp) ||
888 (ent->variability == variability_uninitialized)) return ;
890 n_vals = get_compound_ent_n_values(ent);
891 if (n_vals == 0) return;
893 /* We can not compute the indicees if there is more than one array
894 with an unknown bound. For this remember the first entity that
895 represents such an array. It could be ent. */
896 if (is_array_type(tp)) {
897 assert(get_array_n_dimensions(tp) == 1 && "other not implemented");
899 if (!has_array_lower_bound(tp, dim) || !has_array_upper_bound(tp, dim))
900 unknown_bound_entity = ent;
903 /* Initialize the entity links to lower bound -1 and test all path elements
905 for (i = 0; i < n_vals; ++i) {
906 compound_graph_path *path = get_compound_ent_value_path(ent, i);
907 int j, path_len = get_compound_graph_path_length(path);
908 for (j = 0; j < path_len; ++j) {
909 entity *node = get_compound_graph_path_node(path, j);
910 type *elem_tp = get_entity_type(node);
912 if (is_array_type(elem_tp)) {
913 assert(get_array_n_dimensions(elem_tp) == 1 && "other not implemented");
915 if (!has_array_lower_bound(elem_tp, dim) || !has_array_upper_bound(elem_tp, dim)) {
916 if (!unknown_bound_entity) unknown_bound_entity = node;
917 if (node != unknown_bound_entity) return;
925 /* Finally compute the indicees ... */
926 for (i = 0; i < n_vals; ++i) {
927 compound_graph_path *path = get_compound_ent_value_path(ent, i);
928 int j, path_len = get_compound_graph_path_length(path);
929 for (j = 0; j < path_len; ++j) {
930 entity *node = get_compound_graph_path_node(path, j);
931 type *owner_tp = get_entity_owner(node);
932 if (is_array_type(owner_tp))
933 set_compound_graph_path_array_index (path, j, get_next_index(node));
940 static int *resize (int *buf, int new_size) {
941 int *new_buf = (int *)calloc(new_size, 4);
942 memcpy(new_buf, buf, new_size>1);
947 /* We sort the elements by placing them at their bit offset in an
948 array where each entry represents one bit called permutation. In
949 fact, we do not place the values themselves, as we would have to
950 copy two things, the value and the path. We only remember the
951 position in the old order. Each value should have a distinct
952 position in the permutation.
954 A second iteration now permutes the actual elements into two
956 void sort_compound_ent_values(entity *ent) {
957 assert(get_type_state(get_entity_type(ent)) == layout_fixed);
959 type *tp = get_entity_type(ent);
960 int i, n_vals = get_compound_ent_n_values(ent);
961 int tp_size = get_type_size_bits(tp);
965 if (!is_compound_type(tp) ||
966 (ent->variability == variability_uninitialized) ||
967 (get_type_state(tp) != layout_fixed) ||
968 (n_vals == 0) ) return;
970 /* estimated upper bound for size. Better: use flexible array ... */
971 size = ((tp_size > (n_vals * 32)) ? tp_size : (n_vals * 32)) * 4;
972 permutation = (int *)calloc(size, 4);
973 for (i = 0; i < n_vals; ++i) {
974 int pos = get_compound_ent_value_offset_bits(ent, i);
975 while (pos >= size) {
977 permutation = resize(permutation, size);
980 assert(permutation[pos] == 0 && "two values with the same offset");
981 permutation[pos] = i + 1; /* We initialized with 0, so we can not distinguish entry 0.
982 So inc all entries by one. */
983 //fprintf(stderr, "i: %d, pos: %d \n", i, pos);
987 ir_node **my_values = NEW_ARR_F(ir_node *, n_vals);
988 compound_graph_path **my_paths = NEW_ARR_F(compound_graph_path *, n_vals);
989 for (i = 0; i < size; ++i) {
990 int pos = permutation[i];
992 //fprintf(stderr, "pos: %d i: %d next %d \n", i, pos, next);
993 assert(next < n_vals);
994 pos--; /* We increased the pos by one */
995 my_values[next] = get_compound_ent_value (ent, pos);
996 my_paths [next] = get_compound_ent_value_path(ent, pos);
1002 DEL_ARR_F(ent->values);
1003 ent->values = my_values;
1004 DEL_ARR_F(ent->val_paths);
1005 ent->val_paths = my_paths;
1009 (get_entity_offset_bytes)(const entity *ent) {
1010 return __get_entity_offset_bytes(ent);
1014 (get_entity_offset_bits)(const entity *ent) {
1015 return __get_entity_offset_bits(ent);
1019 (set_entity_offset_bytes)(entity *ent, int offset) {
1020 __set_entity_offset_bytes(ent, offset);
1024 (set_entity_offset_bits)(entity *ent, int offset) {
1025 __set_entity_offset_bits(ent, offset);
1029 add_entity_overwrites(entity *ent, entity *overwritten) {
1030 assert(ent && is_class_type(get_entity_owner(ent)));
1031 ARR_APP1(entity *, ent->overwrites, overwritten);
1032 ARR_APP1(entity *, overwritten->overwrittenby, ent);
1036 get_entity_n_overwrites(entity *ent) {
1037 assert(ent && is_class_type(get_entity_owner(ent)));
1038 return (ARR_LEN(ent->overwrites));
1042 get_entity_overwrites_index(entity *ent, entity *overwritten) {
1044 assert(ent && is_class_type(get_entity_owner(ent)));
1045 for (i = 0; i < get_entity_n_overwrites(ent); i++)
1046 if (get_entity_overwrites(ent, i) == overwritten)
1052 get_entity_overwrites (entity *ent, int pos) {
1053 assert(ent && is_class_type(get_entity_owner(ent)));
1054 assert(pos < get_entity_n_overwrites(ent));
1055 return ent->overwrites[pos];
1059 set_entity_overwrites (entity *ent, int pos, entity *overwritten) {
1060 assert(ent && is_class_type(get_entity_owner(ent)));
1061 assert(pos < get_entity_n_overwrites(ent));
1062 ent->overwrites[pos] = overwritten;
1066 remove_entity_overwrites(entity *ent, entity *overwritten) {
1068 assert(ent && is_class_type(get_entity_owner(ent)));
1069 for (i = 0; i < (ARR_LEN (ent->overwrites)); i++)
1070 if (ent->overwrites[i] == overwritten) {
1071 for(; i < (ARR_LEN (ent->overwrites))-1; i++)
1072 ent->overwrites[i] = ent->overwrites[i+1];
1073 ARR_SETLEN(entity*, ent->overwrites, ARR_LEN(ent->overwrites) - 1);
1079 add_entity_overwrittenby (entity *ent, entity *overwrites) {
1080 assert(ent && is_class_type(get_entity_owner(ent)));
1081 add_entity_overwrites(overwrites, ent);
1085 get_entity_n_overwrittenby (entity *ent) {
1086 assert(ent && is_class_type(get_entity_owner(ent)));
1087 return (ARR_LEN (ent->overwrittenby));
1091 get_entity_overwrittenby_index(entity *ent, entity *overwrites) {
1093 assert(ent && is_class_type(get_entity_owner(ent)));
1094 for (i = 0; i < get_entity_n_overwrittenby(ent); i++)
1095 if (get_entity_overwrittenby(ent, i) == overwrites)
1101 get_entity_overwrittenby (entity *ent, int pos) {
1102 assert(ent && is_class_type(get_entity_owner(ent)));
1103 assert(pos < get_entity_n_overwrittenby(ent));
1104 return ent->overwrittenby[pos];
1108 set_entity_overwrittenby (entity *ent, int pos, entity *overwrites) {
1109 assert(ent && is_class_type(get_entity_owner(ent)));
1110 assert(pos < get_entity_n_overwrittenby(ent));
1111 ent->overwrittenby[pos] = overwrites;
1114 void remove_entity_overwrittenby(entity *ent, entity *overwrites) {
1116 assert(ent && is_class_type(get_entity_owner(ent)));
1117 for (i = 0; i < (ARR_LEN (ent->overwrittenby)); i++)
1118 if (ent->overwrittenby[i] == overwrites) {
1119 for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
1120 ent->overwrittenby[i] = ent->overwrittenby[i+1];
1121 ARR_SETLEN(entity*, ent->overwrittenby, ARR_LEN(ent->overwrittenby) - 1);
1126 /* A link to store intermediate information */
1128 (get_entity_link)(const entity *ent) {
1129 return __get_entity_link(ent);
1133 (set_entity_link)(entity *ent, void *l) {
1134 __set_entity_link(ent, l);
1138 (get_entity_irg)(const entity *ent) {
1139 return __get_entity_irg(ent);
1143 set_entity_irg(entity *ent, ir_graph *irg) {
1144 assert(ent && is_method_type(get_entity_type(ent)));
1145 /* Wie kann man die Referenz auf einen IRG löschen, z.B. wenn die
1146 * Methode selbst nicht mehr aufgerufen werden kann, die Entität
1147 * aber erhalten bleiben soll? Wandle die Entitaet in description oder
1150 assert((irg && ent->peculiarity == peculiarity_existent) ||
1151 (!irg && ent->peculiarity == peculiarity_description) ||
1152 (!irg && ent->peculiarity == peculiarity_inherited));
1157 (is_entity)(const void *thing) {
1158 return __is_entity(thing);
1161 int is_atomic_entity(entity *ent) {
1162 type* t = get_entity_type(ent);
1163 assert(ent && ent->kind == k_entity);
1164 return (is_primitive_type(t) || is_pointer_type(t) ||
1165 is_enumeration_type(t) || is_method_type(t));
1168 int is_compound_entity(entity *ent) {
1169 type* t = get_entity_type(ent);
1170 assert(ent && ent->kind == k_entity);
1171 return (is_class_type(t) || is_struct_type(t) ||
1172 is_array_type(t) || is_union_type(t));
1176 * @todo not implemnted!!! */
1177 bool equal_entity(entity *ent1, entity *ent2) {
1178 fprintf(stderr, " calling unimplemented equal entity!!! \n");
1183 unsigned long get_entity_visited(entity *ent) {
1184 assert(ent && ent->kind == k_entity);
1187 void set_entity_visited(entity *ent, unsigned long num) {
1188 assert(ent && ent->kind == k_entity);
1191 /* Sets visited field in entity to entity_visited. */
1192 void mark_entity_visited(entity *ent) {
1193 assert(ent && ent->kind == k_entity);
1194 ent->visit = type_visited;
1198 bool entity_visited(entity *ent) {
1199 assert(ent && ent->kind == k_entity);
1200 return get_entity_visited(ent) >= type_visited;
1203 bool entity_not_visited(entity *ent) {
1204 assert(ent && ent->kind == k_entity);
1205 return get_entity_visited(ent) < type_visited;
1208 /* Need two routines because I want to assert the result. */
1209 static entity *resolve_ent_polymorphy2 (type *dynamic_class, entity* static_ent) {
1210 int i, n_overwrittenby;
1213 if (get_entity_owner(static_ent) == dynamic_class) return static_ent;
1215 n_overwrittenby = get_entity_n_overwrittenby(static_ent);
1216 for (i = 0; i < n_overwrittenby; ++i) {
1217 res = resolve_ent_polymorphy2(dynamic_class, get_entity_overwrittenby(static_ent, i));
1224 /** Resolve polymorphy in the inheritance relation.
1226 * Returns the dynamically referenced entity if the static entity and the
1227 * dynamic type are given.
1228 * Search downwards in overwritten tree. */
1229 entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent) {
1231 assert(static_ent && static_ent->kind == k_entity);
1233 res = resolve_ent_polymorphy2(dynamic_class, static_ent);
1236 printf(" Could not find entity "); DDME(static_ent);
1237 printf(" in "); DDMT(dynamic_class);
1239 dump_entity(static_ent);
1240 dump_type(get_entity_owner(static_ent));
1241 dump_type(dynamic_class);