aboutsummaryrefslogtreecommitdiff
path: root/src/checker.cpp
diff options
context:
space:
mode:
authorHarold Brenes <harold@hbrenes.com>2025-05-03 00:58:33 -0400
committerHarold Brenes <harold@hbrenes.com>2025-05-03 00:59:33 -0400
commit5f0b47c373e34c231879b2700e78ab1bbd6219b5 (patch)
tree4e9057eb33276486cdcaded3bb1db56ec4660ff7 /src/checker.cpp
parent0746127654aaa980c3a35039c636b3ca1b794fc8 (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.cpp59
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);
}
}
}