Remove "overloading" bug of para-poly-procs

This commit is contained in:
Ginger Bill
2017-06-25 23:41:46 +01:00
parent 3ab481df17
commit 362a118782
5 changed files with 69 additions and 52 deletions
+1 -7
View File
@@ -1,13 +1,7 @@
import (
"fmt.odin";
)
import "fmt.odin";
proc main() {
var ptr = new(int);
ptr^ = 123;
fmt.println(ptr^);
}
/*
+1 -1
View File
@@ -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)));
}
+55 -35
View File
@@ -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<Entity *> 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<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;
+5 -1
View File
@@ -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);
}
+7 -8
View File
@@ -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);