From 08a081ed45520eac4c4ebd8501fa3ab7970b5c77 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 11 Dec 2021 17:42:58 +0000 Subject: Improve debug symbol retention with `-debug -opt:0` --- src/llvm_backend_opt.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index de925655f..5b8468799 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -48,12 +48,6 @@ LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data return LLVMIsAAllocaInst(value) != nullptr; } -void lb_add_must_preserve_predicate_pass(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level) { - if (false && optimization_level == 0 && m->debug_builder) { - // LLVMAddInternalizePassWithMustPreservePredicate(fpm, m, lb_must_preserve_predicate_callback); - } -} - #if LLVM_VERSION_MAJOR < 12 #define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) LLVMAddConstantPropagationPass(fpm) @@ -61,7 +55,10 @@ void lb_add_must_preserve_predicate_pass(lbModule *m, LLVMPassManagerRef fpm, i3 #define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) #endif -void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm) { +void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, i32 optimization_level) { + if (optimization_level == 0 && build_context.ODIN_DEBUG) { + return; + } LLVMAddPromoteMemoryToRegisterPass(fpm); LLVMAddMergedLoadStoreMotionPass(fpm); LLVM_ADD_CONSTANT_VALUE_PASS(fpm); @@ -78,14 +75,12 @@ void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool // TODO(bill): Determine which opt definitions should exist in the first place optimization_level = gb_clamp(optimization_level, 0, 2); - lb_add_must_preserve_predicate_pass(m, fpm, optimization_level); - if (ignore_memcpy_pass) { - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); return; } else if (optimization_level == 0) { LLVMAddMemCpyOptPass(fpm); - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); return; } @@ -96,7 +91,7 @@ void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool LLVMPassManagerBuilderPopulateFunctionPassManager(pmb, fpm); #else LLVMAddMemCpyOptPass(fpm); - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); LLVMAddSCCPPass(fpm); @@ -114,11 +109,9 @@ void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef // TODO(bill): Determine which opt definitions should exist in the first place optimization_level = gb_clamp(optimization_level, 0, 2); - lb_add_must_preserve_predicate_pass(m, fpm, optimization_level); - if (optimization_level == 0) { LLVMAddMemCpyOptPass(fpm); - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); return; } @@ -191,6 +184,9 @@ void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPa // NOTE(bill): Treat -opt:3 as if it was -opt:2 // TODO(bill): Determine which opt definitions should exist in the first place optimization_level = gb_clamp(optimization_level, 0, 2); + if (optimization_level == 0 && build_context.ODIN_DEBUG) { + return; + } LLVMAddAlwaysInlinerPass(mpm); LLVMAddStripDeadPrototypesPass(mpm); -- cgit v1.2.3 From 0548db423067bce16d45af651819bf56feb5d411 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 17 Dec 2021 11:06:17 +0000 Subject: Disallow `@(static)` and `@(thread_local)` within `defer` statements --- src/check_stmt.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 1a424240c..396388629 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -2243,6 +2243,9 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { error(e->token, "The 'static' attribute is not allowed to be applied to '_'"); } else { e->flags |= EntityFlag_Static; + if (ctx->in_defer) { + error(e->token, "'static' variables cannot be declared within a defer statement"); + } } } if (ac.thread_local_model != "") { @@ -2251,9 +2254,13 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { error(e->token, "The 'thread_local' attribute is not allowed to be applied to '_'"); } else { e->flags |= EntityFlag_Static; + if (ctx->in_defer) { + error(e->token, "'thread_local' variables cannot be declared within a defer statement"); + } } e->Variable.thread_local_model = ac.thread_local_model; } + if (ac.is_static && ac.thread_local_model != "") { error(e->token, "The 'static' attribute is not needed if 'thread_local' is applied"); -- cgit v1.2.3 From a48317deee95b956430ace83f0db3e34bef590dd Mon Sep 17 00:00:00 2001 From: Wes Hardee Date: Sat, 18 Dec 2021 12:43:24 -0600 Subject: use '___$startup_runtime' for MacOS MacOS needs 3 underscores unlike the 2 needed by Linux. --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 7b4bc92ee..36b30112f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -439,13 +439,14 @@ i32 linker_stage(lbGenerator *gen) { // so use ld instead. // :UseLDForShared linker = "ld"; - link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' "); // Shared libraries are .dylib on MacOS and .so on Linux. #if defined(GB_SYSTEM_OSX) output_ext = STR_LIT(".dylib"); + link_settings = gb_string_appendc(link_settings, "-init '___$startup_runtime' "); link_settings = gb_string_appendc(link_settings, "-dylib -dynamic "); #else output_ext = STR_LIT(".so"); + link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' "); link_settings = gb_string_appendc(link_settings, "-shared "); #endif } else { -- cgit v1.2.3 From 8dbeed8a9faba5b341823ae3a4ea4f7a453f3f87 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Thu, 23 Dec 2021 01:59:31 +0100 Subject: Removes unneeded lookups / Adds sret to call site which fixes the mac bug --- src/llvm_abi.cpp | 12 ++++++------ src/llvm_backend_proc.cpp | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index e18dc344b..c30f6531a 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -981,16 +981,16 @@ namespace lbAbiArm64 { if (size <= 16) { LLVMTypeRef cast_type = nullptr; if (size <= 1) { - cast_type = LLVMIntTypeInContext(c, 8); + cast_type = LLVMInt8TypeInContext(c); } else if (size <= 2) { - cast_type = LLVMIntTypeInContext(c, 16); + cast_type = LLVMInt16TypeInContext(c); } else if (size <= 4) { - cast_type = LLVMIntTypeInContext(c, 32); + cast_type = LLVMInt32TypeInContext(c); } else if (size <= 8) { - cast_type = LLVMIntTypeInContext(c, 64); + cast_type = LLVMInt64TypeInContext(c); } else { unsigned count = cast(unsigned)((size+7)/8); - cast_type = LLVMArrayType(LLVMIntTypeInContext(c, 64), count); + cast_type = LLVMArrayType(LLVMInt64TypeInContext(c), count); } return lb_arg_type_direct(type, cast_type, nullptr, nullptr); } else { @@ -999,7 +999,7 @@ namespace lbAbiArm64 { } } } - + Array compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) { auto args = array_make(heap_allocator(), arg_count); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 25b27ee47..84fddd9e2 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -736,6 +736,10 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, ""); + if (return_ptr.value != nullptr) { + LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0]))); + } + switch (inlining) { case ProcInlining_none: break; -- cgit v1.2.3 From dce120258fbca70dfaa9a738bc168463df7a3dda Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Thu, 23 Dec 2021 02:46:32 +0000 Subject: src: Add preliminary support for Linux AArch64 Tested via `tests/core`, on a Raspberry Pi 4 running the latest 64-bit Raspberry Pi OS image (LLVM 11). --- src/build_settings.cpp | 14 ++++++++++++++ src/gb/gb.h | 2 ++ src/threading.cpp | 4 ++++ 3 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 29abd441c..b8d50898d 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -300,6 +300,14 @@ gb_global TargetMetrics target_linux_amd64 = { str_lit("x86_64-pc-linux-gnu"), str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; +gb_global TargetMetrics target_linux_arm64 = { + TargetOs_linux, + TargetArch_arm64, + 8, + 16, + str_lit("aarch64-linux-elf"), + str_lit("e-m:e-i8:8:32-i16:32-i64:64-i128:128-n32:64-S128"), +}; gb_global TargetMetrics target_darwin_amd64 = { TargetOs_darwin, @@ -394,6 +402,7 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("essence_amd64"), &target_essence_amd64 }, { str_lit("linux_386"), &target_linux_386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, + { str_lit("linux_arm64"), &target_linux_arm64 }, { str_lit("windows_386"), &target_windows_386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, { str_lit("freebsd_386"), &target_freebsd_386 }, @@ -880,6 +889,8 @@ void init_build_context(TargetMetrics *cross_target) { #endif #elif defined(GB_SYSTEM_FREEBSD) metrics = &target_freebsd_amd64; + #elif defined(GB_CPU_ARM) + metrics = &target_linux_arm64; #else metrics = &target_linux_amd64; #endif @@ -959,6 +970,9 @@ void init_build_context(TargetMetrics *cross_target) { case TargetOs_darwin: bc->link_flags = str_lit("-arch arm64 "); break; + case TargetOs_linux: + bc->link_flags = str_lit("-arch aarch64 "); + break; } } else if (is_arch_wasm()) { gbString link_flags = gb_string_make(heap_allocator(), " "); diff --git a/src/gb/gb.h b/src/gb/gb.h index f716b0840..d9bf09436 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -3355,6 +3355,8 @@ gb_inline u32 gb_thread_current_id(void) { __asm__("mov %%gs:0x08,%0" : "=r"(thread_id)); #elif defined(GB_ARCH_64_BIT) && defined(GB_CPU_X86) __asm__("mov %%fs:0x10,%0" : "=r"(thread_id)); +#elif defined(GB_SYSTEM_LINUX) + thread_id = gettid(); #else #error Unsupported architecture for gb_thread_current_id() #endif diff --git a/src/threading.cpp b/src/threading.cpp index e9412b411..b318e4ff1 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -296,6 +296,8 @@ u32 thread_current_id(void) { __asm__("mov %%gs:0x08,%0" : "=r"(thread_id)); #elif defined(GB_ARCH_64_BIT) && defined(GB_CPU_X86) __asm__("mov %%fs:0x10,%0" : "=r"(thread_id)); +#elif defined(GB_SYSTEM_LINUX) + thread_id = gettid(); #else #error Unsupported architecture for thread_current_id() #endif @@ -315,6 +317,8 @@ gb_inline void yield_thread(void) { #endif #elif defined(GB_CPU_X86) _mm_pause(); +#elif defined(GB_CPU_ARM) + __asm__ volatile ("yield" : : : "memory"); #else #error Unknown architecture #endif -- cgit v1.2.3 From 86f831ddd19e5f4e21179b32d603a6ae2cc6ce2f Mon Sep 17 00:00:00 2001 From: Platin21 Date: Mon, 27 Dec 2021 22:10:52 +0100 Subject: This adds code which checks how big the return is and if it is to big returns the value via sret --- src/llvm_abi.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index c30f6531a..42f05bb27 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -965,6 +965,10 @@ namespace lbAbiArm64 { } return false; } + + unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef *base_type_, unsigned member_count_) { + return (member_count_ <= 4); + } lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef type, bool return_is_defined) { LLVMTypeRef homo_base_type = {}; @@ -975,7 +979,16 @@ namespace lbAbiArm64 { } else if (is_register(type)) { return non_struct(c, type); } else if (is_homogenous_aggregate(c, type, &homo_base_type, &homo_member_count)) { - return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr); + if(is_homogenous_aggregate_small_enough(&homo_base_type, homo_member_count)) { + return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr); + } else { + //TODO(Platin): do i need to create stuff that can handle the diffrent return type? + // else this needs a fix in llvm_backend_proc as we would need to cast it to the correct array type + + //LLVMTypeRef array_type = LLVMArrayType(homo_base_type, homo_member_count); + LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", type); + return lb_arg_type_indirect(type, attr); + } } else { i64 size = lb_sizeof(type); if (size <= 16) { -- cgit v1.2.3 From ed742846cb6447d9d9ff6a4cfde285d7f4bb0eb9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 29 Dec 2021 15:01:56 +0000 Subject: Correct `lb_emit_ptr_offset` bug caused by `LLVMConstGEP` assuming a signed index --- src/llvm_backend_utility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 0350f7287..3fe96459f 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1200,7 +1200,7 @@ lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) { } lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) { - index = lb_correct_endianness(p, index); + index = lb_emit_conv(p, index, t_int); LLVMValueRef indices[1] = {index.value}; lbValue res = {}; res.type = ptr.type; -- cgit v1.2.3 From bdf66bb1e1096690be66eda90b35c6cfdc8a5cf0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 31 Dec 2021 22:54:12 +0000 Subject: Correct `abs` type behaviour for quaternions --- src/check_builtin.cpp | 13 ++++++++++--- src/types.cpp | 7 +++++++ 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index f93cf9886..dc8c209c9 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1858,7 +1858,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 f64 r = operand->value.value_complex->real; f64 i = operand->value.value_complex->imag; operand->value = exact_value_float(gb_sqrt(r*r + i*i)); - + break; + } + case ExactValue_Quaternion: { + f64 r = operand->value.value_quaternion->real; + f64 i = operand->value.value_quaternion->imag; + f64 j = operand->value.value_quaternion->jmag; + f64 k = operand->value.value_quaternion->kmag; + operand->value = exact_value_float(gb_sqrt(r*r + i*i + j*j + k*k)); break; } default: @@ -1877,10 +1884,10 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } } - if (is_type_complex(operand->type)) { + if (is_type_complex_or_quaternion(operand->type)) { operand->type = base_complex_elem_type(operand->type); } - GB_ASSERT(!is_type_complex(operand->type)); + GB_ASSERT(!is_type_complex_or_quaternion(operand->type)); break; } diff --git a/src/types.cpp b/src/types.cpp index 2b7ea93dc..f621d4346 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1253,6 +1253,13 @@ bool is_type_quaternion(Type *t) { } return false; } +bool is_type_complex_or_quaternion(Type *t) { + t = core_type(t); + if (t->kind == Type_Basic) { + return (t->Basic.flags & (BasicFlag_Complex|BasicFlag_Quaternion)) != 0; + } + return false; +} bool is_type_f16(Type *t) { t = core_type(t); if (t->kind == Type_Basic) { -- cgit v1.2.3 From 0d7cb02386c765f6f4fe343b463e84c3a7c1d1fc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 31 Dec 2021 23:20:14 +0000 Subject: Fix conversion from float to quaternion --- core/math/linalg/extended.odin | 4 ++-- src/check_expr.cpp | 7 +++++++ src/llvm_backend_expr.cpp | 30 +++++++----------------------- 3 files changed, 16 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/core/math/linalg/extended.odin b/core/math/linalg/extended.odin index ba64356ce..c2bf5552a 100644 --- a/core/math/linalg/extended.odin +++ b/core/math/linalg/extended.odin @@ -103,10 +103,10 @@ max :: proc{max_single, max_double, max_triple} abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) { when IS_ARRAY(T) { for i in 0.. Date: Sun, 2 Jan 2022 14:45:39 +0000 Subject: Fix #1381 --- src/parser.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/parser.cpp b/src/parser.cpp index cbd4d61d5..5bf43cee9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5362,6 +5362,15 @@ isize calc_decl_count(Ast *decl) { count += calc_decl_count(decl->BlockStmt.stmts.data[i]); } break; + case Ast_WhenStmt: + { + isize inner_count = calc_decl_count(decl->WhenStmt.body); + if (decl->WhenStmt.else_stmt) { + inner_count = gb_max(inner_count, calc_decl_count(decl->WhenStmt.else_stmt)); + } + count += inner_count; + } + break; case Ast_ValueDecl: count = decl->ValueDecl.names.count; break; -- cgit v1.2.3 From 65434911489fdb5b9136b3b06b279a07137d7415 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 2 Jan 2022 15:31:47 +0000 Subject: Clean up code for queue (no logic changed) --- src/queue.cpp | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/queue.cpp b/src/queue.cpp index d69a2845c..ee8b1b086 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -71,6 +71,29 @@ void mpmc_destroy(MPMCQueue *q) { } +template +bool mpmc_internal_grow(MPMCQueue *q) { + mutex_lock(&q->mutex); + i32 old_size = q->mask+1; + i32 new_size = old_size*2; + resize_array_raw(&q->nodes, q->allocator, old_size, new_size); + if (q->nodes == nullptr) { + GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); + mutex_unlock(&q->mutex); + return false; + } + resize_array_raw(&q->indices, q->allocator, old_size, new_size); + if (q->indices == nullptr) { + GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); + mutex_unlock(&q->mutex); + return false; + } + mpmc_internal_init_indices(q->indices, old_size, new_size); + q->mask = new_size-1; + mutex_unlock(&q->mutex); + return true; +} + template i32 mpmc_enqueue(MPMCQueue *q, T const &data) { GB_ASSERT(q->mask != 0); @@ -78,8 +101,9 @@ i32 mpmc_enqueue(MPMCQueue *q, T const &data) { i32 head_idx = q->head_idx.load(std::memory_order_relaxed); for (;;) { - auto node = &q->nodes[head_idx & q->mask]; - auto node_idx_ptr = &q->indices[head_idx & q->mask]; + i32 index = head_idx & q->mask; + auto node = &q->nodes[index]; + auto node_idx_ptr = &q->indices[index]; i32 node_idx = node_idx_ptr->load(std::memory_order_acquire); i32 diff = node_idx - head_idx; @@ -91,24 +115,9 @@ i32 mpmc_enqueue(MPMCQueue *q, T const &data) { return q->count.fetch_add(1, std::memory_order_release); } } else if (diff < 0) { - mutex_lock(&q->mutex); - i32 old_size = q->mask+1; - i32 new_size = old_size*2; - resize_array_raw(&q->nodes, q->allocator, old_size, new_size); - if (q->nodes == nullptr) { - GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); - mutex_unlock(&q->mutex); - return -1; - } - resize_array_raw(&q->indices, q->allocator, old_size, new_size); - if (q->indices == nullptr) { - GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); - mutex_unlock(&q->mutex); + if (!mpmc_internal_grow(q)) { return -1; } - mpmc_internal_init_indices(q->indices, old_size, new_size); - q->mask = new_size-1; - mutex_unlock(&q->mutex); } else { head_idx = q->head_idx.load(std::memory_order_relaxed); } -- cgit v1.2.3 From 236b08cb4921d5c6000d5029f2936271acb45f29 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 3 Jan 2022 12:51:32 +0000 Subject: Fix #1356 --- src/check_type.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/check_type.cpp b/src/check_type.cpp index b4f30d2f0..282da4d0a 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -922,20 +922,19 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no i64 lower = big_int_to_i64(&i); i64 upper = big_int_to_i64(&j); - bool lower_changed = false; + i64 actual_lower = lower; i64 bits = MAX_BITS; if (type->BitSet.underlying != nullptr) { bits = 8*type_size_of(type->BitSet.underlying); if (lower > 0) { - lower = 0; - lower_changed = true; + actual_lower = 0; } else if (lower < 0) { error(bs->elem, "bit_set does not allow a negative lower bound (%lld) when an underlying type is set", lower); } } - i64 bits_required = upper-lower; + i64 bits_required = upper-actual_lower; switch (be->op.kind) { case Token_Ellipsis: case Token_RangeFull: @@ -959,7 +958,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no break; } if (!is_valid) { - if (lower_changed) { + if (actual_lower != lower) { error(bs->elem, "bit_set range is greater than %lld bits, %lld bits are required (internal the lower changed was changed 0 as an underlying type was set)", bits, bits_required); } else { error(bs->elem, "bit_set range is greater than %lld bits, %lld bits are required", bits, bits_required); -- cgit v1.2.3 From e6b8f7e77a419c8ff9e5f7de23fe15bef63264b1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 3 Jan 2022 12:54:31 +0000 Subject: Fix #1398 --- src/check_expr.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 67e2f3bd7..cfffffd9f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7688,6 +7688,14 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type } } + if (t->kind == Type_Matrix) { + if (cl->elems.count > 0 && cl->elems[0]->kind != Ast_FieldValue) { + if (0 < max && max < max_type_count) { + error(node, "Expected %lld values for this matrix literal, got %lld", cast(long long)max_type_count, cast(long long)max); + } + } + } + break; } -- cgit v1.2.3 From 12f459b5fb7904bfa926b5ad3fc5f80c6b5b4193 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 3 Jan 2022 13:12:39 +0000 Subject: Fix #1344 --- src/check_stmt.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src') diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 396388629..c3b8c46ca 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -58,6 +58,30 @@ bool contains_deferred_call(Ast *node) { return false; } +Ast *last_stmt_blocking_in_list(Slice const &stmts) { + for_array(i, stmts) { + Ast *n = stmts[i]; + switch (n->kind) { + case Ast_ReturnStmt: + return n; + case Ast_BranchStmt: + return n; + case Ast_ExprStmt: + if (is_diverging_stmt(n)) { + return n; + } + break; + case Ast_BlockStmt: + n = last_stmt_blocking_in_list(n->BlockStmt.stmts); + if (n != nullptr) { + return n; + } + break; + } + } + return nullptr; +} + void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { if (stmts.count == 0) { return; @@ -102,6 +126,7 @@ void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) check_stmt(ctx, n, new_flags); if (i+1 < max_non_constant_declaration) { + never_executed_error:; switch (n->kind) { case Ast_ReturnStmt: error(n, "Statements after this 'return' are never executed"); @@ -116,6 +141,13 @@ void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) error(n, "Statements after a diverging procedure call are never executed"); } break; + + case Ast_BlockStmt: + n = last_stmt_blocking_in_list(n->BlockStmt.stmts); + if (n != nullptr) { + goto never_executed_error; + } + break; } } else if (i+1 == max_non_constant_declaration) { if (is_diverging_stmt(n)) { -- cgit v1.2.3 From defc1672c3d1b27c4720f53e95a0e1be0775e5e9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 3 Jan 2022 13:48:12 +0000 Subject: Revert fix #1344 --- src/check_stmt.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'src') diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index c3b8c46ca..396388629 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -58,30 +58,6 @@ bool contains_deferred_call(Ast *node) { return false; } -Ast *last_stmt_blocking_in_list(Slice const &stmts) { - for_array(i, stmts) { - Ast *n = stmts[i]; - switch (n->kind) { - case Ast_ReturnStmt: - return n; - case Ast_BranchStmt: - return n; - case Ast_ExprStmt: - if (is_diverging_stmt(n)) { - return n; - } - break; - case Ast_BlockStmt: - n = last_stmt_blocking_in_list(n->BlockStmt.stmts); - if (n != nullptr) { - return n; - } - break; - } - } - return nullptr; -} - void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { if (stmts.count == 0) { return; @@ -126,7 +102,6 @@ void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) check_stmt(ctx, n, new_flags); if (i+1 < max_non_constant_declaration) { - never_executed_error:; switch (n->kind) { case Ast_ReturnStmt: error(n, "Statements after this 'return' are never executed"); @@ -141,13 +116,6 @@ void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) error(n, "Statements after a diverging procedure call are never executed"); } break; - - case Ast_BlockStmt: - n = last_stmt_blocking_in_list(n->BlockStmt.stmts); - if (n != nullptr) { - goto never_executed_error; - } - break; } } else if (i+1 == max_non_constant_declaration) { if (is_diverging_stmt(n)) { -- cgit v1.2.3 From f818d0feb1fe0bb421ba27060ea6ff812bf67117 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 3 Jan 2022 19:43:22 +0000 Subject: Fix #1344 --- src/llvm_backend_stmt.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 016e464b8..20b444058 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2188,6 +2188,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { lb_emit_defer_stmts(p, lbDeferExit_Branch, block); } lb_emit_jump(p, block); + lb_start_block(p, lb_create_block(p, "unreachable")); case_end; } } -- cgit v1.2.3 From 17613185e79b324948c14257f64c388c8e2a52fb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 4 Jan 2022 11:44:34 +0000 Subject: Support struct field tags in odin doc format --- core/odin/doc-format/doc_format.odin | 4 +++- src/docs_format.cpp | 3 ++- src/docs_writer.cpp | 9 +++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin index c80be2489..83cd89ca2 100644 --- a/core/odin/doc-format/doc_format.odin +++ b/core/odin/doc-format/doc_format.odin @@ -11,7 +11,7 @@ String :: distinct Array(byte) Version_Type_Major :: 0 Version_Type_Minor :: 2 -Version_Type_Patch :: 1 +Version_Type_Patch :: 2 Version_Type :: struct { major, minor, patch: u8, @@ -242,6 +242,8 @@ Type :: struct { polymorphic_params: Type_Index, // Used By: .Struct, .Union where_clauses: Array(String), + // Used By: .Struct + tags: Array(String), } Type_Flags_Basic :: distinct bit_set[Type_Flag_Basic; u32le] diff --git a/src/docs_format.cpp b/src/docs_format.cpp index 1c3af6257..5cfac4817 100644 --- a/src/docs_format.cpp +++ b/src/docs_format.cpp @@ -15,7 +15,7 @@ struct OdinDocVersionType { #define OdinDocVersionType_Major 0 #define OdinDocVersionType_Minor 2 -#define OdinDocVersionType_Patch 1 +#define OdinDocVersionType_Patch 2 struct OdinDocHeaderBase { u8 magic[8]; @@ -137,6 +137,7 @@ struct OdinDocType { OdinDocArray entities; OdinDocTypeIndex polmorphic_params; OdinDocArray where_clauses; + OdinDocArray tags; // struct field tags }; struct OdinDocAttribute { diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index e8e8892ec..56ad0561e 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -598,6 +598,15 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { } doc_type.where_clauses = odin_doc_where_clauses(w, st->where_clauses); } + + auto tags = array_make(heap_allocator(), type->Struct.fields.count); + defer (array_free(&tags)); + + for_array(i, type->Struct.fields) { + tags[i] = odin_doc_write_string(w, type->Struct.tags[i]); + } + + doc_type.tags = odin_write_slice(w, tags.data, tags.count); } break; case Type_Union: -- cgit v1.2.3 From 7a14acaa01d37ca02597bf40df00f7d62903a291 Mon Sep 17 00:00:00 2001 From: Platin21 Date: Wed, 5 Jan 2022 16:49:58 +0100 Subject: Fixes syscall intrinsic on macOS they use a slightly different section + register for the id --- src/llvm_backend_proc.cpp | 61 +++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 84fddd9e2..50aa5f6db 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2058,26 +2058,47 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, break; case TargetArch_arm64: { - GB_ASSERT(arg_count <= 7); - - char asm_string[] = "svc #0"; - gbString constraints = gb_string_make(heap_allocator(), "={x0}"); - for (unsigned i = 0; i < arg_count; i++) { - constraints = gb_string_appendc(constraints, ",{"); - static char const *regs[] = { - "x8", - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - }; - constraints = gb_string_appendc(constraints, regs[i]); - constraints = gb_string_appendc(constraints, "}"); - } - - inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + GB_ASSERT(arg_count <= 7); + + if(build_context.metrics.os == TargetOs_darwin) { + char asm_string[] = "svc #0x80"; + gbString constraints = gb_string_make(heap_allocator(), "={x0}"); + for (unsigned i = 0; i < arg_count; i++) { + constraints = gb_string_appendc(constraints, ",{"); + static char const *regs[] = { + "x16", + "x0", + "x1", + "x2", + "x3", + "x4", + "x5", + }; + constraints = gb_string_appendc(constraints, regs[i]); + constraints = gb_string_appendc(constraints, "}"); + } + + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + } else { + char asm_string[] = "svc #0"; + gbString constraints = gb_string_make(heap_allocator(), "={x0}"); + for (unsigned i = 0; i < arg_count; i++) { + constraints = gb_string_appendc(constraints, ",{"); + static char const *regs[] = { + "x8", + "x0", + "x1", + "x2", + "x3", + "x4", + "x5", + }; + constraints = gb_string_appendc(constraints, regs[i]); + constraints = gb_string_appendc(constraints, "}"); + } + + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + } } break; default: -- cgit v1.2.3 From 80bd1eb615ba83727a57173a391ae2bb710f6533 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jan 2022 12:19:49 +0000 Subject: Fix polymorphic matrix element with a minor hack --- core/math/linalg/general.odin | 8 ++++---- src/check_type.cpp | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/core/math/linalg/general.odin b/core/math/linalg/general.odin index b0572c0d3..9f22fa45e 100644 --- a/core/math/linalg/general.odin +++ b/core/math/linalg/general.odin @@ -287,10 +287,10 @@ array_cast :: proc(v: $A/[$N]$T, $Elem_Type: typeid) -> (w: [N]Elem_Type) #no_bo return } -matrix_cast :: proc(v: $A/[$M][$N]$T, $Elem_Type: typeid) -> (w: [M][N]Elem_Type) #no_bounds_check { - for i in 0.. (w: matrix[M, N]Elem_Type) #no_bounds_check { + for j in 0..elem); + if (e && e->kind == Entity_TypeName && e->TypeName.is_type_alias) { + // HACK TODO(bill): This is to allow polymorphic parameters for matrix elements + // proc($T: typeid) -> matrix[2, 2]T + // + // THIS IS NEEDS TO BE FIXED AND NOT USE THIS HACK + goto type_assign; + } + } gbString s = type_to_string(elem); error(column.expr, "Matrix elements types are limited to integers, floats, and complex, got %s", s); gb_string_free(s); } +type_assign:; *type = alloc_type_matrix(elem, row_count, column_count, generic_row, generic_column); -- cgit v1.2.3 From cb1080d56c7a5d26f344a41ea6553bf154509072 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jan 2022 13:31:34 +0000 Subject: Fix `check_procedure_bodies` to allow multiple threads caused by a typo --- src/checker.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/checker.cpp b/src/checker.cpp index 667146eda..c270e8210 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4941,7 +4941,6 @@ void check_procedure_bodies(Checker *c) { if (!build_context.threaded_checker) { worker_count = 0; } - worker_count = 0; if (worker_count == 0) { auto *this_queue = &c->procs_to_check_queue; -- cgit v1.2.3 From 6f3e450c502a8d05653ffcd98c74e2e933a34d1d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jan 2022 14:03:36 +0000 Subject: Move error handling code to a separate file --- src/error.cpp | 411 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tokenizer.cpp | 415 +----------------------------------------------------- 2 files changed, 413 insertions(+), 413 deletions(-) create mode 100644 src/error.cpp (limited to 'src') diff --git a/src/error.cpp b/src/error.cpp new file mode 100644 index 000000000..1496b4775 --- /dev/null +++ b/src/error.cpp @@ -0,0 +1,411 @@ +struct ErrorCollector { + TokenPos prev; + std::atomic count; + std::atomic warning_count; + std::atomic in_block; + BlockingMutex mutex; + BlockingMutex error_out_mutex; + BlockingMutex string_mutex; + RecursiveMutex block_mutex; + + Array error_buffer; + Array errors; +}; + +gb_global ErrorCollector global_error_collector; + +#define MAX_ERROR_COLLECTOR_COUNT (36) + + +bool any_errors(void) { + return global_error_collector.count.load() != 0; +} + +void init_global_error_collector(void) { + mutex_init(&global_error_collector.mutex); + mutex_init(&global_error_collector.block_mutex); + mutex_init(&global_error_collector.error_out_mutex); + mutex_init(&global_error_collector.string_mutex); + array_init(&global_error_collector.errors, heap_allocator()); + array_init(&global_error_collector.error_buffer, heap_allocator()); + array_init(&global_file_path_strings, heap_allocator(), 1, 4096); + array_init(&global_files, heap_allocator(), 1, 4096); +} + + +bool set_file_path_string(i32 index, String const &path) { + bool ok = false; + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + if (index >= global_file_path_strings.count) { + array_resize(&global_file_path_strings, index+1); + } + String prev = global_file_path_strings[index]; + if (prev.len == 0) { + global_file_path_strings[index] = path; + ok = true; + } + + mutex_unlock(&global_error_collector.string_mutex); + return ok; +} + +bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) { + bool ok = false; + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + if (index >= global_files.count) { + array_resize(&global_files, index+1); + } + AstFile *prev = global_files[index]; + if (prev == nullptr) { + global_files[index] = file; + ok = true; + } + + mutex_unlock(&global_error_collector.string_mutex); + return ok; +} + +String get_file_path_string(i32 index) { + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + String path = {}; + if (index < global_file_path_strings.count) { + path = global_file_path_strings[index]; + } + + mutex_unlock(&global_error_collector.string_mutex); + return path; +} + +AstFile *thread_safe_get_ast_file_from_id(i32 index) { + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + AstFile *file = nullptr; + if (index < global_files.count) { + file = global_files[index]; + } + + mutex_unlock(&global_error_collector.string_mutex); + return file; +} + + + +void begin_error_block(void) { + mutex_lock(&global_error_collector.block_mutex); + global_error_collector.in_block.store(true); +} + +void end_error_block(void) { + if (global_error_collector.error_buffer.count > 0) { + isize n = global_error_collector.error_buffer.count; + u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); + gb_memmove(text, global_error_collector.error_buffer.data, n); + text[n] = 0; + String s = {text, n}; + array_add(&global_error_collector.errors, s); + global_error_collector.error_buffer.count = 0; + } + + global_error_collector.in_block.store(false); + mutex_unlock(&global_error_collector.block_mutex); +} + +#define ERROR_BLOCK() begin_error_block(); defer (end_error_block()) + + +#define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va) +typedef ERROR_OUT_PROC(ErrorOutProc); + +ERROR_OUT_PROC(default_error_out_va) { + gbFile *f = gb_file_get_standard(gbFileStandard_Error); + + char buf[4096] = {}; + isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va); + isize n = len-1; + if (global_error_collector.in_block) { + isize cap = global_error_collector.error_buffer.count + n; + array_reserve(&global_error_collector.error_buffer, cap); + u8 *data = global_error_collector.error_buffer.data + global_error_collector.error_buffer.count; + gb_memmove(data, buf, n); + global_error_collector.error_buffer.count += n; + } else { + mutex_lock(&global_error_collector.error_out_mutex); + { + u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); + gb_memmove(text, buf, n); + text[n] = 0; + array_add(&global_error_collector.errors, make_string(text, n)); + } + mutex_unlock(&global_error_collector.error_out_mutex); + + } + gb_file_write(f, buf, n); +} + + +ErrorOutProc *error_out_va = default_error_out_va; + +// NOTE: defined in build_settings.cpp +bool global_warnings_as_errors(void); +bool global_ignore_warnings(void); +bool show_error_line(void); +gbString get_file_line_as_string(TokenPos const &pos, i32 *offset); + +void error_out(char const *fmt, ...) { + va_list va; + va_start(va, fmt); + error_out_va(fmt, va); + va_end(va); +} + + +bool show_error_on_line(TokenPos const &pos, TokenPos end) { + if (!show_error_line()) { + return false; + } + + i32 offset = 0; + gbString the_line = get_file_line_as_string(pos, &offset); + defer (gb_string_free(the_line)); + + if (the_line != nullptr) { + String line = make_string(cast(u8 const *)the_line, gb_string_length(the_line)); + + // TODO(bill): This assumes ASCII + + enum { + MAX_LINE_LENGTH = 76, + MAX_TAB_WIDTH = 8, + ELLIPSIS_PADDING = 8 + }; + + error_out("\n\t"); + if (line.len+MAX_TAB_WIDTH+ELLIPSIS_PADDING > MAX_LINE_LENGTH) { + i32 const half_width = MAX_LINE_LENGTH/2; + i32 left = cast(i32)(offset); + i32 right = cast(i32)(line.len - offset); + left = gb_min(left, half_width); + right = gb_min(right, half_width); + + line.text += offset-left; + line.len -= offset+right-left; + + line = string_trim_whitespace(line); + + offset = left + ELLIPSIS_PADDING/2; + + error_out("... %.*s ...", LIT(line)); + } else { + error_out("%.*s", LIT(line)); + } + error_out("\n\t"); + + for (i32 i = 0; i < offset; i++) { + error_out(" "); + } + error_out("^"); + if (end.file_id == pos.file_id) { + if (end.line > pos.line) { + for (i32 i = offset; i < line.len; i++) { + error_out("~"); + } + } else if (end.line == pos.line && end.column > pos.column) { + i32 length = gb_min(end.offset - pos.offset, cast(i32)(line.len-offset)); + for (i32 i = 1; i < length-1; i++) { + error_out("~"); + } + if (length > 1) { + error_out("^"); + } + } + } + + error_out("\n\n"); + return true; + } + return false; +} + +void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + global_error_collector.count.fetch_add(1); + + mutex_lock(&global_error_collector.mutex); + // NOTE(bill): Duplicate error, skip it + if (pos.line == 0) { + error_out("Error: %s\n", gb_bprintf_va(fmt, va)); + } else if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } + mutex_unlock(&global_error_collector.mutex); + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { + gb_exit(1); + } +} + +void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + if (global_warnings_as_errors()) { + error_va(pos, end, fmt, va); + return; + } + global_error_collector.warning_count.fetch_add(1); + mutex_lock(&global_error_collector.mutex); + if (!global_ignore_warnings()) { + // NOTE(bill): Duplicate error, skip it + if (pos.line == 0) { + error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); + } else if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s Warning: %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } + } + mutex_unlock(&global_error_collector.mutex); +} + + +void error_line_va(char const *fmt, va_list va) { + error_out_va(fmt, va); +} + +void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) { + mutex_lock(&global_error_collector.mutex); + global_error_collector.count++; + // NOTE(bill): Duplicate error, skip it + if (pos.line == 0) { + error_out("Error: %s", gb_bprintf_va(fmt, va)); + } else if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s %s", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + } + mutex_unlock(&global_error_collector.mutex); + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { + gb_exit(1); + } +} + + +void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + mutex_lock(&global_error_collector.mutex); + global_error_collector.count++; + // NOTE(bill): Duplicate error, skip it + if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s Syntax Error: %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } else if (pos.line == 0) { + error_out("Syntax Error: %s\n", gb_bprintf_va(fmt, va)); + } + + mutex_unlock(&global_error_collector.mutex); + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { + gb_exit(1); + } +} + +void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + if (global_warnings_as_errors()) { + syntax_error_va(pos, end, fmt, va); + return; + } + mutex_lock(&global_error_collector.mutex); + global_error_collector.warning_count++; + if (!global_ignore_warnings()) { + // NOTE(bill): Duplicate error, skip it + if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s Syntax Warning: %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } else if (pos.line == 0) { + error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); + } + } + mutex_unlock(&global_error_collector.mutex); +} + + + +void warning(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + warning_va(token.pos, {}, fmt, va); + va_end(va); +} + +void error(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + error_va(token.pos, {}, fmt, va); + va_end(va); +} + +void error(TokenPos pos, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + Token token = {}; + token.pos = pos; + error_va(pos, {}, fmt, va); + va_end(va); +} + +void error_line(char const *fmt, ...) { + va_list va; + va_start(va, fmt); + error_line_va(fmt, va); + va_end(va); +} + + +void syntax_error(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + syntax_error_va(token.pos, {}, fmt, va); + va_end(va); +} + +void syntax_error(TokenPos pos, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + syntax_error_va(pos, {}, fmt, va); + va_end(va); +} + +void syntax_warning(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + syntax_warning_va(token.pos, {}, fmt, va); + va_end(va); +} + + +void compiler_error(char const *fmt, ...) { + va_list va; + + va_start(va, fmt); + gb_printf_err("Internal Compiler Error: %s\n", + gb_bprintf_va(fmt, va)); + va_end(va); + gb_exit(1); +} + + + + diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 624aea2aa..20815fd16 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -264,419 +264,6 @@ bool token_is_newline(Token const &tok) { return tok.kind == Token_Semicolon && tok.string == "\n"; } - -struct ErrorCollector { - TokenPos prev; - std::atomic count; - std::atomic warning_count; - std::atomic in_block; - BlockingMutex mutex; - BlockingMutex error_out_mutex; - BlockingMutex string_mutex; - RecursiveMutex block_mutex; - - Array error_buffer; - Array errors; -}; - -gb_global ErrorCollector global_error_collector; - -#define MAX_ERROR_COLLECTOR_COUNT (36) - - -bool any_errors(void) { - return global_error_collector.count.load() != 0; -} - -void init_global_error_collector(void) { - mutex_init(&global_error_collector.mutex); - mutex_init(&global_error_collector.block_mutex); - mutex_init(&global_error_collector.error_out_mutex); - mutex_init(&global_error_collector.string_mutex); - array_init(&global_error_collector.errors, heap_allocator()); - array_init(&global_error_collector.error_buffer, heap_allocator()); - array_init(&global_file_path_strings, heap_allocator(), 1, 4096); - array_init(&global_files, heap_allocator(), 1, 4096); -} - - -bool set_file_path_string(i32 index, String const &path) { - bool ok = false; - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - if (index >= global_file_path_strings.count) { - array_resize(&global_file_path_strings, index+1); - } - String prev = global_file_path_strings[index]; - if (prev.len == 0) { - global_file_path_strings[index] = path; - ok = true; - } - - mutex_unlock(&global_error_collector.string_mutex); - return ok; -} - -bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) { - bool ok = false; - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - if (index >= global_files.count) { - array_resize(&global_files, index+1); - } - AstFile *prev = global_files[index]; - if (prev == nullptr) { - global_files[index] = file; - ok = true; - } - - mutex_unlock(&global_error_collector.string_mutex); - return ok; -} - -String get_file_path_string(i32 index) { - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - String path = {}; - if (index < global_file_path_strings.count) { - path = global_file_path_strings[index]; - } - - mutex_unlock(&global_error_collector.string_mutex); - return path; -} - -AstFile *thread_safe_get_ast_file_from_id(i32 index) { - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - AstFile *file = nullptr; - if (index < global_files.count) { - file = global_files[index]; - } - - mutex_unlock(&global_error_collector.string_mutex); - return file; -} - - - -void begin_error_block(void) { - mutex_lock(&global_error_collector.block_mutex); - global_error_collector.in_block.store(true); -} - -void end_error_block(void) { - if (global_error_collector.error_buffer.count > 0) { - isize n = global_error_collector.error_buffer.count; - u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); - gb_memmove(text, global_error_collector.error_buffer.data, n); - text[n] = 0; - String s = {text, n}; - array_add(&global_error_collector.errors, s); - global_error_collector.error_buffer.count = 0; - } - - global_error_collector.in_block.store(false); - mutex_unlock(&global_error_collector.block_mutex); -} - -#define ERROR_BLOCK() begin_error_block(); defer (end_error_block()) - - -#define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va) -typedef ERROR_OUT_PROC(ErrorOutProc); - -ERROR_OUT_PROC(default_error_out_va) { - gbFile *f = gb_file_get_standard(gbFileStandard_Error); - - char buf[4096] = {}; - isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va); - isize n = len-1; - if (global_error_collector.in_block) { - isize cap = global_error_collector.error_buffer.count + n; - array_reserve(&global_error_collector.error_buffer, cap); - u8 *data = global_error_collector.error_buffer.data + global_error_collector.error_buffer.count; - gb_memmove(data, buf, n); - global_error_collector.error_buffer.count += n; - } else { - mutex_lock(&global_error_collector.error_out_mutex); - { - u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); - gb_memmove(text, buf, n); - text[n] = 0; - array_add(&global_error_collector.errors, make_string(text, n)); - } - mutex_unlock(&global_error_collector.error_out_mutex); - - } - gb_file_write(f, buf, n); -} - - -ErrorOutProc *error_out_va = default_error_out_va; - -// NOTE: defined in build_settings.cpp -bool global_warnings_as_errors(void); -bool global_ignore_warnings(void); -bool show_error_line(void); -gbString get_file_line_as_string(TokenPos const &pos, i32 *offset); - -void error_out(char const *fmt, ...) { - va_list va; - va_start(va, fmt); - error_out_va(fmt, va); - va_end(va); -} - - -bool show_error_on_line(TokenPos const &pos, TokenPos end) { - if (!show_error_line()) { - return false; - } - - i32 offset = 0; - gbString the_line = get_file_line_as_string(pos, &offset); - defer (gb_string_free(the_line)); - - if (the_line != nullptr) { - String line = make_string(cast(u8 const *)the_line, gb_string_length(the_line)); - - // TODO(bill): This assumes ASCII - - enum { - MAX_LINE_LENGTH = 76, - MAX_TAB_WIDTH = 8, - ELLIPSIS_PADDING = 8 - }; - - error_out("\n\t"); - if (line.len+MAX_TAB_WIDTH+ELLIPSIS_PADDING > MAX_LINE_LENGTH) { - i32 const half_width = MAX_LINE_LENGTH/2; - i32 left = cast(i32)(offset); - i32 right = cast(i32)(line.len - offset); - left = gb_min(left, half_width); - right = gb_min(right, half_width); - - line.text += offset-left; - line.len -= offset+right-left; - - line = string_trim_whitespace(line); - - offset = left + ELLIPSIS_PADDING/2; - - error_out("... %.*s ...", LIT(line)); - } else { - error_out("%.*s", LIT(line)); - } - error_out("\n\t"); - - for (i32 i = 0; i < offset; i++) { - error_out(" "); - } - error_out("^"); - if (end.file_id == pos.file_id) { - if (end.line > pos.line) { - for (i32 i = offset; i < line.len; i++) { - error_out("~"); - } - } else if (end.line == pos.line && end.column > pos.column) { - i32 length = gb_min(end.offset - pos.offset, cast(i32)(line.len-offset)); - for (i32 i = 1; i < length-1; i++) { - error_out("~"); - } - if (length > 1) { - error_out("^"); - } - } - } - - error_out("\n\n"); - return true; - } - return false; -} - -void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - global_error_collector.count.fetch_add(1); - - mutex_lock(&global_error_collector.mutex); - // NOTE(bill): Duplicate error, skip it - if (pos.line == 0) { - error_out("Error: %s\n", gb_bprintf_va(fmt, va)); - } else if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } - mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { - gb_exit(1); - } -} - -void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - if (global_warnings_as_errors()) { - error_va(pos, end, fmt, va); - return; - } - global_error_collector.warning_count.fetch_add(1); - mutex_lock(&global_error_collector.mutex); - if (!global_ignore_warnings()) { - // NOTE(bill): Duplicate error, skip it - if (pos.line == 0) { - error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); - } else if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s Warning: %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } - } - mutex_unlock(&global_error_collector.mutex); -} - - -void error_line_va(char const *fmt, va_list va) { - error_out_va(fmt, va); -} - -void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) { - mutex_lock(&global_error_collector.mutex); - global_error_collector.count++; - // NOTE(bill): Duplicate error, skip it - if (pos.line == 0) { - error_out("Error: %s", gb_bprintf_va(fmt, va)); - } else if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s %s", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - } - mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { - gb_exit(1); - } -} - - -void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - mutex_lock(&global_error_collector.mutex); - global_error_collector.count++; - // NOTE(bill): Duplicate error, skip it - if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s Syntax Error: %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } else if (pos.line == 0) { - error_out("Syntax Error: %s\n", gb_bprintf_va(fmt, va)); - } - - mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { - gb_exit(1); - } -} - -void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - if (global_warnings_as_errors()) { - syntax_error_va(pos, end, fmt, va); - return; - } - mutex_lock(&global_error_collector.mutex); - global_error_collector.warning_count++; - if (!global_ignore_warnings()) { - // NOTE(bill): Duplicate error, skip it - if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s Syntax Warning: %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } else if (pos.line == 0) { - error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); - } - } - mutex_unlock(&global_error_collector.mutex); -} - - - -void warning(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - warning_va(token.pos, {}, fmt, va); - va_end(va); -} - -void error(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - error_va(token.pos, {}, fmt, va); - va_end(va); -} - -void error(TokenPos pos, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - Token token = {}; - token.pos = pos; - error_va(pos, {}, fmt, va); - va_end(va); -} - -void error_line(char const *fmt, ...) { - va_list va; - va_start(va, fmt); - error_line_va(fmt, va); - va_end(va); -} - - -void syntax_error(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - syntax_error_va(token.pos, {}, fmt, va); - va_end(va); -} - -void syntax_error(TokenPos pos, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - syntax_error_va(pos, {}, fmt, va); - va_end(va); -} - -void syntax_warning(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - syntax_warning_va(token.pos, {}, fmt, va); - va_end(va); -} - - -void compiler_error(char const *fmt, ...) { - va_list va; - - va_start(va, fmt); - gb_printf_err("Internal Compiler Error: %s\n", - gb_bprintf_va(fmt, va)); - va_end(va); - gb_exit(1); -} - - - - - gb_inline bool token_is_literal(TokenKind t) { return gb_is_between(t, Token__LiteralBegin+1, Token__LiteralEnd-1); } @@ -695,6 +282,8 @@ gb_inline bool token_is_shift(TokenKind t) { gb_inline void print_token(Token t) { gb_printf("%.*s\n", LIT(t.string)); } +#include "error.cpp" + enum TokenizerInitError { TokenizerInit_None, -- cgit v1.2.3 From 7cc265e14ce3ec08a5908d31441000bdcb4ac645 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jan 2022 14:50:28 +0000 Subject: Add mutex guards for signature scopes --- src/array.cpp | 4 ++++ src/check_decl.cpp | 2 +- src/check_expr.cpp | 2 ++ src/check_stmt.cpp | 2 +- src/checker.cpp | 2 +- src/common_memory.cpp | 34 ++++++++++++++++++++++++---------- src/threading.cpp | 34 ++++++++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/array.cpp b/src/array.cpp index c41125c6d..ac3727978 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -77,15 +77,19 @@ template Slice slice_from_array(Array const &a); template Slice slice_make(gbAllocator const &allocator, isize count) { + GB_ASSERT(count >= 0); Slice s = {}; s.data = gb_alloc_array(allocator, T, count); + GB_ASSERT(s.data != nullptr); s.count = count; return s; } template void slice_init(Slice *s, gbAllocator const &allocator, isize count) { + GB_ASSERT(count >= 0); s->data = gb_alloc_array(allocator, T, count); + GB_ASSERT(s->data != nullptr); s->count = count; } diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 42f68203c..55ad67abf 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1286,7 +1286,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty using_entities.allocator = heap_allocator(); defer (array_free(&using_entities)); - { + MUTEX_GUARD_BLOCK(ctx->scope->mutex) { if (type->Proc.param_count > 0) { TypeTuple *params = &type->Proc.params->Tuple; for_array(i, params->variables) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index cfffffd9f..1162cefee 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4021,10 +4021,12 @@ void check_did_you_mean_scope(String const &name, Scope *scope) { DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); defer (did_you_mean_destroy(&d)); + mutex_lock(&scope->mutex); for_array(i, scope->elements.entries) { Entity *e = scope->elements.entries[i].value; did_you_mean_append(&d, e->token.string); } + mutex_unlock(&scope->mutex); check_did_you_mean_print(&d); } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 396388629..94b7561c7 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -607,7 +607,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b case Entity_ImportName: { Scope *scope = e->ImportName.scope; - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { String name = scope->elements.entries[i].key.string; Entity *decl = scope->elements.entries[i].value; if (!is_entity_exported(decl)) continue; diff --git a/src/checker.cpp b/src/checker.cpp index c270e8210..58c71a176 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -622,7 +622,7 @@ void check_scope_usage(Checker *c, Scope *scope) { Array vetted_entities = {}; array_init(&vetted_entities, heap_allocator()); - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { Entity *e = scope->elements.entries[i].value; if (e == nullptr) continue; VettedEntity ve = {}; diff --git a/src/common_memory.cpp b/src/common_memory.cpp index 2d7a7a246..096c35b5c 100644 --- a/src/common_memory.cpp +++ b/src/common_memory.cpp @@ -325,18 +325,32 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) { // TODO(bill): Throughly test! switch (type) { #if defined(GB_COMPILER_MSVC) - case gbAllocation_Alloc: { - isize aligned_size = align_formula_isize(size, alignment); - // TODO(bill): Make sure this is aligned correctly - ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); - } break; + case gbAllocation_Alloc: + if (size == 0) { + return NULL; + } else { + isize aligned_size = align_formula_isize(size, alignment); + // TODO(bill): Make sure this is aligned correctly + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); + } + break; case gbAllocation_Free: - HeapFree(GetProcessHeap(), 0, old_memory); + if (old_memory != nullptr) { + HeapFree(GetProcessHeap(), 0, old_memory); + } + break; + case gbAllocation_Resize: + if (old_memory != nullptr && size > 0) { + isize aligned_size = align_formula_isize(size, alignment); + ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size); + } else if (old_memory != nullptr) { + HeapFree(GetProcessHeap(), 0, old_memory); + } else if (size != 0) { + isize aligned_size = align_formula_isize(size, alignment); + // TODO(bill): Make sure this is aligned correctly + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); + } break; - case gbAllocation_Resize: { - isize aligned_size = align_formula_isize(size, alignment); - ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size); - } break; #elif defined(GB_SYSTEM_LINUX) // TODO(bill): *nix version that's decent case gbAllocation_Alloc: { diff --git a/src/threading.cpp b/src/threading.cpp index b318e4ff1..e848bba00 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -68,6 +68,40 @@ void yield_thread(void); void yield_process(void); +struct MutexGuard { + MutexGuard() = delete; + MutexGuard(MutexGuard const &) = delete; + + MutexGuard(BlockingMutex *bm) : bm{bm} { + mutex_lock(this->bm); + } + MutexGuard(RecursiveMutex *rm) : rm{rm} { + mutex_lock(this->rm); + } + MutexGuard(BlockingMutex &bm) : bm{&bm} { + mutex_lock(this->bm); + } + MutexGuard(RecursiveMutex &rm) : rm{&rm} { + mutex_lock(this->rm); + } + ~MutexGuard() { + if (this->bm) { + mutex_unlock(this->bm); + } else if (this->rm) { + mutex_unlock(this->rm); + } + } + + operator bool() const { return true; } + + BlockingMutex *bm; + RecursiveMutex *rm; +}; + +#define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_) = m) +#define MUTEX_GUARD(m) MutexGuard GB_DEFER_3(_mutex_guard_) = m + + #if defined(GB_SYSTEM_WINDOWS) struct BlockingMutex { SRWLOCK srwlock; -- cgit v1.2.3 From 32ec1162bf467359ed47ba0bd4e74ec0c7fbd167 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jan 2022 14:52:47 +0000 Subject: Use more `{}` ctor --- src/threading.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/threading.cpp b/src/threading.cpp index e848bba00..50d0dfed1 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -98,8 +98,8 @@ struct MutexGuard { RecursiveMutex *rm; }; -#define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_) = m) -#define MUTEX_GUARD(m) MutexGuard GB_DEFER_3(_mutex_guard_) = m +#define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_){m}) +#define MUTEX_GUARD(m) MutexGuard GB_DEFER_3(_mutex_guard_){m} #if defined(GB_SYSTEM_WINDOWS) -- cgit v1.2.3 From 8f91e9307c6ea7a243001efb2ecb135d37587301 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Mon, 10 Jan 2022 17:57:33 -0500 Subject: shared library fixes --- src/llvm_backend.cpp | 8 +++++++- src/main.cpp | 51 +++++++++++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 5acd2a80f..1a657e47b 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1238,12 +1238,18 @@ void lb_generate_code(lbGenerator *gen) { // NOTE(bill, 2021-05-04): Target machines must be unique to each module because they are not thread safe auto target_machines = array_make(permanent_allocator(), gen->modules.entries.count); + // NOTE(dweiler): Dynamic libraries require position-independent code. + LLVMRelocMode reloc_mode = LLVMRelocDefault; + if (build_context.build_mode == BuildMode_DynamicLibrary) { + reloc_mode = LLVMRelocPIC; + } + for_array(i, gen->modules.entries) { target_machines[i] = LLVMCreateTargetMachine( target, target_triple, llvm_cpu, llvm_features, code_gen_level, - LLVMRelocDefault, + reloc_mode, code_mode); LLVMSetModuleDataLayout(gen->modules.entries[i].value->mod, LLVMCreateTargetDataLayout(target_machines[i])); } diff --git a/src/main.cpp b/src/main.cpp index 36b30112f..0e8894ed0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -432,40 +432,39 @@ i32 linker_stage(lbGenerator *gen) { // typically executable files on *NIX systems don't have extensions. String output_ext = {}; gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); - char const *linker; + + // NOTE(dweiler): We use clang as a frontend for the linker as there are + // other runtime and compiler support libraries that need to be linked in + // very specific orders such as libgcc_s, ld-linux-so, unwind, etc. + // These are not always typically inside /lib, /lib64, or /usr versions + // of that, e.g libgcc.a is in /usr/lib/gcc/{version}, and can vary on + // the distribution of Linux even. The gcc or clang specs is the only + // reliable way to query this information to call ld directly. if (build_context.build_mode == BuildMode_DynamicLibrary) { - // NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time. - // Clang, for some reason, won't let us pass the '-init' flag that lets us do this, - // so use ld instead. - // :UseLDForShared - linker = "ld"; + // NOTE(dweiler): Let the frontend know we're building a shared library + // so it doesn't generate symbols which cannot be relocated. + link_settings = gb_string_appendc(link_settings, "-shared "); + + // NOTE(dweiler): __$startup_runtime must be called at initialization + // time of the shared object, we can pass -init to the linker by using + // a comma separated list of arguments to -Wl. + // + // This previously used ld but ld cannot actually build a shared library + // correctly this way since all the other dependencies provided implicitly + // by the compiler frontend are still needed and most of the command + // line arguments prepared previously are incompatible with ld. + // // Shared libraries are .dylib on MacOS and .so on Linux. #if defined(GB_SYSTEM_OSX) output_ext = STR_LIT(".dylib"); - link_settings = gb_string_appendc(link_settings, "-init '___$startup_runtime' "); - link_settings = gb_string_appendc(link_settings, "-dylib -dynamic "); + link_settings = gb_string_appendc(link_settings, "-Wl,-init,'___$startup_runtime' "); #else output_ext = STR_LIT(".so"); - link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' "); - link_settings = gb_string_appendc(link_settings, "-shared "); + link_settings = gb_string_appendc(link_settings, "-Wl,-init,'__$startup_runtime' "); #endif } else { - #if defined(GB_SYSTEM_OSX) - linker = "ld"; - #else - // TODO(zangent): Figure out how to make ld work on Linux. - // It probably has to do with including the entire CRT, but - // that's quite a complicated issue to solve while remaining distro-agnostic. - // Clang can figure out linker flags for us, and that's good enough _for now_. - linker = "clang -Wno-unused-command-line-argument"; - #endif - } - - if (build_context.metrics.os == TargetOs_linux) { link_settings = gb_string_appendc(link_settings, "-no-pie "); } - - if (build_context.out_filepath.len > 0) { //NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that isize pos = string_extension_position(build_context.out_filepath); @@ -475,7 +474,7 @@ i32 linker_stage(lbGenerator *gen) { } result = system_exec_command_line_app("ld-link", - "%s %s -o \"%.*s%.*s\" %s " + "clang -Wunused-command-line-argument %s -o \"%.*s%.*s\" %s " " %s " " %.*s " " %.*s " @@ -492,7 +491,7 @@ i32 linker_stage(lbGenerator *gen) { // This points the linker to where the entry point is " -e _main " #endif - , linker, object_files, LIT(output_base), LIT(output_ext), + , object_files, LIT(output_base), LIT(output_ext), #if defined(GB_SYSTEM_OSX) "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", #else -- cgit v1.2.3 From 4334dbe69ac7b2e03d327c93ff559042c03db427 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Mon, 10 Jan 2022 18:00:38 -0500 Subject: disable this warning --- src/main.cpp | 124 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 0e8894ed0..444ab44f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,16 +74,16 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { isize cmd_len = 0; va_list va; i32 exit_code = 0; - + va_start(va, fmt); cmd_len = gb_snprintf_va(cmd_line, cmd_cap-1, fmt, va); va_end(va); - + #if defined(GB_SYSTEM_WINDOWS) STARTUPINFOW start_info = {gb_size_of(STARTUPINFOW)}; PROCESS_INFORMATION pi = {0}; String16 wcmd = {}; - + start_info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; start_info.wShowWindow = SW_SHOW; start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); @@ -118,11 +118,11 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { } exit_code = system(cmd_line); #endif - + if (exit_code) { exit(exit_code); } - + return exit_code; } @@ -137,7 +137,7 @@ i32 linker_stage(lbGenerator *gen) { if (is_arch_wasm()) { timings_start_section(timings, str_lit("wasm-ld")); - + #if defined(GB_SYSTEM_WINDOWS) result = system_exec_command_line_app("wasm-ld", "\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s", @@ -211,12 +211,12 @@ i32 linker_stage(lbGenerator *gen) { add_path(find_result.windows_sdk_ucrt_library_path); add_path(find_result.vs_library_path); } - - + + StringSet libs = {}; string_set_init(&libs, heap_allocator(), 64); defer (string_set_destroy(&libs)); - + StringSet asm_files = {}; string_set_init(&asm_files, heap_allocator(), 64); defer (string_set_destroy(&asm_files)); @@ -241,13 +241,13 @@ i32 linker_stage(lbGenerator *gen) { string_set_add(&libs, lib); } } - + for_array(i, libs.entries) { String lib = libs.entries[i].value; lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); } - - + + if (build_context.build_mode == BuildMode_DynamicLibrary) { output_ext = "dll"; link_settings = gb_string_append_fmt(link_settings, " /DLL"); @@ -268,7 +268,7 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.ODIN_DEBUG) { link_settings = gb_string_append_fmt(link_settings, " /DEBUG"); } - + for_array(i, asm_files.entries) { String asm_file = asm_files.entries[i].value; String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj")); @@ -283,7 +283,7 @@ i32 linker_stage(lbGenerator *gen) { LIT(obj_file), LIT(build_context.extra_assembler_flags) ); - + if (result) { return result; } @@ -305,7 +305,7 @@ i32 linker_stage(lbGenerator *gen) { LIT(output_base), LIT(build_context.resource_filepath) ); - + if (result) { return result; } @@ -340,11 +340,11 @@ i32 linker_stage(lbGenerator *gen) { lib_str ); } - + if (result) { return result; } - + } else { // lld result = system_exec_command_line_app("msvc-lld-link", "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s.%s\" %s " @@ -360,7 +360,7 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.extra_linker_flags), lib_str ); - + if (result) { return result; } @@ -474,7 +474,7 @@ i32 linker_stage(lbGenerator *gen) { } result = system_exec_command_line_app("ld-link", - "clang -Wunused-command-line-argument %s -o \"%.*s%.*s\" %s " + "clang -Wno-unused-command-line-argument %s -o \"%.*s%.*s\" %s " " %s " " %.*s " " %.*s " @@ -501,7 +501,7 @@ i32 linker_stage(lbGenerator *gen) { LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), link_settings); - + if (result) { return result; } @@ -513,7 +513,7 @@ i32 linker_stage(lbGenerator *gen) { result = system_exec_command_line_app("dsymutil", "dsymutil %.*s%.*s", LIT(output_base), LIT(output_ext) ); - + if (result) { return result; } @@ -674,9 +674,9 @@ enum BuildFlagKind { BuildFlag_IgnoreWarnings, BuildFlag_WarningsAsErrors, BuildFlag_VerboseErrors, - + // internal use only - BuildFlag_InternalIgnoreLazy, + BuildFlag_InternalIgnoreLazy, #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, @@ -826,7 +826,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all); - + add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); #if defined(GB_SYSTEM_WINDOWS) @@ -1355,7 +1355,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); build_context.extra_linker_flags = value.value_string; break; - case BuildFlag_ExtraAssemblerFlags: + case BuildFlag_ExtraAssemblerFlags: GB_ASSERT(value.kind == ExactValue_String); build_context.extra_assembler_flags = value.value_string; break; @@ -1817,7 +1817,7 @@ void show_timings(Checker *c, Timings *t) { void remove_temp_files(lbGenerator *gen) { if (build_context.keep_temp_files) return; - + TIME_SECTION("remove keep temp files"); for_array(i, gen->output_temp_paths) { @@ -1866,7 +1866,7 @@ void print_show_help(String const arg0, String const &command) { } else if (command == "strip-semicolon") { print_usage_line(1, "strip-semicolon"); print_usage_line(2, "parse and type check .odin file(s) and then remove unneeded semicolons from the entire project"); - } + } bool doc = command == "doc"; bool build = command == "build"; @@ -2071,7 +2071,7 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-extra-linker-flags:"); print_usage_line(2, "Adds extra linker specific flags in a string"); print_usage_line(0, ""); - + print_usage_line(1, "-extra-assembler-flags:"); print_usage_line(2, "Adds extra assembler specific flags in a string"); print_usage_line(0, ""); @@ -2097,7 +2097,7 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-strict-style"); print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons"); print_usage_line(0, ""); - + print_usage_line(1, "-strict-style-init-only"); print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons, only on the initial project"); print_usage_line(0, ""); @@ -2262,7 +2262,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt } written += to_write; prev_offset = token_pos_end(*token).offset; - } + } if (token->flags & TokenFlag_Replace) { if (token->kind == Token_Ellipsis) { if (!gb_file_write(f, "..=", 3)) { @@ -2281,7 +2281,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt } written += to_write; } - + if (written_) *written_ = written; return err; } @@ -2292,14 +2292,14 @@ int strip_semicolons(Parser *parser) { AstPackage *pkg = parser->packages[i]; file_count += pkg->files.count; } - + auto generated_files = array_make(permanent_allocator(), 0, file_count); - + for_array(i, parser->packages) { AstPackage *pkg = parser->packages[i]; for_array(j, pkg->files) { AstFile *file = pkg->files[j]; - + bool nothing_to_change = true; for_array(i, file->tokens) { Token *token = &file->tokens[i]; @@ -2308,29 +2308,29 @@ int strip_semicolons(Parser *parser) { break; } } - + if (nothing_to_change) { continue; } - + String old_fullpath = copy_string(permanent_allocator(), file->fullpath); - + // assumes .odin extension String fullpath_base = substring(old_fullpath, 0, old_fullpath.len-5); - + String old_fullpath_backup = concatenate_strings(permanent_allocator(), fullpath_base, str_lit("~backup.odin-temp")); String new_fullpath = concatenate_strings(permanent_allocator(), fullpath_base, str_lit("~temp.odin-temp")); - + array_add(&generated_files, StripSemicolonFile{old_fullpath, old_fullpath_backup, new_fullpath, file}); } } - + gb_printf_err("File count to be stripped of unneeded tokens: %td\n", generated_files.count); - - + + isize generated_count = 0; bool failed = false; - + for_array(i, generated_files) { auto *file = &generated_files[i]; char const *filename = cast(char const *)file->new_fullpath.text; @@ -2338,15 +2338,15 @@ int strip_semicolons(Parser *parser) { defer (if (err != gbFileError_None) { failed = true; }); - - gbFile f = {}; + + gbFile f = {}; err = gb_file_create(&f, filename); if (err) { break; } defer (err = gb_file_close(&f)); generated_count += 1; - + i64 written = 0; defer (err = gb_file_truncate(&f, written)); @@ -2367,23 +2367,23 @@ int strip_semicolons(Parser *parser) { } return 1; } - + isize overwritten_files = 0; - + for_array(i, generated_files) { auto *file = &generated_files[i]; - + char const *old_fullpath = cast(char const *)file->old_fullpath.text; char const *old_fullpath_backup = cast(char const *)file->old_fullpath_backup.text; char const *new_fullpath = cast(char const *)file->new_fullpath.text; - + debugf("Copy '%s' to '%s'\n", old_fullpath, old_fullpath_backup); if (!gb_file_copy(old_fullpath, old_fullpath_backup, false)) { gb_printf_err("failed to copy '%s' to '%s'\n", old_fullpath, old_fullpath_backup); failed = true; break; } - + debugf("Copy '%s' to '%s'\n", new_fullpath, old_fullpath); if (!gb_file_copy(new_fullpath, old_fullpath, false)) { @@ -2400,19 +2400,19 @@ int strip_semicolons(Parser *parser) { if (!gb_file_remove(old_fullpath_backup)) { gb_printf_err("failed to remove '%s'\n", old_fullpath_backup); } - + overwritten_files++; } - + if (!build_context.keep_temp_files) { for_array(i, generated_files) { auto *file = &generated_files[i]; char const *filename = nullptr; filename = cast(char const *)file->new_fullpath.text; - + debugf("Remove '%s'\n", filename); GB_ASSERT_MSG(gb_file_remove(filename), "unable to delete file %s", filename); - + filename = cast(char const *)file->old_fullpath_backup.text; debugf("Remove '%s'\n", filename); if (gb_file_exists(filename) && !gb_file_remove(filename)) { @@ -2423,10 +2423,10 @@ int strip_semicolons(Parser *parser) { } } } - + gb_printf_err("Files stripped of unneeded token: %td\n", generated_files.count); - - + + return cast(int)failed; } @@ -2442,7 +2442,7 @@ int main(int arg_count, char const **arg_ptr) { defer (timings_destroy(&global_timings)); MAIN_TIME_SECTION("initialization"); - + virtual_memory_init(); mutex_init(&fullpath_mutex); mutex_init(&hash_exact_value_mutex); @@ -2617,7 +2617,7 @@ int main(int arg_count, char const **arg_ptr) { init_global_thread_pool(); defer (thread_pool_destroy(&global_thread_pool)); - + init_universal(); // TODO(bill): prevent compiling without a linker @@ -2649,7 +2649,7 @@ int main(int arg_count, char const **arg_ptr) { if (any_errors()) { return 1; } - + if (build_context.command_kind == Command_strip_semicolon) { return strip_semicolons(parser); } @@ -2703,7 +2703,7 @@ int main(int arg_count, char const **arg_ptr) { } remove_temp_files(gen); - + if (build_context.show_timings) { show_timings(checker, &global_timings); } -- cgit v1.2.3 From 847b05013f71c69a4123fe5a4606c88039b716a3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 11 Jan 2022 10:56:07 +0000 Subject: Disable `DEFAULT_TO_THREADED_CHECKER` until race condition is found --- src/bug_report.cpp | 26 +++++++++++++------------- src/build_settings.cpp | 2 +- src/check_decl.cpp | 9 ++++----- src/checker.cpp | 10 +++++----- src/checker.hpp | 2 +- 5 files changed, 24 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/bug_report.cpp b/src/bug_report.cpp index 27e7fcf9a..9a1cb2254 100644 --- a/src/bug_report.cpp +++ b/src/bug_report.cpp @@ -140,7 +140,7 @@ void report_windows_product_type(DWORD ProductType) { break; default: - gb_printf("Unknown Edition (%08x)", ProductType); + gb_printf("Unknown Edition (%08x)", cast(unsigned)ProductType); } } #endif @@ -316,14 +316,14 @@ void print_bug_report_help() { } if (false) { - gb_printf("dwMajorVersion: %d\n", osvi.dwMajorVersion); - gb_printf("dwMinorVersion: %d\n", osvi.dwMinorVersion); - gb_printf("dwBuildNumber: %d\n", osvi.dwBuildNumber); - gb_printf("dwPlatformId: %d\n", osvi.dwPlatformId); - gb_printf("wServicePackMajor: %d\n", osvi.wServicePackMajor); - gb_printf("wServicePackMinor: %d\n", osvi.wServicePackMinor); - gb_printf("wSuiteMask: %d\n", osvi.wSuiteMask); - gb_printf("wProductType: %d\n", osvi.wProductType); + gb_printf("dwMajorVersion: %u\n", cast(unsigned)osvi.dwMajorVersion); + gb_printf("dwMinorVersion: %u\n", cast(unsigned)osvi.dwMinorVersion); + gb_printf("dwBuildNumber: %u\n", cast(unsigned)osvi.dwBuildNumber); + gb_printf("dwPlatformId: %u\n", cast(unsigned)osvi.dwPlatformId); + gb_printf("wServicePackMajor: %u\n", cast(unsigned)osvi.wServicePackMajor); + gb_printf("wServicePackMinor: %u\n", cast(unsigned)osvi.wServicePackMinor); + gb_printf("wSuiteMask: %u\n", cast(unsigned)osvi.wSuiteMask); + gb_printf("wProductType: %u\n", cast(unsigned)osvi.wProductType); } gb_printf("Windows "); @@ -441,18 +441,18 @@ void print_bug_report_help() { TEXT("DisplayVersion"), RRF_RT_REG_SZ, ValueType, - &DisplayVersion, + DisplayVersion, &ValueSize ); if (status == 0x0) { - gb_printf(" (version: %s)", &DisplayVersion); + gb_printf(" (version: %s)", DisplayVersion); } /* Now print build number. */ - gb_printf(", build %d", osvi.dwBuildNumber); + gb_printf(", build %u", cast(unsigned)osvi.dwBuildNumber); ValueSize = sizeof(UBR); status = RegGetValue( @@ -466,7 +466,7 @@ void print_bug_report_help() { ); if (status == 0x0) { - gb_printf(".%d", UBR); + gb_printf(".%u", cast(unsigned)UBR); } gb_printf("\n"); } diff --git a/src/build_settings.cpp b/src/build_settings.cpp index b8d50898d..ccae0fcf0 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -5,7 +5,7 @@ // #if defined(GB_SYSTEM_WINDOWS) -#define DEFAULT_TO_THREADED_CHECKER +// #define DEFAULT_TO_THREADED_CHECKER // #endif enum TargetOsKind { diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 55ad67abf..3f7d2f33d 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1286,7 +1286,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty using_entities.allocator = heap_allocator(); defer (array_free(&using_entities)); - MUTEX_GUARD_BLOCK(ctx->scope->mutex) { + { if (type->Proc.param_count > 0) { TypeTuple *params = &type->Proc.params->Tuple; for_array(i, params->variables) { @@ -1303,7 +1303,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty if (t->kind == Type_Struct) { Scope *scope = t->Struct.scope; GB_ASSERT(scope != nullptr); - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { Entity *f = scope->elements.entries[i].value; if (f->kind == Entity_Variable) { Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr); @@ -1321,11 +1321,10 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty } } - - for_array(i, using_entities) { + MUTEX_GUARD_BLOCK(ctx->scope->mutex) for_array(i, using_entities) { Entity *e = using_entities[i].e; Entity *uvar = using_entities[i].uvar; - Entity *prev = scope_insert(ctx->scope, uvar); + Entity *prev = scope_insert(ctx->scope, uvar, false); if (prev != nullptr) { error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string)); error_line("%.*s != %.*s\n", LIT(uvar->token.string), LIT(prev->token.string)); diff --git a/src/checker.cpp b/src/checker.cpp index 58c71a176..b4c5d0c72 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -446,7 +446,7 @@ Entity *scope_lookup(Scope *s, String const &name) { -Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { +Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { if (name == "") { return nullptr; } @@ -454,8 +454,8 @@ Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { Entity **found = nullptr; Entity *result = nullptr; - mutex_lock(&s->mutex); - defer (mutex_unlock(&s->mutex)); + if (use_mutex) mutex_lock(&s->mutex); + defer (if (use_mutex) mutex_unlock(&s->mutex)); found = string_map_get(&s->elements, key); @@ -485,9 +485,9 @@ end:; return result; } -Entity *scope_insert(Scope *s, Entity *entity) { +Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { String name = entity->token.string; - return scope_insert_with_name(s, name, entity); + return scope_insert_with_name(s, name, entity, use_mutex); } diff --git a/src/checker.hpp b/src/checker.hpp index 74435c1d4..db59ebce7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -423,7 +423,7 @@ Entity *entity_of_node(Ast *expr); Entity *scope_lookup_current(Scope *s, String const &name); Entity *scope_lookup (Scope *s, String const &name); void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_); -Entity *scope_insert (Scope *s, Entity *entity); +Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true); void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value); -- cgit v1.2.3 From 7e4067c44ceb21b4ca0ce89e501df1bf9de106b7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Jan 2022 19:18:54 +0000 Subject: Begin work to move entry point code to Odin itself rather than in C++ side --- core/intrinsics/intrinsics.odin | 5 +++ core/runtime/procs_windows_amd64.odin | 2 +- src/check_builtin.cpp | 6 +++ src/check_decl.cpp | 36 +++++++++-------- src/checker.cpp | 74 +++++++++++++++++++---------------- src/checker.hpp | 3 ++ src/checker_builtin_procs.hpp | 7 +++- src/llvm_backend.cpp | 15 ++++--- src/llvm_backend_proc.cpp | 8 ++++ 9 files changed, 100 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index 2da7a7439..803b04d17 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -197,3 +197,8 @@ type_field_index_of :: proc($T: typeid, $name: string) -> uintptr --- type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, rawptr) -> bool) where type_is_comparable(T) --- type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) --- + + +// Internal compiler use only + +__entry_point :: proc() --- \ No newline at end of file diff --git a/core/runtime/procs_windows_amd64.odin b/core/runtime/procs_windows_amd64.odin index 273bb57b2..e430357be 100644 --- a/core/runtime/procs_windows_amd64.odin +++ b/core/runtime/procs_windows_amd64.odin @@ -22,4 +22,4 @@ windows_trap_type_assertion :: proc "contextless" () -> ! { when ODIN_NO_CRT { @(require) foreign import crt_lib "procs_windows_amd64.asm" -} \ No newline at end of file +} diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index dc8c209c9..82ad6d161 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -219,6 +219,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 GB_PANIC("Implement built-in procedure: %.*s", LIT(builtin_name)); break; + case BuiltinProc___entry_point: + operand->mode = Addressing_NoValue; + operand->type = nullptr; + mpmc_enqueue(&c->info->intrinsics_entry_point_usage, call); + break; + case BuiltinProc_DIRECTIVE: { ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 3f7d2f33d..f9bc17ba4 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -777,21 +777,23 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (e->pkg != nullptr && e->token.string == "main") { - if (pt->param_count != 0 || - pt->result_count != 0) { - gbString str = type_to_string(proc_type); - error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str); - gb_string_free(str); - } - if (pt->calling_convention != default_calling_convention()) { - error(e->token, "Procedure 'main' cannot have a custom calling convention"); - } - pt->calling_convention = default_calling_convention(); - if (e->pkg->kind == Package_Init) { - if (ctx->info->entry_point != nullptr) { - error(e->token, "Redeclaration of the entry pointer procedure 'main'"); - } else { - ctx->info->entry_point = e; + if (e->pkg->kind != Package_Runtime) { + if (pt->param_count != 0 || + pt->result_count != 0) { + gbString str = type_to_string(proc_type); + error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str); + gb_string_free(str); + } + if (pt->calling_convention != default_calling_convention()) { + error(e->token, "Procedure 'main' cannot have a custom calling convention"); + } + pt->calling_convention = default_calling_convention(); + if (e->pkg->kind == Package_Init) { + if (ctx->info->entry_point != nullptr) { + error(e->token, "Redeclaration of the entry pointer procedure 'main'"); + } else { + ctx->info->entry_point = e; + } } } } @@ -924,7 +926,9 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { "\tother at %s", LIT(name), token_pos_to_string(pos)); } else if (name == "main") { - error(d->proc_lit, "The link name 'main' is reserved for internal use"); + if (d->entity->pkg->kind != Package_Runtime) { + error(d->proc_lit, "The link name 'main' is reserved for internal use"); + } } else { string_map_set(fp, key, e); } diff --git a/src/checker.cpp b/src/checker.cpp index b4c5d0c72..42575f88d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -823,6 +823,7 @@ void init_universal(void) { add_global_bool_constant("ODIN_NO_CRT", bc->no_crt); add_global_bool_constant("ODIN_USE_SEPARATE_MODULES", bc->use_separate_modules); add_global_bool_constant("ODIN_TEST", bc->command_kind == Command_test); + add_global_bool_constant("ODIN_NO_ENTRY_POINT", bc->no_entry_point); // Builtin Procedures @@ -941,6 +942,8 @@ void init_checker_info(CheckerInfo *i) { mutex_init(&i->foreign_mutex); semaphore_init(&i->collect_semaphore); + + mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used } void destroy_checker_info(CheckerInfo *i) { @@ -1228,7 +1231,7 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty while (prev_expr != expr) { prev_expr = expr; expr->tav.mode = mode; - if (type != nullptr && expr->tav.type != nullptr && + if (type != nullptr && expr->tav.type != nullptr && is_type_any(type) && is_type_untyped(expr->tav.type)) { // ignore } else { @@ -1424,7 +1427,7 @@ bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return false; } else if (name == "linkage") { return false; - } + } } } } @@ -1704,7 +1707,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_type_internal(c, bt->RelativeSlice.slice_type); add_type_info_type_internal(c, bt->RelativeSlice.base_integer); break; - + case Type_Matrix: add_type_info_type_internal(c, bt->Matrix.elem); break; @@ -1919,7 +1922,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { add_min_dep_type_info(c, bt->RelativeSlice.slice_type); add_min_dep_type_info(c, bt->RelativeSlice.base_integer); break; - + case Type_Matrix: add_min_dep_type_info(c, bt->Matrix.elem); break; @@ -2020,7 +2023,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("__init_context"), str_lit("__type_info_of"), str_lit("cstring_to_string"), - str_lit("_cleanup_runtime"), + str_lit("_cleanup_runtime"), // Pseudo-CRT required procedures str_lit("memset"), @@ -2047,7 +2050,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("gnu_h2f_ieee"), str_lit("gnu_f2h_ieee"), str_lit("extendhfsf2"), - + // WASM Specific str_lit("__ashlti3"), str_lit("__multi3"), @@ -2119,25 +2122,25 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { if (e->flags & EntityFlag_Init) { Type *t = base_type(e->type); GB_ASSERT(t->kind == Type_Proc); - + bool is_init = true; - + if (t->Proc.param_count != 0 || t->Proc.result_count != 0) { gbString str = type_to_string(t); error(e->token, "@(init) procedures must have a signature type with no parameters nor results, got %s", str); gb_string_free(str); is_init = false; } - + if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { error(e->token, "@(init) procedures must be declared at the file scope"); is_init = false; } - + if (is_init) { add_dependency_to_set(c, e); array_add(&c->info.init_procedures, e); - } + } } break; } @@ -3677,11 +3680,6 @@ void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { error(e->token, "'main' is reserved as the entry point procedure in the initial scope"); return; } - } else if (pkg->kind == Package_Runtime) { - if (e->token.string == "main") { - error(e->token, "'main' is reserved as the entry point procedure in the initial scope"); - return; - } } check_entity_decl(ctx, e, d, nullptr); @@ -3841,7 +3839,7 @@ void add_import_dependency_node(Checker *c, Ast *decl, PtrMap generate_import_dependency_graph(Checker *c) { - PtrMap M = {}; + PtrMap M = {}; map_init(&M, heap_allocator(), 2*c->parser->packages.count); defer (map_destroy(&M)); @@ -4121,11 +4119,11 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); add_entity_use(ctx, nullptr, e); } - + if (has_asm_extension(fullpath)) { if (build_context.metrics.arch != TargetArch_amd64 || build_context.metrics.os != TargetOs_windows) { - error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s", + error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s", LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch])); } } @@ -4327,7 +4325,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { if (!build_context.threaded_checker) { worker_count = 0; } - + semaphore_post(&c->info.collect_semaphore, cast(i32)thread_count); if (worker_count == 0) { ThreadProcCheckerSection section_all = {}; @@ -4351,7 +4349,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { } GB_ASSERT(remaining_count <= 0); - + for (isize i = 0; i < thread_count; i++) { global_thread_pool_add_task(proc, thread_data+i); } @@ -4750,11 +4748,11 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc ctx.decl = pi->decl; ctx.procs_to_check_queue = procs_to_check_queue; GB_ASSERT(procs_to_check_queue != nullptr); - + GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; String name = pi->token.string; - + if (pt->is_polymorphic && !pt->is_poly_specialized) { Token token = pi->token; if (pi->poly_def_node != nullptr) { @@ -4832,7 +4830,7 @@ void check_unchecked_bodies(Checker *c) { if (pi->body == nullptr) { continue; } - + debugf("unchecked: %.*s\n", LIT(e->token.string)); mpmc_enqueue(&c->procs_to_check_queue, pi); } @@ -4943,14 +4941,14 @@ void check_procedure_bodies(Checker *c) { } if (worker_count == 0) { auto *this_queue = &c->procs_to_check_queue; - + UntypedExprInfoMap untyped = {}; map_init(&untyped, heap_allocator()); - + for (ProcInfo *pi = nullptr; mpmc_dequeue(this_queue, &pi); /**/) { consume_proc_info_queue(c, pi, this_queue, &untyped); } - + map_destroy(&untyped); debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); @@ -4994,7 +4992,7 @@ void check_procedure_bodies(Checker *c) { GB_ASSERT(total_queued == original_queue_count); semaphore_post(&c->procs_to_check_semaphore, cast(i32)thread_count); - + for (isize i = 0; i < thread_count; i++) { global_thread_pool_add_task(thread_proc_body, thread_data+i); } @@ -5031,7 +5029,7 @@ void check_deferred_procedures(Checker *c) { Entity *dst = src->Procedure.deferred_procedure.entity; GB_ASSERT(dst != nullptr); GB_ASSERT(dst->kind == Entity_Procedure); - + char const *attribute = "deferred_none"; switch (dst_kind) { case DeferredProcedure_none: @@ -5232,7 +5230,7 @@ GB_COMPARE_PROC(init_procedures_cmp) { cmp = 0; return cmp; } - + if (x->pkg != y->pkg) { isize order_x = x->pkg ? x->pkg->order : 0; isize order_y = y->pkg ? y->pkg->order : 0; @@ -5246,14 +5244,14 @@ GB_COMPARE_PROC(init_procedures_cmp) { String fullpath_y = y->file ? y->file->fullpath : (String{}); String file_x = filename_from_path(fullpath_x); String file_y = filename_from_path(fullpath_y); - + cmp = string_compare(file_x, file_y); if (cmp) { return cmp; } } - + cmp = u64_cmp(x->order_in_src, y->order_in_src); if (cmp) { return cmp; @@ -5433,9 +5431,19 @@ void check_parsed_files(Checker *c) { TIME_SECTION("sanity checks"); GB_ASSERT(c->info.entity_queue.count.load(std::memory_order_relaxed) == 0); GB_ASSERT(c->info.definition_queue.count.load(std::memory_order_relaxed) == 0); - + TIME_SECTION("sort init procedures"); check_sort_init_procedures(c); + if (c->info.intrinsics_entry_point_usage.count > 0) { + TIME_SECTION("check intrinsics.__entry_point usage"); + Ast *node = nullptr; + while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { + if (c->info.entry_point == nullptr && node != nullptr) { + warning(node, "usage of intrinsics.__entry_point will be a no-op"); + } + } + } + TIME_SECTION("type check finish"); } diff --git a/src/checker.hpp b/src/checker.hpp index db59ebce7..9a8753efd 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -338,6 +338,9 @@ struct CheckerInfo { MPMCQueue required_global_variable_queue; MPMCQueue required_foreign_imports_through_force_queue; + MPMCQueue intrinsics_entry_point_usage; + + }; struct CheckerContext { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index abd9fc6ca..e8f5174c0 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -250,6 +250,8 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc__type_end, + BuiltinProc___entry_point, + BuiltinProc_COUNT, }; gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { @@ -497,6 +499,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_equal_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_hasher_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - + + {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + + {STR_LIT("__entry_point"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, }; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1a657e47b..b42ea8211 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -873,7 +873,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) } else { if (m->info->entry_point != nullptr) { lbValue entry_point = lb_find_procedure_value_from_entity(m, m->info->entry_point); - lb_emit_call(p, entry_point, {}); + lb_emit_call(p, entry_point, {}, ProcInlining_no_inline); } } @@ -1408,6 +1408,7 @@ void lb_generate_code(lbGenerator *gen) { Entity *entry_point = info->entry_point; bool has_dll_main = false; bool has_win_main = false; + bool already_has_entry_point = false; for_array(i, info->entities) { Entity *e = info->entities[i]; @@ -1425,7 +1426,9 @@ void lb_generate_code(lbGenerator *gen) { if (e->Procedure.is_export || (e->Procedure.link_name.len > 0) || ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) { - if (!has_dll_main && name == "DllMain") { + if (name == "main" || name == "DllMain" || name == "WinMain" || name == "mainCRTStartup") { + already_has_entry_point = true; + } else if (!has_dll_main && name == "DllMain") { has_dll_main = true; } else if (!has_win_main && name == "WinMain") { has_win_main = true; @@ -1643,9 +1646,11 @@ void lb_generate_code(lbGenerator *gen) { } - if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { - TIME_SECTION("LLVM main"); - lb_create_main_procedure(default_module, startup_runtime); + if (!already_has_entry_point) { + if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { + TIME_SECTION("LLVM main"); + lb_create_main_procedure(default_module, startup_runtime); + } } for_array(j, gen->modules.entries) { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 50aa5f6db..10b8a093f 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1965,6 +1965,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, return res; } + case BuiltinProc___entry_point: + if (p->module->info->entry_point) { + lbValue entry_point = lb_find_procedure_value_from_entity(p->module, p->module->info->entry_point); + GB_ASSERT(entry_point.value != nullptr); + lb_emit_call(p, entry_point, {}); + } + return {}; + case BuiltinProc_syscall: { unsigned arg_count = cast(unsigned)ce->args.count; -- cgit v1.2.3 From 5ec93677a04f17f38117f0cf301d9a72036a04e7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Jan 2022 19:27:49 +0000 Subject: Correct look for entry point in llvm backend (Windows only currently) --- src/llvm_backend.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index b42ea8211..0b4c674ac 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1406,19 +1406,15 @@ void lb_generate_code(lbGenerator *gen) { isize global_variable_max_count = 0; Entity *entry_point = info->entry_point; - bool has_dll_main = false; - bool has_win_main = false; bool already_has_entry_point = false; for_array(i, info->entities) { Entity *e = info->entities[i]; String name = e->token.string; - bool is_global = e->pkg != nullptr; - if (e->kind == Entity_Variable) { global_variable_max_count++; - } else if (e->kind == Entity_Procedure && !is_global) { + } else if (e->kind == Entity_Procedure) { if ((e->scope->flags&ScopeFlag_Init) && name == "main") { GB_ASSERT(e == entry_point); // entry_point = e; @@ -1426,12 +1422,9 @@ void lb_generate_code(lbGenerator *gen) { if (e->Procedure.is_export || (e->Procedure.link_name.len > 0) || ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) { - if (name == "main" || name == "DllMain" || name == "WinMain" || name == "mainCRTStartup") { + String link_name = e->Procedure.link_name; + if (link_name == "main" || link_name == "DllMain" || link_name == "WinMain" || link_name == "mainCRTStartup") { already_has_entry_point = true; - } else if (!has_dll_main && name == "DllMain") { - has_dll_main = true; - } else if (!has_win_main && name == "WinMain") { - has_win_main = true; } } } @@ -1647,10 +1640,8 @@ void lb_generate_code(lbGenerator *gen) { if (!already_has_entry_point) { - if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { - TIME_SECTION("LLVM main"); - lb_create_main_procedure(default_module, startup_runtime); - } + TIME_SECTION("LLVM main"); + lb_create_main_procedure(default_module, startup_runtime); } for_array(j, gen->modules.entries) { -- cgit v1.2.3 From fb0a3ab7c14d4bc3b821cef723ec6ea3e956c956 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Jan 2022 20:07:17 +0000 Subject: Correct linkage for entry point procedures on Windows --- src/checker.cpp | 8 +++++++- src/llvm_backend.cpp | 23 +++++++++++------------ src/llvm_backend_proc.cpp | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/checker.cpp b/src/checker.cpp index 42575f88d..f261c8f4a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2113,11 +2113,15 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { case Entity_Variable: if (e->Variable.is_export) { add_dependency_to_set(c, e); + } else if (e->flags & EntityFlag_Require) { + add_dependency_to_set(c, e); } break; case Entity_Procedure: if (e->Procedure.is_export) { add_dependency_to_set(c, e); + } else if (e->flags & EntityFlag_Require) { + add_dependency_to_set(c, e); } if (e->flags & EntityFlag_Init) { Type *t = base_type(e->type); @@ -5440,7 +5444,9 @@ void check_parsed_files(Checker *c) { Ast *node = nullptr; while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { if (c->info.entry_point == nullptr && node != nullptr) { - warning(node, "usage of intrinsics.__entry_point will be a no-op"); + if (node->file()->pkg->kind != Package_Runtime) { + warning(node, "usage of intrinsics.__entry_point will be a no-op"); + } } } } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 0b4c674ac..1c3cf86ac 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1405,7 +1405,6 @@ void lb_generate_code(lbGenerator *gen) { isize global_variable_max_count = 0; - Entity *entry_point = info->entry_point; bool already_has_entry_point = false; for_array(i, info->entities) { @@ -1416,14 +1415,17 @@ void lb_generate_code(lbGenerator *gen) { global_variable_max_count++; } else if (e->kind == Entity_Procedure) { if ((e->scope->flags&ScopeFlag_Init) && name == "main") { - GB_ASSERT(e == entry_point); - // entry_point = e; + GB_ASSERT(e == info->entry_point); } if (e->Procedure.is_export || (e->Procedure.link_name.len > 0) || ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) { String link_name = e->Procedure.link_name; - if (link_name == "main" || link_name == "DllMain" || link_name == "WinMain" || link_name == "mainCRTStartup") { + if (link_name == "main" || + link_name == "DllMain" || + link_name == "WinMain" || + link_name == "wWinMain" || + link_name == "mainCRTStartup") { already_has_entry_point = true; } } @@ -1562,6 +1564,11 @@ void lb_generate_code(lbGenerator *gen) { } } + TIME_SECTION("LLVM Runtime Type Information Creation"); + lbProcedure *startup_type_info = lb_create_startup_type_info(default_module); + + TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); + lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables); TIME_SECTION("LLVM Global Procedures and Types"); for_array(i, info->entities) { @@ -1621,14 +1628,6 @@ void lb_generate_code(lbGenerator *gen) { } } - - TIME_SECTION("LLVM Runtime Type Information Creation"); - lbProcedure *startup_type_info = lb_create_startup_type_info(default_module); - - TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); - lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables); - - TIME_SECTION("LLVM Procedure Generation"); for_array(j, gen->modules.entries) { lbModule *m = gen->modules.entries[j].value; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 10b8a093f..c52572588 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -304,7 +304,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) { { lbValue *found = string_map_get(&m->members, link_name); - GB_ASSERT(found == nullptr); + GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name)); } lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure); -- cgit v1.2.3 From e30f16b1f3fa5630c43c62f5602e26aa8d55e53b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Jan 2022 20:17:30 +0000 Subject: Correct `-init` for *nix --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 444ab44f0..9b2c5d5de 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -445,7 +445,7 @@ i32 linker_stage(lbGenerator *gen) { // so it doesn't generate symbols which cannot be relocated. link_settings = gb_string_appendc(link_settings, "-shared "); - // NOTE(dweiler): __$startup_runtime must be called at initialization + // NOTE(dweiler): _odin_entry_point must be called at initialization // time of the shared object, we can pass -init to the linker by using // a comma separated list of arguments to -Wl. // @@ -457,10 +457,10 @@ i32 linker_stage(lbGenerator *gen) { // Shared libraries are .dylib on MacOS and .so on Linux. #if defined(GB_SYSTEM_OSX) output_ext = STR_LIT(".dylib"); - link_settings = gb_string_appendc(link_settings, "-Wl,-init,'___$startup_runtime' "); + link_settings = gb_string_appendc(link_settings, "-Wl,-init,'__odin_entry_point' "); #else output_ext = STR_LIT(".so"); - link_settings = gb_string_appendc(link_settings, "-Wl,-init,'__$startup_runtime' "); + link_settings = gb_string_appendc(link_settings, "-Wl,-init,'__odin_entry_point' "); #endif } else { link_settings = gb_string_appendc(link_settings, "-no-pie "); -- cgit v1.2.3 From 3def94505eb72dee3ce46047d8e7820cad8d0c8f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Jan 2022 20:28:11 +0000 Subject: Add `dynamic` to error message for `-build-mode` --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 9b2c5d5de..35b3d713b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1280,7 +1280,7 @@ bool parse_build_flags(Array args) { } else { gb_printf_err("Unknown build mode '%.*s'\n", LIT(str)); gb_printf_err("Valid build modes:\n"); - gb_printf_err("\tdll, shared\n"); + gb_printf_err("\tdll, shared, dynamic\n"); gb_printf_err("\tobj, object\n"); gb_printf_err("\texe\n"); gb_printf_err("\tasm, assembly, assembler\n"); -- cgit v1.2.3 From ee260986a9bb5dcf1eed24425313fae95c33f187 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Thu, 13 Jan 2022 00:19:04 -0500 Subject: more fixes --- src/main.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 35b3d713b..9aa9bd2ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -446,8 +446,9 @@ i32 linker_stage(lbGenerator *gen) { link_settings = gb_string_appendc(link_settings, "-shared "); // NOTE(dweiler): _odin_entry_point must be called at initialization - // time of the shared object, we can pass -init to the linker by using - // a comma separated list of arguments to -Wl. + // time of the shared object, similarly, _odin_exit_point must be called + // at deinitialization. We can pass both -init and -fini to the linker by + // using a comma separated list of arguments to -Wl. // // This previously used ld but ld cannot actually build a shared library // correctly this way since all the other dependencies provided implicitly @@ -457,11 +458,11 @@ i32 linker_stage(lbGenerator *gen) { // Shared libraries are .dylib on MacOS and .so on Linux. #if defined(GB_SYSTEM_OSX) output_ext = STR_LIT(".dylib"); - link_settings = gb_string_appendc(link_settings, "-Wl,-init,'__odin_entry_point' "); #else output_ext = STR_LIT(".so"); - link_settings = gb_string_appendc(link_settings, "-Wl,-init,'__odin_entry_point' "); #endif + link_settings = gb_string_appendc(link_settings, "-Wl,-init,'_odin_entry_point' "); + link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); } else { link_settings = gb_string_appendc(link_settings, "-no-pie "); } -- cgit v1.2.3 From c6ed3fa4b5aca2a5e2b444c6b9cd4f8d2ca8f3e1 Mon Sep 17 00:00:00 2001 From: oskarnp Date: Fri, 14 Jan 2022 10:43:33 -0500 Subject: Fix invalid linker flags passed to clang on macOS --- src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 9aa9bd2ac..fe56d451f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -485,16 +485,16 @@ i32 linker_stage(lbGenerator *gen) { // NOTE: If you change this (although this minimum is as low as you can go with Odin working) // make sure to also change the 'mtriple' param passed to 'opt' #if defined(GB_CPU_ARM) - " -macosx_version_min 11.0.0 " + " -mmacosx-version-min=11.0.0 " #else - " -macosx_version_min 10.8.0 " + " -mmacosx-version-min=10.8.0 " #endif // This points the linker to where the entry point is " -e _main " #endif , object_files, LIT(output_base), LIT(output_ext), #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", + "-lSystem -lm -Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", #else "-lc -lm", #endif -- cgit v1.2.3 From 6aa80ee8e4fc8f96c24e9881a5833f14c86eff05 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 15:38:09 +0000 Subject: Correct `_start` as an entry point --- src/llvm_backend.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1c3cf86ac..7a7f20f8d 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1420,13 +1420,16 @@ void lb_generate_code(lbGenerator *gen) { if (e->Procedure.is_export || (e->Procedure.link_name.len > 0) || ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) { - String link_name = e->Procedure.link_name; - if (link_name == "main" || - link_name == "DllMain" || - link_name == "WinMain" || - link_name == "wWinMain" || - link_name == "mainCRTStartup") { - already_has_entry_point = true; + String link_name = e->Procedure.link_name; + if (e->pkg->kind == Package_Runtime) { + if (link_name == "main" || + link_name == "DllMain" || + link_name == "WinMain" || + link_name == "wWinMain" || + link_name == "mainCRTStartup" || + link_name == "_start") { + already_has_entry_point = true; + } } } } -- cgit v1.2.3 From a390ef41f803587ebdf404cd0f10c19a0a651994 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 15:55:01 +0000 Subject: Fix swizzle logic within `lb_build_assign_stmt_array` --- src/llvm_backend_stmt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 20b444058..04e7e0d03 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1766,6 +1766,8 @@ void lb_build_for_stmt(lbProcedure *p, Ast *node) { } void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, lbValue const &value) { + GB_ASSERT(op != Token_Eq); + Type *lhs_type = lb_addr_type(lhs); Type *array_type = base_type(lhs_type); GB_ASSERT(is_type_array_like(array_type)); @@ -1795,7 +1797,6 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, } indices[index_count++] = index; } - gb_sort_array(indices, index_count, gb_i32_cmp(0)); lbValue lhs_ptrs[4] = {}; lbValue x_loads[4] = {}; @@ -1840,7 +1841,6 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, } indices[index_count++] = index; } - gb_sort_array(indices.data, index_count, gb_i32_cmp(0)); lbValue lhs_ptrs[4] = {}; lbValue x_loads[4] = {}; -- cgit v1.2.3 From 7501cc2f17315af368abad8d89f669e414c6cd9e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 16:01:23 +0000 Subject: Remove dead code --- src/llvm_backend_stmt.cpp | 48 ----------------------------------------------- 1 file changed, 48 deletions(-) (limited to 'src') diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 04e7e0d03..5882b71ae 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1868,11 +1868,7 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, lbValue x = lb_addr_get_ptr(p, lhs); - - if (inline_array_arith) { - #if 1 - #if 1 unsigned n = cast(unsigned)count; auto lhs_ptrs = slice_make(temporary_allocator(), n); @@ -1896,50 +1892,6 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, for (unsigned i = 0; i < n; i++) { lb_emit_store(p, lhs_ptrs[i], ops[i]); } - - #else - lbValue y = lb_address_from_load_or_generate_local(p, rhs); - - unsigned n = cast(unsigned)count; - - auto lhs_ptrs = slice_make(temporary_allocator(), n); - auto rhs_ptrs = slice_make(temporary_allocator(), n); - auto x_loads = slice_make(temporary_allocator(), n); - auto y_loads = slice_make(temporary_allocator(), n); - auto ops = slice_make(temporary_allocator(), n); - - for (unsigned i = 0; i < n; i++) { - lhs_ptrs[i] = lb_emit_array_epi(p, x, i); - } - for (unsigned i = 0; i < n; i++) { - rhs_ptrs[i] = lb_emit_array_epi(p, y, i); - } - for (unsigned i = 0; i < n; i++) { - x_loads[i] = lb_emit_load(p, lhs_ptrs[i]); - } - for (unsigned i = 0; i < n; i++) { - y_loads[i] = lb_emit_load(p, rhs_ptrs[i]); - } - for (unsigned i = 0; i < n; i++) { - ops[i] = lb_emit_arith(p, op, x_loads[i], y_loads[i], elem_type); - } - for (unsigned i = 0; i < n; i++) { - lb_emit_store(p, lhs_ptrs[i], ops[i]); - } - #endif - #else - lbValue y = lb_address_from_load_or_generate_local(p, rhs); - - for (i64 i = 0; i < count; i++) { - lbValue a_ptr = lb_emit_array_epi(p, x, i); - lbValue b_ptr = lb_emit_array_epi(p, y, i); - - lbValue a = lb_emit_load(p, a_ptr); - lbValue b = lb_emit_load(p, b_ptr); - lbValue c = lb_emit_arith(p, op, a, b, elem_type); - lb_emit_store(p, a_ptr, c); - } - #endif } else { lbValue y = lb_address_from_load_or_generate_local(p, rhs); -- cgit v1.2.3 From 79f32d7b71f8ca00fa347ed0ab393d0d8c02111b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 16:03:37 +0000 Subject: Remove unused lbDefer kind --- src/llvm_backend.hpp | 3 --- src/llvm_backend_stmt.cpp | 4 ---- 2 files changed, 7 deletions(-) (limited to 'src') diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index e70b1f84c..45e58cacf 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -204,7 +204,6 @@ enum lbDeferExitKind { enum lbDeferKind { lbDefer_Node, - lbDefer_Instr, lbDefer_Proc, }; @@ -215,8 +214,6 @@ struct lbDefer { lbBlock * block; union { Ast *stmt; - // NOTE(bill): 'instr' will be copied every time to create a new one - lbValue instr; struct { lbValue deferred; Array result_as_args; diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 5882b71ae..3375ceda9 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2172,10 +2172,6 @@ void lb_build_defer_stmt(lbProcedure *p, lbDefer const &d) { lb_start_block(p, b); if (d.kind == lbDefer_Node) { lb_build_stmt(p, d.stmt); - } else if (d.kind == lbDefer_Instr) { - // NOTE(bill): Need to make a new copy - LLVMValueRef instr = LLVMInstructionClone(d.instr.value); - LLVMInsertIntoBuilder(p->builder, instr); } else if (d.kind == lbDefer_Proc) { lb_emit_call(p, d.proc.deferred, d.proc.result_as_args); } -- cgit v1.2.3 From 9ecbadd457a6a647c88c9b9670e9a9154fb33e5d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 16:16:11 +0000 Subject: Simplify procedure parameters callee logic --- src/llvm_backend.hpp | 1 - src/llvm_backend_proc.cpp | 47 ++++++++++++++++------------------------------- 2 files changed, 16 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 45e58cacf..49f675a49 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -267,7 +267,6 @@ struct lbProcedure { bool is_done; lbAddr return_ptr; - Array params; Array defer_stmts; Array blocks; Array branch_blocks; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index c52572588..eccf9b360 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -107,7 +107,6 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) gbAllocator a = heap_allocator(); p->children.allocator = a; - p->params.allocator = a; p->defer_stmts.allocator = a; p->blocks.allocator = a; p->branch_blocks.allocator = a; @@ -323,7 +322,6 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type gbAllocator a = permanent_allocator(); p->children.allocator = a; - p->params.allocator = a; p->defer_stmts.allocator = a; p->blocks.allocator = a; p->branch_blocks.allocator = a; @@ -478,42 +476,29 @@ void lb_begin_procedure_body(lbProcedure *p) { if (arg_type->kind == lbArg_Ignore) { continue; } else if (arg_type->kind == lbArg_Direct) { - lbParamPasskind kind = lbParamPass_Value; - LLVMTypeRef param_type = lb_type(p->module, e->type); - if (param_type != arg_type->type) { - kind = lbParamPass_BitCast; - } - LLVMValueRef value = LLVMGetParam(p->value, param_offset+param_index); + if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { + LLVMTypeRef param_type = lb_type(p->module, e->type); + LLVMValueRef value = LLVMGetParam(p->value, param_offset+param_index); - value = OdinLLVMBuildTransmute(p, value, param_type); + value = OdinLLVMBuildTransmute(p, value, param_type); - lbValue param = {}; - param.value = value; - param.type = e->type; - array_add(&p->params, param); + lbValue param = {}; + param.value = value; + param.type = e->type; - if (e->token.string.len != 0) { - lbAddr l = lb_add_local(p, e->type, e, false, param_index); - lb_addr_store(p, l, param); + lbValue ptr = lb_address_from_load_or_generate_local(p, param); + lb_add_entity(p->module, e, ptr); } - - param_index += 1; } else if (arg_type->kind == lbArg_Indirect) { - LLVMValueRef value_ptr = LLVMGetParam(p->value, param_offset+param_index); - LLVMValueRef value = LLVMBuildLoad(p->builder, value_ptr, ""); - - lbValue param = {}; - param.value = value; - param.type = e->type; - array_add(&p->params, param); + if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { + lbValue ptr = {}; + ptr.value = LLVMGetParam(p->value, param_offset+param_index); + ptr.type = alloc_type_pointer(e->type); - lbValue ptr = {}; - ptr.value = value_ptr; - ptr.type = alloc_type_pointer(e->type); - - lb_add_entity(p->module, e, ptr); - param_index += 1; + lb_add_entity(p->module, e, ptr); + } } + param_index += 1; } } -- cgit v1.2.3 From 51dcbc80c3f0ef8755a0dc07b257ca93b264c2cc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 16:26:14 +0000 Subject: Add `LLVMAddMergedLoadStoreMotionPass` on `-debug -opt:0` --- src/llvm_backend_opt.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 5b8468799..8f1c7ad59 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -57,17 +57,13 @@ LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, i32 optimization_level) { if (optimization_level == 0 && build_context.ODIN_DEBUG) { - return; + LLVMAddMergedLoadStoreMotionPass(fpm); + } else { + LLVMAddPromoteMemoryToRegisterPass(fpm); + LLVMAddMergedLoadStoreMotionPass(fpm); + LLVM_ADD_CONSTANT_VALUE_PASS(fpm); + LLVMAddEarlyCSEPass(fpm); } - LLVMAddPromoteMemoryToRegisterPass(fpm); - LLVMAddMergedLoadStoreMotionPass(fpm); - LLVM_ADD_CONSTANT_VALUE_PASS(fpm); - LLVMAddEarlyCSEPass(fpm); - - // LLVM_ADD_CONSTANT_VALUE_PASS(fpm); - // LLVMAddMergedLoadStoreMotionPass(fpm); - // LLVMAddPromoteMemoryToRegisterPass(fpm); - // LLVMAddCFGSimplificationPass(fpm); } void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level) { -- cgit v1.2.3 From 6c4867081985a8dd1cccb3e5c503d72807e4ee87 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 17:34:35 +0000 Subject: Make `ODIN_BUILD_MODE` a enum type --- core/runtime/core.odin | 13 +++++ core/runtime/entry_unix.odin | 2 +- core/runtime/entry_windows.odin | 2 +- core/runtime/internal.odin | 2 +- src/build_settings.cpp | 23 ++------- src/check_expr.cpp | 112 ++++++++++++++++++++++------------------ src/checker.cpp | 64 ++++++++++++++++++++++- 7 files changed, 144 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/core/runtime/core.odin b/core/runtime/core.odin index be30eef02..91b6bf5ca 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -386,6 +386,19 @@ Raw_Cstring :: struct { } +/* + // Defined internally by the compiler + Odin_Build_Mode_Type :: enum int { + Executable, + Dynamic, + Object, + Assembly, + LLVM_IR, + } +*/ +Odin_Build_Mode_Type :: type_of(ODIN_BUILD_MODE) + + ///////////////////////////// // Init Startup Procedures // ///////////////////////////// diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin index 38116c0f9..67d2cbcb7 100644 --- a/core/runtime/entry_unix.odin +++ b/core/runtime/entry_unix.odin @@ -4,7 +4,7 @@ package runtime import "core:intrinsics" -when ODIN_BUILD_MODE == "dynamic" { +when ODIN_BUILD_MODE == .Dynamic { @(link_name="_odin_entry_point", linkage="strong", require, link_section=".init") _odin_entry_point :: proc "c" () { context = default_context() diff --git a/core/runtime/entry_windows.odin b/core/runtime/entry_windows.odin index ef8b0c529..97a5bebe6 100644 --- a/core/runtime/entry_windows.odin +++ b/core/runtime/entry_windows.odin @@ -4,7 +4,7 @@ package runtime import "core:intrinsics" -when ODIN_BUILD_MODE == "dynamic" { +when ODIN_BUILD_MODE == .Dynamic { @(link_name="DllMain", linkage="strong", require) DllMain :: proc "stdcall" (hinstDLL: rawptr, fdwReason: u32, lpReserved: rawptr) -> b32 { context = default_context() diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 6498c4db7..7b283a132 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -8,7 +8,7 @@ IS_WASM :: ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64" @(private) RUNTIME_LINKAGE :: "strong" when ( (ODIN_USE_SEPARATE_MODULES || - ODIN_BUILD_MODE == "dynamic" || + ODIN_BUILD_MODE == .Dynamic || !ODIN_NO_CRT) && !IS_WASM) else "internal" RUNTIME_REQUIRE :: true diff --git a/src/build_settings.cpp b/src/build_settings.cpp index ccae0fcf0..bafa93042 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -119,6 +119,8 @@ enum BuildModeKind { BuildMode_Object, BuildMode_Assembly, BuildMode_LLVM_IR, + + BuildMode_COUNT, }; enum CommandKind : u32 { @@ -172,10 +174,9 @@ struct BuildContext { String ODIN_VENDOR; // compiler vendor String ODIN_VERSION; // compiler version String ODIN_ROOT; // Odin ROOT - String ODIN_BUILD_MODE; bool ODIN_DEBUG; // Odin in debug mode bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not - bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) +bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) TargetEndianKind endian_kind; @@ -855,24 +856,6 @@ void init_build_context(TargetMetrics *cross_target) { bc->ODIN_VENDOR = str_lit("odin"); bc->ODIN_VERSION = ODIN_VERSION; bc->ODIN_ROOT = odin_root_dir(); - switch (bc->build_mode) { - default: - case BuildMode_Executable: - bc->ODIN_BUILD_MODE = str_lit("executable"); - break; - case BuildMode_DynamicLibrary: - bc->ODIN_BUILD_MODE = str_lit("dynamic"); - break; - case BuildMode_Object: - bc->ODIN_BUILD_MODE = str_lit("object"); - break; - case BuildMode_Assembly: - bc->ODIN_BUILD_MODE = str_lit("assembly"); - break; - case BuildMode_LLVM_IR: - bc->ODIN_BUILD_MODE = str_lit("llvm-ir"); - break; - } bc->copy_file_contents = true; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1162cefee..8667d8734 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -119,6 +119,58 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint); void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); + +void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { + auto results = did_you_mean_results(d); + if (results.count != 0) { + error_line("\tSuggestion: Did you mean?\n"); + for_array(i, results) { + String const &target = results[i].target; + error_line("\t\t%s%.*s\n", prefix, LIT(target)); + // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance); + } + } +} + +void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); + defer (did_you_mean_destroy(&d)); + + for_array(i, fields) { + did_you_mean_append(&d, fields[i]->token.string); + } + check_did_you_mean_print(&d, prefix); +} + +void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); + defer (did_you_mean_destroy(&d)); + + for_array(i, fields) { + did_you_mean_append(&d, fields[i]->token.string); + } + check_did_you_mean_print(&d, prefix); +} + +void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); + defer (did_you_mean_destroy(&d)); + + mutex_lock(&scope->mutex); + for_array(i, scope->elements.entries) { + Entity *e = scope->elements.entries[i].value; + did_you_mean_append(&d, e->token.string); + } + mutex_unlock(&scope->mutex); + check_did_you_mean_print(&d, prefix); +} + Entity *entity_from_expr(Ast *expr) { expr = unparen_expr(expr); switch (expr->kind) { @@ -3361,7 +3413,17 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ } } } + ERROR_BLOCK(); + error(operand->expr, "Cannot convert untyped value '%s' to '%s' from '%s'%s", expr_str, type_str, from_type_str, extra_text); + if (operand->value.kind == ExactValue_String) { + String key = operand->value.value_string; + if (is_type_string(operand->type) && is_type_enum(target_type)) { + gb_printf_err("HERE!\n"); + Type *et = base_type(target_type); + check_did_you_mean_type(key, et->Enum.fields, "."); + } + } gb_string_free(from_type_str); gb_string_free(type_str); @@ -3979,56 +4041,6 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti if (success_) *success_ = true; return empty_exact_value; } -void check_did_you_mean_print(DidYouMeanAnswers *d) { - auto results = did_you_mean_results(d); - if (results.count != 0) { - error_line("\tSuggestion: Did you mean?\n"); - for_array(i, results) { - String const &target = results[i].target; - error_line("\t\t%.*s\n", LIT(target)); - // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance); - } - } -} - -void check_did_you_mean_type(String const &name, Array const &fields) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); - defer (did_you_mean_destroy(&d)); - - for_array(i, fields) { - did_you_mean_append(&d, fields[i]->token.string); - } - check_did_you_mean_print(&d); -} - -void check_did_you_mean_type(String const &name, Slice const &fields) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); - defer (did_you_mean_destroy(&d)); - - for_array(i, fields) { - did_you_mean_append(&d, fields[i]->token.string); - } - check_did_you_mean_print(&d); -} - -void check_did_you_mean_scope(String const &name, Scope *scope) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); - defer (did_you_mean_destroy(&d)); - - mutex_lock(&scope->mutex); - for_array(i, scope->elements.entries) { - Entity *e = scope->elements.entries[i].value; - did_you_mean_append(&d, e->token.string); - } - mutex_unlock(&scope->mutex); - check_did_you_mean_print(&d); -} Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) { Type *array_type = base_type(type_deref(original_type)); diff --git a/src/checker.cpp b/src/checker.cpp index f261c8f4a..c3dcd1d11 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -780,6 +780,54 @@ AstPackage *create_builtin_package(char const *name) { return pkg; } +struct GlobalEnumValue { + char const *name; + i64 value; +}; + +Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count) { + Scope *scope = create_scope(nullptr, builtin_pkg->scope); + Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); + + Type *enum_type = alloc_type_enum(); + Type *named_type = alloc_type_named(type_name, enum_type, e); + set_base_type(named_type, enum_type); + enum_type->Enum.base_type = t_int; + enum_type->Enum.scope = scope; + + auto fields = array_make(permanent_allocator(), value_count); + for (isize i = 0; i < value_count; i++) { + i64 value = values[i].value; + Entity *e = alloc_entity_constant(scope, make_token_ident(values[i].name), named_type, exact_value_i64(value)); + e->flags |= EntityFlag_Visited; + e->state = EntityState_Resolved; + fields[i] = e; + + Entity *ie = scope_insert(scope, e); + GB_ASSERT(ie == nullptr); + } + + + enum_type->Enum.fields = fields; + enum_type->Enum.min_value_index = 0; + enum_type->Enum.max_value_index = value_count-1; + enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value; + enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value; + + return slice_from_array(fields); +} +void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { + for (Entity *field : fields) { + GB_ASSERT(field->kind == Entity_Constant); + if (value == exact_value_to_i64(field->Constant.value)) { + add_global_constant(name, field->type, field->Constant.value); + return; + } + } + GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value); +} + + void init_universal(void) { BuildContext *bc = &build_context; @@ -815,7 +863,21 @@ void init_universal(void) { add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); - add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE); + { + GlobalEnumValue values[BuildMode_COUNT] = { + {"Executable", BuildMode_Executable}, + {"Dynamic", BuildMode_DynamicLibrary}, + {"Object", BuildMode_Object}, + {"Assembly", BuildMode_Assembly}, + {"LLVM_IR", BuildMode_LLVM_IR}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Build_Mode_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode); + } + + // add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE); + add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG); add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT); add_global_bool_constant("ODIN_DEFAULT_TO_NIL_ALLOCATOR", bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR); -- cgit v1.2.3 From 29ebe0c3c92724f74392687ee859a0c2db503b0d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 17:40:00 +0000 Subject: Rename architecture `386` to `i386` --- core/c/c.odin | 2 +- core/crypto/_fiat/field_poly1305/field.odin | 2 +- core/crypto/chacha20/chacha20.odin | 2 +- core/runtime/entry_windows.odin | 2 +- core/runtime/procs_windows_386.odin | 28 --------------------------- core/runtime/procs_windows_i386.odin | 28 +++++++++++++++++++++++++++ core/sys/cpu/cpu_x86.odin | 2 +- core/sys/unix/syscalls_linux.odin | 2 +- src/build_settings.cpp | 30 ++++++++++++++--------------- src/check_builtin.cpp | 2 +- src/llvm_abi.cpp | 2 +- src/llvm_backend.cpp | 4 ++-- src/llvm_backend_expr.cpp | 2 +- src/llvm_backend_proc.cpp | 4 ++-- src/llvm_backend_utility.cpp | 2 +- src/microsoft_craziness.h | 10 +++++----- 16 files changed, 62 insertions(+), 62 deletions(-) delete mode 100644 core/runtime/procs_windows_386.odin create mode 100644 core/runtime/procs_windows_i386.odin (limited to 'src') diff --git a/core/c/c.odin b/core/c/c.odin index 139d9920a..d0b8e377f 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -48,7 +48,7 @@ int_least64_t :: builtin.i64 uint_least64_t :: builtin.u64 // Same on Windows, Linux, and FreeBSD -when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" { +when ODIN_ARCH == "i386" || ODIN_ARCH == "amd64" { int_fast8_t :: builtin.i8 uint_fast8_t :: builtin.u8 int_fast16_t :: builtin.i32 diff --git a/core/crypto/_fiat/field_poly1305/field.odin b/core/crypto/_fiat/field_poly1305/field.odin index bfb7cf1f9..4ed8acbff 100644 --- a/core/crypto/_fiat/field_poly1305/field.odin +++ b/core/crypto/_fiat/field_poly1305/field.odin @@ -22,7 +22,7 @@ fe_from_bytes :: #force_inline proc (out1: ^Tight_Field_Element, arg1: []byte, a assert(len(arg1) == 16) - when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" { + when ODIN_ARCH == "i386" || ODIN_ARCH == "amd64" { // While it may be unwise to do deserialization here on our // own when fiat-crypto provides equivalent functionality, // doing it this way provides a little under 3x performance diff --git a/core/crypto/chacha20/chacha20.odin b/core/crypto/chacha20/chacha20.odin index f6f551692..e32dacb2c 100644 --- a/core/crypto/chacha20/chacha20.odin +++ b/core/crypto/chacha20/chacha20.odin @@ -346,7 +346,7 @@ _do_blocks :: proc (ctx: ^Context, dst, src: []byte, nr_blocks: int) { // Until dedicated assembly can be written leverage the fact that // the callers of this routine ensure that src/dst are valid. - when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" { + when ODIN_ARCH == "i386" || ODIN_ARCH == "amd64" { // util.PUT_U32_LE/util.U32_LE are not required on little-endian // systems that also happen to not be strict about aligned // memory access. diff --git a/core/runtime/entry_windows.odin b/core/runtime/entry_windows.odin index 97a5bebe6..35a6bb421 100644 --- a/core/runtime/entry_windows.odin +++ b/core/runtime/entry_windows.odin @@ -22,7 +22,7 @@ when ODIN_BUILD_MODE == .Dynamic { return true } } else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { - when ODIN_ARCH == "386" || ODIN_NO_CRT { + when ODIN_ARCH == "i386" || ODIN_NO_CRT { @(link_name="mainCRTStartup", linkage="strong", require) mainCRTStartup :: proc "stdcall" () -> i32 { context = default_context() diff --git a/core/runtime/procs_windows_386.odin b/core/runtime/procs_windows_386.odin deleted file mode 100644 index f810197f1..000000000 --- a/core/runtime/procs_windows_386.odin +++ /dev/null @@ -1,28 +0,0 @@ -//+private -package runtime - -@require foreign import "system:int64.lib" - -foreign import kernel32 "system:Kernel32.lib" - -windows_trap_array_bounds :: proc "contextless" () -> ! { - DWORD :: u32 - ULONG_PTR :: uint - - EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C - - foreign kernel32 { - RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! --- - } - - RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil) -} - -windows_trap_type_assertion :: proc "contextless" () -> ! { - windows_trap_array_bounds() -} - -@(private, export, link_name="_fltused") _fltused: i32 = 0x9875 - -@(private, export, link_name="_tls_index") _tls_index: u32 -@(private, export, link_name="_tls_array") _tls_array: u32 diff --git a/core/runtime/procs_windows_i386.odin b/core/runtime/procs_windows_i386.odin new file mode 100644 index 000000000..f810197f1 --- /dev/null +++ b/core/runtime/procs_windows_i386.odin @@ -0,0 +1,28 @@ +//+private +package runtime + +@require foreign import "system:int64.lib" + +foreign import kernel32 "system:Kernel32.lib" + +windows_trap_array_bounds :: proc "contextless" () -> ! { + DWORD :: u32 + ULONG_PTR :: uint + + EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C + + foreign kernel32 { + RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! --- + } + + RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil) +} + +windows_trap_type_assertion :: proc "contextless" () -> ! { + windows_trap_array_bounds() +} + +@(private, export, link_name="_fltused") _fltused: i32 = 0x9875 + +@(private, export, link_name="_tls_index") _tls_index: u32 +@(private, export, link_name="_tls_array") _tls_array: u32 diff --git a/core/sys/cpu/cpu_x86.odin b/core/sys/cpu/cpu_x86.odin index 8f3560a87..146822e61 100644 --- a/core/sys/cpu/cpu_x86.odin +++ b/core/sys/cpu/cpu_x86.odin @@ -1,4 +1,4 @@ -//+build 386, amd64 +//+build i386, amd64 package sys_cpu _cache_line_size :: 64; diff --git a/core/sys/unix/syscalls_linux.odin b/core/sys/unix/syscalls_linux.odin index 25c5ed0a1..3dc3d2c74 100644 --- a/core/sys/unix/syscalls_linux.odin +++ b/core/sys/unix/syscalls_linux.odin @@ -675,7 +675,7 @@ when ODIN_ARCH == "amd64" { SYS_landlock_create_ruleset : uintptr : 444 SYS_landlock_add_rule : uintptr : 445 SYS_landlock_restrict_self : uintptr : 446 -} else when ODIN_ARCH == "386" { +} else when ODIN_ARCH == "i386" { SYS_restart_syscall : uintptr : 0 SYS_exit : uintptr : 1 SYS_fork : uintptr : 2 diff --git a/src/build_settings.cpp b/src/build_settings.cpp index bafa93042..5e4534517 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -29,7 +29,7 @@ enum TargetArchKind { TargetArch_Invalid, TargetArch_amd64, - TargetArch_386, + TargetArch_i386, TargetArch_arm64, TargetArch_wasm32, TargetArch_wasm64, @@ -63,7 +63,7 @@ String target_os_names[TargetOs_COUNT] = { String target_arch_names[TargetArch_COUNT] = { str_lit(""), str_lit("amd64"), - str_lit("386"), + str_lit("i386"), str_lit("arm64"), str_lit("wasm32"), str_lit("wasm64"), @@ -269,9 +269,9 @@ bool global_ignore_warnings(void) { } -gb_global TargetMetrics target_windows_386 = { +gb_global TargetMetrics target_windows_i386 = { TargetOs_windows, - TargetArch_386, + TargetArch_i386, 4, 8, str_lit("i386-pc-windows-msvc"), @@ -285,9 +285,9 @@ gb_global TargetMetrics target_windows_amd64 = { str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; -gb_global TargetMetrics target_linux_386 = { +gb_global TargetMetrics target_linux_i386 = { TargetOs_linux, - TargetArch_386, + TargetArch_i386, 4, 8, str_lit("i386-pc-linux-gnu"), @@ -328,9 +328,9 @@ gb_global TargetMetrics target_darwin_arm64 = { str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), // TODO(bill): Is this correct? }; -gb_global TargetMetrics target_freebsd_386 = { +gb_global TargetMetrics target_freebsd_i386 = { TargetOs_freebsd, - TargetArch_386, + TargetArch_i386, 4, 8, str_lit("i386-unknown-freebsd-elf"), @@ -401,12 +401,12 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("darwin_amd64"), &target_darwin_amd64 }, { str_lit("darwin_arm64"), &target_darwin_arm64 }, { str_lit("essence_amd64"), &target_essence_amd64 }, - { str_lit("linux_386"), &target_linux_386 }, + { str_lit("linux_i386"), &target_linux_i386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, { str_lit("linux_arm64"), &target_linux_arm64 }, - { str_lit("windows_386"), &target_windows_386 }, + { str_lit("windows_i386"), &target_windows_i386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, - { str_lit("freebsd_386"), &target_freebsd_386 }, + { str_lit("freebsd_i386"), &target_freebsd_i386 }, { str_lit("freebsd_amd64"), &target_freebsd_amd64 }, { str_lit("freestanding_wasm32"), &target_freestanding_wasm32 }, { str_lit("wasi_wasm32"), &target_wasi_wasm32 }, @@ -879,13 +879,13 @@ void init_build_context(TargetMetrics *cross_target) { #endif #else #if defined(GB_SYSTEM_WINDOWS) - metrics = &target_windows_386; + metrics = &target_windows_i386; #elif defined(GB_SYSTEM_OSX) #error "Build Error: Unsupported architecture" #elif defined(GB_SYSTEM_FREEBSD) - metrics = &target_freebsd_386; + metrics = &target_freebsd_i386; #else - metrics = &target_linux_386; + metrics = &target_linux_i386; #endif #endif @@ -932,7 +932,7 @@ void init_build_context(TargetMetrics *cross_target) { bc->link_flags = str_lit("-arch x86-64 "); break; } - } else if (bc->metrics.arch == TargetArch_386) { + } else if (bc->metrics.arch == TargetArch_i386) { switch (bc->metrics.os) { case TargetOs_windows: bc->link_flags = str_lit("/machine:x86 "); diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 82ad6d161..a42741976 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3225,7 +3225,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case TargetOs_essence: case TargetOs_freebsd: switch (build_context.metrics.arch) { - case TargetArch_386: + case TargetArch_i386: case TargetArch_amd64: case TargetArch_arm64: max_arg_count = 7; diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 42f05bb27..310df6639 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1193,7 +1193,7 @@ LB_ABI_INFO(lb_get_abi_info) { } else { return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); } - case TargetArch_386: + case TargetArch_i386: return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); case TargetArch_arm64: return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 7a7f20f8d..63fb5d4e9 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -783,7 +783,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"), t_u32, false, true); params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true); call_cleanup = false; - } else if (build_context.metrics.os == TargetOs_windows && (build_context.metrics.arch == TargetArch_386 || build_context.no_crt)) { + } else if (build_context.metrics.os == TargetOs_windows && (build_context.metrics.arch == TargetArch_i386 || build_context.no_crt)) { name = str_lit("mainCRTStartup"); } else if (is_arch_wasm()) { name = str_lit("_start"); @@ -1140,7 +1140,7 @@ void lb_generate_code(lbGenerator *gen) { switch (build_context.metrics.arch) { case TargetArch_amd64: - case TargetArch_386: + case TargetArch_i386: LLVMInitializeX86TargetInfo(); LLVMInitializeX86Target(); LLVMInitializeX86TargetMC(); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 0b2f6b3fd..1f0ed6434 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -508,7 +508,7 @@ bool lb_is_matrix_simdable(Type *t) { case TargetArch_arm64: // TODO(bill): determine when this is fine return true; - case TargetArch_386: + case TargetArch_i386: case TargetArch_wasm32: case TargetArch_wasm64: return false; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index eccf9b360..2a6eb6bb3 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1361,7 +1361,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_cpu_relax: - if (build_context.metrics.arch == TargetArch_386 || + if (build_context.metrics.arch == TargetArch_i386 || build_context.metrics.arch == TargetArch_amd64) { LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false); LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("pause"), {}); @@ -2018,7 +2018,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; - case TargetArch_386: + case TargetArch_i386: { GB_ASSERT(arg_count <= 7); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 3fe96459f..5b1b11b44 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1494,7 +1494,7 @@ lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t case TargetArch_arm64: // possible break; - case TargetArch_386: + case TargetArch_i386: case TargetArch_wasm32: case TargetArch_wasm64: is_possible = false; diff --git a/src/microsoft_craziness.h b/src/microsoft_craziness.h index 02f14dda3..b4f815284 100644 --- a/src/microsoft_craziness.h +++ b/src/microsoft_craziness.h @@ -460,7 +460,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res wchar_t *library_path = nullptr; if (build_context.metrics.arch == TargetArch_amd64) { library_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { library_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x86\\"); } else { continue; @@ -472,7 +472,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res wchar_t *link_exe_path = nullptr; if (build_context.metrics.arch == TargetArch_amd64) { link_exe_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\bin\\Hostx64\\x64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { link_exe_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\bin\\Hostx86\\x86\\"); } else { continue; @@ -529,7 +529,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res if (build_context.metrics.arch == TargetArch_amd64) { lib_path = concat(buffer, L"VC\\Lib\\amd64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { lib_path = concat(buffer, L"VC\\Lib\\"); } else { continue; @@ -542,7 +542,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res if (os_file_exists(vcruntime_filename)) { if (build_context.metrics.arch == TargetArch_amd64) { result->vs_exe_path = concat(buffer, L"VC\\bin\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { // result->vs_exe_path = concat(buffer, L"VC\\bin\\amd64_x86\\"); result->vs_exe_path = concat(buffer, L"VC\\bin\\x86_amd64\\"); } else { @@ -573,7 +573,7 @@ Find_Result find_visual_studio_and_windows_sdk() { if (build_context.metrics.arch == TargetArch_amd64) { result.windows_sdk_um_library_path = concat(result.windows_sdk_root, L"um\\x64\\"); result.windows_sdk_ucrt_library_path = concat(result.windows_sdk_root, L"ucrt\\x64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { result.windows_sdk_um_library_path = concat(result.windows_sdk_root, L"um\\x86\\"); result.windows_sdk_ucrt_library_path = concat(result.windows_sdk_root, L"ucrt\\x86\\"); } -- cgit v1.2.3 From 3f59c45740403e538a23f50c2fe4cd25e815531b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 17:42:10 +0000 Subject: Remove `main` creation in llvm_backend.cpp and have it done purely in the runtime package (partial bootstrapping) --- src/llvm_backend.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 63fb5d4e9..304effb7f 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1572,6 +1572,7 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables); + gb_unused(startup_runtime); TIME_SECTION("LLVM Global Procedures and Types"); for_array(i, info->entities) { @@ -1640,12 +1641,6 @@ void lb_generate_code(lbGenerator *gen) { } } - - if (!already_has_entry_point) { - TIME_SECTION("LLVM main"); - lb_create_main_procedure(default_module, startup_runtime); - } - for_array(j, gen->modules.entries) { lbModule *m = gen->modules.entries[j].value; for_array(i, m->missing_procedures_to_check) { -- cgit v1.2.3 From f0529535e02ab175bca3f7ff8c3bc2112d949236 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 15 Jan 2022 17:53:18 +0000 Subject: `ODIN_ENDIAN` changed to an enum constant; `ODIN_ENUM_STRING` is the new string version of the old constant --- core/crypto/_sha3/_sha3.odin | 4 ++-- core/crypto/haval/haval.odin | 2 +- core/encoding/json/marshal.odin | 4 ++-- core/fmt/fmt.odin | 4 ++-- core/hash/xxhash/streaming.odin | 2 +- core/image/png/example.odin | 2 +- core/image/png/png.odin | 2 +- core/math/bits/bits.odin | 32 ++++++++++++++++---------------- core/runtime/core.odin | 10 ++++++++++ core/runtime/udivmod128.odin | 2 +- src/build_settings.cpp | 20 +++++++++----------- src/checker.cpp | 15 +++++++++++++-- vendor/sdl2/sdl_audio.odin | 2 +- vendor/sdl2/sdl_pixels.odin | 8 ++++---- 14 files changed, 64 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/core/crypto/_sha3/_sha3.odin b/core/crypto/_sha3/_sha3.odin index 76e09bf24..9846aca42 100644 --- a/core/crypto/_sha3/_sha3.odin +++ b/core/crypto/_sha3/_sha3.odin @@ -52,7 +52,7 @@ keccakf :: proc "contextless" (st: ^[25]u64) { t: u64 = --- bc: [5]u64 = --- - when ODIN_ENDIAN != "little" { + when ODIN_ENDIAN != .Little { v: uintptr = --- for i = 0; i < 25; i += 1 { v := uintptr(&st[i]) @@ -98,7 +98,7 @@ keccakf :: proc "contextless" (st: ^[25]u64) { st[0] ~= keccakf_rndc[r] } - when ODIN_ENDIAN != "little" { + when ODIN_ENDIAN != .Little { for i = 0; i < 25; i += 1 { v = uintptr(&st[i]) t = st[i] diff --git a/core/crypto/haval/haval.odin b/core/crypto/haval/haval.odin index f95ea344d..442a348e9 100644 --- a/core/crypto/haval/haval.odin +++ b/core/crypto/haval/haval.odin @@ -1332,7 +1332,7 @@ update :: proc(ctx: ^Haval_Context, data: []byte) { } ctx.count[1] += str_len >> 29 - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if rmd_len + str_len >= 128 { copy(util.slice_to_bytes(ctx.block[:])[rmd_len:], data[:fill_len]) block(ctx, ctx.rounds) diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index adbcb95be..aa1c1559c 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -285,8 +285,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) { case runtime.Type_Info_Integer: switch info.endianness { case .Platform: return false - case .Little: return ODIN_ENDIAN != "little" - case .Big: return ODIN_ENDIAN != "big" + case .Little: return ODIN_ENDIAN != .Little + case .Big: return ODIN_ENDIAN != .Big } } return false diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index a9ff6ca47..2cc192c12 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1092,8 +1092,8 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { case runtime.Type_Info_Integer: switch info.endianness { case .Platform: return false - case .Little: return ODIN_ENDIAN != "little" - case .Big: return ODIN_ENDIAN != "big" + case .Little: return ODIN_ENDIAN != .Little + case .Big: return ODIN_ENDIAN != .Big } } return false diff --git a/core/hash/xxhash/streaming.odin b/core/hash/xxhash/streaming.odin index 737e37eae..d6df1089f 100644 --- a/core/hash/xxhash/streaming.odin +++ b/core/hash/xxhash/streaming.odin @@ -96,7 +96,7 @@ XXH3_128_canonical_from_hash :: proc(hash: XXH128_hash_t) -> (canonical: XXH128_ #assert(size_of(XXH128_canonical) == size_of(XXH128_hash_t)) t := hash - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { t.high = byte_swap(t.high) t.low = byte_swap(t.low) } diff --git a/core/image/png/example.odin b/core/image/png/example.odin index 5e7dca4c8..f4eb5128e 100644 --- a/core/image/png/example.odin +++ b/core/image/png/example.odin @@ -189,7 +189,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b img := image // PBM 16-bit images are big endian - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if img.depth == 16 { // The pixel components are in Big Endian. Let's byteswap back. input := mem.slice_data_cast([]u16, img.pixels.buf[:]) diff --git a/core/image/png/png.odin b/core/image/png/png.odin index f77bf7519..da76a4588 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -1611,7 +1611,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH } } } - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if img.depth == 16 { // The pixel components are in Big Endian. Let's byteswap. input := mem.slice_data_cast([]u16be, img.pixels.buf[:]) diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin index bff984cc7..850e8038a 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -69,29 +69,29 @@ rotate_left :: proc(x: uint, k: int) -> uint { } from_be_u8 :: proc(i: u8) -> u8 { return i } -from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } +from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } from_le_u8 :: proc(i: u8) -> u8 { return i } -from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } +from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } to_be_u8 :: proc(i: u8) -> u8 { return i } -to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } +to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } to_le_u8 :: proc(i: u8) -> u8 { return i } -to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } +to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 91b6bf5ca..424650828 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -398,6 +398,16 @@ Raw_Cstring :: struct { */ Odin_Build_Mode_Type :: type_of(ODIN_BUILD_MODE) +/* + // Defined internally by the compiler + Odin_Endian_Type :: enum int { + Unknown, + Little, + Big, + } +*/ +Odin_Endian_Type :: type_of(ODIN_ENDIAN) + ///////////////////////////// // Init Startup Procedures // diff --git a/core/runtime/udivmod128.odin b/core/runtime/udivmod128.odin index 1fd1b5f84..87ef73c2c 100644 --- a/core/runtime/udivmod128.odin +++ b/core/runtime/udivmod128.odin @@ -11,7 +11,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { q, r: [2]u64 sr: u32 = 0 - low :: 1 when ODIN_ENDIAN == "big" else 0 + low :: 1 when ODIN_ENDIAN == .Big else 0 high :: 1 - low U64_BITS :: 8*size_of(u64) U128_BITS :: 8*size_of(u128) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 5e4534517..b4a934ec8 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -170,7 +170,6 @@ struct BuildContext { // Constants String ODIN_OS; // target operating system String ODIN_ARCH; // target architecture - String ODIN_ENDIAN; // target endian String ODIN_VENDOR; // compiler vendor String ODIN_VERSION; // compiler version String ODIN_ROOT; // Odin ROOT @@ -269,7 +268,7 @@ bool global_ignore_warnings(void) { } -gb_global TargetMetrics target_windows_i386 = { +gb_global TargetMetrics target_windows_386 = { TargetOs_windows, TargetArch_i386, 4, @@ -285,7 +284,7 @@ gb_global TargetMetrics target_windows_amd64 = { str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; -gb_global TargetMetrics target_linux_i386 = { +gb_global TargetMetrics target_linux_386 = { TargetOs_linux, TargetArch_i386, 4, @@ -328,7 +327,7 @@ gb_global TargetMetrics target_darwin_arm64 = { str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), // TODO(bill): Is this correct? }; -gb_global TargetMetrics target_freebsd_i386 = { +gb_global TargetMetrics target_freebsd_386 = { TargetOs_freebsd, TargetArch_i386, 4, @@ -401,12 +400,12 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("darwin_amd64"), &target_darwin_amd64 }, { str_lit("darwin_arm64"), &target_darwin_arm64 }, { str_lit("essence_amd64"), &target_essence_amd64 }, - { str_lit("linux_i386"), &target_linux_i386 }, + { str_lit("linux_386"), &target_linux_386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, { str_lit("linux_arm64"), &target_linux_arm64 }, - { str_lit("windows_i386"), &target_windows_i386 }, + { str_lit("windows_386"), &target_windows_386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, - { str_lit("freebsd_i386"), &target_freebsd_i386 }, + { str_lit("freebsd_386"), &target_freebsd_386 }, { str_lit("freebsd_amd64"), &target_freebsd_amd64 }, { str_lit("freestanding_wasm32"), &target_freestanding_wasm32 }, { str_lit("wasi_wasm32"), &target_wasi_wasm32 }, @@ -879,13 +878,13 @@ void init_build_context(TargetMetrics *cross_target) { #endif #else #if defined(GB_SYSTEM_WINDOWS) - metrics = &target_windows_i386; + metrics = &target_windows_386; #elif defined(GB_SYSTEM_OSX) #error "Build Error: Unsupported architecture" #elif defined(GB_SYSTEM_FREEBSD) - metrics = &target_freebsd_i386; + metrics = &target_freebsd_386; #else - metrics = &target_linux_i386; + metrics = &target_linux_386; #endif #endif @@ -904,7 +903,6 @@ void init_build_context(TargetMetrics *cross_target) { bc->metrics = *metrics; bc->ODIN_OS = target_os_names[metrics->os]; bc->ODIN_ARCH = target_arch_names[metrics->arch]; - bc->ODIN_ENDIAN = target_endian_names[target_endians[metrics->arch]]; bc->endian_kind = target_endians[metrics->arch]; bc->word_size = metrics->word_size; bc->max_align = metrics->max_align; diff --git a/src/checker.cpp b/src/checker.cpp index c3dcd1d11..ddb73d33e 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -858,7 +858,6 @@ void init_universal(void) { // TODO(bill): Set through flags in the compiler add_global_string_constant("ODIN_OS", bc->ODIN_OS); add_global_string_constant("ODIN_ARCH", bc->ODIN_ARCH); - add_global_string_constant("ODIN_ENDIAN", bc->ODIN_ENDIAN); add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); @@ -876,7 +875,19 @@ void init_universal(void) { add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode); } - // add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE); + add_global_string_constant("ODIN_ENDIAN_STRING", target_endian_names[target_endians[bc->metrics.arch]]); + { + GlobalEnumValue values[TargetEndian_COUNT] = { + {"Unknown", TargetEndian_Invalid}, + + {"Little", TargetEndian_Little}, + {"Big", TargetEndian_Big}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Endian_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_ENDIAN", target_endians[bc->metrics.arch]); + } + add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG); add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT); diff --git a/vendor/sdl2/sdl_audio.odin b/vendor/sdl2/sdl_audio.odin index e108e31c6..2c5b7fedb 100644 --- a/vendor/sdl2/sdl_audio.odin +++ b/vendor/sdl2/sdl_audio.odin @@ -59,7 +59,7 @@ AUDIO_F32LSB :: 0x8120 /**< 32-bit floating point samples */ AUDIO_F32MSB :: 0x9120 /**< As above, but big-endian byte order */ AUDIO_F32 :: AUDIO_F32LSB -when ODIN_ENDIAN == "little" { +when ODIN_ENDIAN == .Little { AUDIO_U16SYS :: AUDIO_U16LSB AUDIO_S16SYS :: AUDIO_S16LSB AUDIO_S32SYS :: AUDIO_S32LSB diff --git a/vendor/sdl2/sdl_pixels.odin b/vendor/sdl2/sdl_pixels.odin index a8503c621..22f6db440 100644 --- a/vendor/sdl2/sdl_pixels.odin +++ b/vendor/sdl2/sdl_pixels.odin @@ -156,10 +156,10 @@ PixelFormatEnum :: enum u32 { ARGB2101010 = 1<<28 | PIXELTYPE_PACKED32<<24 | PACKEDORDER_ARGB<<20 | PACKEDLAYOUT_2101010<<16 | 32<<8 | 4<<0, /* Aliases for RGBA byte arrays of color data, for the current platform */ - RGBA32 = RGBA8888 when ODIN_ENDIAN == "big" else ABGR8888, - ARGB32 = ARGB8888 when ODIN_ENDIAN == "big" else BGRA8888, - BGRA32 = BGRA8888 when ODIN_ENDIAN == "big" else ARGB8888, - ABGR32 = ABGR8888 when ODIN_ENDIAN == "big" else RGBA8888, + RGBA32 = RGBA8888 when ODIN_ENDIAN == .Big else ABGR8888, + ARGB32 = ARGB8888 when ODIN_ENDIAN == .Big else BGRA8888, + BGRA32 = BGRA8888 when ODIN_ENDIAN == .Big else ARGB8888, + ABGR32 = ABGR8888 when ODIN_ENDIAN == .Big else RGBA8888, YV12 = /**< Planar mode: Y + V + U (3 planes) */ 'Y'<<24 | 'V'<<16 | '1'<<8 | '2'<<0, -- cgit v1.2.3 From 686dbb4421824f17164443b2538b587e91d400a5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jan 2022 14:43:42 +0000 Subject: Correct odin doc comment printing --- src/docs.cpp | 28 ++++++++++++++++++++++------ src/docs_writer.cpp | 5 +++-- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/docs.cpp b/src/docs.cpp index 8d65cb83a..3ea3cce1b 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -67,6 +67,14 @@ GB_COMPARE_PROC(cmp_ast_package_by_name) { #include "docs_format.cpp" #include "docs_writer.cpp" +void print_doc_line(i32 indent, String const &data) { + while (indent --> 0) { + gb_printf("\t"); + } + gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.text, data.len); + gb_printf("\n"); +} + void print_doc_line(i32 indent, char const *fmt, ...) { while (indent --> 0) { gb_printf("\t"); @@ -86,6 +94,13 @@ void print_doc_line_no_newline(i32 indent, char const *fmt, ...) { gb_printf_va(fmt, va); va_end(va); } +void print_doc_line_no_newline(i32 indent, String const &data) { + while (indent --> 0) { + gb_printf("\t"); + } + gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.text, data.len); +} + bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { if (g == nullptr) { @@ -106,8 +121,9 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { String comment = g->list[i].string; String original_comment = comment; - bool slash_slash = comment[1] == '/'; + bool slash_slash = false; if (comment[1] == '/') { + slash_slash = true; comment.text += 2; comment.len -= 2; } else if (comment[1] == '*') { @@ -131,7 +147,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { } if (slash_slash) { - print_doc_line(indent, "%.*s", LIT(comment)); + print_doc_line(indent, comment); count += 1; } else { isize pos = 0; @@ -143,7 +159,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { } } String line = substring(comment, pos, end); - pos = end+1; + pos = end; String trimmed_line = string_trim_whitespace(line); if (trimmed_line.len == 0) { if (count == 0) { @@ -159,7 +175,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { line = substring(line, 2, line.len); } - print_doc_line(indent, "%.*s", LIT(line)); + print_doc_line(indent, line); count += 1; } } @@ -263,7 +279,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { } GB_ASSERT(type_expr != nullptr || init_expr != nullptr); - print_doc_line_no_newline(2, "%.*s", LIT(e->token.string)); + print_doc_line_no_newline(2, e->token.string); if (type_expr != nullptr) { gbString t = expr_to_string(type_expr); gb_printf(": %s ", t); @@ -298,7 +314,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { for_array(i, pkg->files) { AstFile *f = pkg->files[i]; String filename = remove_directory_from_path(f->fullpath); - print_doc_line(2, "%.*s", LIT(filename)); + print_doc_line(2, filename); } } diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index 56ad0561e..94b43be99 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -292,8 +292,9 @@ bool odin_doc_append_comment_group_string(Array *buf, CommentGroup *g) { String comment = g->list[i].string; String original_comment = comment; - bool slash_slash = comment[1] == '/'; + bool slash_slash = false; if (comment[1] == '/') { + slash_slash = true; comment.text += 2; comment.len -= 2; } else if (comment[1] == '*') { @@ -330,7 +331,7 @@ bool odin_doc_append_comment_group_string(Array *buf, CommentGroup *g) { } } String line = substring(comment, pos, end); - pos = end+1; + pos = end; String trimmed_line = string_trim_whitespace(line); if (trimmed_line.len == 0) { if (count == 0) { -- cgit v1.2.3 From 0d4642825fc0d9ad5009bb4e4cae467ee9900112 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jan 2022 19:07:25 +0000 Subject: Correct package docs parsing --- src/parser.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/parser.cpp b/src/parser.cpp index 5bf43cee9..7e7146244 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5412,6 +5412,15 @@ bool parse_file(Parser *p, AstFile *f) { if (f->package_token.kind != Token_package) { return false; } + if (docs != nullptr) { + TokenPos end = token_pos_end(docs->list[docs->list.count-1]); + if (end.line == f->package_token.pos.line || end.line+1 == f->package_token.pos.line) { + // Okay + } else { + docs = nullptr; + } + } + Token package_name = expect_token_after(f, Token_Ident, "package"); if (package_name.kind == Token_Ident) { if (package_name.string == "_") { -- cgit v1.2.3 From cafb6e5587d4d3f5211b945bcb9d949a3980aa89 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jan 2022 21:33:20 +0000 Subject: Correct `//+private` for `odin doc` --- src/checker.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/checker.cpp b/src/checker.cpp index ddb73d33e..44dc90c67 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3446,6 +3446,13 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } } + if (entity_visibility_kind == EntityVisiblity_Public && + (c->scope->flags&ScopeFlag_File) && + c->scope->file && + (c->scope->file->flags & AstFile_IsPrivate)) { + entity_visibility_kind = EntityVisiblity_PrivateToPackage; + } + if (entity_visibility_kind != EntityVisiblity_Public && !(c->scope->flags&ScopeFlag_File)) { error(decl, "Attribute 'private' is not allowed on a non file scope entity"); } -- cgit v1.2.3 From fb01dfe04845a489760956cea4f0019e1464b2e3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jan 2022 22:17:07 +0000 Subject: Improve docs_writer.cpp --- core/math/big/doc.odin | 22 ---------------------- core/math/big/internal.odin | 24 +++++++++++++++++++++++- core/math/big/tune.odin | 3 +-- src/docs_writer.cpp | 2 +- src/types.cpp | 14 +++++--------- 5 files changed, 30 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/core/math/big/doc.odin b/core/math/big/doc.odin index f5e0900f5..0f9b88d01 100644 --- a/core/math/big/doc.odin +++ b/core/math/big/doc.odin @@ -2,27 +2,5 @@ A BigInt implementation in Odin. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. - -========================== Low-level routines ========================== - -IMPORTANT: `internal_*` procedures make certain assumptions about their input. - -The public functions that call them are expected to satisfy their sanity check requirements. -This allows `internal_*` call `internal_*` without paying this overhead multiple times. - -Where errors can occur, they are of course still checked and returned as appropriate. - -When importing `math:core/big` to implement an involved algorithm of your own, you are welcome -to use these procedures instead of their public counterparts. - -Most inputs and outputs are expected to be passed an initialized `Int`, for example. -Exceptions include `quotient` and `remainder`, which are allowed to be `nil` when the calling code doesn't need them. - -Check the comments above each `internal_*` implementation to see what constraints it expects to have met. - -We pass the custom allocator to procedures by default using the pattern `context.allocator = allocator`. -This way we don't have to add `, allocator` at the end of each call. - -TODO: Handle +/- Infinity and NaN. */ package math_big diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin index 5085898e5..dbcd16509 100644 --- a/core/math/big/internal.odin +++ b/core/math/big/internal.odin @@ -1,10 +1,32 @@ -//+ignore /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. + + ========================== Low-level routines ========================== + + IMPORTANT: `internal_*` procedures make certain assumptions about their input. + + The public functions that call them are expected to satisfy their sanity check requirements. + This allows `internal_*` call `internal_*` without paying this overhead multiple times. + + Where errors can occur, they are of course still checked and returned as appropriate. + + When importing `math:core/big` to implement an involved algorithm of your own, you are welcome + to use these procedures instead of their public counterparts. + + Most inputs and outputs are expected to be passed an initialized `Int`, for example. + Exceptions include `quotient` and `remainder`, which are allowed to be `nil` when the calling code doesn't need them. + + Check the comments above each `internal_*` implementation to see what constraints it expects to have met. + + We pass the custom allocator to procedures by default using the pattern `context.allocator = allocator`. + This way we don't have to add `, allocator` at the end of each call. + + TODO: Handle +/- Infinity and NaN. */ +//+ignore package math_big import "core:mem" diff --git a/core/math/big/tune.odin b/core/math/big/tune.odin index 64a73b656..78a20c12b 100644 --- a/core/math/big/tune.odin +++ b/core/math/big/tune.odin @@ -1,4 +1,3 @@ -//+ignore /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -8,7 +7,7 @@ The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. */ - +//+ignore package math_big import "core:time" diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index 94b43be99..762a2afe1 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -513,7 +513,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { break; case Type_Generic: doc_type.kind = OdinDocType_Generic; - doc_type.name = odin_doc_write_string(w, type->Generic.name); + doc_type.name = odin_doc_write_string(w, type->Generic.entity->token.string); if (type->Generic.specialized) { doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized); } diff --git a/src/types.cpp b/src/types.cpp index f621d4346..6162a5aa8 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3933,7 +3933,7 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_appendc(str, " = "); str = write_exact_value_to_string(str, var->Constant.value); } else { - str = gb_string_appendc(str, "="); + str = gb_string_appendc(str, " := "); str = write_exact_value_to_string(str, var->Constant.value); } continue; @@ -3961,14 +3961,10 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_appendc(str, "typeid/"); str = write_type_to_string(str, var->type); } else { - if (var->kind == Entity_TypeName) { - str = gb_string_appendc(str, "$"); - str = gb_string_append_length(str, name.text, name.len); - str = gb_string_appendc(str, "="); - str = write_type_to_string(str, var->type); - } else { - str = gb_string_appendc(str, "typeid"); - } + str = gb_string_appendc(str, "$"); + str = gb_string_append_length(str, name.text, name.len); + str = gb_string_appendc(str, "="); + str = write_type_to_string(str, var->type); } } } -- cgit v1.2.3 From 28a816ef25476086800a294202aad7c1a1bfc0f0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 19 Jan 2022 14:57:27 +0000 Subject: Allow for entity grouping in structs and procedure signatures with the Odin doc-format --- core/odin/doc-format/doc_format.odin | 6 +- src/check_type.cpp | 13 +++ src/docs_format.cpp | 3 +- src/docs_writer.cpp | 20 ++++- src/entity.cpp | 2 + tools/odin-html-docs/odin_html_docs_main.odin | 121 +++++++++++++++----------- tools/odin-html-docs/style.css | 13 ++- 7 files changed, 119 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin index 83cd89ca2..5e869ff73 100644 --- a/core/odin/doc-format/doc_format.odin +++ b/core/odin/doc-format/doc_format.odin @@ -11,7 +11,7 @@ String :: distinct Array(byte) Version_Type_Major :: 0 Version_Type_Minor :: 2 -Version_Type_Patch :: 2 +Version_Type_Patch :: 3 Version_Type :: struct { major, minor, patch: u8, @@ -122,6 +122,10 @@ Entity :: struct { _: u32le, // reserved for init comment: String, docs: String, + // May be used by (Struct fields and procedure fields): + // .Variable + // .Constant + field_group_index: i32le, // May used by: // .Variable diff --git a/src/check_type.cpp b/src/check_type.cpp index 5389252b3..a5a757f3e 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -109,11 +109,14 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields } i32 field_src_index = 0; + i32 field_group_index = -1; for_array(i, params) { Ast *param = params[i]; if (param->kind != Ast_Field) { continue; } + field_group_index += 1; + ast_node(p, Field, param); Ast *type_expr = p->type; Type *type = nullptr; @@ -152,6 +155,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index); add_entity(ctx, ctx->scope, name, field); + field->Variable.field_group_index = field_group_index; array_add(&fields_array, field); String tag = p->tag.string; if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) { @@ -1366,11 +1370,13 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is isize variadic_index = -1; bool is_c_vararg = false; auto variables = array_make(permanent_allocator(), 0, variable_count); + i32 field_group_index = -1; for_array(i, params) { Ast *param = params[i]; if (param->kind != Ast_Field) { continue; } + field_group_index += 1; ast_node(p, Field, param); Ast *type_expr = unparen_expr(p->type); Type *type = nullptr; @@ -1671,9 +1677,11 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is } param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type)); + param->Constant.field_group_index = field_group_index; } else { param = alloc_entity_param(scope, name->Ident.token, type, is_using, true); param->Variable.param_value = param_value; + param->Variable.field_group_index = field_group_index; } } if (p->flags&FieldFlag_no_alias) { @@ -1767,7 +1775,10 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { } auto variables = array_make(permanent_allocator(), 0, variable_count); + i32 field_group_index = -1; for_array(i, results) { + field_group_index += 1; + ast_node(field, Field, results[i]); Ast *default_value = unparen_expr(field->default_value); ParameterValue param_value = {}; @@ -1798,6 +1809,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { token.string = str_lit(""); Entity *param = alloc_entity_param(scope, token, type, false, false); param->Variable.param_value = param_value; + param->Variable.field_group_index = -1; array_add(&variables, param); } else { for_array(j, field->names) { @@ -1821,6 +1833,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { Entity *param = alloc_entity_param(scope, token, type, false, false); param->flags |= EntityFlag_Result; param->Variable.param_value = param_value; + param->Variable.field_group_index = field_group_index; array_add(&variables, param); add_entity(ctx, scope, name, param); // NOTE(bill): Removes `declared but not used` when using -vet diff --git a/src/docs_format.cpp b/src/docs_format.cpp index 5cfac4817..38e7e20c2 100644 --- a/src/docs_format.cpp +++ b/src/docs_format.cpp @@ -15,7 +15,7 @@ struct OdinDocVersionType { #define OdinDocVersionType_Major 0 #define OdinDocVersionType_Minor 2 -#define OdinDocVersionType_Patch 2 +#define OdinDocVersionType_Patch 3 struct OdinDocHeaderBase { u8 magic[8]; @@ -185,6 +185,7 @@ struct OdinDocEntity { u32 reserved_for_init; OdinDocString comment; OdinDocString docs; + i32 field_group_index; OdinDocEntityIndex foreign_library; OdinDocString link_name; OdinDocArray attributes; diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index 762a2afe1..c4a0cd27f 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -512,10 +512,16 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { doc_type.entities = odin_doc_add_entity_as_slice(w, type->Named.type_name); break; case Type_Generic: - doc_type.kind = OdinDocType_Generic; - doc_type.name = odin_doc_write_string(w, type->Generic.entity->token.string); - if (type->Generic.specialized) { - doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized); + { + String name = type->Generic.name; + if (type->Generic.entity) { + name = type->Generic.entity->token.string; + } + doc_type.kind = OdinDocType_Generic; + doc_type.name = odin_doc_write_string(w, name); + if (type->Generic.specialized) { + doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized); + } } break; case Type_Pointer: @@ -810,6 +816,7 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { OdinDocEntityKind kind = OdinDocEntity_Invalid; u32 flags = 0; + i32 field_group_index = -1; switch (e->kind) { case Entity_Invalid: kind = OdinDocEntity_Invalid; break; @@ -839,6 +846,10 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { if (init_expr == nullptr) { init_expr = e->Variable.init_expr; } + field_group_index = e->Variable.field_group_index; + break; + case Entity_Constant: + field_group_index = e->Constant.field_group_index; break; case Entity_Procedure: if (e->Procedure.is_foreign) { flags |= OdinDocEntityFlag_Foreign; } @@ -883,6 +894,7 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { doc_entity.init_string = init_string; doc_entity.comment = odin_doc_comment_group_string(w, comment); doc_entity.docs = odin_doc_comment_group_string(w, docs); + doc_entity.field_group_index = field_group_index; doc_entity.foreign_library = 0; // Set later doc_entity.link_name = odin_doc_write_string(w, link_name); if (e->decl_info != nullptr) { diff --git a/src/entity.cpp b/src/entity.cpp index b39ffc63a..05ee9a33e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -160,10 +160,12 @@ struct Entity { ExactValue value; ParameterValue param_value; u32 flags; + i32 field_group_index; } Constant; struct { Ast *init_expr; // only used for some variables within procedure bodies i32 field_index; + i32 field_group_index; ParameterValue param_value; diff --git a/tools/odin-html-docs/odin_html_docs_main.odin b/tools/odin-html-docs/odin_html_docs_main.odin index a2d516812..e196aa236 100644 --- a/tools/odin-html-docs/odin_html_docs_main.odin +++ b/tools/odin-html-docs/odin_html_docs_main.odin @@ -10,6 +10,7 @@ import "core:sort" import "core:slice" GITHUB_CORE_URL :: "https://github.com/odin-lang/Odin/tree/master/core" +BASE_CORE_URL :: "/core" header: ^doc.Header files: []doc.File @@ -96,7 +97,7 @@ write_html_footer :: proc(w: io.Writer, include_directory_js: bool) { io.write(w, #load("footer.txt.html")) - if include_directory_js { + if false && include_directory_js { io.write_string(w, `