aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp86
1 files changed, 53 insertions, 33 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 2e9a80a67..2f39a6b77 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -1075,9 +1075,6 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
return NULL;
}
- if (operands != NULL) {
- GB_ASSERT(operands->count == params.count);
- }
isize variable_count = 0;
@@ -1089,6 +1086,11 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
}
}
+ if (operands != NULL) {
+ GB_ASSERT_MSG(operands->count == variable_count, "%td vs %td", operands->count, variable_count);
+ }
+
+
bool is_variadic = false;
bool is_c_vararg = false;
Entity **variables = gb_alloc_array(c->allocator, Entity *, variable_count);
@@ -5059,45 +5061,50 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
final_proc_type = make_type_proc(c->allocator, c->context.scope, NULL, 0, NULL, 0, false, pt->calling_convention);
check_procedure_type(c, final_proc_type, pt->node, &operands);
- u64 tags = entity->Procedure.tags;
- AstNode *ident = clone_ast_node(a, entity->identifier);
- Token token = ident->Ident;
- DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, old_decl->parent);
- d->gen_proc_type = final_proc_type;
- d->type_expr = pd->type;
- d->proc_decl = proc_decl;
-
- gen_entity = make_entity_procedure(c->allocator, entity->scope, token, final_proc_type, tags);
- gen_entity->identifier = ident;
-
- add_entity_and_decl_info(c, ident, gen_entity, d);
- add_entity_definition(&c->info, ident, gen_entity);
-
- add_entity_use(c, ident, gen_entity);
- add_entity_use(c, ce->proc, gen_entity);
-
- check_procedure_later(c, c->curr_ast_file, token, d, final_proc_type, pd->body, tags);
-
+ bool skip = false;
auto *found = map_get(&c->info.gen_procs, hash_pointer(entity->identifier));
if (found) {
- bool ok = true;
for_array(i, *found) {
Entity *other = (*found)[i];
- if (are_types_identical(other->type, gen_entity->type)) {
- ok = false;
+ if (are_types_identical(other->type, final_proc_type)) {
+ skip = true;
+ gen_entity = other;
+ final_proc_type = other->type;
break;
}
}
- if (ok) {
+ }
+
+ if (!skip) {
+ u64 tags = entity->Procedure.tags;
+ AstNode *ident = clone_ast_node(a, entity->identifier);
+ Token token = ident->Ident;
+ DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, old_decl->parent);
+ d->gen_proc_type = final_proc_type;
+ d->type_expr = pd->type;
+ d->proc_decl = proc_decl;
+
+ gen_entity = make_entity_procedure(c->allocator, NULL, token, final_proc_type, tags);
+ gen_entity->identifier = ident;
+
+ add_entity_and_decl_info(c, ident, gen_entity, d);
+ gen_entity->scope = entity->scope;
+ add_entity_use(c, ident, gen_entity);
+ check_procedure_later(c, c->curr_ast_file, token, d, final_proc_type, pd->body, tags);
+
+
+ if (found) {
array_add(found, gen_entity);
+ } else {
+ Array<Entity *> array = {};
+ array_init(&array, heap_allocator());
+ array_add(&array, gen_entity);
+ map_set(&c->info.gen_procs, hash_pointer(entity->identifier), array);
}
- } else {
- Array<Entity *> array = {};
- array_init(&array, heap_allocator());
- array_add(&array, gen_entity);
- map_set(&c->info.gen_procs, hash_pointer(entity->identifier), array);
}
+
+ GB_ASSERT(gen_entity != NULL);
}
@@ -5119,7 +5126,12 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
error(o.expr, "Expected a type for the argument");
}
- score += assign_score_function(1);
+ if (are_types_identical(e->type, o.type)) {
+ score += assign_score_function(1);
+ } else {
+ score += assign_score_function(5);
+ }
+
continue;
}
if (variadic) {
@@ -5271,7 +5283,11 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
} else if (o->mode != Addressing_Type) {
error(o->expr, "Expected a type for the argument");
}
- score += assign_score_function(1);
+ if (are_types_identical(e->type, o->type)) {
+ score += assign_score_function(1);
+ } else {
+ score += assign_score_function(5);
+ }
} else {
i64 s = 0;
if (!check_is_assignable_to_with_score(c, o, e->type, &s)) {
@@ -5581,8 +5597,12 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
}
}
+
CallArgumentData data = check_call_arguments(c, operand, proc_type, call);
Type *result_type = data.result_type;
+ if (data.gen_entity != NULL) {
+ add_entity_use(c, ce->proc, data.gen_entity);
+ }
gb_zero_item(operand);
operand->expr = call;