Browse Source

Use templated `Map` for extra type safety

Ginger Bill 8 years ago
parent
commit
5cad7d44a6
10 changed files with 361 additions and 427 deletions
  1. 9 9
      src/check_decl.cpp
  2. 33 33
      src/check_expr.cpp
  3. 14 19
      src/check_stmt.cpp
  4. 84 114
      src/checker.cpp
  5. 1 19
      src/common.cpp
  6. 1 0
      src/exact_value.cpp
  7. 79 88
      src/ir.cpp
  8. 7 7
      src/ir_print.cpp
  9. 114 115
      src/map.cpp
  10. 19 23
      src/ssa.cpp

+ 9 - 9
src/check_decl.cpp

@@ -319,7 +319,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
 	}
 	}
 
 
 	if (is_foreign) {
 	if (is_foreign) {
-		MapEntity *fp = &c->info.foreigns;
+		auto *fp = &c->info.foreigns;
 		String name = e->token.string;
 		String name = e->token.string;
 		if (pd->foreign_name.len > 0) {
 		if (pd->foreign_name.len > 0) {
 			name = pd->foreign_name;
 			name = pd->foreign_name;
@@ -352,7 +352,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
 		e->Procedure.foreign_name = name;
 		e->Procedure.foreign_name = name;
 
 
 		HashKey key = hash_string(name);
 		HashKey key = hash_string(name);
-		Entity **found = map_entity_get(fp, key);
+		Entity **found = map_get(fp, key);
 		if (found) {
 		if (found) {
 			Entity *f = *found;
 			Entity *f = *found;
 			TokenPos pos = f->token.pos;
 			TokenPos pos = f->token.pos;
@@ -365,7 +365,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
 						   LIT(name), LIT(pos.file), pos.line, pos.column);
 						   LIT(name), LIT(pos.file), pos.line, pos.column);
 			}
 			}
 		} else {
 		} else {
-			map_entity_set(fp, key, e);
+			map_set(fp, key, e);
 		}
 		}
 	} else {
 	} else {
 		String name = e->token.string;
 		String name = e->token.string;
@@ -374,12 +374,12 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
 		}
 		}
 
 
 		if (is_link_name || is_export) {
 		if (is_link_name || is_export) {
-			MapEntity *fp = &c->info.foreigns;
+			auto *fp = &c->info.foreigns;
 
 
 			e->Procedure.link_name = name;
 			e->Procedure.link_name = name;
 
 
 			HashKey key = hash_string(name);
 			HashKey key = hash_string(name);
-			Entity **found = map_entity_get(fp, key);
+			Entity **found = map_get(fp, key);
 			if (found) {
 			if (found) {
 				Entity *f = *found;
 				Entity *f = *found;
 				TokenPos pos = f->token.pos;
 				TokenPos pos = f->token.pos;
@@ -389,7 +389,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) {
 						   "\tother at %.*s(%td:%td)",
 						   "\tother at %.*s(%td:%td)",
 						   LIT(name), LIT(pos.file), pos.line, pos.column);
 						   LIT(name), LIT(pos.file), pos.line, pos.column);
 			} else {
 			} else {
-				map_entity_set(fp, key, e);
+				map_set(fp, key, e);
 			}
 			}
 		}
 		}
 	}
 	}
