|
@@ -127,14 +127,6 @@ void check_scope_decls(Checker *c, Array<AstNode *> nodes, isize reserve_size) {
|
|
|
check_entity_decl(c, e, d, nullptr);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- for_array(i, s->elements.entries) {
|
|
|
- Entity *e = s->elements.entries[i].value;
|
|
|
- if (e->kind != Entity_Procedure) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- check_procedure_overloading(c, e);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -659,18 +651,16 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (operand->mode == Addressing_Overload) {
|
|
|
+ if (operand->mode == Addressing_ProcGroup) {
|
|
|
// GB_PANIC("HERE!\n");
|
|
|
|
|
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
|
|
defer (gb_temp_arena_memory_end(tmp));
|
|
|
|
|
|
- Entity **procs = operand->overload_entities;
|
|
|
- isize overload_count = operand->overload_count;
|
|
|
-
|
|
|
+ Array<Entity *> procs = proc_group_entities(c, *operand);
|
|
|
bool good = false;
|
|
|
// NOTE(bill): These should be done
|
|
|
- for (isize i = 0; i < overload_count; i++) {
|
|
|
+ for_array(i, procs) {
|
|
|
Type *t = base_type(procs[i]->type);
|
|
|
if (t == t_invalid) {
|
|
|
continue;
|
|
@@ -783,7 +773,10 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
|
|
|
return false;
|
|
|
case Type_Array:
|
|
|
if (source->kind == Type_Array) {
|
|
|
- if (poly->Array.generic_type && modify_type) {
|
|
|
+
|
|
|
+ // IMPORTANT TODO(bill): Which is correct?
|
|
|
+ // if (poly->Array.generic_type != nullptr && modify_type) {
|
|
|
+ if (poly->Array.generic_type != nullptr) {
|
|
|
Type *gt = poly->Array.generic_type;
|
|
|
GB_ASSERT(gt->kind == Type_Generic);
|
|
|
Entity *e = scope_lookup_entity(gt->Generic.scope, gt->Generic.name);
|
|
@@ -808,8 +801,6 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
- return is_polymorphic_type_assignable(c, poly->Array.elem, source->Array.elem, true, modify_type);
|
|
|
}
|
|
|
if (poly->Array.count == source->Array.count) {
|
|
|
return is_polymorphic_type_assignable(c, poly->Array.elem, source->Array.elem, true, modify_type);
|
|
@@ -936,10 +927,6 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|
|
return nullptr;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- bool is_overloaded = false;
|
|
|
- isize overload_count = 0;
|
|
|
-
|
|
|
bool is_alias = false;
|
|
|
while (e->kind == Entity_Alias) {
|
|
|
GB_ASSERT(e->Alias.base != nullptr);
|
|
@@ -949,63 +936,14 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|
|
|
|
|
HashKey key = hash_string(e->token.string);
|
|
|
|
|
|
-
|
|
|
- if (e->kind == Entity_Procedure) {
|
|
|
- // NOTE(bill): Overloads are only allowed with the same scope
|
|
|
- Scope *s = e->scope;
|
|
|
- overload_count = multi_map_count(&s->elements, key);
|
|
|
- if (overload_count > 1) {
|
|
|
- is_overloaded = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (is_overloaded) {
|
|
|
- Scope *s = e->scope;
|
|
|
- bool skip = false;
|
|
|
-
|
|
|
- Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
|
|
|
- multi_map_get_all(&s->elements, key, procs);
|
|
|
- if (type_hint != nullptr) {
|
|
|
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
|
|
- defer (gb_temp_arena_memory_end(tmp));
|
|
|
-
|
|
|
- // NOTE(bill): These should be done
|
|
|
- for (isize i = 0; i < overload_count; i++) {
|
|
|
- Type *t = base_type(procs[i]->type);
|
|
|
- if (t == t_invalid) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- Operand x = {};
|
|
|
- x.mode = Addressing_Value;
|
|
|
- x.type = t;
|
|
|
- if (check_is_assignable_to(c, &x, type_hint)) {
|
|
|
- e = procs[i];
|
|
|
- add_entity_use(c, n, e);
|
|
|
- skip = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!skip) {
|
|
|
- o->mode = Addressing_Overload;
|
|
|
- o->type = t_invalid;
|
|
|
- o->overload_count = overload_count;
|
|
|
- o->overload_entities = procs;
|
|
|
- return nullptr;
|
|
|
- }
|
|
|
- gb_free(heap_allocator(), procs);
|
|
|
- }
|
|
|
-
|
|
|
- if (e->kind == Entity_ProcedureGrouping) {
|
|
|
- auto *pge = &e->ProcedureGrouping;
|
|
|
+ if (e->kind == Entity_ProcGroup) {
|
|
|
+ auto *pge = &e->ProcGroup;
|
|
|
|
|
|
DeclInfo *d = decl_info_of_entity(&c->info, e);
|
|
|
check_entity_decl(c, e, d, nullptr);
|
|
|
|
|
|
|
|
|
- Entity **procs = pge->entities.data;
|
|
|
- isize overload_count = pge->entities.count;
|
|
|
+ Array<Entity *> procs = pge->entities;
|
|
|
bool skip = false;
|
|
|
|
|
|
if (type_hint != nullptr) {
|
|
@@ -1013,7 +951,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|
|
defer (gb_temp_arena_memory_end(tmp));
|
|
|
|
|
|
// NOTE(bill): These should be done
|
|
|
- for (isize i = 0; i < overload_count; i++) {
|
|
|
+ for_array(i, procs) {
|
|
|
Type *t = base_type(procs[i]->type);
|
|
|
if (t == t_invalid) {
|
|
|
continue;
|
|
@@ -1031,10 +969,9 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|
|
}
|
|
|
|
|
|
if (!skip) {
|
|
|
- o->mode = Addressing_Overload;
|
|
|
- o->type = t_invalid;
|
|
|
- o->overload_count = overload_count;
|
|
|
- o->overload_entities = procs;
|
|
|
+ o->mode = Addressing_ProcGroup;
|
|
|
+ o->type = t_invalid;
|
|
|
+ o->proc_group = e;
|
|
|
return nullptr;
|
|
|
}
|
|
|
}
|
|
@@ -1550,13 +1487,13 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
|
|
|
}
|
|
|
} else {
|
|
|
gbString xt, yt;
|
|
|
- if (x->mode == Addressing_Overload) {
|
|
|
- xt = gb_string_make(heap_allocator(), "overloaded procedure");
|
|
|
+ if (x->mode == Addressing_ProcGroup) {
|
|
|
+ xt = gb_string_make(heap_allocator(), "procedure group");
|
|
|
} else {
|
|
|
xt = type_to_string(x->type);
|
|
|
}
|
|
|
- if (y->mode == Addressing_Overload) {
|
|
|
- yt = gb_string_make(heap_allocator(), "overloaded procedure");
|
|
|
+ if (y->mode == Addressing_ProcGroup) {
|
|
|
+ yt = gb_string_make(heap_allocator(), "procedure group");
|
|
|
} else {
|
|
|
yt = type_to_string(y->type);
|
|
|
}
|
|
@@ -2483,18 +2420,6 @@ bool check_index_value(Checker *c, bool open_range, AstNode *index_value, i64 ma
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-isize entity_overload_count(Scope *s, String name) {
|
|
|
- Entity *e = scope_lookup_entity(s, name);
|
|
|
- if (e == nullptr) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- if (e->kind == Entity_Procedure) {
|
|
|
- // NOTE(bill): Overloads are only allowed with the same scope
|
|
|
- return multi_map_count(&s->elements, hash_string(e->token.string));
|
|
|
- }
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_hint) {
|
|
|
ast_node(se, SelectorExpr, node);
|
|
|
|
|
@@ -2572,7 +2497,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|
|
}
|
|
|
|
|
|
check_entity_decl(c, entity, nullptr, nullptr);
|
|
|
- GB_ASSERT(entity->type != nullptr || entity->kind == Entity_ProcedureGrouping);
|
|
|
+ GB_ASSERT(entity->type != nullptr || entity->kind == Entity_ProcGroup);
|
|
|
|
|
|
if (is_alias) {
|
|
|
// TODO(bill): Which scope do you search for for an alias?
|
|
@@ -2580,46 +2505,26 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|
|
entity_name = entity->token.string;
|
|
|
}
|
|
|
|
|
|
- isize overload_count = entity_overload_count(import_scope, entity_name);
|
|
|
- bool is_overloaded = overload_count > 1;
|
|
|
|
|
|
bool implicit_is_found = is_entity_implicitly_imported(e, entity);
|
|
|
bool is_not_exported = !is_entity_exported(entity);
|
|
|
if (entity->kind == Entity_ImportName) {
|
|
|
is_not_exported = true;
|
|
|
} else if (implicit_is_found) {
|
|
|
- is_not_exported = !is_overloaded;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- Entity **procs = nullptr;
|
|
|
-
|
|
|
- if (is_overloaded) {
|
|
|
- HashKey key = hash_string(entity_name);
|
|
|
- procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
|
|
|
- multi_map_get_all(&import_scope->elements, key, procs);
|
|
|
- } else if (entity->kind == Entity_ProcedureGrouping) {
|
|
|
- is_overloaded = true;
|
|
|
- procs = entity->ProcedureGrouping.entities.data;
|
|
|
- overload_count = entity->ProcedureGrouping.entities.count;
|
|
|
+ is_not_exported = true;
|
|
|
}
|
|
|
|
|
|
- if (is_overloaded) {
|
|
|
+ if (is_not_exported && entity->kind == Entity_ProcGroup) {
|
|
|
+ check_entity_decl(c, entity, nullptr, nullptr);
|
|
|
+ auto *pge = &entity->ProcGroup;
|
|
|
+ Array<Entity *> procs = pge->entities;
|
|
|
bool skip = false;
|
|
|
- for (isize i = 0; i < overload_count; i++) {
|
|
|
+ for_array(i, procs) {
|
|
|
Type *t = base_type(procs[i]->type);
|
|
|
if (t == t_invalid) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- // NOTE(bill): Check to see if it's imported
|
|
|
- if (is_entity_implicitly_imported(e, procs[i])) {
|
|
|
- gb_swap(Entity *, procs[i], procs[overload_count-1]);
|
|
|
- overload_count--;
|
|
|
- i--; // NOTE(bill): Counteract the post event
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
Operand x = {};
|
|
|
x.mode = Addressing_Value;
|
|
|
x.type = t;
|
|
@@ -2633,16 +2538,12 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|
|
}
|
|
|
|
|
|
if (!skip) {
|
|
|
- if (overload_count > 0) {
|
|
|
- operand->mode = Addressing_Overload;
|
|
|
- operand->type = t_invalid;
|
|
|
- operand->expr = node;
|
|
|
- operand->overload_count = overload_count;
|
|
|
- operand->overload_entities = procs;
|
|
|
- return procs[0];
|
|
|
- } else {
|
|
|
- is_not_exported = true;
|
|
|
- }
|
|
|
+ GB_ASSERT(e != nullptr);
|
|
|
+ operand->mode = Addressing_ProcGroup;
|
|
|
+ operand->type = t_invalid;
|
|
|
+ operand->expr = node;
|
|
|
+ operand->proc_group = e;
|
|
|
+ return e;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2791,7 +2692,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|
|
operand->builtin_id = cast(BuiltinProcId)entity->Builtin.id;
|
|
|
break;
|
|
|
|
|
|
- case Entity_ProcedureGrouping:
|
|
|
+ case Entity_ProcGroup:
|
|
|
entity->type = t_invalid;
|
|
|
break;
|
|
|
|
|
@@ -4439,7 +4340,6 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode *call) {
|
|
|
ast_node(ce, CallExpr, call);
|
|
|
|
|
@@ -4469,31 +4369,19 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
|
|
check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false);
|
|
|
}
|
|
|
|
|
|
- if (operand->mode == Addressing_Overload) {
|
|
|
- // GB_ASSERT_MSG(operand->overload_entities != nullptr &&
|
|
|
- // operand->overload_count > 0,
|
|
|
- // "%p %td", operand->overload_entities, operand->overload_count);
|
|
|
- isize overload_count = operand->overload_count;
|
|
|
- Entity ** procs = operand->overload_entities;
|
|
|
- ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, overload_count);
|
|
|
- isize valid_count = 0;
|
|
|
+ if (operand->mode == Addressing_ProcGroup) {
|
|
|
+ Array<Entity *> procs = proc_group_entities(c, *operand);
|
|
|
|
|
|
- defer (gb_free(heap_allocator(), procs));
|
|
|
+ ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count);
|
|
|
+ isize valid_count = 0;
|
|
|
defer (gb_free(heap_allocator(), valids));
|
|
|
|
|
|
gbString expr_name = expr_to_string(operand->expr);
|
|
|
defer (gb_string_free(expr_name));
|
|
|
|
|
|
- for (isize i = 0; i < overload_count; i++) {
|
|
|
- Entity *e = procs[i];
|
|
|
- // GB_ASSERT(e->token.string == name);
|
|
|
- DeclInfo *d = decl_info_of_entity(&c->info, e);
|
|
|
- GB_ASSERT(d != nullptr);
|
|
|
- check_entity_decl(c, e, d, nullptr);
|
|
|
- }
|
|
|
-
|
|
|
- for (isize i = 0; i < overload_count; i++) {
|
|
|
+ for_array(i, procs) {
|
|
|
Entity *p = procs[i];
|
|
|
+ check_entity_decl(c, p, nullptr, nullptr);
|
|
|
Type *pt = base_type(p->type);
|
|
|
if (pt != nullptr && is_type_proc(pt)) {
|
|
|
CallArgumentError err = CallArgumentError_None;
|
|
@@ -4502,6 +4390,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
|
|
defer (c->context = prev_context);
|
|
|
c->context.no_polymorphic_errors = true;
|
|
|
c->context.allow_polymorphic_types = is_type_polymorphic(pt);
|
|
|
+
|
|
|
err = call_checker(c, call, pt, p, operands, CallArgumentMode_NoErrors, &data);
|
|
|
|
|
|
if (err == CallArgumentError_None) {
|
|
@@ -4531,7 +4420,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
|
|
|
|
|
|
|
|
if (valid_count == 0) {
|
|
|
- error(operand->expr, "No overloads or ambiguous call for '%s' that match with the given arguments", expr_name);
|
|
|
+ error(operand->expr, "No procedures or ambiguous call for procedure group '%s' that match with the given arguments", expr_name);
|
|
|
gb_printf_err("\tGiven argument types -> (");
|
|
|
for_array(i, operands) {
|
|
|
Operand o = operands[i];
|
|
@@ -4542,10 +4431,10 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
|
|
}
|
|
|
gb_printf_err(")\n");
|
|
|
|
|
|
- if (overload_count > 0) {
|
|
|
+ if (procs.count > 0) {
|
|
|
gb_printf_err("Did you mean to use one of the following:\n");
|
|
|
}
|
|
|
- for (isize i = 0; i < overload_count; i++) {
|
|
|
+ for_array(i, procs) {
|
|
|
Entity *proc = procs[i];
|
|
|
TokenPos pos = proc->token.pos;
|
|
|
Type *t = base_type(proc->type);
|
|
@@ -4562,12 +4451,12 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
|
|
// gb_printf_err("\t%.*s :: %s at %.*s(%td:%td)\n", LIT(name), pt, LIT(pos.file), pos.line, pos.column);
|
|
|
gb_string_free(pt);
|
|
|
}
|
|
|
- if (overload_count > 0) {
|
|
|
+ if (procs.count > 0) {
|
|
|
gb_printf_err("\n");
|
|
|
}
|
|
|
result_type = t_invalid;
|
|
|
} else if (valid_count > 1) {
|
|
|
- error(operand->expr, "Ambiguous procedure call '%s' tha match with the given arguments", expr_name);
|
|
|
+ error(operand->expr, "Ambiguous procedure group call '%s' that match with the given arguments", expr_name);
|
|
|
gb_printf_err("\tGiven argument types -> (");
|
|
|
for_array(i, operands) {
|
|
|
Operand o = operands[i];
|
|
@@ -4606,11 +4495,8 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
|
|
proc_type = e->type;
|
|
|
CallArgumentData data = {};
|
|
|
CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data);
|
|
|
- if (data.gen_entity != nullptr) {
|
|
|
- add_entity_use(c, ident, data.gen_entity);
|
|
|
- } else {
|
|
|
- add_entity_use(c, ident, e);
|
|
|
- }
|
|
|
+ Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
|
|
|
+ add_entity_use(c, ident, entity_to_use);
|
|
|
return data;
|
|
|
}
|
|
|
} else {
|
|
@@ -4623,11 +4509,8 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
|
|
|
Entity *e = entity_of_ident(&c->info, ident);
|
|
|
CallArgumentData data = {};
|
|
|
CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data);
|
|
|
- if (data.gen_entity != nullptr) {
|
|
|
- add_entity_use(c, ident, data.gen_entity);
|
|
|
- } else {
|
|
|
- add_entity_use(c, ident, e);
|
|
|
- }
|
|
|
+ Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
|
|
|
+ add_entity_use(c, ident, entity_to_use);
|
|
|
return data;
|
|
|
}
|
|
|
|
|
@@ -4953,7 +4836,7 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
|
|
|
}
|
|
|
|
|
|
Type *proc_type = base_type(operand->type);
|
|
|
- if (operand->mode != Addressing_Overload) {
|
|
|
+ if (operand->mode != Addressing_ProcGroup) {
|
|
|
bool valid_type = (proc_type != nullptr) && is_type_proc(proc_type);
|
|
|
bool valid_mode = is_operand_value(*operand);
|
|
|
if (!valid_type || !valid_mode) {
|
|
@@ -5206,8 +5089,8 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
|
|
o->mode = Addressing_Constant;
|
|
|
case_end;
|
|
|
|
|
|
- case_ast_node(pg, ProcGrouping, node);
|
|
|
- error(node, "Illegal use of a procedure grouping");
|
|
|
+ case_ast_node(pg, ProcGroup, node);
|
|
|
+ error(node, "Illegal use of a procedure group");
|
|
|
o->mode = Addressing_Invalid;
|
|
|
case_end;
|
|
|
|
|
@@ -6205,7 +6088,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
|
|
|
str = gb_string_appendc(str, "---");
|
|
|
case_end;
|
|
|
|
|
|
- case_ast_node(pg, ProcGrouping, node);
|
|
|
+ case_ast_node(pg, ProcGroup, node);
|
|
|
str = gb_string_appendc(str, "proc[");
|
|
|
for_array(i, pg->args) {
|
|
|
if (i > 0) str = gb_string_appendc(str, ", ");
|