From 362a11878283eea69cf5a18b7f05c964643a7a64 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Sun, 25 Jun 2017 23:41:46 +0100 Subject: [PATCH] Remove "overloading" bug of para-poly-procs --- code/demo.odin | 8 +---- core/_preload.odin | 2 +- src/check_expr.cpp | 90 ++++++++++++++++++++++++++++------------------ src/checker.cpp | 6 +++- src/ir.cpp | 15 ++++---- 5 files changed, 69 insertions(+), 52 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index d14de8f90..ea88e84b8 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,13 +1,7 @@ -import ( - "fmt.odin"; -) - +import "fmt.odin"; proc main() { - var ptr = new(int); - ptr^ = 123; - fmt.println(ptr^); } /* diff --git a/core/_preload.odin b/core/_preload.odin index 2473d028e..f2fd76d6d 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -264,7 +264,7 @@ proc resize(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGN } -proc new(T: type) -> ^T { +proc new(T: type) -> ^T #inline { return ^T(alloc(size_of(T), align_of(T))); } 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) { - array_add(found, gen_entity); - } - } else { - Array array = {}; - array_init(&array, heap_allocator()); - array_add(&array, gen_entity); - map_set(&c->info.gen_procs, hash_pointer(entity->identifier), array); } + + 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 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; diff --git a/src/checker.cpp b/src/checker.cpp index 7c23843cb..5f5b8a281 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -955,6 +955,9 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) } bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) { + if (scope == NULL) { + return false; + } String name = entity->token.string; if (name != "_") { Entity *ie = scope_insert_entity(scope, entity); @@ -1007,7 +1010,8 @@ void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclIn GB_ASSERT(identifier->kind == AstNode_Ident); GB_ASSERT(e != NULL && d != NULL); GB_ASSERT(identifier->Ident.string == e->token.string); - add_entity(c, e->scope, identifier, e); + if (e->scope != NULL) add_entity(c, e->scope, identifier, e); + add_entity_definition(&c->info, identifier, e); map_set(&c->info.entities, hash_entity(e), d); } diff --git a/src/ir.cpp b/src/ir.cpp index 641412bc1..5e05bd804 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3497,8 +3497,8 @@ String ir_mangle_name(irGen *s, String path, Entity *e) { isize base_len = ext-1-base; isize max_len = base_len + 1 + 1 + 10 + 1 + name.len; - bool is_overloaded = check_is_entity_overloaded(e); - if (is_overloaded) { + bool require_suffix_id = check_is_entity_overloaded(e) || is_type_gen_proc(e->type); + if (require_suffix_id) { max_len += 21; } @@ -3520,7 +3520,7 @@ String ir_mangle_name(irGen *s, String path, Entity *e) { file->id, LIT(name)); } - if (is_overloaded) { + if (require_suffix_id) { char *str = cast(char *)new_name + new_name_len-1; isize len = max_len-new_name_len; isize extra = gb_snprintf(str, len, "-%llu", cast(unsigned long long)e->id); @@ -5853,7 +5853,7 @@ void ir_type_case_body(irProcedure *proc, AstNode *label, AstNode *clause, irBlo } -void ir_build_nested_proc(irProcedure *proc, AstNodeProcDecl *pd, Entity *e) { +void ir_build_poly_proc(irProcedure *proc, AstNodeProcDecl *pd, Entity *e) { GB_ASSERT(pd->body != NULL); if (is_entity_in_dependency_map(&proc->module->min_dep_map, e) == false) { @@ -6018,10 +6018,10 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { for_array(i, found) { Entity *e = found[i]; DeclInfo *d = decl_info_of_entity(info, e); - ir_build_nested_proc(proc, &d->proc_decl->ProcDecl, e); + ir_build_poly_proc(proc, &d->proc_decl->ProcDecl, e); } } else { - ir_build_nested_proc(proc, pd, e); + ir_build_poly_proc(proc, pd, e); } } else { @@ -7359,7 +7359,7 @@ void ir_gen_tree(irGen *s) { continue; } - if (!scope->is_global) { + if (!scope->is_global || is_type_gen_proc(e->type)) { if (e->kind == Entity_Procedure && (e->Procedure.tags & ProcTag_export) != 0) { } else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) { // Handle later @@ -7414,7 +7414,6 @@ void ir_gen_tree(irGen *s) { String original_name = name; AstNode *body = pd->body; - if (e->Procedure.is_foreign) { name = e->token.string; // NOTE(bill): Don't use the mangled name ir_add_foreign_library_path(m, e->Procedure.foreign_library);