Browse Source

Remove "overloading" bug of para-poly-procs

Ginger Bill 8 years ago
parent
commit
362a118782
5 changed files with 67 additions and 50 deletions
  1. 1 7
      code/demo.odin
  2. 1 1
      core/_preload.odin
  3. 53 33
      src/check_expr.cpp
  4. 5 1
      src/checker.cpp
  5. 7 8
      src/ir.cpp

+ 1 - 7
code/demo.odin

@@ -1,13 +1,7 @@
-import (
-	"fmt.odin";
-)
-
+import "fmt.odin";
 
 proc main() {
-	var ptr = new(int);
-	ptr^ = 123;
 
-	fmt.println(ptr^);
 }
 
 /*

+ 1 - 1
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)));
 }
 

+ 53 - 33
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;
 

+ 5 - 1
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);
 }
 

+ 7 - 8
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);