static bool is_externally_visible(const ir_entity *entity) { switch (get_entity_visibility(entity)) { case ir_visibility_external: case ir_visibility_external_private: case ir_visibility_external_protected: return true; case ir_visibility_private: case ir_visibility_local: return false; } /* Return true here, the verification will fail elsewhere for this */ return true; }
static bool is_externally_visible(ir_entity const *const entity) { ir_visibility const vis = get_entity_visibility(entity); switch (vis) { case ir_visibility_private: case ir_visibility_local: return false; case ir_visibility_external: case ir_visibility_external_private: case ir_visibility_external_protected: return true; } panic("invalid visibility in %+F", entity); }
static bool check_external_linkage(const ir_entity *entity, ir_linkage linkage, const char *linkage_name) { bool fine = true; if ((get_entity_linkage(entity) & linkage) == 0) return true; if (get_entity_visibility(entity) != ir_visibility_external) { report_error("entity %+F has IR_LINKAGE_%s but is not externally visible", entity, linkage_name); fine = false; } if (!entity_has_definition(entity)) { report_error("entity %+F has IR_LINKAGE_%s but is just a declaration", entity, linkage_name); fine = false; } return fine; }
int tr_verify(void) { bool fine = true; type_walk(check_tore, NULL, &fine); for (ir_segment_t s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) { ir_type const *const segment = get_segment_type(s); for (size_t e = 0; e < get_compound_n_members(segment); ++e) { ir_entity const *const entity = get_compound_member(segment, e); ident *const ld_ident = get_entity_ld_ident(entity); if (ld_ident == NULL && get_entity_visibility(entity) != ir_visibility_private) { report_error("public segment member %+F has no name", entity); fine = false; continue; } if (segment->flags & tf_info) fine &= verify_info_member(segment, entity); } } ir_type const *const thread_locals = get_segment_type(IR_SEGMENT_THREAD_LOCAL); for (size_t i = 0, n = get_compound_n_members(thread_locals); i < n; ++i) { const ir_entity *entity = get_compound_member(thread_locals, i); /* this is odd and should not be allowed I think */ if (is_method_entity(entity)) { report_error("method %+F in thread local segment", entity); fine = false; } if (get_entity_linkage(entity) & IR_LINKAGE_CONSTANT) { report_error("entity %+F in thread local segment is constant", entity); fine = false; } } return fine; }
int tr_verify(void) { bool fine = true; ir_type *constructors; ir_type *destructors; ir_type *thread_locals; type_walk(check_tore, NULL, &fine); for (ir_segment_t s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) { const ir_type *type = get_segment_type(s); for (size_t e = 0; e < get_compound_n_members(type); ++e) { ir_entity *entity = get_compound_member(type, e); if (get_entity_ld_ident(entity) == NULL && get_entity_visibility(entity) != ir_visibility_private) { report_error("public segment member %+F has no name", entity); fine = false; } } } constructors = get_segment_type(IR_SEGMENT_CONSTRUCTORS); for (size_t i = 0, n = get_compound_n_members(constructors); i < n; ++i) { const ir_entity *entity = get_compound_member(constructors, i); if ((get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER) == 0) { report_error("entity %+F in constructors without LINKAGE_HIDDEN_USER", entity); fine = false; } /* Mach-O doesn't like labels in this section */ if (get_entity_ld_name(entity)[0] != '\0') { report_error("entity %+F in constructors must not have an ld_name", entity); fine = false; } } destructors = get_segment_type(IR_SEGMENT_DESTRUCTORS); for (size_t i = 0, n = get_compound_n_members(destructors); i < n; ++i) { const ir_entity *entity = get_compound_member(destructors, i); if ((get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER) == 0) { report_error("entity %+F in destructors without LINKAGE_HIDDEN_USER", entity); fine = false; } /* Mach-O doesn't like labels in this section */ if (get_entity_ld_name(entity)[0] != '\0') { report_error("entity %+F in destructors must not have an ld_name", entity); fine = false; } } thread_locals = get_segment_type(IR_SEGMENT_THREAD_LOCAL); for (size_t i = 0, n = get_compound_n_members(thread_locals); i < n; ++i) { const ir_entity *entity = get_compound_member(thread_locals, i); /* this is odd and should not be allowed I think */ if (is_method_entity(entity)) { report_error("method %+F in thread local segment"); fine = false; } if (get_entity_linkage(entity) & IR_LINKAGE_CONSTANT) { report_error("entity %+F in thread local segment is constant"); fine = false; } } return fine; }
int check_entity(const ir_entity *entity) { bool fine = true; ir_type *tp = get_entity_type(entity); ir_linkage linkage = get_entity_linkage(entity); fine &= constants_on_wrong_irg(entity); if (is_method_entity(entity)) { ir_graph *irg = get_entity_irg(entity); if (irg != NULL) { ir_entity *irg_entity = get_irg_entity(irg); if (irg_entity != entity) { report_error("entity(%+F)->irg->entity(%+F) relation invalid", entity, irg_entity); fine = false; } } if (get_entity_peculiarity(entity) == peculiarity_existent) { ir_entity *impl = get_SymConst_entity(get_atomic_ent_value(entity)); if (impl == NULL) { report_error("inherited method entity %+F must have constant pointing to existent 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); 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"); if (is_atomic_entity(entity) && entity->initializer != NULL) { ir_mode *mode = NULL; ir_initializer_t *initializer = entity->initializer; switch (initializer->kind) { case IR_INITIALIZER_CONST: mode = get_irn_mode(get_initializer_const_value(initializer)); break; case IR_INITIALIZER_TARVAL: mode = get_tarval_mode(get_initializer_tarval_value(initializer)); break; case IR_INITIALIZER_NULL: case IR_INITIALIZER_COMPOUND: break; } if (mode != NULL && mode != get_type_mode(tp)) { report_error("initializer of entity %+F has wrong mode.", entity); fine = false; } } return fine; }