mirror of
https://github.com/odin-lang/Odin.git
synced 2026-03-02 14:48:20 +00:00
Merge pull request #1164 from odin-lang/llvm-explicit-padding
LLVM Struct Types with Explicit Padding
This commit is contained in:
@@ -1989,7 +1989,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
|
||||
Entity *old_field = old_struct->Struct.fields[i];
|
||||
if (old_field->kind == Entity_Variable) {
|
||||
Type *array_type = alloc_type_array(old_field->type, count);
|
||||
Entity *new_field = alloc_entity_field(scope, old_field->token, array_type, false, old_field->Variable.field_src_index);
|
||||
Entity *new_field = alloc_entity_field(scope, old_field->token, array_type, false, old_field->Variable.field_index);
|
||||
soa_struct->Struct.fields[i] = new_field;
|
||||
add_entity(c, scope, nullptr, new_field);
|
||||
} else {
|
||||
|
||||
@@ -215,13 +215,7 @@ bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) {
|
||||
error(node, "#align must be a power of 2, got %lld", align);
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE(bill): Success!!!
|
||||
i64 custom_align = gb_clamp(align, 1, build_context.max_align);
|
||||
if (custom_align < align) {
|
||||
warning(node, "Custom alignment has been clamped to %lld from %lld", align, custom_align);
|
||||
}
|
||||
*align_ = custom_align;
|
||||
*align_ = align;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2317,7 +2311,7 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
|
||||
} else {
|
||||
field_type = alloc_type_pointer(old_field->type);
|
||||
}
|
||||
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_src_index);
|
||||
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_index);
|
||||
soa_struct->Struct.fields[i] = new_field;
|
||||
add_entity(ctx, scope, nullptr, new_field);
|
||||
add_entity_use(ctx, nullptr, new_field);
|
||||
|
||||
@@ -155,8 +155,7 @@ struct Entity {
|
||||
} Constant;
|
||||
struct {
|
||||
Ast *init_expr; // only used for some variables within procedure bodies
|
||||
i32 field_index;
|
||||
i32 field_src_index;
|
||||
i32 field_index;
|
||||
|
||||
ParameterValue param_value;
|
||||
Ast * param_expr;
|
||||
@@ -319,20 +318,18 @@ Entity *alloc_entity_const_param(Scope *scope, Token token, Type *type, ExactVal
|
||||
}
|
||||
|
||||
|
||||
Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index, EntityState state = EntityState_Unresolved) {
|
||||
Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using, i32 field_index, EntityState state = EntityState_Unresolved) {
|
||||
Entity *entity = alloc_entity_variable(scope, token, type);
|
||||
entity->Variable.field_src_index = field_src_index;
|
||||
entity->Variable.field_index = field_src_index;
|
||||
entity->Variable.field_index = field_index;
|
||||
if (is_using) entity->flags |= EntityFlag_Using;
|
||||
entity->flags |= EntityFlag_Field;
|
||||
entity->state = state;
|
||||
return entity;
|
||||
}
|
||||
|
||||
Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field_src_index) {
|
||||
Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field_index) {
|
||||
Entity *entity = alloc_entity_variable(scope, token, type);
|
||||
entity->Variable.field_src_index = field_src_index;
|
||||
entity->Variable.field_index = field_src_index;
|
||||
entity->Variable.field_index = field_index;
|
||||
entity->flags |= EntityFlag_Field;
|
||||
entity->flags |= EntityFlag_ArrayElem;
|
||||
entity->state = EntityState_Resolved;
|
||||
|
||||
@@ -806,8 +806,6 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
|
||||
lbAddr all_tests_array_addr = lb_add_global_generated(p->module, array_type, {});
|
||||
lbValue all_tests_array = lb_addr_get_ptr(p, all_tests_array_addr);
|
||||
|
||||
LLVMTypeRef lbt_Internal_Test = lb_type(m, t_Internal_Test);
|
||||
|
||||
LLVMValueRef indices[2] = {};
|
||||
indices[0] = LLVMConstInt(lb_type(m, t_i32), 0, false);
|
||||
|
||||
@@ -834,7 +832,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
|
||||
GB_ASSERT(LLVMIsConstant(vals[2]));
|
||||
|
||||
LLVMValueRef dst = LLVMConstInBoundsGEP(all_tests_array.value, indices, gb_count_of(indices));
|
||||
LLVMValueRef src = llvm_const_named_struct(lbt_Internal_Test, vals, gb_count_of(vals));
|
||||
LLVMValueRef src = llvm_const_named_struct(m, t_Internal_Test, vals, gb_count_of(vals));
|
||||
|
||||
LLVMBuildStore(p->builder, src, dst);
|
||||
}
|
||||
|
||||
@@ -432,6 +432,7 @@ void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e);
|
||||
lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type);
|
||||
lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block);
|
||||
|
||||
LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_);
|
||||
LLVMValueRef llvm_const_named_struct(LLVMTypeRef t, LLVMValueRef *values, isize value_count_);
|
||||
void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name);
|
||||
|
||||
@@ -446,6 +447,8 @@ lbCopyElisionHint lb_set_copy_elision_hint(lbProcedure *p, lbAddr const &addr, A
|
||||
void lb_reset_copy_elision_hint(lbProcedure *p, lbCopyElisionHint prev_hint);
|
||||
lbValue lb_consume_copy_elision_hint(lbProcedure *p);
|
||||
|
||||
bool lb_struct_has_padding_prefix(Type *t);
|
||||
|
||||
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
||||
#define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
|
||||
#define LB_TYPE_INFO_DATA_NAME "__$type_info_data"
|
||||
|
||||
@@ -99,7 +99,7 @@ LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) {
|
||||
return LLVMConstNull(dst);
|
||||
}
|
||||
|
||||
GB_ASSERT(LLVMSizeOf(dst) == LLVMSizeOf(src));
|
||||
GB_ASSERT_MSG(LLVMSizeOf(dst) == LLVMSizeOf(src), "%s vs %s", LLVMPrintTypeToString(dst), LLVMPrintTypeToString(src));
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(dst);
|
||||
switch (kind) {
|
||||
case LLVMPointerTypeKind:
|
||||
@@ -125,11 +125,43 @@ lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
|
||||
return res;
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_) {
|
||||
LLVMTypeRef struct_type = lb_type(m, t);
|
||||
GB_ASSERT(LLVMGetTypeKind(struct_type) == LLVMStructTypeKind);
|
||||
|
||||
unsigned value_count = cast(unsigned)value_count_;
|
||||
unsigned elem_count = LLVMCountStructElementTypes(struct_type);
|
||||
if (elem_count == value_count) {
|
||||
return llvm_const_named_struct(struct_type, values, value_count_);
|
||||
}
|
||||
Type *bt = base_type(t);
|
||||
GB_ASSERT(bt->kind == Type_Struct);
|
||||
|
||||
GB_ASSERT(value_count_ == bt->Struct.fields.count);
|
||||
|
||||
unsigned field_offset = 0;
|
||||
if (lb_struct_has_padding_prefix(bt)) {
|
||||
field_offset = 1;
|
||||
}
|
||||
|
||||
unsigned values_with_padding_count = field_offset + cast(unsigned)(bt->Struct.fields.count*2 + 1);
|
||||
LLVMValueRef *values_with_padding = gb_alloc_array(permanent_allocator(), LLVMValueRef, values_with_padding_count);
|
||||
for (unsigned i = 0; i < value_count; i++) {
|
||||
values_with_padding[field_offset + i*2 + 1] = values[i];
|
||||
}
|
||||
for (unsigned i = 0; i < values_with_padding_count; i++) {
|
||||
if (values_with_padding[i] == nullptr) {
|
||||
values_with_padding[i] = LLVMConstNull(LLVMStructGetTypeAtIndex(struct_type, i));
|
||||
}
|
||||
}
|
||||
|
||||
return llvm_const_named_struct(struct_type, values_with_padding, values_with_padding_count);
|
||||
}
|
||||
|
||||
LLVMValueRef llvm_const_named_struct(LLVMTypeRef t, LLVMValueRef *values, isize value_count_) {
|
||||
unsigned value_count = cast(unsigned)value_count_;
|
||||
unsigned elem_count = LLVMCountStructElementTypes(t);
|
||||
GB_ASSERT(value_count == elem_count);
|
||||
GB_ASSERT_MSG(value_count == elem_count, "%s %u %u", LLVMPrintTypeToString(t), value_count, elem_count);
|
||||
for (unsigned i = 0; i < elem_count; i++) {
|
||||
LLVMTypeRef elem_type = LLVMStructGetTypeAtIndex(t, i);
|
||||
values[i] = llvm_const_cast(values[i], elem_type);
|
||||
@@ -235,7 +267,7 @@ lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, To
|
||||
fields[3]/*procedure*/ = lb_find_or_add_entity_string(p->module, procedure).value;
|
||||
|
||||
lbValue res = {};
|
||||
res.value = llvm_const_named_struct(lb_type(m, t_source_code_location), fields, gb_count_of(fields));
|
||||
res.value = llvm_const_named_struct(m, t_source_code_location, fields, gb_count_of(fields));
|
||||
res.type = t_source_code_location;
|
||||
return res;
|
||||
}
|
||||
@@ -422,7 +454,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
|
||||
LLVMValueRef values[2] = {ptr, len};
|
||||
|
||||
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
|
||||
res.value = llvm_const_named_struct(m, original_type, values, 2);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -512,7 +544,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
LLVMValueRef values[2] = {ptr, str_len};
|
||||
GB_ASSERT(is_type_string(original_type));
|
||||
|
||||
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
|
||||
res.value = llvm_const_named_struct(m, original_type, values, 2);
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -554,7 +586,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
break;
|
||||
}
|
||||
|
||||
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
|
||||
res.value = llvm_const_named_struct(m, original_type, values, 2);
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
@@ -585,7 +617,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
break;
|
||||
}
|
||||
|
||||
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 4);
|
||||
res.value = llvm_const_named_struct(m, original_type, values, 4);
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
@@ -802,11 +834,15 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
}
|
||||
|
||||
isize offset = 0;
|
||||
if (type->Struct.custom_align > 0) {
|
||||
if (lb_struct_has_padding_prefix(type)) {
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
LLVMTypeRef struct_type = lb_type(m, original_type);
|
||||
|
||||
isize value_count = type->Struct.fields.count + offset;
|
||||
unsigned value_count = cast(unsigned)(offset + type->Struct.fields.count*2 + 1);
|
||||
GB_ASSERT(LLVMCountStructElementTypes(struct_type) == value_count);
|
||||
|
||||
LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count);
|
||||
bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count);
|
||||
|
||||
@@ -822,9 +858,11 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
|
||||
Selection sel = lookup_field(type, name, false);
|
||||
Entity *f = type->Struct.fields[sel.index[0]];
|
||||
|
||||
isize index = offset + f->Variable.field_index*2 + 1;
|
||||
if (elem_type_can_be_constant(f->type)) {
|
||||
values[offset+f->Variable.field_index] = lb_const_value(m, f->type, tav.value, allow_local).value;
|
||||
visited[offset+f->Variable.field_index] = true;
|
||||
values[index] = lb_const_value(m, f->type, tav.value, allow_local).value;
|
||||
visited[index] = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -835,25 +873,24 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
if (tav.mode != Addressing_Invalid) {
|
||||
val = tav.value;
|
||||
}
|
||||
|
||||
isize index = offset + f->Variable.field_index*2 + 1;
|
||||
if (elem_type_can_be_constant(f->type)) {
|
||||
values[offset+f->Variable.field_index] = lb_const_value(m, f->type, val, allow_local).value;
|
||||
visited[offset+f->Variable.field_index] = true;
|
||||
values[index] = lb_const_value(m, f->type, val, allow_local).value;
|
||||
visited[index] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (isize i = 0; i < type->Struct.fields.count; i++) {
|
||||
if (!visited[offset+i]) {
|
||||
GB_ASSERT(values[offset+i] == nullptr);
|
||||
values[offset+i] = lb_const_nil(m, get_struct_field_type(type, i)).value;
|
||||
for (isize i = 0; i < value_count; i++) {
|
||||
if (!visited[i]) {
|
||||
GB_ASSERT(values[i] == nullptr);
|
||||
LLVMTypeRef type = LLVMStructGetTypeAtIndex(struct_type, cast(unsigned)i);
|
||||
values[i] = LLVMConstNull(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (type->Struct.custom_align > 0) {
|
||||
values[0] = LLVMConstNull(lb_alignment_prefix_type_hack(m, type->Struct.custom_align));
|
||||
}
|
||||
|
||||
bool is_constant = true;
|
||||
|
||||
for (isize i = 0; i < value_count; i++) {
|
||||
@@ -866,7 +903,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
}
|
||||
|
||||
if (is_constant) {
|
||||
res.value = llvm_const_named_struct(lb_type(m, original_type), values, cast(unsigned)value_count);
|
||||
res.value = llvm_const_named_struct(struct_type, values, cast(unsigned)value_count);
|
||||
return res;
|
||||
} else {
|
||||
// TODO(bill): THIS IS HACK BUT IT WORKS FOR WHAT I NEED
|
||||
@@ -880,8 +917,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
||||
new_values[i] = LLVMConstNull(LLVMTypeOf(old_value));
|
||||
}
|
||||
}
|
||||
LLVMValueRef constant_value = llvm_const_named_struct(lb_type(m, original_type), new_values, cast(unsigned)value_count);
|
||||
|
||||
LLVMValueRef constant_value = llvm_const_named_struct(struct_type, new_values, cast(unsigned)value_count);
|
||||
|
||||
GB_ASSERT(is_local);
|
||||
lbProcedure *p = m->curr_procedure;
|
||||
|
||||
@@ -1923,9 +1923,9 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
|
||||
lbValue map_ptr = lb_address_from_load_or_generate_local(p, x);
|
||||
|
||||
unsigned indices[2] = {0, 0};
|
||||
LLVMValueRef hashes_data = LLVMBuildStructGEP(p->builder, map_ptr.value, 0, "");
|
||||
LLVMValueRef hashes_data_ptr_ptr = LLVMBuildStructGEP(p->builder, hashes_data, 0, "");
|
||||
LLVMValueRef hashes_data_ptr = LLVMBuildLoad(p->builder, hashes_data_ptr_ptr, "");
|
||||
lbValue hashes_data = lb_emit_struct_ep(p, map_ptr, 0);
|
||||
lbValue hashes_data_ptr_ptr = lb_emit_struct_ep(p, hashes_data, 0);
|
||||
LLVMValueRef hashes_data_ptr = LLVMBuildLoad(p->builder, hashes_data_ptr_ptr.value, "");
|
||||
|
||||
if (op_kind == Token_CmpEq) {
|
||||
res.value = LLVMBuildIsNull(p->builder, hashes_data_ptr, "");
|
||||
@@ -2786,7 +2786,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
|
||||
bool deref = is_type_pointer(t);
|
||||
t = base_type(type_deref(t));
|
||||
if (is_type_soa_struct(t)) {
|
||||
if (is_type_soa_struct(t)) {
|
||||
// SOA STRUCTURES!!!!
|
||||
lbValue val = lb_build_addr_ptr(p, ie->expr);
|
||||
if (deref) {
|
||||
@@ -2821,7 +2821,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
// lbValue len = ir_soa_struct_len(p, base_struct);
|
||||
// lb_emit_bounds_check(p, ast_token(ie->index), index, len);
|
||||
}
|
||||
|
||||
lbValue val = lb_emit_ptr_offset(p, field, index);
|
||||
return lb_addr(val);
|
||||
}
|
||||
@@ -3259,7 +3258,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
TypeAndValue tav = type_and_value_of_expr(elem);
|
||||
} else {
|
||||
TypeAndValue tav = type_and_value_of_expr(elem);
|
||||
Selection sel = lookup_field_from_index(bt, st->fields[field_index]->Variable.field_src_index);
|
||||
Selection sel = lookup_field_from_index(bt, st->fields[field_index]->Variable.field_index);
|
||||
index = sel.index[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -1109,7 +1109,7 @@ lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
|
||||
|
||||
LLVMTypeRef uvt = LLVMGetElementType(LLVMTypeOf(u.value));
|
||||
unsigned element_count = LLVMCountStructElementTypes(uvt);
|
||||
GB_ASSERT_MSG(element_count == 3, "(%s) != (%s)", type_to_string(ut), LLVMPrintTypeToString(uvt));
|
||||
GB_ASSERT_MSG(element_count == 3, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
|
||||
|
||||
lbValue tag_ptr = {};
|
||||
tag_ptr.value = LLVMBuildStructGEP(p->builder, u.value, 2, "");
|
||||
@@ -1160,13 +1160,9 @@ LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) {
|
||||
return LLVMArrayType(lb_type(m, t_u32), 0);
|
||||
case 8:
|
||||
return LLVMArrayType(lb_type(m, t_u64), 0);
|
||||
case 16:
|
||||
default: case 16:
|
||||
return LLVMArrayType(LLVMVectorType(lb_type(m, t_u32), 4), 0);
|
||||
default:
|
||||
GB_PANIC("Invalid alignment %d", cast(i32)alignment);
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
String lb_mangle_name(lbModule *m, Entity *e) {
|
||||
@@ -1650,11 +1646,17 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
GB_ASSERT(field_count == 2);
|
||||
LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
|
||||
|
||||
LLVMTypeRef entries_fields[4] = {
|
||||
lb_type(m, t_rawptr),
|
||||
LLVMTypeRef padding_type = LLVMArrayType(lb_type(m, t_uintptr), 0);
|
||||
LLVMTypeRef entries_fields[] = {
|
||||
padding_type,
|
||||
lb_type(m, t_rawptr), // data
|
||||
padding_type,
|
||||
lb_type(m, t_int), // len
|
||||
padding_type,
|
||||
lb_type(m, t_int), // cap
|
||||
padding_type,
|
||||
lb_type(m, t_allocator), // allocator
|
||||
padding_type,
|
||||
};
|
||||
|
||||
fields[0] = lb_type(m, internal_type->Struct.fields[0]->type);
|
||||
@@ -1676,25 +1678,63 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
}
|
||||
|
||||
isize offset = 0;
|
||||
if (type->Struct.custom_align > 0) {
|
||||
if (lb_struct_has_padding_prefix(type)) {
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
m->internal_type_level += 1;
|
||||
defer (m->internal_type_level -= 1);
|
||||
|
||||
unsigned field_count = cast(unsigned)(type->Struct.fields.count + offset);
|
||||
unsigned field_count = cast(unsigned)(offset + type->Struct.fields.count*2 + 1);
|
||||
LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
|
||||
|
||||
LLVMTypeRef type_u8 = lb_type(m, t_u8);
|
||||
LLVMTypeRef type_u16 = lb_type(m, t_u16);
|
||||
LLVMTypeRef type_u32 = lb_type(m, t_u32);
|
||||
LLVMTypeRef type_u64 = lb_type(m, t_u64);
|
||||
|
||||
i64 padding_offset = 0;
|
||||
for_array(i, type->Struct.fields) {
|
||||
Entity *field = type->Struct.fields[i];
|
||||
fields[i+offset] = lb_type(m, field->type);
|
||||
i64 padding = type->Struct.offsets[i]-padding_offset;
|
||||
|
||||
LLVMTypeRef padding_type = nullptr;
|
||||
if (padding_offset == 0) {
|
||||
padding_type = lb_alignment_prefix_type_hack(m, type_align_of(type));
|
||||
} else {
|
||||
i64 alignment = type_align_of(field->type);
|
||||
// NOTE(bill): limit to `[N x u64]` to prevent ABI issues
|
||||
alignment = gb_min(alignment, 8);
|
||||
if (padding % alignment == 0) {
|
||||
isize len = padding/alignment;
|
||||
switch (alignment) {
|
||||
case 1: padding_type = LLVMArrayType(type_u8, cast(unsigned)len); break;
|
||||
case 2: padding_type = LLVMArrayType(type_u16, cast(unsigned)len); break;
|
||||
case 4: padding_type = LLVMArrayType(type_u32, cast(unsigned)len); break;
|
||||
case 8: padding_type = LLVMArrayType(type_u64, cast(unsigned)len); break;
|
||||
}
|
||||
} else {
|
||||
padding_type = LLVMArrayType(type_u8, cast(unsigned)padding);
|
||||
}
|
||||
}
|
||||
fields[offset + i*2 + 0] = padding_type;
|
||||
fields[offset + i*2 + 1] = lb_type(m, field->type);
|
||||
if (!type->Struct.is_packed) {
|
||||
padding_offset = align_formula(padding_offset, type_align_of(field->type));
|
||||
}
|
||||
padding_offset += type_size_of(field->type);
|
||||
}
|
||||
|
||||
i64 end_padding = type_size_of(type)-padding_offset;
|
||||
fields[field_count-1] = LLVMArrayType(type_u8, cast(unsigned)end_padding);
|
||||
|
||||
|
||||
if (type->Struct.custom_align > 0) {
|
||||
if (offset != 0) {
|
||||
GB_ASSERT(offset == 1);
|
||||
fields[0] = lb_alignment_prefix_type_hack(m, type->Struct.custom_align);
|
||||
}
|
||||
for (unsigned i = 0; i < field_count; i++) {
|
||||
GB_ASSERT(fields[i] != nullptr);
|
||||
}
|
||||
|
||||
return LLVMStructTypeInContext(ctx, fields, field_count, type->Struct.is_packed);
|
||||
}
|
||||
@@ -2230,7 +2270,7 @@ lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) {
|
||||
LLVMValueRef values[2] = {ptr, str_len};
|
||||
|
||||
lbValue res = {};
|
||||
res.value = llvm_const_named_struct(lb_type(m, t_string), values, 2);
|
||||
res.value = llvm_const_named_struct(m, t_string, values, 2);
|
||||
res.type = t_string;
|
||||
return res;
|
||||
}
|
||||
@@ -2265,7 +2305,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
|
||||
LLVMValueRef values[2] = {ptr, len};
|
||||
|
||||
lbValue res = {};
|
||||
res.value = llvm_const_named_struct(lb_type(m, t_u8_slice), values, 2);
|
||||
res.value = llvm_const_named_struct(m, t_u8_slice, values, 2);
|
||||
res.type = t_u8_slice;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -357,8 +357,7 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
|
||||
lbValue entries = lb_map_entries_ptr(p, expr);
|
||||
lbValue elem = lb_emit_struct_ep(p, entries, 0);
|
||||
elem = lb_emit_load(p, elem);
|
||||
|
||||
lbValue entry = lb_emit_ptr_offset(p, elem, idx);
|
||||
lbValue entry = lb_emit_ptr_offset(p, elem, idx);
|
||||
idx = lb_emit_load(p, lb_emit_struct_ep(p, entry, 2));
|
||||
val = lb_emit_load(p, lb_emit_struct_ep(p, entry, 3));
|
||||
|
||||
|
||||
@@ -157,12 +157,14 @@ lbValue lb_type_info_member_tags_offset(lbProcedure *p, isize count) {
|
||||
void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data
|
||||
lbModule *m = p->module;
|
||||
CheckerInfo *info = m->info;
|
||||
|
||||
|
||||
i64 global_type_info_data_entity_count = 0;
|
||||
{
|
||||
// NOTE(bill): Set the type_table slice with the global backing array
|
||||
lbValue global_type_table = lb_find_runtime_value(m, str_lit("type_table"));
|
||||
Type *type = base_type(lb_global_type_info_data_entity->type);
|
||||
GB_ASSERT(is_type_array(type));
|
||||
global_type_info_data_entity_count = type->Array.count;
|
||||
|
||||
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
||||
LLVMValueRef values[2] = {
|
||||
@@ -179,6 +181,11 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
Entity *type_info_flags_entity = find_core_entity(info->checker, str_lit("Type_Info_Flags"));
|
||||
Type *t_type_info_flags = type_info_flags_entity->type;
|
||||
|
||||
|
||||
auto entries_handled = slice_make<bool>(heap_allocator(), cast(isize)global_type_info_data_entity_count);
|
||||
defer (gb_free(heap_allocator(), entries_handled.data));
|
||||
entries_handled[0] = true;
|
||||
|
||||
for_array(type_info_type_index, info->type_info_types) {
|
||||
Type *t = info->type_info_types[type_info_type_index];
|
||||
if (t == nullptr || t == t_invalid) {
|
||||
@@ -189,19 +196,36 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
if (entry_index <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entries_handled[entry_index]) {
|
||||
continue;
|
||||
}
|
||||
entries_handled[entry_index] = true;
|
||||
|
||||
lbValue global_data_ptr = lb_global_type_info_data_ptr(m);
|
||||
lbValue tag = {};
|
||||
lbValue ti_ptr = lb_emit_array_epi(p, lb_global_type_info_data_ptr(m), cast(i32)entry_index);
|
||||
lbValue ti_ptr = lb_emit_array_epi(p, global_data_ptr, cast(i32)entry_index);
|
||||
|
||||
i64 size = type_size_of(t);
|
||||
i64 align = type_align_of(t);
|
||||
u32 flags = type_info_flags_of_type(t);
|
||||
lbValue id = lb_typeid(m, t);
|
||||
GB_ASSERT_MSG(align != 0, "%lld %s", align, type_to_string(t));
|
||||
|
||||
lbValue type_info_flags = lb_const_int(p->module, t_type_info_flags, flags);
|
||||
|
||||
lbValue size_ptr = lb_emit_struct_ep(p, ti_ptr, 0);
|
||||
lbValue align_ptr = lb_emit_struct_ep(p, ti_ptr, 1);
|
||||
lbValue flags_ptr = lb_emit_struct_ep(p, ti_ptr, 2);
|
||||
lbValue id_ptr = lb_emit_struct_ep(p, ti_ptr, 3);
|
||||
|
||||
lb_emit_store(p, size_ptr, lb_const_int(m, t_int, size));
|
||||
lb_emit_store(p, align_ptr, lb_const_int(m, t_int, align));
|
||||
lb_emit_store(p, flags_ptr, type_info_flags);
|
||||
lb_emit_store(p, id_ptr, id);
|
||||
|
||||
lbValue variant_ptr = lb_emit_struct_ep(p, ti_ptr, 4);
|
||||
|
||||
lbValue type_info_flags = lb_const_int(p->module, t_type_info_flags, type_info_flags_of_type(t));
|
||||
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 0), lb_const_int(m, t_int, type_size_of(t)));
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 1), lb_const_int(m, t_int, type_align_of(t)));
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 2), type_info_flags);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 3), lb_typeid(m, t));
|
||||
|
||||
|
||||
switch (t->kind) {
|
||||
case Type_Named: {
|
||||
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_named_ptr);
|
||||
@@ -233,7 +257,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -298,7 +322,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -334,7 +358,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
@@ -368,7 +392,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
@@ -393,7 +417,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -407,7 +431,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -423,7 +447,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -443,7 +467,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
|
||||
// NOTE(bill): Union assignment
|
||||
@@ -467,7 +491,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -481,7 +505,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -506,7 +530,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -545,7 +569,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
|
||||
break;
|
||||
@@ -596,7 +620,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
@@ -650,7 +674,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
|
||||
@@ -688,7 +712,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
vals[11] = soa_len.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
isize count = t->Struct.fields.count;
|
||||
if (count > 0) {
|
||||
lbValue memory_types = lb_type_info_member_types_offset (p, count);
|
||||
@@ -743,11 +767,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
vals[i] = LLVMConstNull(lb_type(m, get_struct_field_type(tag.type, i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
|
||||
break;
|
||||
@@ -767,7 +790,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
@@ -791,7 +814,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
@@ -808,7 +831,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
@@ -823,7 +846,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
@@ -837,7 +860,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
@@ -856,4 +879,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for_array(i, entries_handled) {
|
||||
if (!entries_handled[i]) {
|
||||
GB_PANIC("UNHANDLED ENTRY %td (%td)", i, entries_handled.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,6 +807,47 @@ lbValue lb_address_from_load(lbProcedure *p, lbValue value) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool lb_struct_has_padding_prefix(Type *t) {
|
||||
Type *bt = base_type(t);
|
||||
GB_ASSERT(bt->kind == Type_Struct);
|
||||
return bt->Struct.custom_align != 0 && bt->Struct.fields.count == 0;
|
||||
}
|
||||
|
||||
i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
|
||||
if (t->kind == Type_Struct) {
|
||||
index = index*2 + 1;
|
||||
if (lb_struct_has_padding_prefix(t)) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
unsigned count = LLVMCountStructElementTypes(lb_type(m, t));
|
||||
GB_ASSERT(count >= cast(unsigned)index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
char const *llvm_type_kinds[] = {
|
||||
"LLVMVoidTypeKind",
|
||||
"LLVMHalfTypeKind",
|
||||
"LLVMFloatTypeKind",
|
||||
"LLVMDoubleTypeKind",
|
||||
"LLVMX86_FP80TypeKind",
|
||||
"LLVMFP128TypeKind",
|
||||
"LLVMPPC_FP128TypeKind",
|
||||
"LLVMLabelTypeKind",
|
||||
"LLVMIntegerTypeKind",
|
||||
"LLVMFunctionTypeKind",
|
||||
"LLVMStructTypeKind",
|
||||
"LLVMArrayTypeKind",
|
||||
"LLVMPointerTypeKind",
|
||||
"LLVMVectorTypeKind",
|
||||
"LLVMMetadataTypeKind",
|
||||
"LLVMX86_MMXTypeKind",
|
||||
"LLVMTokenTypeKind",
|
||||
"LLVMScalableVectorTypeKind",
|
||||
"LLVMBFloatTypeKind",
|
||||
};
|
||||
|
||||
lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
||||
GB_ASSERT(is_type_pointer(s.type));
|
||||
Type *t = base_type(type_deref(s.type));
|
||||
@@ -871,6 +912,7 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
||||
case 0: result_type = get_struct_field_type(gst, 0); break;
|
||||
case 1: result_type = get_struct_field_type(gst, 1); break;
|
||||
}
|
||||
index = index*2 + 1;
|
||||
} else if (is_type_array(t)) {
|
||||
return lb_emit_array_epi(p, s, index);
|
||||
} else if (is_type_relative_slice(t)) {
|
||||
@@ -883,10 +925,9 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
||||
}
|
||||
|
||||
GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
|
||||
|
||||
if (t->kind == Type_Struct && t->Struct.custom_align != 0) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
index = lb_convert_struct_index(p->module, t, index);
|
||||
|
||||
if (lb_is_const(s)) {
|
||||
lbModule *m = p->module;
|
||||
lbValue res = {};
|
||||
@@ -896,6 +937,14 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
||||
return res;
|
||||
} else {
|
||||
lbValue res = {};
|
||||
LLVMTypeRef st = LLVMGetElementType(LLVMTypeOf(s.value));
|
||||
// gb_printf_err("%s\n", type_to_string(s.type));
|
||||
// gb_printf_err("%s\n", LLVMPrintTypeToString(LLVMTypeOf(s.value)));
|
||||
// gb_printf_err("%d\n", index);
|
||||
GB_ASSERT_MSG(LLVMGetTypeKind(st) == LLVMStructTypeKind, "%s", llvm_type_kinds[LLVMGetTypeKind(st)]);
|
||||
unsigned count = LLVMCountStructElementTypes(st);
|
||||
GB_ASSERT(count >= cast(unsigned)index);
|
||||
|
||||
res.value = LLVMBuildStructGEP(p->builder, s.value, cast(unsigned)index, "");
|
||||
res.type = alloc_type_pointer(result_type);
|
||||
return res;
|
||||
@@ -1006,10 +1055,8 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
|
||||
}
|
||||
|
||||
GB_ASSERT_MSG(result_type != nullptr, "%s, %d", type_to_string(s.type), index);
|
||||
|
||||
if (t->kind == Type_Struct && t->Struct.custom_align != 0) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
index = lb_convert_struct_index(p->module, t, index);
|
||||
|
||||
lbValue res = {};
|
||||
res.value = LLVMBuildExtractValue(p->builder, s.value, cast(unsigned)index, "");
|
||||
@@ -1228,7 +1275,7 @@ lbValue lb_map_entries_ptr(lbProcedure *p, lbValue value) {
|
||||
GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t));
|
||||
init_map_internal_types(t);
|
||||
i32 index = 1;
|
||||
lbValue entries = lb_emit_struct_ep(p, value, index);
|
||||
lbValue entries = lb_emit_struct_ep(p, value, index);
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
@@ -2432,7 +2432,7 @@ Selection lookup_field_from_index(Type *type, i64 index) {
|
||||
for (isize i = 0; i < max_count; i++) {
|
||||
Entity *f = type->Struct.fields[i];
|
||||
if (f->kind == Entity_Variable) {
|
||||
if (f->Variable.field_src_index == index) {
|
||||
if (f->Variable.field_index == index) {
|
||||
auto sel_array = array_make<i32>(a, 1);
|
||||
sel_array[0] = cast(i32)i;
|
||||
return make_selection(f, sel_array, false);
|
||||
@@ -2972,7 +2972,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
return 1;
|
||||
}
|
||||
if (t->Union.custom_align > 0) {
|
||||
return gb_clamp(t->Union.custom_align, 1, build_context.max_align);
|
||||
return gb_max(t->Union.custom_align, 1);
|
||||
}
|
||||
|
||||
i64 max = 1;
|
||||
@@ -2993,7 +2993,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
|
||||
case Type_Struct: {
|
||||
if (t->Struct.custom_align > 0) {
|
||||
return gb_clamp(t->Struct.custom_align, 1, build_context.max_align);
|
||||
return gb_max(t->Struct.custom_align, 1);
|
||||
}
|
||||
if (t->Struct.is_raw_union) {
|
||||
i64 max = 1;
|
||||
|
||||
Reference in New Issue
Block a user