diff options
| author | A1029384756 <hayden.gray104@gmail.com> | 2025-10-07 23:29:10 -0400 |
|---|---|---|
| committer | A1029384756 <hayden.gray104@gmail.com> | 2025-10-07 23:29:10 -0400 |
| commit | 067fbfb48c2673ba4cf9c4b163fc99082d195147 (patch) | |
| tree | 94e6d181e27100d08a4411aa6899c6eabe559355 /src/check_expr.cpp | |
| parent | cfe651e8d23cb85097db32662acefd27b4350be9 (diff) | |
| parent | 5320feb6737c4d89ce54fda463ea8ff8b8200dba (diff) | |
Merge remote-tracking branch 'upstream/master' into llvm-14-fixes
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 81 |
1 files changed, 73 insertions, 8 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c1861652a..8834091d1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1296,11 +1296,6 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ error_line("\t Got: %s\n", s_got); gb_string_free(s_got); gb_string_free(s_expected); - - Type *tx = x->Proc.params->Tuple.variables[0]->type; - Type *ty = y->Proc.params->Tuple.variables[0]->type; - gb_printf_err("%s kind:%.*s e:%p ot:%p\n", type_to_string(tx), LIT(type_strings[tx->kind]), tx->Named.type_name, tx->Named.type_name->TypeName.original_type_for_parapoly); - gb_printf_err("%s kind:%.*s e:%p ot:%p\n", type_to_string(ty), LIT(type_strings[ty->kind]), ty->Named.type_name, ty->Named.type_name->TypeName.original_type_for_parapoly); } else { gbString s_expected = type_to_string(y); gbString s_got = type_to_string(x); @@ -6216,7 +6211,6 @@ gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize * continue; } } - break; } } @@ -7488,8 +7482,6 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, Entity *e = proc_entities[valids[0].index]; GB_ASSERT(e != nullptr); - Array<Operand> named_operands = {}; - check_call_arguments_single(c, call, operand, e, e->type, positional_operands, named_operands, @@ -8151,6 +8143,73 @@ gb_internal ExprKind check_call_expr_as_type_cast(CheckerContext *c, Operand *op } +void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice<Type *> param_types); + +gb_internal void check_objc_call_expr(CheckerContext *c, Operand *operand, Ast *call, Entity *proc_entity, Type *proc_type) { + auto &proc = proc_type->Proc; + Slice<Entity *> params = proc.params ? proc.params->Tuple.variables : Slice<Entity *>{}; + + Type *self_type = nullptr; + isize params_start = 1; + + ast_node(ce, CallExpr, call); + + Type *return_type = proc.result_count == 0 ? nullptr : proc.results->Tuple.variables[0]->type; + bool is_return_instancetype = return_type != nullptr && return_type == t_objc_instancetype; + + if (params.count == 0 || !is_type_objc_ptr_to_object(params[0]->type)) { + if (!proc_entity->Procedure.is_objc_class_method) { + // Not a class method, invalid call + error(call, "Invalid Objective-C call: The Objective-C method is not a class method but this first parameter is not an Objective-C object pointer."); + return; + } + + if (is_return_instancetype) { + if (ce->proc->kind == Ast_SelectorExpr) { + ast_node(se, SelectorExpr, ce->proc); + + // NOTE(harold): These should have already been checked, right? + GB_ASSERT(se->expr->tav.mode == Addressing_Type && se->expr->tav.type->kind == Type_Named); + + return_type = alloc_type_pointer(se->expr->tav.type); + } else { + return_type = proc_entity->Procedure.objc_class->type; + } + } + + self_type = t_objc_Class; + params_start = 0; + } else if (ce->args.count > 0) { + GB_ASSERT(is_type_objc_ptr_to_object(params[0]->type)); + + if (ce->args[0]->tav.objc_super_target) { + self_type = t_objc_super_ptr; + } else { + self_type = ce->args[0]->tav.type; + } + + if (is_return_instancetype) { + // NOTE(harold): These should have already been checked, right? + GB_ASSERT(ce->args[0]->tav.type && ce->args[0]->tav.type->kind == Type_Pointer && ce->args[0]->tav.type->Pointer.elem->kind == Type_Named); + + return_type = ce->args[0]->tav.type; + } + } + + auto param_types = slice_make<Type *>(permanent_allocator(), proc.param_count + 2 - params_start); + param_types[0] = self_type; + param_types[1] = t_objc_SEL; + + for (isize i = params_start; i < params.count; i++) { + param_types[i+2-params_start] = params[i]->type; + } + + if (is_return_instancetype) { + operand->type = return_type; + } + + add_objc_proc_type(c, call, return_type, param_types); +} gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice<Ast *> const &args, ProcInlining inlining, Type *type_hint) { if (proc != nullptr && @@ -8414,6 +8473,12 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c } } + Entity *proc_entity = entity_from_expr(call->CallExpr.proc); + bool is_objc_call = proc_entity && proc_entity->kind == Entity_Procedure && proc_entity->Procedure.is_objc_impl_or_import; + if (is_objc_call) { + check_objc_call_expr(c, operand, call, proc_entity, pt); + } + return Expr_Expr; } |