ir_entity *create_compilerlib_entity(ident *id, ir_type *mt) { ir_entity *entity = pmap_get(ir_entity, irp->compilerlib_entities, id); if (entity != NULL) return entity; /* let frontend mangle the name */ ident *ld_name = compilerlib_mangler(id, mt); /* search for an existing entity */ ir_type *glob = get_glob_type(); for (size_t i = 0, n_members = get_compound_n_members(glob); i < n_members; ++i) { ir_entity *member = get_compound_member(glob, i); if (get_entity_ld_ident(member) == ld_name) { entity = member; goto found; } } entity = new_entity(glob, id, mt); set_entity_ld_ident(entity, ld_name); set_entity_visibility(entity, ir_visibility_external); found: pmap_insert(irp->compilerlib_entities, id, entity); return entity; }
/** * Create a trampoline entity for the given method. */ static ir_entity *create_trampoline(be_main_env_t *be, ir_entity *method) { ir_type *type = get_entity_type(method); ident *old_id = get_entity_ld_ident(method); ident *id = new_id_fmt("%s$stub", old_id); ir_type *parent = be->pic_trampolines_type; ir_entity *ent = new_entity(parent, old_id, type); set_entity_ld_ident(ent, id); set_entity_visibility(ent, ir_visibility_private); return ent; }
static ir_entity *create_pic_symbol(be_main_env_t *be, ir_entity *entity) { ident *old_id = get_entity_ld_ident(entity); ident *id = new_id_fmt("%s$non_lazy_ptr", old_id); ir_type *e_type = get_entity_type(entity); ir_type *type = new_type_pointer(e_type); ir_type *parent = be->pic_symbols_type; ir_entity *ent = new_entity(parent, old_id, type); set_entity_ld_ident(ent, id); set_entity_visibility(ent, ir_visibility_private); return ent; }
static bool verify_info_member(ir_type const *const segment, ir_entity const *const entity) { bool fine = true; /* Mach-O does not allow labels in segments like constructors, * destructors, ... */ ident *const ld_ident = get_entity_ld_ident(entity); if (ld_ident[0] != '\0') { report_error("entity %+F in %s segment must not have an ld_name", entity, get_compound_name(segment)); fine = false; } if ((get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER) == 0) { report_error("entity %+F in segment %s without LINKAGE_HIDDEN_USER", entity, get_compound_name(segment)); 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; }