diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-05-08 12:58:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-08 12:58:33 +0100 |
| commit | 92df892f25832b368e29b39dda094a7357c7f3e6 (patch) | |
| tree | 9f56732962285a117dc4fa6b602c89ed04ffbec8 /src/check_builtin.cpp | |
| parent | 4a709086a49f97e6d22bcd441bac38169b1baa21 (diff) | |
| parent | 14e25c0f2a0dea725cb098dcf9939a8d4681e7d6 (diff) | |
Merge pull request #5064 from harold-b/hb/objc-classes
Add support for Objective-C class implementation
Diffstat (limited to 'src/check_builtin.cpp')
| -rw-r--r-- | src/check_builtin.cpp | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 84e30d5b4..dd9896927 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -223,9 +223,9 @@ gb_internal void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_t data.kind = kind; data.proc_type = alloc_type_proc(scope, params, param_types.count, results, results->Tuple.variables.count, false, ProcCC_CDecl); - mutex_lock(&c->info->objc_types_mutex); + mutex_lock(&c->info->objc_objc_msgSend_mutex); map_set(&c->info->objc_msgSend_types, call, data); - mutex_unlock(&c->info->objc_types_mutex); + mutex_unlock(&c->info->objc_objc_msgSend_mutex); try_to_add_package_dependency(c, "runtime", "objc_msgSend"); try_to_add_package_dependency(c, "runtime", "objc_msgSend_fpret"); @@ -387,6 +387,59 @@ gb_internal bool check_builtin_objc_procedure(CheckerContext *c, Operand *operan try_to_add_package_dependency(c, "runtime", "objc_allocateClassPair"); return true; } break; + + case BuiltinProc_objc_ivar_get: + { + Type *self_type = nullptr; + + Operand self = {}; + check_expr_or_type(c, &self, ce->args[0]); + + if (!is_operand_value(self) || !check_is_assignable_to(c, &self, t_objc_id)) { + gbString e = expr_to_string(self.expr); + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a type or value derived from intrinsics.objc_object, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } else if (!is_type_pointer(self.type)) { + gbString e = expr_to_string(self.expr); + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a pointer of a value derived from intrinsics.objc_object, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + self_type = type_deref(self.type); + + if (!(self_type->kind == Type_Named && + self_type->Named.type_name != nullptr && + self_type->Named.type_name->TypeName.objc_class_name != "")) { + gbString t = type_to_string(self_type); + error(self.expr, "'%.*s' expected a named type with the attribute @(objc_class=<string>) , got type %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + Type *ivar_type = self_type->Named.type_name->TypeName.objc_ivar; + if (ivar_type == nullptr) { + gbString t = type_to_string(self_type); + error(self.expr, "'%.*s' requires that type %s have the attribute @(objc_ivar=<ivar_type_name>).", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + if (type_hint != nullptr && type_hint->kind == Type_Pointer && type_hint->Pointer.elem == ivar_type) { + operand->type = type_hint; + } else { + operand->type = alloc_type_pointer(ivar_type); + } + + operand->mode = Addressing_Value; + return true; + + } break; } } @@ -2167,7 +2220,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_objc_find_selector: case BuiltinProc_objc_find_class: case BuiltinProc_objc_register_selector: - case BuiltinProc_objc_register_class: + case BuiltinProc_objc_register_class: + case BuiltinProc_objc_ivar_get: return check_builtin_objc_procedure(c, operand, call, id, type_hint); case BuiltinProc___entry_point: |