Browse Source

`array_make`

gingerBill 7 years ago
parent
commit
d63885a495
16 changed files with 173 additions and 316 deletions
  1. 40 18
      src/array.cpp
  2. 1 2
      src/build_settings.cpp
  3. 2 3
      src/check_decl.cpp
  4. 9 11
      src/check_expr.cpp
  5. 6 60
      src/check_stmt.cpp
  6. 11 57
      src/check_type.cpp
  7. 6 9
      src/checker.cpp
  8. 45 95
      src/ir.cpp
  9. 2 2
      src/ir_opt.cpp
  10. 4 6
      src/main.cpp
  11. 5 3
      src/map.cpp
  12. 32 31
      src/parser.cpp
  13. 0 7
      src/parser.hpp
  14. 5 3
      src/ptr_set.cpp
  15. 1 1
      src/timings.cpp
  16. 4 8
      src/types.cpp

+ 40 - 18
src/array.cpp

@@ -24,10 +24,12 @@ struct Array {
 	}
 	}
 };
 };
 
 
-template <typename T> void     array_init        (Array<T> *array, gbAllocator a, isize init_capacity = ARRAY_GROW_FORMULA(0));
-template <typename T> void     array_init_count  (Array<T> *array, gbAllocator a, isize count);
-template <typename T> Array<T> array_make        (gbAllocator a, isize init_capacity = ARRAY_GROW_FORMULA(0));
-template <typename T> Array<T> array_make_count  (gbAllocator a, isize count);
+template <typename T> void     array_init        (Array<T> *array, gbAllocator const &a);
+template <typename T> void     array_init        (Array<T> *array, gbAllocator const &a, isize count);
+template <typename T> void     array_init        (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
+template <typename T> Array<T> array_make        (gbAllocator const &a);
+template <typename T> Array<T> array_make        (gbAllocator const &a, isize count);
+template <typename T> Array<T> array_make        (gbAllocator const &a, isize count, isize capacity);
 template <typename T> Array<T> array_make_from_ptr(T *data, isize count, isize capacity);
 template <typename T> Array<T> array_make_from_ptr(T *data, isize count, isize capacity);
 template <typename T> void     array_free        (Array<T> *array);
 template <typename T> void     array_free        (Array<T> *array);
 template <typename T> void     array_add         (Array<T> *array, T const &t);
 template <typename T> void     array_add         (Array<T> *array, T const &t);
@@ -38,24 +40,28 @@ template <typename T> void     array_resize      (Array<T> *array, isize count);
 template <typename T> void     array_set_capacity(Array<T> *array, isize capacity);
 template <typename T> void     array_set_capacity(Array<T> *array, isize capacity);
 
 
 template <typename T>
 template <typename T>
-void array_init(Array<T> *array, gbAllocator a, isize init_capacity) {
-	array->allocator = a;
-	array->data = gb_alloc_array(a, T, init_capacity);
-	array->count = 0;
-	array->capacity = init_capacity;
+gb_inline void array_init(Array<T> *array, gbAllocator const &a) {
+	isize cap = ARRAY_GROW_FORMULA(0);
+	array_init(array, a, 0, cap);
+}
+
+template <typename T>
+gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count) {
+	array_init(array, a, count, count);
 }
 }
 
 
 template <typename T>
 template <typename T>
-void array_init_count(Array<T> *array, gbAllocator a, isize count) {
+gb_inline void array_init(Array<T> *array, gbAllocator const &a, isize count, isize capacity) {
 	array->allocator = a;
 	array->allocator = a;
-	array->data = gb_alloc_array(a, T, count);
+	array->data = gb_alloc_array(a, T, capacity);
 	array->count = count;
 	array->count = count;
-	array->capacity = count;
+	array->capacity = capacity;
 }
 }
 
 
 
 
+
 template <typename T>
 template <typename T>
-Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
+gb_inline Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
 	Array<T> a = {0};
 	Array<T> a = {0};
 	a.data = data;
 	a.data = data;
 	a.count = count;
 	a.count = count;