@@ -443,7 +443,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
 	}
 	}
 
 
 	if (d == NULL) {
 	if (d == NULL) {
-		DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
+		DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
 		if (found) {
 		if (found) {
 			d = *found;
 			d = *found;
 		} else {
 		} else {
@@ -511,7 +511,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
 			String name = e->token.string;
 			String name = e->token.string;
 			Type *t = base_type(type_deref(e->type));
 			Type *t = base_type(type_deref(e->type));
 			if (is_type_struct(t) || is_type_raw_union(t)) {
 			if (is_type_struct(t) || is_type_raw_union(t)) {
-				Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
+				Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 				GB_ASSERT(found != NULL);
 				GB_ASSERT(found != NULL);
 				for_array(i, (*found)->elements.entries) {
 				for_array(i, (*found)->elements.entries) {
 					Entity *f = (*found)->elements.entries[i].value;
 					Entity *f = (*found)->elements.entries[i].value;
@@ -557,7 +557,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
 		for_array(i, decl->deps.entries) {
 		for_array(i, decl->deps.entries) {
 			HashKey key = decl->deps.entries[i].key;
 			HashKey key = decl->deps.entries[i].key;
 			Entity *e = cast(Entity *)key.ptr;
 			Entity *e = cast(Entity *)key.ptr;
-			map_bool_set(&decl->parent->deps, key, true);
+			map_set(&decl->parent->deps, key, true);
 		}
 		}
 	}
 	}
 }
 }

+ 33 - 33
src/check_expr.cpp

@@ -62,7 +62,7 @@ void check_scope_decls(Checker *c, Array<AstNode *> nodes, isize reserve_size) {
 		default:
 		default:
 			continue;
 			continue;
 		}
 		}
-		DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
+		DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
 		if (found != NULL) {
 		if (found != NULL) {
 			DeclInfo *d = *found;
 			DeclInfo *d = *found;
 			check_entity_decl(c, e, d, NULL);
 			check_entity_decl(c, e, d, NULL);
@@ -348,7 +348,7 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
 }
 }
 
 
 
 
-void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *entity_map) {
+void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *> *entity_map) {
 	t = base_type(type_deref(t));
 	t = base_type(type_deref(t));
 	gbString str = NULL;
 	gbString str = NULL;
 	if (node != NULL) {
 	if (node != NULL) {
@@ -361,7 +361,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
 			GB_ASSERT(f->kind == Entity_Variable);
 			GB_ASSERT(f->kind == Entity_Variable);
 			String name = f->token.string;
 			String name = f->token.string;
 			HashKey key = hash_string(name);
 			HashKey key = hash_string(name);
-			Entity **found = map_entity_get(entity_map, key);
+			Entity **found = map_get(entity_map, key);
 			if (found != NULL) {
 			if (found != NULL) {
 				Entity *e = *found;
 				Entity *e = *found;
 				// TODO(bill): Better type error
 				// TODO(bill): Better type error
@@ -371,7 +371,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
 					error(e->token, "`%.*s` is already declared`", LIT(name));
 					error(e->token, "`%.*s` is already declared`", LIT(name));
 				}
 				}
 			} else {
 			} else {
-				map_entity_set(entity_map, key, f);
+				map_set(entity_map, key, f);
 				add_entity(c, c->context.scope, NULL, f);
 				add_entity(c, c->context.scope, NULL, f);
 				if (f->flags & EntityFlag_Using) {
 				if (f->flags & EntityFlag_Using) {
 					populate_using_entity_map(c, node, f->type, entity_map);
 					populate_using_entity_map(c, node, f->type, entity_map);
@@ -390,8 +390,8 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
                    String context) {
                    String context) {
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 
 
-	MapEntity entity_map = {};
-	map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
+	Map<Entity *> entity_map = {};
+	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
 
 
 	Entity *using_index_expr = NULL;
 	Entity *using_index_expr = NULL;
 
 
@@ -433,7 +433,7 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
 				error_node(name, "`__tag` is a reserved identifier for fields");
 				error_node(name, "`__tag` is a reserved identifier for fields");
 			} else {
 			} else {
 				HashKey key = hash_string(name_token.string);
 				HashKey key = hash_string(name_token.string);
-				Entity **found = map_entity_get(&entity_map, key);
+				Entity **found = map_get(&entity_map, key);
 				if (found != NULL) {
 				if (found != NULL) {
 					Entity *e = *found;
 					Entity *e = *found;
 					// NOTE(bill): Scope checking already checks the declaration but in many cases, this can happen so why not?
 					// NOTE(bill): Scope checking already checks the declaration but in many cases, this can happen so why not?
@@ -441,7 +441,7 @@ isize check_fields(Checker *c, AstNode *node, Array<AstNode *> decls,
 					error(name_token, "`%.*s` is already declared in this type", LIT(name_token.string));
 					error(name_token, "`%.*s` is already declared in this type", LIT(name_token.string));
 					error(e->token,   "\tpreviously declared");
 					error(e->token,   "\tpreviously declared");
 				} else {
 				} else {
-					map_entity_set(&entity_map, key, e);
+					map_set(&entity_map, key, e);
 					fields[field_index++] = e;
 					fields[field_index++] = e;
 					add_entity(c, c->context.scope, name, e);
 					add_entity(c, c->context.scope, name, e);
 				}
 				}
@@ -650,8 +650,8 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
 
 
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 
 
-	MapEntity entity_map = {}; // Key: String
-	map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
+	Map<Entity *> entity_map = {}; // Key: String
+	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*variant_count);
 
 
 	Entity *using_index_expr = NULL;
 	Entity *using_index_expr = NULL;
 
 
@@ -666,7 +666,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
 	for (isize i = 0; i < field_count; i++) {
 	for (isize i = 0; i < field_count; i++) {
 		Entity *f = fields[i];
 		Entity *f = fields[i];
 		String name = f->token.string;
 		String name = f->token.string;
-		map_entity_set(&entity_map, hash_string(name), f);
+		map_set(&entity_map, hash_string(name), f);
 	}
 	}
 
 
 	union_type->Record.fields              = fields;
 	union_type->Record.fields              = fields;
@@ -735,11 +735,11 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
 		}
 		}
 
 
 		HashKey key = hash_string(name_token.string);
 		HashKey key = hash_string(name_token.string);
-		if (map_entity_get(&entity_map, key) != NULL) {
+		if (map_get(&entity_map, key) != NULL) {
 			// NOTE(bill): Scope checking already checks the declaration
 			// NOTE(bill): Scope checking already checks the declaration
 			error(name_token, "`%.*s` is already declared in this union", LIT(name_token.string));
 			error(name_token, "`%.*s` is already declared in this union", LIT(name_token.string));
 		} else {
 		} else {
-			map_entity_set(&entity_map, key, e);
+			map_set(&entity_map, key, e);
 			variants[variant_index++] = e;
 			variants[variant_index++] = e;
 		}
 		}
 		add_entity_use(c, f->name, e);
 		add_entity_use(c, f->name, e);
@@ -801,8 +801,8 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 	// NOTE(bill): Must be up here for the `check_init_constant` system
 	// NOTE(bill): Must be up here for the `check_init_constant` system
 	enum_type->Record.enum_base_type = base_type;
 	enum_type->Record.enum_base_type = base_type;
 
 
-	MapEntity entity_map = {}; // Key: String
-	map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
+	Map<Entity *> entity_map = {}; // Key: String
+	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
 
 
 	Entity **fields = gb_alloc_array(c->allocator, Entity *, et->fields.count);
 	Entity **fields = gb_alloc_array(c->allocator, Entity *, et->fields.count);
 	isize field_count = 0;
 	isize field_count = 0;
@@ -888,10 +888,10 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 		e->flags |= EntityFlag_Visited;
 		e->flags |= EntityFlag_Visited;
 
 
 		HashKey key = hash_string(name);
 		HashKey key = hash_string(name);
-		if (map_entity_get(&entity_map, key) != NULL) {
+		if (map_get(&entity_map, key) != NULL) {
 			error_node(ident, "`%.*s` is already declared in this enumeration", LIT(name));
 			error_node(ident, "`%.*s` is already declared in this enumeration", LIT(name));
 		} else {
 		} else {
-			map_entity_set(&entity_map, key, e);
+			map_set(&entity_map, key, e);
 			add_entity(c, c->context.scope, NULL, e);
 			add_entity(c, c->context.scope, NULL, e);
 			fields[field_count++] = e;
 			fields[field_count++] = e;
 			add_entity_use(c, field, e);
 			add_entity_use(c, field, e);
@@ -922,8 +922,8 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 
 
 
 
-	MapEntity entity_map = {}; // Key: String
-	map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
+	Map<Entity *> entity_map = {}; // Key: String
+	map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(bft->fields.count));
 
 
 	isize field_count = 0;
 	isize field_count = 0;
 	Entity **fields  = gb_alloc_array(c->allocator, Entity *, bft->fields.count);
 	Entity **fields  = gb_alloc_array(c->allocator, Entity *, bft->fields.count);
@@ -967,10 +967,10 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As
 
 
 		HashKey key = hash_string(name);
 		HashKey key = hash_string(name);
 		if (name != "_" &&
 		if (name != "_" &&
-		    map_entity_get(&entity_map, key) != NULL) {
+		    map_get(&entity_map, key) != NULL) {
 			error_node(ident, "`%.*s` is already declared in this bit field", LIT(name));
 			error_node(ident, "`%.*s` is already declared in this bit field", LIT(name));
 		} else {
 		} else {
-			map_entity_set(&entity_map, key, e);
+			map_set(&entity_map, key, e);
 			add_entity(c, c->context.scope, NULL, e);
 			add_entity(c, c->context.scope, NULL, e);
 			add_entity_use(c, field, e);
 			add_entity_use(c, field, e);
 
 
@@ -1418,7 +1418,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
 	if (e->kind == Entity_Procedure) {
 	if (e->kind == Entity_Procedure) {
 		// NOTE(bill): Overloads are only allowed with the same scope
 		// NOTE(bill): Overloads are only allowed with the same scope
 		Scope *s = e->scope;
 		Scope *s = e->scope;
-		overload_count = map_entity_multi_count(&s->elements, key);
+		overload_count = multi_map_count(&s->elements, key);
 		if (overload_count > 1) {
 		if (overload_count > 1) {
 			is_overloaded = true;
 			is_overloaded = true;
 		}
 		}
@@ -1429,7 +1429,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
 		bool skip = false;
 		bool skip = false;
 
 
 		Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
 		Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
-		map_entity_multi_get_all(&s->elements, key, procs);
+		multi_map_get_all(&s->elements, key, procs);
 		if (type_hint != NULL) {
 		if (type_hint != NULL) {
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 			// NOTE(bill): These should be done
 			// NOTE(bill): These should be done
@@ -2488,7 +2488,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
 
 
 		TokenPos pos = ast_node_token(x->expr).pos;
 		TokenPos pos = ast_node_token(x->expr).pos;
 		if (x_is_untyped) {
 		if (x_is_untyped) {
-			ExprInfo *info = map_expr_info_get(&c->info.untyped, hash_pointer(x->expr));
+			ExprInfo *info = map_get(&c->info.untyped, hash_pointer(x->expr));
 			if (info != NULL) {
 			if (info != NULL) {
 				info->is_lhs = true;
 				info->is_lhs = true;
 			}
 			}
@@ -2944,7 +2944,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
 
 
 void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
 void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
 	HashKey key = hash_pointer(e);
 	HashKey key = hash_pointer(e);
-	ExprInfo *found = map_expr_info_get(&c->info.untyped, key);
+	ExprInfo *found = map_get(&c->info.untyped, key);
 	if (found == NULL) {
 	if (found == NULL) {
 		return;
 		return;
 	}
 	}
@@ -2983,12 +2983,12 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
 
 
 	if (!final && is_type_untyped(type)) {
 	if (!final && is_type_untyped(type)) {
 		old.type = base_type(type);
 		old.type = base_type(type);
-		map_expr_info_set(&c->info.untyped, key, old);
+		map_set(&c->info.untyped, key, old);
 		return;
 		return;
 	}
 	}
 
 
 	// We need to remove it and then give it a new one
 	// We need to remove it and then give it a new one
-	map_expr_info_remove(&c->info.untyped, key);
+	map_remove(&c->info.untyped, key);
 
 
 	if (old.is_lhs && !is_type_integer(type)) {
 	if (old.is_lhs && !is_type_integer(type)) {
 		gbString expr_str = expr_to_string(e);
 		gbString expr_str = expr_to_string(e);
@@ -3003,7 +3003,7 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
 }
 }
 
 
 void update_expr_value(Checker *c, AstNode *e, ExactValue value) {
 void update_expr_value(Checker *c, AstNode *e, ExactValue value) {
-	ExprInfo *found = map_expr_info_get(&c->info.untyped, hash_pointer(e));
+	ExprInfo *found = map_get(&c->info.untyped, hash_pointer(e));
 	if (found) {
 	if (found) {
 		found->value = value;
 		found->value = value;
 	}
 	}
@@ -3206,7 +3206,7 @@ isize entity_overload_count(Scope *s, String name) {
 	}
 	}
 	if (e->kind == Entity_Procedure) {
 	if (e->kind == Entity_Procedure) {
 		// NOTE(bill): Overloads are only allowed with the same scope
 		// NOTE(bill): Overloads are only allowed with the same scope
-		return map_entity_multi_count(&s->elements, hash_string(e->token.string));
+		return multi_map_count(&s->elements, hash_string(e->token.string));
 	}
 	}
 	return 1;
 	return 1;
 }
 }
@@ -3298,7 +3298,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 			isize overload_count = entity_overload_count(import_scope, entity_name);
 			isize overload_count = entity_overload_count(import_scope, entity_name);
 			bool is_overloaded = overload_count > 1;
 			bool is_overloaded = overload_count > 1;
 
 
-			bool implicit_is_found = map_bool_get(&e->ImportName.scope->implicit, hash_pointer(entity)) != NULL;
+			bool implicit_is_found = map_get(&e->ImportName.scope->implicit, hash_pointer(entity)) != NULL;
 			bool is_not_exported = !is_entity_exported(entity);
 			bool is_not_exported = !is_entity_exported(entity);
 			if (!implicit_is_found) {
 			if (!implicit_is_found) {
 				is_not_exported = false;
 				is_not_exported = false;
@@ -3320,7 +3320,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 				bool skip = false;
 				bool skip = false;
 
 
 				Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
 				Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
-				map_entity_multi_get_all(&import_scope->elements, key, procs);
+				multi_map_get_all(&import_scope->elements, key, procs);
 
 
 				for (isize i = 0; i < overload_count; i++) {
 				for (isize i = 0; i < overload_count; i++) {
 					Type *t = base_type(procs[i]->type);
 					Type *t = base_type(procs[i]->type);
@@ -3329,7 +3329,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 					}
 					}
 
 
 					// NOTE(bill): Check to see if it's imported
 					// NOTE(bill): Check to see if it's imported
-					if (map_bool_get(&import_scope->implicit, hash_pointer(procs[i]))) {
+					if (map_get(&import_scope->implicit, hash_pointer(procs[i]))) {
 						gb_swap(Entity *, procs[i], procs[overload_count-1]);
 						gb_swap(Entity *, procs[i], procs[overload_count-1]);
 						overload_count--;
 						overload_count--;
 						i--; // NOTE(bill): Counteract the post event
 						i--; // NOTE(bill): Counteract the post event
@@ -4892,7 +4892,7 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod
 
 
 		for (isize i = 0; i < overload_count; i++) {
 		for (isize i = 0; i < overload_count; i++) {
 			Entity *e = procs[i];
 			Entity *e = procs[i];
-			DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
+			DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
 			GB_ASSERT(found != NULL);
 			GB_ASSERT(found != NULL);
 			DeclInfo *d = *found;
 			DeclInfo *d = *found;
 			check_entity_decl(c, e, d, NULL);
 			check_entity_decl(c, e, d, NULL);

+ 14 - 19
src/check_stmt.cpp

@@ -389,11 +389,6 @@ struct TypeAndToken {
 	Token token;
 	Token token;
 };
 };
 
 
-#define MAP_TYPE TypeAndToken
-#define MAP_PROC map_type_and_token_
-#define MAP_NAME MapTypeAndToken
-#include "map.cpp"
-
 void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
 void check_when_stmt(Checker *c, AstNodeWhenStmt *ws, u32 flags) {
 	flags &= ~Stmt_CheckScopeDecls;
 	flags &= ~Stmt_CheckScopeDecls;
 	Operand operand = {Addressing_Invalid};
 	Operand operand = {Addressing_Invalid};
@@ -535,7 +530,7 @@ bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bo
 		Type *t = base_type(type_deref(e->type));
 		Type *t = base_type(type_deref(e->type));
 		if (is_type_struct(t) || is_type_raw_union(t) || is_type_union(t)) {
 		if (is_type_struct(t) || is_type_raw_union(t) || is_type_union(t)) {
 			// TODO(bill): Make it work for unions too
 			// TODO(bill): Make it work for unions too
-			Scope **found_ = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
+			Scope **found_ = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 			GB_ASSERT(found_ != NULL);
 			GB_ASSERT(found_ != NULL);
 			Scope *found = *found_;
 			Scope *found = *found_;
 			for_array(i, found->elements.entries) {
 			for_array(i, found->elements.entries) {
@@ -1130,8 +1125,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 			}
 			}
 		}
 		}
 
 
-		MapTypeAndToken seen = {}; // NOTE(bill): Multimap
-		map_type_and_token_init(&seen, heap_allocator());
+		Map<TypeAndToken> seen = {}; // NOTE(bill): Multimap
+		map_init(&seen, heap_allocator());
 
 
 		for_array(i, bs->stmts) {
 		for_array(i, bs->stmts) {
 			AstNode *stmt = bs->stmts[i];
 			AstNode *stmt = bs->stmts[i];
@@ -1222,13 +1217,13 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 
 
 					if (y.value.kind != ExactValue_Invalid) {
 					if (y.value.kind != ExactValue_Invalid) {
 						HashKey key = hash_exact_value(y.value);
 						HashKey key = hash_exact_value(y.value);
-						TypeAndToken *found = map_type_and_token_get(&seen, key);
+						TypeAndToken *found = map_get(&seen, key);
 						if (found != NULL) {
 						if (found != NULL) {
 							gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 							gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
-							isize count = map_type_and_token_multi_count(&seen, key);
+							isize count = multi_map_count(&seen, key);
 							TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
 							TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
 
 
-							map_type_and_token_multi_get_all(&seen, key, taps);
+							multi_map_get_all(&seen, key, taps);
 							bool continue_outer = false;
 							bool continue_outer = false;
 
 
 							for (isize i = 0; i < count; i++) {
 							for (isize i = 0; i < count; i++) {
@@ -1254,7 +1249,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 							}
 							}
 						}
 						}
 						TypeAndToken tap = {y.type, ast_node_token(y.expr)};
 						TypeAndToken tap = {y.type, ast_node_token(y.expr)};
-						map_type_and_token_multi_insert(&seen, key, tap);
+						multi_map_insert(&seen, key, tap);
 					}
 					}
 				}
 				}
 			}
 			}
@@ -1268,7 +1263,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 			check_close_scope(c);
 			check_close_scope(c);
 		}
 		}
 
 
-		map_type_and_token_destroy(&seen);
+		map_destroy(&seen);
 
 
 		check_close_scope(c);
 		check_close_scope(c);
 	case_end;
 	case_end;
@@ -1346,8 +1341,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 		}
 		}
 
 
 
 
-		MapBool seen = {}; // Multimap
-		map_bool_init(&seen, heap_allocator());
+		Map<bool> seen = {}; // Multimap
+		map_init(&seen, heap_allocator());
 
 
 		for_array(i, bs->stmts) {
 		for_array(i, bs->stmts) {
 			AstNode *stmt = bs->stmts[i];
 			AstNode *stmt = bs->stmts[i];
@@ -1391,7 +1386,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 					}
 					}
 
 
 					HashKey key = hash_pointer(y.type);
 					HashKey key = hash_pointer(y.type);
-					bool *found = map_bool_get(&seen, key);
+					bool *found = map_get(&seen, key);
 					if (found) {
 					if (found) {
 						TokenPos pos = cc->token.pos;
 						TokenPos pos = cc->token.pos;
 						gbString expr_str = expr_to_string(y.expr);
 						gbString expr_str = expr_to_string(y.expr);
@@ -1403,7 +1398,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 						gb_string_free(expr_str);
 						gb_string_free(expr_str);
 						break;
 						break;
 					}
 					}
-					map_bool_set(&seen, key, cast(bool)true);
+					map_set(&seen, key, cast(bool)true);
 				}
 				}
 			}
 			}
 
 
@@ -1434,7 +1429,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 			check_stmt_list(c, cc->stmts, mod_flags);
 			check_stmt_list(c, cc->stmts, mod_flags);
 			check_close_scope(c);
 			check_close_scope(c);
 		}
 		}
-		map_bool_destroy(&seen);
+		map_destroy(&seen);
 
 
 		check_close_scope(c);
 		check_close_scope(c);
 	case_end;
 	case_end;
@@ -1635,7 +1630,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 					Type *t = base_type(type_deref(e->type));
 					Type *t = base_type(type_deref(e->type));
 
 
 					if (is_type_struct(t) || is_type_raw_union(t)) {
 					if (is_type_struct(t) || is_type_raw_union(t)) {
-						Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
+						Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 						GB_ASSERT(found != NULL);
 						GB_ASSERT(found != NULL);
 						for_array(i, (*found)->elements.entries) {
 						for_array(i, (*found)->elements.entries) {
 							Entity *f = (*found)->elements.entries[i].value;
 							Entity *f = (*found)->elements.entries[i].value;

+ 84 - 114
src/checker.cpp

@@ -195,7 +195,7 @@ struct DeclInfo {
 	AstNode *         init_expr;
 	AstNode *         init_expr;
 	AstNode *         proc_lit; // AstNode_ProcLit
 	AstNode *         proc_lit; // AstNode_ProcLit
 
 
-	MapBool           deps; // Key: Entity *
+	Map<bool>         deps; // Key: Entity *
 	Array<BlockLabel> labels;
 	Array<BlockLabel> labels;
 };
 };
 
 
@@ -226,18 +226,13 @@ ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue
 
 
 
 
 
 
-#define MAP_TYPE Entity *
-#define MAP_PROC map_entity_
-#define MAP_NAME MapEntity
-#include "map.cpp"
-
 struct Scope {
 struct Scope {
 	Scope *          parent;
 	Scope *          parent;
 	Scope *          prev, *next;
 	Scope *          prev, *next;
 	Scope *          first_child;
 	Scope *          first_child;
 	Scope *          last_child;
 	Scope *          last_child;
-	MapEntity        elements; // Key: String
-	MapBool          implicit; // Key: Entity *
+	Map<Entity *>    elements; // Key: String
+	Map<bool>        implicit; // Key: Entity *
 
 
 	Array<Scope *>   shared;
 	Array<Scope *>   shared;
 	Array<Scope *>   imported;
 	Array<Scope *>   imported;
@@ -254,31 +249,6 @@ gb_global Scope *universal_scope = NULL;
 
 
 
 
 
 
-#define MAP_TYPE TypeAndValue
-#define MAP_PROC map_tav_
-#define MAP_NAME MapTypeAndValue
-#include "map.cpp"
-
-#define MAP_TYPE Scope *
-#define MAP_PROC map_scope_
-#define MAP_NAME MapScope
-#include "map.cpp"
-
-#define MAP_TYPE DeclInfo *
-#define MAP_PROC map_decl_info_
-#define MAP_NAME MapDeclInfo
-#include "map.cpp"
-
-#define MAP_TYPE AstFile *
-#define MAP_PROC map_ast_file_
-#define MAP_NAME MapAstFile
-#include "map.cpp"
-
-#define MAP_TYPE ExprInfo
-#define MAP_PROC map_expr_info_
-#define MAP_NAME MapExprInfo
-#include "map.cpp"
-
 struct DelayedDecl {
 struct DelayedDecl {
 	Scope *  parent;
 	Scope *  parent;
 	AstNode *decl;
 	AstNode *decl;
@@ -304,16 +274,16 @@ struct CheckerContext {
 
 
 // CheckerInfo stores all the symbol information for a type-checked program
 // CheckerInfo stores all the symbol information for a type-checked program
 struct CheckerInfo {
 struct CheckerInfo {
-	MapTypeAndValue      types;           // Key: AstNode * | Expression -> Type (and value)
-	MapEntity            definitions;     // Key: AstNode * | Identifier -> Entity
-	MapEntity            uses;            // Key: AstNode * | Identifier -> Entity
-	MapScope             scopes;          // Key: AstNode * | Node       -> Scope
-	MapExprInfo          untyped;         // Key: AstNode * | Expression -> ExprInfo
-	MapEntity            implicits;       // Key: AstNode *
-	MapDeclInfo          entities;        // Key: Entity *
-	MapEntity            foreigns;        // Key: String
-	MapAstFile           files;           // Key: String (full path)
-	MapIsize             type_info_map;   // Key: Type *
+	Map<TypeAndValue>    types;           // Key: AstNode * | Expression -> Type (and value)
+	Map<Entity *>        definitions;     // Key: AstNode * | Identifier -> Entity
+	Map<Entity *>        uses;            // Key: AstNode * | Identifier -> Entity
+	Map<Scope *>         scopes;          // Key: AstNode * | Node       -> Scope
+	Map<ExprInfo>        untyped;         // Key: AstNode * | Expression -> ExprInfo
+	Map<Entity *>        implicits;       // Key: AstNode *
+	Map<DeclInfo *>      entities;        // Key: Entity *
+	Map<Entity *>        foreigns;        // Key: String
+	Map<AstFile *>       files;           // Key: String (full path)
+	Map<isize>           type_info_map;   // Key: Type *
 	isize                type_info_count;
 	isize                type_info_count;
 };
 };
 
 
@@ -352,7 +322,7 @@ struct DelayedEntity {
 void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
 void init_declaration_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
 	d->parent = parent;
 	d->parent = parent;
 	d->scope  = scope;
 	d->scope  = scope;
-	map_bool_init(&d->deps, heap_allocator());
+	map_init(&d->deps, heap_allocator());
 	array_init(&d->labels,  heap_allocator());
 	array_init(&d->labels,  heap_allocator());
 }
 }
 
 
@@ -363,7 +333,7 @@ DeclInfo *make_declaration_info(gbAllocator a, Scope *scope, DeclInfo *parent) {
 }
 }
 
 
 void destroy_declaration_info(DeclInfo *d) {
 void destroy_declaration_info(DeclInfo *d) {
-	map_bool_destroy(&d->deps);
+	map_destroy(&d->deps);
 }
 }
 
 
 bool decl_info_has_init(DeclInfo *d) {
 bool decl_info_has_init(DeclInfo *d) {
@@ -390,8 +360,8 @@ bool decl_info_has_init(DeclInfo *d) {
 Scope *make_scope(Scope *parent, gbAllocator allocator) {
 Scope *make_scope(Scope *parent, gbAllocator allocator) {
 	Scope *s = gb_alloc_item(allocator, Scope);
 	Scope *s = gb_alloc_item(allocator, Scope);
 	s->parent = parent;
 	s->parent = parent;
-	map_entity_init(&s->elements,   heap_allocator());
-	map_bool_init(&s->implicit,     heap_allocator());
+	map_init(&s->elements,   heap_allocator());
+	map_init(&s->implicit,     heap_allocator());
 	array_init(&s->shared,          heap_allocator());
 	array_init(&s->shared,          heap_allocator());
 	array_init(&s->imported,        heap_allocator());
 	array_init(&s->imported,        heap_allocator());
 
 
@@ -417,8 +387,8 @@ void destroy_scope(Scope *scope) {
 		destroy_scope(child);
 		destroy_scope(child);
 	}
 	}
 
 
-	map_entity_destroy(&scope->elements);
-	map_bool_destroy(&scope->implicit);
+	map_destroy(&scope->elements);
+	map_destroy(&scope->implicit);
 	array_free(&scope->shared);
 	array_free(&scope->shared);
 	array_free(&scope->imported);
 	array_free(&scope->imported);
 
 
@@ -428,7 +398,7 @@ void destroy_scope(Scope *scope) {
 void add_scope(Checker *c, AstNode *node, Scope *scope) {
 void add_scope(Checker *c, AstNode *node, Scope *scope) {
 	GB_ASSERT(node != NULL);
 	GB_ASSERT(node != NULL);
 	GB_ASSERT(scope != NULL);
 	GB_ASSERT(scope != NULL);
-	map_scope_set(&c->info.scopes, hash_pointer(node), scope);
+	map_set(&c->info.scopes, hash_pointer(node), scope);
 }
 }
 
 
 
 
@@ -454,13 +424,13 @@ void check_close_scope(Checker *c) {
 
 
 Entity *current_scope_lookup_entity(Scope *s, String name) {
 Entity *current_scope_lookup_entity(Scope *s, String name) {
 	HashKey key = hash_string(name);
 	HashKey key = hash_string(name);
-	Entity **found = map_entity_get(&s->elements, key);
+	Entity **found = map_get(&s->elements, key);
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
 	}
 	}
 	for_array(i, s->shared) {
 	for_array(i, s->shared) {
 		Scope *shared = s->shared[i];
 		Scope *shared = s->shared[i];
-		Entity **found = map_entity_get(&shared->elements, key);
+		Entity **found = map_get(&shared->elements, key);
 		if (found) {
 		if (found) {
 			Entity *e = *found;
 			Entity *e = *found;
 			if (e->kind == Entity_Variable &&
 			if (e->kind == Entity_Variable &&
@@ -485,7 +455,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
 	bool gone_thru_file = false;
 	bool gone_thru_file = false;
 	HashKey key = hash_string(name);
 	HashKey key = hash_string(name);
 	for (Scope *s = scope; s != NULL; s = s->parent) {
 	for (Scope *s = scope; s != NULL; s = s->parent) {
-		Entity **found = map_entity_get(&s->elements, key);
+		Entity **found = map_get(&s->elements, key);
 		if (found) {
 		if (found) {
 			Entity *e = *found;
 			Entity *e = *found;
 			if (gone_thru_proc) {
 			if (gone_thru_proc) {
@@ -510,7 +480,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
 			// Check shared scopes - i.e. other files @ global scope
 			// Check shared scopes - i.e. other files @ global scope
 			for_array(i, s->shared) {
 			for_array(i, s->shared) {
 				Scope *shared = s->shared[i];
 				Scope *shared = s->shared[i];
-				Entity **found = map_entity_get(&shared->elements, key);
+				Entity **found = map_get(&shared->elements, key);
 				if (found) {
 				if (found) {
 					Entity *e = *found;
 					Entity *e = *found;
 					if (e->kind == Entity_Variable &&
 					if (e->kind == Entity_Variable &&
@@ -558,7 +528,7 @@ Entity *scope_lookup_entity(Scope *s, String name) {
 Entity *scope_insert_entity(Scope *s, Entity *entity) {
 Entity *scope_insert_entity(Scope *s, Entity *entity) {
 	String name = entity->token.string;
 	String name = entity->token.string;
 	HashKey key = hash_string(name);
 	HashKey key = hash_string(name);
-	Entity **found = map_entity_get(&s->elements, key);
+	Entity **found = map_get(&s->elements, key);
 
 
 #if 1
 #if 1
 	// IMPORTANT NOTE(bill): Procedure overloading code
 	// IMPORTANT NOTE(bill): Procedure overloading code
@@ -576,15 +546,15 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
 		if (s->is_global) {
 		if (s->is_global) {
 			return prev;
 			return prev;
 		}
 		}
-		map_entity_multi_insert(&s->elements, key, entity);
+		multi_map_insert(&s->elements, key, entity);
 	} else {
 	} else {
-		map_entity_set(&s->elements, key, entity);
+		map_set(&s->elements, key, entity);
 	}
 	}
 #else
 #else
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
 	}
 	}
-	map_entity_set(&s->elements, key, entity);
+	map_set(&s->elements, key, entity);
 #endif
 #endif
 	if (entity->scope == NULL) {
 	if (entity->scope == NULL) {
 		entity->scope = s;
 		entity->scope = s;
@@ -599,7 +569,7 @@ void check_scope_usage(Checker *c, Scope *scope) {
 
 
 
 
 void add_dependency(DeclInfo *d, Entity *e) {
 void add_dependency(DeclInfo *d, Entity *e) {
-	map_bool_set(&d->deps, hash_pointer(e), cast(bool)true);
+	map_set(&d->deps, hash_pointer(e), cast(bool)true);
 }
 }
 
 
 void add_declaration_dependency(Checker *c, Entity *e) {
 void add_declaration_dependency(Checker *c, Entity *e) {
@@ -607,7 +577,7 @@ void add_declaration_dependency(Checker *c, Entity *e) {
 		return;
 		return;
 	}
 	}
 	if (c->context.decl != NULL) {
 	if (c->context.decl != NULL) {
-		DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
+		DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
 		if (found) {
 		if (found) {
 			add_dependency(c->context.decl, e);
 			add_dependency(c->context.decl, e);
 		}
 		}
@@ -705,31 +675,31 @@ void init_universal_scope(void) {
 
 
 void init_checker_info(CheckerInfo *i) {
 void init_checker_info(CheckerInfo *i) {
 	gbAllocator a = heap_allocator();
 	gbAllocator a = heap_allocator();
-	map_tav_init(&i->types,            a);
-	map_entity_init(&i->definitions,   a);
-	map_entity_init(&i->uses,          a);
-	map_scope_init(&i->scopes,         a);
-	map_decl_info_init(&i->entities,   a);
-	map_expr_info_init(&i->untyped,    a);
-	map_entity_init(&i->foreigns,      a);
-	map_entity_init(&i->implicits,     a);
-	map_isize_init(&i->type_info_map,  a);
-	map_ast_file_init(&i->files,       a);
+	map_init(&i->types,            a);
+	map_init(&i->definitions,   a);
+	map_init(&i->uses,          a);
+	map_init(&i->scopes,         a);
+	map_init(&i->entities,   a);
+	map_init(&i->untyped,    a);
+	map_init(&i->foreigns,      a);
+	map_init(&i->implicits,     a);
+	map_init(&i->type_info_map,  a);
+	map_init(&i->files,       a);
 	i->type_info_count = 0;
 	i->type_info_count = 0;
 
 
 }
 }
 
 
 void destroy_checker_info(CheckerInfo *i) {
 void destroy_checker_info(CheckerInfo *i) {
-	map_tav_destroy(&i->types);
-	map_entity_destroy(&i->definitions);
-	map_entity_destroy(&i->uses);
-	map_scope_destroy(&i->scopes);
-	map_decl_info_destroy(&i->entities);
-	map_expr_info_destroy(&i->untyped);
-	map_entity_destroy(&i->foreigns);
-	map_entity_destroy(&i->implicits);
-	map_isize_destroy(&i->type_info_map);
-	map_ast_file_destroy(&i->files);
+	map_destroy(&i->types);
+	map_destroy(&i->definitions);
+	map_destroy(&i->uses);
+	map_destroy(&i->scopes);
+	map_destroy(&i->entities);
+	map_destroy(&i->untyped);
+	map_destroy(&i->foreigns);
+	map_destroy(&i->implicits);
+	map_destroy(&i->type_info_map);
+	map_destroy(&i->files);
 }
 }
 
 
 
 
@@ -793,11 +763,11 @@ void destroy_checker(Checker *c) {
 
 
 Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
 Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
 	if (identifier->kind == AstNode_Ident) {
 	if (identifier->kind == AstNode_Ident) {
-		Entity **found = map_entity_get(&i->definitions, hash_pointer(identifier));
+		Entity **found = map_get(&i->definitions, hash_pointer(identifier));
 		if (found) {
 		if (found) {
 			return *found;
 			return *found;
 		}
 		}
-		found = map_entity_get(&i->uses, hash_pointer(identifier));
+		found = map_get(&i->uses, hash_pointer(identifier));
 		if (found) {
 		if (found) {
 			return *found;
 			return *found;
 		}
 		}
@@ -808,7 +778,7 @@ Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
 
 
 TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expression) {
 TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expression) {
 	TypeAndValue result = {};
 	TypeAndValue result = {};
-	TypeAndValue *found = map_tav_get(&i->types, hash_pointer(expression));
+	TypeAndValue *found = map_get(&i->types, hash_pointer(expression));
 	if (found) result = *found;
 	if (found) result = *found;
 	return result;
 	return result;
 }
 }
@@ -831,7 +801,7 @@ Type *type_of_expr(CheckerInfo *i, AstNode *expr) {
 
 
 
 
 void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
 void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
-	map_expr_info_set(&i->untyped, hash_pointer(expression), make_expr_info(lhs, mode, basic_type, value));
+	map_set(&i->untyped, hash_pointer(expression), make_expr_info(lhs, mode, basic_type, value));
 }
 }
 
 
 void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
 void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
@@ -858,7 +828,7 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
 	tv.type  = type;
 	tv.type  = type;
 	tv.value = value;
 	tv.value = value;
 	tv.mode  = mode;
 	tv.mode  = mode;
-	map_tav_set(&i->types, hash_pointer(expression), tv);
+	map_set(&i->types, hash_pointer(expression), tv);
 }
 }
 
 
 void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) {
 void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) {
@@ -868,7 +838,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
 			return;
 			return;
 		}
 		}
 		HashKey key = hash_pointer(identifier);
 		HashKey key = hash_pointer(identifier);
-		map_entity_set(&i->definitions, key, entity);
+		map_set(&i->definitions, key, entity);
 	} else {
 	} else {
 		// NOTE(bill): Error should handled elsewhere
 		// NOTE(bill): Error should handled elsewhere
 	}
 	}
@@ -918,7 +888,7 @@ void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) {
 		return;
 		return;
 	}
 	}
 	HashKey key = hash_pointer(identifier);
 	HashKey key = hash_pointer(identifier);
-	map_entity_set(&c->info.uses, key, entity);
+	map_set(&c->info.uses, key, entity);
 	add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
 	add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
 }
 }
 
 
@@ -928,14 +898,14 @@ void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclIn
 	GB_ASSERT(e != NULL && d != NULL);
 	GB_ASSERT(e != NULL && d != NULL);
 	GB_ASSERT(identifier->Ident.string == e->token.string);
 	GB_ASSERT(identifier->Ident.string == e->token.string);
 	add_entity(c, e->scope, identifier, e);
 	add_entity(c, e->scope, identifier, e);
-	map_decl_info_set(&c->info.entities, hash_pointer(e), d);
+	map_set(&c->info.entities, hash_pointer(e), d);
 }
 }
 
 
 
 
 void add_implicit_entity(Checker *c, AstNode *node, Entity *e) {
 void add_implicit_entity(Checker *c, AstNode *node, Entity *e) {
 	GB_ASSERT(node != NULL);
 	GB_ASSERT(node != NULL);
 	GB_ASSERT(e != NULL);
 	GB_ASSERT(e != NULL);
-	map_entity_set(&c->info.implicits, hash_pointer(node), e);
+	map_set(&c->info.implicits, hash_pointer(node), e);
 }
 }
 
 
 
 
@@ -951,14 +921,14 @@ void add_type_info_type(Checker *c, Type *t) {
 		return; // Could be nil
 		return; // Could be nil
 	}
 	}
 
 
-	if (map_isize_get(&c->info.type_info_map, hash_pointer(t)) != NULL) {
+	if (map_get(&c->info.type_info_map, hash_pointer(t)) != NULL) {
 		// Types have already been added
 		// Types have already been added
 		return;
 		return;
 	}
 	}
 
 
 	isize ti_index = -1;
 	isize ti_index = -1;
 	for_array(i, c->info.type_info_map.entries) {
 	for_array(i, c->info.type_info_map.entries) {
-		MapIsizeEntry *e = &c->info.type_info_map.entries[i];
+		auto *e = &c->info.type_info_map.entries[i];
 		Type *prev_type = cast(Type *)e->key.ptr;
 		Type *prev_type = cast(Type *)e->key.ptr;
 		if (are_types_identical(t, prev_type)) {
 		if (are_types_identical(t, prev_type)) {
 			// Duplicate entry
 			// Duplicate entry
@@ -972,7 +942,7 @@ void add_type_info_type(Checker *c, Type *t) {
 		ti_index = c->info.type_info_count;
 		ti_index = c->info.type_info_count;
 		c->info.type_info_count++;
 		c->info.type_info_count++;
 	}
 	}
-	map_isize_set(&c->info.type_info_map, hash_pointer(t), ti_index);
+	map_set(&c->info.type_info_map, hash_pointer(t), ti_index);
 
 
 
 
 
 
@@ -1123,17 +1093,17 @@ void add_curr_ast_file(Checker *c, AstFile *file) {
 
 
 
 
 
 
-void add_dependency_to_map(MapEntity *map, CheckerInfo *info, Entity *node) {
+void add_dependency_to_map(Map<Entity *> *map, CheckerInfo *info, Entity *node) {
 	if (node == NULL) {
 	if (node == NULL) {
 		return;
 		return;
 	}
 	}
-	if (map_entity_get(map, hash_pointer(node)) != NULL) {
+	if (map_get(map, hash_pointer(node)) != NULL) {
 		return;
 		return;
 	}
 	}
-	map_entity_set(map, hash_pointer(node), node);
+	map_set(map, hash_pointer(node), node);
 
 
 
 
-	DeclInfo **found = map_decl_info_get(&info->entities, hash_pointer(node));
+	DeclInfo **found = map_get(&info->entities, hash_pointer(node));
 	if (found == NULL) {
 	if (found == NULL) {
 		return;
 		return;
 	}
 	}
@@ -1145,9 +1115,9 @@ void add_dependency_to_map(MapEntity *map, CheckerInfo *info, Entity *node) {
 	}
 	}
 }
 }
 
 
-MapEntity generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
-	MapEntity map = {}; // Key: Entity *
-	map_entity_init(&map, heap_allocator());
+Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
+	Map<Entity *> map = {}; // Key: Entity *
+	map_init(&map, heap_allocator());
 
 
 	for_array(i, info->definitions.entries) {
 	for_array(i, info->definitions.entries) {
 		Entity *e = info->definitions.entries[i].value;
 		Entity *e = info->definitions.entries[i].value;
@@ -1289,7 +1259,7 @@ bool check_is_entity_overloaded(Entity *e) {
 	}
 	}
 	Scope *s = e->scope;
 	Scope *s = e->scope;
 	HashKey key = hash_string(e->token.string);
 	HashKey key = hash_string(e->token.string);
-	isize overload_count = map_entity_multi_count(&s->elements, key);
+	isize overload_count = multi_map_count(&s->elements, key);
 	return overload_count > 1;
 	return overload_count > 1;
 }
 }
 
 
@@ -1309,7 +1279,7 @@ void check_procedure_overloading(Checker *c, Entity *e) {
 	String name = e->token.string;
 	String name = e->token.string;
 	HashKey key = hash_string(name);
 	HashKey key = hash_string(name);
 	Scope *s = e->scope;
 	Scope *s = e->scope;
-	isize overload_count = map_entity_multi_count(&s->elements, key);
+	isize overload_count = multi_map_count(&s->elements, key);
 	GB_ASSERT(overload_count >= 1);
 	GB_ASSERT(overload_count >= 1);
 	if (overload_count == 1) {
 	if (overload_count == 1) {
 		e->Procedure.overload_kind = Overload_No;
 		e->Procedure.overload_kind = Overload_No;
@@ -1320,7 +1290,7 @@ void check_procedure_overloading(Checker *c, Entity *e) {
 
 
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	Entity **procs = gb_alloc_array(c->tmp_allocator, Entity *, overload_count);
 	Entity **procs = gb_alloc_array(c->tmp_allocator, Entity *, overload_count);
-	map_entity_multi_get_all(&s->elements, key, procs);
+	multi_map_get_all(&s->elements, key, procs);
 
 
 	for (isize j = 0; j < overload_count; j++) {
 	for (isize j = 0; j < overload_count; j++) {
 		Entity *p = procs[j];
 		Entity *p = procs[j];
@@ -1660,7 +1630,7 @@ void check_all_global_entities(Checker *c) {
 	Scope *prev_file = {};
 	Scope *prev_file = {};
 
 
 	for_array(i, c->info.entities.entries) {
 	for_array(i, c->info.entities.entries) {
-		MapDeclInfoEntry *entry = &c->info.entities.entries[i];
+		auto *entry = &c->info.entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		DeclInfo *d = entry->value;
 		DeclInfo *d = entry->value;
 
 
@@ -1698,7 +1668,7 @@ void check_all_global_entities(Checker *c) {
 	}
 	}
 
 
 	for_array(i, c->info.entities.entries) {
 	for_array(i, c->info.entities.entries) {
-		MapDeclInfoEntry *entry = &c->info.entities.entries[i];
+		auto *entry = &c->info.entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		if (e->kind != Entity_Procedure) {
 		if (e->kind != Entity_Procedure) {
 			continue;
 			continue;
@@ -1769,7 +1739,7 @@ String path_to_entity_name(String name, String fullpath) {
 	}
 	}
 }
 }
 
 
-void check_import_entities(Checker *c, MapScope *file_scopes) {
+void check_import_entities(Checker *c, Map<Scope *> *file_scopes) {
 #if 0
 #if 0
 	// TODO(bill): Dependency ordering for imports
 	// TODO(bill): Dependency ordering for imports
 	{
 	{
@@ -1810,7 +1780,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
 		}
 		}
 
 
 		HashKey key = hash_string(id->fullpath);
 		HashKey key = hash_string(id->fullpath);
-		Scope **found = map_scope_get(file_scopes, key);
+		Scope **found = map_get(file_scopes, key);
 		if (found == NULL) {
 		if (found == NULL) {
 			for_array(scope_index, file_scopes->entries) {
 			for_array(scope_index, file_scopes->entries) {
 				Scope *scope = file_scopes->entries[scope_index].value;
 				Scope *scope = file_scopes->entries[scope_index].value;
@@ -1883,7 +1853,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
 		}
 		}
 
 
 		HashKey key = hash_string(id->fullpath);
 		HashKey key = hash_string(id->fullpath);
-		Scope **found = map_scope_get(file_scopes, key);
+		Scope **found = map_get(file_scopes, key);
 		if (found == NULL) {
 		if (found == NULL) {
 			for_array(scope_index, file_scopes->entries) {
 			for_array(scope_index, file_scopes->entries) {
 				Scope *scope = file_scopes->entries[scope_index].value;
 				Scope *scope = file_scopes->entries[scope_index].value;
@@ -1946,7 +1916,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
 						// TODO(bill): Should these entities be imported but cause an error when used?
 						// TODO(bill): Should these entities be imported but cause an error when used?
 						bool ok = add_entity(c, parent_scope, e->identifier, e);
 						bool ok = add_entity(c, parent_scope, e->identifier, e);
 						if (ok) {
 						if (ok) {
-							map_bool_set(&parent_scope->implicit, hash_pointer(e), true);
+							map_set(&parent_scope->implicit, hash_pointer(e), true);
 						}
 						}
 					}
 					}
 				} else {
 				} else {
@@ -2021,8 +1991,8 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
 
 
 
 
 void check_parsed_files(Checker *c) {
 void check_parsed_files(Checker *c) {
-	MapScope file_scopes; // Key: String (fullpath)
-	map_scope_init(&file_scopes, heap_allocator());
+	Map<Scope *> file_scopes; // Key: String (fullpath)
+	map_init(&file_scopes, heap_allocator());
 
 
 	// Map full filepaths to Scopes
 	// Map full filepaths to Scopes
 	for_array(i, c->parser->files) {
 	for_array(i, c->parser->files) {
@@ -2047,8 +2017,8 @@ void check_parsed_files(Checker *c) {
 		f->scope = scope;
 		f->scope = scope;
 		f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
 		f->decl_info = make_declaration_info(c->allocator, f->scope, c->context.decl);
 		HashKey key = hash_string(f->tokenizer.fullpath);
 		HashKey key = hash_string(f->tokenizer.fullpath);
-		map_scope_set(&file_scopes, key, scope);
-		map_ast_file_set(&c->info.files, key, f);
+		map_set(&file_scopes, key, scope);
+		map_set(&c->info.files, key, f);
 	}
 	}
 
 
 	// Collect Entities
 	// Collect Entities
@@ -2091,7 +2061,7 @@ void check_parsed_files(Checker *c) {
 
 
 	// Add untyped expression values
 	// Add untyped expression values
 	for_array(i, c->info.untyped.entries) {
 	for_array(i, c->info.untyped.entries) {
-		MapExprInfoEntry *entry = &c->info.untyped.entries[i];
+		auto *entry = &c->info.untyped.entries[i];
 		HashKey key = entry->key;
 		HashKey key = entry->key;
 		AstNode *expr = cast(AstNode *)cast(uintptr)key.key;
 		AstNode *expr = cast(AstNode *)cast(uintptr)key.key;
 		ExprInfo *info = &entry->value;
 		ExprInfo *info = &entry->value;
@@ -2166,6 +2136,6 @@ void check_parsed_files(Checker *c) {
 		}
 		}
 	}
 	}
 
 
-	map_scope_destroy(&file_scopes);
+	map_destroy(&file_scopes);
 
 
 }
 }

+ 1 - 19
src/common.cpp

@@ -18,6 +18,7 @@ gbAllocator heap_allocator(void) {
 #include "array.cpp"
 #include "array.cpp"
 #include "integer128.cpp"
 #include "integer128.cpp"
 #include "murmurhash3.cpp"
 #include "murmurhash3.cpp"
+#include "map.cpp"
 
 
 u128 fnv128a(void const *data, isize len) {
 u128 fnv128a(void const *data, isize len) {
 	u128 o = u128_lo_hi(0x13bull, 0x1000000ull);
 	u128 o = u128_lo_hi(0x13bull, 0x1000000ull);
@@ -234,23 +235,4 @@ f64 gb_sqrt(f64 x) {
 	} \
 	} \
 } while (0)
 } while (0)
 
 
-////////////////////////////////////////////////////////////////
-//
-// Generic Data Structures
-//
-////////////////////////////////////////////////////////////////
-
-#define MAP_TYPE String
-#define MAP_PROC map_string_
-#define MAP_NAME MapString
-#include "map.cpp"
-
-#define MAP_TYPE bool
-#define MAP_PROC map_bool_
-#define MAP_NAME MapBool
-#include "map.cpp"
 
 
-#define MAP_TYPE isize
-#define MAP_PROC map_isize_
-#define MAP_NAME MapIsize
-#include "map.cpp"

+ 1 - 0
src/exact_value.cpp

@@ -4,6 +4,7 @@
 // IMPORTANT TODO(bill): This needs to be completely fixed!!!!!!!!
 // IMPORTANT TODO(bill): This needs to be completely fixed!!!!!!!!
 
 
 struct AstNode;
 struct AstNode;
+struct HashKey;
 
 
 struct Complex128 {
 struct Complex128 {
 	f64 real, imag;
 	f64 real, imag;

+ 79 - 88
src/ir.cpp

@@ -3,15 +3,6 @@ struct irBlock;
 struct irValue;
 struct irValue;
 struct irDebugInfo;
 struct irDebugInfo;
 
 
-#define MAP_TYPE irValue *
-#define MAP_PROC map_ir_value_
-#define MAP_NAME MapIrValue
-#include "map.cpp"
-
-#define MAP_TYPE irDebugInfo *
-#define MAP_PROC map_ir_debug_info_
-#define MAP_NAME MapIrDebugInfo
-#include "map.cpp"
 
 
 
 
 struct irModule {
 struct irModule {
@@ -28,11 +19,11 @@ struct irModule {
 	String layout;
 	String layout;
 	// String triple;
 	// String triple;
 
 
-	MapEntity             min_dep_map; // Key: Entity *
-	MapIrValue            values;      // Key: Entity *
-	MapIrValue            members;     // Key: String
-	MapString             entity_names;  // Key: Entity * of the typename
-	MapIrDebugInfo        debug_info;  // Key: Unique pointer
+	Map<Entity *>         min_dep_map; // Key: Entity *
+	Map<irValue *>        values;      // Key: Entity *
+	Map<irValue *>        members;     // Key: String
+	Map<String>           entity_names;  // Key: Entity * of the typename
+	Map<irDebugInfo *>    debug_info;  // Key: Unique pointer
 	i32                   global_string_index;
 	i32                   global_string_index;
 	i32                   global_array_index; // For ConstantSlice
 	i32                   global_array_index; // For ConstantSlice
 	i32                   global_generated_index;
 	i32                   global_generated_index;
@@ -811,7 +802,7 @@ String ir_get_global_name(irModule *m, irValue *v) {
 	irValueGlobal *g = &v->Global;
 	irValueGlobal *g = &v->Global;
 	Entity *e = g->entity;
 	Entity *e = g->entity;
 	String name = e->token.string;
 	String name = e->token.string;
-	String *found = map_string_get(&m->entity_names, hash_pointer(e));
+	String *found = map_get(&m->entity_names, hash_pointer(e));
 	if (found != NULL) {
 	if (found != NULL) {
 		name = *found;
 		name = *found;
 	}
 	}
@@ -1136,14 +1127,14 @@ irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefi
 	irValue *value = ir_value_global(a, e, NULL);
 	irValue *value = ir_value_global(a, e, NULL);
 	value->Global.is_private = true;
 	value->Global.is_private = true;
 	ir_module_add_value(m, e, value);
 	ir_module_add_value(m, e, value);
-	map_ir_value_set(&m->members, hash_string(token.string), value);
+	map_set(&m->members, hash_string(token.string), value);
 	return value;
 	return value;
 }
 }
 
 
 irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
 irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
 	Scope *scope = NULL;
 	Scope *scope = NULL;
 	if (node != NULL) {
 	if (node != NULL) {
-		Scope **found = map_scope_get(&proc->module->info->scopes, hash_pointer(node));
+		Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node));
 		if (found) {
 		if (found) {
 			scope = *found;
 			scope = *found;
 		} else {
 		} else {
@@ -1239,7 +1230,7 @@ irValue *ir_add_module_constant(irModule *m, Type *type, ExactValue value) {
 		Entity *e = make_entity_constant(a, NULL, make_token_ident(name), t, value);
 		Entity *e = make_entity_constant(a, NULL, make_token_ident(name), t, value);
 		irValue *g = ir_value_global(a, e, backing_array);
 		irValue *g = ir_value_global(a, e, backing_array);
 		ir_module_add_value(m, e, g);
 		ir_module_add_value(m, e, g);
-		map_ir_value_set(&m->members, hash_string(name), g);
+		map_set(&m->members, hash_string(name), g);
 
 
 		return ir_value_constant_slice(a, type, g, count);
 		return ir_value_constant_slice(a, type, g, count);
 	}
 	}
@@ -1270,7 +1261,7 @@ irValue *ir_add_global_string_array(irModule *m, String string) {
 	// g->Global.is_constant = true;
 	// g->Global.is_constant = true;
 
 
 	ir_module_add_value(m, entity, g);
 	ir_module_add_value(m, entity, g);
-	map_ir_value_set(&m->members, hash_string(name), g);
+	map_set(&m->members, hash_string(name), g);
 
 
 	return g;
 	return g;
 }
 }
@@ -1291,7 +1282,7 @@ irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr) {
 	// }
 	// }
 
 
 	if (expr != NULL && proc->entity != NULL) {
 	if (expr != NULL && proc->entity != NULL) {
-		irDebugInfo *di = *map_ir_debug_info_get(&proc->module->debug_info, hash_pointer(proc->entity));
+		irDebugInfo *di = *map_get(&proc->module->debug_info, hash_pointer(proc->entity));
 		ir_emit(proc, ir_instr_debug_declare(proc, di, expr, e, true, instr));
 		ir_emit(proc, ir_instr_debug_declare(proc, di, expr, e, true, instr));
 	}
 	}
 
 
@@ -1299,7 +1290,7 @@ irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr) {
 }
 }
 
 
 irValue *ir_add_local_for_identifier(irProcedure *proc, AstNode *name, bool zero_initialized) {
 irValue *ir_add_local_for_identifier(irProcedure *proc, AstNode *name, bool zero_initialized) {
-	Entity **found = map_entity_get(&proc->module->info->definitions, hash_pointer(name));
+	Entity **found = map_get(&proc->module->info->definitions, hash_pointer(name));
 	if (found) {
 	if (found) {
 		Entity *e = *found;
 		Entity *e = *found;
 		ir_emit_comment(proc, e->token.string);
 		ir_emit_comment(proc, e->token.string);
@@ -1341,7 +1332,7 @@ irValue *ir_add_global_generated(irModule *m, Type *type, irValue *value) {
 
 
 	irValue *g = ir_value_global(a, e, value);
 	irValue *g = ir_value_global(a, e, value);
 	ir_module_add_value(m, e, g);
 	ir_module_add_value(m, e, g);
-	map_ir_value_set(&m->members, hash_string(name), g);
+	map_set(&m->members, hash_string(name), g);
 	return g;
 	return g;
 }
 }
 
 
@@ -1407,7 +1398,7 @@ irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) {
 	di->File.filename = filename;
 	di->File.filename = filename;
 	di->File.directory = directory;
 	di->File.directory = directory;
 
 
-	map_ir_debug_info_set(&proc->module->debug_info, hash_pointer(file), di);
+	map_set(&proc->module->debug_info, hash_pointer(file), di);
 	return di;
 	return di;
 }
 }
 
 
@@ -1424,7 +1415,7 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
 	di->Proc.file = file;
 	di->Proc.file = file;
 	di->Proc.pos = entity->token.pos;
 	di->Proc.pos = entity->token.pos;
 
 
-	map_ir_debug_info_set(&proc->module->debug_info, hash_pointer(entity), di);
+	map_set(&proc->module->debug_info, hash_pointer(entity), di);
 	return di;
 	return di;
 }
 }
 
 
@@ -1517,7 +1508,7 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_
 
 
 irValue *ir_emit_global_call(irProcedure *proc, char *name_, irValue **args, isize arg_count) {
 irValue *ir_emit_global_call(irProcedure *proc, char *name_, irValue **args, isize arg_count) {
 	String name = make_string_c(name_);
 	String name = make_string_c(name_);
-	irValue **found = map_ir_value_get(&proc->module->members, hash_string(name));
+	irValue **found = map_get(&proc->module->members, hash_string(name));
 	GB_ASSERT_MSG(found != NULL, "%.*s", LIT(name));
 	GB_ASSERT_MSG(found != NULL, "%.*s", LIT(name));
 	irValue *gp = *found;
 	irValue *gp = *found;
 	return ir_emit_call(proc, gp, args, arg_count);
 	return ir_emit_call(proc, gp, args, arg_count);
@@ -3280,7 +3271,7 @@ isize ir_type_info_index(CheckerInfo *info, Type *type) {
 
 
 	isize entry_index = -1;
 	isize entry_index = -1;
 	HashKey key = hash_pointer(type);
 	HashKey key = hash_pointer(type);
-	isize *found_entry_index = map_isize_get(&info->type_info_map, key);
+	isize *found_entry_index = map_get(&info->type_info_map, key);
 	if (found_entry_index) {
 	if (found_entry_index) {
 		entry_index = *found_entry_index;
 		entry_index = *found_entry_index;
 	}
 	}
@@ -3288,12 +3279,12 @@ isize ir_type_info_index(CheckerInfo *info, Type *type) {
 		// NOTE(bill): Do manual search
 		// NOTE(bill): Do manual search
 		// TODO(bill): This is O(n) and can be very slow
 		// TODO(bill): This is O(n) and can be very slow
 		for_array(i, info->type_info_map.entries){
 		for_array(i, info->type_info_map.entries){
-			MapIsizeEntry *e = &info->type_info_map.entries[i];
+			auto *e = &info->type_info_map.entries[i];
 			Type *prev_type = cast(Type *)e->key.ptr;
 			Type *prev_type = cast(Type *)e->key.ptr;
 			if (are_types_identical(prev_type, type)) {
 			if (are_types_identical(prev_type, type)) {
 				entry_index = e->value;
 				entry_index = e->value;
 				// NOTE(bill): Add it to the search map
 				// NOTE(bill): Add it to the search map
-				map_isize_set(&info->type_info_map, key, entry_index);
+				map_set(&info->type_info_map, key, entry_index);
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -3434,7 +3425,7 @@ String ir_mangle_name(irGen *s, String path, Entity *e) {
 	irModule *m = &s->module;
 	irModule *m = &s->module;
 	CheckerInfo *info = m->info;
 	CheckerInfo *info = m->info;
 	gbAllocator a = m->allocator;
 	gbAllocator a = m->allocator;
-	AstFile *file = *map_ast_file_get(&info->files, hash_string(path));
+	AstFile *file = *map_get(&info->files, hash_string(path));
 
 
 	char *str = gb_alloc_array(a, char, path.len+1);
 	char *str = gb_alloc_array(a, char, path.len+1);
 	gb_memmove(str, path.text, path.len);
 	gb_memmove(str, path.text, path.len);
@@ -3496,14 +3487,14 @@ void ir_mangle_add_sub_type_name(irModule *m, Entity *field, String parent) {
 	                                 "%.*s.%.*s", LIT(parent), LIT(cn));
 	                                 "%.*s.%.*s", LIT(parent), LIT(cn));
 
 
 	String child = {text, new_name_len-1};
 	String child = {text, new_name_len-1};
-	map_string_set(&m->entity_names, hash_pointer(field), child);
+	map_set(&m->entity_names, hash_pointer(field), child);
 	ir_gen_global_type_name(m, field, child);
 	ir_gen_global_type_name(m, field, child);
 }
 }
 
 
 
 
 irBranchBlocks ir_lookup_branch_blocks(irProcedure *proc, AstNode *ident) {
 irBranchBlocks ir_lookup_branch_blocks(irProcedure *proc, AstNode *ident) {
 	GB_ASSERT(ident->kind == AstNode_Ident);
 	GB_ASSERT(ident->kind == AstNode_Ident);
-	Entity **found = map_entity_get(&proc->module->info->uses, hash_pointer(ident));
+	Entity **found = map_get(&proc->module->info->uses, hash_pointer(ident));
 	GB_ASSERT(found != NULL);
 	GB_ASSERT(found != NULL);
 	Entity *e = *found;
 	Entity *e = *found;
 	GB_ASSERT(e->kind == Entity_Label);
 	GB_ASSERT(e->kind == Entity_Label);
@@ -3553,7 +3544,7 @@ void ir_pop_target_list(irProcedure *proc) {
 void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
 void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
 	irValue *t = ir_value_type_name(m->allocator, name, e->type);
 	irValue *t = ir_value_type_name(m->allocator, name, e->type);
 	ir_module_add_value(m, e, t);
 	ir_module_add_value(m, e, t);
-	map_ir_value_set(&m->members, hash_string(name), t);
+	map_set(&m->members, hash_string(name), t);
 
 
 	if (is_type_union(e->type)) {
 	if (is_type_union(e->type)) {
 		Type *bt = base_type(e->type);
 		Type *bt = base_type(e->type);
@@ -3602,7 +3593,7 @@ irValue *ir_emit_clamp(irProcedure *proc, Type *t, irValue *x, irValue *min, irV
 
 
 
 
 irValue *ir_find_global_variable(irProcedure *proc, String name) {
 irValue *ir_find_global_variable(irProcedure *proc, String name) {
-	irValue **value = map_ir_value_get(&proc->module->members, hash_string(name));
+	irValue **value = map_get(&proc->module->members, hash_string(name));
 	GB_ASSERT_MSG(value != NULL, "Unable to find global variable `%.*s`", LIT(name));
 	GB_ASSERT_MSG(value != NULL, "Unable to find global variable `%.*s`", LIT(name));
 	return *value;
 	return *value;
 }
 }
@@ -3660,7 +3651,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 	case_end;
 	case_end;
 
 
 	case_ast_node(i, Ident, expr);
 	case_ast_node(i, Ident, expr);
-		Entity *e = *map_entity_get(&proc->module->info->uses, hash_pointer(expr));
+		Entity *e = *map_get(&proc->module->info->uses, hash_pointer(expr));
 		if (e->kind == Entity_Builtin) {
 		if (e->kind == Entity_Builtin) {
 			Token token = ast_node_token(expr);
 			Token token = ast_node_token(expr);
 			GB_PANIC("TODO(bill): ir_build_single_expr Entity_Builtin `%.*s`\n"
 			GB_PANIC("TODO(bill): ir_build_single_expr Entity_Builtin `%.*s`\n"
@@ -3671,7 +3662,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 			return ir_value_nil(proc->module->allocator, tv.type);
 			return ir_value_nil(proc->module->allocator, tv.type);
 		}
 		}
 
 
-		irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
+		irValue **found = map_get(&proc->module->values, hash_pointer(e));
 		if (found) {
 		if (found) {
 			irValue *v = *found;
 			irValue *v = *found;
 			if (v->kind == irValue_Proc) {
 			if (v->kind == irValue_Proc) {
@@ -3873,7 +3864,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 
 
 
 
 	case_ast_node(ce, CallExpr, expr);
 	case_ast_node(ce, CallExpr, expr);
-		if (map_tav_get(&proc->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
+		if (map_get(&proc->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
 			GB_ASSERT(ce->args.count == 1);
 			GB_ASSERT(ce->args.count == 1);
 			irValue *x = ir_build_expr(proc, ce->args[0]);
 			irValue *x = ir_build_expr(proc, ce->args[0]);
 			irValue *y = ir_emit_conv(proc, x, tv.type);
 			irValue *y = ir_emit_conv(proc, x, tv.type);
@@ -3882,7 +3873,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 
 
 		AstNode *p = unparen_expr(ce->proc);
 		AstNode *p = unparen_expr(ce->proc);
 		if (p->kind == AstNode_Ident) {
 		if (p->kind == AstNode_Ident) {
-			Entity **found = map_entity_get(&proc->module->info->uses, hash_pointer(p));
+			Entity **found = map_get(&proc->module->info->uses, hash_pointer(p));
 			if (found && (*found)->kind == Entity_Builtin) {
 			if (found && (*found)->kind == Entity_Builtin) {
 				Entity *e = *found;
 				Entity *e = *found;
 				switch (e->Builtin.id) {
 				switch (e->Builtin.id) {
@@ -4704,7 +4695,7 @@ irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
 	Entity *parent = e->using_parent;
 	Entity *parent = e->using_parent;
 	Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
 	Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
 	GB_ASSERT(sel.entity != NULL);
 	GB_ASSERT(sel.entity != NULL);
-	irValue **pv = map_ir_value_get(&proc->module->values, hash_pointer(parent));
+	irValue **pv = map_get(&proc->module->values, hash_pointer(parent));
 	irValue *v = NULL;
 	irValue *v = NULL;
 	if (pv != NULL) {
 	if (pv != NULL) {
 		v = *pv;
 		v = *pv;
@@ -4719,7 +4710,7 @@ irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
 
 
 // irValue *ir_add_using_variable(irProcedure *proc, Entity *e) {
 // irValue *ir_add_using_variable(irProcedure *proc, Entity *e) {
 // 	irValue *var = ir_get_using_variable(proc, e);
 // 	irValue *var = ir_get_using_variable(proc, e);
-// 	map_ir_value_set(&proc->module->values, hash_pointer(e), var);
+// 	map_set(&proc->module->values, hash_pointer(e), var);
 // 	return var;
 // 	return var;
 // }
 // }
 
 
@@ -4741,7 +4732,7 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) {
 	GB_ASSERT(e->kind != Entity_Constant);
 	GB_ASSERT(e->kind != Entity_Constant);
 
 
 	irValue *v = NULL;
 	irValue *v = NULL;
-	irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
+	irValue **found = map_get(&proc->module->values, hash_pointer(e));
 	if (found) {
 	if (found) {
 		v = *found;
 		v = *found;
 	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
 	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
@@ -5720,7 +5711,7 @@ void ir_build_range_interval(irProcedure *proc, AstNodeBinaryExpr *node, Type *v
 }
 }
 
 
 void ir_store_type_case_implicit(irProcedure *proc, AstNode *clause, irValue *value) {
 void ir_store_type_case_implicit(irProcedure *proc, AstNode *clause, irValue *value) {
-	Entity **found = map_entity_get(&proc->module->info->implicits, hash_pointer(clause));
+	Entity **found = map_get(&proc->module->info->implicits, hash_pointer(clause));
 	GB_ASSERT(found != NULL);
 	GB_ASSERT(found != NULL);
 	Entity *e = *found; GB_ASSERT(e != NULL);
 	Entity *e = *found; GB_ASSERT(e != NULL);
 	irValue *x = ir_add_local(proc, e, NULL);
 	irValue *x = ir_add_local(proc, e, NULL);
@@ -5836,18 +5827,18 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 
 
 					irValue *value = ir_value_type_name(proc->module->allocator,
 					irValue *value = ir_value_type_name(proc->module->allocator,
 					                                           name, e->type);
 					                                           name, e->type);
-					map_string_set(&proc->module->entity_names, hash_pointer(e), name);
+					map_set(&proc->module->entity_names, hash_pointer(e), name);
 					ir_gen_global_type_name(proc->module, e, name);
 					ir_gen_global_type_name(proc->module, e, name);
 				} break;
 				} break;
 				case Entity_Procedure: {
 				case Entity_Procedure: {
-					DeclInfo **decl_info = map_decl_info_get(&proc->module->info->entities, hash_pointer(e));
+					DeclInfo **decl_info = map_get(&proc->module->info->entities, hash_pointer(e));
 					GB_ASSERT(decl_info != NULL);
 					GB_ASSERT(decl_info != NULL);
 					DeclInfo *dl = *decl_info;
 					DeclInfo *dl = *decl_info;
 					ast_node(pd, ProcLit, dl->proc_lit);
 					ast_node(pd, ProcLit, dl->proc_lit);
 					if (pd->body != NULL) {
 					if (pd->body != NULL) {
 						CheckerInfo *info = proc->module->info;
 						CheckerInfo *info = proc->module->info;
 
 
-						if (map_entity_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
+						if (map_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
 							// NOTE(bill): Nothing depends upon it so doesn't need to be built
 							// NOTE(bill): Nothing depends upon it so doesn't need to be built
 							break;
 							break;
 						}
 						}
@@ -5896,10 +5887,10 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 
 
 						if (value->Proc.tags & ProcTag_foreign) {
 						if (value->Proc.tags & ProcTag_foreign) {
 							HashKey key = hash_string(name);
 							HashKey key = hash_string(name);
-							irValue **prev_value = map_ir_value_get(&proc->module->members, key);
+							irValue **prev_value = map_get(&proc->module->members, key);
 							if (prev_value == NULL) {
 							if (prev_value == NULL) {
 								// NOTE(bill): Don't do mutliple declarations in the IR
 								// NOTE(bill): Don't do mutliple declarations in the IR
-								map_ir_value_set(&proc->module->members, key, value);
+								map_set(&proc->module->members, key, value);
 							}
 							}
 						} else {
 						} else {
 							array_add(&proc->children, &value->Proc);
 							array_add(&proc->children, &value->Proc);
@@ -6509,7 +6500,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 
 
 			Entity *case_entity = NULL;
 			Entity *case_entity = NULL;
 			{
 			{
-				Entity **found = map_entity_get(&proc->module->info->implicits, hash_pointer(clause));
+				Entity **found = map_get(&proc->module->info->implicits, hash_pointer(clause));
 				GB_ASSERT(found != NULL);
 				GB_ASSERT(found != NULL);
 				case_entity = *found;
 				case_entity = *found;
 			}
 			}
@@ -6679,7 +6670,7 @@ void ir_begin_procedure_body(irProcedure *proc) {
 	array_init(&proc->children,         heap_allocator());
 	array_init(&proc->children,         heap_allocator());
 	array_init(&proc->branch_blocks,    heap_allocator());
 	array_init(&proc->branch_blocks,    heap_allocator());
 
 
-	DeclInfo **found = map_decl_info_get(&proc->module->info->entities, hash_pointer(proc->entity));
+	DeclInfo **found = map_get(&proc->module->info->entities, hash_pointer(proc->entity));
 	if (found != NULL) {
 	if (found != NULL) {
 		DeclInfo *decl = *found;
 		DeclInfo *decl = *found;
 		for_array(i, decl->labels) {
 		for_array(i, decl->labels) {
@@ -6774,12 +6765,12 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
 		CheckerInfo *info = m->info;
 		CheckerInfo *info = m->info;
 		Entity *e = proc->entity;
 		Entity *e = proc->entity;
 		String filename = e->token.pos.file;
 		String filename = e->token.pos.file;
-		AstFile **found = map_ast_file_get(&info->files, hash_string(filename));
+		AstFile **found = map_get(&info->files, hash_string(filename));
 		GB_ASSERT(found != NULL);
 		GB_ASSERT(found != NULL);
 		AstFile *f = *found;
 		AstFile *f = *found;
 		irDebugInfo *di_file = NULL;
 		irDebugInfo *di_file = NULL;
 
 
-		irDebugInfo **di_file_found = map_ir_debug_info_get(&m->debug_info, hash_pointer(f));
+		irDebugInfo **di_file_found = map_get(&m->debug_info, hash_pointer(f));
 		if (di_file_found) {
 		if (di_file_found) {
 			di_file = *di_file_found;
 			di_file = *di_file_found;
 			GB_ASSERT(di_file->kind == irDebugInfo_File);
 			GB_ASSERT(di_file->kind == irDebugInfo_File);
@@ -6831,7 +6822,7 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
 
 
 
 
 void ir_module_add_value(irModule *m, Entity *e, irValue *v) {
 void ir_module_add_value(irModule *m, Entity *e, irValue *v) {
-	map_ir_value_set(&m->values, hash_pointer(e), v);
+	map_set(&m->values, hash_pointer(e), v);
 }
 }
 
 
 void ir_init_module(irModule *m, Checker *c) {
 void ir_init_module(irModule *m, Checker *c) {
@@ -6844,10 +6835,10 @@ void ir_init_module(irModule *m, Checker *c) {
 	m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
 	m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
 	m->info = &c->info;
 	m->info = &c->info;
 
 
-	map_ir_value_init(&m->values,  heap_allocator());
-	map_ir_value_init(&m->members, heap_allocator());
-	map_ir_debug_info_init(&m->debug_info, heap_allocator());
-	map_string_init(&m->entity_names, heap_allocator());
+	map_init(&m->values,  heap_allocator());
+	map_init(&m->members, heap_allocator());
+	map_init(&m->debug_info, heap_allocator());
+	map_init(&m->entity_names, heap_allocator());
 	array_init(&m->procs,    heap_allocator());
 	array_init(&m->procs,    heap_allocator());
 	array_init(&m->procs_to_generate, heap_allocator());
 	array_init(&m->procs_to_generate, heap_allocator());
 	array_init(&m->foreign_library_paths, heap_allocator());
 	array_init(&m->foreign_library_paths, heap_allocator());
@@ -6861,7 +6852,7 @@ void ir_init_module(irModule *m, Checker *c) {
 		{
 		{
 			isize max_index = -1;
 			isize max_index = -1;
 			for_array(type_info_map_index, m->info->type_info_map.entries) {
 			for_array(type_info_map_index, m->info->type_info_map.entries) {
-				MapIsizeEntry *entry = &m->info->type_info_map.entries[type_info_map_index];
+				auto *entry = &m->info->type_info_map.entries[type_info_map_index];
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				t = default_type(t);
 				t = default_type(t);
 				isize entry_index = ir_type_info_index(m->info, t);
 				isize entry_index = ir_type_info_index(m->info, t);
@@ -6876,7 +6867,7 @@ void ir_init_module(irModule *m, Checker *c) {
 			irValue *g = ir_value_global(m->allocator, e, NULL);
 			irValue *g = ir_value_global(m->allocator, e, NULL);
 			g->Global.is_private  = true;
 			g->Global.is_private  = true;
 			ir_module_add_value(m, e, g);
 			ir_module_add_value(m, e, g);
-			map_ir_value_set(&m->members, hash_string(name), g);
+			map_set(&m->members, hash_string(name), g);
 			ir_global_type_info_data = g;
 			ir_global_type_info_data = g;
 		}
 		}
 
 
@@ -6886,7 +6877,7 @@ void ir_init_module(irModule *m, Checker *c) {
 			isize count = 0;
 			isize count = 0;
 
 
 			for_array(entry_index, m->info->type_info_map.entries) {
 			for_array(entry_index, m->info->type_info_map.entries) {
-				MapIsizeEntry *entry = &m->info->type_info_map.entries[entry_index];
+				auto *entry = &m->info->type_info_map.entries[entry_index];
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 
 
 				switch (t->kind) {
 				switch (t->kind) {
@@ -6914,7 +6905,7 @@ void ir_init_module(irModule *m, Checker *c) {
 				                                 make_type_array(m->allocator, t_type_info_ptr, count), false);
 				                                 make_type_array(m->allocator, t_type_info_ptr, count), false);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				ir_module_add_value(m, e, g);
 				ir_module_add_value(m, e, g);
-				map_ir_value_set(&m->members, hash_string(name), g);
+				map_set(&m->members, hash_string(name), g);
 				ir_global_type_info_member_types = g;
 				ir_global_type_info_member_types = g;
 			}
 			}
 			{
 			{
@@ -6923,7 +6914,7 @@ void ir_init_module(irModule *m, Checker *c) {
 				                                 make_type_array(m->allocator, t_string, count), false);
 				                                 make_type_array(m->allocator, t_string, count), false);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				ir_module_add_value(m, e, g);
 				ir_module_add_value(m, e, g);
-				map_ir_value_set(&m->members, hash_string(name), g);
+				map_set(&m->members, hash_string(name), g);
 				ir_global_type_info_member_names = g;
 				ir_global_type_info_member_names = g;
 			}
 			}
 			{
 			{
@@ -6932,7 +6923,7 @@ void ir_init_module(irModule *m, Checker *c) {
 				                                 make_type_array(m->allocator, t_int, count), false);
 				                                 make_type_array(m->allocator, t_int, count), false);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				ir_module_add_value(m, e, g);
 				ir_module_add_value(m, e, g);
-				map_ir_value_set(&m->members, hash_string(name), g);
+				map_set(&m->members, hash_string(name), g);
 				ir_global_type_info_member_offsets = g;
 				ir_global_type_info_member_offsets = g;
 			}
 			}
 
 
@@ -6942,7 +6933,7 @@ void ir_init_module(irModule *m, Checker *c) {
 				                                 make_type_array(m->allocator, t_bool, count), false);
 				                                 make_type_array(m->allocator, t_bool, count), false);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				irValue *g = ir_value_global(m->allocator, e, NULL);
 				ir_module_add_value(m, e, g);
 				ir_module_add_value(m, e, g);
-				map_ir_value_set(&m->members, hash_string(name), g);
+				map_set(&m->members, hash_string(name), g);
 				ir_global_type_info_member_usings = g;
 				ir_global_type_info_member_usings = g;
 			}
 			}
 		}
 		}
@@ -6953,15 +6944,15 @@ void ir_init_module(irModule *m, Checker *c) {
 		di->CompileUnit.file = m->info->files.entries[0].value; // Zeroth is the init file
 		di->CompileUnit.file = m->info->files.entries[0].value; // Zeroth is the init file
 		di->CompileUnit.producer = str_lit("odin");
 		di->CompileUnit.producer = str_lit("odin");
 
 
-		map_ir_debug_info_set(&m->debug_info, hash_pointer(m), di);
+		map_set(&m->debug_info, hash_pointer(m), di);
 	}
 	}
 }
 }
 
 
 void ir_destroy_module(irModule *m) {
 void ir_destroy_module(irModule *m) {
-	map_ir_value_destroy(&m->values);
-	map_ir_value_destroy(&m->members);
-	map_string_destroy(&m->entity_names);
-	map_ir_debug_info_destroy(&m->debug_info);
+	map_destroy(&m->values);
+	map_destroy(&m->members);
+	map_destroy(&m->entity_names);
+	map_destroy(&m->debug_info);
 	array_free(&m->procs);
 	array_free(&m->procs);
 	array_free(&m->procs_to_generate);
 	array_free(&m->procs_to_generate);
 	array_free(&m->foreign_library_paths);
 	array_free(&m->foreign_library_paths);
@@ -7089,7 +7080,7 @@ void ir_gen_tree(irGen *s) {
 	bool has_win_main = false;
 	bool has_win_main = false;
 
 
 	for_array(i, info->entities.entries) {
 	for_array(i, info->entities.entries) {
-		MapDeclInfoEntry *entry = &info->entities.entries[i];
+		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		String name = e->token.string;
 		String name = e->token.string;
 		if (e->kind == Entity_Variable) {
 		if (e->kind == Entity_Variable) {
@@ -7121,7 +7112,7 @@ void ir_gen_tree(irGen *s) {
 	m->min_dep_map = generate_minimum_dependency_map(info, entry_point);
 	m->min_dep_map = generate_minimum_dependency_map(info, entry_point);
 
 
 	for_array(i, info->entities.entries) {
 	for_array(i, info->entities.entries) {
-		MapDeclInfoEntry *entry = &info->entities.entries[i];
+		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)entry->key.ptr;
 		Entity *e = cast(Entity *)entry->key.ptr;
 		String name = e->token.string;
 		String name = e->token.string;
 		DeclInfo *decl = entry->value;
 		DeclInfo *decl = entry->value;
@@ -7131,7 +7122,7 @@ void ir_gen_tree(irGen *s) {
 			continue;
 			continue;
 		}
 		}
 
 
-		if (map_entity_get(&m->min_dep_map, hash_pointer(e)) == NULL) {
+		if (map_get(&m->min_dep_map, hash_pointer(e)) == NULL) {
 			// NOTE(bill): Nothing depends upon it so doesn't need to be built
 			// NOTE(bill): Nothing depends upon it so doesn't need to be built
 			continue;
 			continue;
 		}
 		}
@@ -7145,7 +7136,7 @@ void ir_gen_tree(irGen *s) {
 				name = ir_mangle_name(s, e->token.pos.file, e);
 				name = ir_mangle_name(s, e->token.pos.file, e);
 			}
 			}
 		}
 		}
-		map_string_set(&m->entity_names, hash_pointer(e), name);
+		map_set(&m->entity_names, hash_pointer(e), name);
 
 
 		switch (e->kind) {
 		switch (e->kind) {
 		case Entity_TypeName:
 		case Entity_TypeName:
@@ -7183,7 +7174,7 @@ void ir_gen_tree(irGen *s) {
 			}
 			}
 
 
 			ir_module_add_value(m, e, g);
 			ir_module_add_value(m, e, g);
-			map_ir_value_set(&m->members, hash_string(name), g);
+			map_set(&m->members, hash_string(name), g);
 		} break;
 		} break;
 
 
 		case Entity_Procedure: {
 		case Entity_Procedure: {
@@ -7207,15 +7198,15 @@ void ir_gen_tree(irGen *s) {
 
 
 			ir_module_add_value(m, e, p);
 			ir_module_add_value(m, e, p);
 			HashKey hash_name = hash_string(name);
 			HashKey hash_name = hash_string(name);
-			if (map_ir_value_get(&m->members, hash_name) == NULL) {
-				map_ir_value_multi_insert(&m->members, hash_name, p);
+			if (map_get(&m->members, hash_name) == NULL) {
+				multi_map_insert(&m->members, hash_name, p);
 			}
 			}
 		} break;
 		} break;
 		}
 		}
 	}
 	}
 
 
 	for_array(i, m->members.entries) {
 	for_array(i, m->members.entries) {
-		MapIrValueEntry *entry = &m->members.entries[i];
+		auto *entry = &m->members.entries[i];
 		irValue *v = entry->value;
 		irValue *v = entry->value;
 		if (v->kind == irValue_Proc) {
 		if (v->kind == irValue_Proc) {
 			ir_build_proc(v, NULL);
 			ir_build_proc(v, NULL);
@@ -7228,7 +7219,7 @@ void ir_gen_tree(irGen *s) {
 
 
 	isize all_proc_max_count = 0;
 	isize all_proc_max_count = 0;
 	for_array(i, m->debug_info.entries) {
 	for_array(i, m->debug_info.entries) {
-		MapIrDebugInfoEntry *entry = &m->debug_info.entries[i];
+		auto *entry = &m->debug_info.entries[i];
 		irDebugInfo *di = entry->value;
 		irDebugInfo *di = entry->value;
 		di->id = i;
 		di->id = i;
 		if (di->kind == irDebugInfo_Proc) {
 		if (di->kind == irDebugInfo_Proc) {
@@ -7237,12 +7228,12 @@ void ir_gen_tree(irGen *s) {
 	}
 	}
 
 
 	array_init(&all_procs->AllProcs.procs, m->allocator, all_proc_max_count);
 	array_init(&all_procs->AllProcs.procs, m->allocator, all_proc_max_count);
-	map_ir_debug_info_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
+	map_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
 	compile_unit->CompileUnit.all_procs = all_procs;
 	compile_unit->CompileUnit.all_procs = all_procs;
 
 
 
 
 	for_array(i, m->debug_info.entries) {
 	for_array(i, m->debug_info.entries) {
-		MapIrDebugInfoEntry *entry = &m->debug_info.entries[i];
+		auto *entry = &m->debug_info.entries[i];
 		irDebugInfo *di = entry->value;
 		irDebugInfo *di = entry->value;
 		if (di->kind == irDebugInfo_Proc) {
 		if (di->kind == irDebugInfo_Proc) {
 			array_add(&all_procs->AllProcs.procs, di);
 			array_add(&all_procs->AllProcs.procs, di);
@@ -7279,8 +7270,8 @@ void ir_gen_tree(irGen *s) {
 		Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
 		Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
 		irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
 		irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
 
 
-		map_ir_value_set(&m->values, hash_pointer(e), p);
-		map_ir_value_set(&m->members, hash_string(name), p);
+		map_set(&m->values, hash_pointer(e), p);
+		map_set(&m->members, hash_string(name), p);
 
 
 		irProcedure *proc = &p->Proc;
 		irProcedure *proc = &p->Proc;
 		proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
 		proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
@@ -7300,7 +7291,7 @@ void ir_gen_tree(irGen *s) {
 
 
 		{
 		{
 			String main_name = str_lit("main");
 			String main_name = str_lit("main");
-			irValue **found = map_ir_value_get(&m->members, hash_string(main_name));
+			irValue **found = map_get(&m->members, hash_string(main_name));
 			if (found != NULL) {
 			if (found != NULL) {
 				ir_emit_call(proc, *found, NULL, 0);
 				ir_emit_call(proc, *found, NULL, 0);
 			} else {
 			} else {
@@ -7350,8 +7341,8 @@ void ir_gen_tree(irGen *s) {
 
 
 		m->entry_point_entity = e;
 		m->entry_point_entity = e;
 
 
-		map_ir_value_set(&m->values, hash_pointer(e), p);
-		map_ir_value_set(&m->members, hash_string(name), p);
+		map_set(&m->values, hash_pointer(e), p);
+		map_set(&m->members, hash_string(name), p);
 
 
 		irProcedure *proc = &p->Proc;
 		irProcedure *proc = &p->Proc;
 		proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
 		proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
@@ -7373,8 +7364,8 @@ void ir_gen_tree(irGen *s) {
 		Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
 		Entity *e = make_entity_procedure(a, NULL, make_token_ident(name), proc_type, 0);
 		irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
 		irValue *p = ir_value_procedure(a, m, e, proc_type, NULL, body, name);
 
 
-		map_ir_value_set(&m->values, hash_pointer(e), p);
-		map_ir_value_set(&m->members, hash_string(name), p);
+		map_set(&m->values, hash_pointer(e), p);
+		map_set(&m->members, hash_string(name), p);
 
 
 
 
 		irProcedure *proc = &p->Proc;
 		irProcedure *proc = &p->Proc;
@@ -7452,7 +7443,7 @@ void ir_gen_tree(irGen *s) {
 			i32 type_info_member_offsets_index = 0;
 			i32 type_info_member_offsets_index = 0;
 
 
 			for_array(type_info_map_index, info->type_info_map.entries) {
 			for_array(type_info_map_index, info->type_info_map.entries) {
-				MapIsizeEntry *entry = &info->type_info_map.entries[type_info_map_index];
+				auto *entry = &info->type_info_map.entries[type_info_map_index];
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				t = default_type(t);
 				t = default_type(t);
 				isize entry_index = ir_type_info_index(info, t);
 				isize entry_index = ir_type_info_index(info, t);
@@ -7915,7 +7906,7 @@ void ir_gen_tree(irGen *s) {
 	}
 	}
 
 
 	for_array(type_info_map_index, info->type_info_map.entries) {
 	for_array(type_info_map_index, info->type_info_map.entries) {
-		MapIsizeEntry *entry = &info->type_info_map.entries[type_info_map_index];
+		auto *entry = &info->type_info_map.entries[type_info_map_index];
 		Type *t = cast(Type *)cast(uintptr)entry->key.key;
 		Type *t = cast(Type *)cast(uintptr)entry->key.key;
 		t = default_type(t);
 		t = default_type(t);
 		isize entry_index = entry->value;
 		isize entry_index = entry->value;
@@ -7934,7 +7925,7 @@ void ir_gen_tree(irGen *s) {
 
 
 	// Number debug info
 	// Number debug info
 	for_array(i, m->debug_info.entries) {
 	for_array(i, m->debug_info.entries) {
-		MapIrDebugInfoEntry *entry = &m->debug_info.entries[i];
+		auto *entry = &m->debug_info.entries[i];
 		irDebugInfo *di = entry->value;
 		irDebugInfo *di = entry->value;
 		di->id = i;
 		di->id = i;
 	}
 	}

+ 7 - 7
src/ir_print.cpp

@@ -306,7 +306,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
 
 
 	case Type_Named:
 	case Type_Named:
 		if (is_type_struct(t) || is_type_union(t)) {
 		if (is_type_struct(t) || is_type_union(t)) {
-			String *name = map_string_get(&m->entity_names, hash_pointer(t->Named.type_name));
+			String *name = map_get(&m->entity_names, hash_pointer(t->Named.type_name));
 			GB_ASSERT_MSG(name != NULL, "%.*s", LIT(t->Named.name));
 			GB_ASSERT_MSG(name != NULL, "%.*s", LIT(t->Named.name));
 			ir_print_encoded_local(f, *name);
 			ir_print_encoded_local(f, *name);
 		} else {
 		} else {
@@ -1523,7 +1523,7 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
 
 
 	if (proc->entity != NULL) {
 	if (proc->entity != NULL) {
 		if (proc->body != NULL) {
 		if (proc->body != NULL) {
-			irDebugInfo **di_ = map_ir_debug_info_get(&proc->module->debug_info, hash_pointer(proc->entity));
+			irDebugInfo **di_ = map_get(&proc->module->debug_info, hash_pointer(proc->entity));
 			if (di_ != NULL) {
 			if (di_ != NULL) {
 				irDebugInfo *di = *di_;
 				irDebugInfo *di = *di_;
 				GB_ASSERT(di->kind == irDebugInfo_Proc);
 				GB_ASSERT(di->kind == irDebugInfo_Proc);
@@ -1606,7 +1606,7 @@ void print_llvm_ir(irGen *ir) {
 
 
 
 
 	for_array(member_index, m->members.entries) {
 	for_array(member_index, m->members.entries) {
-		MapIrValueEntry *entry = &m->members.entries[member_index];
+		auto *entry = &m->members.entries[member_index];
 		irValue *v = entry->value;
 		irValue *v = entry->value;
 		if (v->kind != irValue_TypeName) {
 		if (v->kind != irValue_TypeName) {
 			continue;
 			continue;
@@ -1619,7 +1619,7 @@ void print_llvm_ir(irGen *ir) {
 	bool dll_main_found = false;
 	bool dll_main_found = false;
 
 
 	for_array(member_index, m->members.entries) {
 	for_array(member_index, m->members.entries) {
-		MapIrValueEntry *entry = &m->members.entries[member_index];
+		auto *entry = &m->members.entries[member_index];
 		irValue *v = entry->value;
 		irValue *v = entry->value;
 		if (v->kind != irValue_Proc) {
 		if (v->kind != irValue_Proc) {
 			continue;
 			continue;
@@ -1631,7 +1631,7 @@ void print_llvm_ir(irGen *ir) {
 	}
 	}
 
 
 	for_array(member_index, m->members.entries) {
 	for_array(member_index, m->members.entries) {
-		MapIrValueEntry *entry = &m->members.entries[member_index];
+		auto *entry = &m->members.entries[member_index];
 		irValue *v = entry->value;
 		irValue *v = entry->value;
 		if (v->kind != irValue_Proc) {
 		if (v->kind != irValue_Proc) {
 			continue;
 			continue;
@@ -1643,7 +1643,7 @@ void print_llvm_ir(irGen *ir) {
 	}
 	}
 
 
 	for_array(member_index, m->members.entries) {
 	for_array(member_index, m->members.entries) {
-		MapIrValueEntry *entry = &m->members.entries[member_index];
+		auto *entry = &m->members.entries[member_index];
 		irValue *v = entry->value;
 		irValue *v = entry->value;
 		if (v->kind != irValue_Global) {
 		if (v->kind != irValue_Global) {
 			continue;
 			continue;
@@ -1713,7 +1713,7 @@ void print_llvm_ir(irGen *ir) {
 
 
 			switch (di->kind) {
 			switch (di->kind) {
 			case irDebugInfo_CompileUnit: {
 			case irDebugInfo_CompileUnit: {
-				irDebugInfo *file = *map_ir_debug_info_get(&m->debug_info, hash_pointer(di->CompileUnit.file));
+				irDebugInfo *file = *map_get(&m->debug_info, hash_pointer(di->CompileUnit.file));
 				ir_fprintf(f,
 				ir_fprintf(f,
 				            "distinct !DICompileUnit("
 				            "distinct !DICompileUnit("
 				            "language: DW_LANG_Go, " // Is this good enough?
 				            "language: DW_LANG_Go, " // Is this good enough?

+ 114 - 115
src/map.cpp

@@ -1,38 +1,30 @@
-/*
-	Example of usage:
-
-	#define MAP_TYPE String
-	#define MAP_PROC map_string_
-	#define MAP_NAME MapString
-	#include "map.cpp"
-*/
 // A `Map` is an unordered hash table which can allow for a key to point to multiple values
 // A `Map` is an unordered hash table which can allow for a key to point to multiple values
 // with the use of the `multi_*` procedures.
 // with the use of the `multi_*` procedures.
-// TODO(bill): I should probably allow the `multi_*` stuff to be #ifdefed out
+// TODO(bill): I should probably allow the `multi_map_*` stuff to be #ifdefed out
 
 
 #ifndef MAP_UTIL_STUFF
 #ifndef MAP_UTIL_STUFF
 #define MAP_UTIL_STUFF
 #define MAP_UTIL_STUFF
 // NOTE(bill): This util stuff is the same for every `Map`
 // NOTE(bill): This util stuff is the same for every `Map`
-typedef struct MapFindResult {
+struct MapFindResult {
 	isize hash_index;
 	isize hash_index;
 	isize entry_prev;
 	isize entry_prev;
 	isize entry_index;
 	isize entry_index;
-} MapFindResult;
+};
 
 
-typedef enum HashKeyKind {
+enum HashKeyKind {
 	HashKey_Default,
 	HashKey_Default,
 	HashKey_String,
 	HashKey_String,
 	HashKey_Pointer,
 	HashKey_Pointer,
-} HashKeyKind;
+};
 
 
-typedef struct HashKey {
+struct HashKey {
 	HashKeyKind kind;
 	HashKeyKind kind;
 	u64         key;
 	u64         key;
 	union {
 	union {
 		String string; // if String, s.len > 0
 		String string; // if String, s.len > 0
 		void * ptr;
 		void * ptr;
 	};
 	};
-} HashKey;
+};
 
 
 gb_inline HashKey hashing_proc(void const *data, isize len) {
 gb_inline HashKey hashing_proc(void const *data, isize len) {
 	HashKey h = {HashKey_Default};
 	HashKey h = {HashKey_Default};
@@ -73,75 +65,75 @@ bool hash_key_equal(HashKey a, HashKey b) {
 	}
 	}
 	return false;
 	return false;
 }
 }
-#endif
-
-#define _J2_IND(a, b) a##b
-#define _J2(a, b) _J2_IND(a, b)
+bool operator==(HashKey a, HashKey b) { return hash_key_equal(a, b); }
+bool operator!=(HashKey a, HashKey b) { return !hash_key_equal(a, b); }
 
 
-/*
-MAP_TYPE - Entry type
-MAP_PROC - Function prefix (e.g. entity_map_)
-MAP_NAME - Name of Map (e.g. EntityMap)
-*/
-#define MAP_ENTRY _J2(MAP_NAME,Entry)
+#endif
 
 
-typedef struct MAP_ENTRY {
+template <typename T>
+struct MapEntry {
 	HashKey  key;
 	HashKey  key;
 	isize    next;
 	isize    next;
-	MAP_TYPE value;
-} MAP_ENTRY;
-
-typedef struct MAP_NAME {
-	Array<isize>     hashes;
-	Array<MAP_ENTRY> entries;
-} MAP_NAME;
-
-void      _J2(MAP_PROC,init)             (MAP_NAME *h, gbAllocator a);
-void      _J2(MAP_PROC,init_with_reserve)(MAP_NAME *h, gbAllocator a, isize capacity);
-void      _J2(MAP_PROC,destroy)          (MAP_NAME *h);
-MAP_TYPE *_J2(MAP_PROC,get)              (MAP_NAME *h, HashKey key);
-void      _J2(MAP_PROC,set)              (MAP_NAME *h, HashKey key, MAP_TYPE value);
-void      _J2(MAP_PROC,remove)           (MAP_NAME *h, HashKey key);
-void      _J2(MAP_PROC,clear)            (MAP_NAME *h);
-void      _J2(MAP_PROC,grow)             (MAP_NAME *h);
-void      _J2(MAP_PROC,rehash)           (MAP_NAME *h, isize new_count);
+	T        value;
+};
+
+template <typename T>
+struct Map {
+	Array<isize>        hashes;
+	Array<MapEntry<T> > entries;
+};
+
+
+template <typename T> void map_init             (Map<T> *h, gbAllocator a);
+template <typename T> void map_init_with_reserve(Map<T> *h, gbAllocator a, isize capacity);
+template <typename T> void map_destroy          (Map<T> *h);
+template <typename T> T *  map_get              (Map<T> *h, HashKey key);
+template <typename T> void map_set              (Map<T> *h, HashKey key, T const &value);
+template <typename T> void map_remove           (Map<T> *h, HashKey key);
+template <typename T> void map_clear            (Map<T> *h);
+template <typename T> void map_grow             (Map<T> *h);
+template <typename T> void map_rehash           (Map<T> *h, isize new_count);
 
 
 // Mutlivalued map procedure
 // Mutlivalued map procedure
-MAP_ENTRY *_J2(MAP_PROC,multi_find_first)(MAP_NAME *h, HashKey key);
-MAP_ENTRY *_J2(MAP_PROC,multi_find_next) (MAP_NAME *h, MAP_ENTRY *e);
-
-isize _J2(MAP_PROC,multi_count)     (MAP_NAME *h, HashKey key);
-void  _J2(MAP_PROC,multi_get_all)   (MAP_NAME *h, HashKey key, MAP_TYPE *items);
-void  _J2(MAP_PROC,multi_insert)    (MAP_NAME *h, HashKey key, MAP_TYPE value);
-void  _J2(MAP_PROC,multi_remove)    (MAP_NAME *h, HashKey key, MAP_ENTRY *e);
-void  _J2(MAP_PROC,multi_remove_all)(MAP_NAME *h, HashKey key);
+template <typename T> MapEntry<T> * multi_map_find_first(Map<T> *h, HashKey key);
+template <typename T> MapEntry<T> * multi_map_find_next (Map<T> *h, MapEntry<T> *e);
 
 
+template <typename T> isize multi_map_count     (Map<T> *h, HashKey key);
+template <typename T> void  multi_map_get_all   (Map<T> *h, HashKey key, T *items);
+template <typename T> void  multi_map_insert    (Map<T> *h, HashKey key, T const &value);
+template <typename T> void  multi_map_remove    (Map<T> *h, HashKey key, MapEntry<T> *e);
+template <typename T> void  multi_map_remove_all(Map<T> *h, HashKey key);
 
 
 
 
-gb_inline void _J2(MAP_PROC,init)(MAP_NAME *h, gbAllocator a) {
+template <typename T>
+gb_inline void map_init(Map<T> *h, gbAllocator a) {
 	array_init(&h->hashes,  a);
 	array_init(&h->hashes,  a);
 	array_init(&h->entries, a);
 	array_init(&h->entries, a);
 }
 }
 
 
-gb_inline void _J2(MAP_PROC,init_with_reserve)(MAP_NAME *h, gbAllocator a, isize capacity) {
+template <typename T>
+gb_inline void map_init_with_reserve(Map<T> *h, gbAllocator a, isize capacity) {
 	array_init(&h->hashes,  a, capacity);
 	array_init(&h->hashes,  a, capacity);
 	array_init(&h->entries, a, capacity);
 	array_init(&h->entries, a, capacity);
 }
 }
 
 
-gb_inline void _J2(MAP_PROC,destroy)(MAP_NAME *h) {
+template <typename T>
+gb_inline void map_destroy(Map<T> *h) {
 	array_free(&h->entries);
 	array_free(&h->entries);
 	array_free(&h->hashes);
 	array_free(&h->hashes);
 }
 }
 
 
-gb_internal isize _J2(MAP_PROC,_add_entry)(MAP_NAME *h, HashKey key) {
-	MAP_ENTRY e = {};
+template <typename T>
+gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
+	MapEntry<T> e = {};
 	e.key = key;
 	e.key = key;
 	e.next = -1;
 	e.next = -1;
 	array_add(&h->entries, e);
 	array_add(&h->entries, e);
 	return h->entries.count-1;
 	return h->entries.count-1;
 }
 }
 
 
-gb_internal MapFindResult _J2(MAP_PROC,_find)(MAP_NAME *h, HashKey key) {
+template <typename T>
+gb_internal MapFindResult map__find(Map<T> *h, HashKey key) {
 	MapFindResult fr = {-1, -1, -1};
 	MapFindResult fr = {-1, -1, -1};
 	if (h->hashes.count > 0) {
 	if (h->hashes.count > 0) {
 		fr.hash_index  = key.key % h->hashes.count;
 		fr.hash_index  = key.key % h->hashes.count;
@@ -157,7 +149,8 @@ gb_internal MapFindResult _J2(MAP_PROC,_find)(MAP_NAME *h, HashKey key) {
 	return fr;
 	return fr;
 }
 }
 
 
-gb_internal MapFindResult _J2(MAP_PROC,_find_from_entry)(MAP_NAME *h, MAP_ENTRY *e) {
+template <typename T>
+gb_internal MapFindResult map__find_from_entry(Map<T> *h, MapEntry<T> *e) {
 	MapFindResult fr = {-1, -1, -1};
 	MapFindResult fr = {-1, -1, -1};
 	if (h->hashes.count > 0) {
 	if (h->hashes.count > 0) {
 		fr.hash_index  = e->key.key % h->hashes.count;
 		fr.hash_index  = e->key.key % h->hashes.count;
@@ -173,33 +166,35 @@ gb_internal MapFindResult _J2(MAP_PROC,_find_from_entry)(MAP_NAME *h, MAP_ENTRY
 	return fr;
 	return fr;
 }
 }
 
 
-
-gb_internal b32 _J2(MAP_PROC,_full)(MAP_NAME *h) {
+template <typename T>
+gb_internal b32 map__full(Map<T> *h) {
 	return 0.75f * h->hashes.count <= h->entries.count;
 	return 0.75f * h->hashes.count <= h->entries.count;
 }
 }
 
 
-gb_inline void _J2(MAP_PROC,grow)(MAP_NAME *h) {
+template <typename T>
+gb_inline void map_grow(Map<T> *h) {
 	isize new_count = ARRAY_GROW_FORMULA(h->entries.count);
 	isize new_count = ARRAY_GROW_FORMULA(h->entries.count);
-	_J2(MAP_PROC,rehash)(h, new_count);
+	map_rehash(h, new_count);
 }
 }
 
 
-void _J2(MAP_PROC,rehash)(MAP_NAME *h, isize new_count) {
+template <typename T>
+void map_rehash(Map<T> *h, isize new_count) {
 	isize i, j;
 	isize i, j;
-	MAP_NAME nh = {};
-	_J2(MAP_PROC,init)(&nh, h->hashes.allocator);
+	Map<T> nh = {};
+	map_init(&nh, h->hashes.allocator);
 	array_resize(&nh.hashes, new_count);
 	array_resize(&nh.hashes, new_count);
 	array_reserve(&nh.entries, h->entries.count);
 	array_reserve(&nh.entries, h->entries.count);
 	for (i = 0; i < new_count; i++) {
 	for (i = 0; i < new_count; i++) {
 		nh.hashes[i] = -1;
 		nh.hashes[i] = -1;
 	}
 	}
 	for (i = 0; i < h->entries.count; i++) {
 	for (i = 0; i < h->entries.count; i++) {
-		MAP_ENTRY *e = &h->entries[i];
+		MapEntry<T> *e = &h->entries[i];
 		MapFindResult fr;
 		MapFindResult fr;
 		if (nh.hashes.count == 0) {
 		if (nh.hashes.count == 0) {
-			_J2(MAP_PROC,grow)(&nh);
+			map_grow(&nh);
 		}
 		}
-		fr = _J2(MAP_PROC,_find)(&nh, e->key);
-		j = _J2(MAP_PROC,_add_entry)(&nh, e->key);
+		fr = map__find(&nh, e->key);
+		j = map__add_entry(&nh, e->key);
 		if (fr.entry_prev < 0) {
 		if (fr.entry_prev < 0) {
 			nh.hashes[fr.hash_index] = j;
 			nh.hashes[fr.hash_index] = j;
 		} else {
 		} else {
@@ -207,32 +202,34 @@ void _J2(MAP_PROC,rehash)(MAP_NAME *h, isize new_count) {
 		}
 		}
 		nh.entries[j].next = fr.entry_index;
 		nh.entries[j].next = fr.entry_index;
 		nh.entries[j].value = e->value;
 		nh.entries[j].value = e->value;
-		if (_J2(MAP_PROC,_full)(&nh)) {
-			_J2(MAP_PROC,grow)(&nh);
+		if (map__full(&nh)) {
+			map_grow(&nh);
 		}
 		}
 	}
 	}
-	_J2(MAP_PROC,destroy)(h);
+	map_destroy(h);
 	*h = nh;
 	*h = nh;
 }
 }
 
 
-gb_inline MAP_TYPE *_J2(MAP_PROC,get)(MAP_NAME *h, HashKey key) {
-	isize index = _J2(MAP_PROC,_find)(h, key).entry_index;
+template <typename T>
+gb_inline T *map_get(Map<T> *h, HashKey key) {
+	isize index = map__find(h, key).entry_index;
 	if (index >= 0) {
 	if (index >= 0) {
 		return &h->entries[index].value;
 		return &h->entries[index].value;
 	}
 	}
 	return NULL;
 	return NULL;
 }
 }
 
 
-void _J2(MAP_PROC,set)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
+template <typename T>
+void map_set(Map<T> *h, HashKey key, T const &value) {
 	isize index;
 	isize index;
 	MapFindResult fr;
 	MapFindResult fr;
 	if (h->hashes.count == 0)
 	if (h->hashes.count == 0)
-		_J2(MAP_PROC,grow)(h);
-	fr = _J2(MAP_PROC,_find)(h, key);
+		map_grow(h);
+	fr = map__find(h, key);
 	if (fr.entry_index >= 0) {
 	if (fr.entry_index >= 0) {
 		index = fr.entry_index;
 		index = fr.entry_index;
 	} else {
 	} else {
-		index = _J2(MAP_PROC,_add_entry)(h, key);
+		index = map__add_entry(h, key);
 		if (fr.entry_prev >= 0) {
 		if (fr.entry_prev >= 0) {
 			h->entries[fr.entry_prev].next = index;
 			h->entries[fr.entry_prev].next = index;
 		} else {
 		} else {
@@ -241,14 +238,14 @@ void _J2(MAP_PROC,set)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
 	}
 	}
 	h->entries[index].value = value;
 	h->entries[index].value = value;
 
 
-	if (_J2(MAP_PROC,_full)(h)) {
-		_J2(MAP_PROC,grow)(h);
+	if (map__full(h)) {
+		map_grow(h);
 	}
 	}
 }
 }
 
 
 
 
-
-void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
+template <typename T>
+void map__erase(Map<T> *h, MapFindResult fr) {
 	MapFindResult last;
 	MapFindResult last;
 	if (fr.entry_prev < 0) {
 	if (fr.entry_prev < 0) {
 		h->hashes[fr.hash_index] = h->entries[fr.entry_index].next;
 		h->hashes[fr.hash_index] = h->entries[fr.entry_index].next;
@@ -260,7 +257,7 @@ void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
 		return;
 		return;
 	}
 	}
 	h->entries[fr.entry_index] = h->entries[h->entries.count-1];
 	h->entries[fr.entry_index] = h->entries[h->entries.count-1];
-	last = _J2(MAP_PROC,_find)(h, h->entries[fr.entry_index].key);
+	last = map__find(h, h->entries[fr.entry_index].key);
 	if (last.entry_prev >= 0) {
 	if (last.entry_prev >= 0) {
 		h->entries[last.entry_prev].next = fr.entry_index;
 		h->entries[last.entry_prev].next = fr.entry_index;
 	} else {
 	} else {
@@ -268,29 +265,33 @@ void _J2(MAP_PROC,_erase)(MAP_NAME *h, MapFindResult fr) {
 	}
 	}
 }
 }
 
 
-void _J2(MAP_PROC,remove)(MAP_NAME *h, HashKey key) {
-	MapFindResult fr = _J2(MAP_PROC,_find)(h, key);
+template <typename T>
+void map_remove(Map<T> *h, HashKey key) {
+	MapFindResult fr = map__find(h, key);
 	if (fr.entry_index >= 0) {
 	if (fr.entry_index >= 0) {
-		_J2(MAP_PROC,_erase)(h, fr);
+		map__erase(h, fr);
 	}
 	}
 }
 }
 
 
-gb_inline void _J2(MAP_PROC,clear)(MAP_NAME *h) {
+template <typename T>
+gb_inline void map_clear(Map<T> *h) {
 	array_clear(&h->hashes);
 	array_clear(&h->hashes);
 	array_clear(&h->entries);
 	array_clear(&h->entries);
 }
 }
 
 
 
 
 #if 1
 #if 1
-MAP_ENTRY *_J2(MAP_PROC,multi_find_first)(MAP_NAME *h, HashKey key) {
-	isize i = _J2(MAP_PROC,_find)(h, key).entry_index;
+template <typename T>
+MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey key) {
+	isize i = map__find(h, key).entry_index;
 	if (i < 0) {
 	if (i < 0) {
 		return NULL;
 		return NULL;
 	}
 	}
 	return &h->entries[i];
 	return &h->entries[i];
 }
 }
 
 
-MAP_ENTRY *_J2(MAP_PROC,multi_find_next)(MAP_NAME *h, MAP_ENTRY *e) {
+template <typename T>
+MapEntry<T> *multi_map_find_next(Map<T> *h, MapEntry<T> *e) {
 	isize i = e->next;
 	isize i = e->next;
 	while (i >= 0) {
 	while (i >= 0) {
 		if (hash_key_equal(h->entries[i].key, e->key)) {
 		if (hash_key_equal(h->entries[i].key, e->key)) {
@@ -301,34 +302,37 @@ MAP_ENTRY *_J2(MAP_PROC,multi_find_next)(MAP_NAME *h, MAP_ENTRY *e) {
 	return NULL;
 	return NULL;
 }
 }
 
 
-isize _J2(MAP_PROC,multi_count)(MAP_NAME *h, HashKey key) {
+template <typename T>
+isize multi_map_count(Map<T> *h, HashKey key) {
 	isize count = 0;
 	isize count = 0;
-	MAP_ENTRY *e = _J2(MAP_PROC,multi_find_first)(h, key);
+	MapEntry<T> *e = multi_map_find_first(h, key);
 	while (e != NULL) {
 	while (e != NULL) {
 		count++;
 		count++;
-		e = _J2(MAP_PROC,multi_find_next)(h, e);
+		e = multi_map_find_next(h, e);
 	}
 	}
 	return count;
 	return count;
 }
 }
 
 
-void _J2(MAP_PROC,multi_get_all)(MAP_NAME *h, HashKey key, MAP_TYPE *items) {
+template <typename T>
+void multi_map_get_all(Map<T> *h, HashKey key, T *items) {
 	isize i = 0;
 	isize i = 0;
-	MAP_ENTRY *e = _J2(MAP_PROC,multi_find_first)(h, key);
+	MapEntry<T> *e = multi_map_find_first(h, key);
 	while (e != NULL) {
 	while (e != NULL) {
 		items[i++] = e->value;
 		items[i++] = e->value;
-		e = _J2(MAP_PROC,multi_find_next)(h, e);
+		e = multi_map_find_next(h, e);
 	}
 	}
 }
 }
 
 
-void _J2(MAP_PROC,multi_insert)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
+template <typename T>
+void multi_map_insert(Map<T> *h, HashKey key, T const &value) {
 	MapFindResult fr;
 	MapFindResult fr;
 	isize i;
 	isize i;
 	if (h->hashes.count == 0) {
 	if (h->hashes.count == 0) {
-		_J2(MAP_PROC,grow)(h);
+		map_grow(h);
 	}
 	}
 	// Make
 	// Make
-	fr = _J2(MAP_PROC,_find)(h, key);
-	i = _J2(MAP_PROC,_add_entry)(h, key);
+	fr = map__find(h, key);
+	i = map__add_entry(h, key);
 	if (fr.entry_prev < 0) {
 	if (fr.entry_prev < 0) {
 		h->hashes[fr.hash_index] = i;
 		h->hashes[fr.hash_index] = i;
 	} else {
 	} else {
@@ -337,28 +341,23 @@ void _J2(MAP_PROC,multi_insert)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
 	h->entries[i].next = fr.entry_index;
 	h->entries[i].next = fr.entry_index;
 	h->entries[i].value = value;
 	h->entries[i].value = value;
 	// Grow if needed
 	// Grow if needed
-	if (_J2(MAP_PROC,_full)(h)) {
-		_J2(MAP_PROC,grow)(h);
+	if (map__full(h)) {
+		map_grow(h);
 	}
 	}
 }
 }
 
 
-void _J2(MAP_PROC,multi_remove)(MAP_NAME *h, HashKey key, MAP_ENTRY *e) {
-	MapFindResult fr = _J2(MAP_PROC,_find_from_entry)(h, e);
+template <typename T>
+void multi_map_remove(Map<T> *h, HashKey key, MapEntry<T> *e) {
+	MapFindResult fr = map__find_from_entry(h, e);
 	if (fr.entry_index >= 0) {
 	if (fr.entry_index >= 0) {
-		_J2(MAP_PROC,_erase)(h, fr);
+		map__erase(h, fr);
 	}
 	}
 }
 }
 
 
-void _J2(MAP_PROC,multi_remove_all)(MAP_NAME *h, HashKey key) {
-	while (_J2(MAP_PROC,get)(h, key) != NULL) {
-		_J2(MAP_PROC,remove)(h, key);
+template <typename T>
+void multi_map_remove_all(Map<T> *h, HashKey key) {
+	while (map_get(h, key) != NULL) {
+		map_remove(h, key);
 	}
 	}
 }
 }
 #endif
 #endif
-
-
-#undef _J2
-#undef MAP_TYPE
-#undef MAP_PROC
-#undef MAP_NAME
-#undef MAP_ENTRY

+ 19 - 23
src/ssa.cpp

@@ -14,10 +14,6 @@ enum   ssaDeferExitKind;
 
 
 String ssa_mangle_name(ssaModule *m, String path, Entity *e);
 String ssa_mangle_name(ssaModule *m, String path, Entity *e);
 
 
-#define MAP_TYPE ssaValue *
-#define MAP_PROC map_ssa_value_
-#define MAP_NAME MapSsaValue
-#include "map.cpp"
 
 
 #include "ssa_op.cpp"
 #include "ssa_op.cpp"
 
 
@@ -148,7 +144,7 @@ struct ssaProc {
 
 
 	i32               block_id;
 	i32               block_id;
 	i32               value_id;
 	i32               value_id;
-	MapSsaValue       values;   // Key: Entity *
+	Map<ssaValue *>   values;   // Key: Entity *
 
 
 	Array<ssaDefer>   defer_stmts;
 	Array<ssaDefer>   defer_stmts;
 	i32               scope_level;
 	i32               scope_level;
@@ -166,8 +162,8 @@ struct ssaModule {
 	gbAllocator        tmp_allocator;
 	gbAllocator        tmp_allocator;
 	gbArena            tmp_arena;
 	gbArena            tmp_arena;
 
 
-	MapEntity          min_dep_map; // Key: Entity *
-	MapSsaValue        values;      // Key: Entity *
+	Map<Entity *>      min_dep_map; // Key: Entity *
+	Map<ssaValue *>    values;      // Key: Entity *
 	// List of registers for the specific architecture
 	// List of registers for the specific architecture
 	Array<ssaRegister> registers;
 	Array<ssaRegister> registers;
 
 
@@ -584,7 +580,7 @@ ssaProc *ssa_new_proc(ssaModule *m, String name, Entity *entity, DeclInfo *decl_
 
 
 	array_init(&p->blocks, heap_allocator());
 	array_init(&p->blocks, heap_allocator());
 	array_init(&p->defer_stmts, heap_allocator());
 	array_init(&p->defer_stmts, heap_allocator());
-	map_ssa_value_init(&p->values, heap_allocator());
+	map_init(&p->values, heap_allocator());
 
 
 	return p;
 	return p;
 }
 }
@@ -597,14 +593,14 @@ ssaAddr ssa_add_local(ssaProc *p, Entity *e, AstNode *expr) {
 	ssaValue *local = ssa_new_value0(p, ssaOp_Local, t);
 	ssaValue *local = ssa_new_value0(p, ssaOp_Local, t);
 	p->curr_block = cb;
 	p->curr_block = cb;
 
 
-	map_ssa_value_set(&p->values,         hash_pointer(e), local);
-	map_ssa_value_set(&p->module->values, hash_pointer(e), local);
+	map_set(&p->values,         hash_pointer(e), local);
+	map_set(&p->module->values, hash_pointer(e), local);
 	local->comment_string = e->token.string;
 	local->comment_string = e->token.string;
 	ssa_new_value1(p, ssaOp_Zero, t, local);
 	ssa_new_value1(p, ssaOp_Zero, t, local);
 	return ssa_addr(local);
 	return ssa_addr(local);
 }
 }
 ssaAddr ssa_add_local_for_ident(ssaProc *p, AstNode *name) {
 ssaAddr ssa_add_local_for_ident(ssaProc *p, AstNode *name) {
-	Entity **found = map_entity_get(&p->module->info->definitions, hash_pointer(name));
+	Entity **found = map_get(&p->module->info->definitions, hash_pointer(name));
 	if (found) {
 	if (found) {
 		Entity *e = *found;
 		Entity *e = *found;
 		return ssa_add_local(p, e, name);
 		return ssa_add_local(p, e, name);
@@ -710,7 +706,7 @@ ssaValue *ssa_get_using_variable(ssaProc *p, Entity *e) {
 	Entity *parent = e->using_parent;
 	Entity *parent = e->using_parent;
 	Selection sel = lookup_field(p->allocator, parent->type, name, false);
 	Selection sel = lookup_field(p->allocator, parent->type, name, false);
 	GB_ASSERT(sel.entity != NULL);
 	GB_ASSERT(sel.entity != NULL);
-	ssaValue **pv = map_ssa_value_get(&p->module->values, hash_pointer(parent));
+	ssaValue **pv = map_get(&p->module->values, hash_pointer(parent));
 	ssaValue *v = NULL;
 	ssaValue *v = NULL;
 	if (pv != NULL) {
 	if (pv != NULL) {
 		v = *pv;
 		v = *pv;
@@ -726,7 +722,7 @@ ssaAddr ssa_build_addr_from_entity(ssaProc *p, Entity *e, AstNode *expr) {
 	GB_ASSERT(e != NULL);
 	GB_ASSERT(e != NULL);
 
 
 	ssaValue *v = NULL;
 	ssaValue *v = NULL;
-	ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
+	ssaValue **found = map_get(&p->module->values, hash_pointer(e));
 	if (found) {
 	if (found) {
 		v = *found;
 		v = *found;
 	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
 	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
@@ -1690,7 +1686,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
 	case_end;
 	case_end;
 
 
 	case_ast_node(i, Ident, expr);
 	case_ast_node(i, Ident, expr);
-		Entity *e = *map_entity_get(&p->module->info->uses, hash_pointer(expr));
+		Entity *e = *map_get(&p->module->info->uses, hash_pointer(expr));
 		if (e->kind == Entity_Builtin) {
 		if (e->kind == Entity_Builtin) {
 			Token token = ast_node_token(expr);
 			Token token = ast_node_token(expr);
 			GB_PANIC("TODO(bill): ssa_build_expr Entity_Builtin `%.*s`\n"
 			GB_PANIC("TODO(bill): ssa_build_expr Entity_Builtin `%.*s`\n"
@@ -1702,7 +1698,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
 			return NULL;
 			return NULL;
 		}
 		}
 
 
-		ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
+		ssaValue **found = map_get(&p->module->values, hash_pointer(e));
 		if (found) {
 		if (found) {
 			ssaValue *v = *found;
 			ssaValue *v = *found;
 			if (v->op == ssaOp_Proc) {
 			if (v->op == ssaOp_Proc) {
@@ -1840,7 +1836,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
 
 
 
 
 	case_ast_node(ce, CallExpr, expr);
 	case_ast_node(ce, CallExpr, expr);
-		if (map_tav_get(&p->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
+		if (map_get(&p->module->info->types, hash_pointer(ce->proc))->mode == Addressing_Type) {
 			GB_ASSERT(ce->args.count == 1);
 			GB_ASSERT(ce->args.count == 1);
 			ssaValue *x = ssa_build_expr(p, ce->args[0]);
 			ssaValue *x = ssa_build_expr(p, ce->args[0]);
 			return ssa_emit_conv(p, x, tv.type);
 			return ssa_emit_conv(p, x, tv.type);
@@ -2484,7 +2480,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
 		m.tmp_allocator = gb_arena_allocator(&m.tmp_arena);
 		m.tmp_allocator = gb_arena_allocator(&m.tmp_arena);
 		m.allocator     = gb_arena_allocator(&m.arena);
 		m.allocator     = gb_arena_allocator(&m.arena);
 
 
-		map_ssa_value_init(&m.values,    heap_allocator());
+		map_init(&m.values,    heap_allocator());
 		array_init(&m.registers,         heap_allocator());
 		array_init(&m.registers,         heap_allocator());
 		array_init(&m.procs,             heap_allocator());
 		array_init(&m.procs,             heap_allocator());
 		array_init(&m.procs_to_generate, heap_allocator());
 		array_init(&m.procs_to_generate, heap_allocator());
@@ -2496,7 +2492,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
 	bool has_win_main = false;
 	bool has_win_main = false;
 
 
 	for_array(i, info->entities.entries) {
 	for_array(i, info->entities.entries) {
-		MapDeclInfoEntry *entry = &info->entities.entries[i];
+		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		String name = e->token.string;
 		String name = e->token.string;
 		if (e->kind == Entity_Variable) {
 		if (e->kind == Entity_Variable) {
@@ -2522,7 +2518,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
 	m.min_dep_map = generate_minimum_dependency_map(info, entry_point);
 	m.min_dep_map = generate_minimum_dependency_map(info, entry_point);
 
 
 	for_array(i, info->entities.entries) {
 	for_array(i, info->entities.entries) {
-		MapDeclInfoEntry *entry = &info->entities.entries[i];
+		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)entry->key.ptr;
 		Entity *e = cast(Entity *)entry->key.ptr;
 		String name = e->token.string;
 		String name = e->token.string;
 		DeclInfo *decl = entry->value;
 		DeclInfo *decl = entry->value;
@@ -2532,7 +2528,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
 			continue;
 			continue;
 		}
 		}
 
 
-		if (map_entity_get(&m.min_dep_map, hash_pointer(e)) == NULL) {
+		if (map_get(&m.min_dep_map, hash_pointer(e)) == NULL) {
 			// NOTE(bill): Nothing depends upon it so doesn't need to be built
 			// NOTE(bill): Nothing depends upon it so doesn't need to be built
 			continue;
 			continue;
 		}
 		}
@@ -2579,8 +2575,8 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) {
 
 
 			// ssa_module_add_value(m, e, p);
 			// ssa_module_add_value(m, e, p);
 			// HashKey hash_name = hash_string(name);
 			// HashKey hash_name = hash_string(name);
-			// if (map_ssa_value_get(&m.members, hash_name) == NULL) {
-				// map_ssa_value_set(&m.members, hash_name, p);
+			// if (map_get(&m.members, hash_name) == NULL) {
+				// map_set(&m.members, hash_name, p);
 			// }
 			// }
 		} break;
 		} break;
 		}
 		}
@@ -2600,7 +2596,7 @@ String ssa_mangle_name(ssaModule *m, String path, Entity *e) {
 	String name = e->token.string;
 	String name = e->token.string;
 	CheckerInfo *info = m->info;
 	CheckerInfo *info = m->info;
 	gbAllocator a = m->allocator;
 	gbAllocator a = m->allocator;
-	AstFile *file = *map_ast_file_get(&info->files, hash_string(path));
+	AstFile *file = *map_get(&info->files, hash_string(path));
 
 
 	char *str = gb_alloc_array(a, char, path.len+1);
 	char *str = gb_alloc_array(a, char, path.len+1);
 	gb_memmove(str, path.text, path.len);
 	gb_memmove(str, path.text, path.len);