diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 89ac18068..6daa552da 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -158,10 +158,10 @@ fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) { sbprint :: proc(buf: ^strings.Builder, args: ..any) -> string { fi: Info; - prev_string := false; fi.buf = buf; + prev_string := false; for arg, i in args { is_string := arg != nil && reflect.is_string(type_info_of(arg.id)); if i > 0 && !is_string && !prev_string { @@ -937,23 +937,68 @@ enum_value_to_string :: proc(val: any) -> (string, bool) { #partial switch e in type_info.variant { case: return "", false; case runtime.Type_Info_Enum: - get_str :: proc(data: rawptr, e: runtime.Type_Info_Enum) -> (string, bool) { + Enum_Value :: runtime.Type_Info_Enum_Value; + + ev: Enum_Value; + ok := true; + + bv := v; + bv.id = runtime.typeid_core(e.base.id); + + switch i in bv { + case i8: ev = Enum_Value(i); + case i16: ev = Enum_Value(i); + case i32: ev = Enum_Value(i); + case i64: ev = Enum_Value(i); + case i128: ev = Enum_Value(i); + + case int: ev = Enum_Value(i); + + case u8: ev = Enum_Value(i); + case u16: ev = Enum_Value(i); + case u32: ev = Enum_Value(i); + case u64: ev = Enum_Value(i); + case u128: ev = Enum_Value(i); + case uint: ev = Enum_Value(i); + + case uintptr: ev = Enum_Value(i); + + case i16le: ev = Enum_Value(i); + case i32le: ev = Enum_Value(i); + case i64le: ev = Enum_Value(i); + case i128le: ev = Enum_Value(i); + + case u16le: ev = Enum_Value(i); + case u32le: ev = Enum_Value(i); + case u64le: ev = Enum_Value(i); + case u128le: ev = Enum_Value(i); + + case i16be: ev = Enum_Value(i); + case i32be: ev = Enum_Value(i); + case i64be: ev = Enum_Value(i); + case i128be: ev = Enum_Value(i); + + case u16be: ev = Enum_Value(i); + case u32be: ev = Enum_Value(i); + case u64be: ev = Enum_Value(i); + case u128be: ev = Enum_Value(i); + + case: + ok = false; + } + + if ok { if len(e.values) == 0 { return "", true; } else { - for _, idx in e.values { - val := &e.values[idx]; - // NOTE(bill): Removes need for parametric polymorphic check - res := mem.compare_ptrs(val, data, e.base.size); - if res == 0 { + for val, idx in e.values { + if val == ev { return e.names[idx], true; } } } return "", false; } - - return get_str(v.data, e); } return "", false; @@ -1001,81 +1046,28 @@ stored_enum_value_to_string :: proc(enum_type: ^runtime.Type_Info, ev: runtime.T #partial switch e in et.variant { case: return "", false; case runtime.Type_Info_Enum: - get_str :: proc(i: $T, e: runtime.Type_Info_Enum) -> (string, bool) { - if reflect.is_string(e.base) { - for val, idx in e.values { - if v, ok := val.(T); ok && v == i { - return e.names[idx], true; - } - } - } else if len(e.values) == 0 { - return "", true; - } else { - for val, idx in e.values { - if v, ok := val.(T); ok && v == i { - return e.names[idx], true; - } + if reflect.is_string(e.base) { + for val, idx in e.values { + if val == ev { + return e.names[idx], true; + } + } + } else if len(e.values) == 0 { + return "", true; + } else { + for val, idx in e.values { + if val == ev { + return e.names[idx], true; } } - return "", false; - } - - switch v in ev { - case rune: return get_str(v + auto_cast offset, e); - case i8: return get_str(v + auto_cast offset, e); - case i16: return get_str(v + auto_cast offset, e); - case i32: return get_str(v + auto_cast offset, e); - case i64: return get_str(v + auto_cast offset, e); - case int: return get_str(v + auto_cast offset, e); - case u8: return get_str(v + auto_cast offset, e); - case u16: return get_str(v + auto_cast offset, e); - case u32: return get_str(v + auto_cast offset, e); - case u64: return get_str(v + auto_cast offset, e); - case uint: return get_str(v + auto_cast offset, e); - case uintptr: return get_str(v + auto_cast offset, e); } + return "", false; } return "", false; } -enum_value_to_u64 :: proc(ev: runtime.Type_Info_Enum_Value) -> u64 { - switch i in ev { - case rune: return u64(i); - case i8: return u64(i); - case i16: return u64(i); - case i32: return u64(i); - case i64: return u64(i); - case int: return u64(i); - case u8: return u64(i); - case u16: return u64(i); - case u32: return u64(i); - case u64: return u64(i); - case uint: return u64(i); - case uintptr: return u64(i); - } - return 0; -} - -enum_value_to_i64 :: proc(ev: runtime.Type_Info_Enum_Value) -> i64 { - switch i in ev { - case rune: return i64(i); - case i8: return i64(i); - case i16: return i64(i); - case i32: return i64(i); - case i64: return i64(i); - case int: return i64(i); - case u8: return i64(i); - case u16: return i64(i); - case u32: return i64(i); - case u64: return i64(i); - case uint: return i64(i); - case uintptr: return i64(i); - } - return 0; -} - fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool { if ti == nil { @@ -1152,7 +1144,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { if commas > 0 do strings.write_string(fi.buf, ", "); if is_enum do for ev, evi in e.values { - v := enum_value_to_u64(ev); + v := u64(ev); if v == u64(i) { strings.write_string(fi.buf, e.names[evi]); commas += 1; @@ -1437,7 +1429,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { strings.write_byte(fi.buf, '.'); strings.write_string(fi.buf, idx); } else { - strings.write_i64(fi.buf, enum_value_to_i64(info.min_value)+i64(i)); + strings.write_i64(fi.buf, i64(info.min_value)+i64(i)); } strings.write_string(fi.buf, " = "); diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 5399db9a3..19f2b1146 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -34,11 +34,7 @@ Calling_Convention :: enum u8 { Fast = 5, } -Type_Info_Enum_Value :: union { - rune, - i8, i16, i32, i64, int, - u8, u16, u32, u64, uint, uintptr, -}; +Type_Info_Enum_Value :: distinct i64; Platform_Endianness :: enum u8 { Platform = 0, diff --git a/src/ir.cpp b/src/ir.cpp index 066089211..381c24459 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -9799,7 +9799,7 @@ void ir_build_range_enum(irProcedure *proc, Type *enum_type, Type *val_type, irV GB_ASSERT(are_types_identical(enum_type, val_type)); if (is_type_integer(core_elem)) { - irValue *i = ir_emit_load(proc, ir_emit_conv(proc, val_ptr, t_i64_ptr)); + irValue *i = ir_emit_load(proc, val_ptr); val = ir_emit_conv(proc, i, t); } else { GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem)); @@ -11812,8 +11812,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *min_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.min_value); irValue *max_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.max_value); - ir_emit_store_union_variant(proc, min_value, min_v, ir_type(min_v)); - ir_emit_store_union_variant(proc, max_value, max_v, ir_type(max_v)); + ir_emit_store(proc, min_value, min_v); + ir_emit_store(proc, max_value, max_v); break; } case Type_DynamicArray: { @@ -11907,9 +11907,9 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *value_ep = ir_emit_array_epi(proc, value_array, cast(i32)i); ExactValue value = fields[i]->Constant.value; - irValue *v = ir_value_constant(t->Enum.base_type, value); + irValue *v = ir_value_constant(t_i64, value); - ir_emit_store_union_variant(proc, value_ep, v, ir_type(v)); + ir_emit_store(proc, value_ep, v); ir_emit_store(proc, name_ep, ir_const_string(proc->module, fields[i]->token.string)); } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f8a54c066..be0b09372 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2027,6 +2027,11 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { p->value = LLVMAddFunction(m->mod, c_link_name, func_type); + lbCallingConventionKind cc_kind = lbCallingConvention_C; + // TODO(bill): Clean up this logic + if (build_context.metrics.os != TargetOs_js) { + cc_kind = lb_calling_convention_map[pt->Proc.calling_convention]; + } LLVMSetFunctionCallConv(p->value, lb_calling_convention_map[pt->Proc.calling_convention]); lbValue proc_value = {p->value, p->type}; lb_add_entity(m, entity, proc_value); @@ -4464,6 +4469,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) { LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); LLVMSetInitializer(global_data, data); + LLVMSetLinkage(global_data, LLVMInternalLinkage); LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); string_map_set(&m->const_strings, key, ptr); @@ -4500,6 +4506,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) } LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); LLVMSetInitializer(global_data, data); + LLVMSetLinkage(global_data, LLVMInternalLinkage); LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true); @@ -11211,22 +11218,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da LLVMTypeRef align_type = lb_alignment_prefix_type_hack(m, type_align_of(t)); LLVMTypeRef array_type = LLVMArrayType(lb_type(m, t_u8), 8); - LLVMTypeRef u64_type = lb_type(m, t_u64); for_array(i, fields) { - ExactValue value = fields[i]->Constant.value; - lbValue v = lb_const_value(m, t->Enum.base_type, value); - LLVMValueRef zv = LLVMConstZExt(v.value, u64_type); - lbValue tag = lb_const_union_tag(m, t_type_info_enum_value, v.type); - - LLVMValueRef vals[3] = { - LLVMConstNull(align_type), - zv, - tag.value, - }; - name_values[i] = lb_const_string(m, fields[i]->token.string).value; - value_values[i] = LLVMConstStruct(vals, gb_count_of(vals), false); + value_values[i] = lb_const_value(m, t_i64, fields[i]->Constant.value).value; } LLVMValueRef name_init = LLVMConstArray(lb_type(m, t_string), name_values, cast(unsigned)fields.count); @@ -12211,21 +12206,25 @@ void lb_generate_code(lbGenerator *gen) { } + LLVMDIBuilderFinalize(m->debug_builder); + if (LLVMVerifyModule(mod, LLVMAbortProcessAction, &llvm_error)) { + gb_printf_err("LLVM Error: %s\n", llvm_error); + return; + } + llvm_error = nullptr; if (build_context.keep_temp_files) { TIME_SECTION("LLVM Print Module to File"); - LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error); - // exit(1); + if (LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error)) { + gb_printf_err("LLVM Error: %s\n", llvm_error); + return; + } } - LLVMDIBuilderFinalize(m->debug_builder); - LLVMVerifyModule(mod, LLVMAbortProcessAction, &llvm_error); - llvm_error = nullptr; TIME_SECTION("LLVM Object Generation"); LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile; - LLVMBool was_an_error = LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error); - if (was_an_error) { + if (LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) { gb_printf_err("LLVM Error: %s\n", llvm_error); gb_exit(1); return;