@@ -65,15 +71,31 @@ Array<T> array_make_from_ptr(T *data, isize count, isize capacity) {
 
 
 
 
 template <typename T>
 template <typename T>
-Array<T> array_make(gbAllocator a, isize init_capacity) {
+gb_inline Array<T> array_make(gbAllocator const &a) {
+	isize capacity = ARRAY_GROW_FORMULA(0);
+	Array<T> array = {};
+	array.allocator = a;
+	array.data = gb_alloc_array(a, T, capacity);
+	array.count = 0;
+	array.capacity = capacity;
+	return array;
+}
+template <typename T>
+gb_inline Array<T> array_make(gbAllocator const &a, isize count) {
 	Array<T> array = {};
 	Array<T> array = {};
-	array_init(&array, a, init_capacity);
+	array.allocator = a;
+	array.data = gb_alloc_array(a, T, count);
+	array.count = count;
+	array.capacity = count;
 	return array;
 	return array;
 }
 }
 template <typename T>
 template <typename T>
-Array<T> array_make_count(gbAllocator a, isize count) {
+gb_inline Array<T> array_make(gbAllocator const &a, isize count, isize capacity) {
 	Array<T> array = {};
 	Array<T> array = {};
-	array_init_count(&array, a, count);
+	array.allocator = a;
+	array.data = gb_alloc_array(a, T, capacity);
+	array.count = count;
+	array.capacity = capacity;
 	return array;
 	return array;
 }
 }
 
 
@@ -157,7 +179,7 @@ void array_set_capacity(Array<T> *array, isize capacity) {
 
 
 #if 0
 #if 0
 #define Array(Type_) struct { \
 #define Array(Type_) struct { \
-	gbAllocator allocator; \
+	gbAllocator const &allocator; \
 	Type_ *     e; \
 	Type_ *     e; \
 	isize       count; \
 	isize       count; \
 	isize       capacity; \
 	isize       capacity; \

+ 1 - 2
src/build_settings.cpp

@@ -71,7 +71,6 @@ String const NIX_SEPARATOR_STRING   = {cast(u8 *)"/",  1};
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 String odin_root_dir(void) {
 String odin_root_dir(void) {
 	String path = global_module_path;
 	String path = global_module_path;
-	Array<wchar_t> path_buf;
 	isize len, i;
 	isize len, i;
 	gbTempArenaMemory tmp;
 	gbTempArenaMemory tmp;
 	wchar_t *text;
 	wchar_t *text;
@@ -80,7 +79,7 @@ String odin_root_dir(void) {
 		return global_module_path;
 		return global_module_path;
 	}
 	}
 
 
-	array_init_count(&path_buf, heap_allocator(), 300);
+	auto path_buf = array_make<wchar_t>(heap_allocator(), 300);
 
 
 	len = 0;
 	len = 0;
 	for (;;) {
 	for (;;) {

+ 2 - 3
src/check_decl.cpp

@@ -100,8 +100,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, Array<AstNo
 
 
 	// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 	// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 	// an extra allocation
 	// an extra allocation
-	Array<Operand> operands = {};
-	array_init(&operands, c->tmp_allocator, 2*lhs_count);
+	auto operands = array_make<Operand>(c->tmp_allocator, 0, 2*lhs_count);
 	check_unpack_arguments(c, lhs, lhs_count, &operands, inits, true);
 	check_unpack_arguments(c, lhs, lhs_count, &operands, inits, true);
 
 
 	isize rhs_count = operands.count;
 	isize rhs_count = operands.count;
@@ -758,7 +757,7 @@ void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
 
 
 	ast_node(pg, ProcGroup, d->init_expr);
 	ast_node(pg, ProcGroup, d->init_expr);
 
 
-	array_init(&pge->entities, c->allocator, pg->args.count);
+	pge->entities = array_make<Entity*>(c->allocator, 0, pg->args.count);
 
 
 	// NOTE(bill): This must be set here to prevent cycles in checking if someone
 	// NOTE(bill): This must be set here to prevent cycles in checking if someone
 	// places the entity within itself
 	// places the entity within itself

+ 9 - 11
src/check_expr.cpp

@@ -223,7 +223,7 @@ bool find_or_generate_polymorphic_procedure(Checker *c, Entity *base_entity, Typ
 	if (param_operands) {
 	if (param_operands) {
 		operands = *param_operands;
 		operands = *param_operands;
 	} else {
 	} else {
-		array_init(&operands, a, dst->Proc.param_count);
+		operands = array_make<Operand>(a, 0, dst->Proc.param_count);
 		for (isize i = 0; i < dst->Proc.param_count; i++) {
 		for (isize i = 0; i < dst->Proc.param_count; i++) {
 			Entity *param = dst->Proc.params->Tuple.variables[i];
 			Entity *param = dst->Proc.params->Tuple.variables[i];
 			Operand o = {Addressing_Value};
 			Operand o = {Addressing_Value};
@@ -362,8 +362,7 @@ bool find_or_generate_polymorphic_procedure(Checker *c, Entity *base_entity, Typ
 	if (found_gen_procs) {
 	if (found_gen_procs) {
 		array_add(found_gen_procs, entity);
 		array_add(found_gen_procs, entity);
 	} else {
 	} else {
-		Array<Entity *> array = {};
-		array_init(&array, heap_allocator());
+		auto array = array_make<Entity *>(heap_allocator());
 		array_add(&array, entity);
 		array_add(&array, entity);
 		map_set(&c->info.gen_procs, hash_pointer(base_entity->identifier), array);
 		map_set(&c->info.gen_procs, hash_pointer(base_entity->identifier), array);
 	}
 	}
@@ -3606,7 +3605,7 @@ break;
 
 
 		Type *tuple = make_type_tuple(a);
 		Type *tuple = make_type_tuple(a);
 		isize variable_count = type->Struct.fields.count;
 		isize variable_count = type->Struct.fields.count;
-		array_init_count(&tuple->Tuple.variables, a, variable_count);
+		array_init(&tuple->Tuple.variables, a, variable_count);
 		// TODO(bill): Should I copy each of the entities or is this good enough?
 		// TODO(bill): Should I copy each of the entities or is this good enough?
 		gb_memcopy_array(tuple->Tuple.variables.data, type->Struct.fields_in_src_order.data, variable_count);
 		gb_memcopy_array(tuple->Tuple.variables.data, type->Struct.fields_in_src_order.data, variable_count);
 
 
@@ -4277,8 +4276,7 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
 	isize param_count = pt->param_count;
 	isize param_count = pt->param_count;
 	bool *visited = gb_alloc_array(c->tmp_allocator, bool, param_count);
 	bool *visited = gb_alloc_array(c->tmp_allocator, bool, param_count);
 
 
-	Array<Operand> ordered_operands = {};
-	array_init_count(&ordered_operands, c->tmp_allocator, param_count);
+	auto ordered_operands = array_make<Operand>(c->tmp_allocator, param_count);
 
 
 	for_array(i, ce->args) {
 	for_array(i, ce->args) {
 		AstNode *arg = ce->args[i];
 		AstNode *arg = ce->args[i];
@@ -4416,7 +4414,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
 	if (is_call_expr_field_value(ce)) {
 	if (is_call_expr_field_value(ce)) {
 		call_checker = check_named_call_arguments;
 		call_checker = check_named_call_arguments;
 
 
-		array_init_count(&operands, heap_allocator(), ce->args.count);
+		operands = array_make<Operand>(heap_allocator(), ce->args.count);
 		for_array(i, ce->args) {
 		for_array(i, ce->args) {
 			AstNode *arg = ce->args[i];
 			AstNode *arg = ce->args[i];
 			ast_node(fv, FieldValue, arg);
 			ast_node(fv, FieldValue, arg);
@@ -4429,7 +4427,7 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t
 		}
 		}
 
 
 	} else {
 	} else {
-		array_init(&operands, heap_allocator(), 2*ce->args.count);
+		operands = array_make<Operand>(heap_allocator(), 0, 2*ce->args.count);
 		check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false);
 		check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false);
 	}
 	}
 
 
@@ -4630,7 +4628,7 @@ CallArgumentError check_polymorphic_struct_type(Checker *c, Operand *operand, As
 
 
 	if (is_call_expr_field_value(ce)) {
 	if (is_call_expr_field_value(ce)) {
 		named_fields = true;
 		named_fields = true;
-		array_init_count(&operands, heap_allocator(), ce->args.count);
+		operands = array_make<Operand>(heap_allocator(), ce->args.count);
 		for_array(i, ce->args) {
 		for_array(i, ce->args) {
 			AstNode *arg = ce->args[i];
 			AstNode *arg = ce->args[i];
 			ast_node(fv, FieldValue, arg);
 			ast_node(fv, FieldValue, arg);
@@ -4643,7 +4641,7 @@ CallArgumentError check_polymorphic_struct_type(Checker *c, Operand *operand, As
 		}
 		}
 
 
 	} else {
 	} else {
-		array_init(&operands, heap_allocator(), 2*ce->args.count);
+		operands = array_make<Operand>(heap_allocator(), 0, 2*ce->args.count);
 		check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false);
 		check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false);
 	}
 	}
 
 
@@ -4656,7 +4654,7 @@ CallArgumentError check_polymorphic_struct_type(Checker *c, Operand *operand, As
 	if (named_fields) {
 	if (named_fields) {
 		bool *visited = gb_alloc_array(c->allocator, bool, param_count);
 		bool *visited = gb_alloc_array(c->allocator, bool, param_count);
 
 
-		array_init_count(&ordered_operands, c->tmp_allocator, param_count);
+		ordered_operands = array_make<Operand>(c->tmp_allocator, param_count);
 
 
 		for_array(i, ce->args) {
 		for_array(i, ce->args) {
 			AstNode *arg = ce->args[i];
 			AstNode *arg = ce->args[i];

+ 6 - 60
src/check_stmt.cpp

@@ -790,8 +790,7 @@ void check_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
 		gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 		gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 		defer (gb_temp_arena_memory_end(tmp));
 		defer (gb_temp_arena_memory_end(tmp));
 
 
-		Array<Entity *> unhandled = {};
-		array_init(&unhandled, c->tmp_allocator, fields.count);
+		auto unhandled = array_make<Entity *>(c->tmp_allocator, 0, fields.count);
 
 
 		for_array(i, fields) {
 		for_array(i, fields) {
 			Entity *f = fields[i];
 			Entity *f = fields[i];
@@ -1020,8 +1019,7 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
 		gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 		gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 		defer (gb_temp_arena_memory_end(tmp));
 		defer (gb_temp_arena_memory_end(tmp));
 
 
-		Array<Type *> unhandled = {};
-		array_init(&unhandled, c->tmp_allocator, variants.count);
+		auto unhandled = array_make<Type *>(c->tmp_allocator, 0, variants.count);
 
 
 		for_array(i, variants) {
 		for_array(i, variants) {
 			Type *t = variants[i];
 			Type *t = variants[i];
@@ -1117,10 +1115,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 
 
 			// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 			// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 			// an extra allocation
 			// an extra allocation
-			Array<Operand> lhs_operands = {};
-			Array<Operand> rhs_operands = {};
-			array_init_count(&lhs_operands, c->tmp_allocator, lhs_count);
-			array_init(&rhs_operands, c->tmp_allocator, 2 * lhs_count);
+			auto lhs_operands = array_make<Operand>(c->tmp_allocator, lhs_count);
+			auto rhs_operands = array_make<Operand>(c->tmp_allocator, 0, 2*lhs_count);
 
 
 			for_array(i, as->lhs) {
 			for_array(i, as->lhs) {
 				if (is_blank_ident(as->lhs[i])) {
 				if (is_blank_ident(as->lhs[i])) {
@@ -1233,30 +1229,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 			break;
 			break;
 		}
 		}
 
 
-		// bool first_is_field_value = false;
-		// if (rs->results.count > 0) {
-		// 	bool fail = false;
-		// 	first_is_field_value = (rs->results[0]->kind == AstNode_FieldValue);
-		// 	for_array(i, rs->results) {
-		// 		AstNode *arg = rs->results[i];
-		// 		bool mix = false;
-		// 		if (first_is_field_value) {
-		// 			mix = arg->kind != AstNode_FieldValue;
-		// 		} else {
-		// 			mix = arg->kind == AstNode_FieldValue;
-		// 		}
-		// 		if (mix) {
-		// 			error(arg, "Mixture of 'field = value' and value elements in a procedure all is not allowed");
-		// 			fail = true;
-		// 		}
-		// 	}
-
-		// 	if (fail) {
-		// 		return;
-		// 	}
-		// }
-
-
 		Type *proc_type = c->proc_stack[c->proc_stack.count-1];
 		Type *proc_type = c->proc_stack[c->proc_stack.count-1];
 		TypeProc *pt = &proc_type->Proc;
 		TypeProc *pt = &proc_type->Proc;
 		isize result_count = 0;
 		isize result_count = 0;
@@ -1266,36 +1238,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 		}
 		}
 
 
 
 
-		// isize result_count_excluding_defaults = result_count;
-		// for (isize i = result_count-1; i >= 0; i--) {
-		// 	Entity *e = pt->results->Tuple.variables[i];
-		// 	if (e->kind == Entity_TypeName) {
-		// 		break;
-		// 	}
-
-		// 	GB_ASSERT(e->kind == Entity_Variable);
-		// 	if (e->Variable.default_value.kind != ExactValue_Invalid ||
-		// 	    e->Variable.default_is_nil) {
-		// 		result_count_excluding_defaults--;
-		// 		continue;
-		// 	}
-		// 	break;
-		// }
-
-		Array<Operand> operands = {};
+		auto operands = array_make<Operand>(heap_allocator(), 0, 2*rs->results.count);
 		defer (array_free(&operands));
 		defer (array_free(&operands));
 
 
-		// if (first_is_field_value) {
-		// 	array_init_count(&operands, heap_allocator(), rs->results.count);
-		// 	for_array(i, rs->results) {
-		// 		AstNode *arg = rs->results[i];
-		// 		ast_node(fv, FieldValue, arg);
-		// 		check_expr(c, &operands[i], fv->value);
-		// 	}
-		// } else {
-			array_init(&operands, heap_allocator(), 2*rs->results.count);
-			check_unpack_arguments(c, nullptr, -1, &operands, rs->results, false);
-		// }
+		check_unpack_arguments(c, nullptr, -1, &operands, rs->results, false);
 
 
 		if (result_count == 0 && rs->results.count > 0) {
 		if (result_count == 0 && rs->results.count > 0) {
 			error(rs->results[0], "No return values expected");
 			error(rs->results[0], "No return values expected");

+ 11 - 57
src/check_type.cpp

@@ -40,8 +40,7 @@ Array<Entity *> check_struct_fields(Checker *c, AstNode *node, Array<AstNode *>
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
 	defer (gb_temp_arena_memory_end(tmp));
 	defer (gb_temp_arena_memory_end(tmp));
 
 
-	Array<Entity *> fields = {};
-	array_init(&fields, heap_allocator(), init_field_capacity);
+	auto fields = array_make<Entity *>(heap_allocator(), 0, init_field_capacity);
 
 
 	Map<Entity *> entity_map = {};
 	Map<Entity *> entity_map = {};
 	map_init(&entity_map, c->tmp_allocator, 2*init_field_capacity);
 	map_init(&entity_map, c->tmp_allocator, 2*init_field_capacity);
@@ -360,8 +359,7 @@ void add_polymorphic_struct_entity(Checker *c, AstNode *node, Type *named_type,
 	if (found_gen_types) {
 	if (found_gen_types) {
 		array_add(found_gen_types, e);
 		array_add(found_gen_types, e);
 	} else {
 	} else {
-		Array<Entity *> array = {};
-		array_init(&array, heap_allocator());
+		auto array = array_make<Entity *>(heap_allocator());
 		array_add(&array, e);
 		array_add(&array, e);
 		map_set(&c->info.gen_types, hash_pointer(original_type), array);
 		map_set(&c->info.gen_types, hash_pointer(original_type), array);
 	}
 	}
@@ -407,8 +405,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera
 				}
 				}
 			}
 			}
 
 
-			Array<Entity *> entities = {};
-			array_init(&entities, c->allocator, variable_count);
+			auto entities = array_make<Entity *>(c->allocator, 0, variable_count);
 
 
 			for_array(i, params) {
 			for_array(i, params) {
 				AstNode *param = params[i];
 				AstNode *param = params[i];
@@ -566,41 +563,6 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera
 		}
 		}
 	}
 	}
 
 
-
-#if 0
-	// TODO(bill): Move this to the appropriate place
-	if (!struct_type->Struct.is_raw_union) {
-		type_set_offsets(c->allocator, struct_type);
-
-		if (!struct_type->failure && !st->is_packed && !st->is_ordered) {
-			struct_type->failure = false;
-			struct_type->Struct.are_offsets_set = false;
-			struct_type->Struct.are_offsets_being_processed = false;
-			gb_zero_item(&struct_type->Struct.offsets);
-			// NOTE(bill): Reorder fields for reduced size/performance
-
-			Array<Entity *> reordered_fields = {};
-			array_init_count(&reordered_fields, c->allocator, fields.count);
-			for_array(i, reordered_fields) {
-				reordered_fields[i] = struct_type->Struct.fields_in_src_order[i];
-			}
-
-			// NOTE(bill): Hacky thing
-			// TODO(bill): Probably make an inline sorting procedure rather than use global variables
-			// NOTE(bill): compound literal order must match source not layout
-			gb_sort_array(reordered_fields.data, fields.count, cmp_reorder_struct_fields);
-
-			for_array(i, fields) {
-				reordered_fields[i]->Variable.field_index = cast(i32)i;
-			}
-
-			struct_type->Struct.fields = reordered_fields;
-		}
-
-		type_set_offsets(c->allocator, struct_type);
-	}
-#endif
-
 	if (st->align != nullptr) {
 	if (st->align != nullptr) {
 		if (st->is_packed) {
 		if (st->is_packed) {
 			syntax_error(st->align, "'#align' cannot be applied with '#packed'");
 			syntax_error(st->align, "'#align' cannot be applied with '#packed'");
@@ -623,8 +585,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
 
 
 	Entity *using_index_expr = nullptr;
 	Entity *using_index_expr = nullptr;
 
 
-	Array<Type *> variants = {};
-	array_init(&variants, c->allocator, variant_count);
+	auto variants = array_make<Type *>(c->allocator, 0, variant_count);
 
 
 	union_type->Union.scope = c->context.scope;
 	union_type->Union.scope = c->context.scope;
 
 
@@ -698,8 +659,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
 	Map<Entity *> entity_map = {}; // Key: String
 	Map<Entity *> entity_map = {}; // Key: String
 	map_init(&entity_map, c->tmp_allocator, 2*(et->fields.count));
 	map_init(&entity_map, c->tmp_allocator, 2*(et->fields.count));
 
 
-	Array<Entity *> fields = {};
-	array_init(&fields, c->allocator, et->fields.count);
+	auto fields = array_make<Entity *>(c->allocator, 0, et->fields.count);
 
 
 	Type *constant_type = enum_type;
 	Type *constant_type = enum_type;
 	if (named_type != nullptr) {
 	if (named_type != nullptr) {
@@ -1024,8 +984,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
 	bool is_variadic = false;
 	bool is_variadic = false;
 	isize variadic_index = -1;
 	isize variadic_index = -1;
 	bool is_c_vararg = false;
 	bool is_c_vararg = false;
-	Array<Entity *> variables = {};
-	array_init(&variables, c->allocator, variable_count);
+	auto variables = array_make<Entity *>(c->allocator, 0, variable_count);
 	for_array(i, params) {
 	for_array(i, params) {
 		AstNode *param = params[i];
 		AstNode *param = params[i];
 		if (param->kind != AstNode_Field) {
 		if (param->kind != AstNode_Field) {
@@ -1367,8 +1326,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) {
 		}
 		}
 	}
 	}
 
 
-	Array<Entity *> variables = {};
-	array_init(&variables, c->allocator, variable_count);
+	auto variables = array_make<Entity *>(c->allocator, 0, variable_count);
 	for_array(i, results) {
 	for_array(i, results) {
 		ast_node(field, Field, results[i]);
 		ast_node(field, Field, results[i]);
 		AstNode *default_value = unparen_expr(field->default_value);
 		AstNode *default_value = unparen_expr(field->default_value);
@@ -1624,8 +1582,7 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) {
 
 
 	if (new_type != original_type) {
 	if (new_type != original_type) {
 		Type *tuple = make_type_tuple(a);
 		Type *tuple = make_type_tuple(a);
-		Array<Entity *> variables = {};
-		array_init(&variables, a, 1);
+		auto variables = array_make<Entity *>(a, 0, 1);
 		array_add(&variables, make_entity_param(a, original_type->Tuple.variables[0]->scope, empty_token, new_type, false, false));
 		array_add(&variables, make_entity_param(a, original_type->Tuple.variables[0]->scope, empty_token, new_type, false, false));
 		tuple->Tuple.variables = variables;
 		tuple->Tuple.variables = variables;
 		new_type = tuple;
 		new_type = tuple;
@@ -1814,7 +1771,7 @@ i64 check_array_count(Checker *c, Operand *o, AstNode *e) {
 Type *make_optional_ok_type(gbAllocator a, Type *value) {
 Type *make_optional_ok_type(gbAllocator a, Type *value) {
 	bool typed = true;
 	bool typed = true;
 	Type *t = make_type_tuple(a);
 	Type *t = make_type_tuple(a);
-	array_init(&t->Tuple.variables, a, 2);
+	array_init(&t->Tuple.variables, a, 0, 2);
 	array_add (&t->Tuple.variables, make_entity_field(a, nullptr, blank_token, value,  false, 0));
 	array_add (&t->Tuple.variables, make_entity_field(a, nullptr, blank_token, value,  false, 0));
 	array_add (&t->Tuple.variables, make_entity_field(a, nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1));
 	array_add (&t->Tuple.variables, make_entity_field(a, nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1));
 	return t;
 	return t;
@@ -1841,9 +1798,7 @@ void generate_map_entry_type(gbAllocator a, Type *type) {
 	dummy_node->kind = AstNode_Invalid;
 	dummy_node->kind = AstNode_Invalid;
 	Scope *s = create_scope(universal_scope, a);
 	Scope *s = create_scope(universal_scope, a);
 
 
-	isize field_count = 3;
-	Array<Entity *> fields = {};
-	array_init(&fields, a, 3);
+	auto fields = array_make<Entity *>(a, 0, 3);
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("key")),   t_map_key,       false, 0));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("key")),   t_map_key,       false, 0));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("next")),  t_int,           false, 1));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("next")),  t_int,           false, 1));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("value")), type->Map.value, false, 2));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("value")), type->Map.value, false, 2));
@@ -1883,8 +1838,7 @@ void generate_map_internal_types(gbAllocator a, Type *type) {
 	Type *entries_type = make_type_dynamic_array(a, type->Map.entry_type);
 	Type *entries_type = make_type_dynamic_array(a, type->Map.entry_type);
 
 
 
 
-	Array<Entity *> fields = {};
-	array_init(&fields, a, 2);
+	auto fields = array_make<Entity *>(a, 0, 2);
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("hashes")),  hashes_type,  false, 0));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("hashes")),  hashes_type,  false, 0));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("entries")), entries_type, false, 1));
 	array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("entries")), entries_type, false, 1));
 
 

+ 6 - 9
src/checker.cpp

@@ -645,7 +645,7 @@ void init_checker(Checker *c, Parser *parser) {
 	map_init(&c->file_scopes, heap_allocator());
 	map_init(&c->file_scopes, heap_allocator());
 	ptr_set_init(&c->checked_files, heap_allocator());
 	ptr_set_init(&c->checked_files, heap_allocator());
 
 
-	array_init(&c->file_order, heap_allocator(), c->parser->files.count);
+	array_init(&c->file_order, heap_allocator(), 0, c->parser->files.count);
 }
 }
 
 
 void destroy_checker(Checker *c) {
 void destroy_checker(Checker *c) {
@@ -1219,8 +1219,7 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
 		}
 		}
 	}
 	}
 
 
