Commit 08da5b1f authored by Matthias Braun's avatar Matthias Braun
Browse files

improve entity check

parent d4d28e60
......@@ -215,6 +215,11 @@ static inline int _is_entity(const void *thing)
return get_kind(thing) == k_entity;
}
static inline ir_entity_kind get_entity_kind(const ir_entity *entity)
{
return (ir_entity_kind)entity->entity_kind;
}
static inline ident *_get_entity_ident(const ir_entity *ent)
{
assert(ent->kind == k_entity);
......
......@@ -229,17 +229,75 @@ static bool check_external_linkage(const ir_entity *entity, ir_linkage linkage,
return fine;
}
int check_entity(const ir_entity *entity)
static bool is_data_type(const ir_type *type)
{
bool fine = true;
ir_type *tp = get_entity_type(entity);
ir_linkage linkage = get_entity_linkage(entity);
return type != get_code_type() && !is_Method_type(type);
}
int check_entity(const ir_entity *entity)
{
bool fine = true;
const ir_initializer_t *initializer = get_entity_initializer(entity);
const ir_type *type = get_entity_type(entity);
if (initializer != NULL)
fine &= check_initializer(initializer, tp, entity);
fine &= check_initializer(initializer, type, entity);
if (is_method_entity(entity)) {
ir_linkage linkage = get_entity_linkage(entity);
if (linkage & IR_LINKAGE_NO_CODEGEN) {
if (!is_method_entity(entity)) {
report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not a function", entity);
fine = false;
} else if (get_entity_irg(entity) == NULL) {
report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but has no ir-graph anyway", entity);
fine = false;
}
if (get_entity_visibility(entity) != ir_visibility_external) {
report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not externally visible", entity);
fine = false;
}
}
check_external_linkage(entity, IR_LINKAGE_WEAK, "WEAK");
check_external_linkage(entity, IR_LINKAGE_GARBAGE_COLLECT,
"GARBAGE_COLLECT");
check_external_linkage(entity, IR_LINKAGE_MERGE, "MERGE");
const ir_type *owner = get_entity_owner(entity);
switch (get_entity_kind(entity)) {
case IR_ENTITY_NORMAL:
if (!is_data_type(type)) {
report_error("normal entity %+F has non-data type %+F", entity,
type);
fine = false;
}
break;
case IR_ENTITY_COMPOUND_MEMBER:
if (!is_compound_type(owner)) {
report_error("compound member entity %+F has non-compound owner %+F",
entity, owner);
fine = false;
}
if (initializer != NULL) {
report_error("compound member entity %+F has initializer", entity);
fine = false;
}
break;
case IR_ENTITY_LABEL:
if (type != get_code_type()) {
report_error("label entity %+F has non-code type %+F", entity,
type);
fine = false;
}
if (initializer != NULL) {
report_error("label entity %+F has initializer", entity);
fine = false;
}
break;
case IR_ENTITY_METHOD:
if (!is_Method_type(type)) {
report_error("method entity %+F has non-method type %+F", entity,
type);
fine = false;
}
ir_graph *irg = get_entity_irg(entity);
if (irg != NULL) {
ir_entity *irg_entity = get_irg_entity(irg);
......@@ -256,25 +314,26 @@ int check_entity(const ir_entity *entity)
fine = false;
}
}
}
if (linkage & IR_LINKAGE_NO_CODEGEN) {
if (!is_method_entity(entity)) {
report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not a function", entity);
break;
case IR_ENTITY_PARAMETER:
if (!is_frame_type(owner)) {
report_error("parameter entity %+F has non-frame owner %+F",
entity, owner);
fine = false;
} else if (get_entity_irg(entity) == NULL) {
report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but has no ir-graph anyway", entity);
}
if (!is_data_type(type)) {
report_error("parameter entity %+F has non-data type %+F", entity,
type);
fine = false;
}
if (get_entity_visibility(entity) != ir_visibility_external) {
report_error("entity %+F has IR_LINKAGE_NO_CODEGEN but is not externally visible", entity);
if (initializer != NULL) {
report_error("parameter entity %+F has initializer", entity);
fine = false;
}
break;
case IR_ENTITY_UNKNOWN:
break;
}
check_external_linkage(entity, IR_LINKAGE_WEAK, "WEAK");
check_external_linkage(entity, IR_LINKAGE_GARBAGE_COLLECT,
"GARBAGE_COLLECT");
check_external_linkage(entity, IR_LINKAGE_MERGE, "MERGE");
return fine;
}
......@@ -293,10 +352,10 @@ static void check_tore(type_or_ent tore, void *env)
int tr_verify(void)
{
bool fine = true;
ir_type *constructors;
ir_type *destructors;
ir_type *thread_locals;
bool fine = true;
ir_type *constructors;
ir_type *destructors;
ir_type *thread_locals;
type_walk(check_tore, NULL, &fine);
......
Supports Markdown
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