diff --git a/core/sys/win32/kernel32.odin b/core/sys/win32/kernel32.odin index 3cedf72e4..036fc016a 100644 --- a/core/sys/win32/kernel32.odin +++ b/core/sys/win32/kernel32.odin @@ -39,7 +39,6 @@ foreign kernel32 { @(link_name="FileTimeToSystemTime") file_time_to_system_time :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool ---; @(link_name="SystemTimeToFileTime") system_time_to_file_time :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool ---; - @(link_name="CloseHandle") close_handle :: proc(h: Handle) -> i32 ---; @(link_name="GetStdHandle") get_std_handle :: proc(h: i32) -> Handle ---; @(link_name="CreateFileA") @@ -116,9 +115,10 @@ foreign kernel32 { @(link_name="WaitForSingleObject") wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 ---; } -@(default_calling_convention = "c") +// @(default_calling_convention = "c") foreign kernel32 { @(link_name="GetLastError") get_last_error :: proc() -> i32 ---; + @(link_name="CloseHandle") close_handle :: proc(h: Handle) -> i32 ---; @(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: cstring) -> u32 ---; @(link_name="GetFileAttributesW") get_file_attributes_w :: proc(filename: Wstring) -> u32 ---; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 5ede584aa..adcbf7684 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -432,6 +432,48 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, } +typedef bool TypeCheckSig(Type *t); +bool sig_compare(TypeCheckSig *a, Type *x, Type *y) { + return (a(x) && a(y)); +} +bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y) { + if (a == b) { + return sig_compare(a, x, y); + } + return (a(x) && b(y) || b(x) && a(y)); +} + +bool signature_parameter_similar_enough(Type *x, Type *y) { + if (sig_compare(is_type_pointer, x, y)) { + return true; + } + + if (sig_compare(is_type_integer, x, y)) { + GB_ASSERT(x->kind == Type_Basic); + GB_ASSERT(y->kind == Type_Basic); + i64 sx = type_size_of(x); + i64 sy = type_size_of(y); + if (sx == sy) return true; + } + + if (sig_compare(is_type_integer, is_type_boolean, x, y)) { + GB_ASSERT(x->kind == Type_Basic); + GB_ASSERT(y->kind == Type_Basic); + i64 sx = type_size_of(x); + i64 sy = type_size_of(y); + if (sx == sy) return true; + } + if (sig_compare(is_type_cstring, is_type_u8_ptr, x, y)) { + return true; + } + + if (sig_compare(is_type_uintptr, is_type_rawptr, x, y)) { + return true; + } + + return are_types_identical(x, y); +} + bool are_signatures_similar_enough(Type *a_, Type *b_) { GB_ASSERT(a_->kind == Type_Proc); @@ -448,36 +490,14 @@ bool are_signatures_similar_enough(Type *a_, Type *b_) { for (isize i = 0; i < a->param_count; i++) { Type *x = core_type(a->params->Tuple.variables[i]->type); Type *y = core_type(b->params->Tuple.variables[i]->type); - if (is_type_pointer(x) && is_type_pointer(y)) { - continue; + if (!signature_parameter_similar_enough(x, y)) { + return false; } - - if (is_type_integer(x) && is_type_integer(y)) { - GB_ASSERT(x->kind == Type_Basic); - GB_ASSERT(y->kind == Type_Basic); - i64 sx = type_size_of(x); - i64 sy = type_size_of(y); - if (sx == sy) continue; - } - - if (!are_types_identical(x, y)) return false; } for (isize i = 0; i < a->result_count; i++) { Type *x = base_type(a->results->Tuple.variables[i]->type); Type *y = base_type(b->results->Tuple.variables[i]->type); - if (is_type_pointer(x) && is_type_pointer(y)) { - continue; - } - - if (is_type_integer(x) && is_type_integer(y)) { - GB_ASSERT(x->kind == Type_Basic); - GB_ASSERT(y->kind == Type_Basic); - i64 sx = type_size_of(x); - i64 sy = type_size_of(y); - if (sx == sy) continue; - } - - if (!are_types_identical(x, y)) { + if (!signature_parameter_similar_enough(x, y)) { return false; } } diff --git a/src/checker.cpp b/src/checker.cpp index 130c4aee5..971c714b2 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1993,6 +1993,12 @@ DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { error(elem, "Expected a string value for '%.*s'", LIT(name)); } return true; + } else if (name == "private") { + if (ev.kind != ExactValue_Invalid) { + error(value, "'%.*s' does not expect a value", LIT(name)); + } + c->foreign_context.is_private = true; + return true; } return false; @@ -2414,7 +2420,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { ast_node(vd, ValueDecl, decl); - bool entity_is_private = false; + bool entity_is_private = c->foreign_context.is_private; for_array(i, vd->attributes) { Ast *attr = vd->attributes[i]; if (attr->kind != Ast_Attribute) continue; diff --git a/src/checker.hpp b/src/checker.hpp index 4420d6bb4..479a368e6 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -425,6 +425,7 @@ struct ForeignContext { Ast * curr_library; ProcCallingConvention default_cc; String link_prefix; + bool is_private; }; typedef Array CheckerTypePath;