diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 9ddb8ee83..2b33c45a8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -93,7 +93,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-python@v2 with: - python-version: '3.x' + python-version: '3.8.x' - name: Install B2 CLI shell: bash @@ -127,16 +127,23 @@ jobs: BUCKET: ${{ secrets.B2_BUCKET }} DAYS_TO_KEEP: ${{ secrets.B2_DAYS_TO_KEEP }} run: | + echo Authorizing B2 account b2 authorize-account "$APPID" "$APPKEY" - + + echo Uploading artifcates to B2 chmod +x ./ci/upload_create_nightly.sh ./ci/upload_create_nightly.sh "$BUCKET" windows-amd64 windows_artifacts/ ./ci/upload_create_nightly.sh "$BUCKET" ubuntu-amd64 ubuntu_artifacts/ ./ci/upload_create_nightly.sh "$BUCKET" macos-amd64 macos_artifacts/ + echo Deleting old artifacts in B2 python3 ci/delete_old_binaries.py "$BUCKET" "$DAYS_TO_KEEP" + echo Creating nightly.json python3 ci/create_nightly_json.py "$BUCKET" > nightly.json + + echo Uploading nightly.json b2 upload-file "$BUCKET" nightly.json nightly.json + echo Clear B2 account info b2 clear-account diff --git a/core/log/multi_logger.odin b/core/log/multi_logger.odin index b4cd8b1a1..55c0f1436 100644 --- a/core/log/multi_logger.odin +++ b/core/log/multi_logger.odin @@ -13,6 +13,8 @@ create_multi_logger :: proc(logs: ..Logger) -> Logger { } destroy_multi_logger :: proc(log : ^Logger) { + data := (^Multi_Logger_Data)(log.data) + delete(data.loggers) free(log.data) log^ = nil_logger() } diff --git a/core/runtime/default_allocators_nil.odin b/core/runtime/default_allocators_nil.odin index 443f41a51..5100bc517 100644 --- a/core/runtime/default_allocators_nil.odin +++ b/core/runtime/default_allocators_nil.odin @@ -6,12 +6,12 @@ package runtime default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) { - return nil, .None; + return nil, .None } default_allocator :: proc() -> Allocator { return Allocator{ procedure = default_allocator_proc, data = nil, - }; + } } diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index 16930185e..96944c7f2 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -177,8 +177,70 @@ mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignment new_ptr = raw_data(new_data) return } -memory_equal :: proc "contextless" (a, b: rawptr, n: int) -> bool { - return memory_compare(a, b, n) == 0 +memory_equal :: proc "contextless" (x, y: rawptr, n: int) -> bool { + switch { + case n == 0: return true + case x == y: return true + } + + a, b := ([^]byte)(x), ([^]byte)(y) + length := uint(n) + + when size_of(uint) == 8 { + if word_length := length >> 3; word_length != 0 { + for i in 0..> 2; word_length != 0 { + for i in 0.. int #no_bounds_check { switch { @@ -258,15 +320,13 @@ memory_compare_zero :: proc "contextless" (a: rawptr, n: int) -> int #no_bounds_ return 0 } -string_eq :: proc "contextless" (a, b: string) -> bool { - x := transmute(Raw_String)a - y := transmute(Raw_String)b - switch { - case x.len != y.len: return false - case x.len == 0: return true - case x.data == y.data: return true +string_eq :: proc "contextless" (lhs, rhs: string) -> bool { + x := transmute(Raw_String)lhs + y := transmute(Raw_String)rhs + if x.len != y.len { + return false } - return string_cmp(a, b) == 0 + return #force_inline memory_equal(x.data, y.data, x.len) } string_cmp :: proc "contextless" (a, b: string) -> int { @@ -708,7 +768,7 @@ floattidf :: proc "c" (a: i128) -> f64 { a += 1 a >>= 2 - if a & (1 << DBL_MANT_DIG) != 0 { + if a & (i128(1) << DBL_MANT_DIG) != 0 { a >>= 1 e += 1 } diff --git a/core/runtime/os_specific_freestanding.odin b/core/runtime/os_specific_freestanding.odin index 15323f763..a6d04cefb 100644 --- a/core/runtime/os_specific_freestanding.odin +++ b/core/runtime/os_specific_freestanding.odin @@ -3,5 +3,5 @@ package runtime // TODO(bill): reimplement `os.write` _os_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { - return 0, -1; + return 0, -1 } diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 6b7fe21f1..9b94be002 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -2749,6 +2749,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_volatile_store: /*fallthrough*/ + case BuiltinProc_unaligned_store: + /*fallthrough*/ case BuiltinProc_atomic_store: case BuiltinProc_atomic_store_rel: case BuiltinProc_atomic_store_relaxed: @@ -2770,6 +2772,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_volatile_load: /*fallthrough*/ + case BuiltinProc_unaligned_load: + /*fallthrough*/ case BuiltinProc_atomic_load: case BuiltinProc_atomic_load_acq: case BuiltinProc_atomic_load_relaxed: diff --git a/src/check_expr.cpp b/src/check_expr.cpp index ee7493553..d8ca190b7 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -837,7 +837,7 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co operand->mode = Addressing_Invalid; } - + convert_to_typed(c, operand, type); return; } @@ -3208,6 +3208,10 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) if (type != nullptr && type != t_invalid) { if (e->tav.type == nullptr || e->tav.type == t_invalid) { add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value); + if (e->kind == Ast_TernaryIfExpr) { + update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final); + update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final); + } } } return; @@ -3414,9 +3418,9 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { case Basic_UntypedNil: if (is_type_any(target_type)) { - target_type = t_untyped_nil; + // target_type = t_untyped_nil; } else if (is_type_cstring(target_type)) { - target_type = t_untyped_nil; + // target_type = t_untyped_nil; } else if (!type_has_nil(target_type)) { operand->mode = Addressing_Invalid; convert_untyped_error(c, operand, target_type); @@ -3587,6 +3591,14 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { } break; } + + if (is_type_any(target_type) && is_type_untyped(operand->type)) { + if (is_type_untyped_nil(operand->type) && is_type_untyped_undef(operand->type)) { + + } else { + target_type = default_type(operand->type); + } + } update_untyped_expr_type(c, operand->expr, target_type, true); operand->type = target_type; @@ -7030,18 +7042,18 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type return kind; } - Type *type = x.type; - if (is_type_untyped_nil(type) || is_type_untyped_undef(type)) { - type = y.type; + o->type = x.type; + if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) { + o->type = y.type; } - o->type = type; o->mode = Addressing_Value; - if (type_hint != nullptr && is_type_untyped(type)) { + o->expr = node; + if (type_hint != nullptr && is_type_untyped(o->type)) { if (check_cast_internal(c, &x, type_hint) && check_cast_internal(c, &y, type_hint)) { + convert_to_typed(c, o, type_hint); update_untyped_expr_type(c, node, type_hint, !is_type_untyped(type_hint)); - o->type = type_hint; } } case_end; diff --git a/src/checker.cpp b/src/checker.cpp index 23597167b..8db9e1bd6 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1111,9 +1111,12 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type void check_remove_expr_info(CheckerContext *c, Ast *e) { if (c->untyped != nullptr) { map_remove(c->untyped, hash_pointer(e)); + GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr); } else { + auto *untyped = &c->info->global_untyped; mutex_lock(&c->info->global_untyped_mutex); - map_remove(&c->info->global_untyped, hash_pointer(e)); + map_remove(untyped, hash_pointer(e)); + GB_ASSERT(map_get(untyped, hash_pointer(e)) == nullptr); mutex_unlock(&c->info->global_untyped_mutex); } } @@ -1190,7 +1193,13 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty while (prev_expr != expr) { prev_expr = expr; expr->tav.mode = mode; - expr->tav.type = type; + if (type != nullptr && expr->tav.type != nullptr && + is_type_any(type) && is_type_untyped(expr->tav.type)) { + // ignore + } else { + expr->tav.type = type; + } + if (mode == Addressing_Constant || mode == Addressing_Invalid) { expr->tav.value = value; } else if (mode == Addressing_Value && is_type_typeid(type)) { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index b503460da..3ab85f31b 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -77,6 +77,9 @@ enum BuiltinProcId { BuiltinProc_volatile_store, BuiltinProc_volatile_load, + BuiltinProc_unaligned_store, + BuiltinProc_unaligned_load, + BuiltinProc_prefetch_read_instruction, BuiltinProc_prefetch_read_data, BuiltinProc_prefetch_write_instruction, @@ -326,6 +329,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("volatile_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("volatile_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("unaligned_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("unaligned_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("prefetch_read_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("prefetch_read_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index b543089e5..49c3207fa 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -329,7 +329,7 @@ LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, BigInt const * debug_print_big_int(a); gb_printf_err("%s -> %tu\n", type_to_string(original_type), sz);; } - GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu", max_count, sz, written); + GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu, type %s", max_count, sz, written, type_to_string(original_type)); GB_ASSERT(gb_size_of(rop64) >= sz); mp_err err = mp_pack(rop, sz, &written, diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index f1d717d24..9c114882e 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2806,17 +2806,18 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { TokenPos expr_pos = ast_token(expr).pos; TypeAndValue tv = type_and_value_of_expr(expr); + Type *type = type_of_expr(expr); GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type)); if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): The commented out code below is just for debug purposes only - // GB_ASSERT_MSG(!is_type_untyped(tv.type), "%s @ %s\n%s", type_to_string(tv.type), token_pos_to_string(expr_pos), expr_to_string(expr)); - // if (is_type_untyped(tv.type)) { - // gb_printf_err("%s %s\n", token_pos_to_string(expr_pos), expr_to_string(expr)); + // if (is_type_untyped(type)) { + // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); + // GB_PANIC("%s\n", type_to_string(tv.type)); // } // NOTE(bill): Short on constant values - return lb_const_value(p->module, tv.type, tv.value); + return lb_const_value(p->module, type, tv.value); } #if 0 @@ -2847,12 +2848,12 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_ast_node(u, Undef, expr) lbValue res = {}; - if (is_type_untyped(tv.type)) { + if (is_type_untyped(type)) { res.value = nullptr; res.type = t_untyped_undef; } else { - res.value = LLVMGetUndef(lb_type(m, tv.type)); - res.type = tv.type; + res.value = LLVMGetUndef(lb_type(m, type)); + res.type = type; } return res; case_end; @@ -2893,7 +2894,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { TypeAndValue tav = type_and_value_of_expr(expr); GB_ASSERT(tav.mode == Addressing_Constant); - return lb_const_value(p->module, tv.type, tv.value); + return lb_const_value(p->module, type, tv.value); case_end; case_ast_node(se, SelectorCallExpr, expr); @@ -2966,7 +2967,6 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_ast_node(ta, TypeAssertion, expr); TokenPos pos = ast_token(expr).pos; - Type *type = tv.type; lbValue e = lb_build_expr(p, ta->expr); Type *t = type_deref(e.type); if (is_type_union(t)) { @@ -2986,16 +2986,16 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbValue e = lb_build_expr(p, tc->expr); switch (tc->token.kind) { case Token_cast: - return lb_emit_conv(p, e, tv.type); + return lb_emit_conv(p, e, type); case Token_transmute: - return lb_emit_transmute(p, e, tv.type); + return lb_emit_transmute(p, e, type); } GB_PANIC("Invalid AST TypeCast"); case_end; case_ast_node(ac, AutoCast, expr); lbValue value = lb_build_expr(p, ac->expr); - return lb_emit_conv(p, value, tv.type); + return lb_emit_conv(p, value, type); case_end; case_ast_node(ue, UnaryExpr, expr); @@ -3005,7 +3005,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { default: { lbValue v = lb_build_expr(p, ue->expr); - return lb_emit_unary_arith(p, ue->op.kind, v, tv.type); + return lb_emit_unary_arith(p, ue->op.kind, v, type); } } case_end; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 5623f75ec..5423ab51b 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1,3 +1,62 @@ +void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false) { + dst = lb_emit_conv(p, dst, t_rawptr); + src = lb_emit_conv(p, src, t_rawptr); + len = lb_emit_conv(p, len, t_int); + + char const *name = "llvm.memmove"; + if (LLVMIsConstant(len.value)) { + i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value); + if (const_len <= 4*build_context.word_size) { + name = "llvm.memmove.inline"; + } + } + + LLVMTypeRef types[3] = { + lb_type(p->module, t_rawptr), + lb_type(p->module, t_rawptr), + lb_type(p->module, t_int) + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[4] = {}; + args[0] = dst.value; + args[1] = src.value; + args[2] = len.value; + args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile); + LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); +} +void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false) { + dst = lb_emit_conv(p, dst, t_rawptr); + src = lb_emit_conv(p, src, t_rawptr); + len = lb_emit_conv(p, len, t_int); + + char const *name = "llvm.memcpy"; + if (LLVMIsConstant(len.value)) { + i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value); + if (const_len <= 4*build_context.word_size) { + name = "llvm.memcpy.inline"; + } + } + + LLVMTypeRef types[3] = { + lb_type(p->module, t_rawptr), + lb_type(p->module, t_rawptr), + lb_type(p->module, t_int) + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[4] = {}; + args[0] = dst.value; + args[1] = src.value; + args[2] = len.value; + args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile); + LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); +} + lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) { GB_ASSERT(entity != nullptr); @@ -1487,61 +1546,21 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_mem_copy: + { + lbValue dst = lb_build_expr(p, ce->args[0]); + lbValue src = lb_build_expr(p, ce->args[1]); + lbValue len = lb_build_expr(p, ce->args[2]); + + lb_mem_copy_overlapping(p, dst, src, len, false); + return {}; + } case BuiltinProc_mem_copy_non_overlapping: { lbValue dst = lb_build_expr(p, ce->args[0]); lbValue src = lb_build_expr(p, ce->args[1]); lbValue len = lb_build_expr(p, ce->args[2]); - dst = lb_emit_conv(p, dst, t_rawptr); - src = lb_emit_conv(p, src, t_rawptr); - len = lb_emit_conv(p, len, t_int); - - bool is_inlinable = false; - - if (ce->args[2]->tav.mode == Addressing_Constant) { - ExactValue ev = exact_value_to_integer(ce->args[2]->tav.value); - i64 const_len = exact_value_to_i64(ev); - // TODO(bill): Determine when it is better to do the `*.inline` versions - if (const_len <= 4*build_context.word_size) { - is_inlinable = true; - } - } - - char const *name = nullptr; - switch (id) { - case BuiltinProc_mem_copy: - if (is_inlinable) { - name = "llvm.memmove.inline"; - } else { - name = "llvm.memmove"; - } - break; - case BuiltinProc_mem_copy_non_overlapping: - if (is_inlinable) { - name = "llvm.memcpy.line"; - } else { - name = "llvm.memcpy"; - } - break; - } - - LLVMTypeRef types[3] = { - lb_type(p->module, t_rawptr), - lb_type(p->module, t_rawptr), - lb_type(p->module, t_int) - }; - unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); - GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2])); - LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); - - LLVMValueRef args[4] = {}; - args[0] = dst.value; - args[1] = src.value; - args[2] = len.value; - args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, false); // is_volatile parameter - - LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); - + + lb_mem_copy_non_overlapping(p, dst, src, len, false); return {}; } @@ -1647,6 +1666,25 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, res.type = type_deref(dst.type); return res; } + + case BuiltinProc_unaligned_store: + { + lbValue dst = lb_build_expr(p, ce->args[0]); + lbValue src = lb_build_expr(p, ce->args[1]); + src = lb_address_from_load_or_generate_local(p, src); + Type *t = type_deref(dst.type); + lb_mem_copy_non_overlapping(p, dst, src, lb_const_int(p->module, t_int, type_size_of(t)), false); + return {}; + } + + case BuiltinProc_unaligned_load: + { + lbValue src = lb_build_expr(p, ce->args[0]); + Type *t = type_deref(src.type); + lbAddr dst = lb_add_local_generated(p, t, false); + lb_mem_copy_non_overlapping(p, dst.addr, src, lb_const_int(p->module, t_int, type_size_of(t)), false); + return lb_addr_load(p, dst); + } case BuiltinProc_atomic_add: case BuiltinProc_atomic_add_acq: diff --git a/src/main.cpp b/src/main.cpp index cdc6468ab..8c6fb90af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -632,7 +632,9 @@ enum BuildFlagKind { BuildFlag_IgnoreWarnings, BuildFlag_WarningsAsErrors, BuildFlag_VerboseErrors, - BuildFlag_IgnoreLazy, // internal use only + + // internal use only + BuildFlag_InternalIgnoreLazy, #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, @@ -779,7 +781,8 @@ 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_IgnoreLazy, str_lit("ignore-lazy"), BuildFlagParam_None, Command_all); + + add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); #if defined(GB_SYSTEM_WINDOWS) add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); @@ -1393,7 +1396,7 @@ bool parse_build_flags(Array args) { build_context.show_error_line = true; break; - case BuildFlag_IgnoreLazy: + case BuildFlag_InternalIgnoreLazy: build_context.ignore_lazy = true; break; diff --git a/src/map.cpp b/src/map.cpp index 55eb4fbce..3a34764bf 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -114,16 +114,17 @@ gb_internal isize map__add_entry(Map *h, HashKey const &key) { template gb_internal MapFindResult map__find(Map *h, HashKey const &key) { MapFindResult fr = {-1, -1, -1}; - if (h->hashes.count > 0) { - fr.hash_index = key.key & (h->hashes.count-1); - fr.entry_index = h->hashes.data[fr.hash_index]; - while (fr.entry_index >= 0) { - if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) { - return fr; - } - fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + if (h->hashes.count == 0) { + return fr; + } + fr.hash_index = key.key & (h->hashes.count-1); + fr.entry_index = h->hashes.data[fr.hash_index]; + while (fr.entry_index >= 0) { + if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) { + return fr; } + fr.entry_prev = fr.entry_index; + fr.entry_index = h->entries.data[fr.entry_index].next; } return fr; } @@ -131,16 +132,17 @@ gb_internal MapFindResult map__find(Map *h, HashKey const &key) { template gb_internal MapFindResult map__find_from_entry(Map *h, MapEntry *e) { MapFindResult fr = {-1, -1, -1}; - if (h->hashes.count > 0) { - fr.hash_index = e->key.key & (h->hashes.count-1); - fr.entry_index = h->hashes.data[fr.hash_index]; - while (fr.entry_index >= 0) { - if (&h->entries.data[fr.entry_index] == e) { - return fr; - } - fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + if (h->hashes.count == 0) { + return fr; + } + fr.hash_index = e->key.key & (h->hashes.count-1); + fr.entry_index = h->hashes.data[fr.hash_index]; + while (fr.entry_index >= 0) { + if (&h->entries.data[fr.entry_index] == e) { + return fr; } + fr.entry_prev = fr.entry_index; + fr.entry_index = h->entries.data[fr.entry_index].next; } return fr; } @@ -246,6 +248,8 @@ void map__erase(Map *h, MapFindResult const &fr) { return; } h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; + array_pop(&h->entries); + last = map__find(h, h->entries.data[fr.entry_index].key); if (last.entry_prev >= 0) { h->entries.data[last.entry_prev].next = fr.entry_index; diff --git a/src/parser.cpp b/src/parser.cpp index 83da481d5..12888a52d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2572,6 +2572,9 @@ bool is_literal_type(Ast *node) { case Ast_MatrixType: case Ast_CallExpr: return true; + case Ast_MultiPointerType: + // For better error messages + return true; } return false; } @@ -5426,8 +5429,7 @@ bool parse_file(Parser *p, AstFile *f) { // Ignore } else if (f->flags & AstFile_IsTest) { // Ignore - } else if (build_context.command_kind == Command_doc && - f->pkg->kind == Package_Init) { + } else if (f->pkg->kind == Package_Init && build_context.command_kind == Command_doc) { // Ignore } else { f->flags |= AstFile_IsLazy; diff --git a/src/parser.hpp b/src/parser.hpp index b58047dfd..418d035c4 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -28,9 +28,9 @@ enum AddressingMode : u8 { }; struct TypeAndValue { + Type * type; AddressingMode mode; bool is_lhs; // Debug info - Type * type; ExactValue value; }; diff --git a/vendor/sdl2/sdl_keyboard.odin b/vendor/sdl2/sdl_keyboard.odin index 507b549cb..86112863a 100644 --- a/vendor/sdl2/sdl_keyboard.odin +++ b/vendor/sdl2/sdl_keyboard.odin @@ -9,7 +9,7 @@ when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } Keysym :: struct { scancode: Scancode, /**< SDL physical key code - see ::SDL_Scancode for details */ - sym: KeyCode, /**< SDL virtual key code - see ::SDL_KeyCode for details */ + sym: Keycode, /**< SDL virtual key code - see ::SDL_Keycode for details */ mod: Keymod, /**< current key modifiers */ unused: u32, } @@ -19,12 +19,12 @@ Keysym :: struct { foreign lib { GetKeyboardFocus :: proc() -> ^Window --- GetKeyboardState :: proc(numkeys: ^c.int) -> [^]u8 --- - GetKeyFromScancode :: proc(scancode: Scancode) -> KeyCode --- - GetScancodeFromKey :: proc(key: KeyCode) -> Scancode --- + GetKeyFromScancode :: proc(scancode: Scancode) -> Keycode --- + GetScancodeFromKey :: proc(key: Keycode) -> Scancode --- GetScancodeName :: proc(scancode: Scancode) -> cstring --- GetScancodeFromName :: proc(name: cstring) -> Scancode --- - GetKeyName :: proc(key: KeyCode) -> cstring --- - GetKeyFromName :: proc(name: cstring) -> KeyCode --- + GetKeyName :: proc(key: Keycode) -> cstring --- + GetKeyFromName :: proc(name: cstring) -> Keycode --- StartTextInput :: proc() --- IsTextInputActive :: proc() -> bool --- StopTextInput :: proc() --- diff --git a/vendor/sdl2/sdl_keycode.odin b/vendor/sdl2/sdl_keycode.odin index 2b79d0e47..73637f072 100644 --- a/vendor/sdl2/sdl_keycode.odin +++ b/vendor/sdl2/sdl_keycode.odin @@ -2,11 +2,11 @@ package sdl2 SCANCODE_MASK :: 1<<30 -SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> KeyCode { - return KeyCode(i32(X) | SCANCODE_MASK) +SCANCODE_TO_KEYCODE :: #force_inline proc "c" (X: Scancode) -> Keycode { + return Keycode(i32(X) | SCANCODE_MASK) } -KeyCode :: enum i32 { +Keycode :: enum i32 { UNKNOWN = 0, RETURN = '\r',