Browse Source

Amend Checker API

Ginger Bill 8 years ago
parent
commit
9faf0020cc
4 changed files with 81 additions and 57 deletions
  1. 1 1
      src/check_expr.cpp
  2. 50 5
      src/checker.cpp
  3. 8 46
      src/ir.cpp
  4. 22 5
      src/map.cpp

+ 1 - 1
src/check_expr.cpp

@@ -3409,7 +3409,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 			isize overload_count = entity_overload_count(import_scope, entity_name);
 			bool is_overloaded = overload_count > 1;
 
-			bool implicit_is_found = map_get(&e->ImportName.scope->implicit, hash_pointer(entity)) != NULL;
+			bool implicit_is_found = is_entity_implicitly_imported(e, entity);
 			bool is_not_exported = !is_entity_exported(entity);
 			if (!implicit_is_found) {
 				is_not_exported = false;

+ 50 - 5
src/checker.cpp

@@ -308,25 +308,26 @@ struct DelayedEntity {
 	DeclInfo *  decl;
 };
 
-Entity *     entity_of_ident        (CheckerInfo *i, AstNode *identifier);
+// CheckerInfo API
 TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr);
 Type *       type_of_expr           (CheckerInfo *i, AstNode *expr);
+Entity *     entity_of_ident        (CheckerInfo *i, AstNode *identifier);
 Entity *     implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
 DeclInfo *   decl_info_of_entity    (CheckerInfo *i, Entity * e);
 DeclInfo *   decl_info_of_ident     (CheckerInfo *i, AstNode *ident);
 AstFile *    ast_file_of_filename   (CheckerInfo *i, String   filename);
 Scope *      scope_of_node          (CheckerInfo *i, AstNode *node);
-ExprInfo *   check_get_expr_info    (CheckerInfo *i, AstNode *expr);
-void         check_set_expr_info    (CheckerInfo *i, AstNode *expr, ExprInfo info);
-void         check_remove_expr_info (CheckerInfo *i, AstNode *expr);
+isize        type_info_index        (CheckerInfo *i, Type *type); // Only to use once checking is done
+
 
 Entity *current_scope_lookup_entity(Scope *s, String name);
-void    scope_lookup_parent_entity (Scope *s, String name, Scope **scope_, Entity **entity_);
 Entity *scope_lookup_entity        (Scope *s, String name);
+void    scope_lookup_parent_entity (Scope *s, String name, Scope **scope_, Entity **entity_);
 Entity *scope_insert_entity        (Scope *s, Entity *entity);
 
 
 
+
 void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
 	d->parent = parent;
 	d->scope  = scope;
@@ -812,6 +813,11 @@ Entity *implicit_entity_of_node(CheckerInfo *i, AstNode *clause) {
 	}
 	return NULL;
 }
