Browse Source

Replace compiler for loops for the hash-table types to simplify code usage

gingerBill 2 years ago
parent
commit
34a048f7da

+ 7 - 4
src/build_settings.cpp

@@ -1328,23 +1328,26 @@ void enable_target_feature(TokenPos pos, String const &target_feature_list) {
 
 
 char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) {
 char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quotes) {
 	isize len = 0;
 	isize len = 0;
-	for_array(i, build_context.target_features_set.entries) {
+	isize i = 0;
+	for (auto const &entry : build_context.target_features_set) {
 		if (i != 0) {
 		if (i != 0) {
 			len += 1;
 			len += 1;
 		}
 		}
-		String feature = build_context.target_features_set.entries[i].value;
+		String feature = entry.value;
 		len += feature.len;
 		len += feature.len;
 		if (with_quotes) len += 2;
 		if (with_quotes) len += 2;
+		i += 1;
 	}
 	}
 	char *features = gb_alloc_array(allocator, char, len+1);
 	char *features = gb_alloc_array(allocator, char, len+1);
 	len = 0;
 	len = 0;
-	for_array(i, build_context.target_features_set.entries) {
+	i = 0;
+	for (auto const &entry : build_context.target_features_set) {
 		if (i != 0) {
 		if (i != 0) {
 			features[len++] = ',';
 			features[len++] = ',';
 		}
 		}
 
 
 		if (with_quotes) features[len++] = '"';
 		if (with_quotes) features[len++] = '"';
-		String feature = build_context.target_features_set.entries[i].value;
+		String feature = entry.value;
 		gb_memmove(features + len, feature.text, feature.len);
 		gb_memmove(features + len, feature.text, feature.len);
 		len += feature.len;
 		len += feature.len;
 		if (with_quotes) features[len++] = '"';
 		if (with_quotes) features[len++] = '"';

+ 2 - 3
src/check_builtin.cpp

@@ -3455,9 +3455,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 			error(ce->args[0], "Expected a constant string for '%.*s'", LIT(builtin_name));
 			error(ce->args[0], "Expected a constant string for '%.*s'", LIT(builtin_name));
 		} else if (operand->value.kind == ExactValue_String) {
 		} else if (operand->value.kind == ExactValue_String) {
 			String pkg_name = operand->value.value_string;
 			String pkg_name = operand->value.value_string;
-			// TODO(bill): probably should have this be a `StringMap` eventually
-			for_array(i, c->info->packages.entries) {
-				AstPackage *pkg = c->info->packages.entries[i].value;
+			for (auto const &entry : c->info->packages) {
+				AstPackage *pkg = entry.value;
 				if (pkg->name == pkg_name) {
 				if (pkg->name == pkg_name) {
 					value = true;
 					value = true;
 					break;
 					break;

+ 6 - 6
src/check_decl.cpp

@@ -1499,8 +1499,8 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
 				if (t->kind == Type_Struct) {
 				if (t->kind == Type_Struct) {
 					Scope *scope = t->Struct.scope;
 					Scope *scope = t->Struct.scope;
 					GB_ASSERT(scope != nullptr);
 					GB_ASSERT(scope != nullptr);
-					MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
-						Entity *f = scope->elements.entries[i].value;
+					MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) {
+						Entity *f = entry.value;
 						if (f->kind == Entity_Variable) {
 						if (f->kind == Entity_Variable) {
 							Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
 							Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
 							if (is_value) uvar->flags |= EntityFlag_Value;
 							if (is_value) uvar->flags |= EntityFlag_Value;
@@ -1599,12 +1599,12 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
 
 
 			// NOTE(bill): Add the dependencies from the procedure literal (lambda)
 			// NOTE(bill): Add the dependencies from the procedure literal (lambda)
 			// But only at the procedure level
 			// But only at the procedure level
-			for_array(i, decl->deps.entries) {
-				Entity *e = decl->deps.entries[i].ptr;
+			for (auto const &entry : decl->deps) {
+				Entity *e = entry.ptr;
 				ptr_set_add(&decl->parent->deps, e);
 				ptr_set_add(&decl->parent->deps, e);
 			}
 			}
-			for_array(i, decl->type_info_deps.entries) {
-				Type *t = decl->type_info_deps.entries[i].ptr;
+			for (auto const &entry : decl->type_info_deps) {
+				Type *t = entry.ptr;
 				ptr_set_add(&decl->parent->type_info_deps, t);
 				ptr_set_add(&decl->parent->type_info_deps, t);
 			}
 			}
 
 

+ 11 - 14
src/check_expr.cpp

@@ -205,8 +205,8 @@ void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type,
 
 
 	DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), set.entries.count, name);
 	DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), set.entries.count, name);
 	defer (did_you_mean_destroy(&d));
 	defer (did_you_mean_destroy(&d));
-	for_array(i, set.entries) {
-		did_you_mean_append(&d, set.entries[i].value);
+	for (auto const &entry : set) {
+		did_you_mean_append(&d, entry.value);
 	}
 	}
 	check_did_you_mean_print(&d, prefix);
 	check_did_you_mean_print(&d, prefix);
 }
 }
@@ -242,12 +242,10 @@ void check_did_you_mean_scope(String const &name, Scope *scope, char const *pref
 	DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
 	DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name);
 	defer (did_you_mean_destroy(&d));
 	defer (did_you_mean_destroy(&d));
 
 
-	mutex_lock(&scope->mutex);
-	for_array(i, scope->elements.entries) {
-		Entity *e = scope->elements.entries[i].value;
+	MUTEX_GUARD_BLOCK(&scope->mutex) for (auto const &entry : scope->elements) {
+		Entity *e = entry.value;
 		did_you_mean_append(&d, e->token.string);
 		did_you_mean_append(&d, e->token.string);
 	}
 	}
-	mutex_unlock(&scope->mutex);
 	check_did_you_mean_print(&d, prefix);
 	check_did_you_mean_print(&d, prefix);
 }
 }
 
 
@@ -322,8 +320,8 @@ void check_scope_decls(CheckerContext *c, Slice<Ast *> const &nodes, isize reser
 
 
 	check_collect_entities(c, nodes);
 	check_collect_entities(c, nodes);
 
 
-	for_array(i, s->elements.entries) {
-		Entity *e = s->elements.entries[i].value;
+	for (auto const &entry : s->elements) {
+		Entity *e = entry.value;
 		switch (e->kind) {
 		switch (e->kind) {
 		case Entity_Constant:
 		case Entity_Constant:
 		case Entity_TypeName:
 		case Entity_TypeName:
@@ -4918,8 +4916,8 @@ isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs
 			if (e != nullptr) {
 			if (e != nullptr) {
 				DeclInfo *decl = decl_info_of_entity(e);
 				DeclInfo *decl = decl_info_of_entity(e);
 				if (decl != nullptr) {
 				if (decl != nullptr) {
-					for_array(k, decl->deps.entries) {
-						Entity *dep = decl->deps.entries[k].ptr;
+					for (auto const &entry : decl->deps) {
+						Entity *dep = entry.ptr;
 						ptr_set_add(&c->decl->deps, dep);
 						ptr_set_add(&c->decl->deps, dep);
 					}
 					}
 				}
 				}
@@ -5671,8 +5669,7 @@ Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize
 
 
 bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice<Ast *> *clauses, bool print_err) {
 bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice<Ast *> *clauses, bool print_err) {
 	if (clauses != nullptr) {
 	if (clauses != nullptr) {
-		for_array(i, *clauses) {
-			Ast *clause = (*clauses)[i];
+		for (Ast *clause : *clauses) {
 			Operand o = {};
 			Operand o = {};
 			check_expr(ctx, &o, clause);
 			check_expr(ctx, &o, clause);
 			if (o.mode != Addressing_Constant) {
 			if (o.mode != Addressing_Constant) {
@@ -5693,8 +5690,8 @@ bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, S
 
 
 					if (scope != nullptr) {
 					if (scope != nullptr) {
 						isize print_count = 0;
 						isize print_count = 0;
-						for_array(j, scope->elements.entries) {
-							Entity *e = scope->elements.entries[j].value;
+						for (auto const &entry : scope->elements) {
+							Entity *e = entry.value;
 							switch (e->kind) {
 							switch (e->kind) {
 							case Entity_TypeName: {
 							case Entity_TypeName: {
 								if (print_count == 0) error_line("\n\tWith the following definitions:\n");
 								if (print_count == 0) error_line("\n\tWith the following definitions:\n");

+ 7 - 7
src/check_stmt.cpp

@@ -622,9 +622,9 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b
 
 
 	case Entity_ImportName: {
 	case Entity_ImportName: {
 		Scope *scope = e->ImportName.scope;
 		Scope *scope = e->ImportName.scope;
-		MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
-			String name = scope->elements.entries[i].key.string;
-			Entity *decl = scope->elements.entries[i].value;
+		MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) {
+			String name = entry.key.string;
+			Entity *decl = entry.value;
 			if (!is_entity_exported(decl)) continue;
 			if (!is_entity_exported(decl)) continue;
 
 
 			Entity *found = scope_insert_with_name(ctx->scope, name, decl);
 			Entity *found = scope_insert_with_name(ctx->scope, name, decl);
@@ -652,8 +652,8 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b
 		if (t->kind == Type_Struct) {
 		if (t->kind == Type_Struct) {
 			Scope *found = t->Struct.scope;
 			Scope *found = t->Struct.scope;
 			GB_ASSERT(found != nullptr);
 			GB_ASSERT(found != nullptr);
-			for_array(i, found->elements.entries) {
-				Entity *f = found->elements.entries[i].value;
+			for (auto const &entry : found->elements) {
+				Entity *f = entry.value;
 				if (f->kind == Entity_Variable) {
 				if (f->kind == Entity_Variable) {
 					Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, expr);
 					Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, expr);
 					if (!is_ptr && e->flags & EntityFlag_Value) uvar->flags |= EntityFlag_Value;
 					if (!is_ptr && e->flags & EntityFlag_Value) uvar->flags |= EntityFlag_Value;
@@ -2370,8 +2370,8 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 						
 						
 						Scope *scope = t->Struct.scope;
 						Scope *scope = t->Struct.scope;
 						GB_ASSERT(scope != nullptr);
 						GB_ASSERT(scope != nullptr);
-						for_array(i, scope->elements.entries) {
-							Entity *f = scope->elements.entries[i].value;
+						for (auto const &entry : scope->elements) {
+							Entity *f = entry.value;
 							if (f->kind == Entity_Variable) {
 							if (f->kind == Entity_Variable) {
 								Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
 								Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr);
 								uvar->flags |= (e->flags & EntityFlag_Value);
 								uvar->flags |= (e->flags & EntityFlag_Value);

+ 2 - 2
src/check_type.cpp

@@ -1791,8 +1791,8 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
 
 
 	isize specialization_count = 0;
 	isize specialization_count = 0;
 	if (scope != nullptr) {
 	if (scope != nullptr) {
-		for_array(i, scope->elements.entries) {
-			Entity *e = scope->elements.entries[i].value;
+		for (auto const &entry : scope->elements) {
+			Entity *e = entry.value;
 			if (e->kind == Entity_TypeName) {
 			if (e->kind == Entity_TypeName) {
 				Type *t = e->type;
 				Type *t = e->type;
 				if (t->kind == Type_Generic &&
 				if (t->kind == Type_Generic &&

+ 65 - 69
src/checker.cpp

@@ -308,8 +308,8 @@ Scope *create_scope_from_package(CheckerContext *c, AstPackage *pkg) {
 }
 }
 
 
 void destroy_scope(Scope *scope) {
 void destroy_scope(Scope *scope) {
-	for_array(i, scope->elements.entries) {
-		Entity *e =scope->elements.entries[i].value;
+	for (auto const &entry : scope->elements) {
+		Entity *e = entry.value;
 		if (e->kind == Entity_Variable) {
 		if (e->kind == Entity_Variable) {
 			if (!(e->flags & EntityFlag_Used)) {
 			if (!(e->flags & EntityFlag_Used)) {
 #if 0
 #if 0
@@ -659,8 +659,8 @@ void check_scope_usage(Checker *c, Scope *scope) {
 	Array<VettedEntity> vetted_entities = {};
 	Array<VettedEntity> vetted_entities = {};
 	array_init(&vetted_entities, heap_allocator());
 	array_init(&vetted_entities, heap_allocator());
 
 
-	MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) {
-		Entity *e = scope->elements.entries[i].value;
+	MUTEX_GUARD_BLOCK(scope->mutex) for (auto const &entry : scope->elements) {
+		Entity *e = entry.value;
 		if (e == nullptr) continue;
 		if (e == nullptr) continue;
 		VettedEntity ve_unused = {};
 		VettedEntity ve_unused = {};
 		VettedEntity ve_shadowed = {};
 		VettedEntity ve_shadowed = {};
@@ -755,9 +755,8 @@ AstPackage *get_core_package(CheckerInfo *info, String name) {
 		gb_printf_err("Name: %.*s\n", LIT(name));
 		gb_printf_err("Name: %.*s\n", LIT(name));
 		gb_printf_err("Fullpath: %.*s\n", LIT(path));
 		gb_printf_err("Fullpath: %.*s\n", LIT(path));
 		
 		
-		for_array(i, info->packages.entries) {
-			auto *entry = &info->packages.entries[i];
-			gb_printf_err("%.*s\n", LIT(entry->key.string));
+		for (auto const &entry : info->packages) {
+			gb_printf_err("%.*s\n", LIT(entry.key.string));
 		}
 		}
 		GB_ASSERT_MSG(found != nullptr, "Missing core package %.*s", LIT(name));
 		GB_ASSERT_MSG(found != nullptr, "Missing core package %.*s", LIT(name));
 	}
 	}
@@ -1065,9 +1064,9 @@ void init_universal(void) {
 	}
 	}
 
 
 	bool defined_values_double_declaration = false;
 	bool defined_values_double_declaration = false;
-	for_array(i, bc->defined_values.entries) {
-		char const *name = bc->defined_values.entries[i].key;
-		ExactValue value = bc->defined_values.entries[i].value;
+	for (auto const &entry : bc->defined_values) {
+		char const *name = entry.key;
+		ExactValue value = entry.value;
 		GB_ASSERT(value.kind != ExactValue_Invalid);
 		GB_ASSERT(value.kind != ExactValue_Invalid);
 
 
 		Type *type = nullptr;
 		Type *type = nullptr;
@@ -1418,10 +1417,9 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
 	if (entry_index < 0) {
 	if (entry_index < 0) {
 		// 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){
-			auto *e = &info->type_info_map.entries[i];
-			if (are_types_identical_unique_tuples(e->key, type)) {
-				entry_index = e->value;
+		for (auto const &e : info->type_info_map) {
+			if (are_types_identical_unique_tuples(e.key, type)) {
+				entry_index = e.value;
 				// NOTE(bill): Add it to the search map
 				// NOTE(bill): Add it to the search map
 				map_set(&info->type_info_map, type, entry_index);
 				map_set(&info->type_info_map, type, entry_index);
 				break;
 				break;
@@ -1781,11 +1779,10 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) {
 
 
 	bool prev = false;
 	bool prev = false;
 	isize ti_index = -1;
 	isize ti_index = -1;
-	for_array(i, c->info->type_info_map.entries) {
-		auto *e = &c->info->type_info_map.entries[i];
-		if (are_types_identical_unique_tuples(t, e->key)) {
+	for (auto const &e : c->info->type_info_map) {
+		if (are_types_identical_unique_tuples(t, e.key)) {
 			// Duplicate entry
 			// Duplicate entry
-			ti_index = e->value;
+			ti_index = e.value;
 			prev = true;
 			prev = true;
 			break;
 			break;
 		}
 		}
@@ -1908,8 +1905,8 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) {
 
 
 	case Type_Struct:
 	case Type_Struct:
 		if (bt->Struct.scope != nullptr) {
 		if (bt->Struct.scope != nullptr) {
-			for_array(i, bt->Struct.scope->elements.entries) {
-				Entity *e = bt->Struct.scope->elements.entries[i].value;
+			for (auto const &entry : bt->Struct.scope->elements) {
+				Entity *e = entry.value;
 				switch (bt->Struct.soa_kind) {
 				switch (bt->Struct.soa_kind) {
 				case StructSoa_Dynamic:
 				case StructSoa_Dynamic:
 					add_type_info_type_internal(c, t_allocator);
 					add_type_info_type_internal(c, t_allocator);
@@ -2132,8 +2129,8 @@ void add_min_dep_type_info(Checker *c, Type *t) {
 
 
 	case Type_Struct:
 	case Type_Struct:
 		if (bt->Struct.scope != nullptr) {
 		if (bt->Struct.scope != nullptr) {
-			for_array(i, bt->Struct.scope->elements.entries) {
-				Entity *e = bt->Struct.scope->elements.entries[i].value;
+			for (auto const &entry : bt->Struct.scope->elements) {
+				Entity *e = entry.value;
 				switch (bt->Struct.soa_kind) {
 				switch (bt->Struct.soa_kind) {
 				case StructSoa_Dynamic:
 				case StructSoa_Dynamic:
 					add_min_dep_type_info(c, t_allocator);
 					add_min_dep_type_info(c, t_allocator);
@@ -2230,13 +2227,12 @@ void add_dependency_to_set(Checker *c, Entity *entity) {
 		return;
 		return;
 	}
 	}
 
 
-	for_array(i, decl->type_info_deps.entries) {
-		Type *type = decl->type_info_deps.entries[i].ptr;
-		add_min_dep_type_info(c, type);
+	for (auto const &entry : decl->type_info_deps) {
+		add_min_dep_type_info(c, entry.ptr);
 	}
 	}
 
 
-	for_array(i, decl->deps.entries) {
-		Entity *e = decl->deps.entries[i].ptr;
+	for (auto const &entry : decl->deps) {
+		Entity *e = entry.ptr;
 		add_dependency_to_set(c, e);
 		add_dependency_to_set(c, e);
 		if (e->kind == Entity_Procedure && e->Procedure.is_foreign) {
 		if (e->kind == Entity_Procedure && e->Procedure.is_foreign) {
 			Entity *fl = e->Procedure.foreign_library;
 			Entity *fl = e->Procedure.foreign_library;
@@ -2430,8 +2426,8 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
 		Scope *testing_scope = testing_package->scope;
 		Scope *testing_scope = testing_package->scope;
 
 
 		// Add all of testing library as a dependency
 		// Add all of testing library as a dependency
-		for_array(i, testing_scope->elements.entries) {
-			Entity *e = testing_scope->elements.entries[i].value;
+		for (auto const &entry : testing_scope->elements) {
+			Entity *e = entry.value;
 			if (e != nullptr) {
 			if (e != nullptr) {
 				e->flags |= EntityFlag_Used;
 				e->flags |= EntityFlag_Used;
 				add_dependency_to_set(c, e);
 				add_dependency_to_set(c, e);
@@ -2445,8 +2441,8 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
 		AstPackage *pkg = c->info.init_package;
 		AstPackage *pkg = c->info.init_package;
 		Scope *s = pkg->scope;
 		Scope *s = pkg->scope;
 
 
-		for_array(i, s->elements.entries) {
-			Entity *e = s->elements.entries[i].value;
+		for (auto const &entry : s->elements) {
+			Entity *e = entry.value;
 			if (e->kind != Entity_Procedure) {
 			if (e->kind != Entity_Procedure) {
 				continue;
 				continue;
 			}
 			}
@@ -2512,15 +2508,15 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info, gbA
 
 
 	TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
 	TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
 	// Calculate edges for graph M
 	// Calculate edges for graph M
-	for_array(i, M.entries) {
-		EntityGraphNode *n = M.entries[i].value;
+	for (auto const &entry : M) {
+		EntityGraphNode *n = entry.value;
 		Entity *e = n->entity;
 		Entity *e = n->entity;
 
 
 		DeclInfo *decl = decl_info_of_entity(e);
 		DeclInfo *decl = decl_info_of_entity(e);
 		GB_ASSERT(decl != nullptr);
 		GB_ASSERT(decl != nullptr);
 
 
-		for_array(j, decl->deps.entries) {
-			Entity *dep = decl->deps.entries[j].ptr;
+		for (auto const &entry : decl->deps) {
+			Entity *dep = entry.ptr;
 			if (dep->flags & EntityFlag_Field) {
 			if (dep->flags & EntityFlag_Field) {
 				continue;
 				continue;
 			}
 			}
@@ -2539,23 +2535,22 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info, gbA
 	TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2");
 	TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2");
 	auto G = array_make<EntityGraphNode *>(allocator, 0, M.entries.count);
 	auto G = array_make<EntityGraphNode *>(allocator, 0, M.entries.count);
 
 
-	for_array(i, M.entries) {
-		auto *entry = &M.entries[i];
-		auto *e = entry->key;
-		EntityGraphNode *n = entry->value;
+	for (auto const &m_entry : M) {
+		auto *e = m_entry.key;
+		EntityGraphNode *n = m_entry.value;
 
 
 		if (e->kind == Entity_Procedure) {
 		if (e->kind == Entity_Procedure) {
 			// Connect each pred 'p' of 'n' with each succ 's' and from
 			// Connect each pred 'p' of 'n' with each succ 's' and from
 			// the procedure node
 			// the procedure node
-			for_array(j, n->pred.entries) {
-				EntityGraphNode *p = n->pred.entries[j].ptr;
+			for (auto const &p_entry : n->pred) {
+				EntityGraphNode *p = p_entry.ptr;
 
 
 				// Ignore self-cycles
 				// Ignore self-cycles
 				if (p != n) {
 				if (p != n) {
 					// Each succ 's' of 'n' becomes a succ of 'p', and
 					// Each succ 's' of 'n' becomes a succ of 'p', and
 					// each pred 'p' of 'n' becomes a pred of 's'
 					// each pred 'p' of 'n' becomes a pred of 's'
-					for_array(k, n->succ.entries) {
-						EntityGraphNode *s = n->succ.entries[k].ptr;
+					for (auto const &s_entry : n->succ) {
+						EntityGraphNode *s = s_entry.ptr;
 						// Ignore self-cycles
 						// Ignore self-cycles
 						if (s != n) {
 						if (s != n) {
 							if (p->entity->kind == Entity_Procedure &&
 							if (p->entity->kind == Entity_Procedure &&
@@ -4273,9 +4268,10 @@ Array<ImportGraphNode *> generate_import_dependency_graph(Checker *c) {
 	Array<ImportGraphNode *> G = {};
 	Array<ImportGraphNode *> G = {};
 	array_init(&G, heap_allocator(), 0, M.entries.count);
 	array_init(&G, heap_allocator(), 0, M.entries.count);
 
 
-	for_array(i, M.entries) {
-		auto n = M.entries[i].value;
-		n->index = i;
+	isize i = 0;
+	for (auto const &entry : M) {
+		auto n = entry.value;
+		n->index = i++;
 		n->dep_count = n->succ.entries.count;
 		n->dep_count = n->succ.entries.count;
 		GB_ASSERT(n->dep_count >= 0);
 		GB_ASSERT(n->dep_count >= 0);
 		array_add(&G, n);
 		array_add(&G, n);
@@ -4376,8 +4372,8 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
 	} else {
 	} else {
 		AstPackage **found = string_map_get(pkgs, id->fullpath);
 		AstPackage **found = string_map_get(pkgs, id->fullpath);
 		if (found == nullptr) {
 		if (found == nullptr) {
-			for_array(pkg_index, pkgs->entries) {
-				AstPackage *pkg = pkgs->entries[pkg_index].value;
+			for (auto const &entry : *pkgs) {
+				AstPackage *pkg = entry.value;
 				gb_printf_err("%.*s\n", LIT(pkg->fullpath));
 				gb_printf_err("%.*s\n", LIT(pkg->fullpath));
 			}
 			}
 			gb_printf_err("%s\n", token_pos_to_string(token.pos));
 			gb_printf_err("%s\n", token_pos_to_string(token.pos));
@@ -4871,8 +4867,8 @@ void check_import_entities(Checker *c) {
 			}
 			}
 		}
 		}
 
 
-		for_array(i, n->pred.entries) {
-			ImportGraphNode *p = n->pred.entries[i].ptr;
+		for (auto const &entry : n->pred) {
+			ImportGraphNode *p = entry.ptr;
 			p->dep_count = gb_max(p->dep_count-1, 0);
 			p->dep_count = gb_max(p->dep_count-1, 0);
 			priority_queue_fix(&pq, p->index);
 			priority_queue_fix(&pq, p->index);
 		}
 		}
@@ -4979,8 +4975,8 @@ bool find_entity_path_tuple(Type *tuple, Entity *end, PtrSet<Entity *> *visited,
 		if (var_decl == nullptr) {
 		if (var_decl == nullptr) {
 			continue;
 			continue;
 		}
 		}
-		for_array(i, var_decl->deps.entries) {
-			Entity *dep = var_decl->deps.entries[i].ptr;
+		for (auto const &entry : var_decl->deps) {
+			Entity *dep = entry.ptr;
 			if (dep == end) {
 			if (dep == end) {
 				auto path = array_make<Entity *>(heap_allocator());
 				auto path = array_make<Entity *>(heap_allocator());
 				array_add(&path, dep);
 				array_add(&path, dep);
@@ -5032,8 +5028,8 @@ Array<Entity *> find_entity_path(Entity *start, Entity *end, PtrSet<Entity *> *v
 				return path;
 				return path;
 			}
 			}
 		} else {
 		} else {
-			for_array(i, decl->deps.entries) {
-				Entity *dep = decl->deps.entries[i].ptr;
+			for (auto const &entry : decl->deps) {
+				Entity *dep = entry.ptr;
 				if (dep == end) {
 				if (dep == end) {
 					auto path = array_make<Entity *>(heap_allocator());
 					auto path = array_make<Entity *>(heap_allocator());
 					array_add(&path, dep);
 					array_add(&path, dep);
@@ -5091,8 +5087,8 @@ void calculate_global_init_order(Checker *c) {
 			}
 			}
 		}
 		}
 
 
-		for_array(i, n->pred.entries) {
-			EntityGraphNode *p = n->pred.entries[i].ptr;
+		for (auto const &entry : n->pred) {
+			EntityGraphNode *p = entry.ptr;
 			p->dep_count -= 1;
 			p->dep_count -= 1;
 			p->dep_count = gb_max(p->dep_count, 0);
 			p->dep_count = gb_max(p->dep_count, 0);
 			priority_queue_fix(&pq, p->index);
 			priority_queue_fix(&pq, p->index);
@@ -5217,8 +5213,8 @@ void check_unchecked_bodies(Checker *c) {
 	map_init(&untyped, heap_allocator());
 	map_init(&untyped, heap_allocator());
 	defer (map_destroy(&untyped));
 	defer (map_destroy(&untyped));
 
 
-	for_array(i, c->info.minimum_dependency_set.entries) {
-		Entity *e = c->info.minimum_dependency_set.entries[i].ptr;
+	for (auto const &entry : c->info.minimum_dependency_set) {
+		Entity *e = entry.ptr;
 		if (e == nullptr || e->kind != Entity_Procedure) {
 		if (e == nullptr || e->kind != Entity_Procedure) {
 			continue;
 			continue;
 		}
 		}
@@ -5267,8 +5263,8 @@ void check_test_procedures(Checker *c) {
 	AstPackage *pkg = c->info.init_package;
 	AstPackage *pkg = c->info.init_package;
 	Scope *s = pkg->scope;
 	Scope *s = pkg->scope;
 
 
-	for_array(i, build_context.test_names.entries) {
-		String name = build_context.test_names.entries[i].value;
+	for (auto const &entry : build_context.test_names) {
+		String name = entry.value;
 		Entity *e = scope_lookup(s, name);
 		Entity *e = scope_lookup(s, name);
 		if (e == nullptr) {
 		if (e == nullptr) {
 			Token tok = {};
 			Token tok = {};
@@ -5422,9 +5418,9 @@ void add_untyped_expressions(CheckerInfo *cinfo, UntypedExprInfoMap *untyped) {
 	if (untyped == nullptr) {
 	if (untyped == nullptr) {
 		return;
 		return;
 	}
 	}
-	for_array(i, untyped->entries) {
-		Ast *expr = untyped->entries[i].key;
-		ExprInfo *info = untyped->entries[i].value;
+	for (auto const &entry : *untyped) {
+		Ast *expr = entry.key;
+		ExprInfo *info = entry.value;
 		if (expr != nullptr && info != nullptr) {
 		if (expr != nullptr && info != nullptr) {
 			mpmc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info});
 			mpmc_enqueue(&cinfo->checker->global_untyped_queue, UntypedExprInfo{expr, info});
 		}
 		}
@@ -5590,8 +5586,8 @@ void check_unique_package_names(Checker *c) {
 	string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count);
 	string_map_init(&pkgs, heap_allocator(), 2*c->info.packages.entries.count);
 	defer (string_map_destroy(&pkgs));
 	defer (string_map_destroy(&pkgs));
 
 
-	for_array(i, c->info.packages.entries) {
-		AstPackage *pkg = c->info.packages.entries[i].value;
+	for (auto const &entry : c->info.packages) {
+		AstPackage *pkg = entry.value;
 		if (pkg->files.count == 0) {
 		if (pkg->files.count == 0) {
 			continue; // Sanity check
 			continue; // Sanity check
 		}
 		}
@@ -5752,8 +5748,8 @@ void check_parsed_files(Checker *c) {
 	check_merge_queues_into_arrays(c);
 	check_merge_queues_into_arrays(c);
 
 
 	TIME_SECTION("check scope usage");
 	TIME_SECTION("check scope usage");
-	for_array(i, c->info.files.entries) {
-		AstFile *f = c->info.files.entries[i].value;
+	for (auto const &entry : c->info.files) {
+		AstFile *f = entry.value;
 		check_scope_usage(c, f->scope);
 		check_scope_usage(c, f->scope);
 	}
 	}
 
 
@@ -5789,8 +5785,8 @@ void check_parsed_files(Checker *c) {
 			DeclInfo *decl = e->decl_info;
 			DeclInfo *decl = e->decl_info;
 			ast_node(pl, ProcLit, decl->proc_lit);
 			ast_node(pl, ProcLit, decl->proc_lit);
 			if (pl->inlining == ProcInlining_inline) {
 			if (pl->inlining == ProcInlining_inline) {
-				for_array(j, decl->deps.entries) {
-					Entity *dep = decl->deps.entries[j].ptr;
+				for (auto const &entry : decl->deps) {
+					Entity *dep = entry.ptr;
 					if (dep == e) {
 					if (dep == e) {
 						error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string));
 						error(e->token, "Cannot inline recursive procedure '%.*s'", LIT(e->token.string));
 						break;
 						break;

+ 4 - 4
src/docs.cpp

@@ -222,8 +222,8 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) {
 	if (pkg->scope != nullptr) {
 	if (pkg->scope != nullptr) {
 		auto entities = array_make<Entity *>(heap_allocator(), 0, pkg->scope->elements.entries.count);
 		auto entities = array_make<Entity *>(heap_allocator(), 0, pkg->scope->elements.entries.count);
 		defer (array_free(&entities));
 		defer (array_free(&entities));
-		for_array(i, pkg->scope->elements.entries) {
-			Entity *e = pkg->scope->elements.entries[i].value;
+		for (auto const &entry : pkg->scope->elements) {
+			Entity *e = entry.value;
 			switch (e->kind) {
 			switch (e->kind) {
 			case Entity_Invalid:
 			case Entity_Invalid:
 			case Entity_Builtin:
 			case Entity_Builtin:
@@ -359,8 +359,8 @@ void generate_documentation(Checker *c) {
 		odin_doc_write(info, output_file_path);
 		odin_doc_write(info, output_file_path);
 	} else {
 	} else {
 		auto pkgs = array_make<AstPackage *>(permanent_allocator(), 0, info->packages.entries.count);
 		auto pkgs = array_make<AstPackage *>(permanent_allocator(), 0, info->packages.entries.count);
-		for_array(i, info->packages.entries) {
-			AstPackage *pkg = info->packages.entries[i].value;
+		for (auto const &entry : info->packages) {
+			AstPackage *pkg = entry.value;
 			if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) {
 			if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) {
 				array_add(&pkgs, pkg);
 				array_add(&pkgs, pkg);
 			} else {
 			} else {

+ 17 - 19
src/docs_writer.cpp

@@ -480,11 +480,11 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
 	}
 	}
-	for_array(i, w->type_cache.entries) {
+	for (auto const &entry : w->type_cache) {
 		// NOTE(bill): THIS IS SLOW
 		// NOTE(bill): THIS IS SLOW
-		Type *other = w->type_cache.entries[i].key;
+		Type *other = entry.key;
 		if (are_types_identical_unique_tuples(type, other)) {
 		if (are_types_identical_unique_tuples(type, other)) {
-			OdinDocTypeIndex index = w->type_cache.entries[i].value;
+			OdinDocTypeIndex index = entry.value;
 			map_set(&w->type_cache, type, index);
 			map_set(&w->type_cache, type, index);
 			return index;
 			return index;
 		}
 		}
@@ -914,23 +914,21 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) {
 void odin_doc_update_entities(OdinDocWriter *w) {
 void odin_doc_update_entities(OdinDocWriter *w) {
 	{
 	{
 		// NOTE(bill): Double pass, just in case entities are created on odin_doc_type
 		// NOTE(bill): Double pass, just in case entities are created on odin_doc_type
-		auto entities = array_make<Entity *>(heap_allocator(), w->entity_cache.entries.count);
+		auto entities = array_make<Entity *>(heap_allocator(), 0, w->entity_cache.entries.count);
 		defer (array_free(&entities));
 		defer (array_free(&entities));
 
 
-		for_array(i, w->entity_cache.entries) {
-			Entity *e = w->entity_cache.entries[i].key;
-			entities[i] = e;
+		for (auto const &entry : w->entity_cache) {
+			array_add(&entities, entry.key);
 		}
 		}
-		for_array(i, entities) {
-			Entity *e = entities[i];
+		for (Entity *e : entities) {
 			OdinDocTypeIndex type_index = odin_doc_type(w, e->type);
 			OdinDocTypeIndex type_index = odin_doc_type(w, e->type);
 			gb_unused(type_index);
 			gb_unused(type_index);
 		}
 		}
 	}
 	}
 
 
-	for_array(i, w->entity_cache.entries) {
-		Entity *e = w->entity_cache.entries[i].key;
-		OdinDocEntityIndex entity_index = w->entity_cache.entries[i].value;
+	for (auto const &entry : w->entity_cache) {
+		Entity *e = entry.key;
+		OdinDocEntityIndex entity_index = entry.value;
 		OdinDocTypeIndex type_index = odin_doc_type(w, e->type);
 		OdinDocTypeIndex type_index = odin_doc_type(w, e->type);
 
 
 		OdinDocEntityIndex foreign_library = 0;
 		OdinDocEntityIndex foreign_library = 0;
@@ -948,8 +946,8 @@ void odin_doc_update_entities(OdinDocWriter *w) {
 				auto pges = array_make<OdinDocEntityIndex>(heap_allocator(), 0, e->ProcGroup.entities.count);
 				auto pges = array_make<OdinDocEntityIndex>(heap_allocator(), 0, e->ProcGroup.entities.count);
 				defer (array_free(&pges));
 				defer (array_free(&pges));
 
 
-				for_array(j, e->ProcGroup.entities) {
-					OdinDocEntityIndex index = odin_doc_add_entity(w, e->ProcGroup.entities[j]);
+				for (Entity *entity : e->ProcGroup.entities) {
+					OdinDocEntityIndex index = odin_doc_add_entity(w, entity);
 					array_add(&pges, index);
 					array_add(&pges, index);
 				}
 				}
 				grouped_entities = odin_write_slice(w, pges.data, pges.count);
 				grouped_entities = odin_write_slice(w, pges.data, pges.count);
@@ -979,9 +977,9 @@ OdinDocArray<OdinDocScopeEntry> odin_doc_add_pkg_entries(OdinDocWriter *w, AstPa
 	auto entries = array_make<OdinDocScopeEntry>(heap_allocator(), 0, w->entity_cache.entries.count);
 	auto entries = array_make<OdinDocScopeEntry>(heap_allocator(), 0, w->entity_cache.entries.count);
 	defer (array_free(&entries));
 	defer (array_free(&entries));
 
 
-	for_array(i, pkg->scope->elements.entries) {
-		String name = pkg->scope->elements.entries[i].key.string;
-		Entity *e = pkg->scope->elements.entries[i].value;
+	for (auto const &entry : pkg->scope->elements) {
+		String name = entry.key.string;
+		Entity *e = entry.value;
 		switch (e->kind) {
 		switch (e->kind) {
 		case Entity_Invalid:
 		case Entity_Invalid:
 		case Entity_Nil:
 		case Entity_Nil:
@@ -1021,8 +1019,8 @@ OdinDocArray<OdinDocScopeEntry> odin_doc_add_pkg_entries(OdinDocWriter *w, AstPa
 void odin_doc_write_docs(OdinDocWriter *w) {
 void odin_doc_write_docs(OdinDocWriter *w) {
 	auto pkgs = array_make<AstPackage *>(heap_allocator(), 0, w->info->packages.entries.count);
 	auto pkgs = array_make<AstPackage *>(heap_allocator(), 0, w->info->packages.entries.count);
 	defer (array_free(&pkgs));
 	defer (array_free(&pkgs));
-	for_array(i, w->info->packages.entries) {
-		AstPackage *pkg = w->info->packages.entries[i].value;
+	for (auto const &entry : w->info->packages) {
+		AstPackage *pkg = entry.value;
 		if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) {
 		if (build_context.cmd_doc_flags & CmdDocFlag_AllPackages) {
 			array_add(&pkgs, pkg);
 			array_add(&pkgs, pkg);
 		} else {
 		} else {

+ 54 - 71
src/llvm_backend.cpp

@@ -1046,16 +1046,14 @@ void lb_finalize_objc_names(lbProcedure *p) {
 
 
 	LLVMSetLinkage(p->value, LLVMInternalLinkage);
 	LLVMSetLinkage(p->value, LLVMInternalLinkage);
 	lb_begin_procedure_body(p);
 	lb_begin_procedure_body(p);
-	for_array(i, m->objc_classes.entries) {
-		auto const &entry = m->objc_classes.entries[i];
+	for (auto const &entry : m->objc_classes) {
 		String name = entry.key.string;
 		String name = entry.key.string;
 		args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
 		args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
 		lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args);
 		lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args);
 		lb_addr_store(p, entry.value, ptr);
 		lb_addr_store(p, entry.value, ptr);
 	}
 	}
 
 
-	for_array(i, m->objc_selectors.entries) {
-		auto const &entry = m->objc_selectors.entries[i];
+	for (auto const &entry : m->objc_selectors) {
 		String name = entry.key.string;
 		String name = entry.key.string;
 		args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
 		args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
 		lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args);
 		lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args);
@@ -1505,20 +1503,20 @@ WORKER_TASK_PROC(lb_llvm_function_pass_worker_proc) {
 		}
 		}
 	}
 	}
 
 
-	for_array(i, m->equal_procs.entries) {
-		lbProcedure *p = m->equal_procs.entries[i].value;
+	for (auto const &entry : m->equal_procs) {
+		lbProcedure *p = entry.value;
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 	}
 	}
-	for_array(i, m->hasher_procs.entries) {
-		lbProcedure *p = m->hasher_procs.entries[i].value;
+	for (auto const &entry : m->hasher_procs) {
+		lbProcedure *p = entry.value;
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 	}
 	}
-	for_array(i, m->map_get_procs.entries) {
-		lbProcedure *p = m->map_get_procs.entries[i].value;
+	for (auto const &entry : m->map_get_procs) {
+		lbProcedure *p = entry.value;
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 	}
 	}
-	for_array(i, m->map_set_procs.entries) {
-		lbProcedure *p = m->map_set_procs.entries[i].value;
+	for (auto const &entry : m->map_set_procs) {
+		lbProcedure *p = entry.value;
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 		lb_run_function_pass_manager(default_function_pass_manager, p);
 	}
 	}
 
 
@@ -1636,8 +1634,8 @@ void lb_generate_code(lbGenerator *gen) {
 	}
 	}
 
 
 	char const *target_triple = alloc_cstring(permanent_allocator(), build_context.metrics.target_triplet);
 	char const *target_triple = alloc_cstring(permanent_allocator(), build_context.metrics.target_triplet);
-	for_array(i, gen->modules.entries) {
-		LLVMSetTarget(gen->modules.entries[i].value->mod, target_triple);
+	for (auto const &entry : gen->modules) {
+		LLVMSetTarget(entry.value->mod, target_triple);
 	}
 	}
 
 
 	LLVMTargetRef target = {};
 	LLVMTargetRef target = {};
@@ -1701,7 +1699,7 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 	// NOTE(bill): Target Machine Creation
 	// NOTE(bill): Target Machine Creation
 	// NOTE(bill, 2021-05-04): Target machines must be unique to each module because they are not thread safe
 	// NOTE(bill, 2021-05-04): Target machines must be unique to each module because they are not thread safe
-	auto target_machines = array_make<LLVMTargetMachineRef>(permanent_allocator(), gen->modules.entries.count);
+	auto target_machines = array_make<LLVMTargetMachineRef>(permanent_allocator(), 0, gen->modules.entries.count);
 
 
 	// NOTE(dweiler): Dynamic libraries require position-independent code.
 	// NOTE(dweiler): Dynamic libraries require position-independent code.
 	LLVMRelocMode reloc_mode = LLVMRelocDefault;
 	LLVMRelocMode reloc_mode = LLVMRelocDefault;
@@ -1727,21 +1725,25 @@ void lb_generate_code(lbGenerator *gen) {
 		break;
 		break;
 	}
 	}
 
 
-	for_array(i, gen->modules.entries) {
-		target_machines[i] = LLVMCreateTargetMachine(
+	for (auto const entry : gen->modules) {
+		auto target_machine = LLVMCreateTargetMachine(
 			target, target_triple, llvm_cpu,
 			target, target_triple, llvm_cpu,
 			llvm_features,
 			llvm_features,
 			code_gen_level,
 			code_gen_level,
 			reloc_mode,
 			reloc_mode,
 			code_mode);
 			code_mode);
-		LLVMSetModuleDataLayout(gen->modules.entries[i].value->mod, LLVMCreateTargetDataLayout(target_machines[i]));
+		array_add(&target_machines, target_machine);
+
+		lbModule *m = entry.value;
+		m->target_machine = target_machine;
+		LLVMSetModuleDataLayout(m->mod, LLVMCreateTargetDataLayout(target_machine));
 	}
 	}
 
 
-	for_array(i, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[i].value;
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
 		if (m->debug_builder) { // Debug Info
 		if (m->debug_builder) { // Debug Info
-			for_array(i, info->files.entries) {
-				AstFile *f = info->files.entries[i].value;
+			for (auto const &file_entry : info->files) {
+				AstFile *f = file_entry.value;
 				String fullpath = f->fullpath;
 				String fullpath = f->fullpath;
 				String filename = remove_directory_from_path(fullpath);
 				String filename = remove_directory_from_path(fullpath);
 				String directory = directory_from_path(fullpath);
 				String directory = directory_from_path(fullpath);
@@ -2060,8 +2062,8 @@ void lb_generate_code(lbGenerator *gen) {
 	gb_unused(startup_runtime);
 	gb_unused(startup_runtime);
 
 
 	if (build_context.ODIN_DEBUG) {
 	if (build_context.ODIN_DEBUG) {
-		for_array(i, builtin_pkg->scope->elements.entries) {
-			Entity *e = builtin_pkg->scope->elements.entries[i].value;
+		for (auto const &entry : builtin_pkg->scope->elements) {
+			Entity *e = entry.value;
 			add_debug_info_for_global_constant_from_entity(gen, e);
 			add_debug_info_for_global_constant_from_entity(gen, e);
 		}
 		}
 	}
 	}
@@ -2130,10 +2132,9 @@ void lb_generate_code(lbGenerator *gen) {
 	}
 	}
 
 
 	TIME_SECTION("LLVM Procedure Generation");
 	TIME_SECTION("LLVM Procedure Generation");
-	for_array(j, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[j].value;
-		for_array(i, m->procedures_to_generate) {
-			lbProcedure *p = m->procedures_to_generate[i];
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
+		for (lbProcedure *p : m->procedures_to_generate) {
 			lb_generate_procedure(m, p);
 			lb_generate_procedure(m, p);
 		}
 		}
 	}
 	}
@@ -2143,10 +2144,9 @@ void lb_generate_code(lbGenerator *gen) {
 		lb_create_main_procedure(default_module, startup_runtime);
 		lb_create_main_procedure(default_module, startup_runtime);
 	}
 	}
 
 
-	for_array(j, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[j].value;
-		for_array(i, m->missing_procedures_to_check) {
-			lbProcedure *p = m->missing_procedures_to_check[i];
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
+		for (lbProcedure *p : m->missing_procedures_to_check) {
 			debugf("Generate missing procedure: %.*s\n", LIT(p->name));
 			debugf("Generate missing procedure: %.*s\n", LIT(p->name));
 			lb_generate_procedure(m, p);
 			lb_generate_procedure(m, p);
 		}
 		}
@@ -2155,24 +2155,9 @@ void lb_generate_code(lbGenerator *gen) {
 	lb_finalize_objc_names(objc_names);
 	lb_finalize_objc_names(objc_names);
 
 
 	if (build_context.ODIN_DEBUG) {
 	if (build_context.ODIN_DEBUG) {
-		TIME_SECTION("LLVM Debug Info for global constant value declarations");
-		{
-			// lbModule *m = default_module;
-
-
-		}
-		// if (gen->modules.entries.count == 1) {
-		// } else {
-		// 	for_array(j, gen->modules.entries) {
-		// 		lbModule *m = gen->modules.entries[j].value;
-		// 		if (m->debug_builder != nullptr) {
-		// 		}
-		// 	}
-		// }
-
 		TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
 		TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
-		for_array(j, gen->modules.entries) {
-			lbModule *m = gen->modules.entries[j].value;
+		for (auto const &entry : gen->modules) {
+			lbModule *m = entry.value;
 			if (m->debug_builder != nullptr) {
 			if (m->debug_builder != nullptr) {
 				lb_debug_complete_types(m);
 				lb_debug_complete_types(m);
 				LLVMDIBuilderFinalize(m->debug_builder);
 				LLVMDIBuilderFinalize(m->debug_builder);
@@ -2183,23 +2168,22 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 
 
 	TIME_SECTION("LLVM Function Pass");
 	TIME_SECTION("LLVM Function Pass");
-	for_array(i, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[i].value;
-
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
 		lb_llvm_function_pass_worker_proc(m);
 		lb_llvm_function_pass_worker_proc(m);
 	}
 	}
 
 
 	TIME_SECTION("LLVM Module Pass");
 	TIME_SECTION("LLVM Module Pass");
 
 
-	for_array(i, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[i].value;
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
 		
 		
 		lb_run_remove_unused_function_pass(m);
 		lb_run_remove_unused_function_pass(m);
 		lb_run_remove_unused_globals_pass(m);
 		lb_run_remove_unused_globals_pass(m);
 
 
 		auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
 		auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
 		wd->m = m;
 		wd->m = m;
-		wd->target_machine = target_machines[i];
+		wd->target_machine = m->target_machine;
 
 
 		lb_llvm_module_pass_worker_proc(wd);
 		lb_llvm_module_pass_worker_proc(wd);
 	}
 	}
@@ -2214,8 +2198,8 @@ void lb_generate_code(lbGenerator *gen) {
 	}
 	}
 
 
 
 
-	for_array(j, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[j].value;
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
 		if (LLVMVerifyModule(m->mod, LLVMReturnStatusAction, &llvm_error)) {
 		if (LLVMVerifyModule(m->mod, LLVMReturnStatusAction, &llvm_error)) {
 			gb_printf_err("LLVM Error:\n%s\n", llvm_error);
 			gb_printf_err("LLVM Error:\n%s\n", llvm_error);
 			if (build_context.keep_temp_files) {
 			if (build_context.keep_temp_files) {
@@ -2236,8 +2220,8 @@ void lb_generate_code(lbGenerator *gen) {
 	    build_context.build_mode == BuildMode_LLVM_IR) {
 	    build_context.build_mode == BuildMode_LLVM_IR) {
 		TIME_SECTION("LLVM Print Module to File");
 		TIME_SECTION("LLVM Print Module to File");
 
 
-		for_array(j, gen->modules.entries) {
-			lbModule *m = gen->modules.entries[j].value;
+		for (auto const &entry : gen->modules) {
+			lbModule *m = entry.value;
 
 
 			if (lb_is_module_empty(m)) {
 			if (lb_is_module_empty(m)) {
 				continue;
 				continue;
@@ -2260,10 +2244,9 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 	TIME_SECTION("LLVM Add Foreign Library Paths");
 	TIME_SECTION("LLVM Add Foreign Library Paths");
 
 
-	for_array(j, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[j].value;
-		for_array(i, m->info->required_foreign_imports_through_force) {
-			Entity *e = m->info->required_foreign_imports_through_force[i];
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
+		for (Entity *e : m->info->required_foreign_imports_through_force) {
 			lb_add_foreign_library_path(m, e);
 			lb_add_foreign_library_path(m, e);
 		}
 		}
 
 
@@ -2275,16 +2258,16 @@ void lb_generate_code(lbGenerator *gen) {
 	TIME_SECTION("LLVM Object Generation");
 	TIME_SECTION("LLVM Object Generation");
 	
 	
 	isize non_empty_module_count = 0;
 	isize non_empty_module_count = 0;
-	for_array(j, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[j].value;
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
 		if (!lb_is_module_empty(m)) {
 		if (!lb_is_module_empty(m)) {
 			non_empty_module_count += 1;
 			non_empty_module_count += 1;
 		}
 		}
 	}
 	}
 
 
 	if (do_threading && non_empty_module_count > 1) {
 	if (do_threading && non_empty_module_count > 1) {
-		for_array(j, gen->modules.entries) {
-			lbModule *m = gen->modules.entries[j].value;
+		for (auto const &entry : gen->modules) {
+			lbModule *m = entry.value;
 			if (lb_is_module_empty(m)) {
 			if (lb_is_module_empty(m)) {
 				continue;
 				continue;
 			}
 			}
@@ -2295,7 +2278,7 @@ void lb_generate_code(lbGenerator *gen) {
 			array_add(&gen->output_temp_paths, filepath_ll);
 			array_add(&gen->output_temp_paths, filepath_ll);
 
 
 			auto *wd = gb_alloc_item(permanent_allocator(), lbLLVMEmitWorker);
 			auto *wd = gb_alloc_item(permanent_allocator(), lbLLVMEmitWorker);
-			wd->target_machine = target_machines[j];
+			wd->target_machine = m->target_machine;
 			wd->code_gen_file_type = code_gen_file_type;
 			wd->code_gen_file_type = code_gen_file_type;
 			wd->filepath_obj = filepath_obj;
 			wd->filepath_obj = filepath_obj;
 			wd->m = m;
 			wd->m = m;
@@ -2304,8 +2287,8 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 		thread_pool_wait(&global_thread_pool);
 		thread_pool_wait(&global_thread_pool);
 	} else {
 	} else {
-		for_array(j, gen->modules.entries) {
-			lbModule *m = gen->modules.entries[j].value;
+		for (auto const &entry : gen->modules) {
+			lbModule *m = entry.value;
 			if (lb_is_module_empty(m)) {
 			if (lb_is_module_empty(m)) {
 				continue;
 				continue;
 			}
 			}
@@ -2319,7 +2302,7 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 			TIME_SECTION_WITH_LEN(section_name, gb_string_length(section_name));
 			TIME_SECTION_WITH_LEN(section_name, gb_string_length(section_name));
 
 
-			if (LLVMTargetMachineEmitToFile(target_machines[j], m->mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
+			if (LLVMTargetMachineEmitToFile(m->target_machine, m->mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
 				gb_printf_err("LLVM Error: %s\n", llvm_error);
 				gb_printf_err("LLVM Error: %s\n", llvm_error);
 				gb_exit(1);
 				gb_exit(1);
 				return;
 				return;

+ 1 - 0
src/llvm_backend.hpp

@@ -122,6 +122,7 @@ struct lbModule {
 	LLVMContextRef ctx;
 	LLVMContextRef ctx;
 
 
 	struct lbGenerator *gen;
 	struct lbGenerator *gen;
+	LLVMTargetMachineRef target_machine;
 
 
 	CheckerInfo *info;
 	CheckerInfo *info;
 	AstPackage *pkg; // associated
 	AstPackage *pkg; // associated

+ 4 - 4
src/llvm_backend_general.cpp

@@ -137,8 +137,8 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
 	ptr_set_init(&gen->foreign_libraries_set, heap_allocator(), 1024);
 	ptr_set_init(&gen->foreign_libraries_set, heap_allocator(), 1024);
 
 
 	if (USE_SEPARATE_MODULES) {
 	if (USE_SEPARATE_MODULES) {
-		for_array(i, gen->info->packages.entries) {
-			AstPackage *pkg = gen->info->packages.entries[i].value;
+		for (auto const &entry : gen->info->packages) {
+			AstPackage *pkg = entry.value;
 
 
 			auto m = gb_alloc_item(permanent_allocator(), lbModule);
 			auto m = gb_alloc_item(permanent_allocator(), lbModule);
 			m->pkg = pkg;
 			m->pkg = pkg;
@@ -153,8 +153,8 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
 	lb_init_module(&gen->default_module, c);
 	lb_init_module(&gen->default_module, c);
 
 
 
 
-	for_array(i, gen->modules.entries) {
-		lbModule *m = gen->modules.entries[i].value;
+	for (auto const &entry : gen->modules) {
+		lbModule *m = entry.value;
 		LLVMContextRef ctx = LLVMGetModuleContext(m->mod);
 		LLVMContextRef ctx = LLVMGetModuleContext(m->mod);
 		map_set(&gen->modules_through_ctx, ctx, m);
 		map_set(&gen->modules_through_ctx, ctx, m);
 	}
 	}

+ 21 - 0
src/ptr_map.cpp

@@ -339,3 +339,24 @@ void multi_map_remove_all(PtrMap<K, V> *h, K key) {
 	}
 	}
 }
 }
 #endif
 #endif
+
+
+template <typename K, typename V>
+PtrMapEntry<K, V> *begin(PtrMap<K, V> &m) {
+	return m.entries.data;
+}
+template <typename K, typename V>
+PtrMapEntry<K, V> const *begin(PtrMap<K, V> const &m) {
+	return m.entries.data;
+}
+
+
+template <typename K, typename V>
+PtrMapEntry<K, V> *end(PtrMap<K, V> &m) {
+	return m.entries.data + m.entries.count;
+}
+
+template <typename K, typename V>
+PtrMapEntry<K, V> const *end(PtrMap<K, V> const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 21 - 0
src/ptr_set.cpp

@@ -233,3 +233,24 @@ gb_inline void ptr_set_clear(PtrSet<T> *s) {
 		s->hashes.data[i] = MAP_SENTINEL;
 		s->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
 }
 }
+
+
+template <typename T>
+PtrSetEntry<T> *begin(PtrSet<T> &m) {
+	return m.entries.data;
+}
+template <typename T>
+PtrSetEntry<T> const *begin(PtrSet<T> const &m) {
+	return m.entries.data;
+}
+
+
+template <typename T>
+PtrSetEntry<T> *end(PtrSet<T> &m) {
+	return m.entries.data + m.entries.count;
+}
+
+template <typename T>
+PtrSetEntry<T> const *end(PtrSet<T> const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 4 - 4
src/query_data.cpp

@@ -449,8 +449,8 @@ void generate_and_print_query_data_global_definitions(Checker *c, Timings *timin
 		auto sorted_packages = array_make<AstPackage *>(query_value_allocator, 0, c->info.packages.entries.count);
 		auto sorted_packages = array_make<AstPackage *>(query_value_allocator, 0, c->info.packages.entries.count);
 		defer (array_free(&sorted_packages));
 		defer (array_free(&sorted_packages));
 
 
-		for_array(i, c->info.packages.entries) {
-			AstPackage *pkg = c->info.packages.entries[i].value;
+		for (auto const &entry : c->info.packages) {
+			AstPackage *pkg = entry.value;
 			if (pkg != nullptr) {
 			if (pkg != nullptr) {
 				array_add(&sorted_packages, pkg);
 				array_add(&sorted_packages, pkg);
 			}
 			}
@@ -880,8 +880,8 @@ void generate_and_print_query_data_go_to_definitions(Checker *c) {
 
 
 	isize file_path_memory_needed = 0;
 	isize file_path_memory_needed = 0;
 	auto files = array_make<GoToDefFileMap>(a, 0, c->info.files.entries.count);
 	auto files = array_make<GoToDefFileMap>(a, 0, c->info.files.entries.count);
-	for_array(i, c->info.files.entries) {
-		AstFile *f = c->info.files.entries[i].value;
+	for (auto const &entry : c->info.files) {
+		AstFile *f = entry.value;
 		file_path_memory_needed += f->fullpath.len+1; // add NUL terminator
 		file_path_memory_needed += f->fullpath.len+1; // add NUL terminator
 
 
 
 

+ 23 - 0
src/string_map.cpp

@@ -30,6 +30,8 @@ struct StringMapEntry {
 
 
 template <typename T>
 template <typename T>
 struct StringMap {
 struct StringMap {
+	using K = String;
+	using V = T;
 	Slice<MapIndex>           hashes;
 	Slice<MapIndex>           hashes;
 	Array<StringMapEntry<T> > entries;
 	Array<StringMapEntry<T> > entries;
 };
 };
@@ -270,3 +272,24 @@ gb_inline void string_map_clear(StringMap<T> *h) {
 	}
 	}
 }
 }
 
 
+
+
+template <typename T>
+StringMapEntry<T> *begin(StringMap<T> &m) {
+	return m.entries.data;
+}
+template <typename T>
+StringMapEntry<T> const *begin(StringMap<T> const &m) {
+	return m.entries.data;
+}
+
+
+template <typename T>
+StringMapEntry<T> *end(StringMap<T> &m) {
+	return m.entries.data + m.entries.count;
+}
+
+template <typename T>
+StringMapEntry<T> const *end(StringMap<T> const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 18 - 0
src/string_set.cpp

@@ -215,3 +215,21 @@ gb_inline void string_set_clear(StringSet *s) {
 		s->hashes.data[i] = MAP_SENTINEL;
 		s->hashes.data[i] = MAP_SENTINEL;
 	}
 	}
 }
 }
+
+
+
+StringSetEntry *begin(StringSet &m) {
+	return m.entries.data;
+}
+StringSetEntry const *begin(StringSet const &m) {
+	return m.entries.data;
+}
+
+
+StringSetEntry *end(StringSet &m) {
+	return m.entries.data + m.entries.count;
+}
+
+StringSetEntry const *end(StringSet const &m) {
+	return m.entries.data + m.entries.count;
+}

+ 2 - 2
src/types.cpp

@@ -828,8 +828,8 @@ bool type_ptr_set_exists(PtrSet<Type *> *s, Type *t) {
 
 
 	// TODO(bill, 2019-10-05): This is very slow and it's probably a lot
 	// TODO(bill, 2019-10-05): This is very slow and it's probably a lot
 	// faster to cache types correctly
 	// faster to cache types correctly
-	for_array(i, s->entries) {
-		Type *f = s->entries[i].ptr;
+	for (auto const &entry : *s) {
+		Type *f = entry.ptr;
 		if (are_types_identical(t, f)) {
 		if (are_types_identical(t, f)) {
 			ptr_set_add(s, t);
 			ptr_set_add(s, t);
 			return true;
 			return true;