/** return identifier of the class type */
FIRM_DLL const char *get_class_name(const ir_type *clss);
-/** Adds the entity as member of the class. */
-FIRM_DLL void add_class_member(ir_type *clss, ir_entity *member);
-
/** Returns the number of members of this class. */
FIRM_DLL int get_class_n_members(const ir_type *clss);
* owners of the members passed to clss. */
FIRM_DLL void set_class_members(ir_type *clss, ir_entity *members[], int arity);
-/** Finds member in the list of members and removes it.
- *
- * Shrinks the member list, so iterate from the end!!!
- * Does not deallocate the entity. */
-FIRM_DLL void remove_class_member(ir_type *clss, ir_entity *member);
-
/** Adds subtype as subtype to clss.
*
/** return struct identifier as c-string*/
FIRM_DLL const char *get_struct_name(const ir_type *strct);
-/** Adds the entity as member of the struct. */
-FIRM_DLL void add_struct_member(ir_type *strct, ir_entity *member);
-
/** Returns the number of members of this struct. */
FIRM_DLL int get_struct_n_members(const ir_type *strct);
the passed entity. */
FIRM_DLL void set_struct_member(ir_type *strct, int pos, ir_entity *member);
-/** Finds member in the list of members and removes it. */
-FIRM_DLL void remove_struct_member(ir_type *strct, ir_entity *member);
-
/** Returns true if a type is a struct type. */
FIRM_DLL int is_Struct_type(const ir_type *strct);
/** Returns the number of unioned types of this union */
FIRM_DLL int get_union_n_members(const ir_type *uni);
-/** Adds a new entity to a union type */
-FIRM_DLL void add_union_member(ir_type *uni, ir_entity *member);
-
/** Returns the entity at position pos of a union */
FIRM_DLL ir_entity *get_union_member(const ir_type *uni, int pos);
/** Overwrites a entity at position pos in a union type. */
FIRM_DLL void set_union_member(ir_type *uni, int pos, ir_entity *member);
-/** Finds member in the list of members and removes it. */
-FIRM_DLL void remove_union_member(ir_type *uni, ir_entity *member);
-
/** Returns true if a type is a union type. */
FIRM_DLL int is_Union_type(const ir_type *uni);
for (entry = new_list; entry != NULL; entry = entry->next) {
ir_entity *ent = entry->ent;
- /* If the entity is still on the argument type, move it to the frame type.
- This happens if the value_param type was build due to compound
- params. */
+ /* If the entity is still on the argument type, move it to the
+ * frame type.
+ * This happens if the value_param type was build due to compound
+ * params. */
if (get_entity_owner(ent) != frame_tp) {
ir_type *tp = get_entity_type(ent);
unsigned align = get_type_alignment_bytes(tp);
offset += align - 1;
offset &= ~(align - 1);
set_entity_owner(ent, frame_tp);
- add_class_member(frame_tp, ent);
/* must be automatic to set a fixed layout */
set_entity_offset(ent, offset);
offset += get_type_size_bytes(tp);
}
ASSERT_AND_RET(
- is_compound_type(t),
+ is_compound_type(t) || is_Array_type(t),
"CopyB node should copy compound types only", 0 );
/* NoMem nodes are only allowed as memory input if the CopyB is NOT pinned.
irg_walk_graph(irg, NULL, do_copy_return_opt, cr_opt);
for (i = ARR_LEN(cr_opt) - 1; i >= 0; --i) {
- remove_class_member(ft, cr_opt[i].ent);
+ free_entity(cr_opt[i].ent);
}
}
} /* if (n_ret_com) */
DB((dbg, LEVEL_1, " removing entity %+F\n", entity));
- /* TODO: this is O(n^2) improve our interfaces! */
- remove_class_member(get_entity_owner(entity), entity);
+ free_entity(entity);
}
}
DB((dbg, LEVEL_1, " freeing method %+F\n", ent));
remove_irp_irg(irg);
- remove_class_member(get_entity_owner(ent), ent);
+ free_entity(ent);
}
}
/* delete list members */
for (ent = list; ent; ent = list) {
list = get_entity_link(ent);
- remove_class_member(frame_tp, ent);
+ free_entity(ent);
}
/* we changed the frame type, it's layout should be redefined */
set_type_state(frame_tp, layout_undefined);
typedef struct _scalars_t {
ir_entity *ent; /**< A entity for scalar replacement. */
- ir_type *ent_owner; /**< The owner of this entity. */
} scalars_t;
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
ent_type = get_entity_type(ent);
key.ent = ent;
- key.ent_owner = get_entity_owner(ent);
set_insert(set_ent, &key, sizeof(key), HASH_PTR(key.ent));
#ifdef DEBUG_libfirm
do_scalar_replacements(sels, nvals, modes);
foreach_set(set_ent, value) {
- remove_class_member(value->ent_owner, value->ent);
+ free_entity(value->ent);
}
/*
/* ENTITY */
/*-----------------------------------------------------------------*/
-/**
- * Add an entity to it's already set owner type.
- */
-static inline void insert_entity_in_owner(ir_entity *ent)
-{
- ir_type *owner = ent->owner;
- switch (get_type_tpop_code(owner)) {
- case tpo_class:
- add_class_member(owner, ent);
- break;
- case tpo_struct:
- add_struct_member(owner, ent);
- break;
- case tpo_union:
- add_union_member(owner, ent);
- break;
- case tpo_array:
- set_array_element_entity(owner, ent);
- break;
- default:
- panic("Unsupported type kind");
- }
-} /* insert_entity_in_owner */
-
-/**
- * Creates a new entity. This entity is NOT inserted in the owner type.
- *
- * @param db debug info for this entity
- * @param owner the owner type of the new entity
- * @param name the name of the new entity
- * @param type the type of the new entity
- *
- * @return the new created entity
- */
-static inline ir_entity *new_rd_entity(dbg_info *db, ir_type *owner,
- ident *name, ir_type *type)
+ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type,
+ dbg_info *db)
{
ir_entity *res;
ir_graph *rem;
res->attr.code_attr.label = (ir_label_t) -1;
}
+ /* Remember entity in it's owner. */
+ if (owner != NULL)
+ add_compound_member(owner, res);
+
#ifdef DEBUG_libfirm
res->nr = get_irp_new_node_nr();
-#endif /* DEBUG_libfirm */
+#endif
res->visit = 0;
set_entity_dbg_info(res, db);
- return res;
-} /* new_rd_entity */
-
-ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type, dbg_info *db)
-{
- ir_entity *res;
-
- assert(is_compound_type(owner));
- res = new_rd_entity(db, owner, name, type);
- /* Remember entity in it's owner. */
- insert_entity_in_owner(res);
-
hook_new_entity(res);
+
return res;
-} /* new_d_entity */
+}
ir_entity *new_entity(ir_type *owner, ident *name, ir_type *type)
{
return new_d_entity(owner, name, type, NULL);
-} /* new_entity */
+}
/**
* Free entity attributes.
*/
static void free_entity_attrs(ir_entity *ent)
{
- int i;
if (ent->overwrites != NULL) {
DEL_ARR_F(ent->overwrites);
ent->overwrites = NULL;
if (ent->initializer != NULL) {
/* TODO: free initializers */
} else if (entity_has_compound_ent_values(ent)) {
- if (ent->attr.cmpd_attr.val_paths) {
- for (i = get_compound_ent_n_values(ent) - 1; i >= 0; --i)
- if (ent->attr.cmpd_attr.val_paths[i]) {
- /* free_compound_graph_path(ent->attr.cmpd_attr.val_paths[i]) ; * @@@ warum nich? */
- /* Geht nich: wird mehrfach verwendet!!! ==> mehrfach frei gegeben. */
- /* DEL_ARR_F(ent->attr.cmpd_attr.val_paths); */
- }
- ent->attr.cmpd_attr.val_paths = NULL;
- }
+ /* can't free compound graph path as it might be used
+ * multiple times */
+ ent->attr.cmpd_attr.val_paths = NULL;
}
if (is_compound_entity(ent)) {
- if (ent->attr.cmpd_attr.values) {
- /*DEL_ARR_F(ent->attr.cmpd_attr.values)*/;
- }
ent->attr.cmpd_attr.values = NULL;
} else if (is_method_entity(ent)) {
if (ent->attr.mtd_attr.param_access) {
ent->attr.mtd_attr.param_weight = NULL;
}
}
-} /* free_entity_attrs */
+}
/**
* Creates a deep copy of an entity.
#endif
return newe;
}
+
/*
* Copies the entity if the new_owner is different from the
* owner of the old entity, else returns the old entity.
/* create a deep copy so we are safe of aliasing and double-freeing. */
newe = deep_entity_copy(old);
newe->owner = new_owner;
+ add_compound_member(new_owner, newe);
- insert_entity_in_owner(newe);
return newe;
-} /* copy_entity_own */
+}
ir_entity *copy_entity_name(ir_entity *old, ident *new_name)
{
ir_entity *newe;
assert(old && old->kind == k_entity);
- if (old->name == new_name) return old;
+ if (old->name == new_name)
+ return old;
+
newe = deep_entity_copy(old);
newe->name = new_name;
newe->ld_name = NULL;
- insert_entity_in_owner(newe);
+ add_compound_member(old->owner, newe);
return newe;
-} /* copy_entity_name */
+}
void free_entity(ir_entity *ent)
{
+ remove_compound_member(ent->owner, ent);
+
assert(ent && ent->kind == k_entity);
free_entity_attrs(ent);
ent->kind = k_BAD;
free(ent);
-} /* free_entity */
+}
/* Outputs a unique number for this node */
long get_entity_nr(const ir_entity *ent)
#else
return (long)PTR_TO_INT(ent);
#endif
-} /* get_entity_nr */
+}
const char *(get_entity_name)(const ir_entity *ent)
{
{
assert(is_entity(ent));
assert(is_compound_type(owner));
+
+ remove_compound_member(ent->owner, ent);
+ add_compound_member(owner, ent);
ent->owner = owner;
}
default: return "BAD VALUE";
}
#undef X
-} /* get_volatility_name */
+}
ir_align (get_entity_aligned)(const ir_entity *ent)
{
default: return "BAD VALUE";
}
#undef X
-} /* get_align_name */
+}
void set_entity_label(ir_entity *ent, ir_label_t label)
{
int (is_entity_compiler_generated)(const ir_entity *ent)
{
return _is_entity_compiler_generated(ent);
-} /* is_entity_compiler_generated */
+}
/* Sets/resets the compiler generated flag */
void (set_entity_compiler_generated)(ir_entity *ent, int flag)
{
_set_entity_compiler_generated(ent, flag);
-} /* set_entity_compiler_generated */
+}
ir_entity_usage (get_entity_usage)(const ir_entity *ent)
{
break;
}
return 0;
-} /* is_irn_const_expression */
+}
/*
* Copies a firm subgraph that complies to the restrictions for
panic("opcode invalid or not implemented");
}
return nn;
-} /* copy_const_value */
+}
/** Return the name of the initializer kind. */
const char *get_initializer_kind_name(ir_initializer_kind_t ini)
ir_type *entity_tp = get_entity_type(entity);
switch (initializer->kind) {
case IR_INITIALIZER_COMPOUND:
- assert(is_compound_type(entity_tp));
+ assert(is_compound_type(entity_tp) || is_Array_type(entity_tp));
break;
case IR_INITIALIZER_CONST:
/* methods are initialized by a SymConst */
if (mask & mtp_property_inherited)
mask = get_method_additional_properties(get_entity_type(ent));
- /* do not allow to set the mtp_property_inherited flag or
- * the automatic inheritance of flags will not work */
+ /* do not allow to set the mtp_property_inherited flag or
+ * the automatic inheritance of flags will not work */
ent->attr.mtd_attr.irg_add_properties = mask | (flag & ~mtp_property_inherited);
}
}
assert(firm_unknown_type && "Call init_type() before firm_init_entity()!");
assert(!unknown_entity && "Call firm_init_entity() only once!");
- unknown_entity = new_rd_entity(NULL, firm_unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), firm_unknown_type);
+ unknown_entity = new_d_entity(NULL, new_id_from_str(UNKNOWN_ENTITY_NAME),
+ firm_unknown_type, NULL);
set_entity_visibility(unknown_entity, ir_visibility_external);
set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity));
NULL
};
-#define C TP_OP_FLAG_COMPOUND
-#define ID(s) new_id_from_chars(s, sizeof(s) - 1)
-
void init_tpop(void)
{
- type_class = new_tpop(tpo_class , ID("class"), C, sizeof (cls_attr), &class_ops);
- type_struct = new_tpop(tpo_struct , ID("struct"), C, sizeof (stc_attr), &struct_ops);
- type_method = new_tpop(tpo_method , ID("method"), 0, sizeof (mtd_attr), &method_ops);
- type_union = new_tpop(tpo_union , ID("union"), C, sizeof (uni_attr), &union_ops);
- type_array = new_tpop(tpo_array , ID("array"), C, sizeof (arr_attr), &array_ops);
- type_enumeration = new_tpop(tpo_enumeration, ID("enumeration"), 0, sizeof (enm_attr), &enum_ops);
- type_pointer = new_tpop(tpo_pointer , ID("pointer"), 0, sizeof (ptr_attr), &pointer_ops);
- type_primitive = new_tpop(tpo_primitive , ID("primitive"), 0, sizeof (pri_attr), &null_ops);
- tpop_code = new_tpop(tpo_code , ID("code"), 0, /* sizeof (non_attr) */ 0, &null_ops);
- tpop_none = new_tpop(tpo_none , ID("None"), 0, /* sizeof (non_attr) */ 0, &pseudo_ops);
- tpop_unknown = new_tpop(tpo_unknown , ID("Unknown"), 0, /* sizeof (ukn_attr) */ 0, &pseudo_ops);
-}
+#define ID(s) new_id_from_chars(s, sizeof(s) - 1)
+ type_class = new_tpop(tpo_class , ID("class"), TP_OP_FLAG_COMPOUND, sizeof(cls_attr), &class_ops);
+ type_struct = new_tpop(tpo_struct , ID("struct"), TP_OP_FLAG_COMPOUND, sizeof(stc_attr), &struct_ops);
+ type_method = new_tpop(tpo_method , ID("method"), 0, sizeof(mtd_attr), &method_ops);
+ type_union = new_tpop(tpo_union , ID("union"), TP_OP_FLAG_COMPOUND, sizeof(uni_attr), &union_ops);
+ type_array = new_tpop(tpo_array , ID("array"), 0, sizeof(arr_attr), &array_ops);
+ type_enumeration = new_tpop(tpo_enumeration, ID("enumeration"), 0, sizeof(enm_attr), &enum_ops);
+ type_pointer = new_tpop(tpo_pointer , ID("pointer"), 0, sizeof(ptr_attr), &pointer_ops);
+ type_primitive = new_tpop(tpo_primitive , ID("primitive"), 0, sizeof(pri_attr), &null_ops);
+ tpop_code = new_tpop(tpo_code , ID("code"), 0, 0, &null_ops);
+ tpop_none = new_tpop(tpo_none , ID("None"), 0, 0, &pseudo_ops);
+ tpop_unknown = new_tpop(tpo_unknown , ID("Unknown"), 0, 0, &pseudo_ops);
#undef ID
-#undef C
+}
/* Finalize the tpop module.
* Frees all type opcodes. */
return get_id_str(get_class_ident(clss));
}
-void add_class_member(ir_type *clss, ir_entity *member)
+static void add_class_member(ir_type *clss, ir_entity *member)
{
assert(clss && (clss->type_op == type_class));
assert(clss != get_entity_type(member) && "recursive type");
}
}
-void remove_class_member(ir_type *clss, ir_entity *member)
+static void remove_class_member(ir_type *clss, ir_entity *member)
{
int i;
assert(clss && (clss->type_op == type_class));
return ARR_LEN(strct->attr.sa.members);
}
-void add_struct_member(ir_type *strct, ir_entity *member)
+static void add_struct_member(ir_type *strct, ir_entity *member)
{
assert(strct && (strct->type_op == type_struct));
assert(get_type_tpop(get_entity_type(member)) != type_method);
strct->attr.sa.members[pos] = member;
}
-void remove_struct_member(ir_type *strct, ir_entity *member)
+static void remove_struct_member(ir_type *strct, ir_entity *member)
{
int i;
assert(strct && (strct->type_op == type_struct));
return ARR_LEN(uni->attr.ua.members);
}
-void add_union_member(ir_type *uni, ir_entity *member)
+static void add_union_member(ir_type *uni, ir_entity *member)
{
assert(uni && (uni->type_op == type_union));
assert(uni != get_entity_type(member) && "recursive type");
uni->attr.ua.members[pos] = member;
}
-void remove_union_member(ir_type *uni, ir_entity *member)
+static void remove_union_member(ir_type *uni, ir_entity *member)
{
int i;
assert(uni && (uni->type_op == type_union));
current_ir_graph = rem;
res->attr.aa.element_type = element_type;
- new_entity(res, new_id_from_chars("elem_ent", 8), element_type);
+ res->attr.aa.element_ent
+ = new_entity(NULL, new_id_from_chars("elem_ent", 8), element_type);
+ res->attr.aa.element_ent->owner = res;
+
hook_new_type(res);
return res;
}
return get_id_str(get_compound_ident(tp));
}
+void remove_compound_member(ir_type *compound, ir_entity *entity)
+{
+ switch (get_type_tpop_code(compound)) {
+ case tpo_class: remove_class_member(compound, entity); break;
+ case tpo_struct: remove_struct_member(compound, entity); break;
+ case tpo_union: remove_union_member(compound, entity); break;
+ default:
+ panic("argument for remove_compound_member not a compound type");
+ }
+}
+
+void add_compound_member(ir_type *compound, ir_entity *entity)
+{
+ switch (get_type_tpop_code(compound)) {
+ case tpo_class: add_class_member(compound, entity); break;
+ case tpo_struct: add_struct_member(compound, entity); break;
+ case tpo_union: add_union_member(compound, entity); break;
+ default:
+ panic("argument for add_compound_member not a compound type");
+ }
+}
+
+
+
int is_code_type(const ir_type *tp)
{
assert(tp && tp->kind == k_type);
void set_array_size(ir_type *tp, unsigned bytes);
void set_default_size(ir_type *tp, unsigned bytes);
+void add_compound_member(ir_type *compound, ir_entity *entity);
+void remove_compound_member(ir_type *compound, ir_entity *entity);
+
/**
* Initialize the type module.
*