+bool is_entity_implicitly_imported(Entity *import_name, Entity *e) {
+	GB_ASSERT(import_name->kind == Entity_ImportName);
+	return map_get(&import_name->ImportName.scope->implicit, hash_pointer(e)) != NULL;
+}
+
 
 DeclInfo *decl_info_of_entity(CheckerInfo *i, Entity *e) {
 	if (e != NULL) {
@@ -853,6 +859,35 @@ void check_remove_expr_info(CheckerInfo *i, AstNode *expr) {
 
 
 
+isize type_info_index(CheckerInfo *info, Type *type) {
+	type = default_type(type);
+
+	isize entry_index = -1;
+	HashKey key = hash_pointer(type);
+	isize *found_entry_index = map_get(&info->type_info_map, key);
+	if (found_entry_index) {
+		entry_index = *found_entry_index;
+	}
+	if (entry_index < 0) {
+		// NOTE(bill): Do manual search
+		// TODO(bill): This is O(n) and can be very slow
+		for_array(i, info->type_info_map.entries){
+			auto *e = &info->type_info_map.entries[i];
+			Type *prev_type = cast(Type *)e->key.ptr;
+			if (are_types_identical(prev_type, type)) {
+				entry_index = e->value;
+				// NOTE(bill): Add it to the search map
+				map_set(&info->type_info_map, key, entry_index);
+				break;
+			}
+		}
+	}
+
+	if (entry_index < 0) {
+		compiler_error("TypeInfo for `%s` could not be found", type_to_string(type));
+	}
+	return entry_index;
+}
 
 
 void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
@@ -1194,6 +1229,12 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
 	return map;
 }
 
+bool is_entity_in_dependency_map(Map<Entity *> *map, Entity *e) {
+	return map_get(map, hash_pointer(e)) != NULL;
+}
+
+
+
 
 Entity *find_core_entity(Checker *c, String name) {
 	Entity *e = current_scope_lookup_entity(c->global_scope, name);
@@ -1368,6 +1409,10 @@ void check_procedure_overloading(Checker *c, Entity *e) {
 
 			TokenPos pos = q->token.pos;
 
+			if (q->type == NULL) {
+				continue;
+			}
+
 			if (is_type_proc(q->type)) {
 				TypeProc *ptq = &base_type(q->type)->Proc;
 				if (ptq->is_generic) {

+ 8 - 46
src/ir.cpp

@@ -1653,7 +1653,6 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type)
 	ir_emit_store(proc, gep0, m);
 
 	if (is_type_string(key_type)) {
-		// GB_PANIC("TODO(bill): string map keys");
 		ir_emit_store(proc, ir_emit_struct_ep(proc, h, 1), v_true);
 	}
 
@@ -2111,13 +2110,6 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
 	case Token_Shl:
 	case Token_Shr:
 		left = ir_emit_conv(proc, left, type);
-		// if (!is_type_unsigned(ir_type(right))) {
-		// 	Type *t = t_u64;
-		// 	if (build_context.word_size == 32) {
-		// 		t = t_u32;
-		// 	}
-		// 	right = ir_emit_conv(proc, right, t);
-		// }
 		right = ir_emit_conv(proc, right, type);
 
 		break;
@@ -2149,6 +2141,9 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
 	if (op == Token_ModMod) {
 		irValue *n = left;
 		irValue *m = right;
+		if (is_type_unsigned(type)) {
+			return ir_emit_arith(proc, Token_Mod, n, m, type);
+		}
 		irValue *a = ir_emit_arith(proc, Token_Mod, n, m, type);
 		irValue *b = ir_emit_arith(proc, Token_Add, a, m, type);
 		return ir_emit_arith(proc, Token_Mod, b, m, type);
@@ -3321,39 +3316,6 @@ irValue *ir_emit_any_cast(irProcedure *proc, irValue *value, Type *type, TokenPo
 	return ir_addr_load(proc, ir_emit_any_cast_addr(proc, value, type, pos));
 }
 
-
-
-isize ir_type_info_index(CheckerInfo *info, Type *type) {
-	type = default_type(type);
-
-	isize entry_index = -1;
-	HashKey key = hash_pointer(type);
-	isize *found_entry_index = map_get(&info->type_info_map, key);
-	if (found_entry_index) {
-		entry_index = *found_entry_index;
-	}
-	if (entry_index < 0) {
-		// NOTE(bill): Do manual search
-		// TODO(bill): This is O(n) and can be very slow
-		for_array(i, info->type_info_map.entries){
-			auto *e = &info->type_info_map.entries[i];
-			Type *prev_type = cast(Type *)e->key.ptr;
-			if (are_types_identical(prev_type, type)) {
-				entry_index = e->value;
-				// NOTE(bill): Add it to the search map
-				map_set(&info->type_info_map, key, entry_index);
-				break;
-			}
-		}
-	}
-
-	if (entry_index < 0) {
-		compiler_error("TypeInfo for `%s` could not be found", type_to_string(type));
-	}
-	return entry_index;
-}
-
-
 // TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR
 gb_global irValue *ir_global_type_info_data           = NULL;
 gb_global irValue *ir_global_type_info_member_types   = NULL;
@@ -3373,7 +3335,7 @@ irValue *ir_type_info(irProcedure *proc, Type *type) {
 
 	type = default_type(type);
 
-	i32 entry_index = ir_type_info_index(info, type);
+	i32 entry_index = type_info_index(info, type);
 
 	// gb_printf_err("%d %s\n", entry_index, type_to_string(type));
 
@@ -5997,7 +5959,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 		if (pd->body != NULL) {
 			CheckerInfo *info = proc->module->info;
 
-			if (map_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
+			if (is_entity_in_dependency_map(&proc->module->min_dep_map, e) == false) {
 				// NOTE(bill): Nothing depends upon it so doesn't need to be built
 				break;
 			}
@@ -7009,7 +6971,7 @@ void ir_init_module(irModule *m, Checker *c) {
 				auto *entry = &m->info->type_info_map.entries[type_info_map_index];
 				Type *t = cast(Type *)entry->key.ptr;
 				t = default_type(t);
-				isize entry_index = ir_type_info_index(m->info, t);
+				isize entry_index = type_info_index(m->info, t);
 				if (max_index < entry_index) {
 					max_index = entry_index;
 				}
@@ -7161,7 +7123,7 @@ void ir_gen_destroy(irGen *s) {
 // Type Info stuff
 //
 irValue *ir_get_type_info_ptr(irProcedure *proc, Type *type) {
-	i32 index = cast(i32)ir_type_info_index(proc->module->info, type);
+	i32 index = cast(i32)type_info_index(proc->module->info, type);
 	// gb_printf_err("%d %s\n", index, type_to_string(type));
 	irValue *ptr = ir_emit_array_epi(proc, ir_global_type_info_data, index);
 	return ir_emit_bitcast(proc, ptr, t_type_info_ptr);
@@ -7608,7 +7570,7 @@ void ir_gen_tree(irGen *s) {
 				auto *entry = &info->type_info_map.entries[type_info_map_index];
 				Type *t = cast(Type *)entry->key.ptr;
 				t = default_type(t);
-				isize entry_index = ir_type_info_index(info, t);
+				isize entry_index = type_info_index(info, t);
 
 				irValue *tag = NULL;
 				irValue *ti_ptr = ir_emit_array_epi(proc, ir_global_type_info_data, entry_index);

+ 22 - 5
src/map.cpp

@@ -15,6 +15,12 @@ enum HashKeyKind {
 	HashKey_Default,
 	HashKey_String,
 	HashKey_Pointer,
+	HashKey_PointerAndId,
+};
+
+struct PointerAndId {
+	void *ptr;
+	u32   id;
 };
 
 struct HashKey {
@@ -22,8 +28,9 @@ struct HashKey {
 	// u128        key;
 	u64         key;
 	union {
-		String string; // if String, s.len > 0
-		void * ptr;
+		String       string; // if String, s.len > 0
+		void *       ptr;
+		PointerAndId ptr_and_id;
 	};
 };
 
@@ -44,11 +51,16 @@ gb_inline HashKey hash_string(String s) {
 }
 
 gb_inline HashKey hash_pointer(void *ptr) {
-	HashKey h = {HashKey_Default};
-	// h.key = u128_from_u64(cast(u64)cast(uintptr)ptr);
+	HashKey h = {HashKey_Pointer};
 	h.key = cast(u64)cast(uintptr)ptr;
 	h.ptr = ptr;
-	h.kind = HashKey_Default;
+	return h;
+}
+gb_inline HashKey hash_ptr_and_id(void *ptr, u32 id) {
+	HashKey h = {HashKey_PointerAndId};
+	h.key = cast(u64)cast(uintptr)ptr;
+	h.ptr_and_id.ptr = ptr;
+	h.ptr_and_id.id  = id;
 	return h;
 }
 
@@ -60,6 +72,11 @@ bool hash_key_equal(HashKey a, HashKey b) {
 				return a.string == b.string;
 			}
 			return false;
+		} else if (a.kind == HashKey_PointerAndId) {
+			if (b.kind == HashKey_PointerAndId) {
+				return a.ptr_and_id.id == b.ptr_and_id.id;
+			}
+			return false;
 		}
 		return true;
 	}