mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-19 21:10:30 +00:00
Fix any type and casting to any; Fix switch statement
This commit is contained in:
@@ -239,7 +239,7 @@ lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
|
||||
Type *tag_type = union_tag_type(ut);
|
||||
|
||||
lbValue tag_ptr = {};
|
||||
tag_ptr.value = LLVMBuildStructGEP2(p->builder, lb_type(p->module, type_deref(u.type)), u.value, 2, "");
|
||||
tag_ptr.value = LLVMBuildStructGEP(p->builder, u.value, 2, "");
|
||||
tag_ptr.type = alloc_type_pointer(tag_type);
|
||||
return tag_ptr;
|
||||
}
|
||||
@@ -475,7 +475,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
{
|
||||
LLVMTypeRef type = LLVMStructCreateNamed(ctx, "..any");
|
||||
LLVMTypeRef fields[2] = {
|
||||
LLVMPointerType(lb_type(m, t_rawptr), 0),
|
||||
lb_type(m, t_rawptr),
|
||||
lb_type(m, t_typeid),
|
||||
};
|
||||
LLVMStructSetBody(type, fields, 2, false);
|
||||
@@ -2174,9 +2174,6 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(ss, SwitchStmt, node);
|
||||
if (true) {
|
||||
return;
|
||||
}
|
||||
if (ss->init != nullptr) {
|
||||
lb_build_stmt(p, ss->init);
|
||||
}
|
||||
@@ -2259,7 +2256,6 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
lb_emit_if(p, cond, body, next_cond);
|
||||
lb_start_block(p, next_cond);
|
||||
}
|
||||
lb_emit_jump(p, body);
|
||||
lb_start_block(p, body);
|
||||
|
||||
lb_push_target_list(p, ss->label, done, nullptr, fall);
|
||||
@@ -2269,7 +2265,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
lb_pop_target_list(p);
|
||||
|
||||
lb_emit_jump(p, done);
|
||||
p->curr_block = next_cond;
|
||||
lb_start_block(p, next_cond);
|
||||
}
|
||||
|
||||
if (default_block != nullptr) {
|
||||
@@ -2282,6 +2278,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
lb_close_scope(p, lbDeferExit_Default, default_block);
|
||||
lb_pop_target_list(p);
|
||||
}
|
||||
|
||||
lb_emit_jump(p, done);
|
||||
lb_start_block(p, done);
|
||||
case_end;
|
||||
@@ -3403,9 +3400,18 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
|
||||
if (LLVMIsConstant(value.value)) {
|
||||
if (is_type_any(dst)) {
|
||||
lbAddr default_value = lb_add_local_generated(p, default_type(src_type), false);
|
||||
Type *st = default_type(src_type);
|
||||
lbAddr default_value = lb_add_local_generated(p, st, false);
|
||||
lb_addr_store(p, default_value, value);
|
||||
return lb_emit_conv(p, lb_addr_load(p, default_value), t_any);
|
||||
lbValue data = lb_emit_conv(p, default_value.addr, t_rawptr);
|
||||
lbValue id = lb_typeid(m, st);
|
||||
|
||||
lbAddr res = lb_add_local_generated(p, t, false);
|
||||
lbValue a0 = lb_emit_struct_ep(p, res.addr, 0);
|
||||
lbValue a1 = lb_emit_struct_ep(p, res.addr, 1);
|
||||
lb_emit_store(p, a0, data);
|
||||
lb_emit_store(p, a1, id);
|
||||
return lb_addr_load(p, res);
|
||||
} else if (dst->kind == Type_Basic) {
|
||||
if (src->Basic.kind == Basic_string && dst->Basic.kind == Basic_cstring) {
|
||||
// TODO(bill): This is kind of a hack
|
||||
@@ -3721,7 +3727,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
if (is_type_pointer(src) && is_type_pointer(dst)) {
|
||||
lbValue res = {};
|
||||
res.type = t;
|
||||
res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(m, t), "");
|
||||
res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -3731,7 +3737,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
if (is_type_proc(src) && is_type_proc(dst)) {
|
||||
lbValue res = {};
|
||||
res.type = t;
|
||||
res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(m, t), "");
|
||||
res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -3739,73 +3745,67 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
if (is_type_pointer(src) && is_type_proc(dst)) {
|
||||
lbValue res = {};
|
||||
res.type = t;
|
||||
res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(m, t), "");
|
||||
res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
// proc -> pointer
|
||||
if (is_type_proc(src) && is_type_pointer(dst)) {
|
||||
lbValue res = {};
|
||||
res.type = t;
|
||||
res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(m, t), "");
|
||||
res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// []byte/[]u8 <-> string
|
||||
if (is_type_u8_slice(src) && is_type_string(dst)) {
|
||||
lbValue elem = ir_slice_elem(p, value);
|
||||
lbValue len = ir_slice_len(p, value);
|
||||
return ir_emit_string(p, elem, len);
|
||||
return lb_emit_transmute(p, value, t);
|
||||
}
|
||||
if (is_type_string(src) && is_type_u8_slice(dst)) {
|
||||
lbValue elem = ir_string_elem(p, value);
|
||||
lbValue elem_ptr = lb_add_local_generated(p, ir_type(elem), false);
|
||||
lb_emit_store(p, elem_ptr, elem);
|
||||
|
||||
lbValue len = ir_string_len(p, value);
|
||||
lbValue slice = ir_add_local_slice(p, t, elem_ptr, v_zero, len);
|
||||
return lb_emit_load(p, slice);
|
||||
return lb_emit_transmute(p, value, t);
|
||||
}
|
||||
|
||||
if (is_type_array(dst)) {
|
||||
Type *elem = dst->Array.elem;
|
||||
lbValue e = lb_emit_conv(p, value, elem);
|
||||
// NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
|
||||
lbValue v = lb_add_local_generated(p, t, false);
|
||||
lbAddr v = lb_add_local_generated(p, t, false);
|
||||
isize index_count = cast(isize)dst->Array.count;
|
||||
|
||||
for (i32 i = 0; i < index_count; i++) {
|
||||
lbValue elem = ir_emit_array_epi(p, v, i);
|
||||
for (isize i = 0; i < index_count; i++) {
|
||||
lbValue elem = lb_emit_array_epi(p, v.addr, i);
|
||||
lb_emit_store(p, elem, e);
|
||||
}
|
||||
return lb_emit_load(p, v);
|
||||
return lb_addr_load(p, v);
|
||||
}
|
||||
|
||||
if (is_type_any(dst)) {
|
||||
lbValue result = lb_add_local_generated(p, t_any, true);
|
||||
|
||||
if (is_type_untyped_nil(src)) {
|
||||
return lb_emit_load(p, result);
|
||||
return lb_const_nil(p->module, t);
|
||||
}
|
||||
if (is_type_untyped_undef(src)) {
|
||||
return lb_const_undef(p->module, t);
|
||||
}
|
||||
|
||||
lbAddr result = lb_add_local_generated(p, t, true);
|
||||
|
||||
Type *st = default_type(src_type);
|
||||
|
||||
lbValue data = ir_address_from_load_or_generate_local(p, value);
|
||||
GB_ASSERT_MSG(is_type_pointer(ir_type(data)), type_to_string(ir_type(data)));
|
||||
lbValue data = lb_address_from_load_or_generate_local(p, value);
|
||||
GB_ASSERT_MSG(is_type_pointer(data.type), "%s", type_to_string(data.type));
|
||||
GB_ASSERT_MSG(is_type_typed(st), "%s", type_to_string(st));
|
||||
data = lb_emit_conv(p, data, t_rawptr);
|
||||
|
||||
|
||||
lbValue id = lb_typeid(p->module, st);
|
||||
lbValue any_data = lb_emit_struct_ep(p, result.addr, 0);
|
||||
lbValue any_id = lb_emit_struct_ep(p, result.addr, 1);
|
||||
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, result, 0), data);
|
||||
lb_emit_store(p, lb_emit_struct_ep(p, result, 1), id);
|
||||
lb_emit_store(p, any_data, data);
|
||||
lb_emit_store(p, any_id, id);
|
||||
|
||||
return lb_emit_load(p, result);
|
||||
return lb_addr_load(p, result);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_type_untyped(src)) {
|
||||
if (is_type_string(src) && is_type_string(dst)) {
|
||||
@@ -3915,6 +3915,11 @@ lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (is_type_pointer(src) && is_type_pointer(dst)) {
|
||||
res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(p->module, t), "");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (lb_is_type_aggregate(src) || lb_is_type_aggregate(dst)) {
|
||||
lbValue s = lb_address_from_load_or_generate_local(p, value);
|
||||
lbValue d = lb_emit_transmute(p, s, alloc_type_pointer(t));
|
||||
@@ -3997,60 +4002,59 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
||||
}
|
||||
|
||||
if (is_type_struct(t)) {
|
||||
result_type = alloc_type_pointer(t->Struct.fields[index]->type);
|
||||
result_type = t->Struct.fields[index]->type;
|
||||
} else if (is_type_union(t)) {
|
||||
GB_ASSERT(index == -1);
|
||||
// return ir_emit_union_tag_ptr(p, s);
|
||||
GB_PANIC("ir_emit_union_tag_ptr");
|
||||
return lb_emit_union_tag_ptr(p, s);
|
||||
} else if (is_type_tuple(t)) {
|
||||
GB_ASSERT(t->Tuple.variables.count > 0);
|
||||
result_type = alloc_type_pointer(t->Tuple.variables[index]->type);
|
||||
result_type = t->Tuple.variables[index]->type;
|
||||
} else if (is_type_complex(t)) {
|
||||
Type *ft = base_complex_elem_type(t);
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(ft); break;
|
||||
case 1: result_type = alloc_type_pointer(ft); break;
|
||||
case 0: result_type = ft; break;
|
||||
case 1: result_type = ft; break;
|
||||
}
|
||||
} else if (is_type_quaternion(t)) {
|
||||
Type *ft = base_complex_elem_type(t);
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(ft); break;
|
||||
case 1: result_type = alloc_type_pointer(ft); break;
|
||||
case 2: result_type = alloc_type_pointer(ft); break;
|
||||
case 3: result_type = alloc_type_pointer(ft); break;
|
||||
case 0: result_type = ft; break;
|
||||
case 1: result_type = ft; break;
|
||||
case 2: result_type = ft; break;
|
||||
case 3: result_type = ft; break;
|
||||
}
|
||||
} else if (is_type_slice(t)) {
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(alloc_type_pointer(t->Slice.elem)); break;
|
||||
case 1: result_type = alloc_type_pointer(t_int); break;
|
||||
case 0: result_type = alloc_type_pointer(t->Slice.elem); break;
|
||||
case 1: result_type = t_int; break;
|
||||
}
|
||||
} else if (is_type_string(t)) {
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(t_u8_ptr); break;
|
||||
case 1: result_type = alloc_type_pointer(t_int); break;
|
||||
case 0: result_type = t_u8_ptr; break;
|
||||
case 1: result_type = t_int; break;
|
||||
}
|
||||
} else if (is_type_any(t)) {
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(t_rawptr); break;
|
||||
case 1: result_type = alloc_type_pointer(t_typeid); break;
|
||||
case 0: result_type = t_rawptr; break;
|
||||
case 1: result_type = t_typeid; break;
|
||||
}
|
||||
} else if (is_type_dynamic_array(t)) {
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(alloc_type_pointer(t->DynamicArray.elem)); break;
|
||||
case 1: result_type = t_int_ptr; break;
|
||||
case 2: result_type = t_int_ptr; break;
|
||||
case 3: result_type = t_allocator_ptr; break;
|
||||
case 0: result_type = alloc_type_pointer(t->DynamicArray.elem); break;
|
||||
case 1: result_type = t_int; break;
|
||||
case 2: result_type = t_int; break;
|
||||
case 3: result_type = t_allocator; break;
|
||||
}
|
||||
} else if (is_type_map(t)) {
|
||||
init_map_internal_types(t);
|
||||
Type *itp = alloc_type_pointer(t->Map.internal_type);
|
||||
Type *itp = (t->Map.internal_type);
|
||||
s = lb_emit_transmute(p, s, itp);
|
||||
|
||||
Type *gst = t->Map.internal_type;
|
||||
GB_ASSERT(gst->kind == Type_Struct);
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(gst->Struct.fields[0]->type); break;
|
||||
case 1: result_type = alloc_type_pointer(gst->Struct.fields[1]->type); break;
|
||||
case 0: result_type = gst->Struct.fields[0]->type; break;
|
||||
case 1: result_type = gst->Struct.fields[1]->type; break;
|
||||
}
|
||||
} else if (is_type_array(t)) {
|
||||
return lb_emit_array_epi(p, s, index);
|
||||
@@ -4061,8 +4065,8 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
||||
GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
|
||||
|
||||
lbValue res = {};
|
||||
res.value = LLVMBuildStructGEP2(p->builder, lb_type(p->module, type_deref(s.type)), s.value, cast(unsigned)index, "");
|
||||
res.type = result_type;
|
||||
res.value = LLVMBuildStructGEP(p->builder, s.value, cast(unsigned)index, "");
|
||||
res.type = alloc_type_pointer(result_type);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -7739,7 +7743,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
if (entry_index <= 0) {
|
||||
continue;
|
||||
}
|
||||
gb_printf_err("%s @ %td | %.*s\n", type_to_string(t), entry_index, LIT(type_strings[t->kind]));
|
||||
|
||||
// gb_printf_err("%s @ %td | %.*s\n", type_to_string(t), entry_index, LIT(type_strings[t->kind
|
||||
|
||||
lbValue tag = {};
|
||||
lbValue ti_ptr = lb_emit_array_epi(p, lb_global_type_info_data.addr, cast(i32)entry_index);
|
||||
|
||||
Reference in New Issue
Block a user