#include "irhooks.h"
#include "irtools.h"
#include "entity_t.h"
+#include "error.h"
+#include "dbginfo.h"
#include "array.h"
return default_cc_mask;
}
-void firm_init_type(dbg_info *builtin_db, unsigned def_cc_mask)
+void firm_init_type(unsigned def_cc_mask)
{
default_cc_mask = def_cc_mask;
value_params_suffix = new_id_from_str(VALUE_PARAMS_SUFFIX);
value_ress_suffix = new_id_from_str(VALUE_RESS_SUFFIX);
/* construct none and unknown type. */
- firm_none_type = new_type(tpop_none, mode_BAD, new_id_from_str("type_none"), builtin_db);
+ firm_none_type = new_type(tpop_none, mode_BAD, NULL);
set_type_size_bytes(firm_none_type, 0);
set_type_state (firm_none_type, layout_fixed);
remove_irp_type(firm_none_type);
- firm_code_type = new_type(tpop_code, mode_ANY, new_id_from_str("type_code"), builtin_db);
+ firm_code_type = new_type(tpop_code, mode_ANY, NULL);
set_type_state(firm_code_type, layout_fixed);
remove_irp_type(firm_code_type);
- firm_unknown_type = new_type(tpop_unknown, mode_ANY, new_id_from_str("type_unknown"), builtin_db);
+ firm_unknown_type = new_type(tpop_unknown, mode_ANY, NULL);
set_type_size_bytes(firm_unknown_type, 0);
set_type_state (firm_unknown_type, layout_fixed);
remove_irp_type(firm_unknown_type);
_inc_master_type_visited();
}
-ir_type *new_type(const tp_op *type_op, ir_mode *mode, ident *name,
- dbg_info *db)
+ir_type *new_type(const tp_op *type_op, ir_mode *mode, type_dbg_info *db)
{
ir_type *res;
int node_size;
- assert(!id_contains_char(name, ' ') && "type name should not contain spaces");
-
node_size = offsetof(ir_type, attr) + type_op->attr_size;
res = xmalloc(node_size);
memset(res, 0, node_size);
res->kind = k_type;
res->type_op = type_op;
res->mode = mode;
- res->name = name;
- res->visibility = visibility_external_allocated;
+ res->visibility = ir_visibility_external;
res->flags = tf_none;
res->size = 0;
res->align = 0;
assert(0 && "setting a mode is NOT allowed for this type");
}
-ident *(get_type_ident)(const ir_type *tp)
-{
- return _get_type_ident(tp);
-}
-
-void (set_type_ident)(ir_type *tp, ident* id)
-{
- _set_type_ident(tp, id);
-}
-
/* Outputs a unique number for this node */
long get_type_nr(const ir_type *tp)
{
#endif
}
-const char *get_type_name(const ir_type *tp)
-{
- assert(tp && tp->kind == k_type);
- return (get_id_str(tp->name));
-}
-
unsigned (get_type_size_bytes)(const ir_type *tp)
{
return _get_type_size_bytes(tp);
case tpo_struct:
for (i = 0; i < get_struct_n_members(tp); i++) {
assert(get_entity_offset(get_struct_member(tp, i)) > -1);
- assert((get_entity_allocation(get_struct_member(tp, i)) == allocation_automatic));
}
break;
case tpo_union:
return _type_not_visited(tp);
}
-dbg_info *(get_type_dbg_info)(const ir_type *tp)
+type_dbg_info *(get_type_dbg_info)(const ir_type *tp)
{
return _get_type_dbg_info(tp);
}
-void (set_type_dbg_info)(ir_type *tp, dbg_info *db)
+void (set_type_dbg_info)(ir_type *tp, type_dbg_info *db)
{
_set_type_dbg_info(tp, db);
}
if (typ1 == typ2) return 1;
if ((get_type_tpop_code(typ1) != get_type_tpop_code(typ2)) ||
- (get_type_ident(typ1) != get_type_ident(typ2)) ||
+ typ1->name != typ2->name ||
(get_type_mode(typ1) != get_type_mode(typ2)) ||
(get_type_state(typ1) != get_type_state(typ2)))
return 0;
ir_type *t1 = get_class_supertype(typ1, i);
for (j = 0; j < get_class_n_supertypes(typ2); j++) {
ir_type *t2 = get_class_supertype(typ2, j);
- if (get_type_ident(t2) == get_type_ident(t1))
+ if (t2->name == t1->name)
t[i] = t2;
}
}
}
-ir_type *new_d_type_class(ident *name, dbg_info *db)
+ir_type *new_d_type_class(ident *name, type_dbg_info *db)
{
ir_type *res;
- res = new_type(type_class, NULL, name, db);
+ res = new_type(type_class, NULL, db);
+ res->name = name;
res->attr.ca.members = NEW_ARR_F (ir_entity *, 0);
res->attr.ca.subtypes = NEW_ARR_F (ir_type *, 0);
DEL_ARR_F(clss->attr.ca.supertypes);
}
+ident *get_class_ident(const ir_type *clss)
+{
+ assert(clss->type_op == type_class);
+ return clss->name;
+}
+
+const char *get_class_name(const ir_type *clss)
+{
+ if (get_class_ident(clss) == NULL)
+ return NULL;
+ return get_id_str(get_class_ident(clss));
+}
+
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");
- assert(get_type_state(clss) != layout_fixed);
ARR_APP1 (ir_entity *, clss->attr.ca.members, member);
}
ent->repr_class = clss;
}
-const char *get_peculiarity_name(ir_peculiarity p)
-{
-#define X(a) case a: return #a
- switch (p) {
- X(peculiarity_description);
- X(peculiarity_inherited);
- X(peculiarity_existent);
- }
-#undef X
- return "invalid peculiarity";
-}
-
ir_peculiarity get_class_peculiarity(const ir_type *clss)
{
assert(clss && (clss->type_op == type_class));
}
-ir_type *new_d_type_struct(ident *name, dbg_info *db)
+ir_type *new_d_type_struct(ident *name, type_dbg_info *db)
{
- ir_type *res = new_type(type_struct, NULL, name, db);
+ ir_type *res = new_type(type_struct, NULL, db);
+ assert(name != NULL);
+ res->name = name;
res->attr.sa.members = NEW_ARR_F(ir_entity *, 0);
hook_new_type(res);
DEL_ARR_F(strct->attr.sa.members);
}
+ident *get_struct_ident(const ir_type *strct)
+{
+ assert(strct->type_op == type_struct);
+ return strct->name;
+}
+
+const char *get_struct_name(const ir_type *strct)
+{
+ if (get_struct_ident(strct) == NULL)
+ return NULL;
+ return get_id_str(get_struct_ident(strct));
+}
+
int get_struct_n_members(const ir_type *strct)
{
assert(strct && (strct->type_op == type_struct));
assert(strct && (strct->type_op == type_struct));
assert(get_type_tpop(get_entity_type(member)) != type_method);
assert(strct != get_entity_type(member) && "recursive type");
- assert(get_type_state(strct) != layout_fixed);
ARR_APP1 (ir_entity *, strct->attr.sa.members, member);
}
* @param len number of fields
* @param tps array of field types with length len
*/
-static ir_type *build_value_type(ident *name, int len, tp_ent_pair *tps)
+static ir_type *build_value_type(char const* name, int len, tp_ent_pair *tps)
{
int i;
- ir_type *res = new_type_struct(name);
+ ir_type *res = new_type_struct(new_id_from_str(name));
res->flags |= tf_value_param_type;
/* Remove type from type list. Must be treated differently than other types. */
remove_irp_type(res);
ir_type *elt_type = tps[i].tp ? tps[i].tp : res;
/* use the parameter name if specified */
- if (! id)
- id = id_mangle_u(name, get_type_ident(elt_type));
+ if (id == NULL) {
+ id = new_id_from_str("elt");
+ }
tps[i].ent = new_entity(res, id, elt_type);
set_entity_allocation(tps[i].ent, allocation_parameter);
}
return res;
}
-ir_type *new_d_type_method(ident *name, int n_param, int n_res, dbg_info *db)
+ir_type *new_d_type_method(int n_param, int n_res, type_dbg_info *db)
{
ir_type *res;
assert((get_mode_size_bits(mode_P_code) % 8 == 0) && "unorthodox modes not implemented");
- res = new_type(type_method, mode_P_code, name, db);
+ res = new_type(type_method, mode_P_code, db);
res->flags |= tf_layout_fixed;
res->size = get_mode_size_bytes(mode_P_code);
res->attr.ma.n_params = n_param;
return res;
}
-ir_type *new_type_method(ident *name, int n_param, int n_res)
+ir_type *new_type_method(int n_param, int n_res)
{
- return new_d_type_method(name, n_param, n_res, NULL);
+ return new_d_type_method(n_param, n_res, NULL);
}
-ir_type *clone_type_method(ir_type *tp, ident *prefix)
+ir_type *clone_type_method(ir_type *tp)
{
ir_type *res;
- ident *name;
ir_mode *mode;
int n_params, n_res;
- dbg_info *db;
+ type_dbg_info *db;
assert(is_Method_type(tp));
- name = tp->name;
- if (prefix != NULL)
- name = id_mangle(prefix, name);
-
mode = tp->mode;
n_params = tp->attr.ma.n_params;
n_res = tp->attr.ma.n_res;
db = tp->dbi;
- res = new_type(type_method, mode, name, db);
+ res = new_type(type_method, mode, db);
res->flags = tp->flags;
res->assoc_type = tp->assoc_type;
if (!method->attr.ma.value_params) {
/* parameter value type not created yet, build */
- method->attr.ma.value_params
- = build_value_type(id_mangle_u(get_type_ident(method), value_params_suffix),
+ method->attr.ma.value_params = build_value_type("<value param>",
get_method_n_params(method), method->attr.ma.params);
}
/*
if (!method->attr.ma.value_ress) {
/* result value type not created yet, build */
- method->attr.ma.value_ress
- = build_value_type(id_mangle_u(get_type_ident(method), value_ress_suffix),
+ method->attr.ma.value_ress = build_value_type("<value result>",
get_method_n_ress(method), method->attr.ma.res_type);
}
/*
}
-ir_type *new_d_type_union(ident *name, dbg_info *db)
+ir_type *new_d_type_union(ident *name, type_dbg_info *db)
{
- ir_type *res = new_type(type_union, NULL, name, db);
+ ir_type *res = new_type(type_union, NULL, db);
+ res->name = name;
res->attr.ua.members = NEW_ARR_F(ir_entity *, 0);
hook_new_type(res);
DEL_ARR_F(uni->attr.ua.members);
}
+ident *get_union_ident(const ir_type *uni)
+{
+ assert(uni->type_op == type_union);
+ return uni->name;
+}
+
+const char *get_union_name(const ir_type *uni)
+{
+ if (get_union_ident(uni) == NULL)
+ return NULL;
+ return get_id_str(get_union_ident(uni));
+}
+
int get_union_n_members(const ir_type *uni)
{
assert(uni && (uni->type_op == type_union));
{
assert(uni && (uni->type_op == type_union));
assert(uni != get_entity_type(member) && "recursive type");
- assert(get_type_state(uni) != layout_fixed);
ARR_APP1(ir_entity *, uni->attr.ua.members, member);
}
-ir_type *new_d_type_array(ident *name, int n_dimensions, ir_type *element_type,
- dbg_info *db)
+ir_type *new_d_type_array(int n_dimensions, ir_type *element_type,
+ type_dbg_info *db)
{
ir_type *res;
int i;
assert(!is_Method_type(element_type));
- res = new_type(type_array, NULL, name, db);
+ res = new_type(type_array, NULL, db);
res->attr.aa.n_dimensions = n_dimensions;
res->attr.aa.lower_bound = XMALLOCNZ(ir_node*, n_dimensions);
res->attr.aa.upper_bound = XMALLOCNZ(ir_node*, n_dimensions);
current_ir_graph = rem;
res->attr.aa.element_type = element_type;
- new_entity(res, id_mangle_u(name, new_id_from_chars("elem_ent", 8)), element_type);
+ new_entity(res, new_id_from_chars("elem_ent", 8), element_type);
hook_new_type(res);
return res;
}
-ir_type *new_type_array(ident *name, int n_dimensions, ir_type *element_type)
+ir_type *new_type_array(int n_dimensions, ir_type *element_type)
{
- return new_d_type_array(name, n_dimensions, element_type, NULL);
+ return new_d_type_array(n_dimensions, element_type, NULL);
}
void free_array_automatic_entities(ir_type *array)
array->attr.aa.element_type = tp;
}
-ir_type *get_array_element_type(ir_type *array)
+ir_type *get_array_element_type(const ir_type *array)
{
assert(array && (array->type_op == type_array));
return array->attr.aa.element_type;
}
-ir_type *new_d_type_enumeration(ident *name, int n_enums, dbg_info *db)
+ir_type *new_d_type_enumeration(ident *name, int n_enums, type_dbg_info *db)
{
ir_type *res;
assert(n_enums >= 0);
- res = new_type(type_enumeration, NULL, name, db);
+ res = new_type(type_enumeration, NULL, db);
+ res->name = name;
res->attr.ea.enumer = NEW_ARR_F(ir_enum_const, n_enums);
hook_new_type(res);
return res;
DEL_ARR_F(enumeration->attr.ea.enumer);
}
+ident *get_enumeration_ident(const ir_type *enumeration)
+{
+ assert(enumeration->type_op == type_enumeration);
+ return enumeration->name;
+}
+
+const char *get_enumeration_name(const ir_type *enumeration)
+{
+ if (get_enumeration_ident(enumeration) == NULL)
+ return NULL;
+ return get_id_str(get_enumeration_ident(enumeration));
+}
+
int get_enumeration_n_enums(const ir_type *enumeration)
{
assert(enumeration && (enumeration->type_op == type_enumeration));
enum_cnst->nameid = id;
}
-ident *get_enumeration_nameid(const ir_enum_const *enum_cnst)
+ident *get_enumeration_const_nameid(const ir_enum_const *enum_cnst)
{
return enum_cnst->nameid;
}
-const char *get_enumeration_name(const ir_enum_const *enum_cnst)
+const char *get_enumeration_const_name(const ir_enum_const *enum_cnst)
{
return get_id_str(enum_cnst->nameid);
}
-ir_type *new_d_type_pointer(ident *name, ir_type *points_to, ir_mode *ptr_mode,
- dbg_info *db)
+ir_type *new_d_type_pointer(ir_type *points_to, type_dbg_info *db)
{
ir_type *res;
+ ir_mode *mode;
- assert(mode_is_reference(ptr_mode));
- res = new_type(type_pointer, ptr_mode, name, db);
+ if (is_Method_type(points_to) || is_code_type(points_to)) {
+ mode = mode_P_code;
+ } else {
+ mode = mode_P_data;
+ }
+
+ res = new_type(type_pointer, mode, db);
res->attr.pa.points_to = points_to;
assert((get_mode_size_bits(res->mode) % 8 == 0) && "unorthodox modes not implemented");
res->size = get_mode_size_bytes(res->mode);
return res;
}
-ir_type *new_type_pointer(ident *name, ir_type *points_to, ir_mode *ptr_mode)
+ir_type *new_type_pointer(ir_type *points_to)
{
- return new_d_type_pointer(name, points_to, ptr_mode, NULL);
+ return new_d_type_pointer(points_to, NULL);
}
void free_pointer_entities(ir_type *pointer)
pointer->attr.pa.points_to = tp;
}
-ir_type *get_pointer_points_to_type(ir_type *pointer)
+ir_type *get_pointer_points_to_type(const ir_type *pointer)
{
assert(pointer && (pointer->type_op == type_pointer));
return pointer->attr.pa.points_to;
-ir_type *new_d_type_primitive(ident *name, ir_mode *mode, dbg_info *db)
+ir_type *new_d_type_primitive(ir_mode *mode, type_dbg_info *db)
{
- ir_type *res = new_type(type_primitive, mode, name, db);
+ ir_type *res = new_type(type_primitive, mode, db);
res->size = get_mode_size_bytes(mode);
res->flags |= tf_layout_fixed;
res->attr.ba.base_type = NULL;
return res;
}
-ir_type *new_type_primitive(ident *name, ir_mode *mode)
+ir_type *new_type_primitive(ir_mode *mode)
{
- return new_d_type_primitive(name, mode, NULL);
+ return new_d_type_primitive(mode, NULL);
}
int (is_Primitive_type)(const ir_type *primitive)
tp->mode = mode;
}
-ir_type *get_primitive_base_type(ir_type *tp)
+ir_type *get_primitive_base_type(const ir_type *tp)
{
assert(is_Primitive_type(tp));
return tp->attr.ba.base_type;
return tp->type_op->flags & TP_OP_FLAG_COMPOUND;
}
+ident *get_compound_ident(const ir_type *tp)
+{
+ assert(is_compound_type(tp));
+ return tp->name;
+}
+
+const char *get_compound_name(const ir_type *tp)
+{
+ if (get_compound_ident(tp) == NULL)
+ return NULL;
+ return get_id_str(get_compound_ident(tp));
+}
+
int is_code_type(const ir_type *tp)
{
assert(tp && tp->kind == k_type);
return tp->flags & tf_lowered_type;
}
-ir_type *new_type_value(ident *name)
+ir_type *new_type_value(void)
{
- ir_type *res = new_type_struct(name);
+ ir_type *res = new_type_struct(new_id_from_str("<value_type>"));
res->flags |= tf_value_param_type;
return res;
}
-ir_type *new_type_frame(ident *name)
+ir_type *new_type_frame(void)
{
- ir_type *res = new_type_class(name);
+ ir_type *res = new_type_class(new_id_from_str("<frame_type>"));
res->flags |= tf_frame_type;
/* the entity link resource should be allocated if this function is called */
assert(irp_resources_reserved(irp) & IR_RESOURCE_ENTITY_LINK);
- res = new_type_frame(type->name);
+ res = new_type_frame();
for (i = 0, n = get_class_n_members(type); i < n; ++i) {
ir_entity *ent = get_class_member(type, i);
ir_entity *nent = copy_entity_own(ent, res);
tp->size = size;
}
+void default_layout_compound_type(ir_type *type)
+{
+ int i;
+ int n = get_compound_n_members(type);
+ int size = 0;
+ unsigned align_all = 1;
+
+ for (i = 0; i < n; ++i) {
+ ir_entity *entity = get_compound_member(type, i);
+ ir_type *entity_type = get_entity_type(entity);
+ unsigned align;
+ unsigned misalign;
+
+ if (is_Method_type(entity_type))
+ continue;
+
+ assert(get_type_state(entity_type) == layout_fixed);
+ align = get_type_alignment_bytes(entity_type);
+ align_all = align > align_all ? align : align_all;
+ misalign = (align ? size % align : 0);
+ size += (misalign ? align - misalign : 0);
+
+ set_entity_offset(entity, size);
+ if (!is_Union_type(type)) {
+ size += get_type_size_bytes(entity_type);
+ }
+ }
+ if (align_all > 0 && size % align_all) {
+ size += align_all - (size % align_all);
+ }
+ if (align_all > get_type_alignment_bytes(type)) {
+ set_type_alignment_bytes(type, align_all);
+ }
+ set_type_size_bytes(type, size);
+ set_type_state(type, layout_fixed);
+}
+
ir_entity *frame_alloc_area(ir_type *frame_type, int size, unsigned alignment,
int at_start)
{
set_type_state(frame_type, layout_undefined);
if (! a_byte)
- a_byte = new_type_primitive(new_id_from_chars("byte", 4), mode_Bu);
+ a_byte = new_type_primitive(mode_Bu);
snprintf(buf, sizeof(buf), "area%u", area_cnt++);
name = new_id_from_str(buf);
frame_align = get_type_alignment_bytes(frame_type);
size = (size + frame_align - 1) & ~(frame_align - 1);
- tp = new_type_array(id_mangle_u(get_type_ident(frame_type), name), 1, a_byte);
+ tp = new_type_array(1, a_byte);
set_array_bounds_int(tp, 0, 0, size);
set_type_alignment_bytes(tp, alignment);
set_type_state(frame_type, layout_fixed);
return area;
}
+
+void ir_print_type(char *buffer, size_t buffer_size, const ir_type *type)
+{
+ ident *id;
+ int p;
+ type_dbg_info *tdbgi = get_type_dbg_info(type);
+ if (tdbgi != NULL) {
+ ir_retrieve_type_dbg_info(buffer, buffer_size, tdbgi);
+ return;
+ }
+
+ /* we have to construct some name... */
+ switch (get_type_tpop_code(type)) {
+ case tpo_uninitialized:
+ break;
+ case tpo_code:
+ snprintf(buffer, buffer_size, "code");
+ return;
+
+ case tpo_class:
+ id = get_class_ident(type);
+ snprintf(buffer, buffer_size, "class '%s'", get_id_str(id));
+ return;
+
+ case tpo_struct:
+ id = get_struct_ident(type);
+ snprintf(buffer, buffer_size, "struct '%s'", get_id_str(id));
+ return;
+
+ case tpo_union:
+ id = get_union_ident(type);
+ snprintf(buffer, buffer_size, "union '%s'", get_id_str(id));
+ return;
+
+ case tpo_enumeration:
+ id = get_enumeration_ident(type);
+ snprintf(buffer, buffer_size, "enumeration '%s'", get_id_str(id));
+ return;
+
+ case tpo_unknown:
+ snprintf(buffer, buffer_size, "unknown type");
+ return;
+
+ case tpo_pointer:
+ p = snprintf(buffer, buffer_size, "pointer to ");
+ buffer += p;
+ buffer_size -= p;
+ ir_print_type(buffer, buffer_size, get_pointer_points_to_type(type));
+ return;
+
+ case tpo_array:
+ p = snprintf(buffer, buffer_size, "array of ");
+ buffer += p;
+ buffer_size -= p;
+ ir_print_type(buffer, buffer_size, get_array_element_type(type));
+ return;
+
+ case tpo_primitive:
+ id = get_mode_ident(get_type_mode(type));
+ snprintf(buffer, buffer_size, "%s", get_id_str(id));
+ return;
+
+ case tpo_none:
+ snprintf(buffer, buffer_size, "none");
+ return;
+ case tpo_method:
+ /* TODO: we should print argument and return types here... */
+ snprintf(buffer, buffer_size, "method type");
+ return;
+ }
+ snprintf(buffer, buffer_size, "invalid type");
+}