diff options
| author | Harold Brenes <harold@hbrenes.com> | 2025-05-03 00:58:33 -0400 |
|---|---|---|
| committer | Harold Brenes <harold@hbrenes.com> | 2025-05-03 00:59:33 -0400 |
| commit | 5f0b47c373e34c231879b2700e78ab1bbd6219b5 (patch) | |
| tree | 4e9057eb33276486cdcaded3bb1db56ec4660ff7 /src/checker.cpp | |
| parent | 0746127654aaa980c3a35039c636b3ca1b794fc8 (diff) | |
Implement all checker specification for Objective-C class implementations and `objc_ivar_get` intrinsic
Diffstat (limited to 'src/checker.cpp')
| -rw-r--r-- | src/checker.cpp | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/src/checker.cpp b/src/checker.cpp index 15d19fb1a..0b093936d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3352,7 +3352,7 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { ac->test = true; return true; } else if (name == "export") { - if (ac->objc_is_implementation) { + if (ac->objc_is_implementation) { // TODO(harold): Remove from here, this needs to be checked after all attributes are set. error(value, "Setting @(export) explicitly is not allowed when @(objc_implement) is set. It is exported implicitly."); return false; } @@ -3369,7 +3369,7 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { return true; } else if (name == "linkage") { - if (ac->objc_is_implementation) { + if (ac->objc_is_implementation) { // TODO(harold): Remove from here, this needs to be checked after all attributes are set. error(value, "Explicit linkage not allowed when @(objc_implement) is set. It is set implicitly"); return false; } @@ -3684,6 +3684,10 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind == ExactValue_Bool) { ac->objc_is_implementation = ev.value_bool; + + if (!ac->objc_is_implementation) { + ac->objc_is_disabled_implement = true; + } } else if (ev.kind == ExactValue_Invalid) { ac->objc_is_implementation = true; } else { @@ -3970,7 +3974,7 @@ gb_internal DECL_ATTRIBUTE_PROC(type_decl_attribute) { } else if (name == "objc_ivar") { Type *objc_ivar = check_type(c, value); - if (objc_ivar != nullptr) { + if (objc_ivar != nullptr && objc_ivar->kind == Type_Named) { ac->objc_ivar = objc_ivar; } else { error(value, "'%.*s' expected a named type", LIT(name)); @@ -6488,36 +6492,33 @@ gb_internal void check_objc_context_provider_procedures(Checker *c) { Entity *proc_entity = e->TypeName.objc_context_provider; GB_ASSERT(proc_entity->kind == Entity_Procedure); - Type *proc_type = proc_entity->type; + auto &proc = proc_entity->type->Proc; - // TODO(harold): Give better errors here (specify exactly what's wrong) - const char *signature_error = "The procedure for @(objc_context_provider) has an incorrect signature."; - - if (proc_type->Proc.param_count != 1 || proc_type->Proc.result_count != 1) { - error(proc_entity->token, signature_error); - } else { - Type *self_param = base_type(proc_type->Proc.params->Tuple.variables[0]->type); - Type *return_type = base_named_type(proc_type->Proc.results->Tuple.variables[0]->type); + Type *return_type = proc.result_count != 1 ? t_untyped_nil : base_named_type(proc.results->Tuple.variables[0]->type); + if (return_type != t_context) { + error(proc_entity->token, "The @(objc_context_provider) procedure must only return a context."); + } - if (self_param->kind != Type_Pointer) { - error(proc_entity->token, signature_error); - continue; - } + const char *self_param_err = "The @(objc_context_provider) procedure must take as a parameter a single pointer to the @(objc_type) value."; + if (proc.param_count != 1) { + error(proc_entity->token, self_param_err); + } - self_param = base_named_type(self_param->Pointer.elem); + Type *self_param = base_type(proc.params->Tuple.variables[0]->type); + if (self_param->kind == Type_Pointer) { + error(proc_entity->token, self_param_err); + } - if (return_type != t_context) { - error(e->token, signature_error); - } else if (!internal_check_is_assignable_to(self_param, e->type) && - (e->TypeName.objc_ivar && !internal_check_is_assignable_to(self_param, e->TypeName.objc_ivar)) - ) { - error(e->token, signature_error); - } else if (proc_type->Proc.calling_convention != ProcCC_CDecl && - proc_type->Proc.calling_convention != ProcCC_Contextless) { - error(e->token, signature_error); - } else if (proc_type->Proc.is_polymorphic) { - error(e->token, signature_error); - } + Type *self_type = base_named_type(self_param->Pointer.elem); + if (!internal_check_is_assignable_to(self_type, e->type) && + !(e->TypeName.objc_ivar && internal_check_is_assignable_to(self_type, e->TypeName.objc_ivar))) { + error(proc_entity->token, self_param_err); + } + if (proc.calling_convention != ProcCC_CDecl && proc.calling_convention != ProcCC_Contextless) { + error(e->token, self_param_err); + } + if (proc.is_polymorphic) { + error(e->token, self_param_err); } } } |