-	Array<EntityGraphNode *> G = {};
-	array_init(&G, a, M.entries.count);
+	auto G = array_make<EntityGraphNode *>(a, 0, M.entries.count);
 
 
 	for_array(i, M.entries) {
 	for_array(i, M.entries) {
 		auto *entry = &M.entries[i];
 		auto *entry = &M.entries[i];
@@ -2247,12 +2246,11 @@ Array<ImportPathItem> find_import_path(Checker *c, Scope *start, Scope *end, Ptr
 
 
 			ImportPathItem item = {s, decl};
 			ImportPathItem item = {s, decl};
 			if (s == end) {
 			if (s == end) {
-				Array<ImportPathItem> path = {};
-				array_init(&path, heap_allocator());
+				auto path = array_make<ImportPathItem>(heap_allocator());
 				array_add(&path, item);
 				array_add(&path, item);
 				return path;
 				return path;
 			}
 			}
-			Array<ImportPathItem> next_path = find_import_path(c, s, end, visited);
+			auto next_path = find_import_path(c, s, end, visited);
 			if (next_path.count > 0) {
 			if (next_path.count > 0) {
 				array_add(&next_path, item);
 				array_add(&next_path, item);
 				return next_path;
 				return next_path;
@@ -2853,12 +2851,11 @@ Array<Entity *> find_entity_path(Entity *start, Entity *end, Map<Entity *> *visi
 		for_array(i, decl->deps.entries) {
 		for_array(i, decl->deps.entries) {
 			Entity *dep = decl->deps.entries[i].ptr;
 			Entity *dep = decl->deps.entries[i].ptr;
 			if (dep == end) {
 			if (dep == end) {
-				Array<Entity *> path = {};
-				array_init(&path, heap_allocator());
+				auto path = array_make<Entity *>(heap_allocator());
 				array_add(&path, dep);
 				array_add(&path, dep);
 				return path;
 				return path;
 			}
 			}
-			Array<Entity *> next_path = find_entity_path(dep, end, visited);
+			auto next_path = find_entity_path(dep, end, visited);
 			if (next_path.count > 0) {
 			if (next_path.count > 0) {
 				array_add(&next_path, dep);
 				array_add(&next_path, dep);
 				return next_path;
 				return next_path;

+ 45 - 95
src/ir.cpp

@@ -1189,7 +1189,7 @@ irValue *ir_value_procedure(gbAllocator a, irModule *m, Entity *entity, Type *ty
 
 
 	Type *t = base_type(type);
 	Type *t = base_type(type);
 	GB_ASSERT(is_type_proc(t));
 	GB_ASSERT(is_type_proc(t));
-	array_init(&v->Proc.params, heap_allocator(), t->Proc.param_count);
+	array_init(&v->Proc.params, heap_allocator(), 0, t->Proc.param_count);
 
 
 	return v;
 	return v;
 }
 }
@@ -1598,7 +1598,7 @@ void ir_add_debug_location_to_value(irProcedure *proc, irValue *v, AstNode *e) {
 void ir_emit_zero_init(irProcedure *p, irValue *address, AstNode *expr) {
 void ir_emit_zero_init(irProcedure *p, irValue *address, AstNode *expr) {
 	gbAllocator a = p->module->allocator;
 	gbAllocator a = p->module->allocator;
 	Type *t = type_deref(ir_type(address));
 	Type *t = type_deref(ir_type(address));
-	auto args = array_make_count<irValue *>(a, 2);
+	auto args = array_make<irValue *>(a, 2);
 	args[0] = ir_emit_conv(p, address, t_rawptr);
 	args[0] = ir_emit_conv(p, address, t_rawptr);
 	args[1] = ir_const_int(a, type_size_of(a, t));
 	args[1] = ir_const_int(a, type_size_of(a, t));
 	if (p->entity->token.string != "__mem_zero") {
 	if (p->entity->token.string != "__mem_zero") {
@@ -1614,7 +1614,7 @@ irValue *ir_emit_comment(irProcedure *p, String text) {
 void ir_emit_init_context(irProcedure *proc, irValue *c = nullptr) {
 void ir_emit_init_context(irProcedure *proc, irValue *c = nullptr) {
 	irModule *m = proc->module;
 	irModule *m = proc->module;
 	gbAllocator a = m->allocator;
 	gbAllocator a = m->allocator;
-	auto args = array_make_count<irValue *>(a, 1);
+	auto args = array_make<irValue *>(a, 1);
 	args[0] = c ? c : m->global_default_context;
 	args[0] = c ? c : m->global_default_context;
 	ir_emit_global_call(proc, "__init_context", args);
 	ir_emit_global_call(proc, "__init_context", args);
 }
 }
@@ -1884,7 +1884,7 @@ irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) {
 			u64 hs = fnv64a(ev.value_string.text, ev.value_string.len);
 			u64 hs = fnv64a(ev.value_string.text, ev.value_string.len);
 			hashed_str = ir_value_constant(proc->module->allocator, t_u64, exact_value_u64(hs));
 			hashed_str = ir_value_constant(proc->module->allocator, t_u64, exact_value_u64(hs));
 		} else {
 		} else {
-			auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+			auto args = array_make<irValue *>(proc->module->allocator, 1);
 			args[0] = str;
 			args[0] = str;
 			hashed_str = ir_emit_global_call(proc, "__default_hash_string", args);
 			hashed_str = ir_emit_global_call(proc, "__default_hash_string", args);
 		}
 		}
@@ -1943,7 +1943,7 @@ irValue *ir_insert_dynamic_map_key_and_value(irProcedure *proc, irValue *addr, T
 	irValue *ptr = ir_add_local_generated(proc, ir_type(v));
 	irValue *ptr = ir_add_local_generated(proc, ir_type(v));
 	ir_emit_store(proc, ptr, v);
 	ir_emit_store(proc, ptr, v);
 
 
-	auto args = array_make_count<irValue *>(proc->module->allocator, 4);
+	auto args = array_make<irValue *>(proc->module->allocator, 4);
 	args[0] = h;
 	args[0] = h;
 	args[1] = key;
 	args[1] = key;
 	args[2] = ir_emit_conv(proc, ptr, t_rawptr);
 	args[2] = ir_emit_conv(proc, ptr, t_rawptr);
@@ -2044,7 +2044,7 @@ irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
 		irValue *h = ir_gen_map_header(proc, addr.addr, map_type);
 		irValue *h = ir_gen_map_header(proc, addr.addr, map_type);
 		irValue *key = ir_gen_map_key(proc, addr.map_key, map_type->Map.key);
 		irValue *key = ir_gen_map_key(proc, addr.map_key, map_type->Map.key);
 
 
-		auto args = array_make_count<irValue *>(proc->module->allocator, 2);
+		auto args = array_make<irValue *>(proc->module->allocator, 2);
 		args[0] = h;
 		args[0] = h;
 		args[1] = key;
 		args[1] = key;
 
 
@@ -2541,7 +2541,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
 		}
 		}
 		GB_ASSERT(runtime_proc != nullptr);
 		GB_ASSERT(runtime_proc != nullptr);
 
 
-		auto args = array_make_count<irValue *>(proc->module->allocator, 2);
+		auto args = array_make<irValue *>(proc->module->allocator, 2);
 		args[0] = left;
 		args[0] = left;
 		args[1] = right;
 		args[1] = right;
 		return ir_emit_global_call(proc, runtime_proc, args);
 		return ir_emit_global_call(proc, runtime_proc, args);
@@ -2566,7 +2566,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
 		}
 		}
 		GB_ASSERT(runtime_proc != nullptr);
 		GB_ASSERT(runtime_proc != nullptr);
 
 
-		auto args = array_make_count<irValue *>(proc->module->allocator, 2);
+		auto args = array_make<irValue *>(proc->module->allocator, 2);
 		args[0] = left;
 		args[0] = left;
 		args[1] = right;
 		args[1] = right;
 		return ir_emit_global_call(proc, runtime_proc, args);
 		return ir_emit_global_call(proc, runtime_proc, args);
@@ -3137,13 +3137,13 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 			switch (dz) {
 			switch (dz) {
 			case 2: return value;
 			case 2: return value;
 			case 4: {
 			case 4: {
-				auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+				auto args = array_make<irValue *>(proc->module->allocator, 1);
 				args[0] = value;
 				args[0] = value;
 				return ir_emit_global_call(proc, "__gnu_h2f_ieee", args);
 				return ir_emit_global_call(proc, "__gnu_h2f_ieee", args);
 				break;
 				break;
 			}
 			}
 			case 8: {
 			case 8: {
-				auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+				auto args = array_make<irValue *>(proc->module->allocator, 1);
 				args[0] = value;
 				args[0] = value;
 				return ir_emit_global_call(proc, "__f16_to_f64", args);
 				return ir_emit_global_call(proc, "__f16_to_f64", args);
 				break;
 				break;
@@ -3153,13 +3153,13 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 			switch (sz) {
 			switch (sz) {
 			case 2: return value;
 			case 2: return value;
 			case 4: {
 			case 4: {
-				auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+				auto args = array_make<irValue *>(proc->module->allocator, 1);
 				args[0] = value;
 				args[0] = value;
 				return ir_emit_global_call(proc, "__gnu_f2h_ieee", args);
 				return ir_emit_global_call(proc, "__gnu_f2h_ieee", args);
 				break;
 				break;
 			}
 			}
 			case 8: {
 			case 8: {
-				auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+				auto args = array_make<irValue *>(proc->module->allocator, 1);
 				args[0] = value;
 				args[0] = value;
 				return ir_emit_global_call(proc, "__truncdfhf2", args);
 				return ir_emit_global_call(proc, "__truncdfhf2", args);
 				break;
 				break;
@@ -3478,7 +3478,7 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *type, Token
 			Type *dst_type = tuple->Tuple.variables[0]->type;
 			Type *dst_type = tuple->Tuple.variables[0]->type;
 
 
 			irValue *ok = ir_emit_load(proc, ir_emit_struct_ep(proc, v, 1));
 			irValue *ok = ir_emit_load(proc, ir_emit_struct_ep(proc, v, 1));
-			auto args = array_make_count<irValue *>(proc->module->allocator, 6);
+			auto args = array_make<irValue *>(proc->module->allocator, 6);
 			args[0] = ok;
 			args[0] = ok;
 
 
 			args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
 			args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
@@ -3538,7 +3538,7 @@ irAddr ir_emit_any_cast_addr(irProcedure *proc, irValue *value, Type *type, Toke
 		// NOTE(bill): Panic on invalid conversion
 		// NOTE(bill): Panic on invalid conversion
 
 
 		irValue *ok = ir_emit_load(proc, ir_emit_struct_ep(proc, v, 1));
 		irValue *ok = ir_emit_load(proc, ir_emit_struct_ep(proc, v, 1));
-		auto args = array_make_count<irValue *>(proc->module->allocator, 6);
+		auto args = array_make<irValue *>(proc->module->allocator, 6);
 		args[0] = ok;
 		args[0] = ok;
 
 
 		args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
 		args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
@@ -3609,8 +3609,7 @@ irValue *ir_emit_logical_binary_expr(irProcedure *proc, TokenKind op, AstNode *l
 		return ir_build_expr(proc, right);
 		return ir_build_expr(proc, right);
 	}
 	}
 
 
-	Array<irValue *> edges = {};
-	array_init(&edges, proc->module->allocator, done->preds.count+1);
+	auto edges = array_make<irValue *>(proc->module->allocator, 0, done->preds.count+1);
 	for_array(i, done->preds) {
 	for_array(i, done->preds) {
 		array_add(&edges, short_circuit);
 		array_add(&edges, short_circuit);
 	}
 	}
@@ -3652,7 +3651,7 @@ void ir_emit_bounds_check(irProcedure *proc, Token token, irValue *index, irValu
 	irValue *column = ir_const_int(a, token.pos.column);
 	irValue *column = ir_const_int(a, token.pos.column);
 
 
 
 
-	auto args = array_make_count<irValue *>(proc->module->allocator, 5);
+	auto args = array_make<irValue *>(proc->module->allocator, 5);
 	args[0] = file;
 	args[0] = file;
 	args[1] = line;
 	args[1] = line;
 	args[2] = column;
 	args[2] = column;
@@ -3677,7 +3676,7 @@ void ir_emit_slice_bounds_check(irProcedure *proc, Token token, irValue *low, ir
 	low  = ir_emit_conv(proc, low,  t_int);
 	low  = ir_emit_conv(proc, low,  t_int);
 	high = ir_emit_conv(proc, high, t_int);
 	high = ir_emit_conv(proc, high, t_int);
 
 
-	auto args = array_make_count<irValue *>(proc->module->allocator, 6);
+	auto args = array_make<irValue *>(proc->module->allocator, 6);
 	args[0] = file;
 	args[0] = file;
 	args[1] = line;
 	args[1] = line;
 	args[2] = column;
 	args[2] = column;
@@ -3703,7 +3702,7 @@ void ir_emit_dynamic_array_bounds_check(irProcedure *proc, Token token, irValue
 	low  = ir_emit_conv(proc, low,  t_int);
 	low  = ir_emit_conv(proc, low,  t_int);
 	high = ir_emit_conv(proc, high, t_int);
 	high = ir_emit_conv(proc, high, t_int);
 
 
-	auto args = array_make_count<irValue *>(proc->module->allocator, 6);
+	auto args = array_make<irValue *>(proc->module->allocator, 6);
 	args[0] = file;
 	args[0] = file;
 	args[1] = line;
 	args[1] = line;
 	args[2] = column;
 	args[2] = column;
@@ -4005,7 +4004,7 @@ irValue *ir_emit_min(irProcedure *proc, Type *t, irValue *x, irValue *y) {
 	if (is_type_float(t)) {
 	if (is_type_float(t)) {
 		gbAllocator a = proc->module->allocator;
 		gbAllocator a = proc->module->allocator;
 		i64 sz = 8*type_size_of(a, t);
 		i64 sz = 8*type_size_of(a, t);
-		auto args = array_make_count<irValue *>(proc->module->allocator, 2);
+		auto args = array_make<irValue *>(proc->module->allocator, 2);
 		args[0] = x;
 		args[0] = x;
 		args[1] = y;
 		args[1] = y;
 		switch (sz) {
 		switch (sz) {
@@ -4023,7 +4022,7 @@ irValue *ir_emit_max(irProcedure *proc, Type *t, irValue *x, irValue *y) {
 	if (is_type_float(t)) {
 	if (is_type_float(t)) {
 		gbAllocator a = proc->module->allocator;
 		gbAllocator a = proc->module->allocator;
 		i64 sz = 8*type_size_of(a, t);
 		i64 sz = 8*type_size_of(a, t);
-		auto args = array_make_count<irValue *>(proc->module->allocator, 2);
+		auto args = array_make<irValue *>(proc->module->allocator, 2);
 		args[0] = x;
 		args[0] = x;
 		args[1] = y;
 		args[1] = y;
 		switch (sz) {
 		switch (sz) {
@@ -4068,7 +4067,7 @@ bool is_double_pointer(Type *t) {
 
 
 irValue *ir_emit_source_code_location(irProcedure *proc, String procedure, TokenPos pos) {
 irValue *ir_emit_source_code_location(irProcedure *proc, String procedure, TokenPos pos) {
 	gbAllocator a = proc->module->allocator;
 	gbAllocator a = proc->module->allocator;
-	auto args = array_make_count<irValue *>(proc->module->allocator, 4);
+	auto args = array_make<irValue *>(proc->module->allocator, 4);
 	args[0] = ir_find_or_add_entity_string(proc->module, pos.file);
 	args[0] = ir_find_or_add_entity_string(proc->module, pos.file);
 	args[1] = ir_const_int(a, pos.line);
 	args[1] = ir_const_int(a, pos.line);
 	args[2] = ir_const_int(a, pos.column);
 	args[2] = ir_const_int(a, pos.column);
@@ -4283,7 +4282,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
 
 
 			TokenPos pos = ast_node_token(ce->args[0]).pos;
 			TokenPos pos = ast_node_token(ce->args[0]).pos;
 
 
-			auto args = array_make_count<irValue *>(proc->module->allocator, 3);
+			auto args = array_make<irValue *>(proc->module->allocator, 3);
 			args[0] = slice_size;
 			args[0] = slice_size;
 			args[1] = elem_align;
 			args[1] = elem_align;
 			args[2] = ir_emit_source_code_location(proc, proc_name, pos);
 			args[2] = ir_emit_source_code_location(proc, proc_name, pos);
@@ -4311,7 +4310,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
 			irValue *map = ir_add_local_generated(proc, type);
 			irValue *map = ir_add_local_generated(proc, type);
 			irValue *header = ir_gen_map_header(proc, map, base_type(type));
 			irValue *header = ir_gen_map_header(proc, map, base_type(type));
 
 
-			auto args = array_make_count<irValue *>(proc->module->allocator, 3);
+			auto args = array_make<irValue *>(proc->module->allocator, 3);
 			args[0] = header;
 			args[0] = header;
 			args[1] = cap;
 			args[1] = cap;
 			args[2] = ir_emit_source_code_location(proc, ce->args[0]);
 			args[2] = ir_emit_source_code_location(proc, ce->args[0]);
@@ -4333,7 +4332,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
 
 
 			irValue *array = ir_add_local_generated(proc, type);
 			irValue *array = ir_add_local_generated(proc, type);
 
 
-			auto args = array_make_count<irValue *>(proc->module->allocator, 6);
+			auto args = array_make<irValue *>(proc->module->allocator, 6);
 			args[0] = ir_emit_conv(proc, array, t_rawptr);
 			args[0] = ir_emit_conv(proc, array, t_rawptr);
 			args[1] = ir_const_int(a, type_size_of(a, elem_type));
 			args[1] = ir_const_int(a, type_size_of(a, elem_type));
 			args[2] = ir_const_int(a, type_align_of(a, elem_type));
 			args[2] = ir_const_int(a, type_align_of(a, elem_type));
@@ -4736,7 +4735,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
 		Type *t = ir_type(x);
 		Type *t = ir_type(x);
 		if (is_type_complex(t)) {
 		if (is_type_complex(t)) {
 			i64 sz = 8*type_size_of(a, t);
 			i64 sz = 8*type_size_of(a, t);
-			auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+			auto args = array_make<irValue *>(proc->module->allocator, 1);
 			args[0] = x;
 			args[0] = x;
 			switch (sz) {
 			switch (sz) {
 			case 64:  return ir_emit_global_call(proc, "__abs_complex64",  args);
 			case 64:  return ir_emit_global_call(proc, "__abs_complex64",  args);
@@ -4745,7 +4744,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
 			GB_PANIC("Unknown complex type");
 			GB_PANIC("Unknown complex type");
 		} else if (is_type_float(t)) {
 		} else if (is_type_float(t)) {
 			i64 sz = 8*type_size_of(a, t);
 			i64 sz = 8*type_size_of(a, t);
-			auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+			auto args = array_make<irValue *>(proc->module->allocator, 1);
 			args[0] = x;
 			args[0] = x;
 			switch (sz) {
 			switch (sz) {
 			case 32: return ir_emit_global_call(proc, "__abs_f32", args);
 			case 32: return ir_emit_global_call(proc, "__abs_f32", args);
@@ -4888,8 +4887,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
 	case_ast_node(te, TernaryExpr, expr);
 	case_ast_node(te, TernaryExpr, expr);
 		ir_emit_comment(proc, str_lit("TernaryExpr"));
 		ir_emit_comment(proc, str_lit("TernaryExpr"));
 
 
-		Array<irValue *> edges = {};
-		array_init(&edges, proc->module->allocator, 2);
+		auto edges = array_make<irValue *>(proc->module->allocator, 0, 2);
 
 
 		GB_ASSERT(te->y != nullptr);
 		GB_ASSERT(te->y != nullptr);
 		irBlock *then  = ir_new_block(proc, nullptr, "if.then");
 		irBlock *then  = ir_new_block(proc, nullptr, "if.then");
@@ -4918,47 +4916,6 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
 		return ir_emit(proc, ir_instr_phi(proc, edges, type));
 		return ir_emit(proc, ir_instr_phi(proc, edges, type));
 	case_end;
 	case_end;
 
 
-#if 0
-	case_ast_node(ie, IfExpr, expr);
-		ir_emit_comment(proc, str_lit("IfExpr"));
-		if (ie->init != nullptr) {
-			irBlock *init = ir_new_block(proc, expr, "if.init");
-			ir_emit_jump(proc, init);
-			ir_start_block(proc, init);
-			ir_build_stmt(proc, ie->init);
-		}
-
-		Array<irValue *> edges = {};
-		array_init(&edges, proc->module->allocator, 2);
-
-		GB_ASSERT(ie->else_expr != nullptr);
-		irBlock *then  = ir_new_block(proc, expr, "if.then");
-		irBlock *done  = ir_new_block(proc, expr, "if.done"); // NOTE(bill): Append later
-		irBlock *else_ = ir_new_block(proc, ie->else_expr, "if.else");
-
-		irValue *cond = ir_build_cond(proc, ie->cond, then, else_);
-		ir_start_block(proc, then);
-
-		ir_open_scope(proc);
-		array_add(&edges, ir_build_expr(proc, ie->body));
-		ir_close_scope(proc, irDeferExit_Default, nullptr);
-
-		ir_emit_jump(proc, done);
-		ir_start_block(proc, else_);
-
-		ir_open_scope(proc);
-		array_add(&edges, ir_build_expr(proc, ie->else_expr));
-		ir_close_scope(proc, irDeferExit_Default, nullptr);
-
-		ir_emit_jump(proc, done);
-		ir_start_block(proc, done);
-
-		Type *type = type_of_expr(proc->module->info, expr);
-
-		return ir_emit(proc, ir_instr_phi(proc, edges, type));
-	case_end;
-#endif
-
 	case_ast_node(ta, TypeAssertion, expr);
 	case_ast_node(ta, TypeAssertion, expr);
 		TokenPos pos = ast_node_token(expr).pos;
 		TokenPos pos = ast_node_token(expr).pos;
 		Type *type = tv.type;
 		Type *type = tv.type;
@@ -5019,7 +4976,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
 					irValue *dst_tag = ir_const_union_tag(a, src_type, dst_type);
 					irValue *dst_tag = ir_const_union_tag(a, src_type, dst_type);
 
 
 					irValue *ok = ir_emit_comp(proc, Token_CmpEq, src_tag, dst_tag);
 					irValue *ok = ir_emit_comp(proc, Token_CmpEq, src_tag, dst_tag);
-					auto args = array_make_count<irValue *>(proc->module->allocator, 6);
+					auto args = array_make<irValue *>(proc->module->allocator, 6);
 					args[0] = ok;
 					args[0] = ok;
 
 
 					args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
 					args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
@@ -5044,7 +5001,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
 
 
 
 
 					irValue *ok = ir_emit_comp(proc, Token_CmpEq, any_ti, ti_ptr);
 					irValue *ok = ir_emit_comp(proc, Token_CmpEq, any_ti, ti_ptr);
-					auto args = array_make_count<irValue *>(proc->module->allocator, 6);
+					auto args = array_make<irValue *>(proc->module->allocator, 6);
 					args[0] = ok;
 					args[0] = ok;
 
 
 					args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
 					args[1] = ir_find_or_add_entity_string(proc->module, pos.file);
@@ -5896,7 +5853,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 			}
 			}
 			gbAllocator a = proc->module->allocator;
 			gbAllocator a = proc->module->allocator;
 			{
 			{
-				auto args = array_make_count<irValue *>(a, 3);
+				auto args = array_make<irValue *>(a, 3);
 				args[0] = ir_gen_map_header(proc, v, type);
 				args[0] = ir_gen_map_header(proc, v, type);
 				args[1] = ir_const_int(a, 2*cl->elems.count);
 				args[1] = ir_const_int(a, 2*cl->elems.count);
 				args[2] = ir_emit_source_code_location(proc, proc_name, pos);
 				args[2] = ir_emit_source_code_location(proc, proc_name, pos);
@@ -5922,7 +5879,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 			irValue *size  = ir_const_int(a, type_size_of(a, elem));
 			irValue *size  = ir_const_int(a, type_size_of(a, elem));
 			irValue *align = ir_const_int(a, type_align_of(a, elem));
 			irValue *align = ir_const_int(a, type_align_of(a, elem));
 			{
 			{
-				auto args = array_make_count<irValue *>(a, 5);
+				auto args = array_make<irValue *>(a, 5);
 				args[0] = ir_emit_conv(proc, v, t_rawptr);
 				args[0] = ir_emit_conv(proc, v, t_rawptr);
 				args[1] = size;
 				args[1] = size;
 				args[2] = align;
 				args[2] = align;
@@ -5942,7 +5899,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 			}
 			}
 
 
 			{
 			{
-				auto args = array_make_count<irValue *>(a, 6);
+				auto args = array_make<irValue *>(a, 6);
 				args[0] = ir_emit_conv(proc, v, t_rawptr);
 				args[0] = ir_emit_conv(proc, v, t_rawptr);
 				args[1] = size;
 				args[1] = size;
 				args[2] = align;
 				args[2] = align;
@@ -6471,7 +6428,7 @@ void ir_build_range_string(irProcedure *proc, irValue *expr, Type *val_type,
 
 
 	irValue *str_elem = ir_emit_ptr_offset(proc, ir_string_elem(proc, expr), offset);
 	irValue *str_elem = ir_emit_ptr_offset(proc, ir_string_elem(proc, expr), offset);
 	irValue *str_len  = ir_emit_arith(proc, Token_Sub, count, offset, t_int);
 	irValue *str_len  = ir_emit_arith(proc, Token_Sub, count, offset, t_int);
-	auto args = array_make_count<irValue *>(proc->module->allocator, 1);
+	auto args = array_make<irValue *>(proc->module->allocator, 1);
 	args[0] = ir_emit_string(proc, str_elem, str_len);
 	args[0] = ir_emit_string(proc, str_elem, str_len);
 	irValue *rune_and_len = ir_emit_global_call(proc, "__string_decode_rune", args);
 	irValue *rune_and_len = ir_emit_global_call(proc, "__string_decode_rune", args);
 	irValue *len  = ir_emit_struct_ev(proc, rune_and_len, 1);
 	irValue *len  = ir_emit_struct_ev(proc, rune_and_len, 1);
@@ -6613,10 +6570,8 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 					}
 					}
 				}
 				}
 			} else { // Tuple(s)
 			} else { // Tuple(s)
-				Array<irAddr>    lvals = {};
-				Array<irValue *> inits = {};
-				array_init(&lvals, m->tmp_allocator, vd->names.count);
-				array_init(&inits, m->tmp_allocator, vd->names.count);
+				auto lvals = array_make<irAddr>(m->tmp_allocator, 0, vd->names.count);
+				auto inits = array_make<irValue *>(m->tmp_allocator, 0, vd->names.count);
 
 
 				for_array(i, vd->names) {
 				for_array(i, vd->names) {
 					AstNode *name = vd->names[i];
 					AstNode *name = vd->names[i];
@@ -6660,8 +6615,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 
 
 		switch (as->op.kind) {
 		switch (as->op.kind) {
 		case Token_Eq: {
 		case Token_Eq: {
-			Array<irAddr> lvals;
-			array_init(&lvals, m->tmp_allocator);
+			auto lvals = array_make<irAddr>(m->tmp_allocator);
 
 
 			for_array(i, as->lhs) {
 			for_array(i, as->lhs) {
 				AstNode *lhs = as->lhs[i];
 				AstNode *lhs = as->lhs[i];
@@ -6678,8 +6632,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 					irValue *init = ir_build_expr(proc, rhs);
 					irValue *init = ir_build_expr(proc, rhs);
 					ir_addr_store(proc, lvals[0], init);
 					ir_addr_store(proc, lvals[0], init);
 				} else {
 				} else {
-					Array<irValue *> inits;
-					array_init(&inits, m->tmp_allocator, lvals.count);
+					auto inits = array_make<irValue *>(m->tmp_allocator, 0, lvals.count);
 
 
 					for_array(i, as->rhs) {
 					for_array(i, as->rhs) {
 						irValue *init = ir_build_expr(proc, as->rhs[i]);
 						irValue *init = ir_build_expr(proc, as->rhs[i]);
@@ -6691,8 +6644,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 					}
 					}
 				}
 				}
 			} else {
 			} else {
-				Array<irValue *> inits;
-				array_init(&inits, m->tmp_allocator, lvals.count);
+				auto inits = array_make<irValue *>(m->tmp_allocator, 0, lvals.count);
 
 
 				for_array(i, as->rhs) {
 				for_array(i, as->rhs) {
 					irValue *init = ir_build_expr(proc, as->rhs[i]);
 					irValue *init = ir_build_expr(proc, as->rhs[i]);
@@ -6774,8 +6726,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
 			defer (gb_temp_arena_memory_end(tmp));
 			defer (gb_temp_arena_memory_end(tmp));
 
 
-			Array<irValue *> results;
-			array_init(&results, proc->module->tmp_allocator, return_count);
+			auto results = array_make<irValue *>(proc->module->tmp_allocator, 0, return_count);
 
 
 			if (res_count != 0) {
 			if (res_count != 0) {
 				for (isize res_index = 0; res_index < res_count; res_index++) {
 				for (isize res_index = 0; res_index < res_count; res_index++) {
@@ -8309,8 +8260,7 @@ void ir_gen_tree(irGen *s) {
 		irValue *var, *init;
 		irValue *var, *init;
 		DeclInfo *decl;
 		DeclInfo *decl;
 	};
 	};
-	Array<irGlobalVariable> global_variables;
-	array_init(&global_variables, m->tmp_allocator, global_variable_max_count);
+	auto global_variables = array_make<irGlobalVariable>(m->tmp_allocator, 0, global_variable_max_count);
 
 
 	m->entry_point_entity = entry_point;
 	m->entry_point_entity = entry_point;
 	m->min_dep_set = info->minimum_dependency_set;
 	m->min_dep_set = info->minimum_dependency_set;
@@ -8483,7 +8433,7 @@ 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, 0, all_proc_max_count);
 	map_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;
 
 
@@ -8505,8 +8455,8 @@ void ir_gen_tree(irGen *s) {
 
 
 		Scope *proc_scope = gb_alloc_item(a, Scope);
 		Scope *proc_scope = gb_alloc_item(a, Scope);
 
 
-		array_init_count(&proc_params->Tuple.variables, a, 3);
-		array_init_count(&proc_results->Tuple.variables, a, 1);
+		array_init(&proc_params->Tuple.variables, a, 3);
+		array_init(&proc_results->Tuple.variables, a, 1);
 
 
 		proc_params->Tuple.variables[0] = make_entity_param(a, proc_scope, blank_token, t_rawptr, false, false);
 		proc_params->Tuple.variables[0] = make_entity_param(a, proc_scope, blank_token, t_rawptr, false, false);
 		proc_params->Tuple.variables[1] = make_entity_param(a, proc_scope, make_token_ident(str_lit("reason")), t_i32, false, false);
 		proc_params->Tuple.variables[1] = make_entity_param(a, proc_scope, make_token_ident(str_lit("reason")), t_i32, false, false);
@@ -8583,8 +8533,8 @@ void ir_gen_tree(irGen *s) {
 
 
 		Scope *proc_scope = gb_alloc_item(a, Scope);
 		Scope *proc_scope = gb_alloc_item(a, Scope);
 
 
-		array_init_count(&proc_params->Tuple.variables, a, 2);
-		array_init_count(&proc_results->Tuple.variables, a, 1);
+		array_init(&proc_params->Tuple.variables, a, 2);
+		array_init(&proc_results->Tuple.variables, a, 1);
 
 
 		Type *char_ptr_ptr = make_type_pointer(a, make_type_pointer(a, t_u8));
 		Type *char_ptr_ptr = make_type_pointer(a, make_type_pointer(a, t_u8));
 		proc_params->Tuple.variables[0] = make_entity_param(a, proc_scope, make_token_ident(str_lit("argc")), t_i32, false, false);
 		proc_params->Tuple.variables[0] = make_entity_param(a, proc_scope, make_token_ident(str_lit("argc")), t_i32, false, false);

+ 2 - 2
src/ir_opt.cpp

@@ -276,8 +276,8 @@ void ir_opt_blocks(irProcedure *proc) {
 void ir_opt_build_referrers(irProcedure *proc) {
 void ir_opt_build_referrers(irProcedure *proc) {
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
 	gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
 
 
-	Array<irValue *> ops = {0}; // NOTE(bill): Act as a buffer
-	array_init(&ops, proc->module->tmp_allocator, 64); // HACK(bill): This _could_ overflow the temp arena
+	// NOTE(bill): Acta as a buffer
+	auto ops = array_make<irValue *>(proc->module->tmp_allocator, 0, 64); // TODO HACK(bill): This _could_ overflow the temp arena
 	for_array(i, proc->blocks) {
 	for_array(i, proc->blocks) {
 		irBlock *b = proc->blocks[i];
 		irBlock *b = proc->blocks[i];
 		for_array(j, b->instrs) {
 		for_array(j, b->instrs) {

+ 4 - 6
src/main.cpp

@@ -120,7 +120,7 @@ Array<String> setup_args(int argc, char **argv) {
 #if defined(GB_SYSTEM_WINDOWS)
 #if defined(GB_SYSTEM_WINDOWS)
 	int wargc = 0;
 	int wargc = 0;
 	wchar_t **wargv = command_line_to_wargv(GetCommandLineW(), &wargc);
 	wchar_t **wargv = command_line_to_wargv(GetCommandLineW(), &wargc);
-	array_init(&args, a, wargc);
+	args = array_make<String>(a, 0, wargc);
 	for (i = 0; i < wargc; i++) {
 	for (i = 0; i < wargc; i++) {
 		wchar_t *warg = wargv[i];
 		wchar_t *warg = wargv[i];
 		isize wlen = string16_len(warg);
 		isize wlen = string16_len(warg);
@@ -132,7 +132,7 @@ Array<String> setup_args(int argc, char **argv) {
 	}
 	}
 
 
 #else
 #else
-	array_init(&args, a, argc);
+	args = array_make<String>(a, 0, argc);
 	for (i = 0; i < argc; i++) {
 	for (i = 0; i < argc; i++) {
 		String arg = make_string_c(argv[i]);
 		String arg = make_string_c(argv[i]);
 		if (arg.len > 0) {
 		if (arg.len > 0) {
@@ -241,8 +241,7 @@ void add_flag(Array<BuildFlag> *build_flags, BuildFlagKind kind, String name, Bu
 }
 }
 
 
 bool parse_build_flags(Array<String> args) {
 bool parse_build_flags(Array<String> args) {
-	Array<BuildFlag> build_flags = {};
-	array_init(&build_flags, heap_allocator(), BuildFlag_COUNT);
+	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	add_flag(&build_flags, BuildFlag_OutFile,           str_lit("out"),             BuildFlagParam_String);
 	add_flag(&build_flags, BuildFlag_OutFile,           str_lit("out"),             BuildFlagParam_String);
 	add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"),             BuildFlagParam_Integer);
 	add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"),             BuildFlagParam_Integer);
 	add_flag(&build_flags, BuildFlag_ShowTimings,       str_lit("show-timings"),    BuildFlagParam_None);
 	add_flag(&build_flags, BuildFlag_ShowTimings,       str_lit("show-timings"),    BuildFlagParam_None);
@@ -594,8 +593,7 @@ void show_timings(Checker *c, Timings *t) {
 void remove_temp_files(String output_base) {
 void remove_temp_files(String output_base) {
 	if (build_context.keep_temp_files) return;
 	if (build_context.keep_temp_files) return;
 
 
-	Array<u8> data = {};
-	array_init_count(&data, heap_allocator(), output_base.len + 10);
+	auto data = array_make<u8>(heap_allocator(), output_base.len + 10);
 	defer (array_free(&data));
 	defer (array_free(&data));
 
 
 	isize n = output_base.len;
 	isize n = output_base.len;

+ 5 - 3
src/map.cpp

@@ -136,13 +136,15 @@ template <typename T> void  multi_map_remove_all(Map<T> *h, HashKey key);
 
 
 template <typename T>
 template <typename T>
 gb_inline void map_init(Map<T> *h, gbAllocator a, isize capacity) {
 gb_inline void map_init(Map<T> *h, gbAllocator a, isize capacity) {
-	array_init(&h->hashes,  a, capacity);
-	array_init(&h->entries, a, capacity);}
+	array_init(&h->hashes,  a, 0, capacity);
+	array_init(&h->entries, a, 0, capacity);
+}
 
 
 template <typename T>
 template <typename T>
 gb_inline void map_destroy(Map<T> *h) {
 gb_inline void map_destroy(Map<T> *h) {
 	array_free(&h->entries);
 	array_free(&h->entries);
-	array_free(&h->hashes);}
+	array_free(&h->hashes);
+}
 
 
 template <typename T>
 template <typename T>
 gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
 gb_internal isize map__add_entry(Map<T> *h, HashKey key) {

+ 32 - 31
src/parser.cpp

@@ -101,7 +101,7 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node);
 Array<AstNode *> clone_ast_node_array(gbAllocator a, Array<AstNode *> array) {
 Array<AstNode *> clone_ast_node_array(gbAllocator a, Array<AstNode *> array) {
 	Array<AstNode *> result = {};
 	Array<AstNode *> result = {};
 	if (array.count > 0) {
 	if (array.count > 0) {
-		array_init_count(&result, a, array.count);
+		result = array_make<AstNode *>(a, array.count);
 		for_array(i, array) {
 		for_array(i, array) {
 			result[i] = clone_ast_node(a, array[i]);
 			result[i] = clone_ast_node(a, array[i]);
 		}
 		}
@@ -1413,7 +1413,7 @@ AstNode *unparen_expr(AstNode *node) {
 AstNode *parse_value(AstFile *f);
 AstNode *parse_value(AstFile *f);
 
 
 Array<AstNode *> parse_element_list(AstFile *f) {
 Array<AstNode *> parse_element_list(AstFile *f) {
-	Array<AstNode *> elems = make_ast_node_array(f);
+	auto elems = array_make<AstNode *>(heap_allocator());
 
 
 	while (f->curr_token.kind != Token_CloseBrace &&
 	while (f->curr_token.kind != Token_CloseBrace &&
 	       f->curr_token.kind != Token_EOF) {
 	       f->curr_token.kind != Token_EOF) {
@@ -1581,7 +1581,7 @@ AstNode *convert_stmt_to_body(AstFile *f, AstNode *stmt) {
 	GB_ASSERT(is_ast_node_stmt(stmt) || is_ast_node_decl(stmt));
 	GB_ASSERT(is_ast_node_stmt(stmt) || is_ast_node_decl(stmt));
 	Token open = ast_node_token(stmt);
 	Token open = ast_node_token(stmt);
 	Token close = ast_node_token(stmt);
 	Token close = ast_node_token(stmt);
-	Array<AstNode *> stmts = make_ast_node_array(f, 1);
+	auto stmts = array_make<AstNode *>(heap_allocator(), 0, 1);
 	array_add(&stmts, stmt);
 	array_add(&stmts, stmt);
 	return ast_block_stmt(f, stmts, open, close);
 	return ast_block_stmt(f, stmts, open, close);
 }
 }
@@ -1701,8 +1701,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
 		if (f->curr_token.kind == Token_OpenBracket) { // ProcGroup
 		if (f->curr_token.kind == Token_OpenBracket) { // ProcGroup
 			Token open = expect_token(f, Token_OpenBracket);
 			Token open = expect_token(f, Token_OpenBracket);
 
 
-			Array<AstNode *> args = {};
-			array_init(&args, heap_allocator());
+			auto args = array_make<AstNode *>(heap_allocator());
 
 
 			while (f->curr_token.kind != Token_CloseBracket &&
 			while (f->curr_token.kind != Token_CloseBracket &&
 			       f->curr_token.kind != Token_EOF) {
 			       f->curr_token.kind != Token_EOF) {
@@ -1887,7 +1886,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
 	case Token_union: {
 	case Token_union: {
 		Token token = expect_token(f, Token_union);
 		Token token = expect_token(f, Token_union);
 		Token open = expect_token_after(f, Token_OpenBrace, "union");
 		Token open = expect_token_after(f, Token_OpenBrace, "union");
-		Array<AstNode *> variants = make_ast_node_array(f);
+		auto variants = array_make<AstNode *>(heap_allocator());
 		isize total_decl_name_count = 0;
 		isize total_decl_name_count = 0;
 		AstNode *align = nullptr;
 		AstNode *align = nullptr;
 
 
@@ -1956,7 +1955,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
 
 
 	case Token_bit_field: {
 	case Token_bit_field: {
 		Token token = expect_token(f, Token_bit_field);
 		Token token = expect_token(f, Token_bit_field);
-		Array<AstNode *> fields = make_ast_node_array(f);
+		auto fields = array_make<AstNode *>(heap_allocator());
 		AstNode *align = nullptr;
 		AstNode *align = nullptr;
 		Token open, close;
 		Token open, close;
 
 
@@ -2036,7 +2035,7 @@ bool is_literal_type(AstNode *node) {
 }
 }
 
 
 AstNode *parse_call_expr(AstFile *f, AstNode *operand) {
 AstNode *parse_call_expr(AstFile *f, AstNode *operand) {
-	Array<AstNode *> args = make_ast_node_array(f);
+	auto args = array_make<AstNode *>(heap_allocator());
 	Token open_paren, close_paren;
 	Token open_paren, close_paren;
 	Token ellipsis = {};
 	Token ellipsis = {};
 
 
@@ -2322,7 +2321,7 @@ AstNode *parse_expr(AstFile *f, bool lhs) {
 
 
 
 
 Array<AstNode *> parse_expr_list(AstFile *f, bool lhs) {
 Array<AstNode *> parse_expr_list(AstFile *f, bool lhs) {
-	Array<AstNode *> list = make_ast_node_array(f);
+	auto list = array_make<AstNode *>(heap_allocator());
 	for (;;) {
 	for (;;) {
 		AstNode *e = parse_expr(f, lhs);
 		AstNode *e = parse_expr(f, lhs);
 		array_add(&list, e);
 		array_add(&list, e);
@@ -2345,16 +2344,16 @@ Array<AstNode *> parse_rhs_expr_list(AstFile *f) {
 }
 }
 
 
 Array<AstNode *> parse_ident_list(AstFile *f) {
 Array<AstNode *> parse_ident_list(AstFile *f) {
-	Array<AstNode *> list = make_ast_node_array(f);
+	auto list = array_make<AstNode *>(heap_allocator());
 
 
-	do {
+	for (;;) {
 		array_add(&list, parse_ident(f));
 		array_add(&list, parse_ident(f));
 		if (f->curr_token.kind != Token_Comma ||
 		if (f->curr_token.kind != Token_Comma ||
 		    f->curr_token.kind == Token_EOF) {
 		    f->curr_token.kind == Token_EOF) {
 		    break;
 		    break;
 		}
 		}
 		advance_token(f);
 		advance_token(f);
-	} while (true);
+	}
 
 
 	return list;
 	return list;
 }
 }
@@ -2398,7 +2397,7 @@ AstNode *parse_foreign_block(AstFile *f, Token token) {
 	}
 	}
 	Token open = {};
 	Token open = {};
 	Token close = {};
 	Token close = {};
-	Array<AstNode *> decls = make_ast_node_array(f);
+	auto decls = array_make<AstNode *>(heap_allocator());
 
 
 	bool prev_in_foreign_block = f->in_foreign_block;
 	bool prev_in_foreign_block = f->in_foreign_block;
 	defer (f->in_foreign_block = prev_in_foreign_block);
 	defer (f->in_foreign_block = prev_in_foreign_block);
@@ -2468,7 +2467,7 @@ AstNode *parse_value_decl(AstFile *f, Array<AstNode *> names, CommentGroup docs)
 	}
 	}
 
 
 	if (values.data == nullptr) {
 	if (values.data == nullptr) {
-		values = make_ast_node_array(f);
+		values = array_make<AstNode *>(heap_allocator());
 	}
 	}
 
 
 	if (f->expr_level >= 0) {
 	if (f->expr_level >= 0) {
@@ -2531,7 +2530,7 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) {
 			AstNode *expr = parse_expr(f, false);
 			AstNode *expr = parse_expr(f, false);
 			f->allow_range = prev_allow_range;
 			f->allow_range = prev_allow_range;
 
 
-			Array<AstNode *> rhs = make_ast_node_array(f, 1);
+			auto rhs = array_make<AstNode *>(heap_allocator(), 0, 1);
 			array_add(&rhs, expr);
 			array_add(&rhs, expr);
 
 
 			return ast_assign_stmt(f, token, lhs, rhs);
 			return ast_assign_stmt(f, token, lhs, rhs);
@@ -2610,7 +2609,7 @@ AstNode *parse_results(AstFile *f) {
 		CommentGroup empty_group = {};
 		CommentGroup empty_group = {};
 		Token begin_token = f->curr_token;
 		Token begin_token = f->curr_token;
 		Array<AstNode *> empty_names = {};
 		Array<AstNode *> empty_names = {};
-		Array<AstNode *> list = make_ast_node_array(f, 1);
+		auto list = array_make<AstNode *>(heap_allocator(), 0, 1);
 		AstNode *type = parse_type(f);
 		AstNode *type = parse_type(f);
 		array_add(&list, ast_field(f, empty_names, type, nullptr, 0, empty_group, empty_group));
 		array_add(&list, ast_field(f, empty_names, type, nullptr, 0, empty_group, empty_group));
 		return ast_field_list(f, begin_token, list);
 		return ast_field_list(f, begin_token, list);
@@ -2814,7 +2813,7 @@ struct AstNodeAndFlags {
 };
 };
 
 
 Array<AstNode *> convert_to_ident_list(AstFile *f, Array<AstNodeAndFlags> list, bool ignore_flags) {
 Array<AstNode *> convert_to_ident_list(AstFile *f, Array<AstNodeAndFlags> list, bool ignore_flags) {
-	Array<AstNode *> idents = make_ast_node_array(f, list.count);
+	auto idents = array_make<AstNode *>(heap_allocator(), 0, list.count);
 	// Convert to ident list
 	// Convert to ident list
 	for_array(i, list) {
 	for_array(i, list) {
 		AstNode *ident = list[i].node;
 		AstNode *ident = list[i].node;
@@ -2880,7 +2879,7 @@ AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) {
 	CommentGroup docs = f->lead_comment;
 	CommentGroup docs = f->lead_comment;
 	Token start_token = f->curr_token;
 	Token start_token = f->curr_token;
 
 
-	Array<AstNode *> decls = make_ast_node_array(f);
+	auto decls = array_make<AstNode *>(heap_allocator());
 
 
 	isize total_name_count = 0;
 	isize total_name_count = 0;
 
 
@@ -2895,9 +2894,9 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
 
 
 	CommentGroup docs = f->lead_comment;
 	CommentGroup docs = f->lead_comment;
 
 
-	Array<AstNode *> params = make_ast_node_array(f);
+	auto params = array_make<AstNode *>(heap_allocator());
 
 
-	Array<AstNodeAndFlags> list = {}; array_init(&list, heap_allocator());
+	auto list = array_make<AstNodeAndFlags>(heap_allocator());
 	defer (array_free(&list));
 	defer (array_free(&list));
 
 
 	isize total_name_count = 0;
 	isize total_name_count = 0;
@@ -3027,7 +3026,6 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
 	}
 	}
 
 
 	for_array(i, list) {
 	for_array(i, list) {
-		Array<AstNode *> names = {};
 		AstNode *type = list[i].node;
 		AstNode *type = list[i].node;
 		Token token = blank_token;
 		Token token = blank_token;
 		if (allowed_flags&FieldFlag_Results) {
 		if (allowed_flags&FieldFlag_Results) {
@@ -3035,7 +3033,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
 			token.string = str_lit("");
 			token.string = str_lit("");
 		}
 		}
 
 
-		array_init_count(&names, heap_allocator(), 1);
+		auto names = array_make<AstNode *>(heap_allocator(), 1);
 		token.pos = ast_node_token(type).pos;
 		token.pos = ast_node_token(type).pos;
 		names[0] = ast_ident(f, token);
 		names[0] = ast_ident(f, token);
 		u32 flags = check_field_prefixes(f, list.count, allowed_flags, list[i].flags);
 		u32 flags = check_field_prefixes(f, list.count, allowed_flags, list[i].flags);
@@ -3203,7 +3201,7 @@ AstNode *parse_return_stmt(AstFile *f) {
 	}
 	}
 
 
 	Token token = expect_token(f, Token_return);
 	Token token = expect_token(f, Token_return);
-	Array<AstNode *> results = make_ast_node_array(f);
+	auto results = array_make<AstNode *>(heap_allocator());
 
 
 	while (f->curr_token.kind != Token_Semicolon) {
 	while (f->curr_token.kind != Token_Semicolon) {
 		AstNode *arg = parse_expr(f, false);
 		AstNode *arg = parse_expr(f, false);
@@ -3352,7 +3350,7 @@ AstNode *parse_switch_stmt(AstFile *f) {
 	AstNode *body = nullptr;
 	AstNode *body = nullptr;
 	Token open, close;
 	Token open, close;
 	bool is_type_match = false;
 	bool is_type_match = false;
-	Array<AstNode *> list = make_ast_node_array(f);
+	auto list = array_make<AstNode *>(heap_allocator());
 
 
 	if (f->curr_token.kind != Token_OpenBrace) {
 	if (f->curr_token.kind != Token_OpenBrace) {
 		isize prev_level = f->expr_level;
 		isize prev_level = f->expr_level;
@@ -3360,8 +3358,8 @@ AstNode *parse_switch_stmt(AstFile *f) {
 		defer (f->expr_level = prev_level);
 		defer (f->expr_level = prev_level);
 
 
 		if (allow_token(f, Token_in)) {
 		if (allow_token(f, Token_in)) {
-			Array<AstNode *> lhs = make_ast_node_array(f, 1);
-			Array<AstNode *> rhs = make_ast_node_array(f, 1);
+			auto lhs = array_make<AstNode *>(heap_allocator(), 0, 1);
+			auto rhs = array_make<AstNode *>(heap_allocator(), 0, 1);
 			Token blank_ident = token;
 			Token blank_ident = token;
 			blank_ident.kind = Token_Ident;
 			blank_ident.kind = Token_Ident;
 			blank_ident.string = str_lit("_");
 			blank_ident.string = str_lit("_");
@@ -3663,7 +3661,7 @@ AstNode *parse_stmt(AstFile *f) {
 		Token open = expect_token(f, Token_OpenParen);
 		Token open = expect_token(f, Token_OpenParen);
 		f->expr_level++;
 		f->expr_level++;
 		if (f->curr_token.kind != Token_CloseParen) {
 		if (f->curr_token.kind != Token_CloseParen) {
-			elems = make_ast_node_array(f);
+			elems = array_make<AstNode *>(heap_allocator());
 			while (f->curr_token.kind != Token_CloseParen &&
 			while (f->curr_token.kind != Token_CloseParen &&
 			       f->curr_token.kind != Token_EOF) {
 			       f->curr_token.kind != Token_EOF) {
 				AstNode *elem = parse_ident(f);
 				AstNode *elem = parse_ident(f);
@@ -3777,7 +3775,7 @@ AstNode *parse_stmt(AstFile *f) {
 }
 }
 
 
 Array<AstNode *> parse_stmt_list(AstFile *f) {
 Array<AstNode *> parse_stmt_list(AstFile *f) {
-	Array<AstNode *> list = make_ast_node_array(f);
+	auto list = array_make<AstNode *>(heap_allocator());
 
 
 	while (f->curr_token.kind != Token_case &&
 	while (f->curr_token.kind != Token_case &&
 	       f->curr_token.kind != Token_CloseBrace &&
 	       f->curr_token.kind != Token_CloseBrace &&
@@ -3798,6 +3796,7 @@ Array<AstNode *> parse_stmt_list(AstFile *f) {
 
 
 
 
 ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) {
 ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) {
+	GB_ASSERT(f != nullptr);
 	f->fullpath = string_trim_whitespace(fullpath); // Just in case
 	f->fullpath = string_trim_whitespace(fullpath); // Just in case
 	if (!string_ends_with(f->fullpath, str_lit(".odin"))) {
 	if (!string_ends_with(f->fullpath, str_lit(".odin"))) {
 		return ParseFile_WrongExtension;
 		return ParseFile_WrongExtension;
@@ -3819,7 +3818,7 @@ ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) {
 
 
 	isize file_size = f->tokenizer.end - f->tokenizer.start;
 	isize file_size = f->tokenizer.end - f->tokenizer.start;
 	isize init_token_cap = cast(isize)gb_max(next_pow2(cast(i64)(file_size/2ll)), 16);
 	isize init_token_cap = cast(isize)gb_max(next_pow2(cast(i64)(file_size/2ll)), 16);
-	array_init(&f->tokens, heap_allocator(), gb_max(init_token_cap, 16));
+	array_init(&f->tokens, heap_allocator(), 0, gb_max(init_token_cap, 16));
 
 
 	if (err == TokenizerInit_Empty) {
 	if (err == TokenizerInit_Empty) {
 		Token token = {Token_EOF};
 		Token token = {Token_EOF};
@@ -3861,6 +3860,7 @@ ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) {
 }
 }
 
 
 void destroy_ast_file(AstFile *f) {
 void destroy_ast_file(AstFile *f) {
+	GB_ASSERT(f != nullptr);
 	gb_arena_free(&f->arena);
 	gb_arena_free(&f->arena);
 	array_free(&f->tokens);
 	array_free(&f->tokens);
 	array_free(&f->comments);
 	array_free(&f->comments);
@@ -3870,6 +3870,7 @@ void destroy_ast_file(AstFile *f) {
 }
 }
 
 
 bool init_parser(Parser *p) {
 bool init_parser(Parser *p) {
+	GB_ASSERT(p != nullptr);
 	array_init(&p->files, heap_allocator());
 	array_init(&p->files, heap_allocator());
 	array_init(&p->imports, heap_allocator());
 	array_init(&p->imports, heap_allocator());
 	gb_mutex_init(&p->file_add_mutex);
 	gb_mutex_init(&p->file_add_mutex);
@@ -3878,6 +3879,7 @@ bool init_parser(Parser *p) {
 }
 }
 
 
 void destroy_parser(Parser *p) {
 void destroy_parser(Parser *p) {
+	GB_ASSERT(p != nullptr);
 	// TODO(bill): Fix memory leak
 	// TODO(bill): Fix memory leak
 	for_array(i, p->files) {
 	for_array(i, p->files) {
 		destroy_ast_file(p->files[i]);
 		destroy_ast_file(p->files[i]);
@@ -4274,8 +4276,7 @@ ParseFileError parse_files(Parser *p, String init_filename) {
 			curr_import_index++;
 			curr_import_index++;
 		}
 		}
 
 
-		Array<gbThread> worker_threads = {};
-		array_init_count(&worker_threads, heap_allocator(), thread_count);
+		auto worker_threads = array_make<gbThread>(heap_allocator(), thread_count);
 		defer (array_free(&worker_threads));
 		defer (array_free(&worker_threads));
 
 
 		for_array(i, worker_threads) {
 		for_array(i, worker_threads) {

+ 0 - 7
src/parser.hpp

@@ -148,13 +148,6 @@ enum StmtAllowFlag {
 
 
 
 
 
 
-Array<AstNode *> make_ast_node_array(AstFile *f, isize init_capacity = 8) {
-	Array<AstNode *> a;
-	array_init(&a, heap_allocator(), init_capacity);
-	return a;
-}
-
-
 // NOTE(bill): This massive define is so it is possible to create a discriminated union (and extra debug info)
 // NOTE(bill): This massive define is so it is possible to create a discriminated union (and extra debug info)
 // for the AstNode. I personally prefer discriminated unions over subtype polymorphism as I can preallocate
 // for the AstNode. I personally prefer discriminated unions over subtype polymorphism as I can preallocate
 // all the nodes and even memcpy in a different kind of node
 // all the nodes and even memcpy in a different kind of node

+ 5 - 3
src/ptr_set.cpp

@@ -29,13 +29,15 @@ template <typename T> void ptr_set_rehash (PtrSet<T> *s, isize new_count);
 
 
 template <typename T>
 template <typename T>
 void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
 void ptr_set_init(PtrSet<T> *s, gbAllocator a, isize capacity) {
-	array_init(&s->hashes,  a, capacity);
-	array_init(&s->entries, a, capacity);}
+	array_init(&s->hashes,  a, 0, capacity);
+	array_init(&s->entries, a, 0, capacity);
+}
 
 
 template <typename T>
 template <typename T>
 void ptr_set_destroy(PtrSet<T> *s) {
 void ptr_set_destroy(PtrSet<T> *s) {
 	array_free(&s->hashes);
 	array_free(&s->hashes);
-	array_free(&s->entries);}
+	array_free(&s->entries);
+}
 
 
 template <typename T>
 template <typename T>
 gb_internal isize ptr_set__add_entry(PtrSet<T> *s, T ptr) {
 gb_internal isize ptr_set__add_entry(PtrSet<T> *s, T ptr) {

+ 1 - 1
src/timings.cpp

@@ -84,7 +84,7 @@ TimeStamp make_time_stamp(String label) {
 }
 }
 
 
 void timings_init(Timings *t, String label, isize buffer_size) {
 void timings_init(Timings *t, String label, isize buffer_size) {
-	array_init(&t->sections, heap_allocator(), buffer_size);
+	array_init(&t->sections, heap_allocator(), 0, buffer_size);
 	t->total = make_time_stamp(label);
 	t->total = make_time_stamp(label);
 	t->freq  = time_stamp__freq();
 	t->freq  = time_stamp__freq();
 }
 }

+ 4 - 8
src/types.cpp

@@ -1522,8 +1522,7 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
 			Entity *f = type->Struct.fields[i];
 			Entity *f = type->Struct.fields[i];
 			if (f->kind == Entity_Variable) {
 			if (f->kind == Entity_Variable) {
 				if (f->Variable.field_src_index == index) {
 				if (f->Variable.field_src_index == index) {
-					Array<i32> sel_array = {0};
-					array_init_count(&sel_array, a, 1);
+					auto sel_array = array_make<i32>(a, 1);
 					sel_array[0] = cast(i32)i;
 					sel_array[0] = cast(i32)i;
 					return make_selection(f, sel_array, false);
 					return make_selection(f, sel_array, false);
 				}
 				}
@@ -1534,8 +1533,7 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
 		for (isize i = 0; i < max_count; i++) {
 		for (isize i = 0; i < max_count; i++) {
 			Entity *f = type->Tuple.variables[i];
 			Entity *f = type->Tuple.variables[i];
 			if (i == index) {
 			if (i == index) {
-				Array<i32> sel_array = {0};
-				array_init_count(&sel_array, a, 1);
+				auto sel_array = array_make<i32>(a, 1);
 				sel_array[0] = cast(i32)i;
 				sel_array[0] = cast(i32)i;
 				return make_selection(f, sel_array, false);
 				return make_selection(f, sel_array, false);
 			}
 			}
@@ -1543,8 +1541,7 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
 		break;
 		break;
 
 
 	case Type_BitField: {
 	case Type_BitField: {
-		Array<i32> sel_array = {0};
-		array_init_count(&sel_array, a, 1);
+		auto sel_array = array_make<i32>(a, 1);
 		sel_array[0] = cast(i32)index;
 		sel_array[0] = cast(i32)index;
 		return make_selection(type->BitField.fields[index], sel_array, false);
 		return make_selection(type->BitField.fields[index], sel_array, false);
 	} break;
 	} break;
@@ -1979,8 +1976,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
 }
 }
 
 
 Array<i64> type_set_offsets_of(gbAllocator allocator, Array<Entity *> fields, bool is_packed, bool is_raw_union) {
 Array<i64> type_set_offsets_of(gbAllocator allocator, Array<Entity *> fields, bool is_packed, bool is_raw_union) {
-	Array<i64> offsets = {};
-	array_init_count(&offsets, allocator, fields.count);
+	auto offsets = array_make<i64>(allocator, fields.count);
 	i64 curr_offset = 0;
 	i64 curr_offset = 0;
 	if (is_raw_union) {
 	if (is_raw_union) {
 		for_array(i, fields) {
 		for_array(i, fields) {