Commit 373423a4 authored by Matthias Braun's avatar Matthias Braun
Browse files

Segment types are an own kind of type now

This is cleaner than having them being class types with a tf_segment
flag set.
parent e51669e4
......@@ -734,10 +734,11 @@ ENUM_BITSET(ptr_access_kind)
*/
typedef enum tp_opcode {
tpo_uninitialized = 0, /* not a type opcode */
tpo_class, /**< A class type. */
tpo_struct, /**< A struct type. */
tpo_method, /**< A method type. */
tpo_union, /**< An union type. */
tpo_class, /**< A class type. */
tpo_segment, /**< A segment type. */
tpo_method, /**< A method type. */
tpo_array, /**< An array type. */
tpo_pointer, /**< A pointer type. */
tpo_primitive, /**< A primitive type. */
......@@ -1019,12 +1020,6 @@ FIRM_API type_dbg_info *get_type_dbg_info(const ir_type *tp);
*/
FIRM_API long get_type_nr(const ir_type *tp);
/**
* Returns true if a type is a segment type.
* A segment type is one of the global types returned by get_segment_type().
*/
FIRM_API int is_segment_type(const ir_type *tp);
/**
* @ingroup compound_type
* @defgroup class_type Class
......@@ -1615,6 +1610,20 @@ FIRM_API ir_entity *frame_alloc_area(ir_type *frame_type, int size,
/** @} */
/** @defgroup segment_type Segment
*
* Segment types represent segments in the object file.
* @{
*/
/** Checks, whether a type is a frame type. */
FIRM_API int is_segment_type(const ir_type *tp);
/** Returns segment identifier. */
FIRM_API ident *get_segment_ident(ir_type const *type);
/** @} */
/**
* @defgroup trwalk Traversing
* @{
......
......@@ -776,6 +776,7 @@ static void emit_type(ir_type *type)
case tpo_struct:
case tpo_union: emit_compound_type(type); return;
case tpo_method: emit_subroutine_type(type); return;
case tpo_segment:
case tpo_code:
case tpo_unknown:
case tpo_uninitialized:
......
......@@ -1469,6 +1469,7 @@ static void dump_type_info(ir_type *const tp, ir_entity *const ent, void *const
/* FALLTHROUGH */
case tpo_union:
case tpo_struct:
case tpo_segment:
for (size_t i = get_compound_n_members(tp); i-- > 0;) {
ir_entity const *const entity = get_compound_member(tp, i);
print_type_ent_edge(F, tp, entity, TYPE_MEMBER_EDGE_ATTR);
......
......@@ -700,6 +700,7 @@ static void dump_type_details(FILE *const F, ir_type const *const tp)
case tpo_union:
case tpo_struct:
case tpo_segment:
dump_compound_members(F, tp);
return;
......
......@@ -191,6 +191,7 @@ static void symtbl_init(void)
INSERT(tt_tpo, "method", tpo_method);
INSERT(tt_tpo, "pointer", tpo_pointer);
INSERT(tt_tpo, "primitive", tpo_primitive);
INSERT(tt_tpo, "segment", tpo_segment);
INSERT(tt_tpo, "struct", tpo_struct);
INSERT(tt_tpo, "union", tpo_union);
INSERT(tt_tpo, "Unknown", tpo_unknown);
......@@ -674,6 +675,7 @@ static void write_type(write_env_t *env, ir_type *tp)
case tpo_union:
case tpo_struct:
case tpo_class:
case tpo_segment:
write_type_compound(env, tp);
return;
......@@ -1728,6 +1730,12 @@ static void read_type(read_env_t *env)
goto finish_type;
}
case tpo_segment: {
ident *id = read_ident_null(env);
type = new_type_segment(id, 0);
goto finish_type;
}
case tpo_code:
case tpo_unknown:
case tpo_uninitialized:
......
......@@ -539,8 +539,9 @@ static int verify_node_Address(const ir_node *n)
{
ir_entity *ent = get_Address_entity(n);
bool fine = check_mode_func(n, mode_is_reference, "reference");
if (!(get_entity_owner(ent)->flags & tf_segment) && !is_method_entity(ent)) {
warn(n, "entity of %+F is not in a segment type but %+F", ent, get_entity_owner(ent));
if (!is_segment_type(get_entity_owner(ent)) && !is_method_entity(ent)) {
warn(n, "entity of %+F is not in a segment type but %+F", ent,
get_entity_owner(ent));
fine = false;
}
return fine;
......@@ -590,7 +591,7 @@ static int verify_node_Member(const ir_node *n)
if (entity == NULL) {
warn(n, "entity is NULL");
fine = false;
} else if (get_entity_owner(entity)->flags & tf_segment) {
} else if (is_segment_type(get_entity_owner(entity))) {
warn(n, "Member from entity with global/segment type owner");
fine = false;
}
......
......@@ -66,7 +66,7 @@ ir_entity *new_entity(ir_type *owner, ident *name, ir_type *type)
res->attr.mtd_attr.param_access = NULL;
res->attr.mtd_attr.param_weight = NULL;
res->attr.mtd_attr.irg = NULL;
} else if (is_compound_type(owner) && !(owner->flags & tf_segment)) {
} else if (is_compound_type(owner) && !is_segment_type(owner)) {
res = intern_new_entity(owner, IR_ENTITY_COMPOUND_MEMBER, name, type);
res->attr.compound_member.offset = -1;
} else {
......
......@@ -84,7 +84,8 @@ int check_type(const ir_type *tp)
switch (get_type_opcode(tp)) {
case tpo_union:
case tpo_struct:
case tpo_class: return check_compound_type(tp);
case tpo_class:
case tpo_segment: return check_compound_type(tp);
case tpo_primitive: return check_primitive_type(tp);
case tpo_pointer: return check_pointer_type(tp);
case tpo_array:
......
......@@ -61,6 +61,7 @@ const char *get_type_opcode_name(tp_opcode const opcode)
case tpo_method: return "method";
case tpo_pointer: return "pointer";
case tpo_primitive: return "primitive";
case tpo_segment: return "segment";
case tpo_struct: return "struct";
case tpo_uninitialized: return "uninitialized";
case tpo_union: return "union";
......@@ -154,8 +155,9 @@ static void free_type_attrs(ir_type *const type)
case tpo_class:
free_class_attrs(type);
return;
case tpo_union:
case tpo_segment:
case tpo_struct:
case tpo_union:
free_compound_attrs(type);
return;
case tpo_method:
......@@ -279,7 +281,7 @@ void set_type_state(ir_type *tp, ir_type_state state)
#ifndef NDEBUG
/* Just a correctness check: */
if (state == layout_fixed && is_compound_type(tp)
&& !(tp->flags & tf_segment)) {
&& !is_segment_type(tp)) {
for (size_t i = 0, n_mem = get_compound_n_members(tp);
i < n_mem; i++) {
ir_entity *entity = get_compound_member(tp, i);
......@@ -753,14 +755,21 @@ int (is_Union_type)(const ir_type *uni)
ir_type *new_type_segment(ident *const name, type_flags const flags)
{
ir_type *const seg = new_type_class(name);
seg->flags |= tf_segment | flags;
return seg;
ir_type *const res = new_type(tpo_segment, sizeof(compound_attr), NULL);
compound_init(res, name);
res->flags |= flags;
return res;
}
int (is_segment_type)(ir_type const *const type)
{
return is_segment_type_(type);
}
int is_segment_type(const ir_type *type)
ident *get_segment_ident(ir_type const *type)
{
return (type->flags & tf_segment) != 0;
assert(is_segment_type(type));
return type->name;
}
ir_type *new_type_array(ir_type *element_type)
......@@ -1156,6 +1165,12 @@ void ir_print_type(char *buffer, size_t buffer_size, const ir_type *type)
return;
}
case tpo_segment: {
ident *id = get_segment_ident(type);
snprintf(buffer, buffer_size, "segment '%s'", get_id_str(id));
return;
}
case tpo_unknown:
snprintf(buffer, buffer_size, "unknown type");
return;
......
......@@ -38,6 +38,7 @@
#define is_Struct_type(strct) is_struct_type_(strct)
#define is_Method_type(method) is_method_type_(method)
#define is_Union_type(uni) is_union_type_(uni)
#define is_segment_type(type) is_segment_type_(type)
#define is_Array_type(array) is_array_type_(array)
#define is_Pointer_type(pointer) is_pointer_type_(pointer)
#define is_Primitive_type(primitive) is_primitive_type_(primitive)
......@@ -101,12 +102,11 @@ typedef enum type_flags {
tf_layout_fixed = 1U << 2, /**< Set if the layout of a type is fixed */
tf_frame_type = 1U << 3, /**< Set if this is a frame type. */
tf_segment = 1U << 4, /**< type represents a linker segment */
tf_global_type = 1U << 5, /**< Set only for the global type */
tf_tls_type = 1U << 6, /**< Set only for the tls type */
tf_info = 1U << 7, /**< infos (for example constructor, destructor pointers) */
tf_variable_size = 1U << 8, /**< compound or array type may have variable size last element */
tf_lowered_dw = 1U << 9, /**< hack to identify lowered doubleword params */
tf_global_type = 1U << 4, /**< Set only for the global type */
tf_tls_type = 1U << 5, /**< Set only for the tls type */
tf_info = 1U << 6, /**< infos (for example constructor, destructor pointers) */
tf_variable_size = 1U << 7, /**< compound or array type may have variable size last element */
tf_lowered_dw = 1U << 8, /**< hack to identify lowered doubleword params */
} type_flags;
ENUM_BITSET(type_flags)
......@@ -308,6 +308,11 @@ static inline int is_union_type_(ir_type const *const type)
return get_type_opcode(type) == tpo_union;
}
static inline int is_segment_type_(ir_type const *const type)
{
return get_type_opcode(type) == tpo_segment;
}
static inline int is_array_type_(ir_type const *const type)
{
return get_type_opcode(type) == tpo_array;
......
......@@ -133,6 +133,7 @@ static void do_type_walk(ir_type *const tp, ir_entity *const ent,
case tpo_struct:
case tpo_union:
case tpo_segment:
for (size_t i = 0, n_mem = get_compound_n_members(tp);
i < n_mem; ++i) {
do_type_walk(NULL, get_compound_member(tp, i), pre, post, env);
......@@ -361,6 +362,7 @@ void walk_types_entities(ir_type *tp, entity_walk_func *doit, void *env)
case tpo_class:
case tpo_struct:
case tpo_union:
case tpo_segment:
for (size_t i = 0, n = get_compound_n_members(tp); i < n; ++i)
doit(get_compound_member(tp, i), env);
return;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment