aboutsummaryrefslogtreecommitdiff
path: root/src/checker.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2017-12-09 18:11:36 +0000
committergingerBill <bill@gingerbill.org>2017-12-09 18:11:36 +0000
commit3703ca4df47134e0c274cf5096d14c9323331ff0 (patch)
treea01aab633bf3d25aba33357cb8d181537e9c841b /src/checker.cpp
parent41b8281c7355eea7c4a2022027769df8a519ae7a (diff)
Explicit procedure group; Remove implicit procedure overloading
Diffstat (limited to 'src/checker.cpp')
-rw-r--r--src/checker.cpp166
1 files changed, 20 insertions, 146 deletions
diff --git a/src/checker.cpp b/src/checker.cpp
index 7c9f20135..16bc32ca1 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -120,7 +120,7 @@ enum AddressingMode {
Addressing_Constant, // constant
Addressing_Type, // type
Addressing_Builtin, // built-in procedure
- Addressing_Overload, // overloaded procedure
+ Addressing_ProcGroup, // procedure group (overloaded procedure)
Addressing_MapIndex, // map index expression -
// lhs: acts like a Variable
// rhs: acts like OptionalOk
@@ -138,8 +138,7 @@ struct Operand {
ExactValue value;
AstNode * expr;
BuiltinProcId builtin_id;
- isize overload_count;
- Entity ** overload_entities;
+ Entity * proc_group;
};
struct TypeAndValue {
@@ -166,6 +165,8 @@ bool is_operand_undef(Operand o) {
return o.mode == Addressing_Value && o.type == t_untyped_undef;
}
+
+
struct BlockLabel {
String name;
AstNode *label; // AstNode_Label;
@@ -780,28 +781,10 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
HashKey key = hash_string(name);
Entity **found = map_get(&s->elements, key);
-#ifndef DISABLE_PROCEDURE_OVERLOADING
- // IMPORTANT NOTE(bill): Procedure overloading code
- Entity *prev = nullptr;
- if (found) {
- prev = *found;
- if (prev->kind != Entity_Procedure ||
- entity->kind != Entity_Procedure) {
- return prev;
- }
- }
-
- if (prev != nullptr && entity->kind == Entity_Procedure) {
- multi_map_insert(&s->elements, key, entity);
- } else {
- map_set(&s->elements, key, entity);
- }
-#else
if (found) {
return *found;
}
map_set(&s->elements, key, entity);
-#endif
if (entity->scope == nullptr) {
entity->scope = s;
}
@@ -1620,6 +1603,18 @@ Type *find_core_type(Checker *c, String name) {
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type);
+Array<Entity *> proc_group_entities(Checker *c, Operand o) {
+ Array<Entity *> procs = {};
+ if (o.mode == Addressing_ProcGroup) {
+ GB_ASSERT(o.proc_group != nullptr);
+ if (o.proc_group->kind == Entity_ProcGroup) {
+ check_entity_decl(c, o.proc_group, nullptr, nullptr);
+ return o.proc_group->ProcGroup.entities;
+ }
+ }
+ return procs;
+}
+
void init_preload(Checker *c) {
if (t_type_info == nullptr) {
Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info"));
@@ -1736,118 +1731,6 @@ void check_collect_entities(Checker *c, Array<AstNode *> nodes);
void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws);
void check_delayed_file_import_entity(Checker *c, AstNode *decl);
-bool check_is_entity_overloaded(Entity *e) {
- if (e->kind != Entity_Procedure) {
- return false;
- }
- Scope *s = e->scope;
- HashKey key = hash_string(e->token.string);
- isize overload_count = multi_map_count(&s->elements, key);
- return overload_count > 1;
-}
-
-void check_procedure_overloading(Checker *c, Entity *e) {
- GB_ASSERT(e->kind == Entity_Procedure);
- if (e->type == t_invalid) {
- return;
- }
- if (e->Procedure.overload_kind != Overload_Unknown) {
- // NOTE(bill): The overloading has already been handled
- return;
- }
-
-
- // NOTE(bill): Procedures call only overload other procedures in the same scope
-
- String name = e->token.string;
- HashKey key = hash_string(name);
- Scope *s = e->scope;
- isize overload_count = multi_map_count(&s->elements, key);
- GB_ASSERT(overload_count >= 1);
- if (overload_count == 1) {
- e->Procedure.overload_kind = Overload_No;
- return;
- }
- GB_ASSERT(overload_count > 1);
-
-
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- Entity **procs = gb_alloc_array(c->tmp_allocator, Entity *, overload_count);
- multi_map_get_all(&s->elements, key, procs);
-
- for (isize j = 0; j < overload_count; j++) {
- Entity *p = procs[j];
- if (p->type == t_invalid) {
- // NOTE(bill): This invalid overload has already been handled
- continue;
- }
-
- String name = p->token.string;
-
- GB_ASSERT(p->kind == Entity_Procedure);
- for (isize k = j+1; k < overload_count; k++) {
- Entity *q = procs[k];
- GB_ASSERT(p != q);
-
- bool is_invalid = false;
- GB_ASSERT(q->kind == Entity_Procedure);
-
- TokenPos pos = q->token.pos;
-
- if (q->type == nullptr || q->type == t_invalid) {
- continue;
- }
-
- ProcTypeOverloadKind kind = are_proc_types_overload_safe(p->type, q->type);
- switch (kind) {
- case ProcOverload_Identical:
- error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
- is_invalid = true;
- break;
- // case ProcOverload_CallingConvention:
- // error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
- // is_invalid = true;
- // break;
- case ProcOverload_ParamVariadic:
- error(p->token, "Overloaded procedure '%.*s' as the same type as another procedure in this scope", LIT(name));
- is_invalid = true;
- break;
- case ProcOverload_ResultCount:
- case ProcOverload_ResultTypes:
- error(p->token, "Overloaded procedure '%.*s' as the same parameters but different results in this scope", LIT(name));
- is_invalid = true;
- break;
- case ProcOverload_Polymorphic:
- #if 0
- error(p->token, "Overloaded procedure '%.*s' has a polymorphic counterpart in this scope which is not allowed", LIT(name));
- is_invalid = true;
- #endif
- break;
- case ProcOverload_ParamCount:
- case ProcOverload_ParamTypes:
- // This is okay :)
- break;
-
- }
-
- if (is_invalid) {
- gb_printf_err("\tprevious procedure at %.*s(%td:%td)\n", LIT(pos.file), pos.line, pos.column);
- q->type = t_invalid;
- }
- }
- }
-
- for (isize j = 0; j < overload_count; j++) {
- Entity *p = procs[j];
- if (p->type != t_invalid) {
- p->Procedure.overload_kind = Overload_Yes;
- }
- }
-
- gb_temp_arena_memory_end(tmp);
-}
-
-
struct AttributeContext {
String link_name;
String link_prefix;
@@ -2259,11 +2142,11 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
}
d->proc_lit = init;
d->type_expr = pl->type;
- } else if (init->kind == AstNode_ProcGrouping) {
- ast_node(pg, ProcGrouping, init);
- e = make_entity_procedure_grouping(c->allocator, d->scope, token, nullptr);
+ } else if (init->kind == AstNode_ProcGroup) {
+ ast_node(pg, ProcGroup, init);
+ e = make_entity_proc_group(c->allocator, d->scope, token, nullptr);
if (fl != nullptr) {
- error(name, "Procedure groupings are not allowed within a foreign block");
+ error(name, "Procedure groups are not allowed within a foreign block");
}
d->init_expr = init;
} else {
@@ -2447,15 +2330,6 @@ void check_all_global_entities(Checker *c) {
init_preload(c);
}
}
-
- for_array(i, c->info.entities.entries) {
- auto *entry = &c->info.entities.entries[i];
- Entity *e = cast(Entity *)entry->key.ptr;
- if (e->kind != Entity_Procedure) {
- continue;
- }
- check_procedure_overloading(c, e);
- }
}