mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 11:52:22 -07:00
@(private) for foreign blocks; Improve foreign signature similarity rules
This commit is contained in:
@@ -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 ---;
|
||||
|
||||
+45
-25
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -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;
|
||||
|
||||
@@ -425,6 +425,7 @@ struct ForeignContext {
|
||||
Ast * curr_library;
|
||||
ProcCallingConvention default_cc;
|
||||
String link_prefix;
|
||||
bool is_private;
|
||||
};
|
||||
|
||||
typedef Array<Entity *> CheckerTypePath;
|
||||
|
||||
Reference in New Issue
Block a user